Revayat — 英语 → 波斯语书籍翻译
按顺序执行以下九个步骤。每个步骤包含一个命令及其输出处理规则。不要擅自改变顺序,也不要因为上一步看起来没问题就跳过任何步骤。
设置两个变量,然后在各处使用它们:
SKILL_DIR— 存放此文件的文件夹。在 Claude Code 插件中,它为${CLAUDE_PLUGIN_ROOT}/skills/revayat。WORK— 用于处理本书的工作文件夹,例如work/。
每个命令都是 python3 $SKILL_DIR/scripts/revayat.py <阶段> …。
五项绝不可违反的规则
- 切勿反转波斯语文本 使其从右向左读取。方向由构建器设置。反转会产生一个除特定查看器外处处出错的文件。
- 切勿编造、删除、合并、拆分或重排
@@ id标题。 原样返回你收到的标题。 - 切勿删除
[[fn:…]]、**粗体**、*斜体*或`原样`标记。 这些标记会被计数;不匹配会导致 QA 失败。 - 切勿手编辑
book.json来修复翻译。 请修复工作表并重新运行合并。 - 切勿缩短书籍。 不得概括、跳过难句或弱化内容。如果某一步报告内容缺失,请重新运行该块。
步骤 1 — 检查工具
python3 $SKILL_DIR/scripts/revayat.py doctor
"ready": true→ 继续。"ready": false→ 运行pip install -r $SKILL_DIR/requirements.txt,然后重新运行doctor。optional_tools显示not found暂时可以。步骤 2 会告诉你是否真的需要 OCR。
步骤 2 — 提取
python3 $SKILL_DIR/scripts/revayat.py extract "<输入文件>" --out $WORK
对于波斯语源文件,添加 --ocr-lang fas。对于其他语言,使用 Tesseract 代码(deu、fra、ara 等)。
读取它打印的 JSON 并按照下表操作:
| 你看到的内容 | 你需要做什么 |
|---|---|
"kind": "digital" | 无需操作;不需要 OCR |
"kind": "scanned" 或 "mixed" | OCR 已自动运行;检查 ocr.probe_after.text_share 是否高于 0.7 |
| 报错提及 OCRmyPDF | 按消息提示安装,然后重新运行此步骤 |
clean_scan.cleaned 大于 0 | 已从相应页面移除彩色水印 |
ocr.warning 不为 null | 阅读该警告;文件仍可用,请继续 |
page_scans_dropped 大于 0 | 已将相应数量的整页光栅视为扫描本身而非图片 |
清理器永远不会编辑你的文件:原始文件保持不变,清理后的副本写入 $WORK/cleaned.pdf,并在 clean_scan 中为每一页记录删除了什么、保留了什么。传递 --clean-scan off 可完全跳过它,或传递 --clean-scan force 以处理残留印章的情况。
如果书籍是扫描版,请立即执行以下两个额外步骤。
识别置信度 — 没有它,误读的词与正确的词无法区分,因为两者都是流利的波斯语:
python3 $SKILL_DIR/scripts/revayat.py ocr-sidecar --pdf $WORK/ocr.pdf --out $WORK --lang fas --book $WORK/book.json
这将写入 source.ocr.json(每个词、行、块和页面:边界框、置信度、阅读顺序以及执行的预处理)和 source.ocr.txt,然后在 book.json 中为每个块标记其来源区域的置信度。分级为 low 的块会被 qa check 报告为 ocr-low-confidence,接受一个意味着查看页面图像。阈值默认为 85 和 60,可通过 --high / --low 调整。
扫描版内的插图 — 扫描页是一张平面图像,因此上面的照片不会自动成为独立图片:
mineru -p $WORK/cleaned.pdf -o $WORK/mineru -b pipeline -l arabic
python3 $SKILL_DIR/scripts/revayat.py extract "<输入文件>" --out $WORK --figures-from-mineru $WORK/mineru
在 cleaned.pdf 上运行 MinerU,不要在原始文件上运行,否则它会将水印裁剪为图片。仅从 MinerU 获取图片。 它自身对波斯语的识别文本会返回词及其内部字母都反转的结果;使用 fas 的 Tesseract 能正确读取同一页面,因此文本保持不动。当 MinerU 在某个页面范围上运行时,使用 --figures-page-offset N。
然后在继续之前查看结果:
python3 $SKILL_DIR/scripts/revayat.py qa check --book $WORK/book.json --allow-incomplete
此处忽略 untranslated-block — 尚未进行任何翻译。你只需关注 asset-missing。如果对于一本真实书籍,stats.text_blocks 低于 20,则提取失败:请参阅 references/extraction.md。
步骤 3 — 词汇表
python3 $SKILL_DIR/scripts/revayat.py glossary scan \
--book $WORK/book.json --out $WORK/glossary.json
报告列出 needs_persian,最频繁的在前。打开 $WORK/glossary.json,为前 20 个条目中的每一个填写四个字段:
"target": "الیزابت بنت",
"later_form": "الیزابت بنت",
"first_form": "الیزابت بنت (Elizabeth Bennet)",
"locked": true
保持 first_block_id 完全不变 — 流水线用它来决定哪个单个块引入该名称。不要编辑它,也不要自行决定首次提及的位置。
删除非真实名称的条目。然后继续。
步骤 4 — 分块
python3 $SKILL_DIR/scripts/revayat.py chunk build \
--book $WORK/book.json --out $WORK/chunks --glossary $WORK/glossary.json
注意块的数量。每个块成为一个翻译任务。
如果你已经翻译了一些工作表,而输入文件后续发生了变化,此步骤会拒绝执行并在 "refused" 中给出原因 "stale-worksheets",而不是静默地提供不再匹配书籍的工作表。重新阅读给出的原因;仅当你确定现有翻译仍然可用时才添加 --force。
步骤 5 — 翻译
对于每个 $WORK/chunks/chunkNNNN.md,生成 $WORK/chunks/out_chunkNNNN.md。如果你的运行环境中有子代理,则每个块使用一个独立的子代理,一次最多 8 个。如果没有,则逐个执行 — 结果相同,只是速度较慢。
向子代理提供以下精确指令:
读取
$WORK/chunks/chunkNNNN.md并写入$WORK/chunks/out_chunkNNNN.md。翻译成波斯语。首先读取
$SKILL_DIR/references/translation-policy.md并遵守它。输出格式 — 这是机械性要求,必须完全正确:
- 逐行复制每个
@@ <id> <kind>行,保持原样,顺序不变。- 在其下方行上放置波斯语翻译。
- 不输出其他任何内容:无前言,无英语,无评论,无摘要。
规则:
- “名称”表格具有约束力。如果某行说“首次提及,在此处介绍”,则使用较长形式。所有其他情况使用短形式。不要自行决定 — 表格已经决定好了。
- “周围文字”仅作为上下文。切勿翻译或复制它们。
- 保持
**粗体**、*斜体*、`原样`和[[fn:…]]完全不变,放在对应的波斯语词周围。不要添加或删除任何标记。- 完全翻译每个单元。切勿概括或跳过。
- 要添加自己的脚注:在句子中写入
[[fn:tr-01]],并在末尾添加一个包含其文本的@@ tr-01 footnote块。仅用于真正的文化引用或文字游戏。
随时检查剩余进度:
python3 $SKILL_DIR/scripts/revayat.py chunk status --chunks $WORK/chunks
步骤 6 — 合并
python3 $SKILL_DIR/scripts/revayat.py merge --book $WORK/book.json --chunks $WORK/chunks
| 字段 | 含义 | 操作 |
|---|---|---|
"ok": true | 所有内容已归位 | 继续到步骤 7 |
missing_outputs | 这些块从未被翻译 | 翻译它们 |
missing_units | 标题被删除 | 重新运行这些块 |
unknown_units | 标题被编造 | 重新运行这些块 |
修复后重新运行合并始终是安全的。
步骤 7 — 波斯语排版
python3 $SKILL_DIR/scripts/revayat.py falint fix --book $WORK/book.json
仅涉及机械性操作,可安全运行两次。如果书籍必须保留拉丁数字,添加 --digits keep。
步骤 8 — 门控,然后构建
python3 $SKILL_DIR/scripts/revayat.py qa check \
--book $WORK/book.json --assets $WORK/assets --glossary $WORK/glossary.json
当 "ok" 为 false 时不要构建。 根据错误代码进行修复:
| 代码 | 含义 | 操作 |
|---|---|---|
untranslated-block | 某个块没有波斯语 | 翻译该块 |
footnote-marker-lost | 某个 [[fn:…]] 被删除 | 重新运行该块 |
footnote-marker-invented | 某个标记指向空处 | 重新运行该块 |
possible-omission | 目标文本远短于源文本 | 阅读它;通常是一个从句被删除 |
untranslated | 英语残留在波斯语中 | 重新运行该块 |
asset-missing / asset-modified | 图片丢失或更改 | 重新提取 |
copied-source-run | 源文本的某个从句存在于波斯语中 | 重新运行该块 |
duplicate-translation | 两个不同源文本得到相同波斯语 | 某份工作表回复被粘贴两次;重新运行两者 |
first-mention-repeated | 名称在多个地方被介绍 | 保留第一个,删除其余 |
image-order | 包内图片顺序错误 | 重新构建 |
bookmarks-missing / bookmark-duplicate | 目录链接到不存在或错误的地方 | 重新构建 |
emphasis-parity(警告) | 粗体/斜体计数变化 | 随机检查一个;通常没问题 |
glossary-drift(警告) | 锁定名称渲染方式不同 | 重新运行该块 |
ocr-low-confidence(警告) | 引擎对该块不确定 | 打开页面图像并比较 |
对于出版工作,添加 --strict 以使最后三个也变为阻塞性错误。
将书籍的标题和作者翻译到 book.json 中的 meta.title_target 和 meta.author_target — 这是唯一一次预期的手动编辑,因为没有对应的工作表。
然后构建:
python3 $SKILL_DIR/scripts/revayat.py build \
--book $WORK/book.json --assets $WORK/assets --out out/book.fa.docx \
--font "Vazirmatn" --size 11.5
有用的标志:当文件必须在没有波斯语字体的机器上渲染时,使用 --font Tahoma;--heading-size source 可重现原始标题字号;--template ref.docx 可从现有 Word 文件继承样式。完整列表请参阅 references/docx-and-ooxml.md。
步骤 9 — 验证并报告
python3 $SKILL_DIR/scripts/revayat.py qa docx --file out/book.fa.docx --book $WORK/book.json
如果 "ok": false,请先修复它再告知用户文件已就绪。
然后报告:文件位置、章节数、图片数和脚注数、任何 QA 标记但您选择不处理的内容,以及以下限制声明 —
Word 会重新排列文本,因此可编辑的波斯语文档无法在页面上与源 PDF 完全一致。图片字节和物理尺寸、章节结构、强调、脚注和章节链接是精确的。
参考文献
仅在步骤指向它们时阅读这些文件:
references/translation-policy.md— 提供给翻译子代理的内容references/persian-typography.md— 从右到左、ZWNJ、标点、混合脚本references/extraction.md— OCR 路由、水印、难以处理的书籍references/glossary-and-voice.md— 命名策略、别名、角色语态references/docx-and-ooxml.md— 每个构建选项及其生成内容references/troubleshooting.md— 你最可能遇到的失败