openakita/skills@translate-pdf
Translate PDF documents while preserving original layout, styling, tables, images, and formatting. Supports Simplified Chinese, Traditional Chinese, English, Japanese, Korean, and more. Page-by-page translation with structure preservation.
Packaged view
This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.
Install command
npx @skill-hub/cli install openakita-openakita-translate-pdf
Repository
Skill path: skills/translate-pdf
Translate PDF documents while preserving original layout, styling, tables, images, and formatting. Supports Simplified Chinese, Traditional Chinese, English, Japanese, Korean, and more. Page-by-page translation with structure preservation.
Open repositoryBest for
Primary workflow: Ship Full Stack.
Technical facets: Full Stack.
Target audience: everyone.
License: MIT.
Original source
Catalog source: SkillHub Club.
Repository owner: openakita.
This is still a mirrored public skill entry. Review the repository before installing into production workflows.
What it helps with
- Install openakita/skills@translate-pdf into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
- Review https://github.com/openakita/openakita before adding openakita/skills@translate-pdf to shared team environments
- Use openakita/skills@translate-pdf for development workflows
Works across
Favorites: 0.
Sub-skills: 0.
Aggregator: No.
Original source / Raw SKILL.md
---
name: openakita/skills@translate-pdf
description: Translate PDF documents while preserving original layout, styling, tables, images, and formatting. Supports Simplified Chinese, Traditional Chinese, English, Japanese, Korean, and more. Page-by-page translation with structure preservation.
license: MIT
metadata:
author: openakita
version: "1.0.0"
---
# Translate PDF — PDF 文档翻译
## When to Use
- 用户需要将英文 PDF 翻译为中文(或其他语言)
- 需要保留 PDF 的原始排版、表格、图片和格式
- 需要翻译学术论文、技术文档、商业报告
- 需要双语对照的 PDF 输出
- 需要批量翻译多个 PDF 文件
---
## Prerequisites
### 必需依赖
| 依赖 | 用途 | 安装方式 |
|------|------|---------|
| Python ≥ 3.10 | 运行翻译脚本 | 系统预装 |
| `PyMuPDF` (fitz) | PDF 解析与重建 | `pip install PyMuPDF` |
| `httpx` | HTTP API 调用 | `pip install httpx` |
### 可选依赖
| 依赖 | 用途 | 安装方式 |
|------|------|---------|
| `pdf2image` | PDF 转图片(OCR 场景) | `pip install pdf2image` |
| `pytesseract` | OCR 文字识别 | `pip install pytesseract` |
| `pdfplumber` | 表格提取 | `pip install pdfplumber` |
| `reportlab` | PDF 生成 | `pip install reportlab` |
| `deep-translator` | 多引擎翻译 | `pip install deep-translator` |
| `openai` | GPT 翻译 | `pip install openai` |
### 系统级依赖
| 工具 | 用途 | 说明 |
|------|------|------|
| Poppler | pdf2image 的后端 | Windows: 下载 poppler-utils; macOS: `brew install poppler` |
| Tesseract | OCR 引擎 | Windows: 下载安装包; macOS: `brew install tesseract` |
| 中文字体 | PDF 中文渲染 | 系统需安装中文字体(微软雅黑、思源黑体等) |
### 验证安装
```bash
python -c "import fitz; print('PyMuPDF', fitz.version)"
python -c "import pdfplumber; print('pdfplumber OK')"
```
### LLM API 配置
翻译引擎首选 LLM(GPT-4 / Claude),在 `.env` 中配置:
```
OPENAI_API_KEY=sk-xxxxx
```
如果未配置 LLM API,将回退到 `deep-translator`(Google Translate / DeepL)。
---
## Instructions
### 支持的语言
| 语言代码 | 语言 | 翻译质量 |
|---------|------|---------|
| `zh-CN` | 简体中文 | ★★★★★ |
| `zh-TW` | 繁体中文 | ★★★★★ |
| `en` | 英文 | ★★★★★ |
| `ja` | 日文 | ★★★★ |
| `ko` | 韩文 | ★★★★ |
| `fr` | 法文 | ★★★★ |
| `de` | 德文 | ★★★★ |
| `es` | 西班牙文 | ★★★★ |
| `ru` | 俄文 | ★★★ |
| `ar` | 阿拉伯文 | ★★★ |
### 翻译引擎优先级
| 优先级 | 引擎 | 特点 |
|--------|------|------|
| 1 | LLM (GPT-4/Claude) | 最高质量,理解上下文,术语一致 |
| 2 | DeepL API | 高质量机器翻译 |
| 3 | Google Translate | 免费,覆盖语种广 |
Agent 按照优先级自动选择可用的翻译引擎。用户可以指定使用特定引擎。
### PDF 元素处理策略
| 元素 | 处理方式 |
|------|---------|
| 正文文本 | 翻译并保留字体大小、颜色、粗体/斜体 |
| 标题 | 翻译并保留层级和样式 |
| 表格 | 翻译单元格内容,保留表格结构 |
| 图片 | 保留原图不动 |
| 图片中的文字 | 可选 OCR 识别后翻译 |
| 页眉/页脚 | 翻译并保持位置 |
| 页码 | 保持不变 |
| 脚注/尾注 | 翻译内容,保留编号 |
| 目录 | 翻译条目,页码不变 |
| 书签 | 翻译标题 |
| 链接/URL | 保持不变 |
| 数学公式 | 保持不变 |
| 代码块 | 保持不变(仅翻译注释) |
| 水印 | 保留原样 |
---
## Workflows
### Workflow 1: 标准 PDF 翻译
**步骤 1 — 解析 PDF 结构**
```python
import fitz
doc = fitz.open("input.pdf")
print(f"总页数: {doc.page_count}")
print(f"元数据: {doc.metadata}")
for page_num in range(min(3, doc.page_count)):
page = doc[page_num]
text = page.get_text("dict")
print(f"第 {page_num + 1} 页: {len(text['blocks'])} 个文本块")
```
**步骤 2 — 逐页提取文本块**
```python
def extract_text_blocks(page):
"""提取页面中所有文本块及其位置和样式"""
blocks = []
text_dict = page.get_text("dict")
for block in text_dict["blocks"]:
if block["type"] == 0: # text block
for line in block["lines"]:
for span in line["spans"]:
blocks.append({
"text": span["text"],
"bbox": span["bbox"],
"font": span["font"],
"size": span["size"],
"color": span["color"],
"flags": span["flags"],
})
return blocks
```
**步骤 3 — 批量翻译**
将提取的文本按段落分组,批量发送给翻译引擎:
```python
async def translate_blocks(blocks, target_lang="zh-CN"):
paragraphs = merge_spans_to_paragraphs(blocks)
translated = []
for batch in chunk_list(paragraphs, batch_size=20):
texts = [p["text"] for p in batch]
results = await batch_translate(texts, target_lang)
translated.extend(results)
return translated
```
**LLM 翻译 Prompt**
```
你是一位专业的文档翻译师。请将以下文本从{source_lang}翻译为{target_lang}。
要求:
1. 保持专业术语的准确性和一致性
2. 保持段落结构不变
3. 对于技术术语,首次出现时附上原文:如"卷积神经网络(CNN)"
4. 不翻译代码、公式、URL、人名(除非有通用中文译名)
5. 保持原文的语气和风格
待翻译文本:
---
{text}
---
```
**步骤 4 — 重建 PDF**
```python
def rebuild_pdf(original_doc, translated_blocks, output_path):
"""用翻译后的文本替换原文,保留排版"""
new_doc = fitz.open()
for page_num in range(original_doc.page_count):
orig_page = original_doc[page_num]
new_page = new_doc.new_page(
width=orig_page.rect.width,
height=orig_page.rect.height
)
# 复制图片和非文本元素
new_page.show_pdf_page(new_page.rect, original_doc, page_num)
# 覆盖原文区域并写入译文
for block in translated_blocks[page_num]:
rect = fitz.Rect(block["bbox"])
new_page.draw_rect(rect, color=None, fill=(1, 1, 1))
new_page.insert_textbox(
rect,
block["translated_text"],
fontsize=block["size"] * 0.85,
fontname="china-ss",
align=fitz.TEXT_ALIGN_LEFT
)
new_doc.save(output_path)
```
**步骤 5 — 质量检查**
翻译完成后执行自动检查:
- 页数与原文一致
- 无空白页面
- 翻译覆盖率(已翻译文本 / 总文本 ≥ 95%)
- 字体渲染正常
---
### Workflow 2: 双语对照 PDF
生成左右/上下对照的双语 PDF:
**布局选项**
| 布局 | 说明 | 适用场景 |
|------|------|---------|
| 左右对照 | 左页原文、右页译文 | 学术论文、对比审阅 |
| 上下对照 | 段落级交替显示 | 学习材料 |
| 注释模式 | 译文作为侧边注释 | 保留原文为主 |
```python
def create_bilingual_pdf(original_doc, translated_blocks, output_path, layout="side-by-side"):
new_doc = fitz.open()
for page_num in range(original_doc.page_count):
orig_page = original_doc[page_num]
if layout == "side-by-side":
new_width = orig_page.rect.width * 2
new_page = new_doc.new_page(
width=new_width,
height=orig_page.rect.height
)
# 左侧放原文
new_page.show_pdf_page(
fitz.Rect(0, 0, orig_page.rect.width, orig_page.rect.height),
original_doc, page_num
)
# 右侧放译文
insert_translated_page(
new_page,
translated_blocks[page_num],
offset_x=orig_page.rect.width
)
new_doc.save(output_path)
```
---
### Workflow 3: 扫描版 PDF 翻译(OCR)
处理扫描件或图片型 PDF:
**步骤 1 — 检测 PDF 类型**
```python
def is_scanned_pdf(doc):
"""检测 PDF 是否为扫描件"""
for page_num in range(min(3, doc.page_count)):
page = doc[page_num]
text = page.get_text().strip()
images = page.get_images()
if not text and images:
return True
return False
```
**步骤 2 — OCR 识别**
```python
from pdf2image import convert_from_path
import pytesseract
images = convert_from_path("scanned.pdf", dpi=300)
for i, img in enumerate(images):
text = pytesseract.image_to_string(img, lang='eng')
# 使用 image_to_data 获取文字位置信息
data = pytesseract.image_to_data(img, lang='eng', output_type=pytesseract.Output.DICT)
```
**步骤 3** — 对 OCR 结果执行 Workflow 1 的翻译和重建流程
---
### Workflow 4: 批量 PDF 翻译
```python
import glob
import asyncio
async def batch_translate_pdfs(input_dir, output_dir, target_lang="zh-CN"):
pdf_files = glob.glob(f"{input_dir}/*.pdf")
print(f"发现 {len(pdf_files)} 个 PDF 文件")
for pdf_path in pdf_files:
output_path = os.path.join(
output_dir,
os.path.basename(pdf_path).replace('.pdf', f'_{target_lang}.pdf')
)
print(f"翻译: {pdf_path} -> {output_path}")
await translate_single_pdf(pdf_path, output_path, target_lang)
```
---
## Output Format
### 文件命名
```
{原文件名}_{目标语言}.pdf
```
示例:
- `research_paper_zh-CN.pdf`(翻译版)
- `research_paper_bilingual.pdf`(双语版)
### 输出报告
```
📄 PDF 翻译完成
- 原文件:research_paper.pdf (25 页)
- 译文件:research_paper_zh-CN.pdf (25 页)
- 源语言:English → 目标语言:简体中文
- 翻译引擎:GPT-4
- 翻译覆盖率:98.5%
- 表格数量:12 个(已翻译)
- 图片数量:8 张(已保留)
- 耗时:3 分 42 秒
- 费用估算:$0.85
```
---
## Common Pitfalls
### 1. 中文字体缺失导致乱码
**症状**:翻译后的 PDF 中文显示为方框或乱码
**解决**:确保系统安装了中文字体,并在 PyMuPDF 中注册:
```python
import fitz
# PyMuPDF 支持的中文字体
# "china-ss" = 思源宋体 (简体)
# "china-ts" = 思源宋体 (繁体)
# 或使用自定义字体
page.insert_font(fontname="custom-zh", fontfile="/path/to/NotoSansCJK-Regular.ttf")
```
### 2. 表格翻译后错位
**症状**:表格内容溢出单元格
**原因**:中文译文通常比英文短,但某些情况下可能更长
**解决**:
- 动态调整字体大小以适应单元格
- 允许文本自动换行
- 对于复杂表格,使用 pdfplumber 提取后单独翻译
### 3. 数学公式被错误翻译
**症状**:公式被当作文本翻译
**解决**:在翻译前识别并标记数学公式区域,跳过翻译:
```python
import re
def should_skip_translation(text):
"""判断文本是否应跳过翻译"""
# 数学公式模式
if re.match(r'^[\s\d\+\-\*\/\=\(\)\[\]\{\}\^\_\\\$]+$', text):
return True
# LaTeX 公式
if text.strip().startswith('\\') and not text.strip().startswith('\\text'):
return True
# 代码块
if re.match(r'^(def |class |import |from |const |let |var |function )', text.strip()):
return True
return False
```
### 4. 大文件内存溢出
**症状**:处理超过 100 页的大型 PDF 时内存不足
**解决**:逐页处理而非一次性加载:
```python
for page_num in range(doc.page_count):
page = doc[page_num]
# 处理当前页
process_page(page)
# 释放内存
page = None
```
### 5. OCR 识别率低
**症状**:扫描版 PDF 的文字识别错误多
**解决**:
- 提高扫描 DPI(≥ 300)
- 预处理图片(二值化、去噪、倾斜校正)
- 使用语言包:`pytesseract.image_to_string(img, lang='eng+chi_sim')`
### 6. 翻译术语不一致
**症状**:同一术语在不同页面有不同翻译
**解决**:
- 第一遍扫描时建立术语表
- 将术语表作为上下文传递给 LLM
- 翻译后用脚本检查术语一致性
```python
glossary = {
"machine learning": "机器学习",
"neural network": "神经网络",
"gradient descent": "梯度下降",
"backpropagation": "反向传播",
}
```
### 7. 页眉页脚重复翻译
**症状**:每页的页眉页脚翻译结果微有差异
**解决**:先识别页眉页脚模式,统一翻译一次后应用到所有页面
---
## 高级配置
### 翻译质量等级
| 等级 | 方式 | 速度 | 质量 | 费用 |
|------|------|------|------|------|
| 快速 | Google Translate | ★★★★★ | ★★★ | 免费 |
| 标准 | DeepL | ★★★★ | ★★★★ | $$ |
| 专业 | GPT-4 | ★★★ | ★★★★★ | $$$ |
| 人机协作 | GPT-4 + 人工审校 | ★★ | ★★★★★+ | $$$$ |
### 自定义术语表
用户可提供术语表文件(CSV/JSON)确保特定术语的翻译一致:
```json
{
"source_lang": "en",
"target_lang": "zh-CN",
"terms": {
"OpenAkita": "OpenAkita",
"Agent": "智能体",
"fine-tuning": "微调",
"prompt engineering": "提示词工程"
}
}
```
---
## EXTEND.md 扩展
用户可在技能同目录下创建 `EXTEND.md` 添加:
- 行业专用术语表
- 首选翻译引擎和质量等级
- 自定义字体路径
- PDF 模板和样式覆盖规则
- 特定文档类型的预处理规则