Les formes du pluriel dans les traductions

| Jan-Arve Sæther | traducteur : Jonathan Courtois | Qt Quarterly |

Vous êtes-vous déjà trouvé en train d'écrire tr("%1 object(s) found").arg(count) dans l'une de vos applications ? Qt 4.2 introduit un mécanisme puissant permettant de gérer avec élégance les pluriels : celui-ci fonctionne pour toutes les langues et exige peu de travail supplémentaire de la part du développeur.

Commentez

- Titre : Les formes du pluriel dans les traductions

- Auteurs : Jan-Arve Sæther, traducteur : Jonathan Courtois, Qt Quarterly

- Parution : 5 janvier 2010

- Mise à jour : 22 mars 2012

- Licence : Copyright ® 2006 Jan-Arve Sæther. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. L'article original

- II. Quel est le problème avec les formes du pluriel ?

- III. Comment Qt 4.2 règle-t-il le problème ?

- IV. Comment cela fonctionne-t-il sous le capot ?

- V. Divers

I - L'article original

Qt Quarterly est une revue trimestrielle électronique proposée par Nokia à destination des développeurs et utilisateurs de Qt. Vous pouvez trouver les versions originales.

Nokia, Qt, Qt Quarterly et leurs logos sont des marques déposées de Nokia Corporation en Finlande et/ou dans les autres pays. Les autres marques déposées sont détenues par leurs propriétaires respectifs.

Cet article est la traduction de l'article Plural Form(s) in Translation(s) de Jan-Arve Sæther paru dans la Qt Quarterly Issue 19.

Cet article est une traduction de l'un des tutoriels écrits en anglais par Nokia Corporation and/or its subsidiary(-ies) ; il est inclus dans la documentation de Qt. Les éventuels problèmes résultant d'une mauvaise traduction ne sont pas imputables à Nokia.

II - Quel est le problème avec les formes du pluriel ?

Vous avez probablement déjà vu des programmes qui utilisent la même chaîne de caractères pour le singulier et le pluriel, en utilisant des parenthèses pour combiner le singulier et le pluriel dans la chaîne de caractères (comme, "6 occurrence(s) replaced").

Naturellement, il serait préférable d'afficher "6 occurrences replaced" avec un 's', et "1 occurrence replaced" sans 's'. Certains développeurs résolvent ce problème avec du code ressemblant à ceci :

tr("%1 item%2 replaced").arg(count)
.arg(count == 1 ? "" : "s");

Cette approche fonctionne pour les langues telles que l'anglais qui forme systématiquement ses pluriels en utilisant un 's', mais dès que nous essayons de traduire une application dans des langues comme l'arabe, le chinois, l'allemand, l'hébreu ou le japonais (pour en nommer juste quelques-unes), cela devient très difficile.

Les développeurs plus scrupuleux pourraient écrire un code qui ressemble plus à celui-ci :

QString message;
if (count == 1) {
message = tr("%1 item replaced").arg(count);
} else {
message = tr("%1 items replaced").arg(count);
}

Ce code est nettement plus convivial au niveau de l'internationalisation, mais il fait encore deux hypothèses sur la langue en question :

- Il suppose que la langue en question n'a que deux formes grammaticales (singulier et pluriel) ;

- Il suppose que la forme plurielle devrait être utilisée dans le cas n = 0 (par exemple, "0 items").

Ces hypothèses sont vraies pour beaucoup de langues dans le monde, dont le néerlandais, l'anglais, le finlandais, le grec, l'hébreu, l'hindi, le mongol, le swahili, le turc ou le zoulou, mais il y a également beaucoup de langues pour lesquelles elles ne le sont pas.

Exemple typique : en français et en portugais brésilien (mais pas le portugais international, chose intéressante), la forme singulière est utilisée en conjonction avec 0 (par exemple, "0 maison", pas "0 maisons"), contredisant l'hypothèse 2. En polonais, il y a trois formes grammaticales :

- Singulier : n = 1

- Paucal : n = 2--4, 22--24, 32--34, 42--44, ...

- Pluriel : n = 0, 5--21, 25--31, 35--41, ...

Par exemple, le mot polonais dom ("maison") à la forme paucale domy et la forme pluriel domów. Le tableau ci-dessous montre la restitution de "n maison(s)" en anglais, français, et polonais pour différentes valeurs de n.

Anglais

Français

Polonais

0 houses

0 maison

0 domów

1 house

1 maison

1 dom

2 houses

2 maisons

2 domy

3 houses

3 maisons

3 domy

4 houses

4 maisons

4 domy

5 houses

5 maisons

5 domów

21 houses

21 maisons

21 domów

22 houses

22 maisons

22 domy

24 houses

24 maisons

24 domy

30 houses

30 maisons

30 domów

D'autres langues respectent d'autres règles :

- Le letton a un certain nombre de formes grammaticales spécifiques, la nullar, pour le cas "n = 0" ;

- Le divehi, l'inuktitut, l'irlandais, le maori, et certaines autres langues ont un duel pour le cas "n = 2" ;

