Openakita 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.

install
source · Clone the upstream repo
git clone https://github.com/openakita/openakita
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/openakita/openakita "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/translate-pdf" ~/.claude/skills/openakita-openakita-openakita-skills-translate-pdf && rm -rf "$T"
manifest: skills/translate-pdf/SKILL.md
source content

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

系统级依赖

工具用途说明
Popplerpdf2image 的后端Windows: 下载 poppler-utils; macOS:
brew install poppler
TesseractOCR 引擎Windows: 下载安装包; macOS:
brew install tesseract
中文字体PDF 中文渲染系统需安装中文字体(微软雅黑、思源黑体等)

验证安装

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
阿拉伯文★★★

翻译引擎优先级

优先级引擎特点
1LLM (GPT-4/Claude)最高质量,理解上下文,术语一致
2DeepL API高质量机器翻译
3Google Translate免费,覆盖语种广

Agent 按照优先级自动选择可用的翻译引擎。用户可以指定使用特定引擎。

PDF 元素处理策略

元素处理方式
正文文本翻译并保留字体大小、颜色、粗体/斜体
标题翻译并保留层级和样式
表格翻译单元格内容,保留表格结构
图片保留原图不动
图片中的文字可选 OCR 识别后翻译
页眉/页脚翻译并保持位置
页码保持不变
脚注/尾注翻译内容,保留编号
目录翻译条目,页码不变
书签翻译标题
链接/URL保持不变
数学公式保持不变
代码块保持不变(仅翻译注释)
水印保留原样

Workflows

Workflow 1: 标准 PDF 翻译

步骤 1 — 解析 PDF 结构

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 — 逐页提取文本块

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 — 批量翻译

将提取的文本按段落分组,批量发送给翻译引擎:

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

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:

布局选项

布局说明适用场景
左右对照左页原文、右页译文学术论文、对比审阅
上下对照段落级交替显示学习材料
注释模式译文作为侧边注释保留原文为主
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 类型

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 识别

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 翻译

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 中注册:

import fitz

# PyMuPDF 支持的中文字体
# "china-ss" = 思源宋体 (简体)
# "china-ts" = 思源宋体 (繁体)
# 或使用自定义字体
page.insert_font(fontname="custom-zh", fontfile="/path/to/NotoSansCJK-Regular.ttf")

2. 表格翻译后错位

症状:表格内容溢出单元格 原因:中文译文通常比英文短,但某些情况下可能更长 解决

  • 动态调整字体大小以适应单元格
  • 允许文本自动换行
  • 对于复杂表格,使用 pdfplumber 提取后单独翻译

3. 数学公式被错误翻译

症状:公式被当作文本翻译 解决:在翻译前识别并标记数学公式区域,跳过翻译:

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 时内存不足 解决:逐页处理而非一次性加载:

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
  • 翻译后用脚本检查术语一致性
glossary = {
    "machine learning": "机器学习",
    "neural network": "神经网络",
    "gradient descent": "梯度下降",
    "backpropagation": "反向传播",
}

7. 页眉页脚重复翻译

症状:每页的页眉页脚翻译结果微有差异 解决:先识别页眉页脚模式,统一翻译一次后应用到所有页面


高级配置

翻译质量等级

等级方式速度质量费用
快速Google Translate★★★★★★★★免费
标准DeepL★★★★★★★★$$
专业GPT-4★★★★★★★★$$$
人机协作GPT-4 + 人工审校★★★★★★★+$$$$

自定义术语表

用户可提供术语表文件(CSV/JSON)确保特定术语的翻译一致:

{
  "source_lang": "en",
  "target_lang": "zh-CN",
  "terms": {
    "OpenAkita": "OpenAkita",
    "Agent": "智能体",
    "fine-tuning": "微调",
    "prompt engineering": "提示词工程"
  }
}

EXTEND.md 扩展

用户可在技能同目录下创建

EXTEND.md
添加:

  • 行业专用术语表
  • 首选翻译引擎和质量等级
  • 自定义字体路径
  • PDF 模板和样式覆盖规则
  • 特定文档类型的预处理规则