po4av0.55

PO4A

Section: Strumenti Po4a (7)
Updated: 2018-12-10
Index Return to Main Contents
 

NOME

po4a - framework per la traduzione di documentazione e altro materiale  

Introduzione

Lo scopo del progetto po4a (PO for anything - PO per tutto) è di facilitare la traduzione e, cosa ancor più interessante, la manutenzione delle traduzioni usando gettext e i relativi strumenti in campi in cui il loro uso non era programmato, come la documentazione.  

Sommario

Questo documento è organizzato come segue:
1 Perché dovrei usare po4a? A cosa serve?
Questo capitolo introduttivo spiega la motivazione e la filosofia alla base del progetto. Dovrebbe essere letto per primo se si sta valutando l'uso di po4a per le proprie traduzioni.
2 Come si usa po4a?
Questo capitolo è una sorta di guida di riferimento, pensata per rispondere alle domande degli utenti e fornire una migliore comprensione dell'intero processo. Essa presenta il modo in cui usare po4a e serve da introduzione alla documentazione dei singoli strumenti.
Come si inizia una nuova traduzione?
Completata la traduzione, come si ottiene un documento tradotto?
Come si aggiorna una traduzione con po4a?
Come si converte una traduzione già esistente all'uso di po4a?
Come si aggiunge del testo extra (ad es. il nome del traduttore)?
Come si può fare tutto questo chiamando il programma una volta sola?
Come personalizzare po4a?
3 Come funziona?
Questo capitolo fornisce una breve panoramica del funzionamento interno di po4a, in modo che vi possiate sentire a vostro agio se desiderate aiutarci nella manutenzione e contribuire al miglioramento di questo software. Il capitolo può anche aiutare a capire perché il programma non si comporta come ci si aspetta e a risolvere eventuali problemi.
4 FAQ
Questo capitolo raccoglie le domande ricorrenti, la maggior parte delle quali ora possono essere formulate in questo modo: ``Perché è stato progettato in questo modo e non in quest'altro?''. Se ritenete che po4a non sia la giusta soluzione per la traduzione della documentazione, vi consigliamo di leggere questa sezione; se questo non basta a rispondere alle vostre domande, contattateci alla mailing list <devel@lists.po4a.org>. Ci fa sempre molto piacere ricevere i vostri commenti.
5 Note specifiche ai singoli moduli
Questo capitolo espone le caratteristiche di ciascun modulo dal punto di vista del traduttore e dell'autore originale. Leggendolo, si apprenderanno la sintassi che si incontra nel tradurre documenti con questi moduli e le regole da seguire nel documento originale per rendere più facile la vita dei traduttori.

In realtà, questa sezione non fa realmente parte di questo documento. Invece, è inclusa nella documentazione dei singoli moduli. Mantenendo la documentazione insieme al codice, risulta più facile mantenere le informazioni aggiornate.

 

Perché dovrei usare po4a? A cosa serve?

Apprezzo molto l'idea del software open source e il fatto che permetta a chiunque di accedere ai programmi e al codice sorgente. Essendo francese, però, so anche che le licenze non sono le uniche restrizioni che un utente si trova ad affrontare: programmi liberi ma non tradotti sono inutili a chi non parla inglese, pertanto serve ancora qualche ulteriore sforzo per renderli accessibili veramente a tutti.

L'attenzione verso queste tematiche da parte della comunità open source è notevolmente aumentata negli ultimi tempi. Come traduttori, abbiamo vinto la prima battaglia convincendo la gente dell'importanza delle traduzioni. Ora, invece, viene la parte più difficile: portare avanti il nostro lavoro e tradurre tutti questi programmi.

In realtà, il software open source gode di un livello di traduzione piuttosto decente grazie alla splendida suite gettext, composta da strumenti che permettono di estrarre dal programma le stringhe da tradurre, presentare ai traduttori un formato uniforme ed infine, durante l'esecuzione, usare il risultato di questo lavoro per mostrare all'utente i messaggi tradotti.

La situazione purtroppo è molto diversa per quanto concerne la documentazione. Troppo spesso i documenti tradotti sono difficilmente accessibili (come quando non sono distribuiti insieme al programma), contengono solo informazioni parziali o, caso ancora peggiore, non sono aggiornati: una traduzione obsoleta può addirittura dare informazioni errate su un programma, ad esempio descrivendo un vecchio modo di funzionamento che ora non è più in uso.  

Il problema da risolvere

Tradurre la documentazione non presenta di per sé grosse difficoltà: anche se i documenti sono più lunghi dei messaggi dei programmi (e quindi una traduzione richiede più tempo per essere completata), non è realmente necessaria una particolare preparazione tecnica. La parte difficile arriva quando si deve mantenere aggiornato il proprio lavoro: capire quali parti sono cambiate e hanno bisogno di un aggiornamento è un compito impegnativo e profondamente noioso, inoltre è facile compiere errori. Immagino che questi siano i motivi per cui si vedono in giro così tanti documenti tradotti che non sono aggiornati.  

Le risposte di po4a

Lo scopo principale di po4a è di rendere manutenibili le traduzioni della documentazione. Il concetto chiave è l'utilizzo del metodo di gettext in questo nuovo campo: il testo viene estratto dalla posizione originale per poter essere presentato ai traduttori in un formato uniforme. In seguito, i classici strumenti forniti con gettext aiutano gli stessi traduttori ad aggiornare il proprio lavoro quando esce una nuova versione dell'originale ma, diversamente da quanto previsto dal modello classico di gettext, le traduzioni vengono reiniettate nella struttura del documento originale, così da poter essere elaborate e distribuite come la versione inglese.

Grazie a questo, diventa semplice scoprire quali parti del documento sono cambiate e necessitano di un aggiornamento. Un altro vantaggio è dato dal poter delegare la maggior parte del lavoro agli strumenti quando la struttura del documento originale viene riorganizzata completamente o quando dei capitoli sono spostati qua e là, raggruppati o divisi. Separando il testo da tradurre dalla struttura del documento, si permette inoltre al traduttore di rimanere ignaro della complessità richiesta dall'impaginazione, riducendo (ma non eliminando completamente) le possibilità di ottenere un documento con errori di formato.

