Wednesday, September 23, 2015

Using gettext Library for Translations

GNU gettext is a C library which lets you add translation support to your program with fallbacks to original text if no translation is available.

Here's a list of links to how you use the different utils in the gettext package:

See http://stackoverflow.com/questions/1003360/complete-c-i18n-gettext-hello-world-example for a hello world example using gettext.

See http://www.gnu.org/software/libc/manual/html_node/Locating-gettext-catalog.html for selecting translation file in code.
See http://www.gnu.org/software/libc/manual/html_node/Translation-with-gettext.html for using gettext in code.
See http://www.gnu.org/software/gettext/manual/html_node/lib_002fgettext_002eh.html for using gettext.h instead of libintl.h to get extended capabilities such as pgettext (adds context) and support for replacing gettext commmands with no-op if gettext is not installed on system. See http://www.gnu.org/software/gettext/manual/html_node/PO-Files.html for how PO files work (text files translations).
See http://www.heiner-eichmann.de/autotools/using_gettext.html, http://www.gnu.org/software/gettext/FAQ.html, and http://www.gnu.org/savannah-checkouts/gnu/gettext/manual/html_node/xgettext-Invocation.html for some information on using xgettext to extract strings for translation into a POT file.
See http://www.gnu.org/software/gettext/manual/html_node/msginit-Invocation.html on how msginit generates language specific translation files (PO) from POT file.
See http://www.gnu.org/software/gettext/manual/html_node/msgmerge-Invocation.html on how msgmerge generates updated language specific translation files (PO) from a changed POT file.
See http://www.gnu.org/software/gettext/manual/html_node/msgfmt-Invocation.html on how msgfmt generates binary translation files (MO) from human readable translation files (PO).


See http://www.gnu.org/software/gettext/FAQ.html#integrating_noop for troubleshooting missing translations


Simple example

  1. Copy gettext.h from /usr/share/gettext/ to your component or project.
  2. Set macro ENABLE_NLS to 1
  3. Include gettext.h in your cpp file.
  4. Example code:
    ::setlocale(LC_ALL, "");
    
    // Set directory to search for translation files in (which contains
    
    // en_US.UTF-8/LC_MESSAGES/hellogt.mo)
    
    bindtextdomain("hellogt", ".");
    
    // Set name of translation file to use (hellogt.mo)
    
    textdomain( "hellogt");
    
    std::cout << gettext("hi") << std::endl;
    
    std::cout << pgettext("bob", "hello, world!") << std::endl;
    

Generate translation files

#Common
find . -name "*.cpp" > files.txt
xgettext --package-name mygt --package-version 1.2 --default-domain mygt --output mygt.pot -f files.txt

#Spanish translations
sudo locale-gen es_MX.UTF-8
msginit --no-translator --locale es_MX --output-file mygt_spanish.po --input mygt.pot
mkdir -p ./es_MX.UTF-8/LC_MESSAGES
msgfmt --check --verbose --output-file ./es_MX.UTF-8/LC_MESSAGES/mygt.mo mygt_spanish.po

#Norwegian translations
sudo locale-gen nb_NO.UTF-8
msginit --no-translator --locale nb_NO --output-file mygt_norwegian.po --input mygt.pot
mkdir -p ./nb_NO.UTF-8/LC_MESSAGES
msgfmt --check --verbose --output-file ./nb_NO.UTF-8/LC_MESSAGES/mygt.mo mygt_norwegian.po

Update translation files

Add changes in code to language specific translation file:
xgettext --package-name mytgt --package-version 1.2 --default-domain mygt --output mygt.pot -f files.txt
msgmerge mygt_norwegian.po_old mygt.pot --output-file=mygt_norwegian.po_new
use msgfmt to generate new mygt.mo file from mygt_norwegian.po_new.

2 comments:

  1. To better translate your gettext files, I suggest trying an online localization management tool that will make things easier. https://poeditor.com/ is such a service with many features included (API, translation memory, GitHub and Bitbucket integration, WordPress plugin) and a user-friendly interface that will improve and automate your workflow.

    ReplyDelete
    Replies
    1. Nice, I've ever only done it manually.
      Tried some online editor, but can't remember what they were called (Transifex?) and also the program Poedit (https://poedit.net/) works really well for the translation part.

      Also check out https://github.com/wichert/po-xls (or my own fork with some tweaks https://github.com/asmund1/po-xls) to convert from po files to xls for translators who are uncomfortable with Poedit or online tools. :)

      Delete