PO4A.7(1)

NAAM
po4a - raamwerk voor de vertaling van documentatie en ander materiaal

Inleiding
po4a (PO voor alles) vergemakkelijkt het onderhoud van de vertaling van documentatie via het gebruik van het klassieke gettext-gereedschap. De belangrijkste eigenschap van po4a is dat het de vertaling van de inhoud loskoppelt van de structuur van het document.

Dit document dient als een inleiding tot het po4a-project met een focus op potentiële gebruikers die zich afvragen of ze dit hulpmiddel zouden gebruiken, en op nieuwsgierigen die willen begrijpen waarom de dingen zijn zoals ze zijn.

Waarom po4a?
De filosofie van Vrije Software is om de technologie echt voor iedereen beschikbaar te maken. Maar het licentie-aspect is niet het enige om in overweging te nemen: voor niet-Engelstaligen is niet-vertaalde software nutteloos. Daarom hebben we nog steeds wat werk te doen om software voor iedereen beschikbaar te maken.

Door de meeste projecten wordt deze situatie goed begrepen en iedereen is nu overtuigd van de noodzaak om alles te vertalen. Niettemin betekent het eigenlijke vertaalwerk een geweldige inspanning voor veel individuen, gehandicapt door kleine technische moeilijkheden.

Gelukkig wordt opensourcesoftware eigenlijk heel goed vertaald met behulp van de gettext gereedschapssuite. Dit gereedschap wordt gebruikt om de te vertalen tekstfragmenten uit een programma te extraheren en deze te vertalen tekstfragmenten aan te bieden in een gestandaardiseerde indeling (PO-bestanden genoemd, ofwel vertaalcatalogus). Een heel ecosysteem hulpmiddelen is ontstaan om vertalers te helpen bij het daadwerkelijk vertalen van deze PO-bestanden. Het resultaat wordt vervolgens door gettext gebruikt om tijdens de programmauitvoering de vertaalde berichten aan de eindgebruiker te tonen.

Regarding documentation, however, the situation still somewhat disappointing. At first translating documentation may seem to be easier than translating a program as it would seem that you just have to copy the documentation source file and start translating the content. However, when the original documentation is modified, keeping track of the modifications quickly turns into a nightmare for the translators. If done manually, this task is unpleasant and error-prone.

Verouderde vertalingen zijn vaak erger dan helemaal geen vertaling. Eindgebruikers kunnen misleid worden door documentatie die een verouderd gedrag van het programma beschrijft. Bovendien kunnen zij niet rechtstreeks in interactie treden met de onderhouders, omdat zij geen Engels spreken. Daarenboven kan de onderhouder het probleem niet oplossen, aangezien deze niet elke taal kan kennen waarin de documentatie vertaald werd. Deze moeilijkheden, vaak veroorzaakt door slecht gereedschap, kan de motivatie van vertaalvrijwilligers ondermijnen en zo leiden tot een verdere verergering van het probleem.

Het doel van het po4a-project is om het werk van documentatievertalers te vergemakkelijken. In het bijzonder maakt het documentatievertalingen onderhoudbaar.

Het idee bestaat erin de gettext-aanpak te hergebruiken en aan te passen aan deze sector. Zoals dat met gettext het geval is, worden teksten geëxtraheerd uit hun originele locatie en aan vertalers voorgelegd als PO-vertaalcatalogi. De vertalers kunnen gebruik maken van het klassieke gettext-gereedschap om het te presteren werk op te volgen, om samen te werken en zich als team te organiseren. Daarna injecteert po4a de vertalingen rechtstreeks in de structuur van de documentatie om vertaalde bronbestanden te produceren die verwerkt en verspreid kunnen worden, net als de Engelse bestanden. Elke onvertaalde paragraaf blijft in het uiteindelijke document in het Engels staan, zodat er voor gezorgd wordt dat de eindgebruiker nooit een verouderde vertaling te zien krijgt in de documentatie.

Dit automatiseert het grootste deel van het zware werk van het onderhoud van vertalingen. Te weten komen welke paragrafen bijgewerkt moeten worden, wordt erg makkelijk, en het proces van het herordenen van elementen zonder dat er verder iets wijzigt, verloopt volledig automatisch. Ook kan specifieke verificatie toegepast worden om de kans op opmaakfouten, welke tot een defect document zouden leiden, te verkleinen.

Raadpleeg ook de FAQ verder in dit document, voor een meer volledige lijst van de voor- en nadelen van deze aanpak.

  Ondersteunde indelingen
Momenteel werd deze aanpak met succes toegepast voor verschillende soorten tekstopmaakindelingen:

man (voldragen ontleder)
    De goede oude man-paginaindeling, welke door zoveel programma's gebruikt wordt. Ondersteuning door po4a is hier erg welkom, aangezien deze indeling enigszins moeilijk te gebruiken is en niet echt vriendelijk voor nieuwkomers.

    De module Locale::Po4a::Man(3pm) ondersteunt ook de mdoc-indeling, welke door de BSD man-pagina's gebruikt wordt (deze zijn ook redelijk gebruikelijk onder Linux).

AsciiDoc (voldragen ontleder)
    Dit is een lichtgewicht opmaakindeling, bedoeld om het schrijven van documentatie te vergemakkelijken. Zij wordt bijvoorbeeld gebruikt voor het documenteren van het git-systeem. Deze man-pagina's worden vertaald met po4a.

    Zie Locale::Po4a::AsciiDoc voor details.

pod (voldragen ontleder)
    Dit is de indeling voor de Perl Online Documentatie. De computertaal en de uitbreidingen ervan worden gedocumenteerd met behulp van deze indeling, net als de meeste bestaande Perl-scripts. Het maakt het makkelijk om de documentatie dicht bij de echte code te houden, door beide in te bedden in hetzelfde bestand. Het maakt het leven van programmeurs makkelijker, maar jammer genoeg niet dat van vertalers, tenzij u po4a gebruikt.

    Zie Locale::Po4a::Pod voor details.

sgml (voldragen ontleder)
    Zelfs als deze indeling tegenwoordig wordt vervangen door XML, wordt ze nog steeds gebruikt voor documenten van meer dan enkele schermen lang. Ze kan zelfs gebruikt worden voor volledige boeken. Het kan een hele uitdaging zijn om dergelijk lange documenten bij te werken. diff blijkt vaak niet bruikbaar te zijn wanneer na het bijwerken het inspringen van de oorspronkelijke tekst opnieuw werd uitgevoerd. Gelukkig kan po4a u na dit proces behulpzaam zijn.

    Momenteel worden enkel DebianDoc en DocBook DTD ondersteund, maar iets anders ondersteunen is erg gemakkelijk. Het is zelfs mogelijk om zonder de code te wijzigen po4a te gebruiken bij een onbekende SGML DTD door de nodige informatie op te geven aan de commandoregel. Zie Locale::Po4a::Sgml(3pm) voor details.

TeX / LaTeX (voldragen ontleder)
    De LaTeX-indeling is een heel belangrijke indeling voor documentatie in de vrije-softwarewereld evenals voor publicaties.

    De module Locale::Po4a::LaTeX(3pm) werd getest met de Python-documentatie , een boek en enkele presentaties.

text (voldragen ontleder)
    De indeling Text is de basisindeling voor veel indelingen welke lange blokken tekst bevatten, waaronder Markdown, fortunes, inleidend gedeelte van YAML, debian/changelog en debian/control.

    Dit ondersteunt de indeling die Static Site Generators, README's en andere documentatiesystemen gebruiken en gemeen hebben.

xml and XHMTL (vermoedelijk voldragen ontleder)
    De indeling XML is een basisindeling voor veel documentatie-indelingen.

    Momenteel worden DocBook DTD (zie Locale::Po4a::Docbook(3pm) voor details) en XHTML door po4a ondersteund.

BibTex (vermoedelijk voldragen ontleder)
    De BibTex-bestandsindeling wordt naast LaTex gebruikt voor het opmaken van referentielijsten (bibliografieën).

    Zie Locale::Po4a::BibTex voor details.

Docbook (vermoedelijk voldragen ontleder)
    Een op XML gebaseerde opmaaktaal die semantische tags gebruikt om documenten te beschrijven.

    Zie Locale::Po4a:Docbook voor meer details.

Guide XML (vermoedelijk voldragen ontleder)
    Een XML-documentatieformaat. Deze module is speciaal ontwikkeld in functie van het ondersteunen en onderhouden van vertalingen van Gentoo Linux-documentatie tot ten minste maart 2016 (gebaseerd op de Wayback Machine). Gentoo is sindsdien overgestapt naar de DevBook XML-bestandsindeling.

    Zie Locale::Po4a:Guide voor meer details.

Wml (vermoedelijk voldragen ontleder)
    De Web-opmaaktaal (Web Markup Language); verwar WML niet met de WAP-spullen die op mobiele telefoons worden gebruikt. Deze module is gebaseerd op de Xhtml-module, die zelf weer is gebaseerd op de XmL-module.

    Zie Locale::Po4a::Wml voor meer details.

Yaml (vermoedelijk voldragen ontleder)
    Een strikte superset van JSON. YAML wordt vaak gebruikt als systeem- of configuratieproject. YAML vormt de kern van Red Hat's Ansible.

    Zie Locale::Po4a::Yaml voor meer details.

RubyDoc (vermoedelijk voldragen ontleder)
    Het Ruby Document (RD) formaat, oorspronkelijk het standaard documentatieformaat voor Ruby en Ruby-projecten voordat in 2002 werd overgeschakeld naar RDoc, hoewel de Japanse versie van het Ruby Referentiehandboek blijkbaar nog steeds RD gebruikt.

    Zie Locale::Po4a::RubyDoc voor meer details.

