Internationalizing Messages in Linux Programs

An introduction to the GNU gettext system for producing multilingual programs.
Maintaining the Message File

If the source code changes, the corresponding .po file should be updated without losing any previous translation. Unfortunately, simply calling xgettext again does not work because it overwrites the old .po file. In this case, the program tupdate comes in handy. It merges two .po files, keeping translations already made, as long as the new strings match with the old. Its syntax is simple:

tupdate new.po old.po > latest.po

New strings will obviously still be empty in latest.po, but already translated ones will be there without the need for reprocessing.

Exceptions

Listing 3

It is not always possible to use the gettext function “straight”. Let's look at the source code excerpt in Listing 3 as an example. Two goals must be reached during the internationalization of this code. First, each translatable string must appear in the .po file. Second, before printing each string at runtime, we must pass it through gettext.

The string "You have %d %s" poses a problem. We cannot simply transform each string declared in item_names in a gettext call, because arrays must be initialized with constant values.

Listing 4

One solution is shown in Listing 4. gettext_noop is a marker used to make the string recognizable by xgettext (that is why it is looked for by default). The translation occurs at run time with the normal gettext call.

Message File Format

The .po files have a very simple text structure and can be modified with any text editor. Among others, Emacs can be put in a special po mode when dealing with them.

Each message file consists of a sequence of records. Each record has this structure:

(blank lines)
#  optional human comments
#. optional automatic comments
#: optional source code reference
msgid original-string
msgstr translated-string

Comments introduced by the translator should have a whitespace immediately following the # character. Automatic comments are produced by xgettext and tupdate to enhance the file's readability and to allow the translator to quickly browse the source code and find the line where a string is used. This is sometimes necessary to produce a correct translation.

Strings are formatted just like C. For example, it is legal to write:

msgid ""
"Hello     "
"world!\n"
msgstr ""
"Ciao      "
"mondo!\n"

As you can see, strings may span across lines and the backslash is used to introduce special characters such as tabs and newlines.

Other Message Catalog Systems

No POSIX standard for message catalogs exists—the committee could not agree on anything.

GNU gettext is not the only message catalog system that can be used by an internationalized program. Another library, based on the catgets function call, also exists. The catgets interface is supported by the X/Open consortium, while the gettext interface was first used by Sun.

The main disadvantage of catgets is that a unique identifier must be chosen for each message and passed to catgets each time. This makes it quite difficult to manage a large set of messages, where entries are inserted and deleted on a regular basis. However, GNU gettext can use catgets as an underlying interface on systems that support it.

Linux supports both gettext and catgets interfaces. My personal opinion is the gettext system is much easier to use for both programmers and translators.

All listings referred to in this article are available by anonymous download in the file ftp.linuxjournal.com/pub/lj/listings/issue59/3023.tgz

Pancrazio de Mauro (pdemauro@datanord.it) is a technical writer and a Linux consultant. He spends most of his time advocating Linux and trying to convince his friends to call him Ezio which, of course, sounds as bad as Pancrazio in English.

______________________

White Paper
Linux Management with Red Hat Satellite: Measuring Business Impact and ROI

Linux has become a key foundation for supporting today's rapidly growing IT environments. Linux is being used to deploy business applications and databases, trading on its reputation as a low-cost operating environment. For many IT organizations, Linux is a mainstay for deploying Web servers and has evolved from handling basic file, print, and utility workloads to running mission-critical applications and databases, physically, virtually, and in the cloud. As Linux grows in importance in terms of value to the business, managing Linux environments to high standards of service quality — availability, security, and performance — becomes an essential requirement for business success.

Learn More

Sponsored by Red Hat

White Paper
Private PaaS for the Agile Enterprise

If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.

Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.

Learn More

Sponsored by ActiveState