# Traduction de la doc de Python et i18n
### J. Palard et C. Revillet

# L'internationalisa-
### tion :(

## i18n :)


## [Citation du W3C](https://www.w3.org/International/questions/qa-i18n)
> “Internationalization is the design and development of a product, application or document content that enables easy localization for target audiences that vary in culture, region, or language.

## [Citation du W3C](https://www.w3.org/International/questions/qa-i18n)
> Localization refers to the adaptation of a product, application or document content to meet the language, cultural and other requirements of a specific target market (a locale).”


## Localisation

La localisation ne concerne pas que la traduction, mais toutes les
spécificités régionales, culturelles, telles que la monnaie, la
disposition clavier, les symboles, icones, couleurs, formats
numériques, formats de dates, ordre des caractères, lois, …


## i18n vs l10n

- i18n : Rendre possible la traduction dans n’importe quelle langue
- l10n : Ajouter une langue

Notes:

C'est de la préparation (~une fois pour toute),
donner l'exemple de la traduction de la doc: la partie
i18n à été faite par sphinx-doc, la l10n c'est nous.

## POSIX locale database

https://docs.python.org/3/library/locale.html

## POSIX locale database

Extrait de `/usr/share/i18n/locales/fr_FR` :

```
LC_MONETARY
int_curr_symbol     "<U0045><U0055><U0052><U0020>"
currency_symbol     "<U20AC>"
mon_decimal_point   "<U002C>"
mon_thousands_sep   "<U0020>"
mon_grouping        3
positive_sign       ""
negative_sign       "<U002D>"
int_frac_digits     2
```

## POSIX locale database

Liste des sections :

-  LC_CTYPE
-  LC_COLLATE
-  LC_MESSAGES
-  LC_MONETARY
-  LC_NUMERIC
-  LC_TIME
-  LC_ADDRESS
-  …

## POSIX locale database

La traduction est une petite partie de
l'internationalisation, définit par
POSIX pour donner des idées de "qu'est-ce qu'on couvre
quand on localise".
Culture / Coutume.

## POSIX locale database

Tout est documenté !
```
man 5 locale
```

## POSIX locale database

```
dpkg-reconfigure locales
```

## POSIX locale database

```pycon
>>> locale.setlocale(locale.LC_ALL, 'fr_FR.utf-8')
'fr_FR.utf-8'
>>> datetime.datetime.now().strftime("%c")
'mer. 13 juil. 2016 00:36:05 '
```

## POSIX locale database

```pycon
>>> locale.setlocale(locale.LC_ALL, 'en_US.utf-8')
'en_US.utf-8'
>>> datetime.datetime.now().strftime("%c")
'Wed 13 Jul 2016 12:36:42 AM '
```

# La traduction

![](static/2016-translation.png)

