值得一提的是,vFlatScan的「双页捕获」功能在扫描书籍时非常实用,能够有效减少扫描的工作量。当然,如果某些场景vFlatScan识别双页不准确,你也可以关闭这个功能,在后期处理时使用MuPDF或Briss分割扫描得到的PDF。
制作PDF书签前,需要提供书签信息,即章节名称和对应的页码,以供PDFtk读取并写入PDF文件中。好消息是书籍的目录标题一般都很容易获取,不需要自己手动编辑,一般来说,豆瓣、Amazon或出版社官网页的书籍介绍页都会提供目录,我们只需要复制它,然后将其保存为heading.txt。
PDF书签和Markdown中的标题一样,也是有层级的,比如在《遏制民族主义》这本书中,第一章民族主义的困惑是一级标题,民族主义的界定则是二级标题。为了对不同的标题层级进行区分,我们借用Markdown的语法,将其改写为:
按照如上方式将页码全部提取出来,并保存为pagenumber.txt。对于其中的空行,不必一个个手动移除,之后会在命令行中批量移除。
需要注意的是,通过OCR得到的页码是书籍页眉或页脚中注明的页码,并非PDF文件中的真实页码,这是由于书籍的第1页通常是从正文第一页开始计算的,在正文之前还有序言、致谢、目录等部分,而PDF的页码则总是从第1页开始计算的。在《遏制民族主义》这本书中,从PDF第1页开始计算,正文第1页实际上位于第10页,前面的9页是前言部分。
由于PDF书签的页码总是从第1页开始计算的,因此,通过OCR得到的每一个页码都需要加上9。如果需要对正文之前的部分制作书签,可以在pagenumber.txt中手动输入对应页码减去前言部分的页码数。对于《遏制民族主义》这本书来说,「出版说明」和「目录」分别在第4和7页,减去9后分别是-5和-2。下面的例子中,第一列数字是我们OCR和手动编辑后的结果,第二列数字是它们在PDF中对应的页码:
-5->4#出版说明-2->7#目录1->10#正文5->149->1810->1913->2215->2423->3224->3326->3529->3833->4236->4543->5245->5452->6157->6660->6968->7769->7871->8074->8379->88…使用Shell脚本可以非常容易地实现上面这个转换:
catpagenumber.txt|awkNF|whilereadline;doecho$((${line}+9));done>realpage.text上面这行命令,首先使用cat命令读取pagenumber.txt的内容,然后使用awkNF移除其中所有的空行,再将每行的数字加上9(这个数字需要根据正文之前的页数确定),输出为realpage.text。
将上面的目录标题和对应页码这两个文件合并到一起:
#出版说明4#目录7#第一章民族主义的困惑10##民族主义的界定14##治理单元18##民族19##民族的突出特征22##民族主义的类型24#第二章民族主义的起因32##群体的形成33##群体团结的决定因素35##为何民族主义是现代的事物38##谁是民族主义者42##什么制度才能遏制民族主义?45#第三章间接统治与民族主义的缺失52##间接统治的兴起:原始国家形成理论54##欧洲历史上的间接统治61##欧洲殖民地的间接统治66##结论69#第四章国家建设民族主义77##直接统治的兴起78##直接统治的影响80##直接统治与国家建设民族主义83##结论88……转换为PDF元数据使用PDFtk导出一个带有书签的PDF文件的元数据信息,保存为test.text:
pdftkinput.pdfdump_dataoutputtest.text打开test.text可以发现,PDF书签信息的格式形如:
BookmarkBeginBookmarkTitle:Section1BookmarkLevel:1BookmarkPageNumber:10BookmarkBeginBookmarkTitle:Subsection1.1BookmarkLevel:2BookmarkPageNumber:20BookmarkBeginBookmarkTitle:Subsubsection1.1.1BookmarkLevel:3BookmarkPageNumber:30…容易发现,每个书签条目由4行组成:
了解了PDF书签的构成方式,我们就可以使用Perl结合正则表达式,在命令行中将之前得到bookmark.text转换为同样的格式:
BookmarkBeginBookmarkTitle:出版说明BookmarkLevel:1BookmarkPageNumber:4BookmarkBeginBookmarkTitle:目录BookmarkLevel:1BookmarkPageNumber:7BookmarkBeginBookmarkTitle:第一章民族主义的困惑BookmarkLevel:1BookmarkPageNumber:10BookmarkBeginBookmarkTitle:民族主义的界定BookmarkLevel:2BookmarkPageNumber:14…写入书签信息做好以上准备工作,下面就可以将bookmark.text写入PDF中。但是在进行这一步之前,如果该PDF本身就有书签信息,需要先将其移除。
首先使用PDFtk将input.pdf的元数据提取出来,保存为metadata.text:
pdftkinput.pdfdump_data_utf8outputmetadata.text然后使用下面的命令将其中已有的无用书签全部移除:
分步执行以上各个步骤略显麻烦,可以将这些命令集中在一起,写在一个Makefile中:
在AdobeAcrobat中,打开需要调整页码的PDF,在左侧缩略图中选中页面,点击右键选择「PageLabels…」,然后在出现的「PageNumbering」窗口中进行调整,包括需要更改的页码范围、页码前缀、起始页码等,其中Style一栏包括6个选项:
由于PDF的页码标签开头有一个独特字符Catalog,因此可以在终端中输入vim+/Cataloguncompress.pdf,就会在打开后将光标自动定位到Catalog所在的那一行。
接下来点击j移动光标到下一行,再点击o在下方插入一个空行并进入InsertMode,然后粘贴设置页码的文本,例如:
/PageLabels<>1<>4<>24<>]>>上面的示例中,0<
>表示第1页的页码标签为Cover(PDF中第1页的索引是0而不是1),1<>表示2–4页的页码标签为大写罗马数字,4<>表示5–24页的页码标签为小写罗马数字,24<>表示从25页到最后一页,页码标签全都为阿拉伯数字。粘贴完成之后,按下Esc键退出InsertMode,进入NormalMode,然后输入:wq保存更改并退出Vim。
pdftkuncompress.pdfoutputoutput.pdfcompress打开压缩之后得到的output.pdf,可以看到,页码显示效果与预期一致,修改成功。