【问题标题】:How to Internationalize Sphinx (i18n)如何国际化 Sphinx (i18n)
【发布时间】:2020-07-13 21:58:13
【问题描述】:

从执行 sphinx-quickstart 后的默认值中,我如何获得特定于语言的目录,例如 Read The Docs 使用的目录?

我正在创建一个新的 Sphinx 文档站点,该站点由 GitHub Pages 托管,使用 GitHub Actions 构建,并使用 Read The Docs 主题。基本上我正在尝试重新创建 Read The Docs,但没有广告或服务器端搜索。

我将在很长一段时间内无法实际翻译任何内容,但我确实想确保我的新项目已准备好在以后进行翻译。最具体地说,我想确保我的文档的永久链接在我添加翻译后不会改变。为此,我想让我的文档 URL 包含 URL (/en/stable/) 中的语言,例如:

我跟着Sphinx Guide to Internationalization,在conf.py中设置了languagelocale_dirs变量:

language = 'en'
locale_dirs = ['locale/']
gettext_compact = True

不幸的是,经过上述更改后,make htmlmake -e SPHINXOPTS="-D language='en'" html 仍然会生成没有 en 子目录的文件

user@host:~/docs$ tree -L 2 _build
_build
├── doctrees
│   ├── environment.pickle
│   └── index.doctree
└── html
    ├── genindex.html
    ├── index.html
    ├── objects.inv
    ├── search.html
    ├── searchindex.js
    ├── _sources
    └── _static

是我遗漏了什么还是文档遗漏了什么?如何使用 make 设置新的 Sphinx 安装并使用默认值构建为特定语言的 html?

