Let's have an example:
Suppose we have a simple program written for English audiences that shows the number of monitors connected to the computer.
- Code: Select all
if Screen.MonitorCount = 1 then
TheLabel.Caption := 'You have one monitor'
else
TheLabel.Caption := Format('You have %d monitors', [Screen.MonitorCount]);
We are going to change this piece of code, so that it can be localized for any arbitrary culture.
We drop a TLocalizer and a TTranslator component on the form and change the code as follow:
- Code: Select all
if Screen.MonitorCount = 1 then
TheText := Translator.GetText('You have one monitor')
else
TheText := Translator.GetText('You have {0:N0} monitors');
TheLabel.Caption := Localizer.FormatCS(TheText, [Screen.MonitorCount]);
This code looks fine but follows the English language rule for plurals. Depends on the language, plural form of a noun may have one or many forms. In addition to the number of plural forms, the way how plural forms are built differs in each language.
Hopefully, the i18n package knows the number of plural forms for many languages and also knows how to select the right form. We just need to know the rule for the default language of our program (in our case, English).
- Code: Select all
TheText := Translator.GetNText(['You have one monitor', 'You have {0:N0} monitors'], Screen.MonitorCount);
TheLabel.Caption := Localizer.FormatCS(TheText, [Screen.MonitorCount]);
As you can see, instead of
GetText, we used
GetNText method of the Translator object. This method expects an array of strings as the first parameter. The number of strings in this array are identical to the number of plural forms of the programs' default language. The second parameter of this method is the number of items (in our case, monitors) that determines which string should be selected.
Because
GetNText uses a custom expression (known as plural forms expression) to select a plural form from the array, there is no constant rule that we can use to find out the arrangement of plural forms in the array. By convention, usually the string at zero index refers to singular form and the rest are plural form variants.
But in fact we need to know which number will select a string in a specific index. For this purpose knowing a bit about the plural forms expression is necessary.
This plural forms expression is a C-like expression, which means:
- arithmetic, bit-wise, comparison and ternary operators of C are functional
- a comparison expression evaluates to either 0 (false) or 1 (true)
- zero evaluates to false and any non-zero value evaluates to true
You can consider the plural forms expression as an inline function with one parameter named
n. The parameter
n is the number of items in subject. we should
use this value in our expression to evaluate the index of plural forms in the array of strings.
For example, in English language, we use singular form if and only if the quantity is one, otherwise we use plural form (including zero quantity). We decided to put singular form at zero index and plural form at one index. Based on this information, our plural form expression for English language can be:
- Code: Select all
(n == 1) ? 0 : 1
We can also take advantage of C-like expression and write a bit more optimized expression:
- Code: Select all
n != 1
Both of the above expressions evaluate to zero when
n is one and in other cases evaluate to one.
For a language like Persian that has no plural form for nouns, the plural form expression can be as simple as literal 0. But for some languages it would be more complex. As an example, here is the plural form expression for Arabic expression with six plural form variations:
- Code: Select all
n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 ? 4 : 5
In the i18n editor, the plural forms of a text appear on a tabset. The number of tabs is identical to the number of plural forms that the target language has. Besides that, the caption of each tab indicates the expected result of plural forms expression for selecting that item.
You can see or modify the plural forms rule of a language by selecting
Translation => Edit Plural Rule... from the menu of the i18n editor.