<- PW - Intro - Indice Generale - Copertina - PW: GUI+SL -> |
PlutoWare
L'articolo...Questo articolo analizza il procedimento di internazionalizzazione e quello di localizzazione di un programma, dal punto di vista del traduttore (o del sistemista) più che da quello del programmatore. Spero che possa essere uno spunto valido per chi ha il desiderio di contribuire allo sviluppo del software open source senza essere un programmatore. |
Recentemente mi sono imbattuto per ben due volte, a distanza
ravvicinata di tempo, in problemi legati alla traduzione di
programmi.
Il primo caso è legato alla necessità di tradurre
un mio programma, e quindi alla parte di programmazione del
processo di traduzione. Appena avrò risolto completamente
i problemi relativi, cercherò di scrivere qualcosa a
questo proposito.
Il secondo è legato alla mia traduzione del programma per la
gestione di piccoli database Gaby, al quale vorrei dedicare il
prossimo articolo. Da quest'ultima esperienza ho rilevato come, nonostante
le mie buone conoscenze dell'argomento, io abbia incontrato dei
problemi nell'affrontare la traduzione. Ho deciso quindi di
scrivere questi appunti, tentando una semplificazione dell'ampia
documentazione esistente, nella speranza che possano essere utili
a qualcuno.
Come, probabilmente, molti di voi ben sanno, la maggior parte
dei programmi (open source e non) vengono sviluppati in lingua
inglese. Molti utenti non si sentono sufficientemente a loro agio
nell'utilizzare tale lingua. I programmatori hanno quindi dovuto,
da sempre, dedicare parte delle loro energie all'
internazionalizzazione e localizzazione dei programmi,
rispettivamente (per gli amanti delle sigle) i18n e l10n.
Per chi non conoscesse la differenza fra i due termini
dirò, semplificando, che la conversione di un programma
atta a farlo diventare multilingua è comunemente detta
globalizzazione. La globalizzazione di un programma passa
attraverso due fasi.
La prima è il processo di internazionalizzazione,
che consiste nella revisione del codice di un programma in modo
da renderlo atto ad essere "localizzato". Questa è una
procedura generica che vale per qualsiasi numero di lingue il
programma debba supportare; essa deve tenere conto della parte
più tecnica del processo e di problematiche relative ai
formati di data, di ora, dei numeri decimali, delle lettere
accentate, dei segni di interpuntazione e della direzione della
scrittura (in alcune lingue come l'arabo o il giapponese si
scrive da destra a sinistra o addirittura dal basso in alto) e
similari.
La seconda fase, detta localizzazione, è invece
la traduzione del programma in lingue diverse da quella nella
quale è stato scritto. Non è forse così
ovvio che tale fase sia forse la più onerosa, in
quanto va affrontata programma per programma ed è soggetta
a revisione continua all'evolversi dello stesso. Oltretutto
è la parte in cui gli automatismi meno riescono a essere
efficaci, come ben sa chiunque di voi abbia visto una traduzione
automatica di un testo.
Pur non volendo approfondire troppo il lato tecnico, è
opportuno vedere quali sono i passi per la produzione di un
programma multilingua, ovvero individuare i punti nei quali un
traduttore può intervenire in maniera autonoma.
Dovete sapere che un primitivo metodo di globalizzazione
consisteva nel fork (divisione) dello sviluppo di un programma,
attraverso il quale un nuovo team di programmatori si prendeva
carico di creare una versione tradotta dei programmi. Tale metodo
è ovviamente oneroso, e crea ritardi nello sviluppo delle
versioni localizzate dei programmi, oltre a portare bug aggiuntivi
negli stessi.
Chiaramente la situazione si è evoluta, ed oggi quasi tutti
i linguaggi di programmazione permettono
l'internazionalizzazione, (d'ora in poi i18n) tramite l'uso di
apposite librerie. Su tali argomenti vorrei soffermarmi in un
futuro articolo (come accennato in apertura) dedicato alla parte
più tecnica dell'i18n e alla programmazione.
Per il momento sia sufficiente sapere che le funzioni più
utilizzate sono la standard X/Open P.G. catgets()
e,
in ambienti GNU, la funzione gettext()
, che
portano a corredo dei tools per automatizzare alcune operazioni
di manutenzione.
Tramite tali funzioni il programma va a "leggere" la scritta da
visualizzare in un file esterno.
Nel caso della funzione gettext
, la struttura di tale file
è molto semplice: si tratta di un file di "hash", ovvero
una sorta di tabella, nella quale vengono elencate le scritte
originali e di seguito la corrispondente traduzione. La scritta
originale viene, quindi, utilizzata come identificativo, tramite
il quale viene effettuata la ricerca della frase tradotta
all'interno del suddetto file di traduzione.
Il file in realtà non è unico: ne esiste uno per
ogni linguaggio nel quale il programma è stato tradotto.
Ciascun file ha un nome di due+due lettere che corrispondono alla
lingua/stato al quale esso si riferisce. Tali lettere sono
costituite dal codice internazionale della lingua, che per l'Italia
è it, seguite eventualmente da un "underscore" e dal codice del paese
in maiuscolo. Per l'italia avremmo quindi it_IT mente per l'italiano
parlato in svizzera il codice sarebbe it_CH
La selezione del file corretto avviene durante l'esecuzione del
programma, basandosi su una variabile d'ambiente di nome LOCALE
che ha valore uguale al codice internazionale della lingua.
Chiaramente il presupposto per un corretto funzionamento è
che il file con le scritte "it" da visualizzare esista e sia
correttamente formato.
xgettext
il
file prova.pot
. Tale file, a quel punto, contiene
tutte le frasi che il programmatore ha predisposto per la traduzione
in lingua originale (es. inglese). Ogni frase
è racchiusa tra apici ed è preceduta dalla dicitura
msgid. Sotto la frase compare la dicitura msgstr e
una coppia di apici. Tale dicitura serve da marcaposto per la
traduzione.
#: builder/buttonwin.c:605 builder/fileops.c:317 msgid "Open" msgstr "" #: builder/buttonwin.c:605 msgid "Opens a file" msgstr "" |
c) a questo punto tocca a voi, qualora abbiate scelto il ruolo
del traduttore. Innanzitutto è opportuno contattare, con
una mail, il responsabile dello sviluppo per chiedere se sia
già in corso qualche porting del programma nella vostra
lingua. In caso affermativo, potrete unirvi al team di traduzione
che il responsabile vi indicherà, in modo da non sprecare
i vostri sforzi inutilmente con un lavoro duplicato.
In caso negativo state per diventare il responsabile per la
traduzione nella vostra lingua, e potete iniziare ad operare la
traduzione.
d) dovrete quindi copiare il file prova.pot
in
it.po
(nel caso dell'italiano) ovvero in un file,
con estensione .po
il cui nome di due lettere
è la sigla della lingua nella quale si vuole tradurre (può
all'occorenza e4ssere opportuno aggiungere la sigla della nazione
nella quale lingua si vuole tradurre, in questo caso il nostro
esempio diventa it_IT.po).
e) potete ora aprire il file con il vostro editor preferito, per
le modifiche, tenendo conto che esistono due strumenti più
adatti di altri per la traduzione.
Il primo, e più tradizionale, è emacs (ovviamente).
Esiste una apposita modalità operativa di emacs tramite la
quale si può disporre di menu e macro ottimizzate
per lavorare con i file .po. Per attivare il
PO-mode potete modificare il file .emacs aggiungendo quanto segue:
(setq auto-mode-alist (cons '("\\.po\\'\\|\\.po\\." . po-mode) auto-mode-alist)) (autoload 'po-mode "po-mode" "Major mode for translators to edit PO files" t) |
Il secondo strumento è kbabel che, essendo uno
strumento nato esplicitamente per questo uso è, forse, il sistema
ottimale per la traduzione.
"
Qui le operazioni sono ulteriormente facilitate dall'interfaccia grafica, e lo spostamento fra una frase è l'altra avviene attraverso dei comodi bottoni.
# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Free Software Foundation, Inc. # FIRST AUTHOR |
# translation of it.po to Italiano # Gaby 2.0.2 translation - Italiano # Copyright (C) 1999,2003 Free Software Foundation, Inc. # Rudi Giacomini Pilon |
#: builder/buttonwin.c:605 builder/fileops.c:317 msgid "Open" msgstr "Apri" #: builder/buttonwin.c:605 msgid "Opens a file" msgstr "Apre un file" |
chiaramente se la frase da tradurre contiene delle variabili o dei caratteri speciali essi vanno mantenuti e posizionati opportunamente come nell'esempio che segue
#: src/actions.c:77 #, c-format msgid "Unable to find %s\n" msgstr "Impossibile trovare %s\n" |
dove %s
rappresenta una variabile di stringa e
\n
un ritorno a capo.
g) se non avete competenze di programmazione il vostro compito
è quasi completato. Non vi resta infatti che inviare al
responsabile dello sviluppo del software i file contenenti le
traduzioni, in modo che vengano incorporati nella prossima
release. Se invece avete un minimo di conoscenze di base potete
fare ancora qualcosa testando la traduzione nel vostro PC.
h) per fare questo sarà necessario modificare alcuni
file. Se i sorgenti sono stati preparati secondo le specifiche
indicate nel manuale di gettext, portandovi nella root dei
sorgenti del programma, dovreste trovarvi di fronte ad una
struttura ad albero nella quale sono presenti almeno la directory
/po, /intl e /src.
La prima è il vostro obiettivo, ed è all'interno di
essa che dovrete inserire i file it.po e it.gmo. In tale
directory dovrebbe essere inoltre presente il file
LINGUAS
. Apritelo con un editor e aggiungete
it
all'elenco dei linguaggi disponibili.
i) dovrete poi effettuare la modifica del file
configure
contenuto nella root dei sorgenti.
Individuate una riga simile alla seguente:
ALL_LINGUAS="da de es fi fr ja nl no pl sv" |
e aggiungete it fra le lingue disponibili.
l) dal file it.po tramite il comando:
msgfmt it.po -o it.gmo |
configure
e make
export LANGUAGE="it"
e lanciando il
programma prova (dopo averlo compilato) vedremo le scritte
in italiano.Per la naturale evoluzione dei programmi, prima o poi, avrete la necessità di
rivedere delle traduzioni.Vi sono una serie di utility che facilitano
enormemente il lavoro di manutenzione. Elencare il funzionamento di tutte
sarebbe un lavoro estenuante e vi rimando all'opportuna manualistica citata
nei riferimenti a fine articolo. Cito comunque un paio dei programmi principali:
- msgmerge: viene utilizzato per aggiornare i sorgenti di un programma
già, in precedenza, tradotto evitando di perdere la precedente traduzione.
Mi spiego meglio: abbiamo, praticamente, di fronte un programma aggiornato e il
nuovo file da tradurre da esso estratto tramite xgettext() come spiegato sopra.
Tale file (nuovo.po) conterrà le nuove diciture non presenti nel vecchio
programma, frasi modificate etc.. Non essendo il programma completamente nuovo
possiamo ipotizzare che la maggior parte delle traduzioni coincidano con la
vecchia versione e si desidera evitare di rifare tutto il lavoro da capo.
Possiamo quindi prendere la nostra vecchia traduzione (vecchio.po) ed eseguire
il comando:
msgmerge vecchio.po nuovo.po -o risultato.po |
msguniq originale.po -u -o risultato.po |
A questo punto un paio di suggerimenti:
Se volete intervenire nello sviluppo di un programma con la
traduzione dovreste scegliere il momento opportuno per farlo. Se
il programma è immaturo o in una forte fase evolutiva,
c'è il rischio che dobbiate intervenire molto spesso nella
traduzione. Per contro, evitate di affrontare la traduzione di un
programma obsoleto e destinato a scomparire.
Attenzione, inoltre, alle trappole linguistiche dovute al
"linguaggio informatico". La traduzione di un programma non
consiste nella conversione, parola per parola, dei vocaboli, da
una lingua all'altra, o nella traduzione più o meno
letterale delle frasi. Anni fa, per esempio, una nota
multinazionale informatica (evitiamo nomi e cognomi) traduceva,
nei manuali, termini come hard-disk e mouse rispettivamente in
"disco duro" e "topo" che suonavano a dir poco ridicoli. In
ambito informatico, spesso, molte espressioni sono gergali e non
mantengono nessun riferimento alla voce originale.
Riferimenti
alla funzione catgets
Manuale di gettext
Home page di
Kbabel
L' autoreRudi Giacomini Pilon, programmatore dall'età di 14 anni, ex progettista elettronico, ex hardwarista e sistemista presso un Microsoft Solution Provider, ex esperto di reti e programmatore in una concessionaria IBM, incontra Linux nel 1994 e da allora vede pinguini ovunque. Dal 1999 è responsabile EDP in una SpA ove affronta l'informatica a 538 gradi (360 erano pochi). |
<- PW - Intro - Indice Generale - Copertina - PW: GUI+SL -> |