Consultare la FAQ più avanti in questo documento per avere un elenco completo di vantaggi e svantaggi di questo approccio.  

Formati supportati

Attualmente, questo approccio è stato realizzato con successo per diversi formati di documenti di testo:

man

Il buon vecchio formato delle pagine di manuale, usato da così tanti programmi in circolazione. Il supporto di po4a è sicuramente benvenuto, dal momento che questo formato è alquanto difficile da usare direttamente e non è esattamente amichevole con i principianti. Il modulo Locale::Po4a::Man(3pm) supporta anche il formato mdoc, usato dalle pagine man BSD (molto diffuse anche su Linux).

pod

Questo è il formato della documentazione online di Perl. Il linguaggio e le estensioni stesse sono documentate in questo modo, così come molti degli script Perl esistenti. Inglobando entrambi nello stesso file, rende facile mantenere la documentazione vicina al codice corrispondente. Rende la vita più semplice al programmatore, ma sfortunatamente non al traduttore.

sgml

Anche se oggigiorno è stato in qualche modo superato da XML, questo formato è ancora molto spesso usato per documenti più lunghi di qualche schermata. Permette di creare libri completi. Aggiornare la traduzione di documenti così lunghi può rivelarsi un vero e proprio incubo. Strumenti come diff si rivelano spesso inutili quando il testo originale è stato riorganizzato dopo l'aggiormanento. Fortunatamente, po4a può aiutare molto in questo processo.

Al momento sono supportati solo i DTD DebianDoc e DocBook, ma aggiungere supporto a dei nuovi (DTD) è davvero facile. È perfino possibile usare po4a su un DTD SGML sconosciuto senza modificarne il codice, basta fornire le informazioni necessarie dalla riga di comando. Consultare Locale::Po4a::Sgml(3pm) per maggiori dettagli.

TeX / LaTeX

Il formato LaTeX è un formato di documentazione importante usato dal mondo del Free Software e da diverse pubblicazioni. Il modulo Locale::Po4a::LaTeX(3pm) è stato testato con la documentazione Python, un libro e alcune presentazioni.

texinfo

Tutta la documentazione GNU è stata scritta in questo formato (è persino uno dei requisiti per divenire un progetto GNU ufficiale). Il supporto per Locale::Po4a::Texinfo(3pm) in po4a è ancora agli inizi. Si prega di inviare eventuali segnalazioni di difetti e miglioramenti richiesti.

xml

Il formato XML è un formato base per molti formati di documentazione.

Attualmente, il DTD DocBook è supportato da po4a. Consultare Locale::Po4a::Docbook(3pm) per i dettagli.

altri

Po4a può anche gestire qualche altro formato raro o di uso specifico, ad esempio la documentazione delle opzioni di compilazione dei kernel 2.4.x, oppure i diagrammi prodotti dal programma Dia. Aggiungere un nuovo formato è spesso molto facile e il grosso del lavoro è produrre un parser per il formato scelto. Per maggiori informazioni su questo argomento, consultare Locale::Po4a::TransTractor(3pm).  

Formati non supportati

Sfortunatamente, a po4a manca ancora il supporto a molti formati di documentazione.

C'è un intera quantità di altri formati che vorremmo che po4a gestisse, non solo di documentazione. Ebbene, la nostra ambizione è di coprire tutte le «quote di mercato» lasciate vuote dal classico gettext. Essa comprende la documentazione di python, le descrizioni dei pacchetti (deb e rpm), le domande poste dagli script di installazione dei pacchetti, i changelog dei pacchetti e tutti i formati specializzati usati da vari programmi, come gli scenari dei giochi o i file delle risorse di wine.  

Come si usa po4a?

Questo capitolo è una sorta di guida di riferimento, pensata per rispondere alle domande degli utenti e fornire una migliore comprensione dell'intero processo. Essa presenta il modo in cui usare po4a e serve da introduzione alla documentazione dei singoli strumenti.  

Panoramica grafica

Il seguente schema fornisce una panoramica sul processo di traduzione di documentazione tramite l'uso di po4a. Non ci si spaventi a causa della sua apparente complessità, deriva dal fatto che viene qui rappresentato l'intero processo. Una volta che si è convertito il progetto a po4a, solo la parte destra del grafico è rilevante.

Si noti che master.doc viene preso come esempio di documentazione da tradurre mentre translation.doc è il testo corrispondente tradotto. Il suffisso può essere .pod, .xml, o .sgml a seconda del suo formato. Ogni parte dell'immagine verrà dettagliata nelle prossime sezioni.

                                   master.doc
                                       |
                                       V
     +<-----<----+<-----<-----<--------+------->-------->-------+
     :           |                     |                        :
{traduzione}     |      { aggiornamento di master.doc }         :
     :           |                     |                        :
   XX.doc        |                     V                        V
 (opzionale)     |                 master.doc ->-------->------>+
     :           |                  (nuovo)                     |
     V           V                     |                        |
  [po4a-gettextize]  doc.XX.po -->+    |                        |
          |          (vecchio)    |    |                        |
          |              ^        V    V                        |
          |              |     [po4a-updatepo]                  |
          V              |           |                          V
   translation.pot       ^           V                          |
          |              |       doc.XX.po                      |
          |              |        (fuzzy)                       |
   { traduzione }        |           |                          |
          |              ^           V                          V
          |              |   {modifica manuale}                 |
          |              |           |                          |
          V              |           V                          V
      doc.XX.po --->---->+<---<-- doc.XX.po    addendum     master.doc
      (iniziale)                (aggiornato)  (opzionale)  (aggiornato)
          :                          |            |             |
          :                          V            |             |
          +----->----->----->------> +            |             |
                                     |            |             |
                                     V            V             V
                                     +------>-----+------<------+
                                                  |
                                                  V
                                           [po4a-translate]
                                                  |
                                                  V
                                                XX.doc
                                             (aggiornato)