Halibut (vermoedelijk experimentele ontleder)
    Een documentatieproductiesysteem, met elementen die te vergelijken zijn met TeX, debiandoc-sgml, TeXinfo, en andere, ontwikkeld door Simon Tatham, de ontwikkelaar van PuTTY.

    Zie Locale::Po4a:Halibut voor meer details.

Ini (vermoedelijk experimentele ontleder)
    Configuratiebestandsindeling, populair geworden door MS-DOS.

    Zie Locale::Po4a::Ini voor meer details.

texinfo (zeer erg experimentele ontleder)
    Alle GNU-documentatie wordt in deze indeling geschreven (het is zelfs een vereiste om een officieel GNU-project te worden). De ondersteuning in po4a voor Locale::Po4a::Texinfo(3pm) zit nog steeds in zijn beginfase. Gelieve problemen en functieverzoeken te rapporteren.

Andere ondersteunde indelingen
    Po4a kan ook overweg met enkele meer zeldzame of gespecialiseerde indelingen, zoals de documentatie over compilatieopties voor de 2.4+ Linux-kernels (Locale::Po4a::KernelHelp) of de diagrammen die door het programma dia (Locale::Po4a:Dia) geproduceerd worden. Een nieuwe indeling toevoegen is vaak erg gemakkelijk en de belangrijkste taak bestaat erin een ontleder aan te brengen voor de beoogde indeling. Zie Locale::Po4a::TransTractor(3pm) voor meer informatie hierover.

Niet-ondersteunde indelingen
    Jammer genoeg biedt po4a nog geen ondersteuning voor verschillende documentaie-indelingen. Voor vele zou po4a makkelijk ondersteuning kunnen bieden. Het betreft indelingen die niet enkel voor documentatie gebruikt worden, zoals pakketbeschrijvingen (deb en rpm), vragen van pakketinstallatiescripts, changelogs van pakketten en alle gespecialiseerde bestandsformaten welke gebruikt worden door programma's zoals spelscenario's en wine-bronbestanden.

Het gebruik van po4a
The easiest way to use this tool in your project is to write a configuration file for the po4a program, and only interact with this program. Please refer to its documentation, in po4a(1). The rest of this section provides more details for the advanced users of po4a wanting to deepen their understanding.

  Detailed schema of the po4a workflow
Make sure to read po4a(1) before this overly detailed section to get a simplified overview of the po4a workflow. Come back here when you want to get the full scary picture, with almost all details.

In the following schema, master.doc is an example name for the documentation to be translated; XX.doc is the same document translated in the language XX while doc.XX.po is the translation catalog for that document in the XX language. Documentation authors will mostly be concerned with master.doc (which can be a manpage, an XML document, an AsciidDoc file, etc); the translators will be mostly concerned with the PO file, while the end users will only see the XX.doc file.

Transitions with square brackets such as "[po4a updates po]" represent the execution of a po4a tool while transitions with curly brackets such as "{ update of master.doc }" represent a manual modification of the project's files.

                                   master.doc
                                       |
                                       V
     +<-----<----+<-----<-----<--------+------->-------->-------+
     :           |                     |                        :
{translation}    |         { update of master.doc }             :
     :           |                     |                        :
   XX.doc        |                     V                        V
 (optional)      |                 master.doc ->-------->------>+
     :           |                   (new)                      |
     V           V                     |                        |
  [po4a-gettextize]   doc.XX.po -->+   |                        |
          |            (old)       |   |                        |
          |              ^         V   V                        |
          |              |   [po4a updates po]                  |
          V              |           |                          V
   translation.pot       ^           V                          |
          |              |        doc.XX.po                     |
          |              |         (fuzzy)                      |
   { translation }       |           |                          |
          |              ^           V                          V
          |              |     {manual editing}                 |
          |              |           |                          |
          V              |           V                          V
      doc.XX.po --->---->+<---<-- doc.XX.po    addendum     master.doc
      (initial)                 (up-to-date)  (optional)   (up-to-date)
          :                          |            |             |
          :                          V            |             |
          +----->----->----->------> +            |             |
                                     |            |             |
                                     V            V             V
                                     +------>-----+------<------+
                                                  |
                                                  V
                                     [po4a updates translations]
                                                  |
                                                  V
                                                XX.doc
                                             (up-to-date)

Again, this schema is overly complicated. Check on po4a(1) for a simplified overview.

