pdf目录自动生成
起因
最近在阅读一本操作系统有关的书,这本书是打印出来的,但是没有目录,然后想起来之前在 OSChina 上有看到一个开源项目 tocgen
可以识别pdf的目录,所以体验了一下。
# 环境
Windows11
Python3.9.2
由于官方文档里的案例用到了诸如 <
之类 PowerShell 没有操作符,所以我这里用的命令行工具是 Git Bash。
使用流程
安装
pip install -U pdf.tocgen
或仅为当前用户安装:
pip install -U --user pdf.tocgen
原理
软件原理大致是根据标题与其他文本的格式不同来进行判断的,所以我们的步骤大致为三步:
- 获取标题数据
- 提取标题数据
- 合并数据入PDF
根据软件官网的描述,这个项目的设计受到了 Unix哲学
的影响,将整个项目分为了三个小的功能模块,对应完成上面提到的功能:
pdfmeta
pdftocgen
pdftocio
获取标题信息
我们要自己手动找到一个标题,然后记录下他的页面,执行如下命令:
pdfxmeta -p 30 操作系统导论.pdf 关于虚拟化
其中 -p
指定了页面,后面两个参数分别是PDF文件的名称和标题的文字内容。
上述命令会得到如下输出:
$ pdfxmeta -p 30 操作系统导论.pdf 关于虚拟化
关于虚拟化的对话:
font.name = "FZFSJW--GB1-0"
font.size = 9.0
font.color = 0x000000
font.superscript = false
font.italic = false
font.serif = false
font.monospace = false
font.bold = false
bbox.left = 244.1999969482422
bbox.top = 44.362548828125
bbox.right = 316.20001220703125
bbox.bottom = 54.276611328125
如果你执行命令的时候没有任何输出,可能是PDF本身采用了特殊的显示效果等、以及空白字符等的原因,可以尝试换一页试试,或者不带第二个参数
这里有一些数据是不需要带,比如 bbox.*
这些(除非每个标题的长度都是固定的,这不太可能),一般来说,我们只需要字体名称和字体大小的行了,甚至只要字体也可以,这里你要灵活判断一下这里需要的条件。
创建一个文件,例如名称为 recipe.toml
[[heading]]
level 1
font.name = "FZFSJW--GB1-0"
font.size = 9.0
greedy = true
一般来说,我们也要打开
greedy = true
,这样会提取目标的一整行,可以处理既有中文又有英文,或者有特殊公式等字体属性不一致的情况
font.size_tolerance = 0.1
设置字体大小的容忍度,如果你提取的数据有很长的小数点,则有必要带上这个参数
同理,你需要记录下二级标题以及更深标题的信息。
这里一个示例如下:
[[heading]]
level = 1
font.name = "FZFSJW--GB1-0"
font.size = 9.0
greedy = true
font.size_tolerance = 0.1
[[heading]]
level = 2
greedy = true
font.name = "FZLBJW--GB1-0"
font.size = 15.989999771118164
font.size_tolerance = 0.1
开始生成目录
pdftocgen 操作系统导论.pdf < recipe.toml > x.toc
有时候这一步产生的结果会有一点偏差,可以自己用正则表达式或其他工具调整一下
合并目录
确认目录合适后,执行:
pdftocio 操作系统导论.pdf < x.toc
这里如果上一步生成的目录有误差,就会报错。你需要重新调整一下。
评论区