Sulla parte sinistra, si può osservare la conversione di una traduzione che non usa po4a. In alto a destra, viene illustrata l'azione dell'autore originale (aggiornare la documentazione). Nel centro della parte destra, sono raffigurate le azioni automatiche di po4a. Il nuovo materiale viene estratto e confrontato con la traduzione esistente. Rilevale le parti invariate, viene usata la traduzione precedente. Le parti parzialmente modificate vengono associate alla traduzione precedente, ma con una specifica marcatura indicante che la traduzione necessita di aggiornamento. La parte bassa della figura mostra come viene assemblato un documento completo.

Come traduttore, l'unica operazione che si deve fare a mano è la parte contrassegnata come {modifica manuale}. Purtroppo, po4a aiuta soltanto a tradurre; non è in grado di tradurre per voi...  

Come si inizia una nuova traduzione?

Questa sezione presenta i passi necessari per iniziare una nuova traduzione con po4a. Tutti i miglioramenti, le sottigliezze e i dettagli che riguardano la conversione di un progetto esistente all'uso di questo sistema sono esposti nella sezione relativa.

Per iniziare una nuova traduzione usando po4a, bisogna seguire i seguenti passi:

-
Estrarre il testo che deve essere tradotto dal documento originale <master.doc> in un nuovo file modello di traduzione <translation.pot> (nel formato gettext). Per effettuare questa operazione, usare il comando po4a-gettextize nel modo seguente:

  $ po4a-gettextize -f <formato> -m <master.doc> -p <translation.pot>

<formato> è naturalmente il formato usato nel documento master.doc. Come previsto, il risultato va in translation.pot. Fare riferimento a po4a-gettextize(1) per ulteriori informazioni sulle opzioni del comando.

-
Tradurre quello che dovrebbe essere tradotto. Per far ciò, è necessario rinominare il file POT per esempio in doc.XX.po (dove XX è il codice ISO 639-1 della lingua nella quale si sta traducendo, cioè fr per il francese), e modificare il file risultante. È spesso una buona idea non rinominare il file XX.po per evitare confusione con la traduzione dei messaggi del programma, ma è questione di gusti. Non si dimentichi di aggiornare le intestazioni del file PO, che sono importanti.

L'effettiva traduzione può essere eseguita usando la modalità PO di Emacs o di Vi, oppure usando Lokalize (basato su KDE), Gtranslator (basato su GNOME) o qualunque altro editor di file po si preferisca usare (per es. Virtaal).

Se si vuole saperne di più su questo argomento, è assolutamente necessario fare riferimento alla documentazione di gettext, disponibile nel pacchetto gettext-doc.

 

Completata la traduzione, come si ottiene un documento tradotto?

Una volta finito con la traduzione, si può voler prendere la documentazione tradotta e distribuirla agli utenti con quella originale. A questo scopo, usare il programma po4a-translate(1) in questo modo (dove XX è il codice lingua):

  $ po4a-translate -f <formato> -m <master.doc> -p <doc.XX.po> -l <XX.doc>

Come prima, <formato> è il formato usato per il documento master.doc. Ma questa volta, il file PO fornito con la flag -p è parte dell'ingresso. Questa è la traduzione. L'uscita va in XX.doc.

Fare riferimento a po4a-translate(1) per ulteriori dettagli.  

Come si aggiorna una traduzione con po4a?

Per aggiornare la traduzione se il file originale master.doc è cambiato, usare il programma po4a-updatepo(1) in questo modo:

  $ po4a-updatepo -f <formato> -m <nuovo_master.doc> -p <vecchio_doc.XX.po>

(fare riferimento a po4a-updatepo(1) per i dettagli)

Naturalmente, il nuovo paragrafo nel documento non verrà magicamente tradotto nel file PO con quest'operazione, e sarà necessario aggiornare manualmente il file PO. Analogamente, è necessario riprendere in mano la traduzione dei paragrafi che siano stati modificati. Per assicurarci che non si perda nulla, questi vengono marcati come ``fuzzy'' durante il processo ed è necessario rimuovere questa marcatura prima che la traduzione possa essere usata da po4a-translate. Come per la traduzione iniziale, a questo scopo si può usare l'editor di file PO di proprio gradimento.

Una volta che il file PO sia stato nuovamente aggiornato, senza tralasciare nessuna stringa non tradotta o marcata come fuzzy, è possibile generare un file di documentazione tradotto, come spiegato nella sezione precedente.  

Come si converte una traduzione già esistente all'uso di po4a?

Spesso si è tradotto felicemente il documento manualmente fino alla successiva riorganizzazione generale del documento originale master.doc. Poi, dopo qualche spiacevole tentativo con diff o strumenti simili, si è deciso di convertirsi a po4a. Ma naturalmente nel processo non si vorrebbe perdere tutto ciò che è stato sin quì tradotto. Tranquilli, anche questa situazione può essere gestita dagli strumenti di po4a: la procedura si chiama gettext-tizzazione.

Il concetto chiave quì è di avere la stessa struttura nel documento tradotto e nell'originale, in modo che gli strumenti (N.d.T di po4a) ne possano rispettivamente confrontare i contenuti.

Se si è fortunati (cioè se le strutture di entrambi i documenti combaciano perfettamente), si lavorerà senza intoppi e si otterranno risultati in pochi secondi. Altrimenti, si scoprirà perché questo processo ha un nome così brutto, e sarà meglio essere preparati ad un po' di lavoro. In ogni caso, è meglio ricordarsi che è il prezzo da pagare per ottenere in seguito la comodità di po4a. E l'aspetto positivo è che è necessario farlo solo una volta.

Questo fatto deve essere assolutamente chiaro. Per facilitare il processo, è importante trovare e impiegare l'esatta versione utilizzata per fare la traduzione. L'ideale è annotarsi il numero di versione VCS usata per la traduzione ed estrarne una copia non modificata dal processo di traduzione, in modo da poterla usare.

Il procedimento non funzionerà bene se si userà la versione aggiornata del testo originale con la vecchia traduzione. Sarà ancora possibile, ma è più difficile (N.d.T avere dei risultati di qualità) e andrebbe evitato se possibile.

