DevTools:JSword/Internationalization

From CrossWire Bible Society
Jump to: navigation, search

Internationalization (i18n)

This page is a placeholder.

JSword's and BibleDesktop's mechanism for i18n uses one Java property file per Java project for strings and another for UI controls. In order to translate BibleDesktop into another language, each of these needs to be translated. These files lack comments, and they are an ASCII representation of UTF-8. For a user to translate BibleDesktop, these files have to be converted into UTF-8, modified and then converted back. Together this has resulted in BibleDesktop being translated into very few languages.

The request of translators is to:

  • co-locate the files
  • use as few files as possible
  • have the files in UTF-8
  • comment each string that needs to be translated
  • use a format and tooling familiar to translators

Chosen mechanism

GNU's GetText will be used as it satisfies the needs of translators. However, it cannot be used directly as there is no Java implementation. Thus, we'll grow our own, evolving the current mechanism of CWAction and Msg.

Some work has already been done to that end:

  1. Remove //$NON-NLS-1 markers that are throughout the code. These were used to mark what did not need to be i18n'ed. These are no longer helpful and can be eliminated.
  2. Transform the current keys in the property files to the format needed for the GetText mechanism. Currently the keys are a complex symbolic representation of the purpose of the string. These were wrapped in a symbolic constant. These will be replaced with the actual English text.
  3. In Msg create a gettext API that replaces the Msg.SYMBOLIC_NAME.toString(...) API.
  4. Migrate to using these strings with the new API rather than symbolic constants and symbolic keys to do the lookup.

Marking text for i18n

To use GNU's GetText mechanism, translatable text is marked in a simple way and comments are co-located with the string. GNU's GetText mechanism allows for programatic extraction of text needing translation and associated comments.

This section discusses how to mark up the text and comment it in the way that GNU's GetText extraction tools expects them. Later will be how to do the extraction.

Marking strings needing translation

Simply surround it with a call to gettext!

For simple strings:

String s = Msg.gettext("this should be translated");

or if it has variable parts:

String s = Msg.gettext("{0} should be translated", params);

Marking Comments

All comments that immediately precede the call to gettext will be included in the extraction. The comments follow the conventions:

  • Use the standard commenting mechanism of Java, with a space between a comment marker and text.
  • Start with TRANSLATOR:
  • Comments that are not for the translator precede and are are separated by a blank line from those that are.

Examples: One line comment form.

// TRANSLATOR: Clear English explanation of
// how this string is semantically used in the program.
// It should explain everything that the translator needs
// to know in order to translate the string.
// It can span several lines.

Multiple line comment form with a marker starting each line.

/* TRANSLATOR: Clear English explanation of
 * how this string is semantically used in the program.
 * It should explain everything that the translator needs
 * to know in order to translate the string.
 * It can span several lines.
 */

Creating a POT file

The POT file is a GNU Portable Object Template, created initially with a call to xgettext. This call will slam any prior work. So ensure that it is only called once.

See Making the PO Template File for details. As a resource, see [1].

# set some useful environment variables defining the locations
PROJ_ROOT=$PWD/bibledesktop/src/main
TR_DIR=$PROJ_ROOT/i18n
RES_DIR=$PROJ_ROOT/resources
JAVA_ROOT=$PROJ_ROOT/java
# and one for the project name
PROJ_NAME=BibleDesktop
# Ensure that the needed directories exist
[[ -f $TR_DIR  ]] || mkdir $TR_DIR
[[ -f $RES_DIR ]] || mkdir $RES_DIR
# cd to the root of the directory structure containing Java code
cd $JAVA_ROOT
# prepare the list of files
find . -type f -name "*.java" > $TR_DIR/manifest.txt

xgettext --files-from=$TR_DIR/manifest.txt \
         --output=$TR_DIR/${PROJ_NAME}.pot \
         --language=Java \
         --add-comments \
         --keyword=Msg.gettext

Note: --keyword may need more specification

Updating a POT file

Creating PO files per language

Converting POT and PO files into Java property files