Section: User Contributed Perl Documentation (3)Updated: 2010-11-30Local indexUp
Locale::Po4a::Man - convert manual pages from/to PO files
The po4a (PO for anything) project goal is to ease translations (and more
interestingly, the maintenance of translations) using gettext tools on
areas where they were not expected like documentation.
Locale::Po4a::Man is a module to help the translation of documentation in
the nroff format (the language of manual pages) into other [human]
TRANSLATING WITH PO4A::MAN
This module tries pretty hard to make translator's life easier. For that,
the text presented to translators isn't a verbatim copy of the text found
in the man page. Indeed, the cruder parts of the nroff format are hidden, so
that translators can't mess up with them.
Unindented paragraphs are automatically rewrapped for the translator. This
can lead to some minor difference in the generated output, since the
rewrapping rules used by groff aren't very clear. For example, two spaces
after a parenthesis are sometimes preserved.
Anyway, the difference will only be about the position of the extra spaces
in wrapped paragraph, and I think it's worth.
The first change is about font change specifications. In nroff, there are
several ways to specify if a given word should be written in small, bold or
italics. In the text to translate, there is only one way, borrowed from the
POD (Perl online documentation) format:
I<text> --- italic text
equivalent to \fItext\fP or ``.I text''
B<text> --- bold text
equivalent to \fBtext\fP or ``.B text''
R<text> --- roman text
equivalent to \fRtext\fP
CW<text> --- constant width text
equivalent to \f(CWtext\fP or ``.CW text''
Remark: The CW face is not available for all groff devices. It is not
recommended to use it. It is provided for your convenience.
Automatic characters transliteration
Po4a automatically transliterate some characters to ease the translation
or the review of the translation.
Here is the list of the transliterations:
Hyphens (-) and minus signs (\-) in man pages are all transliterated
as simple dashes (-) in the PO file. Then all dash are transliterated into
roff minus signs (\-) when the translation is inserted into the output
Translators can force an hyphen by using the roff glyph '\[hy]' in their
Translators can use non-breaking spaces in their translations. These
non-breaking spaces (0xA0 in latin1) will be transliterated into a roff
non-breaking space ('\ ').
`` and '' are respectively tranliterated into \*(lq and \*(rq.
To avoid these transliterations, translators can insert a zero width roff
character (i.e., using `\&` or '\&' respectively).
Putting '<' and '>' in translations
Since these chars are used to delimit parts under font modification, you
can't use them verbatim. Use E<lt> and E<gt> instead (as in
POD, one more time).
OPTIONS ACCEPTED BY THIS MODULE
These are this module's particular options:
Activate debugging for some internal mechanisms of this module.
Use the source to see which parts can be debugged.
This option permits to change the behavior of the module when it encounter
a .de, .ie or .if section. It can take the following values:
This is the default value.
The module will fail when a .de, .ie or .if section is encountered.
Indicates that the .de, .ie or .if sections must be copied as is
from the original to the translated document.
Indicates that the .de, .ie or .if sections will be proposed for the
You should only use this option if a translatable string is
contained in one of these section. Otherwise, verbatim
should be preferred.
This option specifies that the file was generated, and that po4a should not
try to detect if the man pages was generated from another format.
This permits to use po4a on generated man pages.
This option does not take any argument.
This option is only useful for mdoc pages.
It selects a stricter support of the mdoc format by telling po4a not to
translate the 'NAME' section.
mdoc pages whose 'NAME' section is translated won't generate any header of
According to the groff_mdoc page, the NAME, SYNOPSIS and DESCRIPTION
sections are mandatory.
There are no known issues with translated SYNOPSIS or DESCRIPTION section,
but you can also specify these sections this way:
This mdoc issue can also be solved with an addendum like this one:
.TH DOCUMENT_TITLE 1 ``Month day, year'' OS ``Section Name''
The following options permit to specify the behavior of a new macro
(defined with a .de request), or of a macro not supported by po4a.
They take in argument a coma separated list of macros.
-o noarg=FO,OB,AR -o translate_joined=BA,ZQ,UX
Note: if a macro is not supported by po4a and if you consider that it is a
standard roff macro, you should submit it to the po4a development team.
untranslated indicates that this macro (at its arguments) don't have to
noarg is like untranslated, except that po4a will verify that no
argument is added to this macro.
translate_joined indicates that po4a must propose to translate the
arguments of the macro.
With translate_each, the arguments will also be proposed for the
translation, except that each one will be translated separately.
This option takes in argument a list of coma-separated couples
begin:end, where begin and end are commands that delimit
the begin and end of a section that should not be rewrapped.
Note: no test is done to ensure that an end command matches its
begin command; any ending command stop the no_wrap mode.
If you have a begin (respectively end) macro that has no end
(respectively begin), you can specify an existing end (like fi) or
begin (like nf) as a counterpart.
These macros (and their arguments) wont be translated.
This option specifies a list of coma-separated macros that must
not split the current paragraph. The string to translate will then contain
foo <.bar baz qux> quux, where bar is the command that
should be inlined, and baz qux its arguments.
This option indicates how po4a should behave when an unknown macro is found.
By default, po4a fails with a warning.
It can take the following values: failed (the default value),
untranslated, noarg, translate_joined, translate_each.
AUTHORING MAN PAGES COMPLIANT WITH PO4A::MAN
This module is still very limited, and will always be, because it's not a
real nroff interpreter. It would be possible to do a real nroff
interpreter, to allow authors to use all the existing macros, or even to
define new ones in their pages, but we didn't want to. It would be too
difficult, and we thought it wasn't necessary. We do think that if
manpages' authors want to see their productions translated, they may have to
adapt to ease the work of translators.
So, the man parser implemented in po4a have some known limitations we are
not really inclined to correct, and which will constitute some pitfalls
you'll have to avoid if you want to see translators taking care of your
Don't program in nroff
nroff is a complete programming language, with macro definition,
conditionals and so on. Since this parser isn't a fully featured nroff
interpreter, it will fail on pages using these facilities (There are about
200 such pages on my box).
Use the plain macro set
There are still some macros which are not supported by po4a::man. This is
only because I failed to find any documentation about them. Here is the
list of unsupported macros used on my box. Note that this list isn't
exhaustive since the program fails on the first encountered unsupported
macro. If you have any information about some of these macros, I'll
happily add support for them. Because of these macros, about 250 pages on
my box are inaccessible to po4a::man.
Sometimes, the author knows that some parts are not translatable, and
should not be extracted by po4a. For example, an option may accept an
other argument, and other may also appear as the last item of a
list. In the first case, other should be not be translatable. And in
the second case, other should be translated.
In such case, the author can avoid po4a to extract some strings, using
some special groff constructs:
.if !'po4a'hide' .B other
(this will require the -o groff_code=verbatim option)
A new macro can also be defined to automate this:
. IR \\$@
.IR_untranslated \-q ", " \-\-quiet
(this will require the options -o groff_code=verbatim and
-o untranslated=IR_untranslated; with this construct, the .if
!'po4a'hide' conditional is not strictly needed since po4a will not parse
the internal of the macro definition)
or using an alias:
.als IR_untranslated IR
.IR_untranslated \-q ", " \-\-quiet
(this will require the -o untranslated=als,IR_untranslated option)
To summarise this section, keep simple, and don't try to be clever while
authoring your man pages. A lot of things are possible in nroff, and not
supported by this parser. For example, don't try to mess with \c to
interrupt the text processing (like 40 pages on my box do). Or, be sure to
put the macro arguments on the same line that the macro itself. I know that
it's valid in nroff, but would complicate too much the parser to be
Of course, another possibility is to use another format, more translator
friendly (like POD using po4a::pod, or one of the XML familly like SGML),
but thanks to po4a::man it isn't needed anymore. That being said, if the
source format of your documentation is POD, or XML, it may be clever to
translate the source format and not this generated one. In most cases,
po4a::man will detect generated pages and issue a warning. It will even
refuse to process POD generated pages, because those pages are perfectly
handled by po4a::pod, and because their nroff counterpart defines a lot of
new macros I didn't want to write support for. On my box, 1432 of the 4323
pages are generated from POD and will be ignored by po4a::man.
In most cases, po4a::man will detect the problem and refuse to process the
page, issuing an adapted message. In some rare cases, the program will
complete without warning, but the output will be wrong. Such cases are
called ``bugs'' ;) If you encounter such case, be sure to report this, along
with a fix when possible...
STATUS OF THIS MODULE
This module can be used for most of the existing man pages.
Some tests are regularly run on Linux boxes:
one third of the pages are refused because they were generated from
another format supported by po4a (e.g. POD or SGML).
10% of the remaining pages are rejected with an error (e.g. a
groff macro is not supported).
Then, less than 1% of the pages are accepted silently by po4a, but with
significant issues (i.e. missing words, or new words inserted)
The other pages are usually handled without differences more important
than spacing differences or line rewrapped (font issues in less than 10% of
the processed pages).