Forse sono stato troppo negativo. Anche se le cose dovessero andare male, rimane molto più veloce che tradurre tutto nuovamente. Sono stato in grado di gettext-izzare l'esistente traduzione francese della documentazione Perl in un giorno, anche se le cose sono andate male. Erano più di due megabyte di testo, ed una nuova traduzione mi avrebbe impegnato per mesi o più.

Spiegheremo prima le basi della procedura, poi si tornerà sui suggerimenti per riuscire quando il processo va storto. Per semplificare la comprensione, usiamo ancora l'esempio di prima.

Una volta ottenuto il vecchio master.doc nuovamente corrispondente alla traduzione XX.doc, la gettext-izzazione può essere effettuata direttamente sul file PO doc.XX.po senza la traduzione manuale del file translation.pot:

 $ po4a-gettextize -f <formato> -m <vecchio_master.doc> -l <XX.doc> -p <doc.XX.po>

Se siamo fortunati, questo è tutto. Abbiamo convertito la vecchia traduzione a po4a e possiamo subito cominciare con l'aggiornamento. Basta seguire la procedura spiegata poche sezioni fa per sincronizzare il file PO con il nuovo documento originale, ed aggiornare corrispondentemente la traduzione.

Si noti che anche quando le cose sembrano funzionare correttamente, c'è sempre spazio per errori in questo processo. Il punto è che po4a non è in grado di capire il testo per assicurarsi che la traduzione corrisponda all'originale. Ecco perché tutte le stringhe vengono marchiate come ``fuzzy'' nel processo. Si dovrebbe controllarle una ad una con attenzione prima di rimuovere questi marcatori.

Spesso le strutture della documentazione non corrispondono esattamente, impendendo a po4a-gettextize di fare correttamente il suo lavoro. A questo punto, il gioco consiste nel modificare i file per fare in modo che le loro maledette strutture corrispondano.

Può aiutare la lettura della sezione Gettextizzazione: come funziona? sottostante. Comprendere il processo interno aiuterà a farlo funzionare. La cosa positiva è che po4a-gettextize è piuttosto prolisso su cosa non ha funzionato quando succede. Per primo, indica esattamente dove nella struttura della documentazione vi sono delle discrepanze. Indica le stringhe che non corrispondono, la loro posizione nel testo, e il tipo di ognuna di esse. Inoltre, il file PO generato fin lì verrà scaricato in gettextization.failed.po.

-
Rimuove tutte le parti extra delle traduzioni, come la sezione nella quale si dà il nome del traduttore e si ringrazia tutte le persone che hanno contribuito alla traduzione. Gli addenda, descritti nella prossima sezione, permettono di ri-aggiungerli in seguito.
-
Non si esitati a modificare sia l'originale che la traduzione. La cosa più importante è ottenere il file PO. In seguito lo si potrà eventualmente aggiornare. Detto questo, la modifica della traduzione dovrebbe essere preferita quando entrambe sono possibili, poiché rende le cose più semplici quando viene eseguita la gettext-tizzazione.
-
Se necessario, eliminare alcune parti dell'originale se non sono state tradotte. Quando in seguito si sincronizzerà il file PO con il documento, queste torneranno da sole.
-
Se si ha modificato un po' la struttura (per unire o dividere due paragrafi), annullare queste modifiche. Se ci sono problemi nell'originale, bisogna informare l'autore originale. La correzione nella traduzione corregge solo per una parte della comunità. Inoltre è in pratica impossibile quando si usa po4a.
-
A volte, il contenuto dei paragrafi corrisponde, ma i loro tipi no. La correzione è abbastanza dipendente dal formato. Nel POD e nelle pagine man, spesso deriva dal fatto che uno dei due paragrafi contiene una riga che inizia con uno spazio bianco mentre l'altro paragrafo no. In quei formati, tali paragrafi non possono essere spostati e quindi diventare di un tipo diverso. In tal caso basta rimuovere lo spazio e si è a posto. Alle volte si tratta anche di un semplice refuso nel nome del marcatore.

Allo stesso modo, due paragrafi possono venire uniti assieme nel POD quando la riga di separazione contiene alcuni spazi, o quando non c'è una riga vuota tra la riga dell'elemento =qualcosa e il contenuto dell'elemento stesso.

-
A volte, c'è una desincronizzazione tra i file, e la traduzione viene allegata al paragrafo originale sbagliato. È il segno che il vero problema era prima nei file. Controllare gettextization.failed.po per vedere quando inizia la desincronizzazione e correggerla lì.
-
A volte, si ha forte sospetto che po4a abbia mangiato alcune parti del testo, sia l'originale che la traduzione. gettextization.failed.po indica che erano entrambi parzialmente corrispondenti, e quindi la gettext-tizzazione fallisce perché ha cercato di abbinare un paragrafo a quello dopo (o prima) di quello giusto, come se quello giusto scomparisse. In questo caso può servire maledire con veemenza po4a, come fatto il sottoscritto quando m'è capitato per la prima volta.

Questa sfortunata situazione si verifica quando uno stesso paragrafo si ripete più volte nel documento. In questo caso nel file PO non viene creata nessuna voce aggiuntiva, ma viene invece aggiunto un nuovo riferimento all'esistente.

Quindi, quando lo stesso paragrafo appare due volte nell'originale ma questi due non vengono tradotti allo stesso modo, si avrà la sensazione che un paragrafo dell'originale sia scomparso. Basta cancellare la nuova traduzione. Se si preferisce, cancellare la prima traduzione invece della seconda, quando la seconda è effettivamente migliore.