Het linkerdeel laat zien hoe po4a-gettextize(1) kan worden gebruikt om een bestaand vertaalproject te converteren naar de po4a-infrastructuur. Dit script gebruikt een origineel document en zijn vertaalde tegenhanger en tracht het overeenkomstige PO-bestand te bouwen. Een dergelijke handmatige conversie is nogal omslachtig (zie de documentatie over po4a-gettextize(1) voor meer details), maar ze moet slechts eenmaal gebruikt worden om uw bestaande vertalingen om te zetten. Indien u geen te converteren vertalingen heeft, kunt u dit vergeten en u concentreren op het rechterdeel van het schema.

On the top right part, the action of the original author is depicted, updating the documentation. The middle right part depicts the automatic updates of translation files: the new material is extracted and compared against the exiting translation. The previous translation is used for the parts that didn't change, while partially modified parts are connected to the previous translation with a "fuzzy" marker indicating that the translation must be updated. New or heavily modified material is left untranslated.

Vervolgens geeft het gerapporteerde handmatig bewerken de actie van de vertalers weer, welke de PO-bestanden wijzigen om te voorzien in een vertaling voor elk origineel tekstfragment en alinea. Dit kan gebeuren met een specifieke editor, zoals de GNOME Translation Editor, KDE's Lokalize of poedit, of met een online lokalisatieplatform, zoals weblate of pootle. Het resultaat van de vertaling is een aantal PO-bestanden, één per taal. Raadpleeg de gettext-documentatie voor meer details.

The bottom part of the figure shows how po4a creates a translated source document from the master.doc original document and the doc.XX.po translation catalog that was updated by the translators. The structure of the document is reused, while the original content is replaced by its translated counterpart. Optionally, an addendum can be used to add some extra text to the translation. This is often used to add the name of the translator to the final document. See below for details.

Upon invocation, po4a updates both the translation files and the translated documentation files automatically.

  Starting a new translation project
If you start from scratch, you just have to write a configuration file for po4a, and you are set. The relevant templates are created for the missing files, allowing your contributors to translate your project to their language. Please refer to po4a(1) for a quick start tutorial and for all details.

If you have an existing translation, i.e. a documentation file that was translated manually, you can integrate its content in your po4a workflow using po4a-gettextize. This task is a bit cumbersome (as described in the tool's manpage), but once your project is converted to po4a workflow, everything will be updated automatically.

  Updating the translations and documents
Once setup, invoking po4a is enough to update both the translation PO files and translated documents. You may pass the "--no-translations" to po4a to not update the translations (thus only updating the PO files) or "--no-update" to not update the PO files (thus only updating the translations). This roughly corresponds to the individual po4a-updatepo and po4a-translate scripts which are now deprecated (see "Why are the individual scripts deprecated" in the FAQ below).

  Addenda gebruiken om extra tekst toe te voegen aan vertalingen
Het toevoegen van nieuwe tekst aan de vertaling is waarschijnlijk het enige dat op de lange termijn gemakkelijker is wanneer u bestanden handmatig vertaalt :). Dit gebeurt wanneer u een extra onderdeel wilt toevoegen aan het vertaalde document, waarvoor in het originele document geen overeenkomstige inhoud bestaat. Het klassieke toepassingsgebied is erkenning geven aan het vertaalteam en aangeven hoe vertaalspecifieke problemen gemeld kunnen worden.

Met po4a moet u addendum-bestanden opgeven, die conceptueel beschouwd kunnen worden als patches die na verwerking toegepast worden op het gelokaliseerde document. Elk addendum moet als apart bestand aangereikt worden. De indeling ervan verschilt evenwel erg van klassieke patches. De eerste regel is een header-regel, die het invoegpunt van het addendum definieert (met een helaas cryptische syntaxis -- zie hieronder), terwijl de rest van het bestand woordelijk toegevoegd wordt op de aangegeven positie.

De header-regel moet beginnen met de tekst PO4A-HEADER:, gevolgd door een door puntkomma's gescheiden lijst van I <sleutel> B <=> I <waarde> velden.

Bijvoorbeeld, de volgende header declareert een addendum dat helemaal aan het einde van de vertaling geplaatst moet worden.

 PO4A-HEADER: mode=eof

De zaken zijn complexer wanneer u de extra inhoud wilt toevoegen in het midden van het document. De volgende header declareert bijvoorbeeld een addendum dat ingevoegd moet worden na de XML-sectie welke het tekstfragment "Over dit document" bevat in de vertaling.

 PO4A-HEADER: position=About this document; mode=after; endboundary=</section>

Wanneer po4a tracht een addendum toe te passen, zoekt het in de praktijk naar de eerste regel die overeenkomt met het "position"-argument (dit kan een reguliere expressie zijn). Vergeet niet dat po4a hier rekening houdt met het vertaalde document. Deze documentatie is in het Nederlands (en de originele versie ervan in het Engels), maar uw regel zou er waarschijnlijk als volgt moeten uitzien, indien u van plan bent een addendum toe te passen op de Franse vertaling van het document.

 PO4A-HEADER: position=À propos de ce document; mode=after; endboundary=</section>

