PO4A.1P(1) User Contributed Perl Documentation PO4A.1P(1) po4a - PO po4a [options] config_file po4a (PO ) gettext po4a po4a(7) Upon execution, po4a parses all documentation files specified in its configuration file. It updates the PO files (containing the translation) to reflect any change to the documentation, and produce a translated documentation by injecting the content's translation (found in the PO files) into the structure of the original master document. At first, the PO files only contain the strings to translate from the original documentation. This file format allows the translators to manually provide a translation for each paragraph extracted by po4a. If the documentation is modified after translation, po4a marks the corresponding translations as "fuzzy" in the PO file to request a manual review by the translators. The translators can also provide so- called "addendum", that are extra content stating for example who did the translation and how to report bugs. master documents ---+---->-------->---------+ (doc authoring) | | V (po4a executions) >-----+--> translated | | | documents existing PO files -->--> updated PO files >-+ | ^ | | | V | +----------<---------<-------+ ^ (manual translation process) | | addendum -->--------------------------------------+ The workflow of po4a is asynchronous, as suited to open-source projects. The documentation writers author the master documents at their own pace. The translators review and update the translations in the PO files. The maintainers rerun po4a on need, to reflect any change to the original documentation to the PO files, and to produce updated documentation translations, by injecting the latest translation into the latest document structure. By default, a given translated document is produced when at least 80% of its content is translated. The untranslated text is kept in the original language. The produced documentation thus mixes languages if the translation is not complete. You can change the 80% threshold with the --keep option described below. Note however that discarding translations as soon as they are not 100% may be discouraging for the translators whose work will almost never be shown to the users, while showing "translations" that are too incomplete may be troubling for the end users. Storing the translated documentation files in the version control system is probably a bad idea, since they are automatically generated. The precious files are the PO files, that contain the hard work of your fellow translators. Also, some people find it easier to interact with the translators through an online platform such as weblate, but this is naturally fully optional. Quick start tutorial Let's assume you maintain a program named foo which has a man page man/foo.1 written in English (the bridge language in most open-source projects, but po4a can be used from or to any language). Some times ago, someone provided a German translation named man/foo.de.1 and disappeared. This is a problem because you just got a bug report saying that your documentation contains a gravely misleading information that must be fixed in all languages, but you don't speak German so you can only modify the original, not the translation. Now, another contributor wants to contribute a translation to Japanese, a language that you don't master either. It is time to convert your documentation to po4a to solve your documentation maintenance nightmares. You want to update the doc when needed, you want to ease the work of your fellow translators, and you want to ensure that your users never see any outdated and thus misleading documentation. The conversion includes two steps: setup the po4a infrastructure, and convert the previous German translation to salvage the previous work. This latter part is done using po4a-gettextize, as follows. As detailed in the documentation of po4a-gettextize(1), this process rarely fully automatic, but once it's done, the de.po file containing the German translation can be integrated in your po4a workflow. po4a-gettextize --format man --master foo.1 --localized foo.de.1 --po de.po Let's now configure po4a. With the appropriate file layout, your configuration file could be as simple as this: [po_directory] man/po4a/ [type: man] man/foo.1 $lang:man/translated/foo.$lang.1 It specifies that all PO files (containing the work of the translators) are in the man/po4a/ directory, and that you have only one master file, man/foo.1. If you had several master files, you would have several lines similar to the second one. Each such line also specify where to write the corresponding translation files. Here, the German translation of man/foo.1 is in man/translated/foo.de.1. The last thing we need to complete the configuration of po4a is a POT file containing the template material that should be used to start a new translation. Simply create an empty file with the .pot extension in the specified po_directory (e.g. man/po4a/foo.pot), and po4a will fill it with the expected content. Here is a recap of the files in this setup: man/ | foo.1 <- The original man page, in English | po4a/ | | de.po <- The German PO translation, from gettextization | | foo.pot <- The POT template of future translations (empty at first) | translated/ <- Directory where the translations will be created po4a.cfg <- The configuration file Once setup, executing po4a will parse your documentation, update the POT template file, use it to update the PO translation files, and use them to update the documentation translation files. All in one command: po4a --verbose po4a.cfg This is it. po4a is now fully configured. Once you've fixed your error in man/foo.1, the offending paragraph in the German translation will be replaced by the fixed text in English. Mixing languages is not optimal, but it's the only way to remove errors in translations that you don't even understand, and ensure that the content presented to the users is never misleading. Updating the German translation is also much easier in the corresponding PO file, so the language mix-up may not last long. Finally, when a Japanese translator wants to contribute a new translation, she should rename the foo.pot into ja.po and complete the translation. Once you have this file, just drop it in man/po4a/po/. A translated page will appear as man/translated/foo.ja.1 (provided that enough content is translated) when you run po4a again. -k, --keep ()(80) 80% -w, --width Column at which we should wrap the resulting file if the format supports it (default: 76). -h, --help -M, --master-charset -L, --localized-charset -A, --addendum-charset -V, --version -v, --verbose -q, --quiet -d, --debug -o, --option '-o tablecells' AsciiDoc '-o tabs=split' -f, --force POT PO po4a ( --force ) POT ( --no-update)POT po4a PO ( --KEEP) .po4a-stamp ( --STAMP) --force PO msgmerge-U POT --stamp po4a .po4a stamp .po4a stamp --rm translations --no-translations POT PO --no-update POT PO --keep-translations --keep po4a --rm-translations --no translations --no-backups 0.41 --rm-backups 0.41 --translate-only translated-file PO POT --variable var=value po4a $(var) value --srcdir SRCDIR po4a destdir srcdirdestdir srcdir destdir --destdir DESTDIR po4a --srcdir POT --porefs type type never file counter full full --wrap-po no|newlines|number (default: 76) po git gettext 77 po po4a po4a po newlinespo4a msgid msgstr no po4a po gettext msgid msgstr --master-language --msgid-bugs-address email@address msgid POT Report-Msgid-Bugs-To --copyright-holder string POT "" --package-name string POT "" --package-version string POT "" PO --msgmerge-opt options msgmerge(1) $lang --no-previous msgmerge -previous 0.16 gettext --previous --previous msgmerge gettext 0.16 po4a o PO ; o ; o '#' "t/cfg" PO POT POT PO [po4a_paths] man/po/project.pot de:man/po/de.po fr:man/po/fr.po POT PO / [po4a_langs] fr de [po4a_paths] man/po/project.pot $lang:man/po/$lang.po $lang / [po_directory] man/po/ PO XX.po"XX" ISO 639-1 POT ".pot"(po4a ) "po_" "po4a_" ("po_") / ("po4a_") po4a PO po4a PO weblate msgid PO "[po4a_paths]" PO $master [po4a_paths] doc/$master/$master.pot $lang:doc/$master/$lang.po With this line, po4a will produce separate POT and PO files for each document to translate. For example, if you have 3 documents and 5 languages, this will result in 3 POT files and 15 PO files. These files are named as specified on the "po4a_paths" template, with $master substituted to the basename of each document to translate. In case of name conflict, you can specify the POT file to use as follows, with the "pot=" parameter. This feature can also be used to group several translated files into the same POT file. The following example only produces 2 POT files: l10n/po/foo.pot (containing the material from foo/gui.xml) and l10n/po/bar.pot (containing the material from both bar/gui.xml and bar/cli.xml). [po4a_langs] de fr ja [po4a_paths] l10n/po/$master.pot $lang:l10n/po/$master.$lang.po [type: xml] foo/gui.xml $lang:foo/gui.$lang.xml pot=foo [type: xml] bar/gui.xml $lang:bar/gui.$lang.xml pot=bar [type: xml] bar/cli.xml $lang:bar/cli.$lang.xml pot=bar split po4a PO PO PO po4a fuzzy PO PO You must also list the documents that should be translated. For each master file, you must specify the format parser to use, the location of the translated document to produce, and optionally some configuration. File names should be quoted or escaped if they contain spaces. Here is an example: [type: sgml] "doc/my stuff.sgml" "fr:doc/fr/mon truc.sgml" de:doc/de/mein\ kram.sgml [type: man] script fr:doc/fr/script.1 de:doc/de/script.1 [type: docbook] doc/script.xml fr:doc/fr/script.xml \ de:doc/de/script.xml $lang [type: sgml] doc/my_stuff.sgml $lang:doc/$lang/my_stuff.sgml [type: man] script.1 $lang:po/$lang/script.1 [type: docbook] doc/script.xml $lang:doc/$lang/script.xml po4a options po4a format options po4a options --keep 50% 80%Format options Locale::Po4a::Xml(3pm) nostrip XML "opt:" "opt_XX:" "XX" nostrip XML 0% [type:xml] toto.xml $lang:toto.$lang.xml opt:"-o nostrip" opt_fr:"--keep 0" [type:xml] toto.xml $lang:toto.$lang.xml opt:"--keep 20" opt:"-o nostrip" opt_fr:"--keep 0" [type:xml] toto.xml $lang:toto.$lang.xml opt:"--keep 20 -o nostrip" opt_fr:"--keep 0" [type:xml] toto.xml $lang:toto.$lang.xml opt:--keep opt:20 opt:-o opt:nostrip opt_fr:--keep opt_fr:0 POT nostrip POT "--keep" "test" "man" "--keep 0" [po4a_alias:test] man opt_it:"--keep 0" [type: test] man/page.1 $lang:man/$lang/page.1 [po4a_alias:man] man opt_it:"--keep 0" [type: man] man/page.1 $lang:man/$lang/page.1 "[options]" [options] --keep 20 --option nostrip [options] -k 20 -o nostrip o "[options]" o o o po4a [po_directory] man/po/ [options] --master-charset UTF-8 [po4a_alias:man] man opt:"-o \"mdoc=NAME,SEE ALSO\"" [type:man] t-05-config/test02_man.1 $lang:tmp/test02_man.$lang.1 \ opt:"-k 75" opt_it:"-L UTF-8" opt_fr:--verbose po4a(7) [type: pod] script fr:doc/fr/script.1 \ add_fr:doc/l10n/script.fr.add [type: pod] script $lang:doc/$lang/script.1 \ add_$lang:doc/l10n/script.$lang.add ? appendment_path @ addendment_path ! appendment_path [type: pod] script $lang:doc/$lang/script.1 add_$lang:?doc/l10n/script.$lang.add [type: pod] script $lang:doc/$lang/script.1 add_$lang:@doc/l10n/script.$lang.add "pot_in" pot [type:docbook] book.xml \ pot_in:book-filtered.xml \ $lang:book.$lang.xml book-filtered.xml po4a book.xml . F book.xml book-filtered.xml PO "--keep" po4a-gettextize(1), po4a(7). Denis Barbier Nicolas Francois Martin Quinson (mquinson#debian.org) taotieren Copyright 2002-2023 by SPI, inc. This program is free software; you may redistribute it and/or modify it under the terms of GPL v2.0 or later (see the COPYING file). perl v5.38.2 2024-06-26 PO4A.1P(1)