summaryrefslogtreecommitdiff
path: root/doc/intl.rst
blob: ea81c3ec8ca6a18ae2a20c078be11d19af230a1d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
.. _intl:

Internationalization
====================

.. versionadded:: 1.1

Complementary to translations provided for Sphinx-generated messages such as
navigation bars, Sphinx provides mechanisms facilitating *document* translations
in itself.  See the :ref:`intl-options` for details on configuration.

.. figure:: translation.png
   :width: 100%

   Workflow visualization of translations in Sphinx.  (The stick-figure is taken
   from an `XKCD comic <http://xkcd.com/779/>`_.)

.. contents::
   :local:

Sphinx internationalization details
-----------------------------------

**gettext** [1]_ is an established standard for internationalization and
localization.  It naively maps messages in a program to a translated string.
Sphinx uses these facilities to translate whole documents.

Initially project maintainers have to collect all translatable strings (also
referred to as *messages*) to make them known to translators.  Sphinx extracts
these through invocation of ``sphinx-build -b gettext``.

Every single element in the doctree will end up in a single message which
results in lists being equally split into different chunks while large
paragraphs will remain as coarsely-grained as they were in the original
document.  This grants seamless document updates while still providing a little
bit of context for translators in free-text passages.  It is the maintainer's
task to split up paragraphs which are too large as there is no sane automated
way to do that.

After Sphinx successfully ran the
:class:`~sphinx.builders.gettext.MessageCatalogBuilder` you will find a
collection of ``.pot`` files in your output directory.  These are **catalog
templates** and contain messages in your original language *only*.

They can be delivered to translators which will transform them to ``.po`` files
--- so called **message catalogs** --- containing a mapping from the original
messages to foreign-language strings.

Gettext compiles them into a binary format known as **binary catalogs** through
:program:`msgfmt` for efficiency reasons.  If you make these files discoverable
with :confval:`locale_dirs` for your :confval:`language`, Sphinx will pick them
up automatically.

An example: you have a document ``usage.rst`` in your Sphinx project.  The
gettext builder will put its messages into ``usage.pot``.  Imagine you have
Spanish translations [2]_ on your hands in ``usage.po`` --- for your builds to
be translated you need to follow these instructions:

* Compile your message catalog to a locale directory, say ``locale``, so it
  ends up in ``./locale/es/LC_MESSAGES/usage.mo`` in your source directory
  (where ``es`` is the language code for Spanish.) ::

        msgfmt "usage.po" -o "locale/es/LC_MESSAGES/usage.mo"

* Set :confval:`locale_dirs` to ``["locale/"]``.
* Set :confval:`language` to ``es`` (also possible via :option:`-D`).
* Run your desired build.


Translating with sphinx-intl
----------------------------

Quick guide
^^^^^^^^^^^

`sphinx-intl`_ is a useful tool to work with Sphinx translation flow.
This section describe a easy way to translate with sphinx-intl.

#. Install `sphinx-intl`_ by :command:`pip install sphinx-intl` or
   :command:`easy_install sphinx-intl`.

#. Add configurations to your `conf.py`::

      locale_dirs = ['locale/']   # path is example but recommended.
      gettext_compact = False     # optional.

   This case-study assumes that :confval:`locale_dirs` is set to 'locale/' and
   :confval:`gettext_compact` is set to `False` (the Sphinx document is
   already configured as such).

#. Extract document's translatable messages into pot files::

      $ make gettext

   As a result, many pot files are generated under ``_build/locale``
   directory.

#. Setup/Update your `locale_dir`::

      $ sphinx-intl update -p _build/locale -l de -l ja

   Done. You got these directories that contain po files:

   * `./locale/de/LC_MESSAGES/`
   * `./locale/ja/LC_MESSAGES/`

#. Translate your po files under `./locale/<lang>/LC_MESSAGES/`.

#. Build mo files and make translated document.

   You need a :confval:`language` parameter in ``conf.py`` or you may also
   specify the parameter on the command line::

      $ sphinx-intl build
      $ make -e SPHINXOPTS="-D language='de'" html

Congratulations! You got the translated documentation in the ``_build/html``
directory.


Translating
^^^^^^^^^^^

Translate po file under ``./locale/de/LC_MESSAGES`` directory.
The case of builders.po file for sphinx document:

.. code-block:: po

   # a5600c3d2e3d48fc8c261ea0284db79b
   #: ../../builders.rst:4
   msgid "Available builders"
   msgstr "<FILL HERE BY TARGET LANGUAGE>"

Another case, msgid is multi-line text and contains reStructuredText
syntax:

.. code-block:: po

   # 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."

Please be careful not to break reST notation.  Most po-editors will help you
with that.


Update your po files by new pot files
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If a document is updated, it is necessary to generate updated pot files
and to apply differences to translated po files.
In order to apply the updating difference of a pot file to po file,
use the :command:`sphinx-intl update` command.

.. code-block:: bash

   $ sphinx-intl update -p _build/locale


Using Transifex service for team translation
--------------------------------------------

Transifex_ is one of several services that allow collaborative translation via a
web interface.  It has a nifty Python-based command line client that makes it
easy to fetch and push translations.

.. TODO: why use transifex?


#. Install `transifex-client`_

   You need :command:`tx` command to upload resources (pot files).

   .. code-block:: bash

      $ pip install transifex-client

   .. seealso:: `Transifex Client v0.8 &mdash; Transifex documentation`_


#. Create your transifex_ account and create new project for your document

   Currently, transifex does not allow for a translation project to have more
   than one version of the document, so you'd better include a version number in
   your project name.

   For example:

   :Project ID: ``sphinx-document-test_1_0``
   :Project URL: https://www.transifex.com/projects/p/sphinx-document-test_1_0/


#. Create config files for tx command

   This process will create ``.tx/config`` in the current directory, as well as
   a ``~/.transifexrc`` file that includes auth information.

   .. code-block:: bash

      $ tx init
      Creating .tx folder...
      Transifex instance [https://www.transifex.com]:
      ...
      Please enter your transifex username: <transifex-username>
      Password: <transifex-password>
      ...
      Done.

#. Upload pot files to transifex service

   Register pot files to ``.tx/config`` file:

   .. code-block:: bash

      $ cd /your/document/root
      $ sphinx-intl update-txconfig-resources --pot-dir _build/locale \
        --transifex-project-name sphinx-document-test_1_0

   and upload pot files:

   .. code-block:: bash

      $ tx push -s
      Pushing translations for resource sphinx-document-test_1_0.builders:
      Pushing source file (locale/pot/builders.pot)
      Resource does not exist.  Creating...
      ...
      Done.


#. Forward the translation on transifex

   .. TODO: write this section


#. Pull translated po files and make translated html

   Get translated catalogs and build mo files (ex. for 'de'):

   .. code-block:: bash

      $ cd /your/document/root
      $ tx pull -l de
      Pulling translations for resource sphinx-document-test_1_0.builders (...)
       -> de: locale/de/LC_MESSAGES/builders.po
      ...
      Done.

   Build po files into mo and make html::

      $ sphinx-intl build
      $ make -e SPHINXOPTS="-D language='de'" html


That's all!


.. tip:: Translating locally and on Transifex

   If you want to push all language's po files, you can be done by using
   :command:`tx push -t` command.
   Watch out! This operation overwrites translations in transifex.

   In other words, if you have updated each in the service and local po files,
   it would take much time and effort to integrate them.



Contributing to Sphinx reference translation
--------------------------------------------

The recommended way for new contributors to translate Sphinx reference
is to join the translation team on Transifex.

There is `sphinx translation page`_ for Sphinx-1.3 documentation.

1. Login to transifex_ service.
2. Go to `sphinx translation page`_.
3. Click ``Request language`` and fill form.
4. Wait acceptance by transifex sphinx translation maintainers.
5. (after acceptance) translate on transifex.


.. rubric:: Footnotes

.. [1] See the `GNU gettext utilities
       <http://www.gnu.org/software/gettext/manual/gettext.html#Introduction>`_
       for details on that software suite.
.. [2] Because nobody expects the Spanish Inquisition!


.. _`transifex-client`: https://pypi.python.org/pypi/transifex-client
.. _`sphinx-intl`: https://pypi.python.org/pypi/sphinx-intl
.. _Transifex: https://www.transifex.com/
.. _`sphinx translation page`: https://www.transifex.com/projects/p/sphinx-doc-1_3/
.. _`Transifex Client v0.8 &mdash; Transifex documentation`: http://help.transifex.com/features/client/index.html