either
<filename>.po</filename> or <filename>.mo</filename>. The base
name is either the name of the program it accompanies, or the
language the file is for, depending on the situation. This is a
bit confusing. Examples are <filename>psql.po</filename> (PO file
for psql) or <filename>fr.mo</filename> (MO file in French).
</para>
<para>
The file format of the PO files is illustrated here:
<programlisting>
# comment
msgid "original string"
msgstr "translated string"
msgid "more original"
msgstr "another translated"
"string can be broken up like this"
...
</programlisting>
The msgid lines are extracted from the program source. (They need not
be, but this is the most common way.) The msgstr lines are
initially empty and are filled in with useful strings by the
translator. The strings can contain C-style escape characters and
can be continued across lines as illustrated. (The next line must
start at the beginning of the line.)
</para>
<para>
The # character introduces a comment. If whitespace immediately
follows the # character, then this is a comment maintained by the
translator. There can also be automatic comments, which have a
non-whitespace character immediately following the #. These are
maintained by the various tools that operate on the PO files and
are intended to aid the translator.
<programlisting>
#. automatic comment
#: filename.c:1023
#, flags, flags
</programlisting>
The #. style comments are extracted from the source file where the
message is used. Possibly the programmer has inserted information
for the translator, such as about expected alignment. The #:
comments indicate the exact locations where the message is used
in the source. The translator need not look at the program
source, but can if there is doubt about the correct
translation. The #, comments contain flags that describe the
message in some way. There are currently two flags:
<literal>fuzzy</literal> is set if the message has possibly been
outdated because of changes in the program source. The translator
can then verify this and possibly remove the fuzzy flag. Note
that fuzzy messages are not made available to the end user. The
other flag is <literal>c-format</literal>, which indicates that
the message is a <function>printf</function>-style format
template. This means that the translation should also be a format
string with the same number and type of placeholders. There are
tools that can verify this, which key off the c-format flag.
</para>
</sect2>
<sect2 id="nls-translator-message-catalogs">
<title>Creating and Maintaining Message Catalogs</title>
<para>
OK, so how does one create a <quote>blank</quote> message
catalog? First, go into the directory that contains the program
whose messages you want to translate. If there is a file
<filename>nls.mk</filename>, then this program has been prepared
for translation.
</para>
<para>
If there are already some <filename>.po</filename> files, then
someone has already done some translation work. The files are
named <filename><replaceable>language</replaceable>.po</filename>,
where <replaceable>language</replaceable> is the
<ulink url="https://www.loc.gov/standards/iso639-2/php/English_list.php">
ISO 639-1 two-letter language code (in lower case)</ulink>, e.g.,
<filename>fr.po</filename> for French. If there is really a need
for more than one translation effort per language then the files
can also be named
<filename><replaceable>language</replaceable>_<replaceable>region</replaceable>.po</filename>
where <replaceable>region</replaceable> is the
<ulink url="https://www.iso.org/iso-3166-country-codes.html">
ISO 3166-1 two-letter country code (in upper case)</ulink>,
e.g.,
<filename>pt_BR.po</filename> for Portuguese in Brazil. If you