Nadat in het doeldocument de "position" gevonden werd, zoekt po4a naar de eerstvolgende regel na deze "position" welke overeenkomt met de opgegeven "endboundary". Het addendum wordt ingevoegd net na deze regel (omdat we een endboundary opgaven, d.w.z. een begrenzing die de huidige sectie afsluit).

Exact hetzelfde effect kan bekomen worden met de volgende header, die gelijkwaardig is:

 PO4A-HEADER: position=Over dit document; mode=after; beginboundary=<section>

Here, po4a searches for the first line matching "<section"> after the line matching "About this document" in the translation, and add the addendum before that line since we provided a beginboundary, i.e. a boundary marking the beginning of the next section. So this header line requires placing the addendum after the section containing "About this document", and instruct po4a that a section starts with a line containing the "<section"> tag. This is equivalent to the previous example because what you really want is to add this addendum either after "/section"> or before "<section">.

U kunt de invoeging mode ook instellen op de waarde "before", met een vergelijkbare semantiek: het combineren van "mode = before" met een "endboundary" zal het addendum juist na de overeenkomstige begrenzing plaatsen, welke de laatst mogelijke begrenzing is voor de "position". De combinatie van "mode = before" met een "beginboundary" zal het addendum juist voor de overeenkomstige begrenzing plaatsen, welke de laatst mogelijke grensregel is vóór de "position".

  Modus   | Soort begrenzing |     Gebruikte begrenzing      | Invoegpunt tegenover begrenzing
 ========|===============|========================|=========================================
 'before'| 'endboundary' | laatste voor 'position' | Juist na de geselecteerde begrenzing
 'before'|'beginboundary'| laatste voor 'position' | Juist voor de geselecteerde begrenzing
 'after' | 'endboundary' | eerste na 'position' | Juist na de geselecteerde begrenzing
 'after' |'beginboundary'| eerste na 'position' | Juist voor de geselecteerde begrenzing
 'eof'   |   (geen)      |  n.v.t.                   | Einde van het bestand

Aanwijzingen en kneepjes in verband met addenda

•   Denk eraan dat dit reguliere expressies zijn. Indien u bijvoorbeeld het einde van een nroff-sectie wilt opzoeken welke eindigt met de regel ".fi", moet u niet ".fi" gebruiken als endboundary, omdat dit een overeenkomst zal opleveren met "the [fi]le", hetgeen duidelijk niet is wat u verwacht. De juiste endboundary in dit geval is: "^\.fi$".

•   Witruimte IS belangrijk in de inhoud van de "position" en de begrenzingen. En dus zijn de twee volgende zinnen verschillend. De tweede zal slechts gevonden worden als er in het vertaalde document voldoende nakomende spaties zijn.

     PO4A-HEADER: position=Over dit document; mode=after; beginboundary=<section>
     PO4A-HEADER: position=Over dit document ; mode=after; beginboundary=<section>

•   Hoewel ruwweg zou kunnen aangenomen worden dat deze contextzoekfunctie werkt op elke regel van het vertaalde document, werkt het in feite op de interne gegevensreeks van het vertaalde document. Deze interne gegevensreeks kan een tekst zijn die een volledige alinea beslaat en meerdere regels bevat, of kan ook enkel een XML-tag zijn. Het exacte invoegpunt van het addendum moet voor of na de interne gegevensreeks komen en kan er niet binnenin liggen.

•   Geef het argument -vv op aan po4a om te zien hoe de addenda aan de vertaling worden toegevoegd. Dit kan ook behulpzaam zijn voor het uitvoeren van po4a in debug-modus om de exacte gegevensreeks te bekijken wanneer het addendum niet toegevoegd wordt.

Voorbeelden van addenda

•   Indien u na de volgende nroff-sectie iets wilt toevoegen:

      .SH "AUTEURS"

    You should select a 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=AUTEURS;beginboundary=\.SH

•   Indien u iets wilt toevoegen vlak na een bepaalde regel (bijv. na de regel "Copyright Grote Kerel"), gebruik dan een position die met deze regel overeenkomt, mode=after en geef een beginboundary op die met om het even welke regel overeenkomt.

     PO4A-HEADER:mode=after;position=Copyright Grote Kerel, 2004;beginboundary=^

•   Indien u iets wilt toevoegen aan het einde van het document, geef dan een position op die overeenkomt met om het even welke regel van uw document (maar enkel één regel, omdat po4a niet zal aanvaarden dat de position niet met één enkele regel overeenkomt), en geef een endboundary op die met niets overeenkomt. Gebruik hier geen eenvoudige tekenreeks, zoals "EOF", maar geef de voorkeur aan die welke minder kans maken om in uw document voor te komen.

     PO4A-HEADER:mode=after;position=Over dit document;beginboundary=VerzonnenPo4aBegrenzing

