1PO4A(7) Po4a Tools PO4A(7)
2
3
4
6 po4a - framework to translate documentation and other materials
7
9 po4a (PO for anything) eases the maintenance of documentation
10 translation using the classical gettext tools. The main feature of po4a
11 is that it decouples the translation of content from its document
12 structure.
13
14 This document serves as an introduction to the po4a project with a
15 focus on potential users considering whether to use this tool and on
16 the curious wanting to understand why things are the way they are.
17
19 The philosophy of Free Software is to make the technology truly
20 available to everyone. But licensing is not the only consideration:
21 untranslated free software is useless for non-English speakers.
22 Therefore, we still have some work to do to make software available to
23 everybody.
24
25 This situation is well understood by most projects and everybody is now
26 convinced of the necessity to translate everything. Yet, the actual
27 translations represent a huge effort of many individuals, crippled by
28 small technical difficulties.
29
30 Thankfully, Open Source software is actually very well translated using
31 the gettext tool suite. These tools are used to extract the strings to
32 translate from a program and present the strings to translate in a
33 standardized format (called PO files, or translation catalogs). A whole
34 ecosystem of tools has emerged to help the translators actually
35 translate these PO files. The result is then used by gettext at run
36 time to display translated messages to the end users.
37
38 Regarding documentation, however, the situation still somewhat
39 disappointing. At first translating documentation may seem to be
40 easier than translating a program as it would seem that you just have
41 to copy the documentation source file and start translating the
42 content. However, when the original documentation is modified, keeping
43 track of the modifications quickly turns into a nightmare for the
44 translators. If done manually, this task is unpleasant and error prone.
45
46 Outdated translations are often worse than no translation at all. End-
47 users can be tricked by documentation describing an old behavior of the
48 program. Furthermore, they cannot interact directly with the
49 maintainers since they don't speak English. Additionally, the
50 maintainer cannot fix the problem as they don't know every language in
51 which their documentation is translated. These difficulties, often
52 caused by poor tooling, can undermine the motivation of volunteer
53 translators, further aggravating the problem.
54
55 The goal of the po4a project is to ease the work of documentation
56 translators. In particular, it makes documentation translations
57 maintainable.
58
59 The idea is to reuse and adapt the gettext approach to this field. As
60 with gettext, texts are extracted from their original locations and
61 presented to translators as PO translation catalogs. The translators
62 can leverage the classical gettext tools to monitor the work to do,
63 collaborate and organize as teams. po4a then injects the translations
64 directly into the documentation structure to produce translated source
65 files that can be processed and distributed just like the English
66 files. Any paragraph that is not translated is left in English in the
67 resulting document, ensuring that the end users never see an outdated
68 translation in the documentation.
69
70 This automates most of the grunt work of the translation maintenance.
71 Discovering the paragraphs needing an update becomes very easy, and the
72 process is completely automated when elements are reordered without
73 further modification. Specific verification can also be used to reduce
74 the chance of formatting errors that would result in a broken document.
75
76 Please also see the FAQ below in this document for a more complete list
77 of the advantages and disadvantages of this approach.
78
79 Supported formats
80 Currently, this approach has been successfully implemented to several
81 kinds of text formatting formats:
82
83 man (mature parser)
84 The good old manual pages' format, used by so many programs out
85 there. po4a support is very welcome here since this format is
86 somewhat difficult to use and not really friendly to newbies.
87
88 The Locale::Po4a::Man(3pm) module also supports the mdoc format,
89 used by the BSD man pages (they are also quite common on Linux).
90
91 AsciiDoc (mature parser)
92 This format is a lightweight markup format intended to ease the
93 authoring of documentation. It is for example used to document the
94 git system. Those manpages are translated using po4a.
95
96 pod (mature parser)
97 This is the Perl Online Documentation format. The language and
98 extensions themselves are documented using this format in addition
99 to most existing Perl scripts. It makes easy to keep the
100 documentation close to the actual code by embedding them both in
101 the same file. It makes programmer's life easier, but
102 unfortunately, not the translator's, until you use po4a.
103
104 sgml (mature parser)
105 Even if superseded by XML nowadays, this format is still used for
106 documents which are more than a few screens long. It can even be
107 used for complete books. Documents of this length can be very
108 challenging to update. diff often reveals useless when the original
109 text was re-indented after update. Fortunately, po4a can help you
110 after that process.
111
112 Currently, only DebianDoc and DocBook DTD are supported, but adding
113 support for a new one is really easy. It is even possible to use
114 po4a on an unknown SGML DTD without changing the code by providing
115 the needed information on the command line. See
116 Locale::Po4a::Sgml(3pm) for details.
117
118 TeX / LaTeX (mature parser)
119 The LaTeX format is a major documentation format used in the Free
120 Software world and for publications.
121
122 The Locale::Po4a::LaTeX(3pm) module was tested with the Python
123 documentation, a book and some presentations.
124
125 text (mature parser)
126 The Text format is the base format for many formats that include
127 long blocks of text, including Markdown, debian/changelog, and
128 debian/control.
129
130 This supports the common format used in Static Site Generators,
131 READMEs, and other documentation systems. See
132 Locale::Po4a::Text(3pm) for details.
133
134 xml and XHMTL (probably mature parser)
135 The XML format is a base format for many documentation formats.
136
137 Currently, the DocBook DTD (see Locale::Po4a::Docbook(3pm) for
138 details) and XHTML are supported by po4a.
139
140 texinfo (very highly experimental parser)
141 All of the GNU documentation is written in this format (it's even
142 one of the requirements to become an official GNU project). The
143 support for Locale::Po4a::Texinfo(3pm) in po4a is still at the
144 beginning. Please report bugs and feature requests.
145
146 Others supported formats
147 Po4a can also handle some more rare or specialized formats, such as
148 the documentation of compilation options for the 2.4+ Linux kernels
149 or the diagrams produced by the dia tool. Adding a new format is
150 often very easy and the main task is to come up with a parser for
151 your target format. See Locale::Po4a::TransTractor(3pm) for more
152 information about this.
153
154 Unsupported formats
155 Unfortunately, po4a still lacks support for several documentation
156 formats. Many of them would be easy to support in po4a. This
157 includes formats not just used for documentation, such as, package
158 descriptions (deb and rpm), package installation scripts questions,
159 package changelogs, and all the specialized file formats used by
160 programs such as game scenarios or wine resource files.
161
163 Historically, po4a was built around four scripts, each fulfilling a
164 specific task. po4a-gettextize(1) helps bootstrapping translations and
165 optionally converting existing translation projects to po4a.
166 po4a-updatepo(1) reflects the changes to the original documentation
167 into the corresponding po files. po4a-translate(1) builds translated
168 source file from the original file and the corresponding PO file. In
169 addition, po4a-normalize(1) is mostly useful to debug the po4a parsers,
170 as it produces an untranslated document from the original one. It makes
171 it easier to spot the glitches introduced by the parsing process.
172
173 Most projects only require the features of po4a-updatepo(1) and
174 po4a-translate(1), but these scripts proved to be cumbersome and error
175 prone to use. If the documentation to translate is split over several
176 source files, it is difficult to keep the PO files up to date and build
177 the documentation files correctly. As an answer, a all-in-one tool was
178 provided: po4a(1). This tool takes a configuration file describing the
179 structure of the translation project: the location of the PO files, the
180 list of files to translate, and the options to use, and it fully
181 automatizes the process. When you invoke po4a(1), it both updates the
182 PO files and regenerate the translation files that need to. If
183 everything is already up to date, po4a(1) does not change any file.
184
185 The rest of this section gives an overview of how use the scripts'
186 interface of po4a. Most users will probably prefer to use the all-in-
187 one tool, that is described in the documentation of po4a(1).
188
189 Graphical overview of the po4a scripts
190 The following schema gives an overview of how each po4a script can be
191 used. Here, master.doc is an example name for the documentation to be
192 translated; XX.doc is the same document translated in the language XX
193 while doc.XX.po is the translation catalog for that document in the XX
194 language. Documentation authors will mostly be concerned with
195 master.doc (which can be a manpage, an XML document, an asciidoc file
196 or similar); the translators will be mostly concerned with the PO file,
197 while the end users will only see the XX.doc file.
198
199 master.doc
200 |
201 V
202 +<-----<----+<-----<-----<--------+------->-------->-------+
203 : | | :
204 {translation} | { update of master.doc } :
205 : | | :
206 XX.doc | V V
207 (optional) | master.doc ->-------->------>+
208 : | (new) |
209 V V | |
210 [po4a-gettextize] doc.XX.po -->+ | |
211 | (old) | | |
212 | ^ V V |
213 | | [po4a-updatepo] |
214 V | | V
215 translation.pot ^ V |
216 | | doc.XX.po |
217 | | (fuzzy) |
218 { translation } | | |
219 | ^ V V
220 | | {manual editing} |
221 | | | |
222 V | V V
223 doc.XX.po --->---->+<---<-- doc.XX.po addendum master.doc
224 (initial) (up-to-date) (optional) (up-to-date)
225 : | | |
226 : V | |
227 +----->----->----->------> + | |
228 | | |
229 V V V
230 +------>-----+------<------+
231 |
232 V
233 [po4a-translate]
234 |
235 V
236 XX.doc
237 (up-to-date)
238
239 This schema is complicated, but in practice only the right part
240 (involving po4a-updatepo(1) and po4a-translate(1)) is used once the
241 project is setup and configured.
242
243 The left part depicts how po4a-gettextize(1) can be used to convert an
244 existing translation project to the po4a infrastructure. This script
245 takes an original document and its translated counterpart, and tries to
246 build the corresponding PO file. Such manual conversion is rather
247 cumbersome (see the po4a-gettextize(1) documentation for more details),
248 but it is only needed once to convert your existing translations. If
249 you don't have any translation to convert, you can forget about this
250 and focus on the right part of the schema.
251
252 On the top right part, the action of the original author is depicted,
253 updating the documentation. The middle right part depicts the automatic
254 actions of po4a-updatepo(1). The new material is extracted and compared
255 against the exiting translation. The previous translation is used for
256 the parts that didn't change, while partially modified parts are
257 connected to the previous translation with a "fuzzy" marker indicating
258 that the translation must be updated. New or heavily modified material
259 is left untranslated.
260
261 Then, the manual editing reported depicts the action of the
262 translators, that modify the PO files to provide translations to every
263 original string and paragraph. This can be done using either a specific
264 editor such as the GNOME Translation Editor, KDE's Lokalize or poedit,
265 or using an online localization platform such as weblate or pootle. The
266 translation result is a set of PO files, one per language. Please refer
267 to the gettext documentation for more details.
268
269 The bottom part of the figure shows how po4a-translate(1) creates a
270 translated source document from the master.doc original document and
271 the doc.XX.po translation catalog that was updated by the translators.
272 The structure of the document is reused, while the original content is
273 replaced by its translated counterpart. Optionally, an addendum can be
274 used to add some extra text to the translation. This is often used to
275 add the name of the translator to the final document. See below for
276 details.
277
278 As noted before, the po4a(1) program combines the effects of the
279 separated scripts, updating the PO files and the translated document in
280 one invocation. The underlying logic remains the same.
281
282 Starting a new translation
283 If you use po4a(1), there is no specific step to start a translation.
284 You just have to list the languages in the configuration file, and the
285 missing PO files are automatically created. Naturally, the translator
286 then have to provide translations for every content used in your
287 documents. po4a(1) also creates a POT file, that is a PO template file.
288 Potential translators can translate your project into a new language by
289 renaming this file and providing the translations in their language.
290
291 If you prefer to use the individual scripts separately, you should use
292 po4a-gettextize(1) as follows to create the POT file. This file can
293 then be copied into XX.po to initiate a new translation.
294
295 $ po4a-gettextize --format <format> --master <master.doc> --po <translation.pot>
296
297 The master document is used in input, while the POT file is the output
298 of this process.
299
300 Integrating changes to the original document
301 The script to use for that is po4a-updatepo(1) (please refer to its
302 documentation for details):
303
304 $ po4a-updatepo --format <format> --master <new_master.doc> --po <old_doc.XX.po>
305
306 The master document is used in input, while the PO file is updated: it
307 is used both in input and output.
308
309 Generating a translated document
310 Once you're done with the translation, you want to get the translated
311 documentation and distribute it to users along with the original one.
312 For that, use the po4a-translate(1) program as follows:
313
314 $ po4a-translate --format <format> --master <master.doc> --po <doc.XX.po> --localized <XX.doc>
315
316 Both the master and PO files are used in input, while the localized
317 file is the output of this process.
318
319 Using addenda to add extra text to translations
320 Adding new text to the translation is probably the only thing that is
321 easier in the long run when you translate files manually :). This
322 happens when you want to add an extra section to the translated
323 document, not corresponding to any content in the original document.
324 The classical use case is to give credits to the translation team, and
325 to indicate how to report translation-specific issues.
326
327 With po4a, you have to specify addendum files, that can be conceptually
328 viewed as patches applied to the localized document after processing.
329 Each addendum must be provided as a separate file, which format is
330 however very different from the classical patches. The first line is a
331 header line, defining the insertion point of the addendum (with an
332 unfortunately cryptic syntax -- see below) while the rest of the file
333 is added verbatim at the determined position.
334
335 The header line must begin with the string PO4A-HEADER:, followed by a
336 semi-colon separated list of key=value fields.
337
338 For example, the following header declares an addendum that must be
339 placed at the very end of the translation.
340
341 PO4A-HEADER: mode=eof
342
343 Things are more complex when you want to add your extra content in the
344 middle of the document. The following header declares an addendum that
345 must be placed after the XML section containing the string "About this
346 document" in translation.
347
348 PO4A-HEADER: position=About this document; mode=after; endboundary=</section>
349
350 In practice, when trying to apply an addendum, po4a searches for the
351 first line matching the "position" argument (this can be a regexp). Do
352 not forget that po4a considers the translated document here. This
353 documentation is in English, but your line should probably read as
354 follows if you intend your addendum to apply to the French translation
355 of the document.
356
357 PO4A-HEADER: position=À propos de ce document; mode=after; endboundary=</section>
358
359 Once the "position" is found in the target document, po4a searches for
360 the next line after the "position" that matches the provided
361 "endboundary". The addendum is added right after that line (because we
362 provided an endboundary, i.e. a boundary ending the current section).
363
364 The exact same effect could be obtained with the following header, that
365 is equivalent:
366
367 PO4A-HEADER: position=About this document; mode=after; beginboundary=<section>
368
369 Here, po4a searches for the first line matching "<section"> after the
370 line matching "About this document" in the translation, and add the
371 addendum before that line since we provided a beginboundary, i.e. a
372 boundary marking the beginning of the next section. So this header line
373 requires to place the addendum after the section containing "About this
374 document", and instruct po4a that a section starts with a line
375 containing the "<section"> tag. This is equivalent to the previous
376 example because what you really want is to add this addendum either
377 after "/section"> or before "<section">.
378
379 You can also set the insertion mode to the value "before", with a
380 similar semantic: combining "mode=before" with an "endboundary" will
381 put the addendum just after the matched boundary, that the last
382 potential boundary line before the "position". Combining "mode=before"
383 with an "beginboundary" will put the addendum just before the matched
384 boundary, that the last potential boundary line before the "position".
385
386 Mode | Boundary kind | Used boundary | Insertion point compared to the boundary
387 ========|===============|========================|=========================================
388 'before'| 'endboundary' | last before 'position' | Right after the selected boundary
389 'before'|'beginboundary'| last before 'position' | Right before the selected boundary
390 'after' | 'endboundary' | first after 'position' | Right after the selected boundary
391 'after' |'beginboundary'| first after 'position' | Right before the selected boundary
392 'eof' | (none) | n/a | End of file
393
394 Hint and tricks about addenda
395
396 · Remember that these are regexp. For example, if you want to match
397 the end of a nroff section ending with the line ".fi", do not use
398 ".fi" as endboundary, because it will match with "the[ fi]le",
399 which is obviously not what you expect. The correct endboundary in
400 that case is: "^\.fi$".
401
402 · White spaces ARE important in the content of the "position" and
403 boundaries. So the two following lines are different. The second
404 one will only be found if there is enough trailing spaces in the
405 translated document.
406
407 PO4A-HEADER: position=About this document; mode=after; beginboundary=<section>
408 PO4A-HEADER: position=About this document ; mode=after; beginboundary=<section>
409
410 · Although this context search may be considered to operate roughly
411 on each line of the translated document, it actually operates on
412 the internal data string of the translated document. This internal
413 data string may be a text spanning a paragraph containing multiple
414 lines or may be a XML tag itself alone. The exact insertion point
415 of the addendum must be before or after the internal data string
416 and can not be within the internal data string.
417
418 · Pass the -vv argument to po4a to understand how the addenda are
419 added to the translation. It may also help to run po4a in debug
420 mode to see the actual internal data string when your addendum does
421 not apply.
422
423 Addenda examples
424
425 · If you want to add something after the following nroff section:
426
427 .SH "AUTHORS"
428
429 You should select a two step approach by setting mode=after. Then
430 you should narrow down search to the line after AUTHORS with the
431 position argument regex. Then, you should match the beginning of
432 the next section (i.e., ^\.SH) with the beginboundary argument
433 regex. That is to say:
434
435 PO4A-HEADER:mode=after;position=AUTHORS;beginboundary=\.SH
436
437 · If you want to add something right after a given line (e.g. after
438 the line "Copyright Big Dude"), use a position matching this line,
439 mode=after and give a beginboundary matching any line.
440
441 PO4A-HEADER:mode=after;position=Copyright Big Dude, 2004;beginboundary=^
442
443 · If you want to add something at the end of the document, give a
444 position matching any line of your document (but only one line.
445 Po4a won't proceed if it's not unique), and give an endboundary
446 matching nothing. Don't use simple strings here like "EOF", but
447 prefer those which have less chance to be in your document.
448
449 PO4A-HEADER:mode=after;position=About this document;beginboundary=FakePo4aBoundary
450
451 More detailed example
452
453 Original document (POD formatted):
454
455 |=head1 NAME
456 |
457 |dummy - a dummy program
458 |
459 |=head1 AUTHOR
460 |
461 |me
462
463 Then, the following addendum will ensure that a section (in French)
464 about the translator is added at the end of the file (in French,
465 "TRADUCTEUR" means "TRANSLATOR", and "moi" means "me").
466
467 |PO4A-HEADER:mode=after;position=AUTEUR;beginboundary=^=head
468 |
469 |=head1 TRADUCTEUR
470 |
471 |moi
472 |
473
474 To put your addendum before the AUTHOR, use the following header:
475
476 PO4A-HEADER:mode=after;position=NOM;beginboundary=^=head1
477
478 This works because the next line matching the beginboundary /^=head1/
479 after the section "NAME" (translated to "NOM" in French), is the one
480 declaring the authors. So, the addendum will be put between both
481 sections. Note that if another section is added between NAME and AUTHOR
482 sections later, po4a will wrongfully put the addenda before the new
483 section.
484
485 To avoid this you may accomplish the same using mode=before:
486
487 PO4A-HEADER:mode=before;position=^=head1 AUTEUR
488
490 This chapter gives you a brief overview of the po4a internals, so that
491 you may feel more confident to help us maintaining and improving it. It
492 may also help you understanding why it does not do what you expected,
493 and how to solve your problems.
494
495 The po4a architecture is object oriented. The
496 Locale::Po4a::TransTractor(3pm) class is the common ancestor to all
497 po4a parsers. This strange name comes from the fact that it is at the
498 same time in charge of translating document and extracting strings.
499
500 More formally, it takes a document to translate plus a PO file
501 containing the translations to use as input while producing two
502 separate outputs: Another PO file (resulting of the extraction of
503 translatable strings from the input document), and a translated
504 document (with the same structure than the input one, but with all
505 translatable strings replaced with content of the input PO). Here is a
506 graphical representation of this:
507
508 Input document --\ /---> Output document
509 \ TransTractor:: / (translated)
510 +-->-- parse() --------+
511 / \
512 Input PO --------/ \---> Output PO
513 (extracted)
514
515 This little bone is the core of all the po4a architecture. If you omit
516 the input PO and the output document, you get po4a-gettextize. If you
517 provide both input and disregard the output PO, you get po4a-translate.
518 The po4a calls TransTractor twice and calls msgmerge -U between these
519 TransTractor invocations to provide one-stop solution with a single
520 configuration file. Please see Locale::Po4a::TransTractor(3pm) for
521 more details.
522
524 Here is a very partial list of projects that use po4a in production for
525 their documentation. If you want to add your project to the list, just
526 drop us an email (or a Merge Request).
527
528 · adduser (man): users and groups management tool.
529
530 · apt (man, docbook): Debian package manager.
531
532 · aptitude (docbook, svg): terminal-based package manager for Debian
533
534 · F-Droid website <https://gitlab.com/fdroid/fdroid-website>
535 (markdown): installable catalogue of FOSS (Free and Open Source
536 Software) applications for the Android platform.
537
538 · git <https://github.com/jnavila/git-manpages-l10n> (asciidoc):
539 distributed version-control system for tracking changes in source
540 code.
541
542 · Linux manpages <https://salsa.debian.org/manpages-l10n-
543 team/manpages-l10n> (man)
544
545 This project provides an infrastructure for translating many
546 manpages to different languages, ready for integration into several
547 major distributions (Arch Linux, Debian and derivatives, Fedora).
548
549 · Stellarium <https://github.com/Stellarium/stellarium> (HTML): a
550 free open source planetarium for your computer. po4a is used to
551 translate the sky culture descriptions.
552
554 How do you pronounce po4a?
555 I personally vocalize it as pouah
556 <https://en.wiktionary.org/wiki/pouah>, which is a French onomatopoetic
557 that we use in place of yuck :) I may have a strange sense of humor :)
558
559 What about the other translation tools for documentation using gettext?
560 As far as I know, there are only two of them:
561
562 poxml
563 This is the tool developed by KDE people to handle DocBook XML.
564 AFAIK, it was the first program to extract strings to translate
565 from documentation to PO files, and inject them back after
566 translation.
567
568 It can only handle XML, and only a particular DTD. I'm quite
569 unhappy with the handling of lists, which end in one big msgid.
570 When the list become big, the chunk becomes harder to swallow.
571
572 po-debiandoc
573 This program done by Denis Barbier is a sort of precursor of the
574 po4a SGML module, which more or less deprecates it. As the name
575 says, it handles only the DebianDoc DTD, which is more or less a
576 deprecated DTD.
577
578 The main advantages of po4a over them are the ease of extra content
579 addition (which is even worse there) and the ability to achieve
580 gettextization.
581
582 SUMMARY of the advantages of the gettext based approach
583 · The translations are not stored along with the original, which makes
584 it possible to detect if translations become out of date.
585
586 · The translations are stored in separate files from each other, which
587 prevents translators of different languages from interfering, both
588 when submitting their patch and at the file encoding level.
589
590 · It is based internally on gettext (but po4a offers a very simple
591 interface so that you don't need to understand the internals to use
592 it). That way, we don't have to re-implement the wheel, and because
593 of their wide use, we can think that these tools are more or less bug
594 free.
595
596 · Nothing changed for the end-user (beside the fact translations will
597 hopefully be better maintained). The resulting documentation file
598 distributed is exactly the same.
599
600 · No need for translators to learn a new file syntax and their favorite
601 PO file editor (like Emacs' PO mode, Lokalize or Gtranslator) will
602 work just fine.
603
604 · gettext offers a simple way to get statistics about what is done,
605 what should be reviewed and updated, and what is still to do. Some
606 example can be found at those addresses:
607
608 - https://docs.kde.org/stable5/en/kdesdk/lokalize/project-view.html
609 - http://www.debian.org/intl/l10n/
610
611 But everything isn't green, and this approach also has some
612 disadvantages we have to deal with.
613
614 · Addenda are… strange at the first glance.
615
616 · You can't adapt the translated text to your preferences, like
617 splitting a paragraph here, and joining two other ones there. But in
618 some sense, if there is an issue with the original, it should be
619 reported as a bug anyway.
620
621 · Even with an easy interface, it remains a new tool people have to
622 learn.
623
624 One of my dreams would be to integrate somehow po4a to Gtranslator or
625 Lokalize. When a documentation file is opened, the strings are
626 automatically extracted, and a translated file + po file can be
627 written to disk. If we manage to do an MS Word (TM) module (or at
628 least RTF) professional translators may even use it.
629
631 · The documentation of the all-in-one tool that you should use:
632 po4a(1).
633
634 · The documentation of the individual po4a scripts:
635 po4a-gettextize(1), po4a-updatepo(1), po4a-translate(1),
636 po4a-normalize(1).
637
638 · The additional helping scripts: msguntypot(1), po4a-display-man(1),
639 po4a-display-pod(1).
640
641 · The parsers of each formats, in particular to see the options
642 accepted by each of them: Locale::Po4a::AsciiDoc(3pm)
643 Locale::Po4a::Dia(3pm), Locale::Po4a::Guide(3pm),
644 Locale::Po4a::Ini(3pm), Locale::Po4a::KernelHelp(3pm),
645 Locale::Po4a::Man(3pm), Locale::Po4a::RubyDoc(3pm),
646 Locale::Po4a::Texinfo(3pm), Locale::Po4a::Text(3pm),
647 Locale::Po4a::Xhtml(3pm), Locale::Po4a::Yaml(3pm),
648 Locale::Po4a::BibTeX(3pm), Locale::Po4a::Docbook(3pm),
649 Locale::Po4a::Halibut(3pm), Locale::Po4a::LaTeX(3pm),
650 Locale::Po4a::Pod(3pm), Locale::Po4a::Sgml(3pm),
651 Locale::Po4a::TeX(3pm), Locale::Po4a::Wml(3pm),
652 Locale::Po4a::Xml(3pm).
653
654 · The implementation of the core infrastructure:
655 Locale::Po4a::TransTractor(3pm) (particularly important to
656 understand the code organization), Locale::Po4a::Chooser(3pm),
657 Locale::Po4a::Po(3pm), Locale::Po4a::Common(3pm). Please also check
658 the CONTRIBUTING.md file in the source tree.
659
661 Denis Barbier <barbier,linuxfr.org>
662 Martin Quinson (mquinson#debian.org)
663
664
665
666Po4a Tools 2021-02-23 PO4A(7)