Difference between revisions of "Internationalization/translation function"
(translation function suggestion) |
(Changed escape character) |
||
(12 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
+ | [[Category:Internationalization]] | ||
+ | |||
==Introduction== | ==Introduction== | ||
− | The problem for the translation is that we need a way to translate | + | The problem for the translation is that we need a way to translate three different types of string: |
* normal strings | * normal strings | ||
<code>[eiffel,N] "A normal string"</code> | <code>[eiffel,N] "A normal string"</code> | ||
* composed string | * composed string | ||
− | <code>[eiffel,N] "A string composed by "+count.out+" strings, like this or "+a_string+"%N"</code> | + | <code>[eiffel,N] "A string composed by " + count.out + " strings, like this or " + a_string + "%N"</code> |
* strings with plural form | * strings with plural form | ||
<code>[eiffel,N] | <code>[eiffel,N] | ||
− | if n=1 then | + | if n = 1 then |
Result := "a string" | Result := "a string" | ||
else | else | ||
− | + | Result := "strings" | |
end | end | ||
</code> | </code> | ||
+ | Another problem is that not all languages have the same rules for plural forms, see below and [[internationalization/plural_forms|here]] for more details. | ||
==Possible solution== | ==Possible solution== | ||
Line 22: | Line 25: | ||
<code>[eiffel,N] | <code>[eiffel,N] | ||
− | i18n (a_string : | + | i18n(a_string: STRING_GENERAL): STRING_32 |
− | --Function for the translation of normal strings | + | -- Function for the translation of normal strings |
− | i18n_pl (strings : TUPLE[ | + | i18n_pl(strings: TUPLE[STRING_GENERAL]; form: INTEGER): STRING_32 |
− | --Function for the translation of normal strings | + | -- Function for the translation of normal strings |
-- with plural form | -- with plural form | ||
− | i18n_comp (a_string : | + | i18n_comp(a_string: STRING_GENERAL; args: TUPLE): STRING_32 |
− | --Function for the translation of composit strings | + | -- Function for the translation of composit strings |
− | i18n_comp_pl (strings : TUPLE[ | + | i18n_comp_pl(strings: TUPLE[STRING_GENERAL]; args: TUPLE; form: INTEGER): STRING_32 |
− | --Function for the translation of composit | + | -- Function for the translation of composit |
-- strings with plural forms | -- strings with plural forms | ||
</code> | </code> | ||
− | With this solution, the programmer should write composit strings as (or in a similar way) he would do | + | With this solution, the programmer should write composit strings as (or in a similar way) he would do for the C ''printf'' function. The composit string above would be something like this: |
− | <code>[eiffel,N] i18n_comp("A string composed by | + | <code>[eiffel,N] i18n_comp("A string composed by $1 strings, like this or $2%N", [count, a_string]) |
</code> | </code> | ||
− | where '' | + | where ''$1'' is the place where the first string in the argument tuple (here ''count'') has to go. I've [[Talk:Internationalization/translation_function|'''choosen''']] that the items in the argument tuple are of type ANY, to insert them in the string we have to apply the functon ''out'' to all items. |
===An example=== | ===An example=== | ||
Line 55: | Line 58: | ||
[...] | [...] | ||
if n = 1 | if n = 1 | ||
− | io.put_string("Remove file "+file_name.out+"?%N") | + | io.put_string("Remove file " + file_name.out + "?%N") |
else | else | ||
− | io.put_string ("Delete following files?"+list.out+" there are " | + | io.put_string ("Delete following files?" + list.out + " there are " |
− | +list.count.out+"files%N") | + | + list.count.out + "files%N") |
end | end | ||
[...] | [...] | ||
</code> | </code> | ||
+ | |||
---- | ---- | ||
Line 71: | Line 75: | ||
[...] | [...] | ||
− | io.put_string(["Remove file | + | io.put_string(i18n_comp_pl(["Remove file $1?%N", |
− | "Delete following files? | + | "Delete following files? $2 there are $3 files%N"], |
− | [file_name, list, list_count], n) | + | [file_name, list, list_count], n)) |
[...] | [...] | ||
</code> | </code> | ||
Line 80: | Line 84: | ||
#: A comment | #: A comment | ||
− | msgid "Remove file | + | msgid "Remove file $1?%N" |
− | msgid_plural "Delete following files? | + | msgid_plural "Delete following files? $2 there are $3 files%N" |
− | msgstr[0] "Rimuovere il file | + | msgstr[0] "Rimuovere il file $1?" |
− | msgstr[1] "Cancellare i seguenti file? | + | msgstr[1] "Cancellare i seguenti file? $2 ce ne sono $3%N" |
+ | |||
+ | You might ask yourself, ''why a function for all the pluralforms''? | ||
+ | |||
+ | The number of plural forms differ between languages. This is somewhat surprising for those who only have experiences with Romanic and Germanic languages since here the number is the same (there are two). | ||
+ | But other language families have only one form or many forms. For example, | ||
+ | |||
+ | In Polish the translation of file is plik, and the plural forms are: | ||
+ | |||
+ | :2,3,4 pliki | ||
+ | :5-21 pliko'w | ||
+ | :22-24 pliki | ||
+ | :25-31 pliko'w | ||
+ | :and so on... | ||
+ | |||
+ | for more information about this topic go [http://www.gnu.org/software/gettext/manual/html_mono/gettext.html#SEC150 here] | ||
==Additional things== | ==Additional things== | ||
− | A nice thing | + | A nice thing we could do, when parsing the source code of a program to internationalize, is to recognize comments about the string. |
For example: | For example: | ||
Line 93: | Line 112: | ||
[...] | [...] | ||
− | io.put_string(["Remove file | + | io.put_string(i18n_comp_pl(["Remove file $1?%N", |
− | "Delete following files? | + | "Delete following files? $2 there are $3 files%N"], |
− | [file_name, list, list_count], | + | [file_name, list, list_count], list_count)) |
− | --A comment of the author | + | -- A comment of the author |
[...] | [...] | ||
</code> | </code> | ||
− | + | would then look like this in the PO file: | |
#. A comment of the author | #. A comment of the author | ||
#. Function name, class name, file path | #. Function name, class name, file path | ||
− | #. | + | #. $1 = file_name |
− | #. | + | #. $2 = list |
− | #. | + | #. $3 = list_count |
− | msgid "Remove file | + | msgid "Remove file $1?%N" |
− | msgid_plural "Delete following files? | + | msgid_plural "Delete following files? $2 there are $3 files%N" |
− | msgstr[0] "Rimuovere il file | + | msgstr[0] "Rimuovere il file $1?" |
− | msgstr[1] "Cancellare i seguenti file? | + | msgstr[1] "Cancellare i seguenti file? $2 ce ne sono $3%N" |
Latest revision as of 06:20, 8 June 2006
Introduction
The problem for the translation is that we need a way to translate three different types of string:
- normal strings
"A normal string"
- composed string
"A string composed by " + count.out + " strings, like this or " + a_string + "%N"
- strings with plural form
if n = 1 then Result := "a string" else Result := "strings" end
Another problem is that not all languages have the same rules for plural forms, see below and here for more details.
Possible solution
I propose a solution, with four functions (I've got little fantasy for the function names):
i18n(a_string: STRING_GENERAL): STRING_32 -- Function for the translation of normal strings i18n_pl(strings: TUPLE[STRING_GENERAL]; form: INTEGER): STRING_32 -- Function for the translation of normal strings -- with plural form i18n_comp(a_string: STRING_GENERAL; args: TUPLE): STRING_32 -- Function for the translation of composit strings i18n_comp_pl(strings: TUPLE[STRING_GENERAL]; args: TUPLE; form: INTEGER): STRING_32 -- Function for the translation of composit -- strings with plural forms
With this solution, the programmer should write composit strings as (or in a similar way) he would do for the C printf function. The composit string above would be something like this:
i18n_comp("A string composed by $1 strings, like this or $2%N", [count, a_string])
where $1 is the place where the first string in the argument tuple (here count) has to go. I've choosen that the items in the argument tuple are of type ANY, to insert them in the string we have to apply the functon out to all items.
An example
A complete example of how it could work.
Piece of code without internationalization:
[...] if n = 1 io.put_string("Remove file " + file_name.out + "?%N") else io.put_string ("Delete following files?" + list.out + " there are " + list.count.out + "files%N") end [...]
Piece of code with internationalization:
[...] io.put_string(i18n_comp_pl(["Remove file $1?%N", "Delete following files? $2 there are $3 files%N"], [file_name, list, list_count], n)) [...]
the content of the PO file would be:
#: A comment msgid "Remove file $1?%N" msgid_plural "Delete following files? $2 there are $3 files%N" msgstr[0] "Rimuovere il file $1?" msgstr[1] "Cancellare i seguenti file? $2 ce ne sono $3%N"
You might ask yourself, why a function for all the pluralforms?
The number of plural forms differ between languages. This is somewhat surprising for those who only have experiences with Romanic and Germanic languages since here the number is the same (there are two). But other language families have only one form or many forms. For example,
In Polish the translation of file is plik, and the plural forms are:
- 2,3,4 pliki
- 5-21 pliko'w
- 22-24 pliki
- 25-31 pliko'w
- and so on...
for more information about this topic go here
Additional things
A nice thing we could do, when parsing the source code of a program to internationalize, is to recognize comments about the string. For example:
[...] io.put_string(i18n_comp_pl(["Remove file $1?%N", "Delete following files? $2 there are $3 files%N"], [file_name, list, list_count], list_count)) -- A comment of the author [...]
would then look like this in the PO file:
#. A comment of the author #. Function name, class name, file path #. $1 = file_name #. $2 = list #. $3 = list_count msgid "Remove file $1?%N" msgid_plural "Delete following files? $2 there are $3 files%N" msgstr[0] "Rimuovere il file $1?" msgstr[1] "Cancellare i seguenti file? $2 ce ne sono $3%N"