列出 PDF 中的命名目的地

Gil*_*il' 11 pdf

如何在 PDF 文件中列出指定的目的地?

命名目的地是您可能称之为锚点的正式名称。foo当您点击链接时,主要浏览器会跳转到指定的目的地http://example.com/some.pdf#foo

我有可以看到锚点工作的文档,但我似乎找不到列出锚点的方法。Evince、okular 和 xpdf 会根据指示跳转到它们,但似乎没有列出它们的界面。pdftk dump_data列出书签,但这不是一回事(这是目录条目,很可能与命名目的地位于同一位置,但不能用作锚点)。

我正在寻找命令行解决方案(例如,适合在 之后的完成函数中使用evince -n)。鉴于这是有意义的,我想按照目的地在文档中出现的顺序列出目的地。奖励:显示目标页码和其他有助于确定目的地大致位置的信息。

另请参阅有关GUI 查看器的软件推荐的 PDF 文档中的查看锚点

小智 12

Poppler 的 pdfinfo命令行实用程序将为您提供 PDF 中所有命名目的地的页码、位置和名称。您至少需要 0.58 版的 Poppler。

$ pdfinfo -dests input.pdf
Page  Destination                 Name
   1 [ XYZ null null null      ] "F1"
   1 [ XYZ  122  458 null      ] "G1.1500945"
   1 [ XYZ   79  107 null      ] "G1.1500953"
   1 [ XYZ   79   81 null      ] "G1.1500954"
   1 [ XYZ null null null      ] "P.1"
   2 [ XYZ null null null      ] "L1"
   2 [ XYZ null null null      ] "P.2"
(...)
Run Code Online (Sandbox Code Playgroud)


Gil*_*il' 8

pyPDF库可以列出锚:

#!/usr/bin/env python
import sys
from pyPdf import PdfFileReader
def pdf_list_anchors(fh):
    reader = PdfFileReader(fh)
    destinations = reader.getNamedDestinations()
    for name in destinations:
        print name
pdf_list_anchors(open(sys.argv[1]))
Run Code Online (Sandbox Code Playgroud)

这对于完成用例来说已经足够了,但锚点是按随机顺序列出的。只有pyPdf 1.13的稳定接口,我找不到按顺序列出锚点的方法。我还没有尝试过 pyPdf2。


小智 2

(也在这里回答:查看 PDF 文档中的锚点

我有同样的问题,最终通过如何直观地检查 PDF 的结构以对其进行逆向工程找到了一个很好的答案。

答案是使用Python包pdfminer.six。这甚至是文档中的示例之一!将此代码剪切并粘贴到终端中:

pip install pdfminer.six
cat >extract.py <<EOF
import sys
import pdfminer.pdfparser, pdfminer.pdfdocument
with open(sys.argv[1], "rb") as f:
  parser = pdfminer.pdfparser.PDFParser(f)
  document = pdfminer.pdfdocument.PDFDocument(parser)
  for (level, title, dest, a, se) in document.get_outlines():
    print('  ' * level, title, dest or a, se)
EOF
python extract.py myInputFile.pdf
Run Code Online (Sandbox Code Playgroud)

在我的特定 PDF 上,输出如下所示:

$ python extract.py ~/Desktop/p2786r3.pdf | head
   Abstract {'S': /'GoTo', 'D': b'section.1'} None
   Revision History {'S': /'GoTo', 'D': b'section.2'} None
     R3: October 2023 (midterm mailing)r3-october-2023-midterm-mailing {'S': /'GoTo', 'D': b'section*.2'} None
     R2: June 2023 (Varna meeting)r2-june-2023-varna-meeting {'S': /'GoTo', 'D': b'section*.3'} None
     R1: May 2023 (pre-Varna mailing)r1-may-2023-pre-varna-mailing {'S': /'GoTo', 'D': b'section*.4'} None
     R0: Issaquah 2023r0-issaquah-2023 {'S': /'GoTo', 'D': b'section*.5'} None
   Introduction {'S': /'GoTo', 'D': b'section.3'} None
   Motivating Use Cases {'S': /'GoTo', 'D': b'section.4'} None
     Efficient vector growth {'S': /'GoTo', 'D': b'subsection.4.1'} None
     Moving types without empty states {'S': /'GoTo', 'D': b'subsection.4.2'} None
Run Code Online (Sandbox Code Playgroud)

事实上,p2786r3.pdf#subsection.4.2在我的浏览器中导航到该特定部分会打开 PDF。