# pdftr **Repository Path**: chise0519/pdftr ## Basic Information - **Project Name**: pdftr - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-25 - **Last Updated**: 2026-08-27 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # pdftr — PDF 1:1 排版复刻翻译系统 把英文技术 PDF(芯片手册 / datasheet / 开发指南)翻译成简体中文, **翻译后页面布局、图片、表格框线与原版像素级一致**,仅文字在原位置替换为中文。 全链路本地运行:解析/重绘在本机,翻译走局域网 GPU 大模型,文档不出内网。 ``` 输入: RTL8380M datasheet (103页/1940块) 输出: 同布局中文版 ┌────────────────────────┐ ┌────────────────────────┐ │ TABLE 1. PIN ASSIG... │ │ 表1. 引脚分配表(RTL...) │ │ Name Pin No. Type │ pdftr │ 名称 引脚号 类型 │ │ P2MDIBP 1 AI/O │ ───────────> │ P2MDIBP 1 AI/O │ │ ............ 11 │ │ ············· 11 │ └────────────────────────┘ └────────────────────────┘ 原样: 图片/框线/点线/页码 替换: 文字(坐标/字号/颜色不变) ``` 非文字区域像素 diff = 0.0000。 ## 功能特性 - **行级重绘** — 提取按块(保留翻译上下文),重绘按行:每行用原版 基线位置、字号、颜色写回;超宽自动缩字号,不破坏行结构。 - **目录复原** — 章节号/标题/页码三段原位;页码右对齐; 标题与页码间自动补画点线;逐条目独立翻译,杜绝跨条目串行。 - **表格逐格翻译** — 同基线多单元格自动识别为表格块,逐格独立 翻译防串列;引脚类型缩写(AI/AO/I/OPU/RESERVED...)白名单原样保留。 - **小节标题锚点** — "3.3. xxx" 形式标题编号精确定位,前缀不丢。 - **OCR 校验** — 每页翻译后 RapidOCR 渲染识别,与期望译文逐块比对; 不符自动重翻一次并复检,结果记入 blocks.json(`ocr_ok`/`ocr_sim`)。 - **增量进度** — 翻译前预统计全部块数;每翻完一页立即落盘, 网页端已译页实时可见,无需等整本完成。 - **翻译健壮性** — 批量协议(等长校验)+二分重试+单块降级; 防回显(输出全等于原文视为失败);连接池真并发;`/no_think` 防思考截断。 - **Web 双页界面** — 翻译工作台(任务/进度/下载)与对照查看器 (左右分栏、块级点击对照、缩放翻页)解耦,互不干扰。 ## 架构 ``` pdftr CLI ──┐ ├─> libpdftr.so (MuPDF 1.28: 块/行提取、redaction、中文重绘、渲染) pdftr-web ──┘ │ │ libllmclient (OpenAI 协议, 连接池并发, 批协议+二分重试+降级) │ │ 原生JS前端 OpenAI 兼容端点 ──> 本地/局域网 GPU 推理服务 (当前: Qwen3-8B-Q4_K_M) └── web/tools/ocr_verify.py (RapidOCR 译后校验, 独立进程) ``` 组件: - `core/` — libpdftr:PDF 引擎(提取/redact/重绘/渲染/点线补画) - `llm/` — libllmclient:LLM 客户端(连接池/批协议/防回显) - `cli/` — pdftr 命令行(translate / check / preview) - `web/` — pdftr-web(cpp-httplib 服务端 + 原生 JS 前端 + OCR 校验脚本) - `third_party/` — MuPDF 1.28.2 源码(-fPIC)、nlohmann/json、 cpp-httplib、spdlog(均已就绪,开箱即编) - `fonts/` — NotoSansCJKsc 中文重绘字体 ## 快速开始 ### 1. 构建 ```bash # 依赖已在 third_party/ 就绪, 无需额外安装 cd build && cmake .. && make -j8 # 产物: libpdftr.so, pdftr(CLI), pdftr-web ``` ### 2. 准备 LLM 端点与 OCR ```bash # 任一 OpenAI 兼容推理服务均可 (vLLM/llama.cpp-server/...) # 例: llama.cpp server 跑翻译模型 llama-server -m Qwen3-8B-Q4_K_M.gguf --port 8080 # OCR 校验 (可选, 无则自动跳过) pip install rapidocr-onnxruntime pillow numpy ``` ### 3. 配置 config.json ```json { "endpoint": "http://127.0.0.1:8080/v1", "model": "Qwen3-8B-Q4_K_M.gguf", "fontfile": "fonts/NotoSansCJKsc-Regular.otf", "min_fontsize": 4.0, "concurrency": 4, "system_prompt": "你是硬件文档翻译专家。硬件/芯片/寄存器/协议名词保留英文不翻译..." } ``` | 键 | 说明 | |---|---| | endpoint / model | LLM OpenAI 兼容端点与模型名 | | fontfile | 中文重绘字体 (NotoSansCJK 推荐) | | min_fontsize | 溢出缩字号下限 (默认 4pt) | | max_batch_texts / max_batch_chars | 批量切分阈值 | | concurrency | LLM 并发连接数 (连接池大小) | | system_prompt | 翻译提示词 (硬件术语保留英文) | ### 4. 使用 **CLI:** ```bash ./build/pdftr check --config config.json # 检查端点连通 ./build/pdftr preview input.pdf --page 6 -o p.png # 渲染页面 ./build/pdftr translate input.pdf -o out_zh.pdf \ --pages 5-9,12 --config config.json \ --blocks-json out_blocks.json # 翻译(指定页) ``` **Web:** ```bash ./build/pdftr-web --config config.json --port 9600 # 工作台: http://:9600/ 上传/进度/下载 # 对照页: http://:9600/compare.html 左右分栏对照 ``` - 翻译中即可实时查看已译页(未译页显示占位) - `compare.html?job=` 直达任务;也可上传 原文+译文(+blocks.json) 纯对照 ### 5. 产物 ``` out_zh.pdf 译文 (与原版同页数同布局) out_blocks.json 双语映射: 每块 {src, dst, bbox, font_size, ocr_ok, ocr_sim, lines[]} ``` ## 两条独立工作流 **A. 翻译** — 原文 PDF → 译文 PDF + 双语映射(CLI 或 Web)。 **B. 对照** — 已有 原文+译文(+可选映射) → Web 上传对照模式, 纯查看不翻译:左右分栏同步滚动,译文页点击文本块 → 显示该块 原文/译文,↑↓ 遍历块,←→ 翻页。 ## 适用范围 ✅ **擅长**: 原生电子版 PDF(datasheet/芯片手册/技术规格/应用笔记)、 密集表格(引脚表/寄存器表)、目录结构复杂的长文档、含大量框图的文档。 ⚠️ **局限**: - 扫描版/图片 PDF 需先 OCR 成带文本层 PDF(RapidOCR 在本项目仅用于译后校验) - 文字转曲线的图纸 PDF 无法处理 - 斜排/旋转文字跳过 - 译文统一 NotoSansCJK(字号/颜色/位置还原,字体本身不还原) - 复杂多栏混排偶有阅读序错乱 ## 技术要点 (踩坑记录) **坐标系两个陷阱**: 1. stext 块/行坐标是左上原点,而 `fz_fill_text` 走 PDF 左下原点, 绘制需 `y' = page_h - y`。 2. `pdf_set_annot_rect` 内部已做页面变换,期望左上原点坐标—— 再手动翻转会双重翻转,redaction 框错位。 **字体名冲突**(pdf device 陷阱): pdf device 固定用 `/F0..` 写字体 资源,与原页同名字体互毁;内容流不支持流级 Resources(XObject 特权)。 方案:设备写独立 dict → 关闭后统一改名 `/PDFTRF%d` 合并进页面 `/Font`,内容流同步替换字体名。 **增量保存 vs 垃圾回收**: `pdf_save_document(do_garbage=3)` 会清扫 内存 xref,使 `pdf_add_cid_font` 的字体缓存引用悬空,后续页字体变 null。方案:翻译中逐页用 `do_incremental` 追加保存,全部完成后 全量+垃圾回收收尾。 **原文移除**: 每块创建 Redact 注释,`pdf_redact_page` 应用时 `image_method=NONE, line_art=NONE` —— 图片与矢量线零损伤, 输出文本层为干净中文(非涂白遮盖)。 ## 目录结构 ``` core/ PDF 引擎 (include/pdftr/ + src/) llm/ LLM 客户端库 cli/ 命令行入口 web/ Web 服务 (src/server.cpp + static/ + tools/ocr_verify.py) fonts/ 中文字体 third_party/ MuPDF 等依赖 (源码, 开箱即编) build/ 构建产物 (gitignore) jobs/ Web 任务数据 (gitignore) proto/ 原型验证脚本 (gitignore) docs/ 文档 ``` ## License 内部工具,未定开源协议。