Files
epub_bilingual_translator/archive/v0.13/doc/preprocessing_backfill.md
T

7.6 KiB
Raw Blame History

预处理与回填层技术文档

本文档详细描述 EPUB 双语翻译器的预处理(Preprocessing)和回填(Backfill)层的技术方案、数据结构、问题解决方案,用于指导代码开发、调试和维护。


1. 架构概览

┌─────────────┐     ┌────────────────┐     ┌───────────────────┐
│ EPUB 文件   │ ──► │ EpubCleaner    │ ──► │ book_structure.json│
└─────────────┘     └────────────────┘     └───────────────────┘
                           │
                           ▼
                    ┌────────────────┐     ┌───────────────────┐
                    │FineGrainedExt. │ ──► │  manifest.json    │
                    └────────────────┘     └───────────────────┘
                                                   │
                    ┌────────────────┐             │
                    │ BackfillEngine │ ◄───────────┘
                    └────────────────┘
                           │
                           ▼
                    ┌────────────────┐     ┌───────────────────┐
                    │BilingualBuilder│ ──► │  输出 EPUB        │
                    └────────────────┘     └───────────────────┘

2. 目录结构

work/
  ├── {book_name}/              # 每本书独立的工作目录
  │   ├── book_structure.json   # 书籍结构(会被复用)
  │   ├── manifest.json         # 翻译清单(持久化,Source of Truth
  │   └── assets/               # 解压出的 EPUB 资源文件
  │       └── OEBPS/images/...  # 保留原始路径结构
  └── translations/             # (可选) 翻译记忆或其他中间文件

关键设计book_structure.json 默认复用。为避免 UUID 不一致导致回填失败,除非显式指定强制清理,否则程序优先读取现有的结构文件。


3. 数据结构定义

3.1 BookStructure (book_structure.json)

记录书籍的“骨架”,确保翻译后的章节能按正确顺序和层级重组。

{
  "metadata": {
    "title": "书名",
    "author": "作者",
    "language": "en",
    "identifier": "ISBN或UUID"
  },
  "spine": ["item_id_1", "item_id_2", ...],  // 阅读顺序
  "resources": {
    "item_id_1": {
      "href": "OEBPS/chapter1.xhtml",
      "media_type": "application/xhtml+xml",
      "content": "<html>...</html>",  // 清理并注入ID后的HTML内容
      "properties": "nav"
    },
    ...
  }
}

3.2 ManifestEntry (manifest.json)

翻译清单是全生命周期的核心,记录了所有待翻译段落的状态。

[
  {
    "entry_id": "OEBPS/c3Z.xhtml#uuid-603ff3fb",
    "file_path": "OEBPS/c3Z.xhtml",
    "element_id": "uuid-603ff3fb",
    "original_text": "φ1φHelloφ/1φ world.",
    "placeholders": {
      "1": "<b>",
      "/1": "</b>",
      "_prefix": "<p>",
      "_suffix": "</p>"
    },
    "translated_text": "φ1φ你好φ/1φ 世界。",
    "context": "body"
  }
]
字段 类型 说明
entry_id str 全局唯一ID (file_path#element_id),用于精准追踪。
file_path str 标识该段落属于哪一章,用于按章分组批处理。
element_id str HTML DOM 元素的 ID,回填时的锚点。
original_text str 经过智能抽提和占位符化后的文本,发送给 LLM。
placeholders Dict 格式映射表,用于还原 HTML 结构。
translated_text str 翻译结果(含占位符),初始为 null。

4. 预处理与抽提流程 (Extraction)

流程由 FormatExtractor 驱动,分为三个阶段:

Step 1: 结构索引 (Structure Indexing)

  • 动作: 解析 OPF 文件,提取 Spine 和 Metadata。
  • 目的: 建立骨架,确定处理顺序。

Step 2: 语义识别 (Semantic Detection)

  • 动作: 使用 HeadingDetector 分析 DOM 节点。
  • 逻辑:
    • 匹配 h1-h6 正则,区分 Chapter(章)与 Section(节)。
    • 识别 blockquote 或特定 class 判定 Epigraph(引言)。
  • 目的: 为 LLM 提供差异化的 Prompt(例如翻译标题时不要加句号)。

Step 3: 智能抽提 (Smart Extraction - _smart_extract_v3)

这是核心算法,将 HTML 转换为“纯文本+占位符”。

  1. 首尾分离 (Prefix/Suffix Separation):

    • 将包裹文本的外层标签(如 <p>, div)剥离到 _prefix_suffix
    • 目的: 极大减少 LLM 输入 Token,且防止 LLM 随意修改外层布局。
  2. 首字下沉处理 (Drop Cap Handling):

    • 检测并合并被 <span> 单独包裹的首字母(如 <span class="drop">O</span> + nceOnce)。
    • 目的: 修复语意割裂,让 LLM 看到完整的单词。
  3. 占位符化 (Placeholder Mapping):

    • 将内联标签(<a>, <em>)或公式替换为短码 φIDφ
    • 目的: 保护 HTML 属性不被“翻译”,降低噪声干扰。
  4. 完整性校验 (Integrity Check):

    • 逻辑: 抽提后的文本(去占位符)与原始纯文本进行归一化比对,要求覆盖率 100%
    • 兜底: 若校验失败(如误删内容),回退到简单模式(只剥离首尾标签)。

5. 构建与回填流程 (Backfill & Build)

5.1 翻译回填

  • 根据 entry_id 找到对应的 DOM 节点。
  • 使用 FormatRestorertranslated_text 中的占位符(φ1φ)还原为原始 HTML 标签(<b>)。
  • 根据模式(双语/单语)决定将新节点插入到原文后还是替换原文。

BilingualBuilder 中执行:

  1. ID 补全: 为缺失 ID 的 TOC 节点自动生成 UUID。
  2. 死链检测: 检查 TOC/Nav 指向的文件是否存在。
  3. 模糊修复: 尝试通过文件名后缀匹配(解决路径前缀变更问题)或特定重定向(如 c0.xhtml -> cover.xhtml)。
  4. 坏死剔除: 无法修复的死链将从目录中移除。

5.3 CSS 样式恢复

EbookLib 默认可能会重写 <head> 导致样式丢失。

  • 逻辑:
    • 收集所有 CSS 资源。
    • 在构建每个 HTML Item 时,显式计算 HTML 到 CSS 的相对路径
    • 强制调用 item.add_link(..., rel='stylesheet', type='text/css') 注入引用。

6. 常见问题排查

6.1 UUID 不匹配

现象: WARNING - Element uuid-xxx not found. 原因: 手动删除了 book_structure.json 但保留了 manifest.json,导致重新生成的 HTML ID 与清单记录不一致。 解决: 清空 work/BookName 目录重新运行,或确保两个 JSON 文件版本一致。

6.2 样式丢失

现象: 打开书面目全非,只有黑白文字。 检查: 解压 EPUB,查看 HTML <head> 是否有 <link rel="stylesheet">。如果没有,检查 BilingualBuilder 的 Step 4 逻辑。

6.3 翻译错位

现象: 译文出现在了错误的位置。 检查: 确认 entry_id 生成逻辑是否包含文件名,且文件名在处理过程中未被意外修改。