Een meer gedetailleerd voorbeeld

Origineel document (POD-indeling):

 |=head1 NAAM
 |
 |dummy - een dummy-programma
 |
 |=head1 AUTEUR
 |
 |ik

Dan zal het volgende addendum ervoor zorgen dat een sectie (in het Frans) over de vertaler toegevoegd wordt aan het eind van het bestand ("TRADUCTEUR" in het Frans betekent "VERTALER", en "moi" betekent "ik").

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

Om uw addendum voor de AUTEUR te plaatsen, gebruikt u de volgende header:

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

Dit werkt omdat de volgende regel die overeenkomt met de beginboundary /^=head1/ na de sectie "NAME" (vertaald als "NAAM" in het Nederlands), die is welke de auteurs vermeldt. Dus zal het addendum tussen de beide secties geplaatst worden. Merk op dat indien later een andere sectie toegevoegd wordt tussen de secties NAAM en AUTEUR, po4a de addenda ten onrechte zal plaatsen voor de nieuwe sectie.

Om dit te vermijden, kunt u hetzelfde bereiken met behulp van mode=before:

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

Hoe werkt dit?
This chapter gives you a brief overview of the po4a internals, so that you may feel more confident to help us to maintain and to improve it. It may also help you to understand why it does not do what you expected, and how to solve your problems.

  TransTractors and project architecture
At the core of the po4a project, the Locale::Po4a::TransTractor(3pm) class is the common ancestor to all po4a parsers. This strange name comes from the fact that it is at the same time in charge of translating document and extracting strings.

More formally, it takes a document to translate plus a PO file containing the translations to use as input while producing two separate outputs: Another PO file (resulting of the extraction of translatable strings from the input document), and a translated document (with the same structure as the input one, but with all translatable strings replaced with content of the input PO). Here is a graphical representation of this:

   Invoerdocument --\                             /---> Uitvoerdocument
                     \      TransTractor::       /       (vertaald)
                      +-->--   parse()  --------+
                     /                           \
   Invoer-PO --------/                             \---> Uitvoer-PO
                                                         (geëxtraheerd)

This little bone is the core of all the po4a architecture. If you provide both input and disregard the output PO, you get po4a-translate. If you disregard the output document instead, you get po4a-updatepo. The po4a uses a first TransTractor to get an up-to-date output POT file (disregarding the output documents), calls msgmerge -U to update the translation PO files on disk, and builds a second TransTractor with these updated PO files to update the output documents. In short, po4a provides one-stop solution to update what needs to be, using a single configuration file.

po4a-gettextize also uses two TransTractors, but another way: It builds one TransTractor per language, and then build a new PO file using the msgids of the original document as msgids, and the msgids of the translated document as msgstrs. Much care is needed to ensure that the strings matched this way actually match, as described in po4a-gettextize(1).

  Format-specific parsers
All po4a format parsers are implemented on top of the TransTractor. Some of them are very simple, such as the Text, Markdown and AsciiDoc ones. They load the lines one by one using TransTractor::shiftline(), accumulate the paragraphs' content or whatever. Once a string is completely parsed, the parser uses TransTractor::translate() to (1) add this string to the output PO file and (2) get the translation from the input PO file. The parser then pushes the result to the output file using TransTractor::pushline().

Some other parsers are more complex because they rely on an external parser to analyze the input document. The Xml, HTML, SGML and Pod parsers are built on top of SAX parsers. They declare callbacks to events such as "I found a new title which content is the following" to update the output document and output POT files according to the input content using TransTractor::translate() and TransTractor::pushline(). The Yaml parser is similar but different: it serializes a data structure produced by the YAML::Tiny parser. This is why the Yaml module of po4a fails to declare the reference lines: the location of each string in the input file is not kept by the parser, so we can only provide "$filename:1" as a string location. The SAX-oriented parsers use globals and other tricks to save the file name and line numbers of references.

One specific issues arises from file encodings and BOM markers. Simple parsers can forget about this issue, that is handled by TransTractor::read() (used internally to get the lines of an input document), but the modules relying on an external parser must ensure that all files are read with an appropriate PerlIO decoding layer. The easiest is to open the file yourself, and provide an filehandle or directly the full string to your external parser. Check on Pod::read() and Pod::parse() for an example. The content read by the TransTractor is ignored, but a fresh filehandle is passed to the external parser. The important part is the "<:encoding($charset)" mode that is passed to the open() perl function.

  Po objects
The Locale::Po4a::Po(3pm) class is in charge of loading and using PO and POT files. Basically, you can read a file, add entries, get translations with the gettext() method, write the PO into a file. More advanced features such as merging a PO file against a POT file or validating a file are delegated to msgmerge and msgfmt respectively.

  Contributing to po4a