In the contrary, if two similar but different paragraphs were translated in the exact same way, you will get the feeling that a paragraph of the translation disappeared. A solution is to add a stupid string to the original paragraph (such as ``I'm different''). Don't be afraid, those things will disappear during the synchronization, and when the added text is short enough, gettext will match your translation to the existing text (marking it as fuzzy, but you don't really care since all strings are fuzzy after gettextization).

Hopefully, those tips will help you making your gettextization work and obtain your precious PO file. You are now ready to synchronize your file and begin your translation. Please note that on large text, it may happen that the first synchronization takes a long time.

For example, the first po4a-updatepo of the Perl documentation's French translation (5.5 Mb PO file) took about two days full on a 1Ghz G5 computer. Yes, 48 hours. But the subsequent ones only take a dozen of seconds on my old laptop. This is because the first time, most of the msgid of the PO file don't match any of the POT file ones. This forces gettext to search for the closest one using a costly string proximity algorithm.  

Come si aggiunge del testo extra (ad es. il nome del traduttore)?

Because of the gettext approach, doing this becomes more difficult in po4a than it was when simply editing a new file along the original one. But it remains possible, thanks to the so-called addenda.

It may help the comprehension to consider addenda as a sort of patches applied to the localized document after processing. They are rather different from the usual patches (they have only one line of context, which can embed Perl regular expression, and they can only add new text without removing any), but the functionalities are the same.

Their goal is to allow the translator to add extra content to the document which is not translated from the original document. The most common usage is to add a section about the translation itself, listing contributors and explaining how to report bug against the translation.

An addendum must be provided as a separate file. The first line constitutes a header indicating where in the produced document they should be placed. The rest of the addendum file will be added verbatim at the determined position of the resulting document.

The header line which specify context has a pretty rigid syntax: It must begin with the string PO4A-HEADER:, followed by a semi-colon (;) separated list of key=value fields. White spaces ARE important. Note that you cannot use the semi-colon char (;) in the value, and that quoting it doesn't help. Optionally, spaces ( ) may be inserted before key for readability.

Although this context search may be considered to operate roughly on each line of the translated document, it actually operates on the internal data string of the translated document. This internal data string may be a text spanning a paragraph containing multiple lines or may be a XML tag itself alone. The exact insertion point of the addendum must be before or after the internal data string and can not be within the internal data string.

The actual internal data string of the translated document can be visualized by executing po4a in debug mode.

Again, it sounds scary, but the examples given below should help you to find how to write the header line you need. To illustrate the discussion, assume we want to add a section called ``About this translation'' after the ``About this document'' one.

Ecco le possibili chiavi di intestazioni:

mode (obbligatorio)
It can be either the string before or after.

If mode=before, the insertion point is determined by one step regex match specified by the position argument regex. The insertion point is immediately before the uniquely matched internal data string of the translated document.

If mode=after, the insertion point is determined by two step regex matches specified by the position argument regex; and by the beginboundary or endboundary argument regex.

Since there may be multiple sections for the assumed case, let's use 2 step approach.

     mode=after

position (obbligatorio)
A Perl regexp for specifying the context.

If more than one internal data strings match this expression (or none), the search for the insertion point and addition of the addendum will fail. It is indeed better to report an error than inserting the addendum at the wrong location.

If mode=before, the insertion point is specified to be immediately before the internal data string uniquely matching the position argument regex.

If mode=after, the search for the insertion point is narrowed down to the data after the internal data string uniquely matching the position argument regex. The exact insertion point is further specified by the beginboundary or endboundary.

In our case, we need to skip several preceding sections by narrowing down search using the section title string.

     position=Su questo documento

(In reality, you need to use the translated section title string here, instead.)

beginboundary (used only when mode=after, and mandatory in that case)
endboundary (idem)
A second Perl regexp required only when mode=after. The addendum will be placed immediately before or after the first internal data string matching the beginboundary or endboundary argument regexp, respectively.

Nel nostro caso, possiamo scegliere di indicare la fine della sezione che controlliamo aggiungendo:

   endboundary=</section>

o di indicare l'inizio della prossima sezione indicando:

   beginboundary=<section>

In entrambi i casi, il nostro addendum verrà piazzato dopo </section> e prima di <section>. Il primo è meglio dato che funzionerà anche se il documento viene riorganizzato.

Both forms exist because documentation formats are different. In some of them, there is a way to mark the end of a section (just like the </section> we just used), while some other don't explicitly mark the end of section (like in man). In the former case, you want to make a boundary matching the end of a section, so that the insertion point comes after it. In the latter case, you want to make a boundary matching the beginning of the next section, so that the insertion point comes just before it.

This can seem obscure, but hopefully, the next examples will enlighten you.

To sum up the example we used so far, in order to add a section called "About this translation" after the "About this document" one in a SGML document, you can use either of those header lines:
 PO4A-HEADER: mode=after; position=About this document; endboundary=</section>
 PO4A-HEADER: mode=after; position=About this document; beginboundary=<section>

If you want to add something after the following nroff section:
  .SH "AUTHORS"

You should select two step approach by setting mode=after. Then you should narrow down search to the line after AUTHORS with the position argument regex. Then, you should match the beginning of the next section (i.e., ^\.SH) with the beginboundary argument regex. That is to say:

 PO4A-HEADER:mode=after;position=AUTHORS;beginboundary=\.SH

If you want to add something into a section (like after "Copyright Big Dude") instead of adding a whole section, give a position matching this line, and give a beginboundary matching any line.
 PO4A-HEADER:mode=after;position=Copyright Big Dude, 2004;beginboundary=^

If you want to add something at the end of the document, give a position matching any line of your document (but only one line. Po4a won't proceed if it's not unique), and give an endboundary matching nothing. Don't use simple strings here like "EOF", but prefer those which have less chance to be in your document.
 PO4A-HEADER:mode=after;position=About this document;beginboundary=FakePo4aBoundary

In any case, remember that these are regexp. For example, if you want to match the end of a nroff section ending with the line

  .fi

don't use .fi as endboundary, because it will match with ``the[ fi]le'', which is obviously not what you expect. The correct endboundary in that case is: ^\.fi$.

If the addendum doesn't go where you expected, try to pass the -vv argument to the tools, so that they explain you what they do while placing the addendum.

More detailed example

Original document (POD formatted):

 |=head1 NAME
 |
 |dummy - a dummy program
 |
 |=head1 AUTHOR
 |
 |me

Then, the following addendum will ensure that a section (in French) about the translator is added at the end of the file (in French, ``TRADUCTEUR'' means ``TRANSLATOR'', and ``moi'' means ``me'').

 |PO4A-HEADER:mode=after;position=AUTEUR;beginboundary=^=head
 |
 |=head1 TRADUCTEUR
 |
 |moi
 |

In order to put your addendum before the AUTHOR, use the following header:

 PO4A-HEADER:mode=after;position=NOM;beginboundary=^=head1

This works because the next line matching the beginboundary /^=head1/ after the section ``NAME'' (translated to ``NOM'' in French), is the one declaring the authors. So, the addendum will be put between both sections. Note that if another section is added between NAME and AUTHOR sections later, po4a will wrongfully put the addenda before the new section.

To avoid this you may accomplish the same using mode=before:

 PO4A-HEADER:mode=before;position=^=head1 AUTEUR

 

Come si può fare tutto questo chiamando il programma una volta sola?

The use of po4a proved to be a bit error prone for the users since you have to call two different programs in the right order (po4a-updatepo and then po4a-translate), each of them needing more than 3 arguments. Moreover, it was difficult with this system to use only one PO file for all your documents when more than one format was used.

The po4a(1) program was designed to solve those difficulties. Once your project is converted to the system, you write a simple configuration file explaining where your translation files are (PO and POT), where the original documents are, their formats and where their translations should be placed.

Then, calling po4a(1) on this file ensures that the PO files are synchronized against the original document, and that the translated document are generated properly. Of course, you will want to call this program twice: once before editing the PO files to update them and once afterward to get a completely updated translated document. But you only need to remember one command line.  

Come personalizzare po4a?

po4a modules have options (specified with the -o option) that can be used to change the module behavior.

You can also edit the source code of the existing modules or even write your own modules. To make them visible to po4a, copy your modules into a path called "/bli/blah/blu/lib/Locale/Po4a/" and then adding the path "/bli/blah/blu" in the "PERLIB" or "PERL5LIB" environment variable. For example:

   PERLLIB=$PWD/lib po4a --previous po4a/po4a.cfg

Note: the actual name of the lib directory is not important.  

Come funziona?

Questo capitolo fornisce una breve panoramica del funzionamento interno di po4a, in modo che vi possiate sentire a vostro agio se desiderate aiutarci nella manutenzione e contribuire al miglioramento di questo software. Il capitolo può anche aiutare a capire perché il programma non si comporta come ci si aspetta e a risolvere eventuali problemi.  

Qual'è il quadro d'insieme?

L'architettura po4a è object oriented (in Perl. Non è fantastico?). L'antenato comune di tutte le classi parser si chiama TransTractor. Questo strano nome deriva dal fatto che è allo stesso tempo incaricato di tradurre il documento e di estrarne le stringhe.

Più formalmente, esso prende un documento da tradurre più un file PO contenente le traduzioni da usare come ingresso producendo due risultati separati: un altro file PO (risultato dall'estrazione delle stringhe traducibili dal documento in ingresso), e un documento tradotto (con la stessa struttura di quello in ingresso, ma con tutte le stringhe traducibili rimpiazzate dal contenuto del file PO in ingresso). Ecco una rappresentazione grafica di tutto ciò:

   Documento in ingresso --\                             /---> Documento in uscita
                            \      TransTractor::       /      (tradotto)
                            +-->--   parse()  --------+
                            /                           \
   PO in ingresso ---------/                             \---> PO in uscita
                                                               (estratto)

Questa piccola ossatura è il cuore di tutta l'architettura di po4a. Se si omette il file PO in ingresso e il documento in uscita, si ottiene po4a-gettextize. Se si fornisce entrambi gli ingressi e si ignora il file PO in uscita, si ottiene po4a-translate. po4a chiama TransTractor due volte e chiama msgmerge -U tra queste invocazioni di TransTractor per fornire una soluzione tutta in uno con un singolo file di configurazione.

TransTractor::parse() è una funzione virtuale implementata da ogni modulo. Ecco un piccolo esempio che mostra come essa lavori. Questa analizza un elenco di paragrafi, ogniuno dei quali che comincia con <p>.

  1 sub parse {
  2   PARAGRAPH: while (1) {
  3     $my ($paragraph,$pararef,$line,$lref)=("","","","");
  4     $my $first=1;
  5     while (($line,$lref)=$document->shiftline() && defined($line)) {
  6       if ($line =~ m/<p>/ && !$first--; ) {
  7         $document->unshiftline($line,$lref);
  8
  9         $paragraph =~ s/^<p>//s;
 10         $document->pushline("<p>".$document->translate($paragraph,$pararef));
 11
 12         next PARAGRAPH;
 13       } else {
 14         $paragraph .= $line;
 15         $pararef = $lref unless(length($pararef));
 16       }
 17     }
 18     return; # Did not got a defined line? End of input file.
 19   }
 20 }

On line 6 and 7, we encounter "shiftline()" and "unshiftline()". These help you to read and unread the head of internal input data stream of master document into the line string and its reference. Here, the reference is provided by a string "$filename:$linenum". Please remember Perl only has one dimensional array data structure. So codes handling the internal input data stream line are a bit cryptic.

Alla riga 6, si incontra <p> per la seconda volta. Quello è il segnale del prossimo paragrafo. Si dovrebbe perciò mettere ciò che si è appena ottenuto indietro nel documento originale (riga 7) e mettere il paragrafo così costruito nel risultato. Dopo aver rimosso l'iniziale <p> di esso alla riga 9, si inserisce la concatenazione di questa marcatura con la traduzione del resto del paragrafo.

Questa funzione translate() è molto intelligente. Spinge il suo argomento nel file PO risultante (estrazione) e ritorna la sua traduzione come trovata nel file PO in ingresso (traduzione). Dato che è usata come parte dell'argomento di pushline(), questa traduzione finisce nel documento in uscita.

Non è furbo? È possibile creare un modulo po4a completo in meno di 20 righe se il formato è abbastanza semplice...

È possibile sapere di più su questo argomento in Locale::Po4a::TransTractor(3pm).  

Gettextizzazione: come funziona?

L'idea qui è di prendere il documento originale e la sua traduzione, e dire che la N-esima stringa estratta dalla traduzione è la traduzione della N-esima stringa estratta dall'originale. Per funzionare, entrambi i file devono condividere esattamente la stessa struttura. Per esempio, se i file hanno la seguente struttura, è molto improbabile che la quarta stringa nella traduzione (di tipo 'capitolo') sia la traduzione della quarta stringa nell'originale (di tipo 'paragrafo').

    Originale        Traduzione

  capitolo           capitolo
    paragrafo          paragrafo
    paragrafo          paragrafo
    paragrafo        chapter
  capitolo             paragrafo
    paragrafo          paragrafo

For that, po4a parsers are used on both the original and the translation files to extract PO files, and then a third PO file is built from them taking strings from the second as translation of strings from the first. In order to check that the strings we put together are actually the translations of each other, document parsers in po4a should put information about the syntactical type of extracted strings in the document (all existing ones do so, yours should also). Then, this information is used to make sure that both documents have the same syntax. In the previous example, it would allow us to detect that string 4 is a paragraph in one case, and a chapter title in another case and to report the problem.

In theory, it would be possible to detect the problem, and resynchronize the files afterward (just like diff does). But what we should do of the few strings before desynchronizations is not clear, and it would produce bad results some times. That's why the current implementation don't try to resynchronize anything and verbosely fail when something goes wrong, requiring manual modification of files to fix the problem.

Even with these precautions, things can go wrong very easily here. That's why all translations guessed this way are marked fuzzy to make sure that the translator reviews and checks them.  

Addendum: come funzionano?

Well, that's pretty easy here. The translated document is not written directly to disk, but kept in memory until all the addenda are applied. The algorithms involved here are rather straightforward. We look for a line matching the position regexp, and insert the addendum before it if we're in mode=before. If not, we search for the next line matching the boundary and insert the addendum after this line if it's an endboundary or before this line if it's a beginboundary.  

FAQ

Questo capitolo raccoglie le domande ricorrenti, la maggior parte delle quali ora possono essere formulate in questo modo: ``Perché è stato progettato in questo modo e non in quest'altro?''. Se ritenete che po4a non sia la giusta soluzione per la traduzione della documentazione, vi consigliamo di leggere questa sezione; se questo non basta a rispondere alle vostre domande, contattateci alla mailing list <devel@lists.po4a.org>. Ci fa sempre molto piacere ricevere i vostri commenti.  

Perché tradurre ogni paragrafo separatamente?

Yes, in po4a, each paragraph is translated separately (in fact, each module decides this, but all existing modules do so, and yours should also). There are two main advantages to this approach:
When the technical parts of the document are hidden from the scene, the translator can't mess with them. The fewer markers we present to the translator the less error he can do.
Cutting the document helps in isolating the changes to the original document. When the original is modified, finding what parts of the translation need to be updated is eased by this process.

Even with these advantages, some people don't like the idea of translating each paragraph separately. Here are some of the answers I can give to their fear:

This approach proved successfully in the KDE project and allows people there to produce the biggest corpus of translated and up to date documentation I know.
The translators can still use the context to translate, since the strings in the PO file are in the same order than in the original document. Translating sequentially is thus rather comparable whether you use po4a or not. And in any case, the best way to get the context remains to convert the document to a printable format since the text formatting ones are not really readable, IMHO.
This approach is the one used by professional translators. I agree, that they have somewhat different goals than open-source translators. The maintenance is for example often less critical to them since the content changes rarely.
 

Why not to split on sentence level (or smaller)?

Professional translator tools sometimes split the document at the sentence level in order to maximize the reusability of previous translations and speed up their process. The problem is that the same sentence may have several translations, depending on the context.

Paragraphs are by definition longer than sentences. It will hopefully ensure that having the same paragraph in two documents will have the same meaning (and translation), regardless of the context in each case.

Splitting on smaller parts than the sentence would be very bad. It would be a bit long to explain why here, but interested reader can refer to the Locale::Maketext::TPJ13(3pm) man page (which comes with the Perl documentation), for example. To make short, each language has its specific syntactic rules, and there is no way to build sentences by aggregating parts of sentences working for all existing languages (or even for the 5 of the 10 most spoken ones, or even less).  

Why not put the original as comment along with translation (or the other way around)?

At the first glance, gettext doesn't seem to be adapted to all kind of translations. For example, it didn't seem adapted to debconf, the interface all Debian packages use for their interaction with the user during installation. In that case, the texts to translate were pretty short (a dozen lines for each package), and it was difficult to put the translation in a specialized file since it has to be available before the package installation.

That's why the debconf developer decided to implement another solution, where translations are placed in the same file than the original. This is rather appealing. One would even want to do this for XML, for example. It would look like that:

 <section>
  <title lang="en">My title</title>
  <title lang="fr">Mon titre</title>

  <para>
   <text lang="en">My text.</text>
   <text lang="fr">Mon texte.</text>
  </para>
 </section>

But it was so problematic that a PO-based approach is now used. Only the original can be edited in the file, and the translations must take place in PO files extracted from the master template (and placed back at package compilation time). The old system was deprecated because of several issues:

maintenance problems

If several translators provide a patch at the same time, it gets hard to merge them together.

How will you detect changes to the original, which need to be applied to the translations? In order to use diff, you have to note which version of the original you translated. I.e., you need a PO file in your file ;)

encoding problems

This solution is viable when only European languages are involved, but the introduction of Korean, Russian and/or Arab really complicate the picture. UTF could be a solution, but there are still some problems with it.

Moreover, such problems are hard to detect (i.e., only Korean readers will detect that the encoding of Korean is broken [because of the Russian translator]).

gettext solves all those problems together.  

But gettext wasn't designed for that use!

That's true, but until now nobody came with a better solution. The only known alternative is manual translation, with all the maintenance issues.  

What about the other translation tools for documentation using gettext?

As far as I know, there are only two of them:
poxml
This is the tool developed by KDE people to handle DocBook XML. AFAIK, it was the first program to extract strings to translate from documentation to PO files, and inject them back after translation.

It can only handle XML, and only a particular DTD. I'm quite unhappy with the handling of lists, which end in one big msgid. When the list become big, the chunk becomes harder to swallow.

po-debiandoc
This program done by Denis Barbier is a sort of precursor of the po4a SGML module, which more or less deprecates it. As the name says, it handles only the DebianDoc DTD, which is more or less a deprecated DTD.

The main advantages of po4a over them are the ease of extra content addition (which is even worse there) and the ability to achieve gettextization.  

Educating developers about translation

When you try to translate documentation or programs, you face three kinds of problems; linguistics (not everybody speaks two languages), technical (that's why po4a exists) and relational/human. Not all developers understand the necessity of translating stuff. Even when good willed, they may ignore how to ease the work of translators. To help with that, po4a comes with lot of documentation which can be referred to.

Another important point is that each translated file begins with a short comment indicating what the file is, how to use it. This should help the poor developers flooded with tons of files in different languages they hardly speak, and help them dealing correctly with it.

In the po4a project, translated documents are not source files anymore, in the sense that these files are not the preferred form of the work for making modifications to it. Since this is rather unconventional, that's a source of easy mistakes. That's why all files present this header:

 |       *****************************************************
 |       *           GENERATED FILE, DO NOT EDIT             *
 |       * THIS IS NO SOURCE FILE, BUT RESULT OF COMPILATION *
 |       *****************************************************
 |
 | This file was generated by po4a-translate(1). Do not store it (in VCS,
 | for example), but store the PO file used as source file by po4a-translate.
 |
 | In fact, consider this as a binary, and the PO file as a regular source file:
 | If the PO gets lost, keeping this translation up-to-date will be harder ;)

Likewise, gettext's regular PO files only need to be copied to the po/ directory. But this is not the case of the ones manipulated by po4a. The major risk here is that a developer erases the existing translation of his program with the translation of his documentation. (Both of them can't be stored in the same PO file, because the program needs to install its translation as an mo file while the documentation only uses its translation at compile time). That's why the PO files produced by the po-debiandoc module contain the following header:

 #
 #  ADVISES TO DEVELOPERS:
 #    - you do not need to manually edit POT or PO files.
 #    - this file contains the translation of your debconf templates.
 #      Do not replace the translation of your program with this !!
 #        (or your translators will get very upset)
 #
 #  ADVISES TO TRANSLATORS:
 #    If you are not familiar with the PO format, gettext documentation
 #     is worth reading, especially sections dedicated to this format.
 #    For example, run:
 #         info -n '(gettext)PO Files'
 #         info -n '(gettext)Header Entry'
 #
 #    Some information specific to po-debconf are available at
 #            /usr/share/doc/po-debconf/README-trans
 #         or http://www.debian.org/intl/l10n/po-debconf/README-trans
 #

 

SUMMARY of the advantages of the gettext based approach

The translations are not stored along with the original, which makes it possible to detect if translations become out of date.
The translations are stored in separate files from each other, which prevents translators of different languages from interfering, both when submitting their patch and at the file encoding level.
It is based internally on gettext (but po4a offers a very simple interface so that you don't need to understand the internals to use it). That way, we don't have to re-implement the wheel, and because of their wide use, we can think that these tools are more or less bug free.
Nothing changed for the end-user (beside the fact translations will hopefully be better maintained). The resulting documentation file distributed is exactly the same.
No need for translators to learn a new file syntax and their favorite PO file editor (like Emacs' PO mode, Lokalize or Gtranslator) will work just fine.
gettext offers a simple way to get statistics about what is done, what should be reviewed and updated, and what is still to do. Some example can be found at those addresses:

 - https://docs.kde.org/stable5/en/kdesdk/lokalize/project-view.html
 - http://www.debian.org/intl/l10n/

But everything isn't green, and this approach also has some disadvantages we have to deal with.

Addenda are… strange at the first glance.
You can't adapt the translated text to your preferences, like splitting a paragraph here, and joining two other ones there. But in some sense, if there is an issue with the original, it should be reported as a bug anyway.
Even with an easy interface, it remains a new tool people have to learn.

One of my dreams would be to integrate somehow po4a to Gtranslator or Lokalize. When a documentation file is opened, the strings are automatically extracted, and a translated file + po file can be written to disk. If we manage to do an MS Word (TM) module (or at least RTF) professional translators may even use it.

 

AUTORI

 Denis Barbier <barbier,linuxfr.org>
 Martin Quinson (mquinson#debian.org)

 

TRADUZIONE

 Danilo Piazzalunga <danilopiazza@libero.it>
 Marco Ciampa <ciampix@libero.it>


 

Index

NOME
Introduzione
Sommario
Perché dovrei usare po4a? A cosa serve?
Il problema da risolvere
Le risposte di po4a
Formati supportati
Formati non supportati
Come si usa po4a?
Panoramica grafica
Come si inizia una nuova traduzione?
Completata la traduzione, come si ottiene un documento tradotto?
Come si aggiorna una traduzione con po4a?
Come si converte una traduzione già esistente all'uso di po4a?
Come si aggiunge del testo extra (ad es. il nome del traduttore)?
Come si può fare tutto questo chiamando il programma una volta sola?
Come personalizzare po4a?
Come funziona?
Qual'è il quadro d'insieme?
Gettextizzazione: come funziona?
Addendum: come funzionano?
FAQ
Perché tradurre ogni paragrafo separatamente?
Why not to split on sentence level (or smaller)?
Why not put the original as comment along with translation (or the other way around)?
But gettext wasn't designed for that use!
What about the other translation tools for documentation using gettext?
Educating developers about translation
SUMMARY of the advantages of the gettext based approach
AUTORI
TRADUZIONE

This document was created by using the manual pages.
Time: 11:07:06 GMT, December 10, 2018
català Deutsch English español français Italiano 日本語 Bokmål polski Português Português (Brasil) Русский український 简体中文 (how to set the default document language)