用PDFPatcher为没有书签的PDF制作书签
原创
沈沉舟
沈沉舟
青衣十三楼飞花堂
2026年7月5日 14:27
北京
在小说阅读器读本章
去阅读
创建: 2024-02-27 19:51
更新: 2026-07-02 21:28
有些不是用Pdg2Pic制作的PDF,比如从Z站下载的,只有页面,没有书签,Chrome打开后,左侧只有缩略图,没有电子目录结构(书签)。这种,Chrome显示的页码与纸版页码并不对应,前者是PDF层面的绝对页码,后者是印刷时自定义的页码。比如纸版页码1,对应正文第1页,前面一般还有照片、序言、目录页等,不包含在纸版页码计数器内。
我分享PDF摘录时,用的是Chrome看到的绝对页码,不是纸版页码,因为我主要在PC上看电子版。正经引用书籍内容时,应给纸版页码。
书签的作用,是在纸版页码、绝对页码之间建立映射,书签显示纸版页码,点击后跳至相应的绝对页码。若无书签,就得自己找出纸版页码1所对应的绝对页码,算出差值(delta),对纸版目录中的纸版页码(增加delta)心算出绝对页码,在Chrome中手工跳转。有些人受不了这个麻烦,我倒是无所谓,内容为王,其它不重要。
另一种书签是在章节标题、绝对页码之间建立映射,相比前一种书签,二者各有利弊。
本小节介绍前一种书签的制作过程。有很多方案,只介绍一种自用方案。
用PDFPatcher打开无书签PDF。在右侧PDF页面移动鼠标至左上角,右键\"在此插入书签\",\"书签文本\"处随便输点啥,比如\"foo\",\"方位\"那里显示的数字实际对应刚才鼠标所在点的y坐标,坐标系的原点(0,0)是PDF页面左下角。
菜单上选,文件->换名保存书签文件->some.xml。这个xml长这样
<?xml version=\"1.0\" encoding=\"gb2312\"?>
<PDF信息 程序名称=\"PDFPatcher\" 程序版本=\"...\" 导出时间=\"...\" PDF文件位置=\"some.pdf\">
<文档书签>
<书签 文本=\"foo\" 页码=\"1\" 动作=\"转到页面\" 显示方式=\"坐标缩放\" 上=\"800\" />
</文档书签>
</PDF信息>
手工编辑xml,改成(只是个示例)
<?xml version=\"1.0\" encoding=\"gb2312\"?>
<PDF信息 程序名称=\"PDFPatcher\" 程序版本=\"...\" 导出时间=\"...\" PDF文件位置=\"some.pdf\">
<文档书签>
<书签 文本=\"照片\" 动作=\"转到页面\" 页码=\"4\" 显示方式=\"坐标缩放\" 左=\"0\" 上=\"800\" 比例=\"0\" />
<书签 文本=\"自序\" 动作=\"转到页面\" 页码=\"15\" 显示方式=\"坐标缩放\" 左=\"0\" 上=\"800\" 比例=\"0\" />
<书签 文本=\"目录\" 动作=\"转到页面\" 页码=\"19\" 显示方式=\"坐标缩放\" 左=\"0\" 上=\"800\" 比例=\"0\" />
<书签 文本=\"1\" 动作=\"转到页面\" 页码=\"28\" 显示方式=\"坐标缩放\" 左=\"0\" 上=\"800\" 比例=\"0\" />
<书签 文本=\"2\" 动作=\"转到页面\" 页码=\"29\" 显示方式=\"坐标缩放\" 左=\"0\" 上=\"800\" 比例=\"0\" />
...
<书签 文本=\"384\" 动作=\"转到页面\" 页码=\"411\" 显示方式=\"坐标缩放\" 左=\"0\" 上=\"800\" 比例=\"0\" />
</文档书签>
</PDF信息>
解释一下<书签>中的某几个字段
文本 将来显示的电子目录结构(书签)
页码 与\"文本\"字段关联的绝对页码,即跳转目标的绝对页码
左 跳转目标点的x坐标,一般对应目标页的左上角,可调整至目标页任意位置
上 跳转目标点的y坐标,一般对应目标页的左上角,可调整至目标页任意位置
其他字段保持上例展示的那样。xml决定书签效果,\"文本\"想写什么都可以;\"页码\"要与\"文本\"匹配,否则跳转目标非预期;跳转后展示时自动滚动到(x,y)处,比如想跳至页面中部某处,每个目标页的(x,y)是独立的;有多少条<书签>行都成。
假设已编辑好some.xml,回到PDFPatcher,先删除之前搞的foo书签,菜单上选,文件->导入书签(Ctrl+R),文件->保存PDF文件(Ctrl+S),指定新PDF文件名。
Chrome中打开some\_new.pdf,检验书签效果。
一般<书签>行很多,上例纸版页码从1到384递增,每行只有\"文本\"、\"页码\"两字段递增,手工编辑不理智,可用程序自动生成。
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
#
# python3 bookmark.py <param0> <param1> <param2> [count]
# python3 bookmark.py 1 28 800 10
# python3 bookmark.py 1 28 800 384 > some.txt
#
# param0 书签中看到的数字,对应纸版页码
# param1 Chrome打开PDF时的绝对页码,不对应纸版页码
# param2 用PDFPatcher获取目标页面左上角y坐标
# count 缺省为10
#
import sys
def main ( argv ) :
ret = False
while True :
if len( argv ) < 4 :
print( f\"Usage: python3 {argv[0]} <param0> <param1> <param2> [count]\" )
break
try :
param0 = int( argv[1] )
param1 = int( argv[2] )
except ValueError :
print( \"param0 and param1 must be integer\" )
break
param2 = argv[3]
count = 10
if len( argv ) > 4 :
try :
count = int( argv[4] )
except ValueError :
print( \"count must be integer\" )
break
for _ in range( count ) :
pattern = f'<书签 文本=\"{param0}\" 动作=\"转到页面\" 页码=\"{param1}\" 显示方式=\"坐标缩放\" 左=\"0\" 上=\"{param2}\" 比例=\"0\" />'
print( pattern )
param0 += 1
param1 += 1
ret = True
break
return ret
if \"__main__\" == __name__ :
ret = main( sys.argv )
sys.exit( 0 if ret else -1 )
bookmark.py只生成纸版页码到绝对页码的映射行,照片、序言、目录页的映射行需手工组织。
某些书签制作教程,全自动生成some.xml。PDF是文字版时,是一种搞法;PDF是图片扫描版时,动用OCR提取纸版目录的文字说明。我没全自动的需求,略。
若非从零生成书签,只想微调零星几个映射,可不用xml,直接在PDFPatcher中操作,略。
不确认PDFPatcher是否支持Excel下拉操作,选中纸版页码、绝对页码,下拉自动递增。若支持,前面那些都是废话,忘掉即可。
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论