Even if you have never contributed to any Open Source project in the past, you are welcome: we are willing to help and mentor you here. po4a is best maintained by its users nowadays. As we lack manpower, we try to make the project welcoming by improving the doc and the automatic tests to make you confident in contributing to the project. Please refer to the CONTRIBUTING.md file for more details.

Openbronprojecten die po4a gebruiken
Hier volgt een zeer gedeeltelijke lijst met projecten die po4a in productie gebruiken voor hun documentatie. Indien u wenst dat uw project wordt toegevoegd aan de lijst, stuur dan gewoon een e-mail (of een Merge Request).

•   adduser (man): gereedschap voor het beheer van gebruikers en groepen.

•   apt (man, docbook): pakketbeheerder in Debian.

•   aptitude (docbook, svg): terminalgeoriënteerd pakketbeheerhulpmiddel voor Debian

•   F-Droid website <https://gitlab.com/fdroid/fdroid-website> (markdown): installable catalog of FOSS (Free and Open Source Software) applications for the Android platform.

•   git <https://github.com/jnavila/git-manpages-l10n> (asciidoc): gedistribueerd versiebeheersysteem voor het volgen van wijzigingen in de broncode.

•   Linux man-pagina's <https://salsa.debian.org/manpages-l10n-team/manpages-l10n> (man)

    Dit project voorziet in een infrastructuur voor het vertalen van veel man-pagina's naar verschillende talen, klaar om geïntegreerd te worden in verschillende belangrijke distributies (Arch Linux, Debian en derivativen, Fedora).

•   Stellarium <https://github.com/Stellarium/stellarium> (HTML): een vrij openbronplanetarium voor uw computer. po4a wordt gebruikt om de beschrijving van de lucht en de hemellichamen in verschillende culturen, te vertalen.

•   Jamulus <https://jamulus.io/> (markdown, yaml, HTML): a FOSS application for online jamming in real time. The website documentation is maintained in multiple languages using po4a.

•   Ander uit te zoeken item: <https://gitlab.com/fdroid/fdroid-website/> <https://github.com/fsfe/reuse-docs/pull/61>

FAQ

  Hoe spreekt men po4a uit?
Zelf spreek ik het uit als pouah <https://en.wiktionary.org/wiki/pouah>, wat een Franse klanknabootsing is die men gebruikt voor bah :) Misschien heb ik een vreemd gevoel voor humor :)

  Why are the individual scripts deprecated?
Indeed, po4a-updatepo and po4a-translate are deprecated in flavor of po4a. The reason is that while po4a can be used as a drop-in replacement to these scripts, there is quite a lot of code duplication here. Individual scripts last around 150 lines of codes while the po4a program lasts 1200 lines, so they do a lot in addition of the common internals. The code duplication results in bugs occuring in both versions and needing two fixes. One example of such duplication are the bugs #1022216 in Debian and the issue #442 in GitHub that had the exact same fix, but one in po4a and the other po4a-updatepo.

In the long run, I would like to drop the individual scripts and only maintain one version of this code. The sure thing is that the individual scripts will not get improved anymore, so only po4a will get the new features. That being said, there is no deprecation urgency. I plan to keep the individual scripts as long as possible, and at least until 2030. If your project still use po4a-updatepo and po4a-translate in 2030, you may have a problem.

We may also remove the deprecation of these scripts at some point, if a refactoring reduces the code duplication to zero. If you have an idea (or better: a patch), your help is welcome.

  Hoe zit het met de andere vertaalhulpmiddelen voor documentatie die gebruik maken van gettext?
Er zijn er een paar. Hier is een mogelijk onvolledige lijst, en er verschijnen meer hulpmiddelen aan de horizon.

poxml
    Dit gereedschap werd ontwikkeld door mensen van KDE om DocBook XML te verwerken. Voor zover ik weet was dit het eerste programma dat te vertalen tekstfragmenten uit documentatie extraheerde naar PO-bestanden en deze na vertaling terug injecteerde.

    Het kan enkel XML verwerken, en enkel een specifieke DTD. Ik ben erg ongelukkig met de verwerking van lijsten welke terechtkomen in één grote msgid. Wanneer de lijst groot wordt, is het moeilijker die brok door te slikken.

po-debiandoc
    Dit door Denis Barbier gemaakt programma is een soort voorloper van de SGML-module van po4a, waardoor het min of meer achterhaald werd. Zoals de naam het zegt, verwerkt het enkel de DebianDoc DTD, hetgeen min of meer een achterhaalde DTD is.

xml2po.py
    Wordt gebruikt door het GIMP-documentatieteam sinds 2004. Het werkt redelijk goed, zij het, zoals de naam al doet vermoeden, alleen met XML-bestanden, en het heeft speciaal geconfigureerde makefiles nodig.

