|
| 1 | +# Translations of Comprehensive Rust 🦀 |
| 2 | + |
| 3 | +We would love to have your help with translating the course into other |
| 4 | +languages! We use the [Gettext] system for translations. This means that you |
| 5 | +don't modify the Markdown files directly: instead you modify `.po` files in a |
| 6 | +`po/` directory. The `.po` files are small text-based translation databases. |
| 7 | + |
| 8 | +There is a `.po` file for each language. They are named after the [ISO 639] |
| 9 | +language codes: Danish would go into `po/da.po`, Korean would go into |
| 10 | +`po/ko.po`, etc. The `.po` files contain all the English text plus the |
| 11 | +translations. They are initialized from a `messages.pot` file (a PO template) |
| 12 | +which contains only the English text. |
| 13 | + |
| 14 | +We will show how to update and manipulate the `.po` and `.pot` files using the |
| 15 | +GNU Gettext utilities below. |
| 16 | + |
| 17 | +[Gettext]: https://www.gnu.org/software/gettext/manual/html_node/index.html |
| 18 | +[ISO 639]: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes |
| 19 | + |
| 20 | +## I18n Helpers |
| 21 | + |
| 22 | +We use two helpers for the translations: |
| 23 | + |
| 24 | +* `mdbook-xgettext`: This program extracts the English text. It is an mdbook |
| 25 | + renderer. |
| 26 | +* `mdbook-gettext`: This program translates the book into a target language. It |
| 27 | + is an mdbook preprocessor. |
| 28 | + |
| 29 | +Install both helpers with the following command from the root of the course: |
| 30 | + |
| 31 | +```shell |
| 32 | +$ cargo install --path i18n-helpers |
| 33 | +``` |
| 34 | + |
| 35 | +## Creating and Updating Translations |
| 36 | + |
| 37 | +First, you need to know how to update the `.pot` and `.po` files. |
| 38 | + |
| 39 | +As a general rule, you should never touch the auto-generated `po/messages.pot` |
| 40 | +file. You should also not edit the `msgid` entries in a `po/xx.po` file. If you |
| 41 | +find mistakes, you need to update the original English text instead. The fixes |
| 42 | +to the English text will flow into the `.po` files the next time the translators |
| 43 | +update them. |
| 44 | + |
| 45 | +### Generating the PO Template |
| 46 | + |
| 47 | +To extract the original English text and generate a `messages.pot` file, you run |
| 48 | +`mdbook` with a special renderer: |
| 49 | + |
| 50 | +```shell |
| 51 | +$ MDBOOK_OUTPUT='{"xgettext": {"pot-file": "messages.pot"}}' \ |
| 52 | + mdbook build -d po |
| 53 | +``` |
| 54 | + |
| 55 | +You will find the generated POT file as `po/messages.pot`. |
| 56 | + |
| 57 | +### Initialize a New Translation |
| 58 | + |
| 59 | +To start a new translation, first generate the `po/messages.pot` file. Then use |
| 60 | +`msginit` to create a `xx.po` file for the fictional `xx` language: |
| 61 | + |
| 62 | +```shell |
| 63 | +$ msginit -i po/messages.pot -l xx -o po/xx.po |
| 64 | +``` |
| 65 | + |
| 66 | +You can also simply copy `po/messages.pot` to `po/xx.po`. Then update the file |
| 67 | +header (the first entry with `msgid ""`) to the correct language. |
| 68 | + |
| 69 | +### Updating an Existing Translation |
| 70 | + |
| 71 | +As the English text changes, translations gradually become outdated. To update |
| 72 | +the `po/xx.po` file with new messages, first extract the English text into a |
| 73 | +`po/messages.pot` template file. Then run |
| 74 | + |
| 75 | +```shell |
| 76 | +$ msgmerge --update po/xx.po po/messages.pot |
| 77 | +``` |
| 78 | + |
| 79 | +Unchanged messages will stay intact, deleted messages are marked as old, and |
| 80 | +updated messages are marked "fuzzy". A fuzzy entry will reuse the previous |
| 81 | +translation: you should then go over it and update it as necessary before you |
| 82 | +remove the fuzzy marker. |
| 83 | + |
| 84 | +## Using Translations |
| 85 | + |
| 86 | +This will show you how to use the translations to generate localized HTML |
| 87 | +output. |
| 88 | + |
| 89 | +## Building a Translation |
| 90 | + |
| 91 | +To use the `po/xx.po` file for your output, run the following command: |
| 92 | + |
| 93 | +```shell |
| 94 | +$ MDBOOK_BOOK__LANGUAGE='xx' \ |
| 95 | + MDBOOK_PREPROCESSOR__GETTEXT__PO_FILE='po/xx.po' \ |
| 96 | + MDBOOK_PREPROCESSOR__GETTEXT__RENDERERS='["html"]' \ |
| 97 | + MDBOOK_PREPROCESSOR__GETTEXT__BEFORE='["svgbob"]' \ |
| 98 | + mdbook build -d book/xx |
| 99 | +``` |
| 100 | + |
| 101 | +This will update the book's language to `xx`, it will make the `mdbook-gettext` |
| 102 | +preprocessor become active and tell it to use the `po/xx.po` file, and finally |
| 103 | +it will redirect the output to `book/xx`. |
| 104 | + |
| 105 | +## Serving a Translation |
| 106 | + |
| 107 | +Like normal, you can use `mdbook serve` to view your translation as you work on |
| 108 | +it. You use the same command as with `mdbook build` above, but additionally |
| 109 | +we'll tell `mdbook` to watch the `po/` directory for changes: |
| 110 | + |
| 111 | +```shell |
| 112 | +$ MDBOOK_BOOK__LANGUAGE=xx \ |
| 113 | + MDBOOK_PREPROCESSOR__GETTEXT__PO_FILE=po/xx.po |
| 114 | + MDBOOK_BUILD__EXTRA_WATCH_DIRS='["po"]' |
| 115 | + mdbook serve -d book/xx |
| 116 | +``` |
0 commit comments