Retrouvez cet article dans : Linux Magazine 84
Introduction
Le sujet de l’internationalisation de projets a déjà été abordé dans les colonnes de Linux Magazine. Dans le numéro 10, vous participiez à la réalisation d’une application GNOME multilingue. Mais c’est la dernière partie de l’introduction aux auto-tools du numéro 24 que nous allons reprendre ici, en nous focalisant sur l’internationalisation d’un projet avec les auto-tools, ce qui est le but de l’article. L’internationalisation d’un programme sans utilisation des auto-tools est possible. Vous pouvez utiliser gettext, comme nous le verrons plus loin. Cependant, ce serait à vous de coder certains mécanismes que nous ne décrirons pas ici. Pour cela, veuillez vous reporter à l’ouvrage C en action (O’Reilly) qui y consacre un chapitre entier. Nous préférerons ici ne pas nous priver des avantages que procurent les auto-tools.Bonjour le monde
L’exemple que nous avons l’habitude de prendre, à savoir afficher " Bonjour le monde ", convient presque. En effet, nous pourrions l’utiliser tel quel et proposer une traduction dans d’autres langues dont l’anglais, langue dominante de notre civilisation. Cependant, à cause de cette domination linguistique précisément, nous allons préférer un affichage natif en anglais et une traduction en français. Cela a peu d’importance pour la traduction français/anglais, mais cela en revêt tout de suite plus lorsque vous devez traduire de la langue native de votre programme en une langue exotique. Vous trouverez probablement plus de gens aptes à traduire de l’anglais vers le portugais ou le polonais que du français vers l’une de ces langues.Hello World
Notre exemple parlera donc anglais contrairement aux articles précédents. Rassurez-vous, l’article a pour objet de le traduire ! Mais voici le code : src/main.c#include <config.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char*argv[]) {
printf(“Hello World\n”);
exit(EXIT_SUCCESS);
}
configure.ac
AC_PREREQ(2.59) AC_INIT(bonjour_le_monde, 0.1, ymettier@libertysurf.fr) AM_INIT_AUTOMAKE AC_CONFIG_SRCDIR([src/main.c]) AC_CONFIG_HEADER([config.h]) # Checks for programs. AC_PROG_CC AC_PROG_MAKE_SET # Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS([stdlib.h]) # Checks for library functions. AC_CONFIG_FILES([ Makefile src/Makefile ]) AC_OUTPUTMakefile.am
SUBDIRS=srcsrc/Makefile.am
bin_PROGRAMS=bonjour bonjour_SOURCES=main.c
Étape 1 : internationalisation des auto-fichiers
Ajout du support de gettext
La première chose à faire est d’exécuterUpdating Makefile.am (backup is in Makefile.am~) Updating configure.ac (backup is in configure.ac~) Adding an entry to ChangeLog (backup is in ChangeLog~) Please use AM_GNU_GETTEXT([external]) in order to cause autoconfiguration to look for an external libintl. Please create po/Makevars from the template in po/Makevars.template. You can then remove po/Makevars.template. Please fill po/POTFILES.in as described in the documentation. Please run ‘aclocal -I m4’ to regenerate the aclocal.m4 file. You need aclocal from GNU automake 1.5 (or newer) to do this. Then run ‘autoconf’ to regenerate the configure file. You will also need config.guess and config.sub, which you can get from the CVS of the ‘config’ project at http://savannah.gnu.org/ The commands to fetch them are $ wget ‘http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess’ $ wget ‘http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub’ You might also want to copy the convenience header file gettext.h from the /usr/share/gettext directory into your package. It is a wrapper around <libintl.h> that implements the configure --disable-nls option. Press Return to acknowledge the previous 6 paragraphs.Nous allons revenir sur tout ce qui précède. D’abord, il nous est indiqué que les fichiers
# List of source files which contain translatable strings. src/main.cDans le désordre, il est conseillé de copier le fichier
$ automake -a -c configure.ac:11: installing `./config.guess’ configure.ac:11: installing `./config.sub’Lancez encore ceci pour tester que tout fonctionne :
Définition de LOCALEDIR
Dans les sources, nous allons avoir besoin du chemin contenant les locales. Celui-ci est généralement défini dans une macro du joyeux nom dedatadir = @datadir@ localedir = $(datadir)/locale DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@Il pourrait exister une autre façon de faire, à savoir définir la macro dans le fichier
${prefix}/share
En poussant un peu plus loin, avec par exemple NONE/share/localeEn fait, le script
Étape 2 : internationalisation du code
Les fichiers sources
Dans cette étape, nous allons effectuer des modifications dans le code source. Dans chaque fichier de code, vous allez vous assurer que le fichier d’en-tête#include <config.h> #include <gettext.h> #define _(String) gettext (String) #define N_(String) StringL’inclusion du fichier
char chaine[] = "Plouf !";Ici, la chaîne est statique. Vous devez donc appeler
main()
Le fichier source contenantsetlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE);Ces trois lignes de code initialisent tout le nécessaire pour l’internationalisation de votre code, aussi bien la traduction que la localisation. Les macros utilisées ici ne tombent pas du ciel. La première,
Recompilation
Si vous n’avez pas fait d’erreur, l’exécution deÉtape 3 : traduction des chaînes
La traduction des chaînes de caractères est, au niveau informatique, l’étape la plus simple probablement.Nouvelle traduction
Démarrer une nouvelle traduction s’effectue en trois parties :- Ajoutez ou complétez la macro
LINGUASdans le fichierconfigure.ac. Indiquez-y la langue de la nouvelle traduction, par exemplefrpour notre bonne vieille langue française. - Dans le répertoire
po/, trouvez le fichier portant le nom du projet et d’extension.pot. Faites-en une copie que vous appellerezxx.pooùxxindique la langue. Une traduction française ira donc dans le fichierfr.po. - Éditez le début du fichier de traduction pour y indiquer votre nom, la date de traduction, et d’autres choses comme le jeu de caractères choisi (par exemple ISO-8859-15 ou UTF-8).
Compléter une traduction
Avant de compléter une traduction, vous devez vous assurer que le fichier d’extensionQuelques remarques sur la traduction
Lorsque vous traduisez, et que la chaîne à traduire est longue, vous pouvez couper la chaîne en fermant les guillemets et en les ouvrant à nouveau à la ligne suivante. Le résultat sera concaténé, exactement comme cela se fait en C. Ainsi,msgstr "deux lignes"et
msgstr "deux " "lignes"sont équivalents. N’hésitez pas à en profiter pour plus de lisibilité. Lors de la mise à jour des chaînes de caractères (réalisée avec
Le résultat
À titre d’illustration, voici tous les fichiers ayant subi des modifications par rapport aux fichiers initiaux, suite à l’internationalisation de notre code.configure.ac
AC_PREREQ(2.59) AC_INIT(bonjour_le_monde, 0.1, ymettier@libertysurf.fr) AM_INIT_AUTOMAKE AC_CONFIG_SRCDIR([src/main.c]) AC_CONFIG_HEADER([config.h]) # Checks for programs. AC_PROG_CC AC_PROG_MAKE_SET AM_GNU_GETTEXT([external]) ALL_LINGUAS=fr # Checks for libraries. # Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS([stdlib.h]) # Checks for typedefs, structures, and compiler characteristics.
configure.ac AC_PREREQ(2.59) AC_INIT(bonjour_le_monde, 0.1, ymettier@libertysurf.fr) AM_INIT_AUTOMAKE AC_CONFIG_SRCDIR([src/main.c]) AC_CONFIG_HEADER([config.h]) # Checks for programs. AC_PROG_CC AC_PROG_MAKE_SET AM_GNU_GETTEXT([external]) ALL_LINGUAS=fr # Checks for libraries. # Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS([stdlib.h]) # Checks for typedefs, structures, and compiler characteristics. # Checks for library functions. AC_CONFIG_FILES([ po/Makefile.in Makefile src/Makefile ]) AC_OUTPUT
Makefile.am
SUBDIRS= po src ACLOCAL_AMFLAGS = -I m4 EXTRA_DIST = config.rpath mkinstalldirs m4/ChangeLog
src/Makefile.am
datadir = @datadir@ localedir = $(datadir)/locale DEFS = -DLOCALEDIR=\”$(localedir)\” @DEFS@ bin_PROGRAMS=bonjour bonjour_SOURCES=main.c gettext.h
src/main.c
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <gettext.h>
#define _(String) gettext (String)
#define N_(String) String
int
main (int argc, char *argv[])
{
setlocale (LC_ALL, “”);
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
printf (_(“Hello World\n”));
exit (EXIT_SUCCESS);
}
po/POTFILES.in
# List of source files which contain translatable strings. src/main.c
po/fr.po
# Translation for the bonjour project # Copyright (C) YEAR Free Software Foundation, Inc. # This file is distributed under the same license as the PACKAGE package. # Yves Mettier <ymettier@libertysurf.fr>, 2006. # msgid “” msgstr “” “Project-Id-Version: bonjour_le_monde 0.1\n” "Report-Msgid-Bugs-To: ymettier@libertysurf.fr\n" "POT-Creation-Date: 2006-01-13 00:03+0100\n" "PO-Revision-Date: 2006-01-09 17:29+GMT+1\n" "Last-Translator: Yves Mettier <ymettier@libertysurf.fr>\n" “Language-Team: Français <fr@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-15\n" "Content-Transfer-Encoding: 8bit\n" #: src/main.c:14 #, c-format msgid "Hello World\n" msgstr “Bonjour le monde\n”
Conclusion
Un programme ne parle pas encore français ? Votre projet se limite toujours à la langue française ? Vous avez maintenant de quoi faire pour le traduire. Pour un projet encore non internationalisé, écrivez vos chaînes en anglais pour toucher un public de traducteurs plus grand et, surtout, traduisez d’emblée en français. Cela vous permettra de vous rendre compte d’erreurs ou de difficultés de traduction que vous corrigerez immédiatement. Cela évitera à un traducteur contributeur dans une autre langue de se trouver face à des difficultés de base, qui peuvent le mener à l’abandon de sa contribution spontanée. Cela serait dommage. Alors, à vos dictionnaires bilingues !Références
- Le manuel d’autoconf : http://www.gnu.org/software/autoconf/manual/
- Le manuel d’automake : http://www.gnu.org/software/automake/manual/
- Le manuel de gettext : http://www.gnu.org/software/gettext/manual/
- C en action, O’Reilly, chapitres 17 et 20.
Retrouvez cet article dans : Linux Magazine 84





Donnez votre avis
Vous devez avoir ouvert une session pour écrire un commentaire.