news 2026/10/4 8:14:03

TranslateBooksWithLLMs PDF翻译能力解析:标题、表格与字体如何被保留

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
TranslateBooksWithLLMs PDF翻译能力解析:标题、表格与字体如何被保留

TranslateBooksWithLLMs PDF翻译能力解析:标题、表格与字体如何被保留

【免费下载链接】TranslateBooksWithLLMsTranslate full-length books and documents with Ollama, OpenAI-compatible, Gemini, Mistral, DeepSeek, Poe or OpenRouter. Preserves formatting. Resumes where you left off. No file size limits.项目地址: https://gitcode.com/gh_mirrors/tr/TranslateBooksWithLLMs

TranslateBooksWithLLMs 是一款用大语言模型(LLM)整本翻译书籍与文档的桌面工具,支持的格式包括 EPUB、SRT、DOCX、PDF 和 TXT。它的 PDF 翻译能力采用“重排式输出”:原文 PDF 被解析成段落与结构单元,交给大模型翻译后,再生成一份新的、排版重排的 PDF——标题、表格、字体三大要素在这条流水线中被尽量保留。📄

PDF翻译是如何一步步工作的

整条流水线分三步,核心代码集中在 src/core/pdf/ 目录下:

  1. 提取:extractor.py 用 PyMuPDF 把 PDF 拆成段落列表,同时记录每段的样式(标题级别、列表、表格单元格)、格式(颜色、字体族、加粗)、背景色块与表格结构,统一存入 content.py 中的PdfPlainContent数据模型。
  2. 翻译:段落直接复用项目的纯文本翻译管线 plain_text_pipeline.py,天然支持断点续翻与并行分块。
  3. 重建:builder.py 把译文段落拼装成 HTML + CSS,通过 PyMuPDF 的 Story/DocumentWriter 渲染成与原文同页宽的新 PDF。

需要特别说明:它保留的是结构属性(标题、表格、字体、颜色、色块、图片锚点),而不是原始版式——页面上的每一行都可能在新的页面上重新流动。这也是为什么多栏排版只算“尽力而为”。

标题识别:字号比例三级判级

标题识别是提取器里最“聪明”的一环,逻辑在 extractor.py 的_block_style函数中:

  • 先算正文基准字号:统计全文所有保留文本块的字符加权主字号,作为“body size”。
  • 再按字号比例判级(阈值定义见 extractor.py):
判定结果条件
heading1字号 ≥ 正文 1.6 倍,且不超过 200 字符
heading2字号 ≥ 正文 1.3 倍
heading3字号 ≥ 正文 1.15 倍
加粗兜底整段加粗、不超 80 字符、不超过 2 行且不以句末标点结尾

还有一个容易忽略的细节:标题块拆分。当同一个文本块内相邻行的字号比值达到 1.15 倍(SIZE_SPLIT_RATIO),或主色明显不同,就会强制拆成多个子块——这样“眉题 + 大标题 + 副标题”三种层次能各自获得正确的样式,而不会糊在一起。

到了重建阶段,builder 会把三类标题映射为<h1>/<h2>/<h3>,分别以 20pt、16pt、13pt 的无衬线粗体输出,标题的层级感在译文 PDF 中完整再现。

表格重建:连“只有横线”的表格也能认出

表格检测独立在 layout.py 中,识别两类来源:

  1. 全边框表格:直接调用 PyMuPDF 自带的page.find_tables(),保留行列数 ≥ 2 的表格。
  2. 横线网格表格:这是为现代网页打印 PDF 专门做的适配——无头 Chrome/Skia 打印时会把每个单元格的border-bottom画成一小段独立填充矩形。检测器从page.get_drawings()中收集这些细横线段,把共享相同列边界的横线聚成“网格”,再结合表头底色或表格上方文字确定顶边,最后用显式行列模式精确抽出每个单元格。

抽出表格后发生两件事:

  • 每个非空单元格成为独立翻译单元,样式标记为"cell",空单元格记为占位,保证译文表与原表行列一一对应(见 content.py 的PdfTable结构)。
  • 表头识别与底色保留:表头行的背景色、各列的相对宽度都被记录,重建时表头单元格加粗并保留底色,列宽按比例换算为绝对 pt 宽度还原。

字体保留:名称、标志位与 Type3 三重解析

字体相关逻辑集中在 styling.py,目标是把 PDF 里五花八门的字体名归类为三个通用族:serif(衬线)、sans-serif(无衬线)、monospace(等宽)。

