用途
pdf-toc-bookmarks 用于为缺少可点击导航的 PDF 添加书签。当 PDF 中已经印有目录页(table of contents),但没有对应的可点击书签时,该技能可以读取这些目录页并生成层级化的 PDF 书签。
主要能力
- 将 PDF 的目录页以高分辨率导出为图片,供视觉分析使用。
- 借助视觉能力读取目录结构,并将其转写为 Python 列表格式。
- 计算印刷页码与 PDF 实际页索引之间的偏移量。
- 使用 PyMuPDF 将书签写入 PDF,并输出带书签的新文件。
- 支持层级结构:level 1 表示章、level 2 表示节、level 3 表示小节,以便在 PDF 阅读器中正确嵌套。
使用方式
技能给出的工作流分为五步:
- 提取目录页为图片。调用
extract_toc_images,指定 PDF 路径、目录起始页、目录结束页和输出目录。示例:
from scripts.extract_toc_images import extract_toc_images
extract_toc_images(
pdf_path="/path/to/file.pdf",
toc_start_page=10, # First TOC page (1-based)
toc_end_page=16, # Last TOC page (1-based)
output_dir="/mnt/user-data/outputs/toc_images"
)
- 视觉分析图片。使用
view逐张查看目录图片,并手动将目录结构转写为 Python 列表:
from view import view
view("/mnt/user-data/outputs/toc_images/page_010.png")
view("/mnt/user-data/outputs/toc_images/page_011.png")
转写格式为 [level, title, printed_page_number]:
toc = [
[1, "Chapter 1: Introduction", 10],
[2, "1.1 Overview", 11],
[3, "1.1.1 Background", 12],
[2, "1.2 Methods", 15],
[1, "Chapter 2: Results", 20],
]
其中 level 为层级深度,title 为目录中的原文,printed_page_number 为书中印刷的页码(不是 PDF 页索引)。
-
确定页码偏移量。用 PyMuPDF 打开 PDF,找到已知页面(例如某章起始页),计算
offset = actual_pdf_page - printed_page_number。常见偏移为 0-10 页,因为封面、版权页、前言等通常不编号。 -
添加书签。调用
add_bookmarks:
from scripts.add_bookmarks import add_bookmarks
add_bookmarks(
pdf_path="/path/to/input.pdf",
toc_list=toc,
page_offset=4, # Offset calculated above
output_path="/mnt/user-data/outputs/file_with_bookmarks.pdf"
)
- 验证并交付。在阅读器中打开输出 PDF,确认书签跳转正确,并向用户提供下载链接。
适用场景
- 用户希望为缺少书签的 PDF 添加书签。
- PDF 有印刷目录页但没有可点击导航。
- 用户提到 PDF 的“bookmarks”“navigation”“TOC”或“table of contents”。
关键要点与限制
- 视觉优于文本解析:由于排版差异,OCR 或正则提取目录不可靠,视觉分析更快更准确。
- 页码偏移必须验证:点击书签确认是否落在正确页面。
- 层级编号需保持一致(1=章、2=节、3=小节),以保证 PDF 阅读器中的正确嵌套。
- PyMuPDF 参考用法:
import fitz
doc = fitz.open("file.pdf")
page = doc[page_index] # 0-based
mat = fitz.Matrix(2.0, 2.0) # 2x zoom
pix = page.get_pixmap(matrix=mat)
pix.save("output.png")
toc = [
[1, "Chapter 1", 10], # level, title, page (1-based)
[2, "Section 1.1", 11],
]
doc.set_toc(toc)
doc.save("output.pdf")
doc.close()
- 官方称传统正则/OCR 方式需 30-60 分钟且易出错,而基于视觉的方式为 10-15 分钟且准确率高。
- 关于收费、价格、支持平台等具体信息,资料中暂未提供。