如何半自动地给 PDF 添加目录

date
Feb 19, 2020
slug
how-to-semiauto-add-toc-to-pdfs
status
Published
summary
用 PdgCntEditor 给 PDF 添加目录
type
Post
tags
Update:如果你的 PDF 文件不是影印版,这篇文章介绍了一个很不错的方法,推荐优先尝试一下:
为 PDF 增加目录 - 少数派
Matrix 是少数派的写作社区,我们主张分享真实的产品体验,有实用价值的经验与思考。我们会不定期挑选 Matrix 最优质的文章,展示来自用户的最真实的体验和观点。 文章代表作者个人观点,少数派仅对标题和排版略作修改。 对于需要归档收集的人而言,PDF 无疑是一个绝佳的选择,但有些我们转换或下载的 PDF 可能出现没有目录的情况,这对于快速查找十分的不便。 本文针对影印版文件无效,一个简单的测试方式是打开文件尝试选择/复制,如果不可以选择或复制出来有错字或多余的空格则本文无效 本次使用的工具是 pdf.tocgen ,这是一个能够为 PDF 自动生成目录的开源命令行工具集,其由 pdfxmeta、pdftocgen、pdftocio 三个工具组成。 这是来自官网的介绍图,in.pdf 是我们原始没有目录的 pdf 文件,而 out.pdf 是经过工具处理后增加了目录的新文件。 pdf.tocgen 工具集的原理是 PDF 中的「标题」与「正文」的格式一般是不一样的,同样,标题的不同层级格式一般也是不一样的,pdf.tocgen 则提供了一套工具来利用这一差异半自动的生成目录。该工具集有三个软件组成,pdfxmeta 可以利用文字来查找对应的格式信息,pdftocgen 则是利用 pdfxmeta 输出的格式信息生成目录的描述,而 pdftocio 则是利用 pdftocgen 生成的目录描述为我们的原始 pdf 增加目录并输出新的 pdf 文件。当然,这么说过于抽象了一点,本文中我将使用一个真实例子(就发生在昨天,还很热乎)进行演示,相信你看完会发现听起来虽然很麻烦,但是真的上手操作起来既简单又强大灵活,可以覆盖几乎全部的需要目录的场景。 pdf.tocgen 是由 Python 编写、在 pypi 上发布的工具,因此我们需要先配置 Python 的环境然后下载这一程序。 不要被 Python
为 PDF 增加目录 - 少数派

什么东西比一个 PDF 文档更惹人烦?一个没有目录的 PDF 文档。
没有目录的原因很多。可能是在文档传播的过程中被导出丢失了,也可能就是那个作者,明明知晓那么多 LaTeX 的技巧,但就是懒得多动一下手指方便读者。
我们只能自己给文档加目录了。
要做到这件事,我们需要一个免费的小工具:PdgCntEditor。然后,为了省事,我们还需要一小段脚本来快速修整格式。我把这两样东西打包准备好了:
这个工具只有 Windows 下有,macOS下我暂时还没找到替代品。因此,你还需要一个虚拟机/双系统。
首先,打开你要添加目录的 PDF,找到它正文里的目录。如果连这个也没有,或者你看的 PDF 是扫描版,那还是放弃吧。把正文里的目录复制下来,粘贴到 Drafts 里。
PdgCntEditor 对于批量添加目录的格式要求是:
  1. 目录的标题和对应的页码之间用制表符(Tab)隔开。
  1. 多个标题之间换行隔开。
  1. 有多层级的标题时,在标题前面加额外的制表符表示层级的缩进。
notion image
可以看到,从 PDF 里复制出来的内容可以说惨不忍睹,完全不符合 PdgCntEditor 的格式要求。我手动修改了其中的前几行。我们需要把整个目录八百多行全改成这个样子,才能批量添加成功。
这时候,我们需要一小段脚本来帮助我们完成这项工作。安装压缩包里附的 Drafts 动作,然后对这个草稿运行。我们会得到:
notion image
可以看到,现在的格式都正确了。图中有些页码看起来被换行了,但实际上那是一个制表符。确认这一点的方法是把光标移到有问题的地方,按方向键向前移动一次光标。如果光标回到了上一行最后一个字母的右边,那就表明这里是一个换行。但如果光标移动到了上一行最后一个字母的左边,则说明这里没有换行,只是显示问题。
当然,你得到的很可能和我的结果不一样——因为这个动作只是我针对我面前的这份文档复制出来的目录所写的。它使用 JavaScript 运行正则表达式来匹配并替换文本,大致做了以下几件事:
  1. 把页码和标题之间的「...............」和「. . . . . . . . . . . . 」等内容删除,替换成单个制表符。
  1. 对于所有「1.1」、「10.2」之类的小节号,换行并缩进一次。
  1. 对于所有「1.1.2」、「10.2.5」之类的小节号,换行并缩进两次。
  1. 给大部分单词之间加上空格。
大部分 PDF 拷出来的文本都是类似的格式,所以这个动作应该能帮到你。如果情况不一样,你也可以根据实际情况改写一下我的正则表达式。否则……也许我以后会写一个更通用的动作也说不定。
运行完动作之后,你还是需要手工修整一下。有些地方是复制出来时就有的错误,光靠正则表达式不能去除。
notion image
完成以后,让我们在 PdgCntEditor 中打开待添加目录的文档。首先把修整好的目录文本粘贴进主界面,然后点击右上角的 PDF 文档图标:
notion image
在这里,我们需要为这个目录设定基准页。基准页很好确定:用预览(或者其它 PDF 阅读器)打开该文档,找到待生成的目录中第一章的第一页,它所在的页码就是基准页。
notion image
填入基准页,确认,然后按保存即可。
notion image
这时再打开文档,就可以看到目录了。
notion image
你可以在这里下载到我用的示例文档。最后提醒一句:在目录文本的标题里不要用制表符,否则生成出来的目录会出错。
If you have any questions, please contact me.