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.