- Le tchèque, le slovaque, le lituanien et le macédonien ont aussi une forme duelle, mais ils l'utilisent en fonction de règles complexes ;

- Le slovène a une forme triale en plus des formes du singulier, du duel et du pluriel ;

- Le roumain gére le cas "n >= 20 différemment du cas "n < 20" ;

- L'arabe a six formes différentes, en fonction de la valeur de n ;

- Le chinois, le japonais, le coréen et beaucoup d'autres langues ne font pas la distinction entre le singulier et le pluriel.

La liste ci-dessus, incomplète, n'est destinée qu'à montrer clairement la complexité du problème.

III - Comment Qt 4.2 règle-t-il le problème ?

Qt 4.2 inclut la surcharge QObject::tr() qui permet d'écrire très facilement des applications internationalisées utilisant des formes plurielles correctes. Cette nouvelle surcharge a la signature suivante :

QString tr(const char *text, const char *comment, int n);

En fonction de la valeur de n, la fonction tr() retournera une traduction différente, avec la forme grammaticale correcte pour la langue prévue. De plus, toute occurrence de "%n" est remplacée par la valeur n. Par exemple :

tr("%n item(s) replaced", "", count);

Si une traduction française est chargée, cela renverra "0 item remplacé", "1 item remplacé", "2 items remplacés", etc., en fonction de la valeur de n. Et si aucune traduction n'est chargée, la chaine de caractères originale est utilisée avec "%n" remplacée par la valeur de count (par exemple, "6 item(s) replaced").

Dans le cas de l'anglais, pour obtenir un texte plus naturel, vous devrez charger une traduction anglaise. (1) Une traduction anglaise offre d'autres avantages, tels que la possibilité d'éditer l'interface utilisateur de l'application en anglais sans toucher au code source.

Lorsque l'application est prête à être traduite, les développeurs doivent exécuter lupdate comme d'habitude pour générer un ou plusieurs fichiers .ts qui peuvent être modifiés à l'aide de Qt Linguist. Dans Qt Linguist, le traducteur peut spécifier la langue prévue en cliquant sur Edit|Translation File Settings. Spécifier une langue est nécessaire afin que Qt Linguist sache combien de traductions sont nécessaires pour une chaîne de caractères source qui contient "%n".

La capture d'écran ci-dessus montre comment Qt Linguist permet au traducteur de saisir trois traductions différentes, correspondant aux trois formes grammaticales (singulier, paucal, et pluriel) de la langue polonaise.

IV - Comment cela fonctionne-t-il sous le capot ?

Qt Linguist et son outil d'assistance lrelease connaissent les règles spécifiques du pluriel pour toutes les langues supportées par QLocale. Ces règles sont codées dans le fichier binaire .qm qui est généré à partir du fichier .ts, de sorte que tr() utilise la forme de base correcte sur la valeur n. Le tableau ci-dessous indique les règles spécifiques qui sont produites par Qt Linguist et lrelease pour une sélection de langues.

Langage

Forme 1

Forme 2

Forme 3

Anglais

n == 1

sinon

non disponible

Français

n < 2

sinon

non disponible

Tchèque

n % 100 == 1

n % 100 >= 2
&& n % 100 <= 4

sinon

Irlandais

n == 1

n == 2

sinon

Letton

n % 10 == 1
&& n % 100 != 11

n != 0

sinon

Lituanien

n % 10 == 1
&& n % 100 != 11

n % 100 != 12
&& n % 10 == 2

sinon

Macédonien

n % 10 == 1

n % 10 == 2

sinon

Polonais

n == 1

n % 10 >= 2
&& n % 10 <= 4
&& (n % 100 < 10
|| n % 100 > 20)

sinon

Roumain

n == 1

n == 0
|| (n % 100 >= 1
&& n % 100 <= 20)

sinon

Russe

n % 10 == 1
&& n % 100 != 11

n % 10 >= 2
&& n % 10 <= 4
&& (n % 100 < 10
|| n % 100 > 20)

sinon

Slovaque

n == 1

n >= 2 && n <= 4

sinon

Japonais

sinon

non disponnible

non disponible

Ces règles sont codées en dur dans Qt Linguist et lrelease ; c'est pourquoi ni les développeurs d'application, ni les traducteurs n'ont besoin de les comprendre ou de les connaître.

Considérant combien il est facile d'utiliser la nouvelle surchage de tr(), il ne devrait plus y avoir aucune excuse pour ne pas gérer correctement les formes plurielles dans les applications Qt.

V - Divers

J'adresse ici de chaleureux remerciements à dourouc05 et à Papy_77 pour leur relecture !

Au nom de toute l'équipe Qt, j'aimerais adresser le plus grand remerciement à Nokia pour nous avoir autorisé à traduire en français cet article !

(1) Par souci de simplicité, nous supposons que la langue source est l'anglais. Ce peut être n'importe quelle langue, même les langues qui ne peuvent pas être exprimées en utilisant la norme d'encodage ISO 8859-1 (Latin-1). Pour plus de détails, voir le chapitre Release Manager du manuel de Qt Linguist.