解析策略按优先级:

  1. 字体名关键词:命中mono/courier/menlo…判等宽,sans/helvetica/arial/calibri…判无衬线,serif/times/georgia…判衬线;
  2. PyMuPDF 字形标志位:名称无法识别时,回退到 span flags(位 4 = 衬线、位 8 = 等宽、位 16 = 粗体、位 2 = 斜体);
  3. Type3 字体穿透:浏览器打印的 PDF 常用Type3 (16 0 R)这种引用名,FontResolver会顺着 FontDescriptor 找到真实字体名(如IBM-Plex-Sans-Bold),从而正确识别粗体与字体族。

除此之外,每个段落还会记录文字颜色、整段加粗/斜体、背景色块(带左侧色条的 callout 提示框)。builder 在重建时把这些信息转成内联 CSS,正文整体字体族则取全文段落的主导值(default_font_family),写进样式表的body规则——所以即使个别段落字体未知,整本书的“字体气质”也保持一致。

使用指南与已知限制

用命令行翻译一份 PDF 只需一行:

python translate.py -i paper.pdf -tl French

输出会自动命名为paper (French).pdf,详见 docs/CLI.md。Web 界面中则直接拖入.pdf即可,翻译任务中途暂停后可随时从断点继续(见文章开头截图)。

⚠️ 新手使用前的几个提示:

  • 仅支持文字型 PDF:扫描件会明确报错(不做 OCR),带密码的 PDF 在上传时即被拒绝。
  • 原文版式不保留:输出是重排的新 PDF,多栏、脚注等复杂排版是尽力而为。
  • 句内格式不保留:加粗、颜色只按“整段”粒度保留,句子中间的局部强调会丢失。
  • 暂不支持润色:--refine对 PDF 会给出警告并忽略,详见 docs/BACKLOG.md。

如果你想了解这项能力的设计取舍,项目保留了完整的规划文档:BLUEPRINT_PdfSupport.md(基础能力)与 BLUEPRINT_PdfFormattingA.md(表格、色块与字体保真),回归测试则在 tests/test_pdf/ 中覆盖了解析与重建的往返一致性。

【免费下载链接】TranslateBooksWithLLMsTranslate full-length books and documents with Ollama, OpenAI-compatible, Gemini, Mistral, DeepSeek, Poe or OpenRouter. Preserves formatting. Resumes where you left off. No file size limits.项目地址: https://gitcode.com/gh_mirrors/tr/TranslateBooksWithLLMs

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/4 8:13:12

从零搭建AI工程体系:数据、特征、训练、服务全链路实战

1. 从零搭建AI工程体系&#xff0c;为什么我劝你别急着调包"ai-engineering-from-scratch"这个标题&#xff0c;第一次看到的时候我愣了一下。市面上讲AI的教程铺天盖地&#xff0c;但绝大多数都是教你import torch然后跑个预训练模型&#xff0c;或者调个API接口就完…

作者头像 李华
网站建设 2026/10/4 8:13:03

Orca:面向AI代理的开源并行运行时与ADE执行引擎

1. Orca不是鲸鱼&#xff0c;而是AI代理调度的“交通指挥中心”Orca这个名字&#xff0c;第一眼容易让人联想到海洋哺乳动物——毕竟orca就是虎鲸的学名。但在这个语境下&#xff0c;它和水下生物毫无关系。Orca是一个开源项目&#xff0c;核心定位是AI代理&#xff08;Agent&a…

作者头像 李华
网站建设 2026/10/4 8:10:40

Obsidian+WorkBuddy+Gitee构建本地知识闭环

1. 为什么“Obsidian WorkBuddy Gitee”不是又一个工具堆砌方案&#xff0c;而是知识闭环的最小可行结构你可能已经看过太多“用XX搭建个人知识库”的教程&#xff1a;Obsidian打底、加几个插件、再连个Notion或语雀同步——结果三个月后笔记散落在五个地方&#xff0c;搜索失…

作者头像 李华
网站建设 2026/10/4 8:10:37

AI Agent 沙箱隔离实战:进程、文件、网络与权限的围栏设计

1. 为什么一个能干活的 Agent 反而更需要"围栏"很多人第一次接触 AI Agent 的时候&#xff0c;脑子里想的都是"怎么让它更聪明、能调更多工具、能自己写代码跑命令"。但真正把 Agent 放到生产环境里跑过一轮的人&#xff0c;关注点会迅速从"能力"…

作者头像 李华
网站建设 2026/10/4 8:07:50

51单片机矩阵键盘与LCD1602协同驱动原理与实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/4 8:04:27

COMSOL单通道非绝热逆流SOFC模型搭建与调试全解析

做SOFC仿真的朋友应该都体会过这种尴尬&#xff1a;模型物理场全选了&#xff0c;参数也填了&#xff0c;一跑就发散&#xff1b;或者算出来了&#xff0c;但电流密度分布跟文献对不上&#xff0c;温度场更是离了大谱。这篇东西想分享的是我在COMSOL里把单通道、非绝热、逆流这…

作者头像 李华