Add lightweight standalone PDF to EPUB import and source-page QA
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# 扫描 PDF → EPUB:后续大版本
|
||||
|
||||
这是独立的大版本方向,本轮不实现。目标是把旧中文书的扫描 PDF 转成可重排、可搜索、可点击目录的 EPUB,同时保留原书中有阅读意义的结构与图文关系。
|
||||
2026-10-28 已开始独立模块首版,见 [PDF_IMPORT.md](PDF_IMPORT.md)。首版优先轻量方案和横排单栏;以下困难版式仍属后续范围。目标是把旧中文书的扫描 PDF 转成可重排、可搜索、可点击目录的 EPUB,同时保留原书中有阅读意义的结构与图文关系。
|
||||
|
||||
## 输入与评测样本
|
||||
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
# 轻量 PDF → EPUB 独立模块
|
||||
|
||||
首版只处理横排单栏、普通段落和简单图片。中文 PDF 转为中文重排 EPUB;英文 PDF 转为英文 EPUB,然后由现有翻译程序处理。PDF 模块不导入翻译客户端,不读取 API Key,不发起翻译请求。
|
||||
|
||||
## 安装和后端
|
||||
|
||||
只使用 PDF 模块时,可单独建环境,不安装原项目的翻译 API 依赖:
|
||||
|
||||
```bash
|
||||
python3 -m venv .work/pdf-env
|
||||
.work/pdf-env/bin/pip install -r requirements-pdf.txt
|
||||
```
|
||||
|
||||
当前项目环境也可以直接安装该文件。相对已有项目,新增 PDF 相关依赖仅 `pypdfium2`、`Pillow`;独立安装还包含 EPUB 封装/结构审计所需的 EbookLib、lxml、BeautifulSoup、html5lib。没有 Docling、MinerU、Torch 或额外模型权重。
|
||||
|
||||
- `--ocr auto`:正常文本 PDF 使用文本层;全页扫描图片重新 OCR,即使已有隐藏 OCR 层也不直接相信旧结果。Mac 默认使用系统 Apple Vision;其他系统使用可选 Tesseract。
|
||||
- `--ocr native`:只用已有文本层。扫描页会记录警告,不能把已有 OCR 质量视为已验证。
|
||||
- `--ocr vision`:强制系统 Vision,需要 macOS 和 Apple command line tools 的 `swiftc`。辅助程序在工作目录编译并复用,本地处理图片。Codex 沙箱内 Vision 如报 nilError,应允许本地 OCR 进程在沙箱外执行;不是 API 认证错误。
|
||||
- `--ocr tesseract`:强制可选 Tesseract CLI;需自行安装程序以及 `eng`/`chi_sim` 语言数据。适配器已实现,本轮机器没有安装 Tesseract,未进行真实 Tesseract 识别验收。
|
||||
|
||||
官方依据:[PDFium Python API](https://pypdfium2.readthedocs.io/en/stable/python_api.html)、[Apple Vision](https://developer.apple.com/documentation/vision/recognizing-text-in-images)、[Tesseract TSV](https://tesseract-ocr.github.io/tessdoc/Command-Line-Usage.html)。PDFium 在本模块中串行调用,避免跨线程调用原生库。
|
||||
|
||||
## 中文 PDF 直接重排
|
||||
|
||||
```bash
|
||||
.work/pdf-env/bin/python scripts/pdf_to_epub.py input/chinese.pdf \
|
||||
--output output/pdf/chinese.epub --work .work/pdf-chinese \
|
||||
--language zh-CN --title '书名' --author '作者' --cover-page 1
|
||||
```
|
||||
|
||||
中文正文使用两格缩进;保留原语言,不做繁简转换或自由改写。输出 metadata 明确标注“PDF重排初稿”,不误标为 AI 翻译版。
|
||||
|
||||
## 英文 PDF → EPUB → 翻译
|
||||
|
||||
```bash
|
||||
.work/pdf-env/bin/python scripts/pdf_to_epub.py input/english.pdf \
|
||||
--output output/pdf/english.epub --work .work/pdf-english \
|
||||
--language en --title 'Original Title' --author 'Original Author'
|
||||
|
||||
# 在已有翻译环境中执行,沿用它的模型、凭据和配置:
|
||||
.venv/bin/python main.py output/pdf/english.epub --complete-book --bilingual
|
||||
```
|
||||
|
||||
PDF 转换完成只打印可选的后续翻译命令,不执行。英文原生文本 PDF 已通过真实 PDF 夹具转换,并验证可由现有 EpubCleaner/FineGrainedExtractor 完整提取;没有调用模型翻译此夹具。
|
||||
|
||||
## 小样、图片与恢复
|
||||
|
||||
- `--pages 1-20,30`:按1起算、闭区间选页;未覆盖全书时,书名和报告明确标注部分样例。
|
||||
- `--cover-page 1`:显式指定封面,不默认把所有 PDF 的第一页当封面。
|
||||
- `--image-pages 2,13,476`:手动保留插图、扉页、原目录或封底整页原貌。少量文字/空白页也会保留为原页图片并列入报告,不声称所有页均已文字重排。
|
||||
- `--dpi 180`:扫描渲染分辨率,支持96–400。
|
||||
- 同一工作目录一次运行一个任务。再次运行相同命令会复用完成的逐页 OCR;源 SHA、引擎、OCR 实现/系统版本、语言或 DPI 变化时不复用不匹配结果。另一份源文件必须使用新目录。
|
||||
|
||||
工作目录保留 `source.json`、`pages/` 原始识别/坐标/置信度、`renders/` 原页图、`book.json` 段落与书签结构、`report.json`。OCR 失败保留已完成页面,禁止把仅完成部分的处理结果写成全书 EPUB。
|
||||
|
||||
EPUB 按原书签组织章节和目录层级;没有书签时使用识别出的简单章节标题,或明确的来源页导航。每个原页都有 `pdf-page-N` 来源锚点;跨页仅合并明显连续的正文,保留原页追踪。页眉删除记录和原 OCR 行仍在中间结果中。
|
||||
|
||||
普通文本 PDF 内的独立图片按页面区域渲染嵌入;扫描页中的混合图文首版不做自动精细分割,需要 `--image-pages` 保留原页。双栏、竖排、公式、复杂表格、脚注双向链接重建不在本轮范围,不作为已实现功能。
|
||||
|
||||
## QA
|
||||
|
||||
可选安装现有 `requirements-qa.txt` 和 Chromium 后:
|
||||
|
||||
```bash
|
||||
PLAYWRIGHT_BROWSERS_PATH="$PWD/.work/playwright" \
|
||||
.venv/bin/python scripts/pdf_qa.py output/pdf/chinese.epub \
|
||||
--work .work/pdf-chinese --pages 1,4,16 --out .work/pdf-chinese/qa
|
||||
```
|
||||
|
||||
生成原页/EPUB 900px/390px 对照,实际点击生成的 NAV 目录链接,并检查目标及来源锚点。HTML 报告和 JSON 分开保留自动结果与视觉待审状态。结构审计通过不等于 OCR 字词准确;Vision 置信分数不是字错率,也不能据此给全书准确率。
|
||||
|
||||
EPUB 在临时文件中构建并通过结构审计后才替换输出。没有依赖 Calibre 或桌面阅读器;Chromium 连续 XHTML 不能代表所有阅读器分页。
|
||||
|
||||
## 可追溯的局部校正
|
||||
|
||||
`--corrections corrections.json` 支持查看原扫描后确认的逐行校正:
|
||||
|
||||
```json
|
||||
{
|
||||
"source_sha256": "当前PDF的完整SHA256",
|
||||
"edits": [{
|
||||
"line_id": "p0101-l0011",
|
||||
"expected": "原始OCR整行原文",
|
||||
"replacement": "核对原扫描后的整行文字",
|
||||
"evidence": "核对依据"
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
源 SHA、行 ID 或 expected 不匹配就停止;重复条目和空替换也拒绝。原始 `pages/*.json` 不改写,校正写在派生 `book.json` 和报告里,可在重建时重复应用。识别内容变化会改变输出版本标识。此功能用于有证据的文字校对,不替代全书审读。
|
||||
@@ -0,0 +1,60 @@
|
||||
# 轻量 PDF 导入首版与样本验收
|
||||
|
||||
按本轮收窄的范围开发:不引入 Docling 或大型模型,不实现困难版式。新增独立 `src/pdf_import/`、`scripts/pdf_to_epub.py` 和可选 `scripts/pdf_qa.py`。中文直接重排为 EPUB;英文先生成英文 EPUB,再进入已有翻译程序。转换阶段不调用翻译 API。
|
||||
|
||||
## 已实现与依赖
|
||||
|
||||
新增 PDF 依赖为 PDFium Python 包与 Pillow。独立环境只装 `requirements-pdf.txt`,包含 EPUB 导出/审计的轻量基础库;实际验证未加载 OpenAI SDK、Torch、Transformers、Docling 或 Paddle。macOS 使用系统 Vision;Swift 辅助进程常驻批量识别,未额外下载 OCR 模型权重。Tesseract 适配器可选,本机未安装程序,未做真实 Tesseract 验收。
|
||||
|
||||
原生文本提取与扫描页识别分流,扫描页即使已有隐藏 OCR 层也重新识别。页面缓存按源 SHA、页号、实际引擎/实现与系统版本、语言、DPI 和 PDFium 版本匹配。失败只保留已完成页面;未完成全书时不写出冒充全书的结果。部分选页输出有明确样例标签。
|
||||
|
||||
根据来源坐标重建普通段落,修复首轮发现的页眉混入正文与连续缩进段落被逐行拆开的情况;明显的跨页连续正文合并,原页锚点保留。书签层级生成 NAV/NCX。保留指定整页图,数字 PDF 的独立图片按页面区域渲染嵌入。构建临时 EPUB,结构审计通过后才替换最终输出。
|
||||
|
||||
## 样本
|
||||
|
||||
用户指定下载目录中的《中国的世界高原 上》,沈卫平。476页,无密码;抽查为横排单栏扫描,已有 ABBYY 文本层,但可见漏字,不能当作可靠原文。
|
||||
|
||||
源 SHA256:`aebc9f263ab0599f6d11c7db6c5e89e1316f2a950f2faa9ddbc72a94fe3da335`。
|
||||
|
||||
```bash
|
||||
.venv/bin/python scripts/pdf_to_epub.py \
|
||||
'/Users/kaitan/Downloads/中国的世界高原 上 (沈卫平) (z-library.sk, 1lib.sk, z-lib.sk).pdf' \
|
||||
--output 'output/pdf/中国的世界高原_上_重排初稿.epub' \
|
||||
--work .work/pdf-highland --language zh-CN \
|
||||
--title '中国的世界高原(上)' --author 沈卫平 \
|
||||
--cover-page 1 --image-pages 2,13,476 \
|
||||
--corrections .work/pdf-highland/corrections.json
|
||||
```
|
||||
|
||||
476/476页处理,476个来源页锚点均存在。459页为重排文字,17页为封面、扉页、空白/短文字页等原页图片;报告逐项列明。第2、13、476页为显式指定保留原貌的扉页、纸本目录和带签名二维码的封底;其余少量空白/短文字页自动保留原页图,不称为可搜索的重排文字。
|
||||
|
||||
原87个书签对应87个有效目录目标,层级为10个一级、77个二级。浏览器实际点击87个 NAV 链接,目标均到达。509行页眉/页码候选从派生正文移除,原识别行和删除记录仍保存。
|
||||
|
||||
## 对照 QA 与修复
|
||||
|
||||
以原页序1、4、16、101、248、476生成原扫描/900px/390px对照,检查封面、普通段落、跨页衔接、引文和封底保留。自动结构审计零问题,抽样自动布局检查零问题。实际查看的图片及 SHA 写入 `.work/pdf-highland/review-record.json`。
|
||||
|
||||
原页对照确认第101页两行中的三个字形识别错误,使用带源 SHA、稳定行 ID、expected 原文和 replacement 的校正文件修正;原始逐页 OCR JSON 不变。校正不匹配或重复时拒绝应用,不做全书无证据替换。
|
||||
|
||||
OCR 准确率仍待全文校对,未计算人工真值字错率。Vision 的低置信提示不是准确率百分比。输出 metadata 明确标为“PDF重排初稿”;没有宣称所有文字或每个阅读器分页已验收。
|
||||
|
||||
## 独立与英文路径验证
|
||||
|
||||
在新环境 `.work/pdf-light-env` 仅安装 `requirements-pdf.txt`,实际将两页英文原生文本 PDF 夹具转换为 EPUB,并打印后续翻译命令,没有加载翻译 SDK 或发起翻译。另用现有 EpubCleaner 和 FineGrainedExtractor 验证生成英文 EPUB 可进入现有提取链路。后续翻译在原项目 `.venv` 中执行,沿用其模型与凭据选择。
|
||||
|
||||
测试:98 passed,2 skipped。新增覆盖页范围、页眉误识别、英文提取衔接、扫描页覆盖旧文本层、缓存复用/失效、失败恢复与禁止部分全书输出、连续缩进段落及源绑定校正。
|
||||
|
||||
## 范围限制
|
||||
|
||||
- 首版针对横排单栏普通书;没有实现双栏、竖排正文、公式、复杂表格或脚注双向链接重建。
|
||||
- 扫描页混合插图不自动精细切分;可指定整页保留。并非所有字体、粗体及页面坐标都被重建。
|
||||
- 来源锚点使用PDF文件页序,不冒充纸本页码。纸本目录页保留原图,交互目录由实际 PDF 书签生成。
|
||||
- headless 为连续 XHTML,不代表 Calibre、Apple Books 等所有阅读器的分页。全书文字校对没有完成。
|
||||
|
||||
## 本地证据
|
||||
|
||||
`.work/pdf-highland/`:`source.json`、原始 `pages/`、`renders/`、`book.json`、`corrections.json`、`report.json`、`qa-final/review.html`、`qa-final/report.json` 和 SHA 绑定的 `review-record.json`。原PDF不修改,书籍和识别文字不提交仓库。
|
||||
|
||||
输出:`output/pdf/中国的世界高原_上_重排初稿.epub`。
|
||||
|
||||
输出 SHA256:`9e2bece683420803d59292aa49fb44ee6e1cd002331364af7380ba0a5971b71d`。
|
||||
Reference in New Issue
Block a user