GNU gettext for Delphi, C++ Builder and Kylix 1.2 beta
<<< Previous | Action | Next >>>

# Plural forms

The `ngettext()` function is a very powerful function for handling plural forms. In order to understand this function, you should first understand the `gettext()` function in the Section called function gettext(msg:widestring):widestring; in the appendix called API reference>.

A well known problem is to specify the number of files in a list of filenames. With this function, it can be done like this:

    LabelCount.Caption:=format(ngettext('%s file','%s files',filelist.Count),[filelist.Count]);

If no translations are available, the `ngettext()` function will return '%s file' if filelist.Count=1, and it will return '%s files' otherwise. The `format()` function will then put the actual number of files in place of the %s, and the result will be something like '0 files', '1 file', '2 files', '3 files' etc.

If you would want to translate this to french, the entry in the po file should look like this:

    msgid "%s file"
    msgid_plural "%s files"
    msgstr[0] "%s fichier"
    msgstr[1] "%s fichiers"

The idea with ngettext is, that it doesn't just translate "%s file" to "%s fichier", but it takes into account, that the french use numbers differently. The English say "0 files", but the french use singular to describe the value zero: "0 fichier". So in the above example, the french version would be: '0 fichier', '1 fichier', '2 fichiers', '3 fichiers'...

Some languages are even more complicated. In Polish, there are three plural forms, and the translation would look like this:

    msgid "%s file"
    msgid_plural "%s files"
    msgstr[0] "%s plik"
    msgstr[1] "%s pliki"
    msgstr[2] "%s plików"

When counting files, it will become: '0 plików', '1 plik', '2 pliki', '3 pliki', '4 pliki', '5 plików'. Confused? Don't be. Just use `ngettext()` wherever your text depends on a number, and the translator will provide the correct translations.

| Not all tools handle msgid_plural well
| Please note, that not all tools handle msgid_plural well. This includes poEdit and KBabel. If a po file contains msgid_plural translations, you should use a text editor to edit it/translate. A good text editor for po files is UniRed.

| How does it work?
| The ngettext and dngettext functions use gettext(singular+#0+plural) to get a #0-separated list of plural forms.

Because some tools don't handle msgid_plural forms well, you should put all plural forms translations into a separate po file. You can do this using `dngettext()`, which is equivalent to `ngettext()` except that it takes a text domain name as first parameter:

    LabelCount.Caption:=format(dngettext('plurals','%s file','%s files',filelist.Count),[filelist.Count]);

In this case, the source code string extraction will put the translation into a file named `plurals.po`, and the `dngettext()` function will retrieve the translations from `plurals.mo`. You can then ask the translator to use notepad to translate the `plurals.po` file. Notepad is not always very handy, but it's surely compatible with the msgid_plural notation.

<<< Previous | Home | Next >>>
Solving ambiguities | Up | Database applications