165 lines
14 KiB
Markdown
165 lines
14 KiB
Markdown
# EPUB Bilingual Translator
|
||
|
||
大段翻译、全书术语表、严格占位符校验、agent 审校 skill 和无桌面 headless QA。
|
||
|
||
## 安装与使用
|
||
|
||
```bash
|
||
python3 -m venv .venv
|
||
.venv/bin/pip install -r requirements.txt
|
||
cp .env.example .env
|
||
# 在 .env 中填写 OPENAI_API_KEY;在 config/config.yaml 选择模型及服务地址。
|
||
.venv/bin/python main.py input/book.epub --bilingual
|
||
```
|
||
|
||
不带 `--bilingual` 输出中文版。支持 OpenAI-compatible Chat Completions 服务;保留项目现有模型配置,不自动更换服务商。`chunk_size` 是字符数,不是 token 数;按模型上下文及输出上限调整。默认每段请求约 24,000 字符,输出预算 16,000 token,超时 180 秒;输出截断不会被当作成功。不同供应商对 `max_completion_tokens` 的支持应在接入时确认。
|
||
|
||
指定该书的术语约定:
|
||
|
||
```bash
|
||
.venv/bin/python main.py input/book.epub --bilingual --glossary config/glossary.example.json
|
||
```
|
||
|
||
示例表用于说明格式,请按书籍内容编辑。未指定术语表时,程序先扫描全书,生成 `.work/书名/glossary.json`,然后所有并发翻译共用这份表。冲突建议保存在 `conflicts` 中,已确立译名不会被后续章节覆盖;别名碰撞会报错。人物别名应尽量采用完整名称,避免把同姓的其他人物当作主人公。支持 `aliases`、`notes`、`forbidden_targets` 和 `exclude_contexts`;单独姓氏之后的 family/clan/dynasty/surname 不适用人物译名,更长的明确术语优先匹配。
|
||
|
||
## 质量控制
|
||
|
||
- DOM 遍历保留行内标签,图片、数学公式和脚注作为完整对象保护;占位符须次数正确、嵌套合法,还原后须是合法 XHTML。
|
||
- 大段初译后,只重试未通过校验的条目。网络错误、重复输出 ID、缺失条目、截断和占位符错误保持待处理状态,不写入“错误译文”。正常运行有失败时终止,不静默生成不完整中文版。
|
||
- 在原 EPUB 容器上修改正文;保留 OPF、目录链接及层级、原 CSS 引用、图片、字体和其他资源。双语段落避免复制 ID,中文版保留原锚点;列表和表格不会插入无效兄弟节点。
|
||
- HTML5 修复处理不闭合标签和重复 ID,抽取不会重复处理嵌套列表/段落;支持裸 div、表格单元、图注和混合容器中的直接文本。
|
||
- 已翻译条目按原文、占位符、标题上下文、术语表、模型及风格指南指纹复用;每个 chunk 完成就保存。源文件变更会重新预处理。旧版本缓存会升级,无法安全复用的译文需要重新翻译。
|
||
|
||
`--skip-translation` 用于离线调试/部分样例,不代表全书已翻译。`--force-clean` 重新预处理;`--force-restore` 兼容旧用法,但现在每次回填前都会重新校验,旧的缓存 HTML 不再直接被信任。
|
||
|
||
## 可重复 QA
|
||
|
||
完整翻译使用 `--complete-book`,会纳入默认跳过的尾注、参考文献、索引、版权页及非 spine 文字资源。图片中的文字仍作为原图保留。NAV、NCX 和书内目录继续复用实际章节标题译文。
|
||
|
||
Zenmux 的 Sonnet 5.5 配置见 `config/zenmux.yaml`。凭据使用本地 `ZENMUX_API_KEY`,或通过 `--env-file` 指定 dotenv 文件;不把密钥写入 YAML 或提交到 Git。已有 Anthropic 兼容接口的 Zenmux token 可在本地映射到此变量:
|
||
|
||
```bash
|
||
export ZENMUX_API_KEY="$ANTHROPIC_AUTH_TOKEN"
|
||
.venv/bin/python main.py 'input/Gambling Man.epub' --complete-book --bilingual \
|
||
--config config/zenmux.yaml --output-dir output/sonnet55
|
||
```
|
||
|
||
`--config` 指定独立配置,不需要修改默认模型。全书术语扫描逐批保存;中断后运行相同命令会恢复扫描及已验证译文。自动术语冲突记录在 glossary.json 的 conflicts 中,并保留已有译名,仍需语言复核。
|
||
|
||
```bash
|
||
.venv/bin/pip install -r requirements-dev.txt
|
||
.venv/bin/python -m pytest -q
|
||
.venv/bin/python scripts/corpus_regression.py
|
||
```
|
||
|
||
### Skill + headless QA(推荐)
|
||
|
||
[epub-translate skill](skills/epub-translate/SKILL.md) 将全书术语审读、完整批次翻译、工程检查和截图/语义审校串成闭环。已安装到 Codex 时可用 `$epub-translate`。本轮模型默认 Luna agent;不把 Luna 猜成 API 模型名称,不自动启动旧 Sonnet 任务。原生阅读器是可选补充,桌面锁屏不妨碍本流程。
|
||
|
||
基础 QA 使用项目已有依赖,无需浏览器;可选渲染只增加 Playwright 与 Chromium headless shell:
|
||
|
||
```bash
|
||
.venv/bin/pip install -r requirements-qa.txt
|
||
export PLAYWRIGHT_BROWSERS_PATH="$PWD/.work/playwright"
|
||
.venv/bin/python -m playwright install chromium --only-shell
|
||
.venv/bin/python scripts/headless_qa.py input/book.epub output/translated_book.epub \
|
||
--manifest .work/book/manifest.json --render --out .work/book/headless-qa
|
||
```
|
||
|
||
不加 `--render` 即只做基础审计。Linux 系统运行库和 CJK 字体按部署环境提供。headless 服务仅绑定 loopback,从 EPUB ZIP 读取原样式及资源;书内脚本与外网请求禁用,不用 Calibre/Poppler。渲染器是 Chromium 连续 XHTML,不能代表所有阅读器的分页效果。
|
||
|
||
报告分别保留原书基线与新增问题;核对 OPF 相对路径、完整清单及源 SHA、实际回填文字、目录层级/目标、NAV 直接链接结构、NAV/NCX/书内目录标题和图片/字体摘要。采样截图检查两格缩进、部号字号、横向溢出与坏图,并实际点击注号及可用的返回链接。`visual_review` 和 `semantic_review` 仍为 pending,需由 agent 查看证据后记录验收。
|
||
|
||
尾注分成书内注释、外部入口和非注释目标。例如 House of Huawei 原 EPUB 的 1,099 个注号均跳作者按语,该页指向作者尾注网站;报告明确列为 external_notes_gateway,不能把有效作者按语链接说成书内尾注已验收,也不会误判为翻译新增坏链。
|
||
|
||
Luna agent 的完整测试不调用付费 API:`scripts/agent_book.py prepare/apply/build` 生成全书批次、校验结果摘要并拒绝不完整构建,同时生成中文和双语两版。不同模型使用独立工作目录。批次格式、术语审校及具体命令见 [skill 执行流程](skills/epub-translate/references/workflow.md)。
|
||
|
||
### 可选 Calibre 辅助 QA
|
||
|
||
安装 Calibre 和 Poppler,使 `ebook-convert`、`pdftoppm` 在 PATH 中。翻译主流程自动保存结构审计;加 `--visual-qa` 生成页面截图:
|
||
|
||
```bash
|
||
.venv/bin/python main.py input/book.epub --bilingual --visual-qa
|
||
# 对已有输出检查,默认抽样前 3 个已译章节:
|
||
.venv/bin/python scripts/visual_qa.py input/book.epub output/bilingual_book.epub \
|
||
--manifest .work/book/manifest.json --render --out .work/book/visual-qa
|
||
```
|
||
|
||
QA 输出包括 `report.json`、原文/译文 PNG、Calibre 日志及 `review.html`。`--chapter` 可重复指定 EPUB 内的章节 href;`--max-chapters 0` 检查所有章节,`--pages` 控制截图页数。输出保留源书已经存在的问题,并单独列出新增问题;这是工程审计,不替代 EPUBCheck 的完整标准验证。
|
||
|
||
打开 `review.html` 看对照图,再用 Calibre 阅读 EPUB 检查目录、脚注跳转和实际分页。发现问题后补充可复现测试、修改代码、重新构建并重渲染,记录检查页码和结果。**生成截图不等于视觉通过**,自动报告始终标明 `visual_review: pending`,实际视觉审核写入独立记录。PDF 是 Calibre 转换后的辅助视图,不能代替 EPUB 阅读器验证。
|
||
|
||
Mac 沙箱中 Calibre 的 Qt 渲染可能需要允许进程运行。QA 使用项目目录中的独立 Calibre 配置,参见 [Calibre 环境变量文档](https://manual.calibre-ebook.com/customize.html#environment-variables),避免影响日常书库配置。
|
||
|
||
用子 agent 生成的 Manifest 做离线翻译测试,无需外部 API:
|
||
|
||
```bash
|
||
.venv/bin/python scripts/build_sample.py input/book.epub path/to/agent-translations.json --out .work/sample
|
||
.venv/bin/python scripts/visual_qa.py input/book.epub .work/sample/bilingual-sample.epub \
|
||
--manifest .work/sample/manifest.json --allow-partial --render --out .work/sample/qa
|
||
```
|
||
|
||
`build_sample.py` 只接受与当前原文和占位符完全对应的条目,输出明确标为部分样例。完整架构见 `doc/architecture_flow.md`;本次测试记录见 `doc/QA_2026-10-08.md`。
|
||
|
||
### 中文正文与标题目录
|
||
|
||
中文正文(包括章首段)使用 `2em` 首行缩进;标题、图注、引用和注释保持各自布局。原文段落保留出版社样式。中文段落清除原内联 `text-indent`,以免 `!important` 覆盖中文规则。
|
||
|
||
预处理以目录的目标文件/锚点建立标题映射。每个实际章标题只翻译一次,NAV、NCX、书内目录及阅读器文档标题使用同一结果;目录 href、章节 ID、层级和顺序保留。章号、主标题、副标题分成多个块时,精确匹配相邻标题块并分别回填,不合并 DOM。中文模式把独立章号统一成“第一章”,Part 对应“第一部”;双语模式保留英文标题和目录标签。
|
||
|
||
无法可靠绑定的目录条目仅翻译标签,不改写猜测的章节正文;具体条目记录在 `book_structure.json` 的 `navigation_titles[].binding_note`。这类条目需要检查章节标题是否一致,不能视为全书标题同步已经通过。索引、版权、注释全文仍遵守原有跳过策略;导航中这些页面的名称可以翻译。
|
||
|
||
轻量 PDF/OCR 首版见 [使用说明](doc/PDF_IMPORT.md);后续困难版式见 [路线图](doc/OCR_EPUB_ROADMAP.md)。
|
||
|
||
### 中文封面与书库 metadata(v0.14)
|
||
|
||
新增可选的版本封装步骤,可给已有完整译本补中文封面,无需再调用正文翻译模型。书库标题采用 `中文书名【中文版 · r1】`/`中文书名【中英对照版 · r1】`;封面也必须显示对应版本与修订号。两版使用不同 UUID,原作标识转存 `dc:source`,避免沿用英文版 ISBN/Calibre UUID。原作标题、作者、出版社、日期与生图来源保存在 OPF 的 edition 记录中。本文件标为 AI 译本,不冒用正式中文出版版的译者、出版社或 ISBN。
|
||
|
||
1. 在 edition JSON 固定原作标题/作者(可附标识符)、中文书名、`title_status`、证据网址和 `edition_revision`。正式出版译名优先出版社/国家图书馆记录;找不到时使用 `project`,不得标成权威。`config/editions/gambling-man.json` 采用商周出版译名;`house-of-huawei.json` 暂为项目译名。繁简转换或删改正式译名须另作说明。
|
||
2. 提取参考封面和生图任务:
|
||
|
||
```bash
|
||
.venv/bin/python scripts/localize_edition.py prepare input/book.epub \
|
||
--config config/editions/book.json --mode target_only --work .work/book-cover/chinese
|
||
```
|
||
|
||
3. 由 `epub-translate` skill 调用当前可用生图工具,编辑原封面,另存 PNG/JPEG。分别制作中文版与双语版,版本徽标用朱红/深蓝区分。逐字核对书名、作者、版本徽标和修订号,检查全尺寸与书库缩略图。审查记录须包含实际图片 SHA,示例:
|
||
|
||
```json
|
||
{"cover_sha256":"图片文件的SHA256", "mode":"target_only", "title_zh":"中文书名", "edition_revision":"r1", "visual_review":"passed", "provider":"Codex built-in imagegen", "model":null, "review_notes":"已逐字查看书名、作者及版本徽标"}
|
||
```
|
||
|
||
4. 对**已有译本**封装并审计:
|
||
|
||
```bash
|
||
.venv/bin/python scripts/localize_edition.py apply output/translated_book.epub \
|
||
--config config/editions/book.json --mode target_only \
|
||
--cover .work/book-cover/chinese/cover.png --review .work/book-cover/chinese/review.json \
|
||
--output output/editions/translated_book_r1.epub --work .work/book-cover/chinese
|
||
```
|
||
|
||
原始图片/字体字节保留;新增封面更新 EPUB2 `meta name=cover`、EPUB3 `cover-image` 和 XHTML/SVG 引用;外置 SVG 包装器另存副本。没有封面时新增首个 spine 封面页。修正封面 SVG 强制拉伸,保持图片比例。目录和正文插图保持原样。`edition-qa.json` 包含原/新版差异;headless QA 继续检查封面绑定、图片摘要、metadata、目录和正文完整度。
|
||
|
||
自动流水线可给 `main.py` 或 `scripts/agent_book.py build` 加 `--edition-config config/editions/book.json`。在 JSON 中另加 `covers`:
|
||
|
||
```json
|
||
{"covers":{"target_only":{"image":"../../.work/book-cover/chinese/cover.png","review":"../../.work/book-cover/chinese/review.json"},"bilingual":{"image":"../../.work/book-cover/bilingual/cover.png","review":"../../.work/book-cover/bilingual/review.json"}}}
|
||
```
|
||
|
||
路径相对于 JSON 文件;常规译本保留,另生成 `edition_*.epub`。缺少已审封面会报错,不自动使用另一个版本的图片。基础封装不新增依赖、无网络请求;生图和书目检索由 skill 编排。
|
||
|
||
2026-10-08 接入核实:本机 Codex 使用 ChatGPT 登录,缓存目录没有可选择的 image 模型。官方模型目录提供 `gpt-image-2.5-sunburst`/`gpt-image-2.5-flare`,但[ChatGPT OAuth API 路径暂不支持图片生成](https://developers.openai.com/siwc/token-sharing-open-source/preview-limitations)。本轮实际使用 Codex 内置 imagegen 成功生成两版;该工具不公开模型 ID/选择参数,因此记录 `model: null`,不能宣称使用 GPT-Image-2.5。后续运行先检查当时的官方支持情况和工具能力;不要读取或转用私有 OAuth token 绕过限制,也不自动改用付费 API。
|
||
|
||
### 轻量 PDF → EPUB(独立模块)
|
||
|
||
新增 `scripts/pdf_to_epub.py`,仅安装 `requirements-pdf.txt` 即可独立使用。中文 PDF 直接重排;英文 PDF 先导出 EPUB,再进入现有翻译流程,转换阶段不调用翻译 API。支持文本层、macOS 系统 Vision OCR、可选 Tesseract、逐页恢复、原书签目录和来源锚点。首版限定横排单栏;样本已跑通476页全书,输出仍标为 OCR 重排初稿。
|
||
|
||
```bash
|
||
.venv/bin/pip install -r requirements-pdf.txt
|
||
.venv/bin/python scripts/pdf_to_epub.py input/book.pdf \
|
||
--output output/pdf/book.epub --work .work/pdf-book \
|
||
--language zh-CN --title '书名' --author '作者'
|
||
```
|
||
|
||
独立环境、英文翻译衔接、图片页保留和视觉QA见 [PDF导入使用说明](doc/PDF_IMPORT.md)。
|