12

我想导出存储在一些 PDF 文档中的页面标签以便于解析。我知道我可以在使用 转换后深入研究 PDF 文档qpdf,但这似乎有点矫枉过正。

是否没有命令行工具可以简单地打印每个页面(或与其他元数据一起)的页面标签?我知道 PDFSpy 会导出标签,但不能选择 300 美元,最好是免费的解决方案。

4

2 回答 2

15

简短回答:
我不知道有任何(免费)工具可以“简单地打印”每页的页面标签。

此外,您将无法使用类似qpdf或具有同等功能的工具来逃避扩展压缩对象和对象流。

长答案:
没有这样的工具,因为这些是您在页面标签方面可以安全依赖的仅有的几件事。这些是:

  1. 每个 PDF 文档都必须包含一个根对象。
  2. 该根对象必须/Type /Catalog.
  3. 该文档的预告片将显示在哪里可以使用键/Root和间接对象编号引用找到对象。
  4. 如果PDF 文档使用非标准页面标签,则文档根对象必须有一个名为 的条目/PageLabels

这是它停止相对容易的地方。因为/PageLabels键所指的对象可能包含在压缩的对象流中。这意味着您必须扩展该对象流。

如果你真的成功地将页面标签描述为 ASCII,你会发现它不是一个容易解析的平面列表(就像 a dictionaryis):它是一个数字树

我不会详细介绍这些复杂性,因为要描述所有可能的变化需要很长的文章。您最好直接在官方 ISO PDF-1.7 规范中阅读它。

但相反,我会给你一个 ASCII PDF 代码的例子:

213 0 obj
  << /Type /Catalog
     /PageLabels 
        << 
           /Nums 
                 [ 
                   0 <<           % start labeling from page no. 1
                       /S /r      % label with lowercase roman numbers
                     >> 
                   7 <<           % start new labeling from page no. 8
                       /S /D      % label with standard decimal numbers
                     >> 
                   11 <<          % start labeling page no. 12
                       /S /D      % label with decimal numbers...
                       /P (ABCD-) %   ...but using label prefix 'ABCD-'...
                       /St 3      %   ...followed by '3' as the start decimal.
                     >>
                  ]
        >>
     %%...........................
     %%...more root object keys...
     %%........................... 
  >>
endobj

上面的示例将标记页码1、2、3、...(最后一个),如下所示:

i
ii
iii
iv
v
vi
1
2
3
4
ABCD-3
ABCD-4
ABCD-5
ABCD-6
...and so on until last page...

如您所见,标记页面的 PDF 方法(将页码映射到页面名称)完全不直观。您只能通过研究PDF规范来理解它。

于 2012-10-16T23:56:44.250 回答
2

我编写了一个基于 Poppler 的小型命令行实用程序来完成这项任务:https ://github.com/HeimMatthias/pdfpagelabels

免责声明:我是 OP,并在另一个帐户下创建了原始帖子。多年来,我一直在通过 pdftk(在上面的评论中列出)成功使用该解决方案。然而,去年是时候从头开始重新实现我们的系统了,我们已经有许多实例无法通过我们的实现来解析 pdf-tk 输出。

新的命令行工具遵循只做一件事的理念,但要做得好,并简单地打印 pdf 文件的所有或选定页面的页面标签。如果有人发现这很有用,并在这里偶然发现它,那就更好了。

于 2021-03-07T22:13:39.047 回答