Sphinx
    Ook het documentatieproject van Sphinx maakt veelvuldig gebruik van gettext om zijn vertalingen te beheren. Helaas werkt dit hulpmiddel slechts voor enkele tekstformaten, voor rest en voor markdown, hoewel het misschien wel het enige hulpmiddel is dat dit beheren van het hele vertaalproces op zich neemt.

De belangrijkste voordelen van po4a tegenover hen zijn het gemak waarmee extra inhoud toegevoegd kan worden (wat bij deze andere hulpmiddelen nog moeilijker is) en de mogelijkheid een gettextize-procedure uit te voeren.

  SAMENVATTING van de voordelen van een op gettext gebaseerde benadering

•   De vertalingen worden niet samen met het origineel opgeslagen, wat het mogelijk maakt na te gaan of vertalingen verouderd beginnen te raken.

•   De vertalingen worden in aparte bestanden opgeslagen, wat interferentie tussen vertalers van verschillende talen voorkomt, zowel wanneer deze hun patch indienen als bij de keuze van de tekstcodering van de bestanden.

•   Intern is het gebaseerd op gettext (maar po4a biedt een heel eenvoudige interface, zodat u de interne werking niet moet kennen om het te gebruiken). Op die manier moeten we het wiel niet terug uitvinden, en omdat dit gereedschap zo ruim gebruikt wordt, mogen we aannemen dat het min of meer vrij van fouten is.

•   Voor de eindgebruiker verandert er niets (behalve het feit dat vertalingen hopelijk beter onderhouden zullen worden). Het resulterende documentatiebestand dat verspreid wordt, is exact hetzelfde.

•   Vertalers moeten geen nieuwe bestandsyntaxis leren en hun favoriete editor voor PO-bestanden (zoals de PO-modus in Emacs, Lokalize of Gtranslator) voldoet perfect.

•   gettext biedt een eenvoudige manier om statistieken te bekomen over het gepresteerde werk, over wat nazicht en een update nodig heeft en over wat er nog moet gebeuren. Enkele voorbeelden zijn te vinden op deze adressen:

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

Maar niet alles is rozengeur en deze aanpak heeft ook enkele nadelen waarmee we moeten omgaan.

•   Addenda are somewhat strange at the first glance.

•   Het is niet mogelijk om de vertaalde tekst naar uw smaak aan te passen, zoals hier een paragraaf opsplitsen en er daar twee andere samenvoegen. Maar in zekere zin moet het hoe dan ook als een bug gemeld worden, wanneer er een probleem is met het origineel.

•   Zelfs met een gemakkelijke interface blijft het een nieuw gereedschap dat mensen moeten leren gebruiken.

    Een van mijn dromen is om po4a op een of andere manier te integreren in Gtranslator of Lokalize. Wanneer een documentatiebestand geopend wordt, zouden de tekstfragmenten automatisch geëxtraheerd worden en een vertaald bestand + po-bestand zouden naar schijf geschreven worden. Indien we erin zouden slagen een MS Word(TM)-module te ontwikkelen (of minstens een RTF-module), zouden zelfs professionele vertalers er gebruik van maken.

ZIE OOK

•   De documentatie over het alles-in-één gereedschap dat u zou moeten gebruiken: L <po4a (1)>.

•   De documentatie van de individuele po4a-scripts: po4a-gettextize(1), po4a-updatepo(1), po4a-translate(1), po4a-normalize(1).

•   De extra ondersteunende scripts: msguntypot(1), po4a-display-man(1), po4a-display-pod(1).

•   De ontleders (parsers) voor elke indeling, in het bijzonder om te zien welke opties voor elke van hen mogelijk zijn: Locale::Po4a::AsciiDoc(3pm) Locale::Po4a::Dia(3pm), Locale::Po4a::Guide(3pm), Locale::Po4a::Ini(3pm), Locale::Po4a::KernelHelp(3pm), Locale::Po4a::Man(3pm), Locale::Po4a::RubyDoc(3pm), Locale::Po4a::Texinfo(3pm), Locale::Po4a::Text(3pm), Locale::Po4a::Xhtml(3pm), Locale::Po4a::Yaml(3pm), Locale::Po4a::BibTeX(3pm), Locale::Po4a::Docbook(3pm), Locale::Po4a::Halibut(3pm), Locale::Po4a::LaTeX(3pm), Locale::Po4a::Pod(3pm), Locale::Po4a::Sgml(3pm), Locale::Po4a::TeX(3pm), Locale::Po4a::Wml(3pm), Locale::Po4a::Xml(3pm).

•   De implementatie van de basisinfrastructuur:: Locale::Po4a::TransTractor(3pm) (in het bijzonder van belang om de organisatie van de code te begrijpen), Locale::Po4a::Chooser(3pm), Locale::Po4a::Po(3pm), Locale::Po4a::Common(3pm). Bekijk ook het bestand CONTRIBUTING.md in de broncodeboom.

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