完整实战指南:从 POT 提取到多语言构建)
文档开发工具【免费下载链接】sphinxThe Sphinx documentation generator项目地址https://gitcode.com/gh_mirrors/sp/sphinx点击查看免费下载Sphinx 不仅能为导航栏等内建消息提供翻译更内置了一整套基于 GNU gettext 的**文档级国际化internationalization, i18n**机制先用sphinx-build -M gettext把整篇文档的可翻译文本提取成 POT 目录经译者产出 PO 消息目录再编译为 MO 二进制目录最后被 Sphinx 在构建时自动套用。读完本文你将掌握 Sphinx 从零搭建多语言文档的完整工作流包括手工msgfmt编译、sphinx-intl自动化流水线、与 Transifex 团队协作翻译以及基于translation_progress_classes的翻译进度统计与可视化。本文内容以官方文档 doc/usage/advanced/intl.rst 为主体并结合仓库中的 gettext 构建器源码、i18n 转换源码 与 配置参考 加以印证与扩充。gettext 机制与 Sphinx 的文档级翻译原理gettext是国际化和本地化的成熟标准核心思路是把程序中的消息message映射为翻译后的字符串。Sphinx 借助这一套设施来实现整篇文档的翻译而不是只翻译界面文案。文档中可翻译的字符串被称为messages由项目维护者统一收集后交给译者。消息提取的粒度策略Sphinx 通过sphinx-build -M gettext调用MessageCatalogBuilder提取全部可翻译消息。提取的粒度很有讲究doctree 中的每一个元素都会对应一条消息因此列表会被拆分成多个独立的条目各自成为一条消息大段段落则保持与原文档相同的粗粒度整段成为一条消息。这种“细到元素、粗到段落”的策略既保证了文档局部更新时能精准追踪变更又给译者保留了自由文本上下文。文档维护者需要自行拆分过大的段落因为 Sphinx 并没有“合理”的自动化拆分方式——这一点从源码中也可以印证MessageCatalogBuilder.write_doc遍历 doctree 时对每个extract_messages(doctree)返回的(node, msg)对调用catalog.add(msg, node)消息粒度完全取决于解析器产出的节点结构见 sphinx/builders/gettext.py。从源码看每个消息条目还会附带来源位置源文件、行号以及一个由uuid4().hex生成的uid见 MsgOrigin 定义供模板生成#: ...:行号注释与可选的 UUID 行使用。三种目录POT、PO、MO一次成功的 gettext 构建结束后输出目录默认是_build/gettext中会出现一批.pot文件即目录模板catalog templates其中只包含原始语言的源消息例如文档usage.rst会生成usage.pot。这些 POT 文件可以直接交给译者译者将其转换为.po文件消息目录内容是从原始消息到目标语言字符串的映射通过msgfmt将 PO 编译为高效的二进制.mo文件binary catalog只要把 MO 文件按 Sphinx 约定的目录结构放置并让locale_dirs与language配置指向它Sphinx 就会在构建时自动拾取。实际编译与读取逻辑位于 sphinx/util/i18n.pyCatalogRepository会遍历locale_dirs/{language}/LC_MESSAGES/下的*.po文件并生成CatalogInfoCatalogInfo.write_mo使用 Babel 的read_po/write_mo完成 PO→MO 编译sphinx/util/i18n.py。也就是说新版 Sphinx 在gettext_auto_build默认True开启时会在构建过程中自动完成 PO 到 MO 的编译无需每次都手动执行msgfmt。手工工作流编译目录并让构建使用翻译假设你的 Sphinx 项目有文档usage.rstgettext 构建器已经把它提取为usage.pot而你有一份西班牙语翻译usage.po。要让构建产出翻译后的文档按以下三步操作编译消息目录到源码目录下的locale使其最终位于./locale/es/LC_MESSAGES/usage.moes是西班牙语的语言代码msgfmt usage.po -o locale/es/LC_MESSAGES/usage.mo设置locale_dirslocale_dirs [locale/]设置language为es也可以直接通过命令行-D参数传入sphinx-build -b html . _build/html -D languagees完成这三步后运行你想要的构建即可得到西班牙语文档。其中locale_dirs的默认值为[locales]1.5 起目录是相对于源码目录srcdir解析的见 配置参考而language的默认值为en5.0 起除了驱动文档翻译外还会影响 Sphinx 自动生成文本的语言、LaTeX 的 Babel 语言选项以及按 figure_language_filename 规则查找语言特定图片例如myfigure.png的德文版默认为myfigure.de.png。目录查找规则与调试Sphinx 查找目录时严格遵循locale_dirs/{language}/LC_MESSAGES/{textdomain}.po|.mo结构从源码看CatalogRepository.locale_dirs会拼接basedir / locale_dir / language / LC_MESSAGES若该目录不存在会输出 verbose 日志sphinx/util/i18n.py。文档翻译使用的 textdomain 由docname_to_domain()根据gettext_compact计算而 Sphinx内建界面消息则统一使用sphinx这个 textdomain对应的目录文件应为locales/{language}/LC_MESSAGES/sphinx.mo——仓库的 sphinx/locale/ 目录下就存放了 80 余种语言的内建消息 PO/MO 文件可作为参考样例。如果locale_dirs配置不生效可以用sphinx-build -v开启 verbose 日志排查找不到目录时会输出调试信息。交叉引用一致性检查与 #noqa 豁免为防止翻译出错Sphinx 在把翻译后的段落写回文档时会检查翻译段落中的交叉引用cross-references是否与原文一致不一致时发出警告。这一机制在源码中实现得相当细致_NodeUpdater.compare_references会提取原文与译文中的引用列表默认按rawsource排序比较并忽略顺序差异从而既能允许译者调整引用顺序又能捕获缺失或多余的引用sphinx/transforms/i18n.py。检查覆盖的类型包括命名引用update_refnamed_references自动脚注引用update_autofootnote_references命名脚注引用update_refnamed_footnote_references引文引用update_citation_references待解析交叉引用update_pending_xrefs按reftarget比较允许显示文本被翻译关闭警告的方式有两种全局关闭在conf.py中设置suppress_warnings将i18n.inconsistent_references加入列表即可源码中该警告的typei18n、subtypeinconsistent_references单条消息豁免在该条翻译msgstr末尾加上#noqa4.5 版本引入例如msgstr Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse risus tortor, luctus id ultrices at. #noqa如果你希望译文文本中字面出现#noqa则写成\#noqa即可。需要注意代码块literal block中#noqa会被忽略因为代码块本来就不含引用识别它反而会让人无法在代码块中正常转义——这一点与源码逻辑一致Locale.apply中仅对非LITERAL_TYPE_NODES的节点调用parse_noqa[sphinx/transforms/i18n.py](https://link.gitcode.com/i/68024511f03780ad7f01d0dd5b71645d#L95-L100, L434-L435)。使用 sphinx-intl 自动化翻译流程sphinx-intl是围绕 Sphinx 翻译流程开发的实用工具可以大幅简化 POT 生成、PO 初始化与更新的工作。以下快速指南假定BUILDDIR为_build、locale_dirs为locale/、gettext_compact为FalseSphinx 文档项目本身即如此配置可直接参考 doc/conf.py。1. 安装 sphinx-intl$ pip install sphinx-intl2. 在 conf.py 中添加配置locale_dirs [locale/] # 路径仅为示例但推荐如此设置 gettext_compact False # 可选3. 提取可翻译消息到 POT 文件$ make gettext生成的 POT 文件位于_build/gettext目录。如果你想在intl-options配置参考之外进一步定制输出可以把默认的 POT 模板 message.pot.jinja 替换为自定义的message.pot.jinja放置在任何templates_path列出的目录中即可。从源码看GettextRenderer的模板搜索路径会优先使用templates_path中的自定义模板再回退到内置的DEFAULT_TEMPLATE_PATHsphinx/builders/gettext.py。内置模板会渲染项目名、版本、版权、Last-Translator、Language-Team、消息来源位置受gettext_location控制以及可选的 UUID受gettext_uuid控制。4. 从 POT 生成 PO 文件$ sphinx-intl update -p _build/gettext -l de -l ja执行完成后生成的 PO 文件位于./locale/de/LC_MESSAGES/./locale/ja/LC_MESSAGES/5. 翻译 PO 文件PO 文件位于./locale/lang/LC_MESSAGES/目录。以下是 Sphinx 仓库中builders.po的示例——单行消息# a5600c3d2e3d48fc8c261ea0284db79b #: ../../builders.rst:4 msgid Available builders msgstr FILL HERE BY TARGET LANGUAGE多行消息且包含 reStructuredText 语法的情况# 302558364e1d41c69b3277277e34b184 #: ../../builders.rst:9 msgid These are the built-in Sphinx builders. More builders can be added by :ref:extensions extensions. msgstr FILL HERE BY TARGET LANGUAGE FILL HERE BY TARGET LANGUAGE FILL HERE BY TARGET LANGUAGE :ref:EXTENSIONS extensions FILL HERE.务必小心不要破坏 reStructuredText 记号如:ref:指令、反引号等大多数 PO 编辑器会对此提供辅助。翻译的 msgstr 会作为独立的 reStructuredText 片段重新解析——从源码看_publish_msgstr会针对每个 msgstr 新建 docutils 文档并调用源码解析器重新解析sphinx/transforms/i18n.py因此译文必须是语法完整的reStructuredText 片段否则会被静默跳过或产生解析警告。6. 构建翻译后的文档在conf.py中设置language或在命令行中指定。BSD/GNU make$ make -e SPHINXOPTS-D languagede htmlWindowscmd.exe set SPHINXOPTS-D languagede .\make.bat htmlPowerShellPS Set-Item env:SPHINXOPTS -D languagede PS .\make.bat html构建完成后翻译后的文档就在_build/html目录中。版本提示1.3 起由 make 调用的sphinx-build会把 PO 文件自动编译为 MO 文件。如果你还在使用 1.2.x 或更早版本则需要在make之前先手动执行sphinx-intl build命令。文档更新时同步 PO当源文档更新后需要重新生成 POT 并把这些差异应用到已翻译的 PO 文件上只需重新运行$ sphinx-intl update -p _build/gettextsphinx-intl update会基于新的 POT 更新 PO同时尽量保留已有翻译。值得注意的是Sphinx 的should_write逻辑会对比新旧 POT 内容跳过POT-Creation-Date与PO-Revision-Date时间戳避免因时间戳变化触发无意义的全量重写sphinx/builders/gettext.py这保证了增量构建的稳定性。使用 Transifex 进行团队协作翻译Transifex 是提供 Web 界面协作翻译的服务之一其 Go 语言编写的命令行客户端可以方便地推送和拉取翻译。1. 安装 Transifex CLI 工具需要tx命令行工具来上传资源POT 文件。官方安装脚本会把tx二进制文件放到当前目录连同 README 与 LICENSE并把当前目录加入$PATH$ curl -o- https://raw.githubusercontent.com/transifex/cli/master/install.sh | bash2. 创建 Transifex 账号、组织与项目创建账号后为你的文档新建一个 organization 和一个 project。目前 Transifex 不允许一个翻译项目同时管理同一文档的多个版本因此最好把版本号写进项目名例如Organization IDsphinx-documentProject IDsphinx-document-test_1_0Project URLhttps://www.transifex.com/projects/p/sphinx-document-test_1_0/3. 生成 API token在 Transifex 的 API token 页面生成一个 token并立即复制保存之后无法再次查看。4. 配置 API token写入用户配置文件$HOME/.transifexrc[https://app.transifex.com] rest_hostname https://rest.api.transifex.com token paste_your_api_token_here或者使用环境变量TX_TOKENtx命令同样识别$ export TX_TOKENpaste_your_api_token_here5. 初始化项目配置该命令会在当前目录生成.tx/config$ cd /your/document/root $ tx init Successful creation of .tx/config file6. 注册并上传 POT 资源用sphinx-intl update-txconfig-resources把 POT 文件登记到.tx/config并调整--pot-dir为项目实际 POT 目录$ cd /your/document/root $ sphinx-intl update-txconfig-resources --pot-dir _build/locale \ --transifex-organization-namesphinx-document \ --transifex-project-namesphinx-document-test_1_0也可以使用环境变量SPHINXINTL_TRANSIFEX_ORGANIZATION_NAME和SPHINXINTL_TRANSIFEX_PROJECT_NAME替代上述命令行参数。随后上传源文件$ tx push -s # Getting info about resources sphinx-document-test_1_0.builders - Getting info sphinx-document-test_1_0.builders - Done # Pushing source files sphinx-document-test_1_0.builders - Uploading file sphinx-document-test_1_0.builders - Done7. 在 Transifex 上完成翻译登录 Transifex Web 界面在对应语言下完成翻译工作。8. 拉取翻译并构建例如拉取德语翻译并构建 MO 文件$ cd /your/document/root $ tx pull -l de # Getting info about resources sphinx-document-test_1_0.builders - Getting info sphinx-document-test_1_0.builders - Done # Pulling files sphinx-document-test_1_0.builders [de] - Pulling file sphinx-document-test_1_0.builders [de] - Creating download job sphinx-document-test_1_0.builders [de] - Done然后指定语言代码执行构建$ make -e SPHINXOPTS-D languagede html本地与 Transifex 双端翻译的注意点如果想一次性推送所有语言的 PO 文件可以使用tx push -t命令但该操作会覆盖 Transifex 上的翻译。如果同时更新了服务端和本地两侧的 PO 文件之后再整合会非常耗时费力建议始终明确“本地为准”还是“服务端为准”。对于 Weblate 服务可参阅 Weblate 官方文档中关于 Sphinx 的章节其用法与 Transifex 类似。参与 Sphinx 官方参考文档翻译若想为 Sphinx 官方文档本身贡献翻译推荐加入 Transifex 上的 Sphinx 翻译团队登录 Transifex 服务进入 Sphinxs documentation 翻译项目点击Request language并填写表单申请新语言等待 Sphinx 翻译维护者批准批准后即可在 Transifex 上开始翻译。翻译进度统计与可视化7.1.0 起7.1.0 版本起Sphinx 在渲染过程中会给每个可翻译节点打上translated属性标记该节点文本是否找到了翻译。这一标记由 i18n 转换 在Locale阶段写入节点未找到有效翻译时置False成功替换译文后置True并在TranslationProgressTotaliser优先级 25必须晚于Locale中汇总出文档级的total与translated计数sphinx/transforms/i18n.py。围绕该标记有两个实用的配置与机制translation_progress_classes默认False按translated属性值为每个元素添加 CSS 类方便译者快速区分已译/未译内容。取值含义True给所有含可翻译内容的节点同时添加translated和untranslated类translated只添加translated类untranslated只添加untranslated类False不添加任何类。该逻辑由AddTranslationClasses转换优先级 950实现它遍历所有带translated属性的节点按配置向classes列表追加对应类名sphinx/transforms/i18n.py。有了这些类你就可以在自定义主题或extra_css_files中为.translated/.untranslated定义高亮样式实现“已译绿色、未译红色”之类的可视化效果。|translation progress|替换substitution在文档中插入该替换会显示当前文档已翻译节点的百分比。它在DefaultSubstitutions转换中特殊处理读取TranslationProgressTotaliser计算的translation_progress字典以{translated / total:.2%}的格式输出如50.00%当没有可翻译元素时输出no translated elements!当数据缺失时输出could not calculate translation progress!sphinx/transforms/init.py。可在文档中这样使用Translation progress: |translation progress|测试用例 tests/roots/test-intl/index.txt 中即包含对translation progress替换的使用示例可作为参考。常用国际化配置项速查下表汇总了与文档翻译直接相关的配置项完整说明见 配置参考Options for internationalisation配置项默认值作用languageen文档语言代码决定自动生成文本语言、文档翻译与语言特定图片查找locale_dirs[locales]搜索消息目录的路径列表相对源码目录须符合{language}/LC_MESSAGES/结构gettext_compactTrue文档 textdomain 的计算方式True时顶层文件用 docname、子目录文件用其根目录名False时用完整 docname设为字符串时所有文档共用该 textdomain见 gettext.py 配置注册gettext_uuidFalse为每个 msgid 生成 UUID 行用于版本追踪并参与新旧 msgid 相似度计算可pip install levenshtein加速gettext_locationTrue是否在消息目录中生成来源位置信息gettext_auto_buildTrue构建时是否自动为每个翻译目录编译.mo文件gettext_additional_targets[]额外启用 gettext 翻译的元素类型支持index索引项、literal-block字面块、doctest-block、raw、image图片 URIgettext_allow_fuzzy_translationsFalse是否使用目录中的 fuzzy 消息4.3 起translation_progress_classesFalse控制是否以及为哪些节点添加translated/untranslated类7.1 起gettext_compact的行为在 docname_to_domain 中有清晰体现True时取 docname 的第一段如markup/code.rst→ 域markupFalse时取完整 docnamemarkup/code字符串时直接返回该字符串所有文档共用一个 textdomain。命令行传参时如-D gettext_compact0配置系统会将其解析为对应的布尔或字符串类型相关解析行为有测试覆盖tests/test_config/test_config.py。完整工作流小结把上述知识串成一条可直接落地的流水线初始化pip install sphinx-intl并在conf.py中配置locale_dirs建议[locale/]与可选的gettext_compact False提取make gettext生成_build/gettext/*.pot建翻译sphinx-intl update -p _build/gettext -l de -l ja ...生成各语言的 PO 文件翻译用 PO 编辑器翻译locale/lang/LC_MESSAGES/*.po注意保留 reStructuredText 语法与交叉引用必要时用#noqa豁免引用一致性检查构建make -e SPHINXOPTS-D languagede html或 Windows 下设置SPHINXOPTS后运行make.batSphinx 会自动编译 MO 并产出翻译文档维护文档更新后重新make gettext与sphinx-intl update -p _build/gettext同步翻译协作可选通过sphinx-intl update-txconfig-resourcestx push -s/tx pull -l lang接入 Transifex或接入 Weblate 进行团队翻译质检可选开启translation_progress_classes并在文档中插入|translation progress|随时掌握各文档的翻译完成度。整个过程的基础设施POT 渲染模板、PO→MO 编译、引用一致性检查、进度统计都已在 Sphinx 核心中实现你只需按上述流程配置conf.py、编写翻译、执行构建即可为你的文档项目交付完整的多语言版本。赞分享文档开发工具【免费下载链接】sphinxThe Sphinx documentation generator项目地址https://gitcode.com/gh_mirrors/sp/sphinx点击查看免费下载相关推荐如何快速构建多语言文档Sphinx国际化完整指南 如何快速构建多语言文档Sphinx国际化完整指南 Sphinx是一个功能强大的文档生成器专门用于创建高质量的技术文档。其中 Sphinx国际化与多语文档开发工具JupyterLab 扩展国际化i18n完整指南从 gettext 接入到语言包分发JupyterLab 扩展国际化i18n完整指南从 gettext 接入到语言包分发 导读 本文基于 JupyterLab 官方扩展开发文档 docs/s前端后端数据科学开发工具VitePress国际化(i18n)实现构建多语言文档站点的完整方案VitePress国际化 i18n 实现构建多语言文档站点的完整方案 VitePress作为基于Vite和Vue的静态站点生成器提供了强大的国际化 i18n前端文档上一篇HS2-HF Patch技术架构深度解析Honey Select 2汉化去码补丁的模块化实现方案下一篇WinDirStat终极指南免费开源Windows磁盘分析工具完全使用教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考