(Image de http://www.sphinx-doc.org/en/stable/intl.html)

## Préparation (i18n)

Marquer les chaînes :
- Python
```
print(_('This is a translatable string.'))
```
- Jinja2
```
<p>{% trans %}Parts of the documentation:{% endtrans %}</p>
```
- …

## Générer le `.po`

- gettext
- pybabel extract
- django-admin.py makemessages
- sphinx-build -b gettext
- …

## fichier `.pot`

```po
#: ../Doc/tutorial/appendix.rst:11
msgid "Interactive Mode"
msgstr ""

#: ../Doc/tutorial/appendix.rst:16
msgid "Error Handling"
msgstr ""
```

## Traduire ou faire traduire

- poedit
- transifex.com
- Vé (Android)
- gted
- gtranslator
- lokalize
- betterpoeditor
- …

## fichier `.po` traduit

```
#: ../Doc/tutorial/appendix.rst:11
msgid "Interactive Mode"
msgstr "Mode interactif"

#: ../Doc/tutorial/appendix.rst:16
msgid "Error Handling"
msgstr "Gestion des erreurs"
```

## Compiler le `.po` en `.mo`

- msgfmt
- django-admin compilemessages
- …

Notes:
- le _ est une convention: (gettext, django.utils.translation.urgettext as _, ...)
- `po` pour `portable object`
- `mo` pour `machine object`

## gettext

https://docs.python.org/3/library/gettext.html
- from gettext import gettext as _
- ngettext
- pgettext ?
- …

Notes:
pgettext: Permet de donner du contexte à une traduction (Voir https://bugs.python.org/issue2504)
Basiquement, le genre, l'emplacement (menu, ...), ou n'importe quel autre désambiguation, typiquement "date" pouvant être un fruit ou calendaire, un contexte est necessaire, car ces deux mots peuvent être différents dans d'autres langues.


# potpie

potpie génère des traductions de test, utiles pour trouver les appels manquants à gettext.
```
$ pip install potpie
```
```
$ potpie --type unicode 3.5/tutorial.po potpie/tutorial.po
```
```
#: ../Doc/tutorial/appendix.rst:5
msgid "Appendix"
msgstr "Ȧƥƥḗƞḓīẋ"
#: ../Doc/tutorial/appendix.rst:16
msgid "Error Handling"
msgstr "Ḗřřǿř Ħȧƞḓŀīƞɠ"
```

# Formatage des chaînes

```
_("Hello {name}").format()
```
ou
```
_("Hello {name}".format())
```
> EN : "Hello Guido"
> FR : "Bonjour Guido"

## Formatage des chaînes

```
_("{} likes {}")
```
ou
```
_("{0} likes {1}")
```
> EN : "Guido likes Python"
> FR : "Guido aime Python"

## Formatage des chaînes

```
_("Today is {0} {1}")
```
ou
```
_("Today is {month} {day}")
```
> EN : "Today is October 16"
> FR : "Aujourd'hui c'est le 16 Octobre"

## Formatage des chaînes

```
_("That is a ") + car.color + $(" car")
```
> EN : "That is a blue car"
> FR : "C'est une bleu voiture"

# Faire, ne pas faire

> Donner une chaîne formattée à gettext
Pas bien:
```
_("Hello {name}".format())
```
Bien:
```
_("Hello {name}").format()
```

## Faire, ne pas faire

> Penser que le pluriel se gère pareil dans toutes les langues
Pas bien:
```
print(_("{} file{} deleted").format(n, "s" if n > 1 else ""))
```
Bien:
```
print(ngettext("{nb} file removed",
"{nb} files removed", n).format(n))
```

## Faire, ne pas faire

> Penser que les traducteurs pourront toujours mettre les mots dans le même ordre
Pas bien:
```
print(_("%s %s %s").format(
user_login,
gettext("likes"),
fav_ingredient));
```
Bien:
```
print(_("{username} likes {ingredent}").format(
user_login,
fav_ingredient));
```

# docs.python.org/fr

Autres projets de traduction:
- http://docs.python.jp/3/
- http://docs.python.org.ar/tutorial/3/real-index.html
La doc de Python utilise `sphinx-doc`.

## Historique du projet

- Projet né en 2012 (ou avant ?)
- 2013, 2014 : au point mort
- Fin 2015 : Projet relancé
- 2016 : On avance pour pousser la traduction sur docs.python.org/fr/ http://bugs.python.org/issue26546

## Pourquoi

![](static/2016-helping.jpg)

## Pourquoi

- Je m'ennuie dans le RER, alors je traduis…
- C'est un outil d'évangélisation
- La langue ne devrait pas être un frein pour apprendre le Python, peu importe l'age et le niveau de scolarisation
- Il n'y a aucune raison à ce que l'anglais soit un prérequis de Python, au contraire, Python pourrait être un moyen de se familiariser avec l'anglais
- Apprendre deux langues en même temps, c'est un peu trop meta.

## Github

https://github.com/AFPy/python_doc_fr/
![](static/2016-python_doc_fr_github.png)

## Progression

- 2016-01: 6%
- 2016-02: 11%
- 2016-03: 14%
- 2016-04: 22%
- 2016-05: 23%
- 2016-06: Tentative de merge avec docs.python.org
12 contributeurs depuis 2012

## Github

Progression
![](static/2016-progression_100.png)

## Github

Progression
![](static/2016-progression.png)

## Comment on fait

```bash
$ git clone https://github.com/AFPy/python_doc_fr.git
```
…
```bash
$ poedit 3.5/library.po
```
…
```bash
$ make
```

## Comment on fait

![](static/2016-pyfr.png)

## docs.python.org/fr/

En progrès:
- https://github.com/python/docsbuild-scripts/pull/1
- http://bugs.python.org/issue26546

## Et après ?

- https://docs.python.org/jp/
- https://docs.python.org/es/

## Et après ?

Travailler sur quelques améliorations de
sphinx-doc comme "Highlight untranslated paragraphs" :
https://github.com/sphinx-doc/sphinx/issues/1246

# Questions ?