【问题讨论】:

    标签: internationalization locale python-sphinx read-the-docs


    【解决方案1】:

    未记录的事实是狮身人面像不会这样做。事实上,sphinx i18n 功能停止了构建所有特定语言目录的工作流程。这意味着您必须使用自己的脚本设计和包装 sphinx-build 才能进行设置。

    要将您的 sphinx reST 文件翻译成另一种语言,您不必自己更新您的“.rst”文件。 Sphinx 已经了解文本块的样子,它可以将标题字符串、标题、双换行符分隔的段落等划分为唯一的“源字符串”(msgid),并将它们放入“.pot”源-语言文件和“.po”目标语言文件。

    首先,从“docs/”目录运行make gettext。这告诉 sphinx 解析你的 reST 文件并自动找到一堆要翻译的字符串并给它们一个唯一的msgid

    user@host:~/rtd-github-pages$ cd docs/
    user@host:~/rtd-github-pages/docs$ ls
    autodoc.rst  buildDocs.sh  conf.py.orig  locales   Makefile
    _build       conf.py       index.rst     make.bat  _static
    user@host:~/rtd-github-pages/docs$ 
     
    user@host:~/rtd-github-pages/docs$ make gettext
    Running Sphinx v1.8.4
    making output directory...
    building [gettext]: targets for 0 template files
    building [gettext]: targets for 2 source files that are out of date
    updating environment: 2 added, 0 changed, 0 removed
    Hello Worldrces... [ 50%] autodoc                                               
    reading sources... [100%] index                                                 
    looking for now-outdated files... none found
    pickling environment... done
    checking consistency... done
    preparing documents... done
    writing output... [100%] index                                                  
    writing message catalogs... [100%] index                                        
    build succeeded.
     
    The message catalogs are in _build/gettext.
    user@host:~/rtd-github-pages/docs$ 
    

    上面的执行应该会创建以下文件

    user@host:~/rtd-github-pages/docs$ ls _build/gettext/
    autodoc.pot  index.pot
    user@host:~/rtd-github-pages/docs$ 
    

    这是来自 '_build/gettext/index.pot' 的 sn-p,在我们的文档主页上显示了两个字符串,我们将把它们从英语翻译成西班牙语。

    user@host:~/rtd-github-pages/docs$ grep -m2 -A2 .rst _build/gettext/index.pot 
    #: ../../index.rst:7
    msgid "Welcome to helloWorld's documentation!"
    msgstr ""
    --
    #: ../../index.rst:9
    msgid "Contents:"
    msgstr ""
    user@host:~/rtd-github-pages/docs$ 
    

    接下来,让我们告诉 sphinx 从上面生成的源语言“.pot”文件中准备一些西班牙语目标语言“.po”文件。

    在继续此步骤之前,您需要安装 sphinx-intl 和 python Stemmer 模块。如果您使用的是基于 Debian 的发行版,则可以使用以下命令进行操作。

    sudo apt-get install -y sphinx-intl python3-stemmer
    

    执行以下命令来准备我们的西班牙语特定翻译文件。

    user@host:~/rtd-github-pages/docs$ sphinx-intl update -p _build/gettext -l es
    Create: locales/es/LC_MESSAGES/index.po
    Create: locales/es/LC_MESSAGES/autodoc.po
    user@host:~/rtd-github-pages/docs$ 
    

    上述执行创建了两个“.po”文件:每个“.pot”源语言文件一个,它与我们的两个“.rst”文件(index.rst 和 autodoc.rst)中的每一个直接相关.完美。

    如果我们 grep 新的西班牙语特定的“docs/locales/es/LC_MESSAGES/index.po”文件,我们会看到它与源“.pot”文件的内容相同。

    user@host:~/rtd-github-pages/docs$ grep -m2 -A2 .rst locales/es/LC_MESSAGES/index.po 
    #: ../../index.rst:7
    msgid "Welcome to helloWorld's documentation!"
    msgstr ""
    --
    #: ../../index.rst:9
    msgid "Contents:"
    msgstr ""
    user@host:~/rtd-github-pages/docs$ 
    

    这些特定于语言的“.po”文件是我们实际进行翻译的地方。如果您是一个大型项目,那么您可能需要使用特殊程序或service 来翻译这些文件。但是,为了清楚起见,我们将直接编辑文件。

    user@host:~/rtd-github-pages/docs$ perl -pi -0e "s^(msgid \"Welcome to helloWorld's documentation\!\"\n)msgstr \"\"^\1msgstr \"¡Bienvenido a la documentación de helloWorld\!\"^" locales/es/LC_MESSAGES/index.po
    user@host:~/rtd-github-pages/docs$ perl -pi -0e "s^(msgid \"Contents:\"\n)msgstr \"\"^\1msgstr \"Contenidos:\"^" locales/es/LC_MESSAGES/index.po
    user@host:~/rtd-github-pages/docs$ 
     
    user@host:~/rtd-github-pages/docs$ grep -m2 -A2 .rst locales/es/LC_MESSAGES/index.po 
    #: ../../index.rst:7
    msgid "Welcome to helloWorld's documentation!"
    msgstr "¡Bienvenido a la documentación de helloWorld!"
    --
    #: ../../index.rst:9
    msgid "Contents:"
    msgstr "Contenidos"
    user@host:~/rtd-github-pages/docs$ 
    

    如您所见,上面的执行用原始(英文)语言的对应msgid行的西班牙语翻译填充了msgstr ""的内容。

    现在让我们构建两个版本的 html 静态内容:[1] 英文版和 [2] 西班牙文版。

    user@host:~/rtd-github-pages/docs$ sphinx-build -b html . _build/html/en -D language='en'
    Running Sphinx v1.8.4
    loading translations [en]... done
    making output directory...
    building [mo]: targets for 0 po files that are out of date
    building : targets for 2 source files that are out of date
    updating environment: 2 added, 0 changed, 0 removed
    Hello Worldrces... [ 50%] autodoc                                               
    reading sources... [100%] index                                                 
    looking for now-outdated files... none found
    pickling environment... done
    checking consistency... done
    preparing documents... done
    writing output... [100%] index                                                  
    generating indices... genindex py-modindex
    highlighting module code... [100%] helloWorld                                   
    writing additional pages... search
    copying static files... done
    copying extra files... done
    dumping search index in English (code: en) ... done
    dumping object inventory... done
    build succeeded.
     
    The HTML pages are in _build/html/en.
    user@host:~/rtd-github-pages/docs$
     
    user@host:~/rtd-github-pages/docs$ sphinx-build -b html . _build/html/es -D language='es'
    Running Sphinx v1.8.4
    loading translations [es]... done
    making output directory...
    building [mo]: targets for 1 po files that are out of date
    writing output... [100%] locales/es/LC_MESSAGES/index.mo                        
    building : targets for 2 source files that are out of date
    updating environment: 2 added, 0 changed, 0 removed
    Hello Worldrces... [ 50%] autodoc                                               
    reading sources... [100%] index                                                 
    looking for now-outdated files... none found
    pickling environment... done
    checking consistency... done
    preparing documents... done
    writing output... [100%] index                                                  
    generating indices... genindex py-modindex
    highlighting module code... [100%] helloWorld                                   
    writing additional pages... search
    copying static files... done
    copying extra files... done
    dumping search index in Spanish (code: es) ... done
    dumping object inventory... done
    build succeeded.
     
    The HTML pages are in _build/html/es.
    user@host:~/rtd-github-pages/docs$
     
    user@host:~/rtd-github-pages/docs$ firefox _build/html/en/index.html _build/html/es/index.html &
    [1] 12134
    user@host:~/rtd-github-pages/docs$ 
    

    上述执行中的firefox 命令应该会打开带有两个选项卡的浏览器:(1) 英文版和 (2) 西班牙文版。

    有关更多信息,请参阅how to setup internationalization in Sphinx 上的这篇文章。

    【讨论】: