Huidae Cho ffe755fe09 i18n: Transifex sync (#2236) 2 years ago
..
po ffe755fe09 i18n: Transifex sync (#2236) 2 years ago
scriptstrings db49180dd7 welcome to GRASS 7.0.svn 16 years ago
templates db49180dd7 welcome to GRASS 7.0.svn 16 years ago
transifex 8efbad4d37 transifex: restore transifex_merge.sh method, i.e. file sync structure as used in G74 6 years ago
Makefile 07d095e971 i18n: xgettext --from-code=utf-8 (#2061) 2 years ago
README 15d6526eac GRASS GIS 8 dev: version bump to grass81 (#2084) 2 years ago
grass_po_stats.py e9dfbc4eee Apply Black to locale (#1513) 3 years ago

README

HOWTO translate GRASS messages
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

This file contains following sections:
1. Instructions for programmers;
2. A translation workflow overview;
3. A detailed explanation of translation workflow, testing;
4. Some notes and links

[ Web page: https://grass.osgeo.org/devel/i18n.php ]

Updating the message catalogs currently only works on
unix-like systems and requires xgettext.

------------------------------------------------------

REQUIRED SOURCE CODE CHANGES (programming required)

Generally, to support i18N multiple languages,
message strings in GRASS must be modified from

fprintf ( ..., "...\n", ...);
to either
fprintf ( ..., _("...\n"), ...);
or (omit \n)
G_message ( _("..."), ...);

Careful:
G_message should be used for messages - information about
the process for user while fprintf(stdout...) for data output.
G_message output is not expected to be send to pipe or file.
fprintf(stdout...) output is usually send to pipe or file.


Three steps:
1) check if fprintf is to be replaced (see above)

2) to add (see example above):
the macro _( ) which encapulates the message

3) to be added to file.c header:
#include "glocale.h"

This line has to be added to each C file which contains
user messages, preferably as last #include statement.
Only, if missing, also add
#include "gis.h"

NOTE: Also G_warning() and G_fatal_error() need the message
encapsulation with macro _() but no further changes.

NOTE2: Also the parameters/flags of each module needs the
macro _().

NOTE3: Notices to translators can be added by placing
a comment line starting with GTC tag just above
message to be translated:
/* GTC A comma separated keyword list.
Should not contain spaces! */
keywords = _("first,second,third");

NOTE4: Any string containing a number that requires a correct plural form of
a noun, has to pass trough ngettext function implemented in GRASS
as a n_() macro.
n_("Message in English for singular case", "Message in English for
plural case", number)

Examples of messages with plural forms.
Wrong:
G_message( _("%d map(s) from mapset <%s> removed"), n, ms);
G_message( n == 1 ? _("One file removed") : _("%d files removed"), n);
G_warning( _("%d %s without geometry skipped"), n,
n == 1 ? "feature" : "features");
G_message( _("%d maps selected"), n);
G_message( n == 1 ? _("Remove map") : _("Remove maps"));

Correct:
G_message( n_("%d map from mapset <%s> removed",
"%d maps from mapset <%s> removed", n), n, ms);
/* Notice double use of number "n" - as an argument for
both functions - n_() and G_message() */
G_message( n_("One file removed", "%d files removed", n) n);
/* Both of forms of singular case "%d file" or "One file" are correct.
The choice between them is purely stylistic one. */
G_warning( n_("One feature without geometry skipped",
"%d features without geometry skipped", n), n);
G_message( n_("%d map selected", "%d maps selected", n), n);
/* Although in English it is not necessary to provide a separate
text if "n" always is >1, in other languages is a difference if "n"
is i.e. 2-4, or n==10 etc. */
G_message( n_("Remove map", "Remove maps", n));
/* Number it self doesn't have to be used in the output text */


All these messages strings will be then automatically
extracted into the message files.

See for example ./vector/v.what.rast/main.c

NOTE4: Such lines
fprintf (stdout,"\n");
do not need a change as no translation is needed.

A detailed example of adapting code for use in multiple languages
can be found in gettext manual.
How to prepare program source:
https://www.gnu.org/software/gettext/manual/gettext.html#Sources

More advanced tricks like resolving ambiguties and handling of plural forms:
https://www.gnu.org/software/gettext/manual/gettext.html#Programmers


TODO: ADD PYTHON code snippets here

------------------------------------------------------

GENERAL TRANSLATION PROCEDURE (no programming required)

POT files [1] ----> PO files [2] ----> update PO files [3] ----> PO merge + MO files [4]
(original (translated (updating of msgs (final binary message file,
messages) messages) in Transifex) used by GRASS GIS modules)

see also: https://grasswiki.osgeo.org/wiki/GRASS_messages_translation#Get_the_translated_po_files

[1] .pot files are auto-generated on grass.osgeo.org and
stored in https://grass.osgeo.org/grass-devel/binary/linux/snapshot/transifex/
--> cronjob (on grasslxd container): /home/neteler/cronjobs/cron_grass8_main_src_snapshot.sh

[2] Transifex job copies daily from [1] to here:
https://www.transifex.com/grass-gis/grass7/dashboard/

[3] Translators work in Transifex,

[4] Updated po files are taken from Transifex and merged into GRASS GIS source repo
(MO files are generated when compiling GRASS GIS)
Script: https://github.com/OSGeo/grass-addons/blob/grass8/utils/transifex_merge.sh

# trim disconnected=obsolete translations
POFILE=grassYXZ_LANG.po
msgattrib --output-file=$POFILE --no-obsolete $POFILE


Semi-automated procedure:

1. In the main GRASS source code directory, run:

./configured --with-nls [...further options...]
make

2. In the locale/ directory, run:

TODO OLD make pot creates grass.pot (containing original messages)

TODO OLD make update-po merges new messages into existing *.po files

3. Now translate the messages in the po/*.po files (using kbabel or
other editor). Just open the .po file(s) in your preferred translation
software.

4. In the locale/ directory, run:

make mo creates the mo files (containing translated messages as
binary file)

If you have any difficulty with these instructions please ask for help
on the GRASS development mailing list
(subscribe at https://lists.osgeo.org/mailman/listinfo/grass-dev). Your
willingness, time, and effort translating are valuable. If necessary,
all of these steps except for the actual translation can be done by
someone else on a different computer.

A convenient software package to translate messages is 'kbabel'.
It permits to enhance it's message database by loading existing
.po files to semi-automate the translation.

Note that GRASS must be configured with '--with-nls' and (re)compiled
to make use of the translated messages.

There is a file for all library messages and another for all
module messages (this might be split in future).

------------------------------------------------------
DETAILED PROCEDURE :

1. Define/check language settings

echo $LANG
echo $LANGUAGE
echo $LC_ALL

Maybe you have to change it (example for Japanese):
- for bash shell:
export LANG=ja_JP
export LANGUAGE=ja_JP
export LC_ALL=ja_JP

- for (t)csh shell:
setenv LANG ja_JP
setenv LANGUAGE ja_JP
setenv LC_ALL ja_JP


2. CREATE POT FILES
run
make pot

This will create
./templates/grasslibs.pot
./templates/grassmods.pot
./templates/grasswxpy.pot


3. CREATE LANGUAGE FILES

Two cases have to be distinguished:
a) Messages have not yet been translated to your language.
b) Some messages have already been translated to your language,
so you want to merge your efforts into the existing translation.

3.a) First CASE: Messages have not yet been translated to your language.
No .po file is present for your language in the ./po/ directory.

Run:
make pot
make update-po

Move the generated file from the ./template/ directory
to the ./po/ directory (for example German language):
mv ./template/grasslibs.pot ./po/grasslibs_de.po
mv ./template/grassmods.pot ./po/grassmods_de.po
mv ./template/grasswxpy.pot ./po/grasswxpy_de.po

Get the two characters indicating the language from this
code list: https://www.loc.gov/standards/iso639-2/php/English_list.php
The code to use is ISO 639-1 (two characters).

Then continue with 4. below.

3.b) Second CASE: Some messages have already been translated to
your language (files present in ./po/ directory), and
you want to continue with translating new and still
untranslated messages.

First we have to merge new messages into existing .po files
(which contain already translated messages) as new messages
might have been added into the GRASS system.
To do so, run:

make pot
make update-po

This will update the messages in all existing files in
the .po/ directory.


4. TRANSLATE MESSAGES

In the links section at bottom of this page you find references to the
'kbabel' and 'poEdit' software to easily translate the message files.

Run 'kbabel' or equivalent program
kbabel ./po/grasslibs_.po
kbabel ./po/grassmods_.po
kbabel ./po/grasswxpy_.po

For example (German):
kbabel ./po/grasslibs_de.po
kbabel ./po/grassmods_de.po
kbabel ./po/grasswxpy_de.po

KBABEL: You may load .po files from other projects [see footnote 1].
Then use TOOLS -> ROUGH TRANSLATION to auto-translate messages.
For Asian, Indian and other keymaps, see [footnote 3].

NOTES:
* Pay attention to keep '%s', '\n' and other stuff also
in the translated messages!

* Please use 'ISO-8859-1' or 'ISO-8859-15' for western languages.
See https://en.wikipedia.org/wiki/ISO_8859 for details.

After finishing the translation, save the files.


5. CREATE MO FILES

run
make mo

READY.


6. Now recompile, install and run GRASS.
It should work :-)

If you don't have this possibility, just skip this step.


7. Send the updated .po files to a GRASS Development Team member.
If possible, please send diffs against CVS:
git diff grasslibs_LANG.po > grasslibs_LANG_po.diff
git diff grassmods_LANG.po > grassmods_LANG_po.diff
git diff grasswxpy_LANG.po > grasswxpy_LANG_po.diff

If you updated .c files with _() macros as explained
above, please send C file diffs against git:

git diff file.c > file.diff

Thanks for submitting.


PLEASE HELP TO TRANSLATE GRASS MESSAGES!

----------------------------------------------

LINKS

- Localize: https://userbase.kde.org/Lokalize
- poEdit: https://poedit.net/
- *.po files for many languages: KDE translator center, https://l10n.kde.org/teams-list.php

NOTES

[1] To load existing .po files (eg from older GRASS versions or
KDE translator center, https://l10n.kde.org/teams-list.php) into
Kbabel, use
KBABEL -> SETTINGS -> CONFIGURE DIRECTORY -> PO AUXILIARY

[2] To change/add the keymap under KDE, you have to:
1. Open "(KDE) Control Center = kcontrol"
2. Go to Regional & Accessibility -> Keyboard Layout
3. Check "Enable Keyboard Layout".
4. Select Layout (e.g. Hindi) from the Additional Layouts list
5. Press "Add >>"
6. Press "Apply".

Note!: You can change between the new and the original layouts by
pressing Alt+Ctrl+k or by clicking the keyboard icon in the system
tray.

Command line alternative:
# hindi layout (Devanagari)
setxkbmap -model -layout dev -variant basic
# back to US layout:
setxkbmap -model -layout us -variant basic