有时候我们下载到一些PDF格式的书籍,虽然包含了页面目录,但不是书签形式的,阅读起来不是很方便。那么如何根据书籍的页面目录,快速创建书签目录呢。本篇博文是基于python库pdfbookmarker的一个处理方案。其地址参见:https://github.com/RussellLuo/pdfbookmarker

将目录转换成TXT格式的目录文件

如果是扫描版本的PDF文件,建议使用金山PDF阅读器自带的扫描件识别功能,先将目录部分转换成可以选择的PDF格式(OCR功能)。然后再利用Adobe PDF阅读器的列选择功能,将PDF页面目录拷贝到TXT格式的目录文件中。拷贝方法为:首先按Shift + ALT键,待鼠标指针变化成选择框的时候,再行复制。目前还不知道金山PDF阅读器的列选择功能怎么使,但是Adobe PDF阅读器的这个功能非常不错,尤其是对于双栏目录,不使用列选择功能复制后就会混合在一起。

使用正则格式化目录文件

TXT文件复制制作完成之后,可能还存在很多的问题。例如有些目录因为文字部分太长,就会出现串行。

  • 串行问题
Chapter 6 REACTION EQUILIBRIUM IN IDEAL GAS MIXTURES 174
6.1 Chemical Potentials in an Ideal Gas Mixture 175
6.2 Ideal-Gas Reaction Equilibrium 177
6.3 Temperature Dependence
of the Equilibrium Constant 182
6.4 Ideal-Gas Equilibrium Calculations 186
6.5 Simultaneous Equilibria 191

例如上面的目录,6.3节的目录出现了串行。可以使用如下的正则解决(下面的正则替换均需在Visual Studio Code软件中使用,因为不同的编辑器支持的正则方言不一样)。

# 查找正则
(?<!\d)\n
# 替换部分,输入一个空格就成

如果因为文档的字迹不清楚,导致拷贝后的效果不好,那么可能需要手工校对。字迹清楚的一般不会有其他问题。

将目录格式化成python脚本需要的格式

++"TEXT TITLE"|N

其中+的数量代表level的级别,N代表页码的数字。由于每本书籍的目录格式是不一样的,编写具有鲁棒性的脚本比较困难。我们还是可以使用正则进行针对性的格式化。以上述的目录为例。

  • 给每一行目录增加+"符号(level=1的目录)
# 查找正则
^
# 替换
+"

这样,章一级(level=1)的基本就处理完成了,那么针对节一级(level=2)的还需要替换。

  • 格式化节一级的目录(level=2的目录)
# 查找正则,如果前边的数字包含点,代表为节一级,当然下边的写法比较随意
"(\d*?[.])
# 替换
+"$1
  • Level等于3部分的目录格式化
# 查找正则
"((\d*?[.]){2})
# 替换正则
+"$1
  • 页面数字部分的格式化
# 查找正则
\s*?(\d+)(?=\n)
# 替换
"|$1

这里可能需要经常性的使用正则中的零宽度断言,如有不熟悉或者遗忘,可以参见:https://www.cnblogs.com/macq/p/6597366.html

处理页面目录位置偏移

做完上面的步骤,目录的格式已经处理完毕。但是对于大部分的书籍,其页面目录中对应的数字和实际的PDF页面位置存在一个偏移,由于正则替换功能没有数字计算的功能,因此只能使用脚本了。这里使用Powershell脚本。

param (
    [Parameter(Mandatory)]
    [string]$Path,

    [int]$Gain = 5
)

$OutPath = "{0}-p.ini" -f $Path.Substring(0, $Path.LastIndexOf("."))

Get-Content $Path | % {
    $lr = $_.Split("|")
    "{0}|{1}" -f @($lr[0], ([int]$lr[1] + $Gain))
} | Out-File $OutPath

假设powershell脚本的名字为cp.ps1,那么调用的方式为:

.\cp.ps1 -Path content.txt -Gain 18

其中Gain参数对应偏移的量。对于有些比较变态的书籍,每一个章节的偏移量都不一样,这个时候就需要对脚本进行一些修改了。

小结:对于%循环中的输出,如果出现变量赋值,代表该变量不会传递给下一个命令,否则就会传递。

如果vscode安装了Replace Selection插件,那么不必使用powershell脚本也可以实现页面数字的增加和修改。步骤如下:(1)使用正则表达式$选择所有的结尾,然后在结尾处插入+offset,其中offset为需要增加的数字;(2)使用CTRL+SHIFT+<-增加选择范围,直到覆盖原来的数字;(3)使用插件中Replace with Evaluated Javascript Result命令执行eval功能。更加详细的步骤,可以查看一下视频。

添加书签目录

假设书签的文件名为c.txt,PDF文件的名称为c.pdf则调用的方法为:

pdfbm c.pdf c.txt [c-p.pdf]

其中输出文件的名称是可选的,如果不设置,其名称为原名称加上-new后缀。

以上就是PDF文件的书签目录制作流程,看起来还是比较复杂的,流程有点多,但是如果每一步比较熟,还是很快的。尤其对于那种几百页上千页的PDF文件,这种方式比手工制作目录肯定方便不少。