<?xml version="1.0"?>
<!--
SPDX-FileCopyrightText: Copyright The SCons Foundation (https://scons.org)
SPDX-License-Identifier: MIT
SPDX-FileType: DOCUMENTATION

This file is processed by the bin/SConsDoc.py module.
-->

<!DOCTYPE sconsdoc [
<!ENTITY % scons SYSTEM '../../doc/scons.mod'>
%scons;
<!ENTITY % builders-mod SYSTEM '../../doc/generated/builders.mod'>
%builders-mod;
<!ENTITY % functions-mod SYSTEM '../../doc/generated/functions.mod'>
%functions-mod;
<!ENTITY % tools-mod SYSTEM '../../doc/generated/tools.mod'>
%tools-mod;
<!ENTITY % variables-mod SYSTEM '../../doc/generated/variables.mod'>
%variables-mod;
]>

<sconsdoc xmlns="http://www.scons.org/dbxsd/v1.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://www.scons.org/dbxsd/v1.0 http://www.scons.org/dbxsd/v1.0/scons.xsd">

<tool name="gettext">
<summary>
<para>
A toolset supporting internationalization and
localization of software being constructed with &SCons;.
The toolset loads the following tools:
</para>

<para>
<itemizedlist mark='opencircle'>
  <listitem><para>
    &t-link-xgettext; - extract internationalized messages from source code to
    <literal>POT</literal> file(s).
  </para></listitem>
  <listitem><para>
    &t-link-msginit; - initialize <literal>PO</literal>
    files during initial translation of a project.
  </para></listitem>
  <listitem><para>
    &t-link-msgmerge; - update <literal>PO</literal> files that already contain
    translated messages,</para></listitem>
  <listitem><para>
    &t-link-msgfmt; - compile textual <literal>PO</literal> files to binary
    installable <literal>MO</literal> files.
  </para></listitem>
</itemizedlist>
</para>

<para>
When you enable &t-gettext;, it internally loads all the above-mentioned tools,
so you're encouraged to see their individual documentation.
</para>

<para>
Each of the above tools provides its own builder(s) which may be used to
perform particular activities related to software internationalization. You
may be however interested in <emphasis>top-level</emphasis>
&b-link-Translate; builder.
</para>

<para>
To use the &t-gettext; tools, add the <literal>'gettext'</literal> tool to your
&consenv;:
</para>
<programlisting language="python">
env = Environment(tools=['default', 'gettext'])
</programlisting>
</summary>
<sets>
</sets>
<uses>
<item><!-- PLATFORM --></item>
</uses>
</tool>

<builder name="Translate">
<summary>
<para>
This pseudo-Builder is part of the &t-link-gettext; toolset.
The builder extracts internationalized messages from source files,
updates the <literal>POT</literal> template (if necessary)
and then updates <literal>PO</literal> translations (if necessary).
If &cv-link-POAUTOINIT; is set, missing <literal>PO</literal> files
will be automatically created (i.e. without translator person intervention).
The variables &cv-link-LINGUAS_FILE; and &cv-link-POTDOMAIN; are taken into
account too. All other construction variables used by &b-link-POTUpdate;, and
&b-link-POUpdate; work here too.
</para>

<para>
<emphasis>Example 1</emphasis>.
The simplest way is to specify input files and output languages inline in
a SCons script when invoking &b-Translate;:
</para>
<programlisting language="python">
# SConscript in 'po/' directory
env = Environment(tools=["default", "gettext"])
env['POAUTOINIT'] = True
env.Translate(['en', 'pl'], ['../a.cpp', '../b.cpp'])
</programlisting>

<para>
<emphasis>Example 2</emphasis>.
If you wish, you may also stick to the conventional style known from
<productname>autotools</productname>, i.e. using
<filename>POTFILES.in</filename> and <filename>LINGUAS</filename> files
to specify the targets and sources:
</para>
<programlisting language="python">
# LINGUAS
en pl
# end
</programlisting>

<programlisting>
# POTFILES.in
a.cpp
b.cpp
# end
</programlisting>

<programlisting language="python">
# SConscript
env = Environment(tools=["default", "gettext"])
env['POAUTOINIT'] = True
env['XGETTEXTPATH'] = ['../']
env.Translate(LINGUAS_FILE=True, XGETTEXTFROM='POTFILES.in')
</programlisting>

<para>
The last approach is perhaps the recommended one. It allows easily split
internationalization/localization onto separate SCons scripts, where a script
in source tree is responsible for translations (from sources to
<literal>PO</literal> files) and script(s) under variant directories are
responsible for compilation of <literal>PO</literal> to <literal>MO</literal>
files to and for installation of <literal>MO</literal> files. The "gluing
factor" synchronizing these two scripts is then the content of
<filename>LINGUAS</filename> file.  Note, that the updated
<literal>POT</literal> and <literal>PO</literal> files are usually going to be
committed back to the repository, so they must be updated within the source
directory (and not in variant directories). Additionally, the file listing of
<filename>po/</filename> directory contains <filename>LINGUAS</filename> file,
so the source tree looks familiar to translators, and they may work with the
project in their usual way.
</para>

<para>
<emphasis>Example 3</emphasis>.
Let's prepare a development tree as below
</para>
<programlisting>
 project/
  + SConstruct
  + build/
  + src/
      + po/
          + SConscript
          + SConscript.i18n
          + POTFILES.in
          + LINGUAS
</programlisting>
<para>
with <filename>build</filename> being the variant directory.
Write the top-level
<filename>SConstruct</filename> script as follows
</para>
<programlisting language="python">
# SConstruct
env = Environment(tools=["default", "gettext"])
VariantDir('build', 'src', duplicate=False)
env['POAUTOINIT'] = True
SConscript('src/po/SConscript.i18n', exports='env')
SConscript('build/po/SConscript', exports='env')
</programlisting>
<para>
the <filename>src/po/SConscript.i18n</filename> as
</para>
<programlisting language="python">
# src/po/SConscript.i18n
Import('env')
env.Translate(LINGUAS_FILE=True, XGETTEXTFROM='POTFILES.in', XGETTEXTPATH=['../'])
</programlisting>
<para>
and the <filename>src/po/SConscript</filename>
</para>
<programlisting language="python">
# src/po/SConscript
Import('env')
env.MOFiles(LINGUAS_FILE=True)
</programlisting>
<para>
Such a setup produces <literal>POT</literal> and <literal>PO</literal> files
under the source tree in <filename>src/po/</filename> and binary
<literal>MO</literal> files under the variant tree in
<filename>build/po/</filename>. This way the <literal>POT</literal> and
<literal>PO</literal> files are separated from other output files, which must
not be committed back to source repositories (e.g. <literal>MO</literal>
files).
</para>

<note><para>In the above example,
the <literal>PO</literal> files are not updated,
nor created automatically when you issue the command
<userinput>scons .</userinput>.
The files must be updated (created) by hand via
<userinput>scons po-update</userinput>
and then <literal>MO</literal> files can be compiled by
running <userinput>scons .</userinput>.
</para></note>

</summary>
</builder>

<cvar name="POTDOMAIN">
<summary>
<para>
The &cv-POTDOMAIN; defines default domain, used to generate
<literal>POT</literal> filename as <filename>&cv-POTDOMAIN;.pot</filename> when
no <literal>POT</literal> file name is provided by the user. This applies to
&b-link-POTUpdate;, &b-link-POInit; and &b-link-POUpdate; builders (and
builders, that use them, e.g. &b-Translate;). Normally (if &cv-POTDOMAIN; is
not defined), the builders use <filename>messages.pot</filename> as default
<literal>POT</literal> file name.
</para>
</summary>
</cvar>

<cvar name="POAUTOINIT">
<summary>
<para>
The &cv-POAUTOINIT; variable, if set to <literal>True</literal> (on non-zero
numeric value), let the &t-link-msginit; tool to automatically initialize
<emphasis>missing</emphasis> <literal>PO</literal> files with
<command>msginit(1)</command>.  This applies to both,
&b-link-POInit; and &b-link-POUpdate; builders (and others that use any of
them).
</para>
</summary>
</cvar>

<cvar name="LINGUAS_FILE">
<summary>
<para>
The &cv-LINGUAS_FILE; defines file(s) containing list of additional linguas
to be processed by &b-link-POInit;, &b-link-POUpdate; or &b-link-MOFiles;
builders. It also affects &b-link-Translate; builder. If the variable contains
a string, it defines the name of the list file. The &cv-LINGUAS_FILE; may be a
list of file names as well. If &cv-LINGUAS_FILE; is set to
a non-string truthy value, the list will be read from
the file named
<filename>LINGUAS</filename>.
</para>

</summary>
</cvar>

</sconsdoc>
