<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://dev.eiffel.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Etienner</id>
		<title>EiffelStudio: an EiffelSoftware project - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="https://dev.eiffel.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Etienner"/>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/Special:Contributions/Etienner"/>
		<updated>2026-04-03T20:10:55Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.24.1</generator>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/User_guide&amp;diff=5229</id>
		<title>Internationalization/User guide</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/User_guide&amp;diff=5229"/>
				<updated>2006-10-14T06:33:04Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: /* Usage */  small correction&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
The [[i18n]] library is intended to enable localisation of Eiffel programs.&lt;br /&gt;
&lt;br /&gt;
''localisation'' is the process of adapting a piece of software to a specific place - the ''locale'', often expressed as a combination of language and country codes.&lt;br /&gt;
&lt;br /&gt;
This normally means not only displaying strings in the appropriate language, but also adapting number formatting, date and time formatting etc. to use local conventions.&lt;br /&gt;
The i18n library provides formatting facilities for numbers, currency values and dates, and the ability to identify and load translated strings at run-time.&lt;br /&gt;
&lt;br /&gt;
==Interface==&lt;br /&gt;
&lt;br /&gt;
The library provides most of it's services through one class: LOCALE. This presents all formatting and translation facilities for a given locale.&lt;br /&gt;
LOCALE objects can't be created directly: one must go though the LOCALE_MANAGER class. A LOCALE_MANAGER finds out what information for which locales is available, and offers a list to chose from. It will then load the information for the chosen locale into a LOCALE object and give it to you. With this LOCALE object you can do the really interesting things, like formatting dates and translating strings.&lt;br /&gt;
&lt;br /&gt;
===Choosing a locale===&lt;br /&gt;
&lt;br /&gt;
First you must have a LOCALE_MANAGER. For details on creating them, please see the '''Datasources''' section.&lt;br /&gt;
If you just want to use whatever locale is the default on the user's machine, as in most cases, then it's easy to get a LOCALE object: just call get_system_locale.&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
my_locale := locale_mananger.get_system_locale&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want a specific locale, it's going to be a bit more complicated.&lt;br /&gt;
A LOCALE_MANAGER knows what locales are available and exactly what information is available for a specific locale.&lt;br /&gt;
You can get a list of all locales that are available to some degree by calling the available_locales feature.&lt;br /&gt;
A locale is identified by a LOCALE_ID object, and normally this has two components: language code and country code.&lt;br /&gt;
For example, the US english locale has language code &amp;quot;en&amp;quot; and country code &amp;quot;US&amp;quot;. &lt;br /&gt;
If you've found a locale id  that you like in the list returned by available_locales, you can check exactly what is vailable for it by using &lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
has_translations (a_locale_id: I18N_LOCALE_ID): BOOLEAN&lt;br /&gt;
has_formatting_info (a_locale_id: I18N_LOCALE_ID): BOOLEAN&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can then retrieve the corresponding LOCALE object by calling get_locale.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Using your locale===&lt;br /&gt;
&lt;br /&gt;
Now you've got a LOCALE. After the initial burst of euphoria has faded away, what can you do with it?&lt;br /&gt;
&lt;br /&gt;
====String translation====&lt;br /&gt;
=====Interface=====&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
translate (original: STRING_GENERAL): STRING_32&lt;br /&gt;
translate_plural (original_singular, original_plural: STRING_GENERAL; plural_form : INTEGER): STRING_32&lt;br /&gt;
format_string (original: STRING_GENERAL; token_values: TUPLE[STRING_GENERAL]): STRING_32&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
=====Usage=====&lt;br /&gt;
In naïvely written software, you can often spot things like&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
io.put_string(&amp;quot;My hovercraft is full of eels&amp;quot;)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
We'll use this example to illustrate the use of the string translation features of the i18n library.&lt;br /&gt;
&lt;br /&gt;
If, as above, there is just one constant string to translate, the solution is very easy: simply use the translate function.&lt;br /&gt;
The resulting code would look like this&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
io.put_string(my_locale.translate(&amp;quot;My hovercraft is full of eels&amp;quot;))&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
If the translate function can't find a translation for this string it will simply return the original string - better then nothing!&lt;br /&gt;
&lt;br /&gt;
But life is, of course, not always that simple. What if we have to deal with plurals? The &amp;quot;traditional&amp;quot; way of doing this is something like:&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
n := get_number_of_hovercraft&lt;br /&gt;
if n = 1 then&lt;br /&gt;
	io.put_string(&amp;quot;My hovercraft is full of eels&amp;quot;)&lt;br /&gt;
else&lt;br /&gt;
	io.put_string(&amp;quot;My hovercraft are full of eels&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is not so easy to translate as the above. Why can't we just translate both strings? &lt;br /&gt;
&lt;br /&gt;
Depending on the language, there may be up to 4 different types of plural forms, used in strange and exotic ways. Clearly, it is important to know exactly _how_ many hovercraft there are so that we can choose the right plural form. This can be done by the translate_plural function, which we can use in this way:&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,n]&lt;br /&gt;
n := get_number_of_hovercraft&lt;br /&gt;
io.put_string(my_locale.translate_plural(&amp;quot;My hovercraft is full of eels&amp;quot;,&amp;quot;My hovercraft are full of eels&amp;quot;,n))&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This function will choose and return a translation in the correct plural form. If it can't find one, it will behave like translate and return either the original singular string or the original plural string, following English grammatical rules.&lt;br /&gt;
&lt;br /&gt;
Often even the above is not enough. What if you want to tell the world exactly how many hovercraft you have? You might write something like this:&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
n := get_number_of_hovercraft&lt;br /&gt;
if n = 1 then&lt;br /&gt;
	io.put_string(&amp;quot;My hovercraft is full of eels&amp;quot;)&lt;br /&gt;
else&lt;br /&gt;
	io.put_string(&amp;quot;My &amp;quot;+n.out+&amp;quot; hovercraft are full of eels&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
How can translate_plural handle this? It needs some reinforcements: the solution is to also use ''string templates''.&lt;br /&gt;
This means that we can embed codes like &amp;quot;$1&amp;quot; in a string and replace them in the translation by the actual values.&lt;br /&gt;
Let's see how this works:&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,n]&lt;br /&gt;
n := get_number_of_hovercraft&lt;br /&gt;
plural_string := my_locale.translate_plural(&amp;quot;My hovercraft is full of eels&amp;quot;,&amp;quot;My $1 hovercraft are full of eels&amp;quot;,n)&lt;br /&gt;
io.put_string(my_locale.format_string(plural_string, [n]))&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
To replace the ''escape codes'', such as $1, $2, we use the function format_string. This replaces all the escape codes it finds by the values in a tuple that you give to it a an argument.&lt;br /&gt;
&lt;br /&gt;
====Formatting====&lt;br /&gt;
=====Interface=====&lt;br /&gt;
TODO!&lt;br /&gt;
=====Usage=====&lt;br /&gt;
TODO!&lt;br /&gt;
&lt;br /&gt;
==String extraction==&lt;br /&gt;
&lt;br /&gt;
Somebody has to translate all these strings. Mostly, this isn't a programmer, so somehow you have to be able to give this translator a list of strings that you want translated. &lt;br /&gt;
&lt;br /&gt;
We can extract these strings from your application fairly easily by simply looking at the arguments for each call to translate or translate_plural. By clicking on a handy button in EiffelStudio, these strings will be extracted and placed in a [http://www.gnu.org/software/gettext/manual/html_node/gettext_9.html#SEC9 .po file].&lt;br /&gt;
&lt;br /&gt;
TODO: add more details about clicky thing.&lt;br /&gt;
&lt;br /&gt;
A .po file is a reasonably widespread format for storing strings to be translated. There are several tools to aid translation of these files, such as [http://www.poedit.org/ poEdit] for Windows and [http://kbabel.kde.org/ KBabel] or [http://gtranslator.sourceforge.net/ gtranslator] for KDE and Gnome. &lt;br /&gt;
There are also many tools to convert .po files to other formats, such as the xml [http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=xliff xliff format]. &lt;br /&gt;
&lt;br /&gt;
==Datasources==&lt;br /&gt;
&lt;br /&gt;
The library has to load the translated strings from somewhere - sadly we can't do on the fly translation but if you can, please tell us!&lt;br /&gt;
Instead we load the strings from a datasource. This is appropriately generic: it could be anything, from a database to a system that queries a server via RPC or SOAP, but currently we only have one implementation: files. And in fact, we only support one type of file: the .mo file format. &lt;br /&gt;
The library can't guess the type of datasource you want to use, so you have to tell it when you create a LOCALE_MANAGER.&lt;br /&gt;
This is done via an ''uri''. Currently all uris are interpreted as directories where string catalog files may be found, and any .mo files in this directory will be used by the i18n library. This means that creating a LOCALE_MANAGER looks somewhat like this:&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
create my_locale_mananger.make(&amp;quot;/path/to/my/files&amp;quot;)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mo files===&lt;br /&gt;
&lt;br /&gt;
The mo file format is defined by the GNU [http://www.gnu.org/software/gettext/ gettext] library, a widely-used C library that allows localisation of text strings. We support UTF-8 encoded mo files.&lt;br /&gt;
&lt;br /&gt;
How do you get these .mo files? Once your translator has finished translating a .po file, you can convert it into a .mo file by using the ''msgfmt'' tool, which is obtainable as part of the gettext package under unix and distributed with poEdit under Windows.&lt;br /&gt;
The resulting mo file should be named with the locale identifier of the locale it is intended for (zh_CN.mo or de_CH.mo, for example) and placed in the appropriate directory - this is to say, the one that you give to LOCALE_MANAGER as an uri.&lt;br /&gt;
&lt;br /&gt;
The .mo file should then be seen and used by the i18n library.&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Main_Page&amp;diff=4593</id>
		<title>Talk:Main Page</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Main_Page&amp;diff=4593"/>
				<updated>2006-09-17T16:40:43Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: remove vandalism...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Main_Page&amp;diff=4579</id>
		<title>Talk:Main Page</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Main_Page&amp;diff=4579"/>
				<updated>2006-09-15T11:38:11Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: remove vandalism...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=User_talk:Manus&amp;diff=4547</id>
		<title>User talk:Manus</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=User_talk:Manus&amp;diff=4547"/>
				<updated>2006-09-12T22:18:33Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: /* Vandalism */ again&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Vandalism==&lt;br /&gt;
&lt;br /&gt;
Hi Manus, I wanted to inform you that there are two users that did some vandalism:&lt;br /&gt;
* [[User:Ceas]] did [http://eiffelsoftware.origo.ethz.ch/index.php?title=Main_Page&amp;amp;diff=next&amp;amp;oldid=4215 this]&lt;br /&gt;
* [[User:Moralest]] did [http://eiffelsoftware.origo.ethz.ch/index.php?title=Main_Page&amp;amp;diff=4442&amp;amp;oldid=4401 this]&lt;br /&gt;
* [[B.Gates]] did [http://eiffelsoftware.ethz.ch/index.php?title=Main_Page&amp;amp;diff=4545&amp;amp;oldid=4529 this]&lt;br /&gt;
I propose to block their username... I've already removed the changes. [[User:Etienner|&amp;lt;font color=&amp;quot;Yellow&amp;quot;&amp;gt;'''E'''&amp;lt;/font&amp;gt;&amp;lt;font color=&amp;quot;Black&amp;quot;&amp;gt;'''T'''&amp;lt;/font&amp;gt;&amp;lt;font color=&amp;quot;Yellow&amp;quot;&amp;gt;'''N'''&amp;lt;/font&amp;gt;]] &amp;lt;sup&amp;gt;[[User talk:Etienner|'''&amp;lt;font color=&amp;quot;Yellow&amp;quot;&amp;gt;talk&amp;lt;/font&amp;gt;''']]&amp;lt;/sup&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Not worth it; those are certainlyjust bots, probably run from some zombie. [[User:Leo|Leo]] 10:13, 4 September 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
: Or they were users with weak passwords, if that is possible (I currently do not know what our password policy is) [[User:Schoelle|Bernd]]&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Main_Page&amp;diff=4546</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Main_Page&amp;diff=4546"/>
				<updated>2006-09-12T22:16:43Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: revert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Welcome to [http://www.eiffel.com/ Eiffel Software]'s Wiki, the home page for Eiffel Software's Open Source initiative in collaboration with the [http://se.inf.ethz.ch/ Chair of Software Engineering] at [http://www.ethz.ch ETH Zurich].&lt;br /&gt;
&lt;br /&gt;
{{block|'''Project ideas'''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you'd like to contribute to the progress of Eiffel technology but don't know where to start, be sure to&lt;br /&gt;
take a look at the [[:Category:Projects| project suggestion pages]]. They contain lots of great ideas for projects large and small!}}&lt;br /&gt;
&lt;br /&gt;
To download or look at the source code of EiffelStudio, please go to the [[Repository| SVN repository]] page.&lt;br /&gt;
&lt;br /&gt;
To compile the source code, you will need a snapshot of the current development release of EiffelStudio. To get it go to the [[Downloads| Downloads]] page.&lt;br /&gt;
&lt;br /&gt;
=== Wiki Contents ===&lt;br /&gt;
&lt;br /&gt;
* [[:Category:EiffelStudio|EiffelStudio]]&lt;br /&gt;
* [[:Category:EiffelBuild|EiffelBuild]]&lt;br /&gt;
* [[:Category:Compiler| Eiffel Compiler]]&lt;br /&gt;
* [[:Category:Runtime| Eiffel Runtime]]&lt;br /&gt;
* [[:Category:Library| Eiffel Libraries]]:&lt;br /&gt;
** [[:Category:EiffelBase| EiffelBase]]&lt;br /&gt;
** [[:Category:EiffelVision2| EiffelVision2]]&lt;br /&gt;
** [[:Category:WEL| WEL]]&lt;br /&gt;
* [[:Category:Eiffel for .NET| Eiffel for .NET]]&lt;br /&gt;
* [[:Category:Documentation| Documentation]]&lt;br /&gt;
* [[Roadmap|EiffelStudio Roadmap]]&lt;br /&gt;
* [[Repository| SVN repository]] &lt;br /&gt;
* [[Contributing| How To Contribute?]]&lt;br /&gt;
* [[:Category:Projects| Projects and project suggestions]]&lt;br /&gt;
* [[URLs| Useful URLs]]&lt;br /&gt;
* [[TODOs| Project TODOs]]&lt;br /&gt;
* [[Tools| Tools]]&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/dotnet_locale&amp;diff=4496</id>
		<title>Internationalization/dotnet locale</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/dotnet_locale&amp;diff=4496"/>
				<updated>2006-09-07T11:34:51Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: /* Retrieving locale information */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Internationalization]]&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
There is a class named CULTURE_INFO in &amp;quot;mscorlib&amp;quot; in EiffelStudio, which provides information about a specific culture such as:&lt;br /&gt;
* associated language&lt;br /&gt;
* sublanguage&lt;br /&gt;
* country/region&lt;br /&gt;
* calendar&lt;br /&gt;
* cultural conventions&lt;br /&gt;
&lt;br /&gt;
== Listing available locales ==&lt;br /&gt;
&lt;br /&gt;
I didn't find a function that returns all the available locale informations, I think because under .NET, they are all avaiable.&lt;br /&gt;
&lt;br /&gt;
== Checking for default locale ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
a_culture_info : CULTURE_INFO&lt;br /&gt;
a_culture_info.current_culture.name : SYSTEM_STRING&lt;br /&gt;
    -- returns the name of the current culture info, (in the format described below).&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Retrieving locale information ==&lt;br /&gt;
To obtain informations on a specific locale, it suffices to create an instance of CULTURE_INFO. There are basically two ways to do this:&lt;br /&gt;
&lt;br /&gt;
# Create it with the culture identifier. This identifier maps every culture/language to an integer. It is not very usefull, because I did not find a logic behind the mapping function... You can find a table on [http://msdn2.microsoft.com/en-us/library/ms172470.aspx here]&lt;br /&gt;
# Create it with the name (STRING) of the culture. The culture names follow the RFC 1766 standard in the format &amp;quot;&amp;lt;languagecode2&amp;gt;-&amp;lt;country/regioncode2&amp;gt;&amp;quot;, where &amp;lt;languagecode2&amp;gt; is a lowercase two-letter code derived from ISO 639-1 and &amp;lt;country/regioncode2&amp;gt; is an uppercase two-letter code derived from ISO 3166.&lt;br /&gt;
&lt;br /&gt;
You can find a detailed description of RFC 1766&lt;br /&gt;
&lt;br /&gt;
The CULTURE_INFO Class has some attibutes useful for the retrieving of the informations about Date, Time and Number formatting, they are:&lt;br /&gt;
&lt;br /&gt;
* date_time_format: DATE_TIME_FORMAT_INFO ([http://msdn2.microsoft.com/en-us/library/system.globalization.datetimeformatinfo.aspx see here])&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Some information that is available in DATE_TIME_FORMAT_INFO&lt;br /&gt;
! Information !! Result for locale &amp;quot;it-CH&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| full_date_time_pattern || dddd, d. MMMM yyyy HH:mm:ss&lt;br /&gt;
|-&lt;br /&gt;
| long_date_pattern || dddd, d. MMMM yyyydddd &lt;br /&gt;
|-&lt;br /&gt;
| long_time_pattern || HH:mm:ss&lt;br /&gt;
|-&lt;br /&gt;
| month_day_pattern || d. MMMM&lt;br /&gt;
|-&lt;br /&gt;
| rfc1123_pattern || ddd, dd MMM yyyy HH':'mm':'ss 'GMT'&lt;br /&gt;
|-&lt;br /&gt;
| pm_designator ||&lt;br /&gt;
|-&lt;br /&gt;
| short_date_pattern || dd.MM.yyyy&lt;br /&gt;
|-&lt;br /&gt;
| short_time_pattern || HH:mm&lt;br /&gt;
|-&lt;br /&gt;
| sortable_date_time_pattern || yyyy'-'MM'-'dd'T'HH':'mm':'ss&lt;br /&gt;
|-&lt;br /&gt;
| time_separator ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
where:&lt;br /&gt;
:*d, %d: The day of the month. Single-digit days will not have a leading zero. Specify &amp;quot;%d&amp;quot; if the format pattern is not combined with other format patterns.&lt;br /&gt;
:*dd: The day of the month. Single-digit days will have a leading zero. &lt;br /&gt;
:*ddd: The abbreviated name of the day of the week, as defined in AbbreviatedDayNames. &lt;br /&gt;
:*dddd: The full name of the day of the week, as defined in DayNames.&lt;br /&gt;
:*HH: The hour in a 24-hour clock. Single-digit hours will have a leading zero. &lt;br /&gt;
:*mm: The minute. Single-digit minutes will have a leading zero.&lt;br /&gt;
:*ss: the second. Single-digit seconds will have a leading zero.&lt;br /&gt;
:*yyyy: The year in four or five digits (depending on the calendar used), including the century. Will pad with leading zeroes to get four digits. Thai Buddhist and Korean calendars both have five digit years; users selecting the &amp;quot;yyyy&amp;quot; pattern will see all five digits without leading zeros for calendars that have five digits. Exception: the Japanese and Taiwan calendars always behave as if &amp;quot;yy&amp;quot; was selected.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--HERE A LIST OF OTHER &amp;quot;Format specifier&amp;quot;&lt;br /&gt;
**f, %f: The fraction of a second in single-digit precision. The remaining digits are truncated. Specify &amp;quot;%f&amp;quot; if the format pattern is not combined with other format patterns.&lt;br /&gt;
**ff: The fraction of a second in double-digit precision. The remaining digits are truncated. &lt;br /&gt;
**fff: The fraction of a second in three-digit precision. The remaining digits are truncated. &lt;br /&gt;
**ffff: The fraction of a second in four-digit precision. The remaining digits are truncated. &lt;br /&gt;
**fffff: The fraction of a second in five-digit precision. The remaining digits are truncated. &lt;br /&gt;
**ffffff: The fraction of a second in six-digit precision. The remaining digits are truncated. &lt;br /&gt;
**fffffff: The fraction of a second in seven-digit precision. The remaining digits are truncated. &lt;br /&gt;
**F, %F: Displays the most significant digit of the seconds fraction. Nothing is displayed if the digit is zero. Specify &amp;quot;%F&amp;quot; if the format pattern is not combined with other format patterns.&lt;br /&gt;
**FF: Displays the two most significant digits of the seconds fraction. However, trailing zeros, or two zero digits, are not displayed.&lt;br /&gt;
**FFF: Displays the three most significant digits of the seconds fraction. However, trailing zeros, or three zero digits, are not displayed.&lt;br /&gt;
**FFFF: Displays the four most significant digits of the seconds fraction. However, trailing zeros, or four zero digits, are not displayed.&lt;br /&gt;
**FFFFF: Displays the five most significant digits of the seconds fraction. However, trailing zeros, or five zero digits, are not displayed.&lt;br /&gt;
**FFFFFF: Displays the six most significant digits of the seconds fraction. However, trailing zeros, or six zero digits, are not displayed.&lt;br /&gt;
**FFFFFFF: Displays the seven most significant digits of the seconds fraction. However, trailing zeros, or seven zero digits, are not displayed.&lt;br /&gt;
**gg: The period or era. This pattern is ignored if the date to be formatted does not have an associated period or era string. &lt;br /&gt;
**h, %h: The hour in a 12-hour clock. Single-digit hours will not have a leading zero. Specify &amp;quot;%h&amp;quot; if the format pattern is not combined with other format patterns.&lt;br /&gt;
*hh: The hour in a 12-hour clock. Single-digit hours will have a leading zero. &lt;br /&gt;
*H, %H: The hour in a 24-hour clock. Single-digit hours will not have a leading zero. Specify &amp;quot;%H&amp;quot; if the format pattern is not combined with other format patterns.&lt;br /&gt;
*K: Different values of the DateTime.Kind property, that is, Local, Utc, or Unspecified.&lt;br /&gt;
*m, %m: The minute. Single-digit minutes will not have a leading zero. Specify &amp;quot;%m&amp;quot; if the format pattern is not combined with other format patterns.&lt;br /&gt;
*M, %M: The numeric month. Single-digit months will not have a leading zero. Specify &amp;quot;%M&amp;quot; if the format pattern is not combined with other format patterns.&lt;br /&gt;
*MM: The numeric month. Single-digit months will have a leading zero. &lt;br /&gt;
*MMM: The abbreviated name of the month, as defined in AbbreviatedMonthNames. &lt;br /&gt;
*MMMM: The full name of the month, as defined in MonthNames. &lt;br /&gt;
*s, %s: The second. Single-digit seconds will not have a leading zero. Specify &amp;quot;%s&amp;quot; if the format pattern is not combined with other format patterns.&lt;br /&gt;
*ss: the second. Single-digit seconds will have a leading zero.&lt;br /&gt;
*, %t: The first character in the AM/PM designator defined in AMDesignator or PMDesignator, if any. Specify &amp;quot;%t&amp;quot; if the format pattern is not combined with other format patterns.&lt;br /&gt;
*t:The AM/PM designator defined in AMDesignator or PMDesignator, if any. &lt;br /&gt;
*y, %y: The year without the century. If the year without the century is less than 10, the year is displayed with no leading zero. Specify &amp;quot;%y&amp;quot; if the format pattern is not combined with other format patterns.&lt;br /&gt;
*yy: The year without the century. If the year without the century is less than 10, the year is displayed with a leading zero. &lt;br /&gt;
*yyy: The year in three digits. If the year is less than 100, the year is displayed with a leading zero.&lt;br /&gt;
*yyyyy: The year in five digits. Will pad with leading zeroes to get five digits. Exception: the Japanese and Taiwan calendars always behave as if &amp;quot;yy&amp;quot; was selected.&lt;br /&gt;
*yyyyyy: The year in six digits. Will pad with leading zeroes to get six digits. Exception: the Japanese and Taiwan calendars always behave as if &amp;quot;yy&amp;quot; was selected. The pattern can be continued with a longer string of &amp;quot;y&amp;quot;s padding with more leading zeroes.&lt;br /&gt;
*z, %z: The time zone offset (&amp;quot;+&amp;quot; or &amp;quot;-&amp;quot; followed by the hour only). Single-digit hours will not have a leading zero. For example, Pacific Standard Time is &amp;quot;-8&amp;quot;. Specify &amp;quot;%z&amp;quot; if the format pattern is not combined with other format patterns.&lt;br /&gt;
*zz: The time zone offset (&amp;quot;+&amp;quot; or &amp;quot;-&amp;quot; followed by the hour only). Single-digit hours will have a leading zero. For example, Pacific Standard Time is &amp;quot;-08&amp;quot;. &lt;br /&gt;
*zzz: The full time zone offset (&amp;quot;+&amp;quot; or &amp;quot;-&amp;quot; followed by the hour and minutes). Single-digit hours and minutes will have leading zeros. For example, Pacific Standard Time is &amp;quot;-08:00&amp;quot;. &lt;br /&gt;
*% c: Where c is a format pattern if used alone. That is, to use format pattern &amp;quot;d&amp;quot;, &amp;quot;f&amp;quot;, &amp;quot;F&amp;quot;, &amp;quot;h&amp;quot;, &amp;quot;m&amp;quot;, &amp;quot;s&amp;quot;, &amp;quot;t&amp;quot;, &amp;quot;y&amp;quot;, &amp;quot;z&amp;quot;, &amp;quot;H&amp;quot;, or &amp;quot;M&amp;quot; by itself, specify &amp;quot;%d&amp;quot;, &amp;quot;%f&amp;quot;, &amp;quot;%F&amp;quot;, &amp;quot;%h&amp;quot;, &amp;quot;%m&amp;quot;, &amp;quot;%s&amp;quot;, &amp;quot;%t&amp;quot;, &amp;quot;%y&amp;quot;, &amp;quot;%z&amp;quot;, &amp;quot;%H&amp;quot;, or &amp;quot;%M&amp;quot;. The &amp;quot;%&amp;quot; character can be omitted if the format pattern is combined with literal characters or other format patterns. &lt;br /&gt;
*\ c Where c is any character. Displays the character literally. To display the backslash character, use &amp;quot;\\&amp;quot;.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* there are also functions that return abbreviations of names of months and day:&lt;br /&gt;
** get_abbreviated_day_name (dayofweek: DAY_OF_WEEK) : SYSTEM_STRING&lt;br /&gt;
** get_abbreviated_month_name (month: INTEGER) : SYSTEM_STRING&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* number_format: NUMBER_FORMAT_INFO ([http://msdn2.microsoft.com/en-us/library/system.globalization.numberformatinfo.aspx see here])&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Some information that is available in NUMBER_FORMAT_INFO&lt;br /&gt;
! Information !! Result for locale &amp;quot;it-CH&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| currency_group_separator || '&lt;br /&gt;
|-&lt;br /&gt;
| currency_symbol || SFr.&lt;br /&gt;
|-&lt;br /&gt;
| currency_decimal_digits || 2&lt;br /&gt;
|-&lt;br /&gt;
| negative_sign || -&lt;br /&gt;
|-&lt;br /&gt;
| number_decimal_digits || 2&lt;br /&gt;
|-&lt;br /&gt;
| number_decimal_separator || .&lt;br /&gt;
|-&lt;br /&gt;
| number_group_separator || '&lt;br /&gt;
|-&lt;br /&gt;
| positive_sign || +&lt;br /&gt;
|-&lt;br /&gt;
| negative_sign || -&lt;br /&gt;
|-&lt;br /&gt;
| negative_infinity_symbol || -Infinito&lt;br /&gt;
|-&lt;br /&gt;
| per_mille_symbol || ë&lt;br /&gt;
|-&lt;br /&gt;
| na_n_symbol || Non un numero reale&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Other information ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
&lt;br /&gt;
* ms-help://MS.NETFramework.v20.en/cpref8/html/T_System_Globalization_CultureInfo.htm (ms-help is the .NET documentation)&lt;br /&gt;
* http://msdn2.microsoft.com/en-us/library/system.globalization.cultureinfo.aspx&lt;br /&gt;
* http://msdn2.microsoft.com/en-us/library/system.globalization.compareinfo.aspx&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/posix_locale&amp;diff=4457</id>
		<title>Internationalization/posix locale</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/posix_locale&amp;diff=4457"/>
				<updated>2006-09-05T11:18:23Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: /* Checking for default locale */ another method&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Internationalization]]&lt;br /&gt;
&lt;br /&gt;
==Summary==&lt;br /&gt;
My Summary is based on article by Michael Becker (see [http://www.ijon.de/comp/tutorials/locale.html here]).This summary is more or less concerning SuSE-Linux.&lt;br /&gt;
&lt;br /&gt;
There are differences between User-locale and C-locale. C-locale, is the local, which is only effective in C-environment. If there are no locales  set in user environment, then C-locale is effective, which is so called &amp;quot;POSIX&amp;quot;-locale.&lt;br /&gt;
&lt;br /&gt;
With C-command &amp;lt;code&amp;gt;setlocale (LC_ALL,&amp;quot;&amp;quot;)&amp;lt;/code&amp;gt; one set C-locale with User-locale. So one could retrieve details about User-locale information with C-functions.&lt;br /&gt;
&lt;br /&gt;
==Listing available locales==&lt;br /&gt;
There are two directories that one could get information about locales. &lt;br /&gt;
They are:&lt;br /&gt;
''/usr/share/locale/''&lt;br /&gt;
''/usr/share/i18n/''&lt;br /&gt;
&lt;br /&gt;
In the first directory, the locales are binary files. So we could not need them for our purpose since i do not know how to read them for the moment.&lt;br /&gt;
&lt;br /&gt;
In the second directory there are at least 2 subdirectories, with names charmaps and locales.&lt;br /&gt;
&lt;br /&gt;
Shell command ''ls /usr/share/i18n/locales/'' list all the available locales.&lt;br /&gt;
&lt;br /&gt;
==Checking for default locale==&lt;br /&gt;
&lt;br /&gt;
With shell command &amp;quot;locale&amp;quot; one can get infomation about default locale. &lt;br /&gt;
In C, to get details of localeone can use&lt;br /&gt;
&amp;lt;code&amp;gt;setlocale (LC_ALL,&amp;quot;&amp;quot;)&lt;br /&gt;
localeconv()&amp;lt;/code&amp;gt;  &lt;br /&gt;
see ''manpage locale(7)'' to get more information.&lt;br /&gt;
&lt;br /&gt;
Another way to obtain the current locale is to use the environnement variable ''LANGUAGE'', this is done with the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
environement : EXECUTION_ENVIRONMENT&lt;br /&gt;
...&lt;br /&gt;
environement.get (&amp;quot;LANGUAGE&amp;quot;)&lt;br /&gt;
    -- returns the (rank)list (as string) of languages set by the user&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Retrieving locale information ==&lt;br /&gt;
C-command &amp;lt;code&amp;gt; nl_langinfo() &amp;lt;/code&amp;gt;(defined in langinfo.h) one could get information about all categories.  &lt;br /&gt;
For example, with &amp;lt;code&amp;gt; nl_langinfo(D_T_FMT)&amp;lt;/code&amp;gt;, one get a pointer at a string, which in form of %a %d %b %Y %T %Z.&lt;br /&gt;
&lt;br /&gt;
== Other information ==&lt;br /&gt;
Using a parser one could also retrieve locale information,  about which I do not have a lot of idea.&lt;br /&gt;
&lt;br /&gt;
Still there are C-functions to use categories. &lt;br /&gt;
For example,&lt;br /&gt;
&amp;lt;code&amp;gt;strftime()&lt;br /&gt;
strptime()&lt;br /&gt;
wcsftime()&amp;lt;/code&amp;gt;&lt;br /&gt;
for LC_TIME&lt;br /&gt;
For another example,&lt;br /&gt;
&amp;lt;code&amp;gt;isalnum&lt;br /&gt;
isalpha&lt;br /&gt;
isblank&amp;lt;/code&amp;gt;&lt;br /&gt;
and so on for LC_CTYPE. &lt;br /&gt;
&lt;br /&gt;
For more information please read [http://www.opengroup.org/onlinepubs/007908799/xbd/locale.html local-Specification of Unix Open]&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/dotnet_locale&amp;diff=4456</id>
		<title>Internationalization/dotnet locale</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/dotnet_locale&amp;diff=4456"/>
				<updated>2006-09-05T11:16:27Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: /* Checking for default locale */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Internationalization]]&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
There is a class named CULTURE_INFO in &amp;quot;mscorlib&amp;quot; in EiffelStudio, which provides information about a specific culture such as:&lt;br /&gt;
* associated language&lt;br /&gt;
* sublanguage&lt;br /&gt;
* country/region&lt;br /&gt;
* calendar&lt;br /&gt;
* cultural conventions&lt;br /&gt;
&lt;br /&gt;
== Listing available locales ==&lt;br /&gt;
&lt;br /&gt;
I didn't find a function that returns all the available locale informations, I think because under .NET, they are all avaiable.&lt;br /&gt;
&lt;br /&gt;
== Checking for default locale ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
a_culture_info : CULTURE_INFO&lt;br /&gt;
a_culture_info.current_culture.name : SYSTEM_STRING&lt;br /&gt;
    -- returns the name of the current culture info, (in the format described below).&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Retrieving locale information ==&lt;br /&gt;
To obtain informations on a specific locale, it suffices to create an instance of CULTURE_INFO. There are basically two ways to do this:&lt;br /&gt;
&lt;br /&gt;
# Create it with the culture identifier. This identifier maps every culture/language to an integer. It is not very usefull, because I did not find a logic behind the mapping function... You can find a table on [http://msdn2.microsoft.com/en-us/library/ms172470.aspx here]&lt;br /&gt;
# Create it with the name (STRING) of the culture. The culture names follow the RFC 1766 standard in the format &amp;quot;&amp;lt;languagecode2&amp;gt;-&amp;lt;country/regioncode2&amp;gt;&amp;quot;, where &amp;lt;languagecode2&amp;gt; is a lowercase two-letter code derived from ISO 639-1 and &amp;lt;country/regioncode2&amp;gt; is an uppercase two-letter code derived from ISO 3166.&lt;br /&gt;
&lt;br /&gt;
You can find a detailed description of RFC 1766&lt;br /&gt;
&lt;br /&gt;
The CULTURE_INFO Class has some attibutes useful for the retrieving of the informations about Date, Time and Number formatting, they are:&lt;br /&gt;
&lt;br /&gt;
* date_time_format: DATE_TIME_FORMAT_INFO ([http://msdn2.microsoft.com/en-us/library/system.globalization.datetimeformatinfo.aspx see here])&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Some information that is available in DATE_TIME_FORMAT_INFO&lt;br /&gt;
! Information !! Result for locale &amp;quot;it-CH&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| full_date_time_pattern || dddd, d. MMMM yyyy HH:mm:ss&lt;br /&gt;
|-&lt;br /&gt;
| long_date_pattern || dddd, d. MMMM yyyy&lt;br /&gt;
|-&lt;br /&gt;
| long_time_pattern || HH:mm:ss&lt;br /&gt;
|-&lt;br /&gt;
| month_day_pattern || d. MMMM&lt;br /&gt;
|-&lt;br /&gt;
| rfc1123_pattern || ddd, dd MMM yyyy HH':'mm':'ss 'GMT'&lt;br /&gt;
|-&lt;br /&gt;
| pm_designator ||&lt;br /&gt;
|-&lt;br /&gt;
| short_date_pattern || dd.MM.yyyy&lt;br /&gt;
|-&lt;br /&gt;
| short_time_pattern || HH:mm&lt;br /&gt;
|-&lt;br /&gt;
| sortable_date_time_pattern || yyyy'-'MM'-'dd'T'HH':'mm':'ss&lt;br /&gt;
|-&lt;br /&gt;
| time_separator ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* there are also functions that return abbreviations of names of months and day:&lt;br /&gt;
** get_abbreviated_day_name (dayofweek: DAY_OF_WEEK) : SYSTEM_STRING&lt;br /&gt;
** get_abbreviated_month_name (month: INTEGER) : SYSTEM_STRING&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* number_format: NUMBER_FORMAT_INFO ([http://msdn2.microsoft.com/en-us/library/system.globalization.numberformatinfo.aspx see here])&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Some information that is available in NUMBER_FORMAT_INFO&lt;br /&gt;
! Information !! Result for locale &amp;quot;it-CH&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| currency_group_separator || '&lt;br /&gt;
|-&lt;br /&gt;
| currency_symbol || SFr.&lt;br /&gt;
|-&lt;br /&gt;
| currency_decimal_digits || 2&lt;br /&gt;
|-&lt;br /&gt;
| negative_sign || -&lt;br /&gt;
|-&lt;br /&gt;
| number_decimal_digits || 2&lt;br /&gt;
|-&lt;br /&gt;
| number_decimal_separator || .&lt;br /&gt;
|-&lt;br /&gt;
| number_group_separator || '&lt;br /&gt;
|-&lt;br /&gt;
| positive_sign || +&lt;br /&gt;
|-&lt;br /&gt;
| negative_sign || -&lt;br /&gt;
|-&lt;br /&gt;
| negative_infinity_symbol || -Infinito&lt;br /&gt;
|-&lt;br /&gt;
| per_mille_symbol || ë&lt;br /&gt;
|-&lt;br /&gt;
| na_n_symbol || Non un numero reale&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Other information ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
&lt;br /&gt;
* ms-help://MS.NETFramework.v20.en/cpref8/html/T_System_Globalization_CultureInfo.htm (ms-help is the .NET documentation)&lt;br /&gt;
* http://msdn2.microsoft.com/en-us/library/system.globalization.cultureinfo.aspx&lt;br /&gt;
* http://msdn2.microsoft.com/en-us/library/system.globalization.compareinfo.aspx&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/dotnet_locale&amp;diff=4453</id>
		<title>Internationalization/dotnet locale</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/dotnet_locale&amp;diff=4453"/>
				<updated>2006-09-04T13:18:23Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: /* Checking for default locale */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Internationalization]]&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
There is a class named CULTURE_INFO in &amp;quot;mscorlib&amp;quot; in EiffelStudio, which provides information about a specific culture such as:&lt;br /&gt;
* associated language&lt;br /&gt;
* sublanguage&lt;br /&gt;
* country/region&lt;br /&gt;
* calendar&lt;br /&gt;
* cultural conventions&lt;br /&gt;
&lt;br /&gt;
== Listing available locales ==&lt;br /&gt;
&lt;br /&gt;
I didn't find a function that returns all the available locale informations, I think because under .NET, they are all avaiable.&lt;br /&gt;
&lt;br /&gt;
== Checking for default locale ==&lt;br /&gt;
&lt;br /&gt;
The easiest and way to obtain the current locale is to use the following Eiffel code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
environement : EXECUTION_ENVIRONMENT&lt;br /&gt;
...&lt;br /&gt;
environement.get (&amp;quot;LANGUAGE&amp;quot;)&lt;br /&gt;
    -- returns the (rank)list (as string) of languages set by the user&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
an other method is:&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
a_culture_info : CULTURE_INFO&lt;br /&gt;
a_culture_info.current_culture.name : SYSTEM_STRING&lt;br /&gt;
    -- returns the name of the current culture info, (in the format described below).&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Retrieving locale information ==&lt;br /&gt;
To obtain informations on a specific locale, it suffices to create an instance of CULTURE_INFO. There are basically two ways to do this:&lt;br /&gt;
&lt;br /&gt;
# Create it with the culture identifier. This identifier maps every culture/language to an integer. It is not very usefull, because I did not find a logic behind the mapping function... You can find a table on [http://msdn2.microsoft.com/en-us/library/ms172470.aspx here]&lt;br /&gt;
# Create it with the name (STRING) of the culture. The culture names follow the RFC 1766 standard in the format &amp;quot;&amp;lt;languagecode2&amp;gt;-&amp;lt;country/regioncode2&amp;gt;&amp;quot;, where &amp;lt;languagecode2&amp;gt; is a lowercase two-letter code derived from ISO 639-1 and &amp;lt;country/regioncode2&amp;gt; is an uppercase two-letter code derived from ISO 3166.&lt;br /&gt;
&lt;br /&gt;
You can find a detailed description of RFC 1766&lt;br /&gt;
&lt;br /&gt;
The CULTURE_INFO Class has some attibutes useful for the retrieving of the informations about Date, Time and Number formatting, they are:&lt;br /&gt;
&lt;br /&gt;
* date_time_format: DATE_TIME_FORMAT_INFO ([http://msdn2.microsoft.com/en-us/library/system.globalization.datetimeformatinfo.aspx see here])&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Some information that is available in DATE_TIME_FORMAT_INFO&lt;br /&gt;
! Information !! Result for locale &amp;quot;it-CH&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| full_date_time_pattern || dddd, d. MMMM yyyy HH:mm:ss&lt;br /&gt;
|-&lt;br /&gt;
| long_date_pattern || dddd, d. MMMM yyyy&lt;br /&gt;
|-&lt;br /&gt;
| long_time_pattern || HH:mm:ss&lt;br /&gt;
|-&lt;br /&gt;
| month_day_pattern || d. MMMM&lt;br /&gt;
|-&lt;br /&gt;
| rfc1123_pattern || ddd, dd MMM yyyy HH':'mm':'ss 'GMT'&lt;br /&gt;
|-&lt;br /&gt;
| pm_designator ||&lt;br /&gt;
|-&lt;br /&gt;
| short_date_pattern || dd.MM.yyyy&lt;br /&gt;
|-&lt;br /&gt;
| short_time_pattern || HH:mm&lt;br /&gt;
|-&lt;br /&gt;
| sortable_date_time_pattern || yyyy'-'MM'-'dd'T'HH':'mm':'ss&lt;br /&gt;
|-&lt;br /&gt;
| time_separator ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* there are also functions that return abbreviations of names of months and day:&lt;br /&gt;
** get_abbreviated_day_name (dayofweek: DAY_OF_WEEK) : SYSTEM_STRING&lt;br /&gt;
** get_abbreviated_month_name (month: INTEGER) : SYSTEM_STRING&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* number_format: NUMBER_FORMAT_INFO ([http://msdn2.microsoft.com/en-us/library/system.globalization.numberformatinfo.aspx see here])&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Some information that is available in NUMBER_FORMAT_INFO&lt;br /&gt;
! Information !! Result for locale &amp;quot;it-CH&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| currency_group_separator || '&lt;br /&gt;
|-&lt;br /&gt;
| currency_symbol || SFr.&lt;br /&gt;
|-&lt;br /&gt;
| currency_decimal_digits || 2&lt;br /&gt;
|-&lt;br /&gt;
| negative_sign || -&lt;br /&gt;
|-&lt;br /&gt;
| number_decimal_digits || 2&lt;br /&gt;
|-&lt;br /&gt;
| number_decimal_separator || .&lt;br /&gt;
|-&lt;br /&gt;
| number_group_separator || '&lt;br /&gt;
|-&lt;br /&gt;
| positive_sign || +&lt;br /&gt;
|-&lt;br /&gt;
| negative_sign || -&lt;br /&gt;
|-&lt;br /&gt;
| negative_infinity_symbol || -Infinito&lt;br /&gt;
|-&lt;br /&gt;
| per_mille_symbol || ë&lt;br /&gt;
|-&lt;br /&gt;
| na_n_symbol || Non un numero reale&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Other information ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
&lt;br /&gt;
* ms-help://MS.NETFramework.v20.en/cpref8/html/T_System_Globalization_CultureInfo.htm (ms-help is the .NET documentation)&lt;br /&gt;
* http://msdn2.microsoft.com/en-us/library/system.globalization.cultureinfo.aspx&lt;br /&gt;
* http://msdn2.microsoft.com/en-us/library/system.globalization.compareinfo.aspx&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=User_talk:Manus&amp;diff=4446</id>
		<title>User talk:Manus</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=User_talk:Manus&amp;diff=4446"/>
				<updated>2006-09-03T07:28:00Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: block proposal&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Vandalism==&lt;br /&gt;
&lt;br /&gt;
Hi Manus, I wanted to inform you that there are two users that did some vandalism:&lt;br /&gt;
* [[User:Ceas]] did [http://eiffelsoftware.origo.ethz.ch/index.php?title=Main_Page&amp;amp;diff=next&amp;amp;oldid=4215 this]&lt;br /&gt;
* [[User:Moralest]] did [http://eiffelsoftware.origo.ethz.ch/index.php?title=Main_Page&amp;amp;diff=4442&amp;amp;oldid=4401 this]&lt;br /&gt;
I propose to block their username... I've already removed the changes. [[User:Etienner|&amp;lt;font color=&amp;quot;Yellow&amp;quot;&amp;gt;'''E'''&amp;lt;/font&amp;gt;&amp;lt;font color=&amp;quot;Black&amp;quot;&amp;gt;'''T'''&amp;lt;/font&amp;gt;&amp;lt;font color=&amp;quot;Yellow&amp;quot;&amp;gt;'''N'''&amp;lt;/font&amp;gt;]] &amp;lt;sup&amp;gt;[[User talk:Etienner|'''&amp;lt;font color=&amp;quot;Yellow&amp;quot;&amp;gt;talk&amp;lt;/font&amp;gt;''']]&amp;lt;/sup&amp;gt;&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=User_talk:Manus&amp;diff=4445</id>
		<title>User talk:Manus</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=User_talk:Manus&amp;diff=4445"/>
				<updated>2006-09-03T07:24:59Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: Vandalism...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Vandalism==&lt;br /&gt;
&lt;br /&gt;
Hi Manus, I wanted to inform you that there are two users that did some vandalism:&lt;br /&gt;
* [[User:Ceas]] did [http://eiffelsoftware.origo.ethz.ch/index.php?title=Main_Page&amp;amp;diff=next&amp;amp;oldid=4215 this]&lt;br /&gt;
* [[User:Moralest]] did [http://eiffelsoftware.origo.ethz.ch/index.php?title=Main_Page&amp;amp;diff=4442&amp;amp;oldid=4401 this]&lt;br /&gt;
I've already removed the changes. [[User:Etienner|&amp;lt;font color=&amp;quot;Yellow&amp;quot;&amp;gt;'''E'''&amp;lt;/font&amp;gt;&amp;lt;font color=&amp;quot;Black&amp;quot;&amp;gt;'''T'''&amp;lt;/font&amp;gt;&amp;lt;font color=&amp;quot;Yellow&amp;quot;&amp;gt;'''N'''&amp;lt;/font&amp;gt;]] &amp;lt;sup&amp;gt;[[User talk:Etienner|'''&amp;lt;font color=&amp;quot;Yellow&amp;quot;&amp;gt;talk&amp;lt;/font&amp;gt;''']]&amp;lt;/sup&amp;gt;&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Main_Page&amp;diff=4444</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Main_Page&amp;diff=4444"/>
				<updated>2006-09-03T07:23:15Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: remove vandalism&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Welcome to [http://www.eiffel.com/ Eiffel Software]'s Wiki, the home page for Eiffel Software's Open Source initiative in collaboration with the [http://se.inf.ethz.ch/ Chair of Software Engineering] at [http://www.ethz.ch ETH Zurich].&lt;br /&gt;
&lt;br /&gt;
{{block|'''Project ideas'''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you'd like to contribute to the progress of Eiffel technology but don't know where to start, be sure to&lt;br /&gt;
take a look at the [[:Category:Projects| project suggestion pages]]. They contain lots of great ideas for projects large and small!}}&lt;br /&gt;
&lt;br /&gt;
To download or look at the source code of EiffelStudio, please go to the [[Repository| SVN repository]] page.&lt;br /&gt;
&lt;br /&gt;
To compile the source code, you will need a snapshot of the current development release of EiffelStudio. To get it go to the [[Downloads| Downloads]] page.&lt;br /&gt;
&lt;br /&gt;
=== Wiki Contents ===&lt;br /&gt;
&lt;br /&gt;
* [[:Category:EiffelStudio|EiffelStudio]]&lt;br /&gt;
* [[:Category:EiffelBuild|EiffelBuild]]&lt;br /&gt;
* [[:Category:Compiler| Eiffel Compiler]]&lt;br /&gt;
* [[:Category:Runtime| Eiffel Runtime]]&lt;br /&gt;
* [[:Category:Library| Eiffel Libraries]]:&lt;br /&gt;
** [[:Category:EiffelBase| EiffelBase]]&lt;br /&gt;
** [[:Category:EiffelVision2| EiffelVision2]]&lt;br /&gt;
** [[:Category:WEL| WEL]]&lt;br /&gt;
* [[:Category:Eiffel for .NET| Eiffel for .NET]]&lt;br /&gt;
* [[:Category:Documentation| Documentation]]&lt;br /&gt;
* [[Repository| SVN repository]] &lt;br /&gt;
* [[Contributing| How To Contribute?]]&lt;br /&gt;
* [[:Category:Projects| Projects and project suggestions]]&lt;br /&gt;
* [[URLs| Useful URLs]]&lt;br /&gt;
* [[TODOs| Project TODOs]]&lt;br /&gt;
* [[Tools| Tools]]&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/file_format&amp;diff=4439</id>
		<title>Internationalization/file format</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/file_format&amp;diff=4439"/>
				<updated>2006-09-02T15:45:39Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: /* Format of PO files */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Internationalization]]&lt;br /&gt;
&lt;br /&gt;
==Summary==&lt;br /&gt;
&lt;br /&gt;
A bref description of the most importat file formats used for the translation of programs.&lt;br /&gt;
&lt;br /&gt;
==PO Files==&lt;br /&gt;
&lt;br /&gt;
===Format of PO files===&lt;br /&gt;
&lt;br /&gt;
A PO file has an entry for each string that has to be translated. There are two kind of them, a &amp;quot;normal&amp;quot; one and one that involves plural forms.&lt;br /&gt;
&lt;br /&gt;
====Normal entry====&lt;br /&gt;
&lt;br /&gt;
Here is the general structure of a &amp;quot;normal&amp;quot; entry:&lt;br /&gt;
&lt;br /&gt;
 white-space&lt;br /&gt;
 #  translator-comments&lt;br /&gt;
 #. extracted-comments&lt;br /&gt;
 #: references...&lt;br /&gt;
 #, flag...&lt;br /&gt;
 msgid untranslated-string&lt;br /&gt;
 msgstr translated-string&lt;br /&gt;
&lt;br /&gt;
Where the ''translator-comments'' are created and maintained exclusively by the translator, this comments have some white space immediately following the #. The other comments are created by the program that created the PO file.&lt;br /&gt;
''References'' are space separated lists of locations (sourcefile:linenumber) specifying where the translation unit is found in a source file.&lt;br /&gt;
After the special comment &amp;quot;#,&amp;quot; there can be some ''flags'', as ''fuzzy'' shows that the msgstr string might not be a correct translation, i.e. the translator is not sure of his work.&lt;br /&gt;
The 'untranslated-string' is the untranslated string as it appears in the original program source. The ''translated-string'' is (as the name suggests) the translated string, if there is no translation it is an empty string.&lt;br /&gt;
&lt;br /&gt;
====Plural form entry====&lt;br /&gt;
&lt;br /&gt;
 white-space&lt;br /&gt;
 #  translator-comments&lt;br /&gt;
 #. automatic-comments&lt;br /&gt;
 #: reference...&lt;br /&gt;
 #, flag...&lt;br /&gt;
 msgid untranslated-string-singular&lt;br /&gt;
 msgid_plural untranslated-string-plural&lt;br /&gt;
 msgstr[0] translated-string-case-0&lt;br /&gt;
 ...&lt;br /&gt;
 msgstr[N] translated-string-case-n&lt;br /&gt;
&lt;br /&gt;
===Supported character encodings===&lt;br /&gt;
&lt;br /&gt;
character encodings that can be used are limited to those supported by both GNU libc and GNU libiconv. These are: ASCII, ISO-8859-1, ISO-8859-2, ISO-8859-3, ISO-8859-4, ISO-8859-5, ISO-8859-6, ISO-8859-7, ISO-8859-8, ISO-8859-9, ISO-8859-13, ISO-8859-15, KOI8-R, KOI8-U, CP850, CP866, CP874, CP932, CP949, CP950, CP1250, CP1251, CP1252, CP1253, CP1254, CP1255, CP1256, CP1257, GB2312, EUC-JP, EUC-KR, EUC-TW, BIG5, BIG5-HKSCS, GBK, GB18030, SHIFT_JIS, JOHAB, TIS-620, VISCII, UTF-8.&lt;br /&gt;
&lt;br /&gt;
===Po Editors===&lt;br /&gt;
&lt;br /&gt;
* poEdit&lt;br /&gt;
* KBabel&lt;br /&gt;
* Gtranslator&lt;br /&gt;
* LocFactoryEditor (XLIFF and PO editor for Mac OSX)&lt;br /&gt;
&lt;br /&gt;
===Positive aspects===&lt;br /&gt;
&lt;br /&gt;
* Powerful plural handling&lt;br /&gt;
* Format created for translation purpose&lt;br /&gt;
* Easy for humans to read&lt;br /&gt;
* Used by gettext, kbabel, rosetta and many other programs&lt;br /&gt;
* Support and elaboration tools for almost all plattforms&lt;br /&gt;
&lt;br /&gt;
===Negative aspects===&lt;br /&gt;
&lt;br /&gt;
* The PO file format does not provide a way of identifying the source and target language within a file. By GNU standards, GNU software is written in American English (en-US), and this is reflected in Gettext by only having support for Germanic plural forms in the source language. It is therefore recommended to set the source-language attribute to en-US by default.&lt;br /&gt;
&lt;br /&gt;
==ts Files==&lt;br /&gt;
&lt;br /&gt;
===Format of ts files===&lt;br /&gt;
&lt;br /&gt;
The .ts file format is used Trolltech for the QT applications. They are XML conforming files. Here an example of a .ts file, generated my lupdate (a tool made by Trolltech that extracts translatable text from the C++ source code of the Qt application, see [[Internationalization/tool evaluation|here]] for further information):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;!DOCTYPE TS&amp;gt;&amp;lt;TS&amp;gt;&lt;br /&gt;
     &amp;lt;context&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;MyExample&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;message&amp;gt;&lt;br /&gt;
             &amp;lt;source&amp;gt;i18n=Internationalization&amp;lt;/source&amp;gt;&lt;br /&gt;
             &amp;lt;translation type=&amp;quot;unfinished&amp;quot;&amp;gt;&amp;lt;/translation&amp;gt;&lt;br /&gt;
         &amp;lt;/message&amp;gt;&lt;br /&gt;
     &amp;lt;/context&amp;gt;&lt;br /&gt;
 &amp;lt;/TS&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And after the translation (for example with Qt Linguist) it would look like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;!DOCTYPE TS&amp;gt;&amp;lt;TS&amp;gt;&lt;br /&gt;
     &amp;lt;context&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;MyExample&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;message&amp;gt;&lt;br /&gt;
             &amp;lt;source&amp;gt;i18n=Internationalization&amp;lt;/source&amp;gt;&lt;br /&gt;
             &amp;lt;translation&amp;gt;i20e=Internazionalizzazione&amp;lt;/translation&amp;gt;&lt;br /&gt;
         &amp;lt;/message&amp;gt;&lt;br /&gt;
     &amp;lt;/context&amp;gt;&lt;br /&gt;
 &amp;lt;/TS&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The .ts file is than converted to the .qm file format, a compact binary format that provides extremely fast lookups for translations, with a tool named lrelease.&lt;br /&gt;
&lt;br /&gt;
The creation of .qm files can also be done with the GNU gettext tools: with &amp;quot;xgettext --qt&amp;quot; as string extractor for producing the .pot file. And then convert the translated file (.po) with the &amp;quot;msgfmt --qt&amp;quot; command for creating the .qm files.&lt;br /&gt;
&lt;br /&gt;
=== ts Editors ===&lt;br /&gt;
&lt;br /&gt;
*QT Linguistic&lt;br /&gt;
&lt;br /&gt;
===Positive aspects===&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;full&amp;quot; support for unicode character encodings&lt;br /&gt;
* In trolltech's opinion it's a human readable text&lt;br /&gt;
&lt;br /&gt;
===Negative aspects===&lt;br /&gt;
&lt;br /&gt;
* QT's translation framework does not support plurals&lt;br /&gt;
* Qt message catalog format supports Unicode only in the translated strings, not in the untranslated strings&lt;br /&gt;
&lt;br /&gt;
== xliff Files ==&lt;br /&gt;
&lt;br /&gt;
===Format of XLIFF files===&lt;br /&gt;
&lt;br /&gt;
XLIFF is the XML Localization Interchange File Format. It is intended to give any software provider a single interchange file format that can be understood by any localization provider.&lt;br /&gt;
&lt;br /&gt;
You can find a XLIFF Tree Structure [http://www.oasis-open.org/committees/xliff/documents/xliff-specification.htm#AppTree here]&lt;br /&gt;
&lt;br /&gt;
=== ts Editors ===&lt;br /&gt;
&lt;br /&gt;
*[http://www.heartsome.net/EN/xlfedit.html heartsome]&lt;br /&gt;
*[https://open-language-tools.dev.java.net/editor/about-xliff-editor.html XLIFF Translation Editor]&lt;br /&gt;
&lt;br /&gt;
===Positive aspects===&lt;br /&gt;
&lt;br /&gt;
* OASIS standard&lt;br /&gt;
&lt;br /&gt;
===Negative aspects===&lt;br /&gt;
&lt;br /&gt;
* complicated plural form handling&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
* [http://www.gnu.org/software/gettext/manual/html_mono/gettext.html Gettext manual (for PO files)]&lt;br /&gt;
* [http://librarian.launchpad.net/2395419/it.po Example of a PO file (from rosetta)]&lt;br /&gt;
* [http://news.com.com/2100-1013_3-5146581.html Microsoft and XML]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/XML#Quick_syntax_tour XML syntax description on Wikipedia]&lt;br /&gt;
* [http://doc.trolltech.com/4.1/i18n.html Trolltech i18n]&lt;br /&gt;
* [http://translate.sourceforge.net/wiki/ open source i18n and l10n project]&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/file_format&amp;diff=4438</id>
		<title>Internationalization/file format</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/file_format&amp;diff=4438"/>
				<updated>2006-09-02T15:44:53Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: xliff...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Internationalization]]&lt;br /&gt;
&lt;br /&gt;
==Summary==&lt;br /&gt;
&lt;br /&gt;
A bref description of the most importat file formats used for the translation of programs.&lt;br /&gt;
&lt;br /&gt;
==PO Files==&lt;br /&gt;
&lt;br /&gt;
===Format of PO files===&lt;br /&gt;
&lt;br /&gt;
A PO file has an entry for each string that has to be translated. There are two kind of them, a &amp;quot;normal&amp;quot; one and one that involves plural forms.&lt;br /&gt;
&lt;br /&gt;
====Normal entry====&lt;br /&gt;
&lt;br /&gt;
Here is the general structure of a &amp;quot;normal&amp;quot; entry:&lt;br /&gt;
&lt;br /&gt;
 white-space&lt;br /&gt;
 #  translator-comments&lt;br /&gt;
 #. extracted-comments&lt;br /&gt;
 #: references...&lt;br /&gt;
 #, flag...&lt;br /&gt;
 msgid untranslated-string&lt;br /&gt;
 msgstr translated-string&lt;br /&gt;
&lt;br /&gt;
Where the ''translator-comments'' are created and maintained exclusively by the translator, this comments have some white space immediately following the #. The other comments are created by the program that created the PO file.&lt;br /&gt;
''References'' are space separated lists of locations (sourcefile:linenumber) specifying where the translation unit is found in a source file.&lt;br /&gt;
After the special comment &amp;quot;#,&amp;quot; there can be some ''flags'', as ''fuzzy'' shows that the msgstr string might not be a correct translation, i.e. the translator is not sure of his work.&lt;br /&gt;
The 'untranslated-string' is the untranslated string as it appears in the original program source. The ''translated-string'' is (as the name suggests) the translated string, if there is no translation it is an empty string.&lt;br /&gt;
&lt;br /&gt;
====Plural form entry====&lt;br /&gt;
&lt;br /&gt;
 white-space&lt;br /&gt;
 #  translator-comments&lt;br /&gt;
 #. automatic-comments&lt;br /&gt;
 #: reference...&lt;br /&gt;
 #, flag...&lt;br /&gt;
 msgid untranslated-string-singular&lt;br /&gt;
 msgid_plural untranslated-string-plural&lt;br /&gt;
 msgstr[0] translated-string-case-0&lt;br /&gt;
 ...&lt;br /&gt;
 msgstr[N] translated-string-case-n&lt;br /&gt;
&lt;br /&gt;
===Supported character encodings===&lt;br /&gt;
&lt;br /&gt;
character encodings that can be used are limited to those supported by both GNU libc and GNU libiconv. These are: ASCII, ISO-8859-1, ISO-8859-2, ISO-8859-3, ISO-8859-4, ISO-8859-5, ISO-8859-6, ISO-8859-7, ISO-8859-8, ISO-8859-9, ISO-8859-13, ISO-8859-15, KOI8-R, KOI8-U, CP850, CP866, CP874, CP932, CP949, CP950, CP1250, CP1251, CP1252, CP1253, CP1254, CP1255, CP1256, CP1257, GB2312, EUC-JP, EUC-KR, EUC-TW, BIG5, BIG5-HKSCS, GBK, GB18030, SHIFT_JIS, JOHAB, TIS-620, VISCII, UTF-8.&lt;br /&gt;
&lt;br /&gt;
===Po Editors===&lt;br /&gt;
&lt;br /&gt;
* poEdit&lt;br /&gt;
* KBabel&lt;br /&gt;
* Gtranslator&lt;br /&gt;
* LocFactoryEditor (XLIFF and PO editor for Mac OSX)&lt;br /&gt;
&lt;br /&gt;
===Positive aspects===&lt;br /&gt;
&lt;br /&gt;
* Powerful plural handling&lt;br /&gt;
* Format created for translation purpose&lt;br /&gt;
* Easy for humans to read&lt;br /&gt;
* Used by gettext, kbabel, rosetta and many other programs&lt;br /&gt;
* Support and elaboration tools for almost all plattforms&lt;br /&gt;
&lt;br /&gt;
===Negative aspects===&lt;br /&gt;
&lt;br /&gt;
* The PO file format does not provide a way of identifying the source and target language within a file. By GNU standards, GNU software is written in American English (en-US), and this is reflected in Gettext by only having support for Germanic plural forms in the source language. It is therefore recommended to set the source-language attribute to en-US by default.&lt;br /&gt;
&lt;br /&gt;
==ts Files==&lt;br /&gt;
&lt;br /&gt;
===Format of ts files===&lt;br /&gt;
&lt;br /&gt;
The .ts file format is used Trolltech for the QT applications. They are XML conforming files. Here an example of a .ts file, generated my lupdate (a tool made by Trolltech that extracts translatable text from the C++ source code of the Qt application, see [[Internationalization/tool evaluation|here]] for further information):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;!DOCTYPE TS&amp;gt;&amp;lt;TS&amp;gt;&lt;br /&gt;
     &amp;lt;context&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;MyExample&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;message&amp;gt;&lt;br /&gt;
             &amp;lt;source&amp;gt;i18n=Internationalization&amp;lt;/source&amp;gt;&lt;br /&gt;
             &amp;lt;translation type=&amp;quot;unfinished&amp;quot;&amp;gt;&amp;lt;/translation&amp;gt;&lt;br /&gt;
         &amp;lt;/message&amp;gt;&lt;br /&gt;
     &amp;lt;/context&amp;gt;&lt;br /&gt;
 &amp;lt;/TS&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And after the translation (for example with Qt Linguist) it would look like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;!DOCTYPE TS&amp;gt;&amp;lt;TS&amp;gt;&lt;br /&gt;
     &amp;lt;context&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;MyExample&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;message&amp;gt;&lt;br /&gt;
             &amp;lt;source&amp;gt;i18n=Internationalization&amp;lt;/source&amp;gt;&lt;br /&gt;
             &amp;lt;translation&amp;gt;i20e=Internazionalizzazione&amp;lt;/translation&amp;gt;&lt;br /&gt;
         &amp;lt;/message&amp;gt;&lt;br /&gt;
     &amp;lt;/context&amp;gt;&lt;br /&gt;
 &amp;lt;/TS&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The .ts file is than converted to the .qm file format, a compact binary format that provides extremely fast lookups for translations, with a tool named lrelease.&lt;br /&gt;
&lt;br /&gt;
The creation of .qm files can also be done with the GNU gettext tools: with &amp;quot;xgettext --qt&amp;quot; as string extractor for producing the .pot file. And then convert the translated file (.po) with the &amp;quot;msgfmt --qt&amp;quot; command for creating the .qm files.&lt;br /&gt;
&lt;br /&gt;
=== ts Editors ===&lt;br /&gt;
&lt;br /&gt;
*QT Linguistic&lt;br /&gt;
&lt;br /&gt;
===Positive aspects===&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;full&amp;quot; support for unicode character encodings&lt;br /&gt;
* In trolltech's opinion it's a human readable text&lt;br /&gt;
&lt;br /&gt;
===Negative aspects===&lt;br /&gt;
&lt;br /&gt;
* QT's translation framework does not support plurals&lt;br /&gt;
* Qt message catalog format supports Unicode only in the translated strings, not in the untranslated strings&lt;br /&gt;
&lt;br /&gt;
== xliff Files ==&lt;br /&gt;
&lt;br /&gt;
===Format of PO files===&lt;br /&gt;
&lt;br /&gt;
XLIFF is the XML Localization Interchange File Format. It is intended to give any software provider a single interchange file format that can be understood by any localization provider.&lt;br /&gt;
&lt;br /&gt;
You can find a XLIFF Tree Structure [http://www.oasis-open.org/committees/xliff/documents/xliff-specification.htm#AppTree here]&lt;br /&gt;
&lt;br /&gt;
=== ts Editors ===&lt;br /&gt;
&lt;br /&gt;
*[http://www.heartsome.net/EN/xlfedit.html heartsome]&lt;br /&gt;
*[https://open-language-tools.dev.java.net/editor/about-xliff-editor.html XLIFF Translation Editor]&lt;br /&gt;
&lt;br /&gt;
===Positive aspects===&lt;br /&gt;
&lt;br /&gt;
* OASIS standard&lt;br /&gt;
&lt;br /&gt;
===Negative aspects===&lt;br /&gt;
&lt;br /&gt;
* complicated plural form handling&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
* [http://www.gnu.org/software/gettext/manual/html_mono/gettext.html Gettext manual (for PO files)]&lt;br /&gt;
* [http://librarian.launchpad.net/2395419/it.po Example of a PO file (from rosetta)]&lt;br /&gt;
* [http://news.com.com/2100-1013_3-5146581.html Microsoft and XML]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/XML#Quick_syntax_tour XML syntax description on Wikipedia]&lt;br /&gt;
* [http://doc.trolltech.com/4.1/i18n.html Trolltech i18n]&lt;br /&gt;
* [http://translate.sourceforge.net/wiki/ open source i18n and l10n project]&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/file_format&amp;diff=4437</id>
		<title>Internationalization/file format</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/file_format&amp;diff=4437"/>
				<updated>2006-09-02T14:56:02Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: /* Negative aspects */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Internationalization]]&lt;br /&gt;
&lt;br /&gt;
==Summary==&lt;br /&gt;
&lt;br /&gt;
Here [[Internationalization|we]] evaluate various file formats used for the translation of programs. For the moment we are considering:&lt;br /&gt;
&lt;br /&gt;
* XML&lt;br /&gt;
* po&lt;br /&gt;
* [http://transolution.python-hosting.com xliff] (good description in this homepage)&lt;br /&gt;
* create an own format&lt;br /&gt;
&lt;br /&gt;
==PO Files==&lt;br /&gt;
&lt;br /&gt;
===Format of PO files===&lt;br /&gt;
&lt;br /&gt;
A PO file has an entry for each string that has to be translated. There are two kind of them, a &amp;quot;normal&amp;quot; one and one that involves plural forms.&lt;br /&gt;
&lt;br /&gt;
====Normal entry====&lt;br /&gt;
&lt;br /&gt;
Here is the general structure of a &amp;quot;normal&amp;quot; entry:&lt;br /&gt;
&lt;br /&gt;
 white-space&lt;br /&gt;
 #  translator-comments&lt;br /&gt;
 #. extracted-comments&lt;br /&gt;
 #: references...&lt;br /&gt;
 #, flag...&lt;br /&gt;
 msgid untranslated-string&lt;br /&gt;
 msgstr translated-string&lt;br /&gt;
&lt;br /&gt;
Where the ''translator-comments'' are created and maintained exclusively by the translator, this comments have some white space immediately following the #. The other comments are created by the program that created the PO file.&lt;br /&gt;
''References'' are space separated lists of locations (sourcefile:linenumber) specifying where the translation unit is found in a source file.&lt;br /&gt;
After the special comment &amp;quot;#,&amp;quot; there can be some ''flags'', as ''fuzzy'' shows that the msgstr string might not be a correct translation, i.e. the translator is not sure of his work.&lt;br /&gt;
The 'untranslated-string' is the untranslated string as it appears in the original program source. The ''translated-string'' is (as the name suggests) the translated string, if there is no translation it is an empty string.&lt;br /&gt;
&lt;br /&gt;
====Plural form entry====&lt;br /&gt;
&lt;br /&gt;
 white-space&lt;br /&gt;
 #  translator-comments&lt;br /&gt;
 #. automatic-comments&lt;br /&gt;
 #: reference...&lt;br /&gt;
 #, flag...&lt;br /&gt;
 msgid untranslated-string-singular&lt;br /&gt;
 msgid_plural untranslated-string-plural&lt;br /&gt;
 msgstr[0] translated-string-case-0&lt;br /&gt;
 ...&lt;br /&gt;
 msgstr[N] translated-string-case-n&lt;br /&gt;
&lt;br /&gt;
===Supported character encodings===&lt;br /&gt;
&lt;br /&gt;
character encodings that can be used are limited to those supported by both GNU libc and GNU libiconv. These are: ASCII, ISO-8859-1, ISO-8859-2, ISO-8859-3, ISO-8859-4, ISO-8859-5, ISO-8859-6, ISO-8859-7, ISO-8859-8, ISO-8859-9, ISO-8859-13, ISO-8859-15, KOI8-R, KOI8-U, CP850, CP866, CP874, CP932, CP949, CP950, CP1250, CP1251, CP1252, CP1253, CP1254, CP1255, CP1256, CP1257, GB2312, EUC-JP, EUC-KR, EUC-TW, BIG5, BIG5-HKSCS, GBK, GB18030, SHIFT_JIS, JOHAB, TIS-620, VISCII, UTF-8.&lt;br /&gt;
&lt;br /&gt;
I think they are a lot...&lt;br /&gt;
&lt;br /&gt;
===Po Editors===&lt;br /&gt;
&lt;br /&gt;
* poEdit&lt;br /&gt;
* KBabel&lt;br /&gt;
* Gtranslator&lt;br /&gt;
* LocFactoryEditor (XLIFF and PO editor for Mac OSX)&lt;br /&gt;
&lt;br /&gt;
===Positive aspects===&lt;br /&gt;
&lt;br /&gt;
* Powerful plural handling&lt;br /&gt;
* Format created for translation purpose&lt;br /&gt;
* Easy for humans to read&lt;br /&gt;
* Used by gettext, kbabel, rosetta and many other programs&lt;br /&gt;
* Support and elaboration tools for almost all plattforms&lt;br /&gt;
&lt;br /&gt;
===Negative aspects===&lt;br /&gt;
&lt;br /&gt;
* The PO file format does not provide a way of identifying the source and target language within a file. By GNU standards, GNU software is written in American English (en-US), and this is reflected in Gettext by only having support for Germanic plural forms in the source language. It is therefore recommended to set the source-language attribute to en-US by default.&lt;br /&gt;
&lt;br /&gt;
==ts Files==&lt;br /&gt;
&lt;br /&gt;
===Format of ts files===&lt;br /&gt;
&lt;br /&gt;
The .ts file format is used Trolltech for the QT applications. They are XML conforming files. Here an example of a .ts file, generated my lupdate (a tool made by Trolltech that extracts translatable text from the C++ source code of the Qt application, see [[Internationalization/tool evaluation|here]] for further information):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;!DOCTYPE TS&amp;gt;&amp;lt;TS&amp;gt;&lt;br /&gt;
     &amp;lt;context&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;MyExample&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;message&amp;gt;&lt;br /&gt;
             &amp;lt;source&amp;gt;i18n=Internationalization&amp;lt;/source&amp;gt;&lt;br /&gt;
             &amp;lt;translation type=&amp;quot;unfinished&amp;quot;&amp;gt;&amp;lt;/translation&amp;gt;&lt;br /&gt;
         &amp;lt;/message&amp;gt;&lt;br /&gt;
     &amp;lt;/context&amp;gt;&lt;br /&gt;
 &amp;lt;/TS&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And after the translation (for example with Qt Linguist) it would look like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;!DOCTYPE TS&amp;gt;&amp;lt;TS&amp;gt;&lt;br /&gt;
     &amp;lt;context&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;MyExample&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;message&amp;gt;&lt;br /&gt;
             &amp;lt;source&amp;gt;i18n=Internationalization&amp;lt;/source&amp;gt;&lt;br /&gt;
             &amp;lt;translation&amp;gt;i20e=Internazionalizzazione&amp;lt;/translation&amp;gt;&lt;br /&gt;
         &amp;lt;/message&amp;gt;&lt;br /&gt;
     &amp;lt;/context&amp;gt;&lt;br /&gt;
 &amp;lt;/TS&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The .ts file is than converted to the .qm file format, a compact binary format that provides extremely fast lookups for translations, with a tool named lrelease.&lt;br /&gt;
&lt;br /&gt;
The creation of .qm files can also be done with the GNU gettext tools: with &amp;quot;xgettext --qt&amp;quot; as string extractor for producing the .pot file. And then convert the translated file (.po) with the &amp;quot;msgfmt --qt&amp;quot; command for creating the .qm files.&lt;br /&gt;
&lt;br /&gt;
===Positive aspects===&lt;br /&gt;
&lt;br /&gt;
* full support for unicode character encodings&lt;br /&gt;
* In trolltech's opinion it's a human readable text&lt;br /&gt;
&lt;br /&gt;
===Negative aspects===&lt;br /&gt;
&lt;br /&gt;
* QT's translation framework does not support plurals&lt;br /&gt;
* Qt message catalog format supports Unicode only in the translated strings, not in the untranslated strings&lt;br /&gt;
&lt;br /&gt;
==New Format==&lt;br /&gt;
&lt;br /&gt;
===Format of our Format===&lt;br /&gt;
&lt;br /&gt;
* It doesn't exist yet, so we don't know how it looks like.&lt;br /&gt;
* We could give our own extension to the file format for example .et (eiffel translation) or .babe (babylon eiffel) or .eint (eiffel i18n) ... (''huge'' advantage)&lt;br /&gt;
&lt;br /&gt;
===Positive aspects===&lt;br /&gt;
&lt;br /&gt;
* Free to do what we want&lt;br /&gt;
* We don't have to care about licenses&lt;br /&gt;
* Possibility to make it the best human readable format&lt;br /&gt;
* So that we can say that we invented a new file format&lt;br /&gt;
* Better integrated and consistent with eiffel syntax&lt;br /&gt;
&lt;br /&gt;
===Negative aspects===&lt;br /&gt;
&lt;br /&gt;
* A new format? Why should we be different?&lt;br /&gt;
* Do more work as needed (there are already good formats)&lt;br /&gt;
* Long time until it becomes famous&lt;br /&gt;
&lt;br /&gt;
==Conclusions==&lt;br /&gt;
&lt;br /&gt;
Our decision is to use the po file format.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
* [http://www.gnu.org/software/gettext/manual/html_mono/gettext.html Gettext manual (for PO files)]&lt;br /&gt;
* [http://librarian.launchpad.net/2395419/it.po Example of a PO file (from rosetta)]&lt;br /&gt;
* [http://news.com.com/2100-1013_3-5146581.html Microsoft and XML]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/XML#Quick_syntax_tour XML syntax description on Wikipedia]&lt;br /&gt;
* [http://doc.trolltech.com/4.1/i18n.html Trolltech i18n]&lt;br /&gt;
* [http://translate.sourceforge.net/wiki/ open source i18n and l10n project]&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/file_format&amp;diff=4436</id>
		<title>Internationalization/file format</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/file_format&amp;diff=4436"/>
				<updated>2006-09-02T14:54:59Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: /* Normal entry */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Internationalization]]&lt;br /&gt;
&lt;br /&gt;
==Summary==&lt;br /&gt;
&lt;br /&gt;
Here [[Internationalization|we]] evaluate various file formats used for the translation of programs. For the moment we are considering:&lt;br /&gt;
&lt;br /&gt;
* XML&lt;br /&gt;
* po&lt;br /&gt;
* [http://transolution.python-hosting.com xliff] (good description in this homepage)&lt;br /&gt;
* create an own format&lt;br /&gt;
&lt;br /&gt;
==PO Files==&lt;br /&gt;
&lt;br /&gt;
===Format of PO files===&lt;br /&gt;
&lt;br /&gt;
A PO file has an entry for each string that has to be translated. There are two kind of them, a &amp;quot;normal&amp;quot; one and one that involves plural forms.&lt;br /&gt;
&lt;br /&gt;
====Normal entry====&lt;br /&gt;
&lt;br /&gt;
Here is the general structure of a &amp;quot;normal&amp;quot; entry:&lt;br /&gt;
&lt;br /&gt;
 white-space&lt;br /&gt;
 #  translator-comments&lt;br /&gt;
 #. extracted-comments&lt;br /&gt;
 #: references...&lt;br /&gt;
 #, flag...&lt;br /&gt;
 msgid untranslated-string&lt;br /&gt;
 msgstr translated-string&lt;br /&gt;
&lt;br /&gt;
Where the ''translator-comments'' are created and maintained exclusively by the translator, this comments have some white space immediately following the #. The other comments are created by the program that created the PO file.&lt;br /&gt;
''References'' are space separated lists of locations (sourcefile:linenumber) specifying where the translation unit is found in a source file.&lt;br /&gt;
After the special comment &amp;quot;#,&amp;quot; there can be some ''flags'', as ''fuzzy'' shows that the msgstr string might not be a correct translation, i.e. the translator is not sure of his work.&lt;br /&gt;
The 'untranslated-string' is the untranslated string as it appears in the original program source. The ''translated-string'' is (as the name suggests) the translated string, if there is no translation it is an empty string.&lt;br /&gt;
&lt;br /&gt;
====Plural form entry====&lt;br /&gt;
&lt;br /&gt;
 white-space&lt;br /&gt;
 #  translator-comments&lt;br /&gt;
 #. automatic-comments&lt;br /&gt;
 #: reference...&lt;br /&gt;
 #, flag...&lt;br /&gt;
 msgid untranslated-string-singular&lt;br /&gt;
 msgid_plural untranslated-string-plural&lt;br /&gt;
 msgstr[0] translated-string-case-0&lt;br /&gt;
 ...&lt;br /&gt;
 msgstr[N] translated-string-case-n&lt;br /&gt;
&lt;br /&gt;
===Supported character encodings===&lt;br /&gt;
&lt;br /&gt;
character encodings that can be used are limited to those supported by both GNU libc and GNU libiconv. These are: ASCII, ISO-8859-1, ISO-8859-2, ISO-8859-3, ISO-8859-4, ISO-8859-5, ISO-8859-6, ISO-8859-7, ISO-8859-8, ISO-8859-9, ISO-8859-13, ISO-8859-15, KOI8-R, KOI8-U, CP850, CP866, CP874, CP932, CP949, CP950, CP1250, CP1251, CP1252, CP1253, CP1254, CP1255, CP1256, CP1257, GB2312, EUC-JP, EUC-KR, EUC-TW, BIG5, BIG5-HKSCS, GBK, GB18030, SHIFT_JIS, JOHAB, TIS-620, VISCII, UTF-8.&lt;br /&gt;
&lt;br /&gt;
I think they are a lot...&lt;br /&gt;
&lt;br /&gt;
===Po Editors===&lt;br /&gt;
&lt;br /&gt;
* poEdit&lt;br /&gt;
* KBabel&lt;br /&gt;
* Gtranslator&lt;br /&gt;
* LocFactoryEditor (XLIFF and PO editor for Mac OSX)&lt;br /&gt;
&lt;br /&gt;
===Positive aspects===&lt;br /&gt;
&lt;br /&gt;
* Powerful plural handling&lt;br /&gt;
* Format created for translation purpose&lt;br /&gt;
* Easy for humans to read&lt;br /&gt;
* Used by gettext, kbabel, rosetta and many other programs&lt;br /&gt;
* Support and elaboration tools for almost all plattforms&lt;br /&gt;
&lt;br /&gt;
===Negative aspects===&lt;br /&gt;
&lt;br /&gt;
* We have to write a PO parser&lt;br /&gt;
&lt;br /&gt;
==ts Files==&lt;br /&gt;
&lt;br /&gt;
===Format of ts files===&lt;br /&gt;
&lt;br /&gt;
The .ts file format is used Trolltech for the QT applications. They are XML conforming files. Here an example of a .ts file, generated my lupdate (a tool made by Trolltech that extracts translatable text from the C++ source code of the Qt application, see [[Internationalization/tool evaluation|here]] for further information):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;!DOCTYPE TS&amp;gt;&amp;lt;TS&amp;gt;&lt;br /&gt;
     &amp;lt;context&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;MyExample&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;message&amp;gt;&lt;br /&gt;
             &amp;lt;source&amp;gt;i18n=Internationalization&amp;lt;/source&amp;gt;&lt;br /&gt;
             &amp;lt;translation type=&amp;quot;unfinished&amp;quot;&amp;gt;&amp;lt;/translation&amp;gt;&lt;br /&gt;
         &amp;lt;/message&amp;gt;&lt;br /&gt;
     &amp;lt;/context&amp;gt;&lt;br /&gt;
 &amp;lt;/TS&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And after the translation (for example with Qt Linguist) it would look like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;!DOCTYPE TS&amp;gt;&amp;lt;TS&amp;gt;&lt;br /&gt;
     &amp;lt;context&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;MyExample&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;message&amp;gt;&lt;br /&gt;
             &amp;lt;source&amp;gt;i18n=Internationalization&amp;lt;/source&amp;gt;&lt;br /&gt;
             &amp;lt;translation&amp;gt;i20e=Internazionalizzazione&amp;lt;/translation&amp;gt;&lt;br /&gt;
         &amp;lt;/message&amp;gt;&lt;br /&gt;
     &amp;lt;/context&amp;gt;&lt;br /&gt;
 &amp;lt;/TS&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The .ts file is than converted to the .qm file format, a compact binary format that provides extremely fast lookups for translations, with a tool named lrelease.&lt;br /&gt;
&lt;br /&gt;
The creation of .qm files can also be done with the GNU gettext tools: with &amp;quot;xgettext --qt&amp;quot; as string extractor for producing the .pot file. And then convert the translated file (.po) with the &amp;quot;msgfmt --qt&amp;quot; command for creating the .qm files.&lt;br /&gt;
&lt;br /&gt;
===Positive aspects===&lt;br /&gt;
&lt;br /&gt;
* full support for unicode character encodings&lt;br /&gt;
* In trolltech's opinion it's a human readable text&lt;br /&gt;
&lt;br /&gt;
===Negative aspects===&lt;br /&gt;
&lt;br /&gt;
* QT's translation framework does not support plurals&lt;br /&gt;
* Qt message catalog format supports Unicode only in the translated strings, not in the untranslated strings&lt;br /&gt;
&lt;br /&gt;
==New Format==&lt;br /&gt;
&lt;br /&gt;
===Format of our Format===&lt;br /&gt;
&lt;br /&gt;
* It doesn't exist yet, so we don't know how it looks like.&lt;br /&gt;
* We could give our own extension to the file format for example .et (eiffel translation) or .babe (babylon eiffel) or .eint (eiffel i18n) ... (''huge'' advantage)&lt;br /&gt;
&lt;br /&gt;
===Positive aspects===&lt;br /&gt;
&lt;br /&gt;
* Free to do what we want&lt;br /&gt;
* We don't have to care about licenses&lt;br /&gt;
* Possibility to make it the best human readable format&lt;br /&gt;
* So that we can say that we invented a new file format&lt;br /&gt;
* Better integrated and consistent with eiffel syntax&lt;br /&gt;
&lt;br /&gt;
===Negative aspects===&lt;br /&gt;
&lt;br /&gt;
* A new format? Why should we be different?&lt;br /&gt;
* Do more work as needed (there are already good formats)&lt;br /&gt;
* Long time until it becomes famous&lt;br /&gt;
&lt;br /&gt;
==Conclusions==&lt;br /&gt;
&lt;br /&gt;
Our decision is to use the po file format.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
* [http://www.gnu.org/software/gettext/manual/html_mono/gettext.html Gettext manual (for PO files)]&lt;br /&gt;
* [http://librarian.launchpad.net/2395419/it.po Example of a PO file (from rosetta)]&lt;br /&gt;
* [http://news.com.com/2100-1013_3-5146581.html Microsoft and XML]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/XML#Quick_syntax_tour XML syntax description on Wikipedia]&lt;br /&gt;
* [http://doc.trolltech.com/4.1/i18n.html Trolltech i18n]&lt;br /&gt;
* [http://translate.sourceforge.net/wiki/ open source i18n and l10n project]&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/file_format&amp;diff=4427</id>
		<title>Internationalization/file format</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/file_format&amp;diff=4427"/>
				<updated>2006-09-02T09:01:47Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: /* ts Files */ -&amp;gt; Negative aspects&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Internationalization]]&lt;br /&gt;
&lt;br /&gt;
==Summary==&lt;br /&gt;
&lt;br /&gt;
Here [[Internationalization|we]] evaluate various file formats used for the translation of programs. For the moment we are considering:&lt;br /&gt;
&lt;br /&gt;
* XML&lt;br /&gt;
* po&lt;br /&gt;
* [http://transolution.python-hosting.com xliff] (good description in this homepage)&lt;br /&gt;
* create an own format&lt;br /&gt;
&lt;br /&gt;
==PO Files==&lt;br /&gt;
&lt;br /&gt;
===Format of PO files===&lt;br /&gt;
&lt;br /&gt;
A PO file has an entry for each string that has to be translated. There are two kind of them, a &amp;quot;normal&amp;quot; one and one that involves plural forms.&lt;br /&gt;
&lt;br /&gt;
====Normal entry====&lt;br /&gt;
&lt;br /&gt;
Here is the general structure of a &amp;quot;normal&amp;quot; entry:&lt;br /&gt;
&lt;br /&gt;
 white-space&lt;br /&gt;
 #  translator-comments&lt;br /&gt;
 #. automatic-comments&lt;br /&gt;
 #: reference...&lt;br /&gt;
 #, flag...&lt;br /&gt;
 msgid untranslated-string&lt;br /&gt;
 msgstr translated-string&lt;br /&gt;
&lt;br /&gt;
Where the ''translator-comments'' are created and maintained exclusively by the translator, this comments have some white space immediately following the #. The other comments are created by the program that created the PO file.&lt;br /&gt;
After the special comment &amp;quot;#,&amp;quot; there can be some ''flags'', as ''fuzzy'' shows that the msgstr string might not be a correct translation, i.e. the translator is not sure of his work.&lt;br /&gt;
The 'untranslated-string' is the untranslated string as it appears in the original program source. The ''translated-string'' is (as the name suggests) the translated string, if there is no translation it is an empty string.&lt;br /&gt;
&lt;br /&gt;
====Plural form entry====&lt;br /&gt;
&lt;br /&gt;
 white-space&lt;br /&gt;
 #  translator-comments&lt;br /&gt;
 #. automatic-comments&lt;br /&gt;
 #: reference...&lt;br /&gt;
 #, flag...&lt;br /&gt;
 msgid untranslated-string-singular&lt;br /&gt;
 msgid_plural untranslated-string-plural&lt;br /&gt;
 msgstr[0] translated-string-case-0&lt;br /&gt;
 ...&lt;br /&gt;
 msgstr[N] translated-string-case-n&lt;br /&gt;
&lt;br /&gt;
===Supported character encodings===&lt;br /&gt;
&lt;br /&gt;
character encodings that can be used are limited to those supported by both GNU libc and GNU libiconv. These are: ASCII, ISO-8859-1, ISO-8859-2, ISO-8859-3, ISO-8859-4, ISO-8859-5, ISO-8859-6, ISO-8859-7, ISO-8859-8, ISO-8859-9, ISO-8859-13, ISO-8859-15, KOI8-R, KOI8-U, CP850, CP866, CP874, CP932, CP949, CP950, CP1250, CP1251, CP1252, CP1253, CP1254, CP1255, CP1256, CP1257, GB2312, EUC-JP, EUC-KR, EUC-TW, BIG5, BIG5-HKSCS, GBK, GB18030, SHIFT_JIS, JOHAB, TIS-620, VISCII, UTF-8.&lt;br /&gt;
&lt;br /&gt;
I think they are a lot...&lt;br /&gt;
&lt;br /&gt;
===Po Editors===&lt;br /&gt;
&lt;br /&gt;
* poEdit&lt;br /&gt;
* KBabel&lt;br /&gt;
* Gtranslator&lt;br /&gt;
* LocFactoryEditor (XLIFF and PO editor for Mac OSX)&lt;br /&gt;
&lt;br /&gt;
===Positive aspects===&lt;br /&gt;
&lt;br /&gt;
* Powerful plural handling&lt;br /&gt;
* Format created for translation purpose&lt;br /&gt;
* Easy for humans to read&lt;br /&gt;
* Used by gettext, kbabel, rosetta and many other programs&lt;br /&gt;
* Support and elaboration tools for almost all plattforms&lt;br /&gt;
&lt;br /&gt;
===Negative aspects===&lt;br /&gt;
&lt;br /&gt;
* We have to write a PO parser&lt;br /&gt;
&lt;br /&gt;
==ts Files==&lt;br /&gt;
&lt;br /&gt;
===Format of ts files===&lt;br /&gt;
&lt;br /&gt;
The .ts file format is used Trolltech for the QT applications. They are XML conforming files. Here an example of a .ts file, generated my lupdate (a tool made by Trolltech that extracts translatable text from the C++ source code of the Qt application, see [[Internationalization/tool evaluation|here]] for further information):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;!DOCTYPE TS&amp;gt;&amp;lt;TS&amp;gt;&lt;br /&gt;
     &amp;lt;context&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;MyExample&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;message&amp;gt;&lt;br /&gt;
             &amp;lt;source&amp;gt;i18n=Internationalization&amp;lt;/source&amp;gt;&lt;br /&gt;
             &amp;lt;translation type=&amp;quot;unfinished&amp;quot;&amp;gt;&amp;lt;/translation&amp;gt;&lt;br /&gt;
         &amp;lt;/message&amp;gt;&lt;br /&gt;
     &amp;lt;/context&amp;gt;&lt;br /&gt;
 &amp;lt;/TS&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And after the translation (for example with Qt Linguist) it would look like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;!DOCTYPE TS&amp;gt;&amp;lt;TS&amp;gt;&lt;br /&gt;
     &amp;lt;context&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;MyExample&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;message&amp;gt;&lt;br /&gt;
             &amp;lt;source&amp;gt;i18n=Internationalization&amp;lt;/source&amp;gt;&lt;br /&gt;
             &amp;lt;translation&amp;gt;i20e=Internazionalizzazione&amp;lt;/translation&amp;gt;&lt;br /&gt;
         &amp;lt;/message&amp;gt;&lt;br /&gt;
     &amp;lt;/context&amp;gt;&lt;br /&gt;
 &amp;lt;/TS&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The .ts file is than converted to the .qm file format, a compact binary format that provides extremely fast lookups for translations, with a tool named lrelease.&lt;br /&gt;
&lt;br /&gt;
The creation of .qm files can also be done with the GNU gettext tools: with &amp;quot;xgettext --qt&amp;quot; as string extractor for producing the .pot file. And then convert the translated file (.po) with the &amp;quot;msgfmt --qt&amp;quot; command for creating the .qm files.&lt;br /&gt;
&lt;br /&gt;
===Positive aspects===&lt;br /&gt;
&lt;br /&gt;
* full support for unicode character encodings&lt;br /&gt;
* In trolltech's opinion it's a human readable text&lt;br /&gt;
&lt;br /&gt;
===Negative aspects===&lt;br /&gt;
&lt;br /&gt;
* QT's translation framework does not support plurals&lt;br /&gt;
* Qt message catalog format supports Unicode only in the translated strings, not in the untranslated strings&lt;br /&gt;
&lt;br /&gt;
==New Format==&lt;br /&gt;
&lt;br /&gt;
===Format of our Format===&lt;br /&gt;
&lt;br /&gt;
* It doesn't exist yet, so we don't know how it looks like.&lt;br /&gt;
* We could give our own extension to the file format for example .et (eiffel translation) or .babe (babylon eiffel) or .eint (eiffel i18n) ... (''huge'' advantage)&lt;br /&gt;
&lt;br /&gt;
===Positive aspects===&lt;br /&gt;
&lt;br /&gt;
* Free to do what we want&lt;br /&gt;
* We don't have to care about licenses&lt;br /&gt;
* Possibility to make it the best human readable format&lt;br /&gt;
* So that we can say that we invented a new file format&lt;br /&gt;
* Better integrated and consistent with eiffel syntax&lt;br /&gt;
&lt;br /&gt;
===Negative aspects===&lt;br /&gt;
&lt;br /&gt;
* A new format? Why should we be different?&lt;br /&gt;
* Do more work as needed (there are already good formats)&lt;br /&gt;
* Long time until it becomes famous&lt;br /&gt;
&lt;br /&gt;
==Conclusions==&lt;br /&gt;
&lt;br /&gt;
Our decision is to use the po file format.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
* [http://www.gnu.org/software/gettext/manual/html_mono/gettext.html Gettext manual (for PO files)]&lt;br /&gt;
* [http://librarian.launchpad.net/2395419/it.po Example of a PO file (from rosetta)]&lt;br /&gt;
* [http://news.com.com/2100-1013_3-5146581.html Microsoft and XML]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/XML#Quick_syntax_tour XML syntax description on Wikipedia]&lt;br /&gt;
* [http://doc.trolltech.com/4.1/i18n.html Trolltech i18n]&lt;br /&gt;
* [http://translate.sourceforge.net/wiki/ open source i18n and l10n project]&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/file_format&amp;diff=4426</id>
		<title>Internationalization/file format</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/file_format&amp;diff=4426"/>
				<updated>2006-09-02T08:39:22Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: /* XML */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Internationalization]]&lt;br /&gt;
&lt;br /&gt;
==Summary==&lt;br /&gt;
&lt;br /&gt;
Here [[Internationalization|we]] evaluate various file formats used for the translation of programs. For the moment we are considering:&lt;br /&gt;
&lt;br /&gt;
* XML&lt;br /&gt;
* po&lt;br /&gt;
* [http://transolution.python-hosting.com xliff] (good description in this homepage)&lt;br /&gt;
* create an own format&lt;br /&gt;
&lt;br /&gt;
==PO Files==&lt;br /&gt;
&lt;br /&gt;
===Format of PO files===&lt;br /&gt;
&lt;br /&gt;
A PO file has an entry for each string that has to be translated. There are two kind of them, a &amp;quot;normal&amp;quot; one and one that involves plural forms.&lt;br /&gt;
&lt;br /&gt;
====Normal entry====&lt;br /&gt;
&lt;br /&gt;
Here is the general structure of a &amp;quot;normal&amp;quot; entry:&lt;br /&gt;
&lt;br /&gt;
 white-space&lt;br /&gt;
 #  translator-comments&lt;br /&gt;
 #. automatic-comments&lt;br /&gt;
 #: reference...&lt;br /&gt;
 #, flag...&lt;br /&gt;
 msgid untranslated-string&lt;br /&gt;
 msgstr translated-string&lt;br /&gt;
&lt;br /&gt;
Where the ''translator-comments'' are created and maintained exclusively by the translator, this comments have some white space immediately following the #. The other comments are created by the program that created the PO file.&lt;br /&gt;
After the special comment &amp;quot;#,&amp;quot; there can be some ''flags'', as ''fuzzy'' shows that the msgstr string might not be a correct translation, i.e. the translator is not sure of his work.&lt;br /&gt;
The 'untranslated-string' is the untranslated string as it appears in the original program source. The ''translated-string'' is (as the name suggests) the translated string, if there is no translation it is an empty string.&lt;br /&gt;
&lt;br /&gt;
====Plural form entry====&lt;br /&gt;
&lt;br /&gt;
 white-space&lt;br /&gt;
 #  translator-comments&lt;br /&gt;
 #. automatic-comments&lt;br /&gt;
 #: reference...&lt;br /&gt;
 #, flag...&lt;br /&gt;
 msgid untranslated-string-singular&lt;br /&gt;
 msgid_plural untranslated-string-plural&lt;br /&gt;
 msgstr[0] translated-string-case-0&lt;br /&gt;
 ...&lt;br /&gt;
 msgstr[N] translated-string-case-n&lt;br /&gt;
&lt;br /&gt;
===Supported character encodings===&lt;br /&gt;
&lt;br /&gt;
character encodings that can be used are limited to those supported by both GNU libc and GNU libiconv. These are: ASCII, ISO-8859-1, ISO-8859-2, ISO-8859-3, ISO-8859-4, ISO-8859-5, ISO-8859-6, ISO-8859-7, ISO-8859-8, ISO-8859-9, ISO-8859-13, ISO-8859-15, KOI8-R, KOI8-U, CP850, CP866, CP874, CP932, CP949, CP950, CP1250, CP1251, CP1252, CP1253, CP1254, CP1255, CP1256, CP1257, GB2312, EUC-JP, EUC-KR, EUC-TW, BIG5, BIG5-HKSCS, GBK, GB18030, SHIFT_JIS, JOHAB, TIS-620, VISCII, UTF-8.&lt;br /&gt;
&lt;br /&gt;
I think they are a lot...&lt;br /&gt;
&lt;br /&gt;
===Po Editors===&lt;br /&gt;
&lt;br /&gt;
* poEdit&lt;br /&gt;
* KBabel&lt;br /&gt;
* Gtranslator&lt;br /&gt;
* LocFactoryEditor (XLIFF and PO editor for Mac OSX)&lt;br /&gt;
&lt;br /&gt;
===Positive aspects===&lt;br /&gt;
&lt;br /&gt;
* Powerful plural handling&lt;br /&gt;
* Format created for translation purpose&lt;br /&gt;
* Easy for humans to read&lt;br /&gt;
* Used by gettext, kbabel, rosetta and many other programs&lt;br /&gt;
* Support and elaboration tools for almost all plattforms&lt;br /&gt;
&lt;br /&gt;
===Negative aspects===&lt;br /&gt;
&lt;br /&gt;
* We have to write a PO parser&lt;br /&gt;
&lt;br /&gt;
==ts Files==&lt;br /&gt;
&lt;br /&gt;
===Format of ts files===&lt;br /&gt;
&lt;br /&gt;
The .ts file format is used Trolltech for the QT applications. They are XML conforming files. Here an example of a .ts file, generated my lupdate (a tool made by Trolltech that extracts translatable text from the C++ source code of the Qt application, see [[Internationalization/tool evaluation|here]] for further information):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;!DOCTYPE TS&amp;gt;&amp;lt;TS&amp;gt;&lt;br /&gt;
     &amp;lt;context&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;MyExample&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;message&amp;gt;&lt;br /&gt;
             &amp;lt;source&amp;gt;i18n=Internationalization&amp;lt;/source&amp;gt;&lt;br /&gt;
             &amp;lt;translation type=&amp;quot;unfinished&amp;quot;&amp;gt;&amp;lt;/translation&amp;gt;&lt;br /&gt;
         &amp;lt;/message&amp;gt;&lt;br /&gt;
     &amp;lt;/context&amp;gt;&lt;br /&gt;
 &amp;lt;/TS&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And after the translation (for example with Qt Linguist) it would look like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;!DOCTYPE TS&amp;gt;&amp;lt;TS&amp;gt;&lt;br /&gt;
     &amp;lt;context&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;MyExample&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;message&amp;gt;&lt;br /&gt;
             &amp;lt;source&amp;gt;i18n=Internationalization&amp;lt;/source&amp;gt;&lt;br /&gt;
             &amp;lt;translation&amp;gt;i20e=Internazionalizzazione&amp;lt;/translation&amp;gt;&lt;br /&gt;
         &amp;lt;/message&amp;gt;&lt;br /&gt;
     &amp;lt;/context&amp;gt;&lt;br /&gt;
 &amp;lt;/TS&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The .ts file is than converted to the .qm file format, a compact binary format that provides extremely fast lookups for translations, with a tool named lrelease.&lt;br /&gt;
&lt;br /&gt;
The creation of .qm files can also be done with the GNU gettext tools: with &amp;quot;xgettext --qt&amp;quot; as string extractor for producing the .pot file. And then convert the translated file (.po) with the &amp;quot;msgfmt --qt&amp;quot; command for creating the .qm files.&lt;br /&gt;
&lt;br /&gt;
===Positive aspects===&lt;br /&gt;
&lt;br /&gt;
* full support for unicode character encodings&lt;br /&gt;
* In trolltech's opinion it's a human readable text&lt;br /&gt;
&lt;br /&gt;
===Negative aspects===&lt;br /&gt;
&lt;br /&gt;
* Not everybody knows it&lt;br /&gt;
* QT's translation framework does not support plurals&lt;br /&gt;
&lt;br /&gt;
==New Format==&lt;br /&gt;
&lt;br /&gt;
===Format of our Format===&lt;br /&gt;
&lt;br /&gt;
* It doesn't exist yet, so we don't know how it looks like.&lt;br /&gt;
* We could give our own extension to the file format for example .et (eiffel translation) or .babe (babylon eiffel) or .eint (eiffel i18n) ... (''huge'' advantage)&lt;br /&gt;
&lt;br /&gt;
===Positive aspects===&lt;br /&gt;
&lt;br /&gt;
* Free to do what we want&lt;br /&gt;
* We don't have to care about licenses&lt;br /&gt;
* Possibility to make it the best human readable format&lt;br /&gt;
* So that we can say that we invented a new file format&lt;br /&gt;
* Better integrated and consistent with eiffel syntax&lt;br /&gt;
&lt;br /&gt;
===Negative aspects===&lt;br /&gt;
&lt;br /&gt;
* A new format? Why should we be different?&lt;br /&gt;
* Do more work as needed (there are already good formats)&lt;br /&gt;
* Long time until it becomes famous&lt;br /&gt;
&lt;br /&gt;
==Conclusions==&lt;br /&gt;
&lt;br /&gt;
Our decision is to use the po file format.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
* [http://www.gnu.org/software/gettext/manual/html_mono/gettext.html Gettext manual (for PO files)]&lt;br /&gt;
* [http://librarian.launchpad.net/2395419/it.po Example of a PO file (from rosetta)]&lt;br /&gt;
* [http://news.com.com/2100-1013_3-5146581.html Microsoft and XML]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/XML#Quick_syntax_tour XML syntax description on Wikipedia]&lt;br /&gt;
* [http://doc.trolltech.com/4.1/i18n.html Trolltech i18n]&lt;br /&gt;
* [http://translate.sourceforge.net/wiki/ open source i18n and l10n project]&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/dotnet_locale&amp;diff=4420</id>
		<title>Internationalization/dotnet locale</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/dotnet_locale&amp;diff=4420"/>
				<updated>2006-09-01T15:19:11Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: Checking for default locale&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Internationalization]]&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
There is a class named CULTURE_INFO in &amp;quot;mscorlib&amp;quot; in EiffelStudio, which provides information about a specific culture such as:&lt;br /&gt;
* associated language&lt;br /&gt;
* sublanguage&lt;br /&gt;
* country/region&lt;br /&gt;
* calendar&lt;br /&gt;
* cultural conventions&lt;br /&gt;
&lt;br /&gt;
== Listing available locales ==&lt;br /&gt;
&lt;br /&gt;
I didn't find a function that returns all the available locale informations, I think because under .NET, they are all avaiable.&lt;br /&gt;
&lt;br /&gt;
== Checking for default locale ==&lt;br /&gt;
&lt;br /&gt;
To obtain the current locale:&lt;br /&gt;
&lt;br /&gt;
 a_culture_info : CULTURE_INFO&lt;br /&gt;
 a_culture_info.current_culture.name : SYSTEM_STRING&lt;br /&gt;
:returns the name of the current culture info, (in the format described below).&lt;br /&gt;
&lt;br /&gt;
== Retrieving locale information ==&lt;br /&gt;
To obtain informations on a specific locale, it suffices to create an instance of CULTURE_INFO. There are basically two ways to do this:&lt;br /&gt;
&lt;br /&gt;
# Create it with the culture identifier. This identifier maps every culture/language to an integer. It is not very usefull, because I did not find a logic behind the mapping function... You can find a table on [http://msdn2.microsoft.com/en-us/library/ms172470.aspx here]&lt;br /&gt;
# Create it with the name (STRING) of the culture. The culture names follow the RFC 1766 standard in the format &amp;quot;&amp;lt;languagecode2&amp;gt;-&amp;lt;country/regioncode2&amp;gt;&amp;quot;, where &amp;lt;languagecode2&amp;gt; is a lowercase two-letter code derived from ISO 639-1 and &amp;lt;country/regioncode2&amp;gt; is an uppercase two-letter code derived from ISO 3166.&lt;br /&gt;
&lt;br /&gt;
You can find a detailed description of RFC 1766&lt;br /&gt;
&lt;br /&gt;
The CULTURE_INFO Class has some attibutes useful for the retrieving of the informations about Date, Time and Number formatting, they are:&lt;br /&gt;
&lt;br /&gt;
* date_time_format: DATE_TIME_FORMAT_INFO ([http://msdn2.microsoft.com/en-us/library/system.globalization.datetimeformatinfo.aspx see here])&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Some information that is available in DATE_TIME_FORMAT_INFO&lt;br /&gt;
! Information !! Result for locale &amp;quot;it-CH&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| full_date_time_pattern || dddd, d. MMMM yyyy HH:mm:ss&lt;br /&gt;
|-&lt;br /&gt;
| long_date_pattern || dddd, d. MMMM yyyy&lt;br /&gt;
|-&lt;br /&gt;
| long_time_pattern || HH:mm:ss&lt;br /&gt;
|-&lt;br /&gt;
| month_day_pattern || d. MMMM&lt;br /&gt;
|-&lt;br /&gt;
| rfc1123_pattern || ddd, dd MMM yyyy HH':'mm':'ss 'GMT'&lt;br /&gt;
|-&lt;br /&gt;
| pm_designator ||&lt;br /&gt;
|-&lt;br /&gt;
| short_date_pattern || dd.MM.yyyy&lt;br /&gt;
|-&lt;br /&gt;
| short_time_pattern || HH:mm&lt;br /&gt;
|-&lt;br /&gt;
| sortable_date_time_pattern || yyyy'-'MM'-'dd'T'HH':'mm':'ss&lt;br /&gt;
|-&lt;br /&gt;
| time_separator ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* there are also functions that return abbreviations of names of months and day:&lt;br /&gt;
** get_abbreviated_day_name (dayofweek: DAY_OF_WEEK) : SYSTEM_STRING&lt;br /&gt;
** get_abbreviated_month_name (month: INTEGER) : SYSTEM_STRING&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* number_format: NUMBER_FORMAT_INFO ([http://msdn2.microsoft.com/en-us/library/system.globalization.numberformatinfo.aspx see here])&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Some information that is available in NUMBER_FORMAT_INFO&lt;br /&gt;
! Information !! Result for locale &amp;quot;it-CH&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| currency_group_separator || '&lt;br /&gt;
|-&lt;br /&gt;
| currency_symbol || SFr.&lt;br /&gt;
|-&lt;br /&gt;
| currency_decimal_digits || 2&lt;br /&gt;
|-&lt;br /&gt;
| negative_sign || -&lt;br /&gt;
|-&lt;br /&gt;
| number_decimal_digits || 2&lt;br /&gt;
|-&lt;br /&gt;
| number_decimal_separator || .&lt;br /&gt;
|-&lt;br /&gt;
| number_group_separator || '&lt;br /&gt;
|-&lt;br /&gt;
| positive_sign || +&lt;br /&gt;
|-&lt;br /&gt;
| negative_sign || -&lt;br /&gt;
|-&lt;br /&gt;
| negative_infinity_symbol || -Infinito&lt;br /&gt;
|-&lt;br /&gt;
| per_mille_symbol || ë&lt;br /&gt;
|-&lt;br /&gt;
| na_n_symbol || Non un numero reale&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Other information ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
&lt;br /&gt;
* ms-help://MS.NETFramework.v20.en/cpref8/html/T_System_Globalization_CultureInfo.htm (ms-help is the .NET documentation)&lt;br /&gt;
* http://msdn2.microsoft.com/en-us/library/system.globalization.cultureinfo.aspx&lt;br /&gt;
* http://msdn2.microsoft.com/en-us/library/system.globalization.compareinfo.aspx&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/dotnet_locale&amp;diff=4419</id>
		<title>Internationalization/dotnet locale</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/dotnet_locale&amp;diff=4419"/>
				<updated>2006-09-01T15:03:48Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: /* Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Internationalization]]&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
There is a class named CULTURE_INFO in &amp;quot;mscorlib&amp;quot; in EiffelStudio, which provides information about a specific culture such as:&lt;br /&gt;
* associated language&lt;br /&gt;
* sublanguage&lt;br /&gt;
* country/region&lt;br /&gt;
* calendar&lt;br /&gt;
* cultural conventions&lt;br /&gt;
&lt;br /&gt;
== Listing available locales ==&lt;br /&gt;
&lt;br /&gt;
I didn't find a function that returns all the available locale informations, I think because under .NET, they are all avaiable.&lt;br /&gt;
&lt;br /&gt;
== Checking for default locale ==&lt;br /&gt;
== Retrieving locale information ==&lt;br /&gt;
To obtain informations on a specific locale, it suffices to create an instance of CULTURE_INFO. There are basically two ways to do this:&lt;br /&gt;
&lt;br /&gt;
# Create it with the culture identifier. This identifier maps every culture/language to an integer. It is not very usefull, because I did not find a logic behind the mapping function... You can find a table on [http://msdn2.microsoft.com/en-us/library/ms172470.aspx here]&lt;br /&gt;
# Create it with the name (STRING) of the culture. The culture names follow the RFC 1766 standard in the format &amp;quot;&amp;lt;languagecode2&amp;gt;-&amp;lt;country/regioncode2&amp;gt;&amp;quot;, where &amp;lt;languagecode2&amp;gt; is a lowercase two-letter code derived from ISO 639-1 and &amp;lt;country/regioncode2&amp;gt; is an uppercase two-letter code derived from ISO 3166.&lt;br /&gt;
&lt;br /&gt;
You can find a detailed description of RFC 1766&lt;br /&gt;
&lt;br /&gt;
The CULTURE_INFO Class has some attibutes useful for the retrieving of the informations about Date, Time and Number formatting, they are:&lt;br /&gt;
&lt;br /&gt;
* date_time_format: DATE_TIME_FORMAT_INFO ([http://msdn2.microsoft.com/en-us/library/system.globalization.datetimeformatinfo.aspx see here])&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Some information that is available in DATE_TIME_FORMAT_INFO&lt;br /&gt;
! Information !! Result for locale &amp;quot;it-CH&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| full_date_time_pattern || dddd, d. MMMM yyyy HH:mm:ss&lt;br /&gt;
|-&lt;br /&gt;
| long_date_pattern || dddd, d. MMMM yyyy&lt;br /&gt;
|-&lt;br /&gt;
| long_time_pattern || HH:mm:ss&lt;br /&gt;
|-&lt;br /&gt;
| month_day_pattern || d. MMMM&lt;br /&gt;
|-&lt;br /&gt;
| rfc1123_pattern || ddd, dd MMM yyyy HH':'mm':'ss 'GMT'&lt;br /&gt;
|-&lt;br /&gt;
| pm_designator ||&lt;br /&gt;
|-&lt;br /&gt;
| short_date_pattern || dd.MM.yyyy&lt;br /&gt;
|-&lt;br /&gt;
| short_time_pattern || HH:mm&lt;br /&gt;
|-&lt;br /&gt;
| sortable_date_time_pattern || yyyy'-'MM'-'dd'T'HH':'mm':'ss&lt;br /&gt;
|-&lt;br /&gt;
| time_separator ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* there are also functions that return abbreviations of names of months and day:&lt;br /&gt;
** get_abbreviated_day_name (dayofweek: DAY_OF_WEEK) : SYSTEM_STRING&lt;br /&gt;
** get_abbreviated_month_name (month: INTEGER) : SYSTEM_STRING&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* number_format: NUMBER_FORMAT_INFO ([http://msdn2.microsoft.com/en-us/library/system.globalization.numberformatinfo.aspx see here])&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Some information that is available in NUMBER_FORMAT_INFO&lt;br /&gt;
! Information !! Result for locale &amp;quot;it-CH&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| currency_group_separator || '&lt;br /&gt;
|-&lt;br /&gt;
| currency_symbol || SFr.&lt;br /&gt;
|-&lt;br /&gt;
| currency_decimal_digits || 2&lt;br /&gt;
|-&lt;br /&gt;
| negative_sign || -&lt;br /&gt;
|-&lt;br /&gt;
| number_decimal_digits || 2&lt;br /&gt;
|-&lt;br /&gt;
| number_decimal_separator || .&lt;br /&gt;
|-&lt;br /&gt;
| number_group_separator || '&lt;br /&gt;
|-&lt;br /&gt;
| positive_sign || +&lt;br /&gt;
|-&lt;br /&gt;
| negative_sign || -&lt;br /&gt;
|-&lt;br /&gt;
| negative_infinity_symbol || -Infinito&lt;br /&gt;
|-&lt;br /&gt;
| per_mille_symbol || ë&lt;br /&gt;
|-&lt;br /&gt;
| na_n_symbol || Non un numero reale&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Other information ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
&lt;br /&gt;
* ms-help://MS.NETFramework.v20.en/cpref8/html/T_System_Globalization_CultureInfo.htm (ms-help is the .NET documentation)&lt;br /&gt;
* http://msdn2.microsoft.com/en-us/library/system.globalization.cultureinfo.aspx&lt;br /&gt;
* http://msdn2.microsoft.com/en-us/library/system.globalization.compareinfo.aspx&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/dotnet_locale&amp;diff=4418</id>
		<title>Internationalization/dotnet locale</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/dotnet_locale&amp;diff=4418"/>
				<updated>2006-09-01T14:54:13Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: Style&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Internationalization]]&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
There is a class named CULTURE_INFO in &amp;quot;mscorlib&amp;quot; in EiffelStudio, which provides information about a specific culture such as:&lt;br /&gt;
* associated language&lt;br /&gt;
* sublanguage&lt;br /&gt;
* country/region&lt;br /&gt;
* calendar&lt;br /&gt;
* cultural conventions&lt;br /&gt;
&lt;br /&gt;
== Listing available locales ==&lt;br /&gt;
&lt;br /&gt;
I didn't find a function that returns all the available locale informations, I think because under .NET, they are all avaiable.&lt;br /&gt;
&lt;br /&gt;
== Checking for default locale ==&lt;br /&gt;
== Retrieving locale information ==&lt;br /&gt;
To obtain informations on a specific locale, it suffices to create an instance of CULTURE_INFO. There are basically two ways to do this:&lt;br /&gt;
&lt;br /&gt;
# Create it with the culture identifier. This identifier maps every culture/language to an integer. It is not very usefull, because I did not find a logic behind the mapping function... You can find a table on [http://msdn2.microsoft.com/en-us/library/ms172470.aspx here]&lt;br /&gt;
# Create it with the name (STRING) of the culture. The culture names follow the RFC 1766 standard in the format &amp;quot;&amp;lt;languagecode2&amp;gt;-&amp;lt;country/regioncode2&amp;gt;&amp;quot;, where &amp;lt;languagecode2&amp;gt; is a lowercase two-letter code derived from ISO 639-1 and &amp;lt;country/regioncode2&amp;gt; is an uppercase two-letter code derived from ISO 3166.&lt;br /&gt;
&lt;br /&gt;
You can find a detailed description of RFC 1766&lt;br /&gt;
&lt;br /&gt;
The CULTURE_INFO Class has some attibutes useful for the retrieving of the informations about Date, Time and Number formatting, they are:&lt;br /&gt;
&lt;br /&gt;
* date_time_format: DATE_TIME_FORMAT_INFO ([http://msdn2.microsoft.com/en-us/library/system.globalization.datetimeformatinfo.aspx see here])&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Some information that is available in DATE_TIME_FORMAT_INFO&lt;br /&gt;
! Information !! Result for locale &amp;quot;it-CH&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| full_date_time_pattern || dddd, d. MMMM yyyy HH:mm:ss&lt;br /&gt;
|-&lt;br /&gt;
| long_date_pattern || dddd, d. MMMM yyyy&lt;br /&gt;
|-&lt;br /&gt;
| long_time_pattern || HH:mm:ss&lt;br /&gt;
|-&lt;br /&gt;
| month_day_pattern || d. MMMM&lt;br /&gt;
|-&lt;br /&gt;
| rfc1123_pattern || ddd, dd MMM yyyy HH':'mm':'ss 'GMT'&lt;br /&gt;
|-&lt;br /&gt;
| pm_designator ||&lt;br /&gt;
|-&lt;br /&gt;
| short_date_pattern || dd.MM.yyyy&lt;br /&gt;
|-&lt;br /&gt;
| short_time_pattern || HH:mm&lt;br /&gt;
|-&lt;br /&gt;
| sortable_date_time_pattern || yyyy'-'MM'-'dd'T'HH':'mm':'ss&lt;br /&gt;
|-&lt;br /&gt;
| time_separator ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* there are also functions that return abbreviations of names of months and day:&lt;br /&gt;
** get_abbreviated_day_name (dayofweek: DAY_OF_WEEK) : SYSTEM_STRING&lt;br /&gt;
** get_abbreviated_month_name (month: INTEGER) : SYSTEM_STRING&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* number_format: NUMBER_FORMAT_INFO ([http://msdn2.microsoft.com/en-us/library/system.globalization.numberformatinfo.aspx see here])&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Some information that is available in NUMBER_FORMAT_INFO&lt;br /&gt;
! Information !! Result for locale &amp;quot;it-CH&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| currency_group_separator || '&lt;br /&gt;
|-&lt;br /&gt;
| currency_symbol || SFr.&lt;br /&gt;
|-&lt;br /&gt;
| currency_decimal_digits || 2&lt;br /&gt;
|-&lt;br /&gt;
| negative_sign || -&lt;br /&gt;
|-&lt;br /&gt;
| number_decimal_digits || 2&lt;br /&gt;
|-&lt;br /&gt;
| number_decimal_separator || .&lt;br /&gt;
|-&lt;br /&gt;
| number_group_separator || '&lt;br /&gt;
|-&lt;br /&gt;
| positive_sign || +&lt;br /&gt;
|-&lt;br /&gt;
| negative_sign || -&lt;br /&gt;
|-&lt;br /&gt;
| negative_infinity_symbol || -Infinito&lt;br /&gt;
|-&lt;br /&gt;
| per_mille_symbol || ë&lt;br /&gt;
|-&lt;br /&gt;
| na_n_symbol || Non un numero reale&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Other information ==&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
&lt;br /&gt;
[4] http://msdn2.microsoft.com/en-us/library/system.globalization.numberformatinfo.aspx&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
&lt;br /&gt;
* ms-help://MS.NETFramework.v20.en/cpref8/html/T_System_Globalization_CultureInfo.htm (ms-help is the .NET documentation)&lt;br /&gt;
* http://msdn2.microsoft.com/en-us/library/system.globalization.cultureinfo.aspx&lt;br /&gt;
* http://msdn2.microsoft.com/en-us/library/system.globalization.compareinfo.aspx&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/obstacles&amp;diff=3882</id>
		<title>Internationalization/obstacles</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/obstacles&amp;diff=3882"/>
				<updated>2006-06-29T17:08:49Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: small syntax fix&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Problems we encountered during implementation&lt;br /&gt;
&lt;br /&gt;
* Unicode (UTF-8) support was not fully implemented (e.g. for gtk)&lt;br /&gt;
* Facilities to write and read STRING_32 to/from files were not present&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Difficulties to complete the translation of EiffelStudio:&lt;br /&gt;
* Many strings are hard-coded anywhere inside EiffelStudio, making the translation difficult&lt;br /&gt;
* All the functions taking strings as arguments expect a STRING, where they should expect a STRING_GENERAL, and they return a STRING which may not be applicable in every case. A STRING_32 can also represent the same content of a STRING_8, thus it should be preferred.&lt;br /&gt;
* It seems that to_uppercase and to_lowercase procedures are not defined for STRING_32 and are used in the studio, these should have been implemented by the vision project and may be buggy.&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=User:Etienner&amp;diff=3866</id>
		<title>User:Etienner</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=User:Etienner&amp;diff=3866"/>
				<updated>2006-06-28T18:26:03Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Userpage of Etienne Reichenbach==&lt;br /&gt;
&lt;br /&gt;
I am involved in the following projects:&lt;br /&gt;
&lt;br /&gt;
* [[Internationalization]]&lt;br /&gt;
** [http://eiffelsoftware.origo.ethz.ch/index.php/Category:Internationalization Article list]&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization&amp;diff=3865</id>
		<title>Internationalization</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization&amp;diff=3865"/>
				<updated>2006-06-28T18:23:14Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: /* M5: July ?? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Projects]]&lt;br /&gt;
[[Category:Internationalization]]&lt;br /&gt;
[[Image:ebabylon.png|right|frame| Our Eiffel Tower of Babylon]]&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
&lt;br /&gt;
''&amp;quot;Many [people] would simply love seeing their computer screen showing a lot less of English, and far more of their own language.&amp;quot;'' -- gettext doc&lt;br /&gt;
&lt;br /&gt;
Our aim is not only to provide a framework to ease the translation of Eiffel-written applications, allowing the user to chose his/her preferred language at runtime, but also to let the developer access information and formats based on users' locale.&lt;br /&gt;
&lt;br /&gt;
==What is internationalisation?==&lt;br /&gt;
&lt;br /&gt;
The first thing that comes to mind is translation. But internationalisation isn't restricted to enabling translation: it includes making it possible to localise notations (time, date, numbers), measures, paper size, and much more.&lt;br /&gt;
&lt;br /&gt;
==What should we achieve?==&lt;br /&gt;
*Applications should be able to load localized strings at runtime and be provided with localized format strings (e.g date format).&lt;br /&gt;
*Developers can use tools that automagically extract strings from source code and can try to get them translated in a file to distribute along with the application.&lt;br /&gt;
*Users will still be unhappy and get depressed ''but in their own language'', which we can all agree is a significant step forward.&lt;br /&gt;
&lt;br /&gt;
=Milestones=&lt;br /&gt;
&lt;br /&gt;
==M2: May 5 ==&lt;br /&gt;
* [[Internationalization/feasibility|feasibility]]: look at string classes (unicode and not) and how strings are used in EiffelStudio (creation, composition) ''(Ivano, Carlo, Leo, Hong)''&lt;br /&gt;
* [[Internationalization/file_format|file format]]: compare existing file formats for dictionaries ''(Etienne, Andreas)''&lt;br /&gt;
* [[Internationalization/tool_evaluation|tool evaluation]]: list and compare existing translation tools ''(Christian, Martino)''&lt;br /&gt;
&lt;br /&gt;
==M3: June 13 ==&lt;br /&gt;
* write an initial .po to start translating and have a .mo for testing ''(Leo, Carlo)''&lt;br /&gt;
* [[Internationalization/mo parser|mo parser]]: extract translated strings from .mo files ''([[User:etienner|Etienne]], [[User:Trosim|Martino]])''&lt;br /&gt;
* [[Internationalization/translation function|translation function]]: map hard-coded strings to translated strings ''(Martino)''&lt;br /&gt;
** find a solution with templates&lt;br /&gt;
** globality: how to implement, the object should be shared between all modules (see [[Internationalization/class_structure|class structure]])&lt;br /&gt;
** find out how to use plurals (see [[Internationalization/plural_forms|plural forms]])&lt;br /&gt;
* Test unicode support in Vision2. [See test application in the [https://eiffelsoftware.origo.ethz.ch/svn/es/branches/soft-arch/Src/library/i18n/example/ SVN repository]]&lt;br /&gt;
* compile a [[Internationalization/features list|list of basic features]] to provide (e.g. date/time format, system locale) ''[deferred]''&lt;br /&gt;
&lt;br /&gt;
==M4: June 28 ==&lt;br /&gt;
* internationalization of EiffelStudio: surround strings with our functions&lt;br /&gt;
* [[Internationalization/translation|translation]] of EiffelStudio in some languages, for demo purposes (Italian, German, Chinese, ...) (see [http://slhk.ath.cx/projects/estudio/ pootle])&lt;br /&gt;
* [[Internationalization/code_parser|code parser]]: extract strings to be translated from source code and generate .pot file ''(Leo)''&lt;br /&gt;
* language selection: add an entry in the preferences system&lt;br /&gt;
* create a function to detect current environment language and settings (aka [[Internationalization/locale|locale]])&lt;br /&gt;
&lt;br /&gt;
==M5: July ?? ==&lt;br /&gt;
* Refactoring of whole library&lt;br /&gt;
* Use our library for EiffelStudio&lt;br /&gt;
* Clean up Wiki and improve Developer manual&lt;br /&gt;
&lt;br /&gt;
= Possible future developments =&lt;br /&gt;
&lt;br /&gt;
* collaborate with the [[ESWizard]] team. Create wizards for programs with translation facilities.&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
* [[Internationalization/requirements_specification|Requirements specification]]&lt;br /&gt;
* [[Internationalization/developer_manual|Developer manual]]&lt;br /&gt;
* [[Internationalization/obstacles|Obstacles]]: why can't achieve all of our goals&lt;br /&gt;
&lt;br /&gt;
= l10n: completed and on the work =&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;0&amp;quot; cellspacing=&amp;quot;3&amp;quot; cellpadding=&amp;quot;5&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
!'''Language'''&lt;br /&gt;
!'''Status'''&lt;br /&gt;
|-&lt;br /&gt;
|Arabic&lt;br /&gt;
|Active&lt;br /&gt;
|-&lt;br /&gt;
|Chinese&lt;br /&gt;
|Active&lt;br /&gt;
|-&lt;br /&gt;
|Italian&lt;br /&gt;
|Active&lt;br /&gt;
|-&lt;br /&gt;
|Rhaeto-Romanic&lt;br /&gt;
|Active - Ready for use&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Relevant Links=&lt;br /&gt;
[http://www.debian.org/doc/manuals/intro-i18n/ Introduction to i18n]&lt;br /&gt;
&lt;br /&gt;
==What other people have done==&lt;br /&gt;
[http://doc.trolltech.com/4.1/i18n.html internationalisation with QT]&lt;br /&gt;
&lt;br /&gt;
[http://oss.erdfunkstelle.de/kde-i18n/tiki-index.php?page=miniHowtoGui howto for internationalisation of KDE programs ]&lt;br /&gt;
&lt;br /&gt;
[http://l10n.kde.org/docs/translation-howto/ another KDE howto (doesn't Gnome do any internationalisation?)]&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&lt;br /&gt;
Everyone interested in this project is welcome to [http://origo.ethz.ch/cgi-bin/mailman/listinfo/es-i18n join our mailinglist] es-i18n@origo.ethz.ch&lt;br /&gt;
&lt;br /&gt;
* Project Leader: [[User:Carlo|Carlo Vanini]]&lt;br /&gt;
* [[User:leo| Leo Fellmann]]&lt;br /&gt;
* [[User:kiwi| Ivano Somaini]]&lt;br /&gt;
* [[User:murbi|Andreas Murbach]]&lt;br /&gt;
* [[User:etienner|Etienne Reichenbach]]&lt;br /&gt;
* [[User:hong |Hong Zhang]]&lt;br /&gt;
* [[User:cconti | Christian Conti]]&lt;br /&gt;
* [[User:Trosim |Martino Trosi]]&lt;br /&gt;
* [[User:Schoelle| Bernd Schoeller]]&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization&amp;diff=3863</id>
		<title>Internationalization</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization&amp;diff=3863"/>
				<updated>2006-06-28T15:25:34Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: /* Milestones */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Projects]]&lt;br /&gt;
[[Category:Internationalization]]&lt;br /&gt;
[[Image:ebabylon.png|right|frame| Our Eiffel Tower of Babylon]]&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
&lt;br /&gt;
''&amp;quot;Many [people] would simply love seeing their computer screen showing a lot less of English, and far more of their own language.&amp;quot;'' -- gettext doc&lt;br /&gt;
&lt;br /&gt;
Our aim is not only to provide a framework to ease the translation of Eiffel-written applications, allowing the user to chose his/her preferred language at runtime, but also to let the developer access information and formats based on users' locale.&lt;br /&gt;
&lt;br /&gt;
==What is internationalisation?==&lt;br /&gt;
&lt;br /&gt;
The first thing that comes to mind is translation. But internationalisation isn't restricted to enabling translation: it includes making it possible to localise notations (time, date, numbers), measures, paper size, and much more.&lt;br /&gt;
&lt;br /&gt;
==What should we achieve?==&lt;br /&gt;
*Applications should be able to load localized strings at runtime and be provided with localized format strings (e.g date format).&lt;br /&gt;
*Developers can use tools that automagically extract strings from source code and can try to get them translated in a file to distribute along with the application.&lt;br /&gt;
*Users will still be unhappy and get depressed ''but in their own language'', which we can all agree is a significant step forward.&lt;br /&gt;
&lt;br /&gt;
=Milestones=&lt;br /&gt;
&lt;br /&gt;
==M2: May 5 ==&lt;br /&gt;
* [[Internationalization/feasibility|feasibility]]: look at string classes (unicode and not) and how strings are used in EiffelStudio (creation, composition) ''(Ivano, Carlo, Leo, Hong)''&lt;br /&gt;
* [[Internationalization/file_format|file format]]: compare existing file formats for dictionaries ''(Etienne, Andreas)''&lt;br /&gt;
* [[Internationalization/tool_evaluation|tool evaluation]]: list and compare existing translation tools ''(Christian, Martino)''&lt;br /&gt;
&lt;br /&gt;
==M3: June 13 ==&lt;br /&gt;
* write an initial .po to start translating and have a .mo for testing ''(Leo, Carlo)''&lt;br /&gt;
* [[Internationalization/mo parser|mo parser]]: extract translated strings from .mo files ''([[User:etienner|Etienne]], [[User:Trosim|Martino]])''&lt;br /&gt;
* [[Internationalization/translation function|translation function]]: map hard-coded strings to translated strings ''(Martino)''&lt;br /&gt;
** find a solution with templates&lt;br /&gt;
** globality: how to implement, the object should be shared between all modules (see [[Internationalization/class_structure|class structure]])&lt;br /&gt;
** find out how to use plurals (see [[Internationalization/plural_forms|plural forms]])&lt;br /&gt;
* Test unicode support in Vision2. [See test application in the [https://eiffelsoftware.origo.ethz.ch/svn/es/branches/soft-arch/Src/library/i18n/example/ SVN repository]]&lt;br /&gt;
* compile a [[Internationalization/features list|list of basic features]] to provide (e.g. date/time format, system locale) ''[deferred]''&lt;br /&gt;
&lt;br /&gt;
==M4: June 28 ==&lt;br /&gt;
* internationalization of EiffelStudio: surround strings with our functions&lt;br /&gt;
* [[Internationalization/translation|translation]] of EiffelStudio in some languages, for demo purposes (Italian, German, Chinese, ...) (see [http://slhk.ath.cx/projects/estudio/ pootle])&lt;br /&gt;
* [[Internationalization/code_parser|code parser]]: extract strings to be translated from source code and generate .pot file ''(Leo)''&lt;br /&gt;
* language selection: add an entry in the preferences system&lt;br /&gt;
* create a function to detect current environment language and settings (aka [[Internationalization/locale|locale]])&lt;br /&gt;
&lt;br /&gt;
==M5: July ?? ==&lt;br /&gt;
* Refactoring of whole library&lt;br /&gt;
* Use our library for EiffelStudio&lt;br /&gt;
&lt;br /&gt;
= Possible future developments =&lt;br /&gt;
&lt;br /&gt;
* collaborate with the [[ESWizard]] team. Create wizards for programs with translation facilities.&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
* [[Internationalization/requirements_specification|Requirements specification]]&lt;br /&gt;
* [[Internationalization/developer_manual|Developer manual]]&lt;br /&gt;
* [[Internationalization/obstacles|Obstacles]]: why can't achieve all of our goals&lt;br /&gt;
&lt;br /&gt;
= l10n: completed and on the work =&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;0&amp;quot; cellspacing=&amp;quot;3&amp;quot; cellpadding=&amp;quot;5&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
!'''Language'''&lt;br /&gt;
!'''Status'''&lt;br /&gt;
|-&lt;br /&gt;
|Arabic&lt;br /&gt;
|Active&lt;br /&gt;
|-&lt;br /&gt;
|Chinese&lt;br /&gt;
|Active&lt;br /&gt;
|-&lt;br /&gt;
|Italian&lt;br /&gt;
|Active&lt;br /&gt;
|-&lt;br /&gt;
|Rhaeto-Romanic&lt;br /&gt;
|Active - Ready for use&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Relevant Links=&lt;br /&gt;
[http://www.debian.org/doc/manuals/intro-i18n/ Introduction to i18n]&lt;br /&gt;
&lt;br /&gt;
==What other people have done==&lt;br /&gt;
[http://doc.trolltech.com/4.1/i18n.html internationalisation with QT]&lt;br /&gt;
&lt;br /&gt;
[http://oss.erdfunkstelle.de/kde-i18n/tiki-index.php?page=miniHowtoGui howto for internationalisation of KDE programs ]&lt;br /&gt;
&lt;br /&gt;
[http://l10n.kde.org/docs/translation-howto/ another KDE howto (doesn't Gnome do any internationalisation?)]&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&lt;br /&gt;
Everyone interested in this project is welcome to [http://origo.ethz.ch/cgi-bin/mailman/listinfo/es-i18n join our mailinglist] es-i18n@origo.ethz.ch&lt;br /&gt;
&lt;br /&gt;
* Project Leader: [[User:Carlo|Carlo Vanini]]&lt;br /&gt;
* [[User:leo| Leo Fellmann]]&lt;br /&gt;
* [[User:kiwi| Ivano Somaini]]&lt;br /&gt;
* [[User:murbi|Andreas Murbach]]&lt;br /&gt;
* [[User:etienner|Etienne Reichenbach]]&lt;br /&gt;
* [[User:hong |Hong Zhang]]&lt;br /&gt;
* [[User:cconti | Christian Conti]]&lt;br /&gt;
* [[User:Trosim |Martino Trosi]]&lt;br /&gt;
* [[User:Schoelle| Bernd Schoeller]]&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/developer_manual&amp;diff=3790</id>
		<title>Internationalization/developer manual</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/developer_manual&amp;diff=3790"/>
				<updated>2006-06-26T05:53:40Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: /* Translating with templates */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Internationalization]]&lt;br /&gt;
&lt;br /&gt;
= How to design the software =&lt;br /&gt;
There is only a few things which can help you using our library, the most important one is dividing completely the logic of the program from the content.&lt;br /&gt;
In other words, you should write a class which contains all the strings you use in the program; so applying out system will be very easy.&lt;br /&gt;
&lt;br /&gt;
= How to use the library =&lt;br /&gt;
&lt;br /&gt;
Here you can find instructions on how to use our library; how to initialize the system and how to make the translations actually appear in your application.&lt;br /&gt;
&lt;br /&gt;
== Initialization ==&lt;br /&gt;
&lt;br /&gt;
To initialize the library you should have a class that inherits from the SHARED_I18N_LOCALIZATOR; this will bring you all the necessary infrastructure to start localizing your software.&lt;br /&gt;
&lt;br /&gt;
What to do?&lt;br /&gt;
* create datasource&lt;br /&gt;
* create datastructure&lt;br /&gt;
* load localizator&lt;br /&gt;
&lt;br /&gt;
=== Creating a datasource ===&lt;br /&gt;
&lt;br /&gt;
We equip you with a simple factory to create the sources, simply create an I18N_DATASOURCE_FACTORY&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
datasource_factory: I18N_DATASOURCE_FACTORY&lt;br /&gt;
&lt;br /&gt;
create datasource_factory.make&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you now have the possibility to create a new source based on an mo file, as follows&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
datasource: I18N_DATASOURCE&lt;br /&gt;
&lt;br /&gt;
datasource_factory.use_mo_file(mo_file_path)&lt;br /&gt;
if datasource_factory.last_datasource /= Void then&lt;br /&gt;
  datasource := datasource_factory.last_datasource&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if something went wrong, you can alway fallback with an empty datasource&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
datasource_factory.use_empty_source&lt;br /&gt;
datasource := datasource_factory.last_datasource&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The datasource is ready, you should create a datastructure for storing the strings.&lt;br /&gt;
&lt;br /&gt;
=== Creating a datastructure ===&lt;br /&gt;
&lt;br /&gt;
We provide you with a simple factory to create datastructures, so follow the example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
datastructure_factory: I18N_DATASTRUCTURE_FACTORY&lt;br /&gt;
&lt;br /&gt;
create datastructure_factory.make&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can now create, for example, an hash table&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
datastructure: I18N_DATASTRUCTURE&lt;br /&gt;
&lt;br /&gt;
datastructure_factory.use_hash_table&lt;br /&gt;
if datastructure_factory.last_datastructure /= Void then&lt;br /&gt;
  datastructure := datastructure_factory.last_datastructure&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and, even in this case, if something went wrong, you can create a dummy datastructure&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
datastructure_factory.use_dummy&lt;br /&gt;
datastructure := datastructure_factory.last_datastructure&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that you have the datastructure ready, you can load the localizator.&lt;br /&gt;
&lt;br /&gt;
=== Loading the localizator ===&lt;br /&gt;
&lt;br /&gt;
It's important that you do this part before trying to localize any string, if not, the localizator would serve you what you pass as argument.&lt;br /&gt;
&lt;br /&gt;
Pass the source to the localizator&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
i18n_use_datasource(datasource)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
then pass the datastructure&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
i18n_use_datastructure(datastructure)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and finally load the localizator with the new source and structure&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
i18n_load&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You now have a working localization environment!&lt;br /&gt;
&lt;br /&gt;
{{Warning|If you don't assign a source AND a structure AND then call load, the system will continue to use the old ones.}}&lt;br /&gt;
&lt;br /&gt;
== Localization ==&lt;br /&gt;
&lt;br /&gt;
Here you can find some instructions to translate the strings of you program, including substituting variables into templates.&lt;br /&gt;
&lt;br /&gt;
=== Translating simple strings ===&lt;br /&gt;
&lt;br /&gt;
If you have a simple string to translate, like this&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
simple_string: STRING&lt;br /&gt;
&lt;br /&gt;
simple_string := &amp;quot;A simple string&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you only have to enclose the string by the simple i18n() function&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
simple_string := i18n(&amp;quot;A simple string&amp;quot;)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the system will then be charged of the translation in whatever language you've chosen.&lt;br /&gt;
&lt;br /&gt;
=== Translating plurals ===&lt;br /&gt;
&lt;br /&gt;
Sometimes you must change the translated string in relation with a variable; this piece of code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
string: STRING&lt;br /&gt;
i: INTEGER&lt;br /&gt;
&lt;br /&gt;
if i = 1 then&lt;br /&gt;
  string := &amp;quot;There is 1 file&amp;quot;&lt;br /&gt;
else&lt;br /&gt;
  string := &amp;quot;There are more files&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will be written as follows using our system&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
string := i18n_pl(&amp;quot;There is 1 file&amp;quot;, &amp;quot;There are more files&amp;quot;, i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the right form will be selected and displayed for you.&lt;br /&gt;
&lt;br /&gt;
=== Translating with templates ===&lt;br /&gt;
&lt;br /&gt;
{{Warning|We encourage you to use a stand alone template engine and not rely on our built-in functions, which will not be maintained.}}&lt;br /&gt;
&lt;br /&gt;
You can use our library to translate something like this&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
string := &amp;quot;Number &amp;quot; + i.out&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in this way&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
string := i18n_comp(&amp;quot;Number $1&amp;quot;, [i])&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and of course you can do the same with the plural forms&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
if i = 1 then&lt;br /&gt;
  string := &amp;quot;There is 1 file&amp;quot;&lt;br /&gt;
else&lt;br /&gt;
  string := &amp;quot;There are &amp;quot; + i.out + &amp;quot; files&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
would look like this&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
string := i18n_comp_pl(&amp;quot;There is 1 file&amp;quot;, &amp;quot;There are $1 files&amp;quot;, [i], i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
we've so covered all the possibilities.&lt;br /&gt;
&lt;br /&gt;
= How to translate / use translation files =&lt;br /&gt;
&lt;br /&gt;
== Editing PO files == &lt;br /&gt;
&lt;br /&gt;
You can edit the PO files created with your preferred editor; some possible tools are listed [[Internationalization/tool_evaluation|here]].&lt;br /&gt;
&lt;br /&gt;
== Issues with MO files ==&lt;br /&gt;
&lt;br /&gt;
Into the header section of the PO file must be present the &amp;quot;Plural-Forms&amp;quot; header.&lt;br /&gt;
&lt;br /&gt;
It looks like this line:&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Plural-Forms: nplurals=2; plural=(n!=1);&amp;quot;&lt;br /&gt;
&lt;br /&gt;
with &amp;quot;nplural&amp;quot; being the number of plurals of the destination language and &amp;quot;plural&amp;quot; the C-like function for finding the right plural form starting with an integer.&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/locale&amp;diff=3765</id>
		<title>Internationalization/locale</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/locale&amp;diff=3765"/>
				<updated>2006-06-25T06:34:50Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: /* Linux */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Internationalization]]&lt;br /&gt;
&lt;br /&gt;
In computing, locale is a set of parameters that defines the user's language, country and any special variant preferences that the user wants to see in their user interface.&lt;br /&gt;
&lt;br /&gt;
== Format of locale on OS's ==&lt;br /&gt;
* windows (for unmanaged code): hexadecimal code consisting of a language code (lower 10 bits) and culture code (upper bits), aka Locale Identifier (LCID)&lt;br /&gt;
* linux, unix: defined as [language[_territory][.codeset][@modifier]]&lt;br /&gt;
&lt;br /&gt;
== Where to find locale ==&lt;br /&gt;
=== Linux ===&lt;br /&gt;
the environment variable is LANG&lt;br /&gt;
&lt;br /&gt;
here is a list for more specific variables:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;0&amp;quot; cellspacing=&amp;quot;3&amp;quot; cellpadding=&amp;quot;5&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! '''Locale category'''&lt;br /&gt;
! '''Application'''&lt;br /&gt;
|-&lt;br /&gt;
|LC_COLLATE&lt;br /&gt;
|Collation of strings (sort order.)&lt;br /&gt;
|-&lt;br /&gt;
|LC_CTYPE&lt;br /&gt;
|Classification and conversion of characters.&lt;br /&gt;
|-&lt;br /&gt;
|LC_MESSAGES&lt;br /&gt;
|Translations of yes and no.&lt;br /&gt;
|-&lt;br /&gt;
|LC_MONETARY&lt;br /&gt;
|Format of monetary values.&lt;br /&gt;
|-&lt;br /&gt;
|LC_NUMERIC&lt;br /&gt;
|Format of non-monetary numeric values. &lt;br /&gt;
|-&lt;br /&gt;
|LC_TIME&lt;br /&gt;
|Date and time formats.&lt;br /&gt;
|-&lt;br /&gt;
|LC_ALL&lt;br /&gt;
|Sets all of the above (overrides all of them.)&lt;br /&gt;
|-&lt;br /&gt;
|LANG&lt;br /&gt;
|Sets all the categories, but can be overridden by the individual locale categories.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Windows ===&lt;br /&gt;
The LCID for &amp;quot;Language for non-Unicode programs&amp;quot; (aka system locale) can be found in the windows registry.&amp;lt;br&amp;gt;&lt;br /&gt;
The LCID of &amp;quot;standards and formats&amp;quot; (aka user locale) doesn't seem to be in the registry nor in the environment variables of windows.&lt;br /&gt;
&lt;br /&gt;
== How to access to locale ==&lt;br /&gt;
=== Linux ===&lt;br /&gt;
The function &amp;quot;get&amp;quot; that fetches the language environment variable (LANG) can be found in class EXECUTION_ENVIRONMENT&lt;br /&gt;
&lt;br /&gt;
SHARED_EXEC_ENVIRONMENT: located [https://eiffelsoftware.origo.ethz.ch/svn/es/branches/soft-arch/Src/Eiffel/eiffel/shared/shared_exec_environment.e here]&lt;br /&gt;
&lt;br /&gt;
=== Windows ===&lt;br /&gt;
In Eiffel there exist a &amp;quot;locale_id&amp;quot; in class WEL_COMPARE_ITEM_STRUCT that uses the macro MAKELCID to get the locale identifier (aka LCID) from the language id.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two solutions:&amp;lt;br&amp;gt;&lt;br /&gt;
* Find out how to get the language id&lt;br /&gt;
* Use the locale id (convenient if SortID is needed)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Notes:&amp;lt;br&amp;gt;&lt;br /&gt;
Locale id is formed by SortID and LanguageID.&amp;lt;br&amp;gt;&lt;br /&gt;
SortID contains info on the language encoding (?) like japanese unicode order, japanese XJIS order, chinese unicode order, chinese BIG5 order,...&amp;lt;br&amp;gt;&lt;br /&gt;
Macros for windows are contained in &amp;quot;windows.h&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Found the macro needed: GetUserDefaultLCID()'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The code should then look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
language_id: NATURAL_32 is&lt;br /&gt;
	external&lt;br /&gt;
		&amp;quot;C inline use &amp;lt;windows.h&amp;gt;&amp;quot;&lt;br /&gt;
	alias&lt;br /&gt;
		&amp;quot;return GetUserDefaultLCID();&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== OS detection ==&lt;br /&gt;
Queries for OS detection cam be found in class PLATFORM&lt;br /&gt;
&lt;br /&gt;
== References and useful links ==&lt;br /&gt;
* [http://www-950.ibm.com/software/globalization/icu/demo/locales info] about what's contained in a locale (language codes, time format,...)&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Date_and_time_notation_by_country date and time notations]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Locale Locale on wikipedia]&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/locale&amp;diff=3594</id>
		<title>Internationalization/locale</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/locale&amp;diff=3594"/>
				<updated>2006-06-19T10:51:10Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: Category&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Internationalization]]&lt;br /&gt;
&lt;br /&gt;
== Definition (from wikipedia: [http://en.wikipedia.org/wiki/Locale Locale])==&lt;br /&gt;
In computing, locale is a set of parameters that defines the user's language, country and any special variant preferences that the user wants to see in their user interface.&lt;br /&gt;
&lt;br /&gt;
== Format of locale on OS's (from wikipedia: [http://en.wikipedia.org/wiki/Locale Locale]) ==&lt;br /&gt;
* windows (for unmanaged code): hexadecimal code consisting of a language code (lower 10 bits) and culture code (upper bits), aka Locale Identifier (LCID)&lt;br /&gt;
* linux, unix: defined as [language[_territory][.codeset][@modifier]]&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
* [http://www-950.ibm.com/software/globalization/icu/demo/locales info] about what's contained in a locale (language codes, time format,...)&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Date_and_time_notation_by_country date and time notations]&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=User:Etienner&amp;diff=3316</id>
		<title>User:Etienner</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=User:Etienner&amp;diff=3316"/>
				<updated>2006-06-11T16:00:13Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I am involved in the following projects:&lt;br /&gt;
&lt;br /&gt;
* [[Internationalization]]&lt;br /&gt;
:* [http://eiffelsoftware.origo.ethz.ch/index.php/Category:Internationalization Article list]&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/translation&amp;diff=3283</id>
		<title>Internationalization/translation</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/translation&amp;diff=3283"/>
				<updated>2006-06-09T11:53:04Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Internationalization]]&lt;br /&gt;
&lt;br /&gt;
The translation of EiffelStudio is going on [http://slhk.ath.cx/projects/estudio/ here].&lt;br /&gt;
&lt;br /&gt;
EiffelStudio contains many sectorial terms, wich may have a corresponding expression in other languages but their meaning may not be clear enough to the end user.&lt;br /&gt;
&lt;br /&gt;
This page is intended for discussion on terms difficult to translate.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ancestor&lt;br /&gt;
* it:Antenato&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Callers&lt;br /&gt;
* it: chiamanti&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Parent&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Put Handle Left&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Step Out&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Suppliers&lt;br /&gt;
* it: contribuenti&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Toggle visibility&lt;br /&gt;
* it: Mostra/nascondi ''[used]''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Wizard&lt;br /&gt;
* it: Procedura guidata ''[used]'', wizard ''[used in menu]''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Following words are left unchanged&lt;br /&gt;
* it: file, inheritance, overflow, stack, feature, routine&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization&amp;diff=3279</id>
		<title>Internationalization</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization&amp;diff=3279"/>
				<updated>2006-06-09T05:41:46Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Projects]]&lt;br /&gt;
[[Category:Internationalization]]&lt;br /&gt;
[[Image:ebabylon.png|right|frame| Our Eiffel Tower of Babylon]]&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
&lt;br /&gt;
''&amp;quot;Many [people] would simply love seeing their computer screen showing a lot less of English, and far more of their own language.&amp;quot;'' -- gettext doc&lt;br /&gt;
&lt;br /&gt;
Our aim is not only to provide a framework to ease the translation of Eiffel-written applications, allowing the user to chose his/her preferred language at runtime, but also to let the developer access information and formats based on users' locale.&lt;br /&gt;
&lt;br /&gt;
==What is internationalisation?==&lt;br /&gt;
&lt;br /&gt;
The first thing that comes to mind is translation. But internationalisation isn't restricted to enabling translation: it includes making it possible to localise notations (time, date, numbers), measures, paper size, and much more.&lt;br /&gt;
&lt;br /&gt;
==What should we achieve?==&lt;br /&gt;
*Applications should be able to load localized strings at runtime and be provided with localized format strings (e.g date format).&lt;br /&gt;
*Developers can use tools that automagically extract strings from source code and can try to get them translated in a file to distribute along with the application.&lt;br /&gt;
*Users will still be unhappy and get depressed ''but in their own language'', which we can all agree is a significant step forward.&lt;br /&gt;
&lt;br /&gt;
=Milestones=&lt;br /&gt;
&lt;br /&gt;
==M2: May 5 ==&lt;br /&gt;
* [[Internationalization/feasibility|feasibility]]: look at string classes (unicode and not) and how strings are used in EiffelStudio (creation, composition) ''(Ivano, Carlo, Leo, Hong)''&lt;br /&gt;
* [[Internationalization/file_format|file format]]: compare existing file formats for dictionaries ''(Etienne, Andreas)''&lt;br /&gt;
* [[Internationalization/tool_evaluation|tool evaluation]]: list and compare existing translation tools ''(Christian, Martino)''&lt;br /&gt;
&lt;br /&gt;
==M3: June 13 ==&lt;br /&gt;
* write an initial .po to start translating and have a .mo for testing ''(Leo, Carlo)''&lt;br /&gt;
* [[Internationalization/mo parser|mo parser]]: extract translated strings from .mo files ''([[User:etienner|Etienne]], [[User:Trosim|Martino]])''&lt;br /&gt;
* [[Internationalization/translation function|translation function]]: map hard-coded strings to translated strings ''(Martino)''&lt;br /&gt;
** find a solution with templates&lt;br /&gt;
** globality: how to implement, the object should be shared between all modules (see [[Internationalization/class_structure|class structure]])&lt;br /&gt;
** find out how to use plurals (see [[Internationalization/plural_forms|plural forms]])&lt;br /&gt;
* Test unicode support in Vision2. [See test application in the [https://eiffelsoftware.origo.ethz.ch/svn/es/branches/soft-arch/Src/library/i18n/example/ SVN repository]]&lt;br /&gt;
* [[Internationalization/code_parser|code parser]]: extract strings to be translated from source code and generate .po file ''(Leo)'' ''[deferred]''&lt;br /&gt;
* compile a [[Internationalization/features list|list of basic features]] to provide (e.g. date/time format, system locale) ''[deferred]''&lt;br /&gt;
&lt;br /&gt;
==M4: June ??? ==&lt;br /&gt;
* internationalization of EiffelStudio: surround strings with our functions&lt;br /&gt;
* translation of EiffelStudio in some languages, for demo purposes (Italian, German, Chinese, ...) (see [http://slhk.ath.cx/projects/estudio/ pootle])&lt;br /&gt;
* [[Internationalization/code_parser|code parser]]: extract strings to be translated from source code and generate .pot file ''(Leo)''&lt;br /&gt;
* language selection: add an entry in the preferences system&lt;br /&gt;
&lt;br /&gt;
= Possible future developments =&lt;br /&gt;
&lt;br /&gt;
* collaborate with the [[ESWizard]] team. Create wizards for programms with translation facilities.&lt;br /&gt;
&lt;br /&gt;
=Relevant Links=&lt;br /&gt;
[http://www.debian.org/doc/manuals/intro-i18n/ Introduction to i18n]&lt;br /&gt;
&lt;br /&gt;
==What other people have done==&lt;br /&gt;
[http://doc.trolltech.com/4.1/i18n.html internationalisation with QT]&lt;br /&gt;
&lt;br /&gt;
[http://oss.erdfunkstelle.de/kde-i18n/tiki-index.php?page=miniHowtoGui howto for internationalisation of KDE programs ]&lt;br /&gt;
&lt;br /&gt;
[http://l10n.kde.org/docs/translation-howto/ another KDE howto (doesn't Gnome do any internationalisation?)]&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&lt;br /&gt;
Everyone interested in this project is welcome to [http://origo.ethz.ch/cgi-bin/mailman/listinfo/es-i18n join our mailinglist] es-i18n@origo.ethz.ch&lt;br /&gt;
&lt;br /&gt;
* Project Leader: [[User:Carlo|Carlo Vanini]]&lt;br /&gt;
* [[User:leo| Leo Fellmann]]&lt;br /&gt;
* [[User:kiwi| Ivano Somaini]]&lt;br /&gt;
* [[User:murbi|Andreas Murbach]]&lt;br /&gt;
* [[User:etienner|Etienne Reichenbach]]&lt;br /&gt;
* [[User:hong |Hong Zhang]]&lt;br /&gt;
* [[User:cconti | Christian Conti]]&lt;br /&gt;
* [[User:Trosim |Martino Trosi]]&lt;br /&gt;
* [[User:Schoelle| Bernd Schoeller]]&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization&amp;diff=3236</id>
		<title>Internationalization</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization&amp;diff=3236"/>
				<updated>2006-06-07T18:57:28Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: /* M3: June ??? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Projects]]&lt;br /&gt;
[[Category:Internationalization]]&lt;br /&gt;
[[Image:ebabylon.png|right|frame| Our Eiffel Tower of Babylon]]&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
&lt;br /&gt;
''&amp;quot;Many [people] would simply love seeing their computer screen showing a lot less of English, and far more of their own language.&amp;quot;'' -- gettext doc&lt;br /&gt;
&lt;br /&gt;
Our aim is not only to provide a framework to ease the translation of Eiffel-written applications, allowing the user to chose his/her preferred language at runtime, but also to let the developer access information and formats based on users' locale.&lt;br /&gt;
&lt;br /&gt;
==What is internationalisation?==&lt;br /&gt;
&lt;br /&gt;
The first thing that comes to mind is translation. But internationalisation isn't restricted to enabling translation: it includes making it possible to localise notations (time, date, numbers), measures, paper size, and much more.&lt;br /&gt;
&lt;br /&gt;
==What should we achieve?==&lt;br /&gt;
*Applications should be able to load localized strings at runtime and be provided with localized format strings (e.g date format).&lt;br /&gt;
*Developers can use tools that automagically extract strings from source code and can try to get them translated in a file to distribute along with the application.&lt;br /&gt;
*Users will still be unhappy and get depressed ''but in their own language'', which we can all agree is a significant step forward.&lt;br /&gt;
&lt;br /&gt;
==Who should do the achieving?==&lt;br /&gt;
It is clear that our [[User:Carlo|Glorious Leader]] should be credited with any achieving. However he will have to delegate things somewhat, as he is is not [http://en.wikipedia.org/wiki/Aleksei_Grigorievich_Stakhanov Stakhanov].&lt;br /&gt;
We can probably divide the project into the following parts, modulo preliminary research:&lt;br /&gt;
&lt;br /&gt;
''This should be probably be completed after we have got past M1''&lt;br /&gt;
&lt;br /&gt;
=Milestones=&lt;br /&gt;
&lt;br /&gt;
==M2: May 5 ==&lt;br /&gt;
* [[Internationalization/feasibility|feasibility]]: look at string classes (unicode and not) and how strings are used in EiffelStudio (creation, composition) ''(Ivano, Carlo, Leo, Hong)''&lt;br /&gt;
* [[Internationalization/file_format|file format]]: compare existing file formats for dictionaries ''(Etienne, Andreas)''&lt;br /&gt;
* [[Internationalization/tool_evaluation|tool evaluation]]: list and compare existing translation tools ''(Christian, Martino)''&lt;br /&gt;
&lt;br /&gt;
==M3: June ??? ==&lt;br /&gt;
* write an initial .po to start translating and have a .mo for testing ''(Leo, Carlo)''&lt;br /&gt;
* [[Internationalization/mo parser|mo parser]]: extract translated strings from .mo files ''([[User:etienner|Etienne]], [[User:Trosim|Martino]])''&lt;br /&gt;
* [[Internationalization/code_parser|code parser]]: extract strings to be translated from source code and generate .po file&lt;br /&gt;
* [[Internationalization/translation function|translation function]]: map hard-coded strings to translated strings ''(Martino)''&lt;br /&gt;
** find a solution with templates&lt;br /&gt;
** globality: how to implement, the object should be shared between all modules (see [[Internationalization/class_structure|class structure]])&lt;br /&gt;
** find out how to use plurals (see [[Internationalization/plural_forms|plural forms]])&lt;br /&gt;
* collaborate with the [[Vision2_and_Unicode]] team&lt;br /&gt;
* Test unicode support in Vision2. [See test application in the [https://eiffelsoftware.origo.ethz.ch/svn/es/branches/soft-arch/Src/library/i18n/example/ SVN repository]]&lt;br /&gt;
* compile a [[Internationalization/features list|list of basic features]] to provide (e.g. date/time format, system locale) ''[deferred]''&lt;br /&gt;
&lt;br /&gt;
= Possible future developments =&lt;br /&gt;
&lt;br /&gt;
* collaborate with the [[ESWizard]] team. Create wizards for programms with translation facilities.&lt;br /&gt;
&lt;br /&gt;
=Relevant Links=&lt;br /&gt;
[http://www.debian.org/doc/manuals/intro-i18n/ Introduction to i18n]&lt;br /&gt;
&lt;br /&gt;
==What other people have done==&lt;br /&gt;
[http://doc.trolltech.com/4.1/i18n.html internationalisation with QT]&lt;br /&gt;
&lt;br /&gt;
[http://oss.erdfunkstelle.de/kde-i18n/tiki-index.php?page=miniHowtoGui howto for internationalisation of KDE programs ]&lt;br /&gt;
&lt;br /&gt;
[http://l10n.kde.org/docs/translation-howto/ another KDE howto (doesn't Gnome do any internationalisation?)]&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&lt;br /&gt;
Everyone interested in this project is welcome to [http://origo.ethz.ch/cgi-bin/mailman/listinfo/es-i18n join our mailinglist] es-i18n@origo.ethz.ch&lt;br /&gt;
&lt;br /&gt;
* Project Leader: [[User:Carlo|Carlo Vanini]]&lt;br /&gt;
* [[User:leo| Leo Fellmann]]&lt;br /&gt;
* [[User:kiwi| Ivano Somaini]]&lt;br /&gt;
* [[User:murbi|Andreas Murbach]]&lt;br /&gt;
* [[User:etienner|Etienne Reichenbach]]&lt;br /&gt;
* [[User:hong |Hong Zhang]]&lt;br /&gt;
* [[User:cconti | Christian Conti]]&lt;br /&gt;
* [[User:Trosim |Martino Trosi]]&lt;br /&gt;
* [[User:Schoelle| Bernd Schoeller]]&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/code_parser&amp;diff=3155</id>
		<title>Internationalization/code parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/code_parser&amp;diff=3155"/>
				<updated>2006-06-03T06:14:02Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Internationalization]]&lt;br /&gt;
&lt;br /&gt;
page moved to [[Internationalization/mo parser|mo parser]] because content didn't match title. --[[User:Carlo|Carlo]] 18:23, 7 May 2006 (CEST)&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/file_format&amp;diff=3154</id>
		<title>Internationalization/file format</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/file_format&amp;diff=3154"/>
				<updated>2006-06-03T06:13:44Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Internationalization]]&lt;br /&gt;
&lt;br /&gt;
==Summary==&lt;br /&gt;
&lt;br /&gt;
Here [[Internationalization|we]] evaluate various file formats used for the translation of programs. For the moment we are considering:&lt;br /&gt;
&lt;br /&gt;
* XML&lt;br /&gt;
* po&lt;br /&gt;
* [http://transolution.python-hosting.com xliff] (good description in this homepage)&lt;br /&gt;
* create an own format&lt;br /&gt;
&lt;br /&gt;
==PO Files==&lt;br /&gt;
&lt;br /&gt;
===Format of PO files===&lt;br /&gt;
&lt;br /&gt;
A PO file has an entry for each string that has to be translated. There are two kind of them, a &amp;quot;normal&amp;quot; one and one that involves plural forms.&lt;br /&gt;
&lt;br /&gt;
====Normal entry====&lt;br /&gt;
&lt;br /&gt;
Here is the general structure of a &amp;quot;normal&amp;quot; entry:&lt;br /&gt;
&lt;br /&gt;
 white-space&lt;br /&gt;
 #  translator-comments&lt;br /&gt;
 #. automatic-comments&lt;br /&gt;
 #: reference...&lt;br /&gt;
 #, flag...&lt;br /&gt;
 msgid untranslated-string&lt;br /&gt;
 msgstr translated-string&lt;br /&gt;
&lt;br /&gt;
Where the ''translator-comments'' are created and maintained exclusively by the translator, this comments have some white space immediately following the #. The other comments are created by the program that created the PO file.&lt;br /&gt;
After the special comment &amp;quot;#,&amp;quot; there can be some ''flags'', as ''fuzzy'' shows that the msgstr string might not be a correct translation, i.e. the translator is not sure of his work.&lt;br /&gt;
The 'untranslated-string' is the untranslated string as it appears in the original program source. The ''translated-string'' is (as the name suggests) the translated string, if there is no translation it is an empty string.&lt;br /&gt;
&lt;br /&gt;
====Plural form entry====&lt;br /&gt;
&lt;br /&gt;
 white-space&lt;br /&gt;
 #  translator-comments&lt;br /&gt;
 #. automatic-comments&lt;br /&gt;
 #: reference...&lt;br /&gt;
 #, flag...&lt;br /&gt;
 msgid untranslated-string-singular&lt;br /&gt;
 msgid_plural untranslated-string-plural&lt;br /&gt;
 msgstr[0] translated-string-case-0&lt;br /&gt;
 ...&lt;br /&gt;
 msgstr[N] translated-string-case-n&lt;br /&gt;
&lt;br /&gt;
===Supported character encodings===&lt;br /&gt;
&lt;br /&gt;
character encodings that can be used are limited to those supported by both GNU libc and GNU libiconv. These are: ASCII, ISO-8859-1, ISO-8859-2, ISO-8859-3, ISO-8859-4, ISO-8859-5, ISO-8859-6, ISO-8859-7, ISO-8859-8, ISO-8859-9, ISO-8859-13, ISO-8859-15, KOI8-R, KOI8-U, CP850, CP866, CP874, CP932, CP949, CP950, CP1250, CP1251, CP1252, CP1253, CP1254, CP1255, CP1256, CP1257, GB2312, EUC-JP, EUC-KR, EUC-TW, BIG5, BIG5-HKSCS, GBK, GB18030, SHIFT_JIS, JOHAB, TIS-620, VISCII, UTF-8.&lt;br /&gt;
&lt;br /&gt;
I think they are a lot...&lt;br /&gt;
&lt;br /&gt;
===Po Editors===&lt;br /&gt;
&lt;br /&gt;
* poEdit&lt;br /&gt;
* KBabel&lt;br /&gt;
* Gtranslator&lt;br /&gt;
* LocFactoryEditor (XLIFF and PO editor for Mac OSX)&lt;br /&gt;
&lt;br /&gt;
===Positive aspects===&lt;br /&gt;
&lt;br /&gt;
* Powerful plural handling&lt;br /&gt;
* Format created for translation purpose&lt;br /&gt;
* Easy for humans to read&lt;br /&gt;
* Used by gettext, kbabel, rosetta and many other programs&lt;br /&gt;
* Support and elaboration tools for almost all plattforms&lt;br /&gt;
&lt;br /&gt;
===Negative aspects===&lt;br /&gt;
&lt;br /&gt;
* We have to write a PO parser&lt;br /&gt;
&lt;br /&gt;
==XML==&lt;br /&gt;
&lt;br /&gt;
===Format of XML===&lt;br /&gt;
&lt;br /&gt;
XML is used for example by Trolltech for their .ts files. Here an example of .ts file, generated my lupdate (a tool made by trolltech that extracts translatable text from the C++ source code of the Qt application, see [[Internationalization/tool evaluation|here]] for further information):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;!DOCTYPE TS&amp;gt;&amp;lt;TS&amp;gt;&lt;br /&gt;
     &amp;lt;context&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;MyExample&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;message&amp;gt;&lt;br /&gt;
             &amp;lt;source&amp;gt;i18n=Internationalization&amp;lt;/source&amp;gt;&lt;br /&gt;
             &amp;lt;translation type=&amp;quot;unfinished&amp;quot;&amp;gt;&amp;lt;/translation&amp;gt;&lt;br /&gt;
         &amp;lt;/message&amp;gt;&lt;br /&gt;
     &amp;lt;/context&amp;gt;&lt;br /&gt;
 &amp;lt;/TS&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And after the translation (for example with Qt Linguist) it would look like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;!DOCTYPE TS&amp;gt;&amp;lt;TS&amp;gt;&lt;br /&gt;
     &amp;lt;context&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;MyExample&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;message&amp;gt;&lt;br /&gt;
             &amp;lt;source&amp;gt;i18n=Internationalization&amp;lt;/source&amp;gt;&lt;br /&gt;
             &amp;lt;translation&amp;gt;i20e=Internazionalizzazione&amp;lt;/translation&amp;gt;&lt;br /&gt;
         &amp;lt;/message&amp;gt;&lt;br /&gt;
     &amp;lt;/context&amp;gt;&lt;br /&gt;
 &amp;lt;/TS&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Positive aspects===&lt;br /&gt;
&lt;br /&gt;
* full support for unicode character encodings&lt;br /&gt;
* There is already a parser in the EiffelBase&lt;br /&gt;
* In trolltech's opinion it's a human readable text&lt;br /&gt;
&lt;br /&gt;
===Negative aspects===&lt;br /&gt;
&lt;br /&gt;
* Not everybody knows it&lt;br /&gt;
* Microsoft seeks XML-related patents that could restrict the use of XML (there should be a &amp;quot;Very negative aspect&amp;quot; section)&lt;br /&gt;
:Thank you for that link, but the Microsoft Patents apply only on the Office dialect of XML, which it uses to save its own documents... they DON'T apply to the XML standard and general use (as we would create our format). [[User:Trosim|Trosim]]&lt;br /&gt;
* In my opinion it's not a human readable text (Fortunately not all human beings are Computer scientists)&lt;br /&gt;
&lt;br /&gt;
==New Format==&lt;br /&gt;
&lt;br /&gt;
===Format of our Format===&lt;br /&gt;
&lt;br /&gt;
* It doesn't exist yet, so we don't know how it looks like.&lt;br /&gt;
* We could give our own extension to the file format for example .et (eiffel translation) or .babe (babylon eiffel) or .eint (eiffel i18n) ... (''huge'' advantage)&lt;br /&gt;
&lt;br /&gt;
===Positive aspects===&lt;br /&gt;
&lt;br /&gt;
* Free to do what we want&lt;br /&gt;
* We don't have to care about licenses&lt;br /&gt;
* Possibility to make it the best human readable format&lt;br /&gt;
* So that we can say that we invented a new file format&lt;br /&gt;
* Better integrated and consistent with eiffel syntax&lt;br /&gt;
&lt;br /&gt;
===Negative aspects===&lt;br /&gt;
&lt;br /&gt;
* A new format? Why should we be different?&lt;br /&gt;
* Do more work as needed (there are already good formats)&lt;br /&gt;
* Long time until it becomes famous&lt;br /&gt;
&lt;br /&gt;
==Conclusions==&lt;br /&gt;
&lt;br /&gt;
Our decision is to use the po file format.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
* [http://www.gnu.org/software/gettext/manual/html_mono/gettext.html Gettext manual (for PO files)]&lt;br /&gt;
* [http://librarian.launchpad.net/2395419/it.po Example of a PO file (from rosetta)]&lt;br /&gt;
* [http://news.com.com/2100-1013_3-5146581.html Microsoft and XML]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/XML#Quick_syntax_tour XML syntax description on Wikipedia]&lt;br /&gt;
* [http://doc.trolltech.com/4.1/i18n.html Trolltech i18n]&lt;br /&gt;
* [http://translate.sourceforge.net/wiki/ open source i18n and l10n project]&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/mo_parser&amp;diff=3153</id>
		<title>Internationalization/mo parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/mo_parser&amp;diff=3153"/>
				<updated>2006-06-03T06:13:23Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Internationalization]]&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
That's what this part of the project should achieve:&lt;br /&gt;
* reading and parsing of MO files containing the strings and their translations&lt;br /&gt;
* organize the object collection in an incremental way: don't load the whole file if it's not needed&lt;br /&gt;
* give a simple interface to the localization class, so that the strings can be printed out without too much efforts&lt;br /&gt;
&lt;br /&gt;
==What is a mo file==&lt;br /&gt;
&lt;br /&gt;
MO stands for '''M'''achine '''O'''bject, as the name suggests, they are meant to be read by programs, and are binary in nature. The GNU program that creates them out of a PO file, is [http://www.scit.wlv.ac.uk/cgi-bin/mansec?1+msgfmt ''msgfmt''].&lt;br /&gt;
&lt;br /&gt;
== Reading and parsing ==&lt;br /&gt;
&lt;br /&gt;
=== Parser structure ===&lt;br /&gt;
&lt;br /&gt;
I'll propose the class structure of the parser, later.&lt;br /&gt;
&lt;br /&gt;
=== MO file structure ===&lt;br /&gt;
&lt;br /&gt;
As reported from the [http://www.gnu.org/software/gettext/manual/html_mono/gettext.html#SEC136 gettext manual].&lt;br /&gt;
&lt;br /&gt;
           byte&lt;br /&gt;
                +------------------------------------------+&lt;br /&gt;
             0  | magic number = 0x950412de                |&lt;br /&gt;
                |                                          |&lt;br /&gt;
             4  | file format revision = 0                 |&lt;br /&gt;
                |                                          |&lt;br /&gt;
             8  | number of strings                        |  == N&lt;br /&gt;
                |                                          |&lt;br /&gt;
            12  | offset of table with original strings    |  == O&lt;br /&gt;
                |                                          |&lt;br /&gt;
            16  | offset of table with translation strings |  == T&lt;br /&gt;
                |                                          |&lt;br /&gt;
            20  | size of hashing table                    |  == S&lt;br /&gt;
                |                                          |&lt;br /&gt;
            24  | offset of hashing table                  |  == H&lt;br /&gt;
                |                                          |&lt;br /&gt;
                .                                          .&lt;br /&gt;
                .    (possibly more entries later)         .&lt;br /&gt;
                .                                          .&lt;br /&gt;
                |                                          |&lt;br /&gt;
             O  | length &amp;amp; offset 0th string  ----------------.&lt;br /&gt;
         O + 8  | length &amp;amp; offset 1st string  ------------------.&lt;br /&gt;
                 ...                                    ...   | |&lt;br /&gt;
 O + ((N-1)*8)  | length &amp;amp; offset (N-1)th string           |  | |&lt;br /&gt;
                |                                          |  | |&lt;br /&gt;
             T  | length &amp;amp; offset 0th translation  ---------------.&lt;br /&gt;
         T + 8  | length &amp;amp; offset 1st translation  -----------------.&lt;br /&gt;
                 ...                                    ...   | | | |&lt;br /&gt;
 T + ((N-1)*8)  | length &amp;amp; offset (N-1)th translation      |  | | | |&lt;br /&gt;
                |                                          |  | | | |&lt;br /&gt;
             H  | start hash table                         |  | | | |&lt;br /&gt;
                 ...                                    ...   | | | |&lt;br /&gt;
     H + S * 4  | end hash table                           |  | | | |&lt;br /&gt;
                |                                          |  | | | |&lt;br /&gt;
                | NUL terminated 0th string  &amp;lt;----------------' | | |&lt;br /&gt;
                |                                          |    | | |&lt;br /&gt;
                | NUL terminated 1st string  &amp;lt;------------------' | |&lt;br /&gt;
                |                                          |      | |&lt;br /&gt;
                 ...                                    ...       | |&lt;br /&gt;
                |                                          |      | |&lt;br /&gt;
                | NUL terminated 0th translation  &amp;lt;---------------' |&lt;br /&gt;
                |                                          |        |&lt;br /&gt;
                | NUL terminated 1st translation  &amp;lt;-----------------'&lt;br /&gt;
                |                                          |&lt;br /&gt;
                 ...                                    ...&lt;br /&gt;
                |                                          |&lt;br /&gt;
                +------------------------------------------+&lt;br /&gt;
====Magic number====&lt;br /&gt;
&lt;br /&gt;
The magic number signals GNU MO files, it is stored in the byte order of the generating machine, so the magic number really is two numbers: 0x950412de and 0xde120495&lt;br /&gt;
&lt;br /&gt;
====Tables====&lt;br /&gt;
&lt;br /&gt;
In the tables, each string descriptor uses two 32 bits integers, the first for the string length, and the second for the offset of the string in the MO file, counting in bytes from the start of the file. The first table contains descriptors for the original strings, and is sorted in lexicographical order. The second table contains descriptors for the translated strings, and is parallel to the first table: to find the corresponding translation one has to access the array slot in the second array with the same index.&lt;br /&gt;
&lt;br /&gt;
====Hash table====&lt;br /&gt;
&lt;br /&gt;
The hash table is not contained in al Mo files, in this cases the size S is zero. It is sometimes better to not include the hash table because a precomputed hashing table takes disk space, and does not win that much speed. The hash table contains indices to the sorted array of strings in the MO file.&lt;br /&gt;
&lt;br /&gt;
==Hash Function==&lt;br /&gt;
&lt;br /&gt;
Here the description of the hash function used by gettext. I've taken it from it's source code [ftp://mirrors.kernel.org/gnu/gettext/gettext-0.14.5.tar.gz gettext-0.14.5].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Each string has an associate hashing value V computed by a fixed function (see below).  To locate the string, open addressing with double hashing is used. The first index will be V % S, where S is the size of the hashing table. If no entry is found, iterating with a second, independent hashing function takes place. This second value will be:&lt;br /&gt;
 1 + V % (S - 2).&lt;br /&gt;
The approximate number of probes will be&lt;br /&gt;
&lt;br /&gt;
:for unsuccessful search:  (1 - N / S) ^ -1&lt;br /&gt;
:for successful search:    - (N / S) ^ -1 * ln (1 - N / S)&lt;br /&gt;
::where N is the number of keys.&lt;br /&gt;
&lt;br /&gt;
If we now choose S to be the next prime bigger than 4 / 3 * N,&lt;br /&gt;
we get the values&lt;br /&gt;
:::4   and   1.85  resp.&lt;br /&gt;
Because unsuccessful searches are unlikely this is a good value.&lt;br /&gt;
Formulas: [Knuth, The Art of Computer Programming, Volume 3, Sorting and Searching, 1973, Addison Wesley]&lt;br /&gt;
&lt;br /&gt;
The hash function used to convert stings to an integer, is the so called ''hashpjw'' function by P.J. Weinberger [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools, 1986, 1987 Bell Telephone Laboratories, Inc.]&lt;br /&gt;
&lt;br /&gt;
The C code of the function comes from the source code of gettext (./gettext-0.14.5/gettext-runtime/intl/hash-string.h):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[c,N]&lt;br /&gt;
#define HASHWORDBITS 32&lt;br /&gt;
hash_string (const char *str_param) {&lt;br /&gt;
   unsigned long int hval, g;&lt;br /&gt;
   const char *str = str_param;&lt;br /&gt;
 &lt;br /&gt;
   /* Compute the hash value for the given string.  */&lt;br /&gt;
   hval = 0&lt;br /&gt;
   while (*str != '\0'&lt;br /&gt;
     {&lt;br /&gt;
       hval &amp;lt;&amp;lt;= 4;&lt;br /&gt;
       hval += (unsigned char) *str++;&lt;br /&gt;
       g = hval &amp;amp; ((unsigned long int) 0xf &amp;lt;&amp;lt; (HASHWORDBITS - 4));&lt;br /&gt;
       if (g != 0&lt;br /&gt;
 	{&lt;br /&gt;
 	  hval ^= g &amp;gt;&amp;gt; (HASHWORDBITS - 8);&lt;br /&gt;
 	  hval ^= g;&lt;br /&gt;
 	}&lt;br /&gt;
     }&lt;br /&gt;
   return hval;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the translated function in Eiffel:&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
hash_string (a_string: STRING): INTEGER is&lt;br /&gt;
    -- Compute the hash value for the given string&lt;br /&gt;
require&lt;br /&gt;
    valid_string: a_string /= Void&lt;br /&gt;
local&lt;br /&gt;
    position: INTEGER&lt;br /&gt;
    l_result, g: NATURAL_32&lt;br /&gt;
 do&lt;br /&gt;
    from&lt;br /&gt;
        position := 1&lt;br /&gt;
    invariant&lt;br /&gt;
        position &amp;gt;= 1&lt;br /&gt;
        position &amp;lt;= a_string.count + 1&lt;br /&gt;
    variant&lt;br /&gt;
        a_string.count + 1 - position&lt;br /&gt;
    until&lt;br /&gt;
        position &amp;gt; a_string.count&lt;br /&gt;
    loop&lt;br /&gt;
        l_result := l_result |&amp;lt;&amp;lt; 4&lt;br /&gt;
        l_result := l_result + a_string.code(position)&lt;br /&gt;
        g := l_result &amp;amp; ({NATURAL_32} 0xf |&amp;lt;&amp;lt; 28)&lt;br /&gt;
        if g /= 0 then&lt;br /&gt;
            l_result := l_result.bit_xor(g |&amp;gt;&amp;gt; 24)&lt;br /&gt;
            l_result := l_result.bit_xor(g)&lt;br /&gt;
        end&lt;br /&gt;
        position := position + 1&lt;br /&gt;
    end&lt;br /&gt;
    Result := l_result.as_integer_32&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/plural_forms&amp;diff=3152</id>
		<title>Internationalization/plural forms</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/plural_forms&amp;diff=3152"/>
				<updated>2006-06-03T06:11:46Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Internationalization]]&lt;br /&gt;
&lt;br /&gt;
The information about the plural form selection has to be stored in the header entry of the PO file (the one with the empty msgid string). The plural form information looks like this: &lt;br /&gt;
::Plural-Forms: nplurals=2; plural=n == 1 ? 0 : 1;&lt;br /&gt;
&lt;br /&gt;
The ''nplurals'' value must be a decimal number which specifies how many different plural forms exist for this language. The string following plural is an expression which is using the C language syntax. Exceptions are that no negative numbers are allowed, numbers must be decimal, and the only variable allowed is ''n''. This expression will be evaluated whenever one of the [[internationalization/translation_function|translation function]] for a &amp;quot;plural form&amp;quot; is called. The numeric value passed to these functions is then substituted for all uses of the variable n in the expression. The resulting value then must be greater or equal to zero and smaller than the value given as the value of ''nplurals''.&lt;br /&gt;
&lt;br /&gt;
==Rules==&lt;br /&gt;
The (at this point) known rules are:&lt;br /&gt;
===Only one form===&lt;br /&gt;
&lt;br /&gt;
Some languages only require one single form. There is no distinction between the singular and plural form. An appropriate header entry would look like this: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=1; plural=0;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Finno-Ugric family &lt;br /&gt;
:*Hungarian &lt;br /&gt;
:*Asian family &lt;br /&gt;
:*Japanese, Korean &lt;br /&gt;
:*Turkic/Altaic family &lt;br /&gt;
:*Turkish &lt;br /&gt;
&lt;br /&gt;
===Two forms, singular used for one only===&lt;br /&gt;
&lt;br /&gt;
This is the form used in most existing programs since it is what English is using. A header entry would look like this: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=2; plural=n != 1;&lt;br /&gt;
:::(Note: this uses the feature of C expressions that boolean expressions have to value zero or one.) &lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Germanic family &lt;br /&gt;
:*Danish, Dutch, English, German, Norwegian, Swedish &lt;br /&gt;
:*Finno-Ugric family &lt;br /&gt;
:*Estonian, Finnish &lt;br /&gt;
:*Latin/Greek family &lt;br /&gt;
:*Greek &lt;br /&gt;
:*Semitic family &lt;br /&gt;
:*Hebrew &lt;br /&gt;
:*Romanic family &lt;br /&gt;
:*Italian, Portuguese, Spanish &lt;br /&gt;
:*Artificial &lt;br /&gt;
:*Esperanto &lt;br /&gt;
&lt;br /&gt;
===Two forms, singular used for zero and one===&lt;br /&gt;
&lt;br /&gt;
Exceptional case in the language family. The header entry would be: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=2; plural=n&amp;gt;1;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Romanic family &lt;br /&gt;
:*French, Brazilian Portuguese &lt;br /&gt;
&lt;br /&gt;
===Three forms, special case for zero===&lt;br /&gt;
&lt;br /&gt;
The header entry would be: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=3; plural=n%10==1 &amp;amp;&amp;amp; n%100!=11 ? 0 : n != 0 ? 1 : 2;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Baltic family &lt;br /&gt;
:*Latvian &lt;br /&gt;
&lt;br /&gt;
===Three forms, special cases for one and two===&lt;br /&gt;
The header entry would be: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=3; plural=n==1 ? 0 : n==2 ? 1 : 2;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Celtic &lt;br /&gt;
:*Gaeilge (Irish) &lt;br /&gt;
&lt;br /&gt;
===Three forms, special case for numbers ending in 1[2-9]===&lt;br /&gt;
&lt;br /&gt;
The header entry would look like this: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=3; \&lt;br /&gt;
::plural=n%10==1 &amp;amp;&amp;amp; n%100!=11 ? 0 : \&lt;br /&gt;
::::::::n%10&amp;gt;=2 &amp;amp;&amp;amp; (n%100&amp;lt;10 || n%100&amp;gt;=20) ? 1 : 2;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Baltic family &lt;br /&gt;
:*Lithuanian&lt;br /&gt;
&lt;br /&gt;
===Three forms, special cases for numbers ending in 1 and 2, 3, 4, except those ending in 1[1-4]===&lt;br /&gt;
&lt;br /&gt;
The header entry would look like this: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=3; \&lt;br /&gt;
::plural=n%10==1 &amp;amp;&amp;amp; n%100!=11 ? 0 : \&lt;br /&gt;
::::n%10&amp;gt;=2 &amp;amp;&amp;amp; n%10&amp;lt;=4 &amp;amp;&amp;amp; (n%100&amp;lt;10 || n%100&amp;gt;=20) ? 1 : 2;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Slavic family &lt;br /&gt;
:*Croatian, Czech, Russian, Slovak, Ukrainian &lt;br /&gt;
&lt;br /&gt;
===Three forms, special case for one and some numbers ending in 2, 3, or 4===&lt;br /&gt;
&lt;br /&gt;
The header entry would look like this: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=3; \&lt;br /&gt;
::plural=n==1 ? 0 : \&lt;br /&gt;
::::n%10&amp;gt;=2 &amp;amp;&amp;amp; n%10&amp;lt;=4 &amp;amp;&amp;amp; (n%100&amp;lt;10 || n%100&amp;gt;=20) ? 1 : 2;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Slavic family &lt;br /&gt;
:*Polish &lt;br /&gt;
&lt;br /&gt;
===Four forms, special case for one and all numbers ending in 02, 03, or 04===&lt;br /&gt;
&lt;br /&gt;
The header entry would look like this: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=4; \&lt;br /&gt;
::plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Slavic family &lt;br /&gt;
:*Slovenian&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/tool_evaluation&amp;diff=3151</id>
		<title>Internationalization/tool evaluation</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/tool_evaluation&amp;diff=3151"/>
				<updated>2006-06-03T06:11:24Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Internationalization]]&lt;br /&gt;
&lt;br /&gt;
In this section it will be discussed which tool should be taken for the i18n work.&lt;br /&gt;
&lt;br /&gt;
= What should the tools be able to do =&lt;br /&gt;
* Search the source code for strings and other things that needs to be changed&lt;br /&gt;
* Create a file containing these results&lt;br /&gt;
* Enable the change of language and format of Eiffel&lt;br /&gt;
&lt;br /&gt;
= Tasks =&lt;br /&gt;
&lt;br /&gt;
The tools we should analyse have several tasks:&lt;br /&gt;
* find the strings into the source code and extract them&lt;br /&gt;
* find &amp;quot;information&amp;quot; about specific formats (time, measure units,...) in the code&lt;br /&gt;
* give the possibility to translate in a friendly environment&lt;br /&gt;
* replace the string with a function(string) construct&lt;br /&gt;
&lt;br /&gt;
Here you'll find the advantages and drawbacks of every tool we evaluate.&lt;br /&gt;
&lt;br /&gt;
== Tools to evaluate ==&lt;br /&gt;
Here is the list of existing tools we are now evaluating:&lt;br /&gt;
&lt;br /&gt;
=== GNU gettext ===&lt;br /&gt;
This set of tool is funded by the GNU community and is meant to help internationalize the C-Programs (and also C++, ObjectiveC, Pascal, PO, Python, Lisp, EmacsLisp, librep, Java, awk, YCP, Tcl, RST, Glade). As we are dealing with Eiffel this can be a bit harder to implement, but some tools can still be used.&lt;br /&gt;
&lt;br /&gt;
Advantages&lt;br /&gt;
* has tools to translate&lt;br /&gt;
* has tools to merge new strings into the actual catalog&lt;br /&gt;
* independent from the platform&lt;br /&gt;
Drawbacks&lt;br /&gt;
* uses only PO files (we should write a parser)&lt;br /&gt;
* has no runtime library for Eiffel&lt;br /&gt;
&lt;br /&gt;
=== poEdit ===&lt;br /&gt;
Yet another PO catalog editor.&lt;br /&gt;
&lt;br /&gt;
Advantages&lt;br /&gt;
* has tools to translate&lt;br /&gt;
* independent from the platform&lt;br /&gt;
Drawbacks&lt;br /&gt;
* uses only PO files (we should write a parser)&lt;br /&gt;
* has no runtime library for Eiffel&lt;br /&gt;
&lt;br /&gt;
[[http://www.poedit.org/ Visit the website for more information.]]&lt;br /&gt;
&lt;br /&gt;
=== KBabel ===&lt;br /&gt;
This is the tool used by the KDE community to translate the interface, it works with gettext and PO files.&lt;br /&gt;
From their [http://kbabel.kde.org/ website]:&lt;br /&gt;
&amp;quot;KBabel is a set of tools for editing and managing gettext PO files. Main part is a powerful and comfortable PO file editor which features full navigation capabilities, full editing functionality, possibility to search for translations in different dictionaries, spell and syntax checking, showing diffs and many more. Also included is a &amp;quot;Catalog Manager&amp;quot;, a file manager view which helps keeping an overview of PO files. Last but not least it includes a standalone dictionary application as an additional possibility to access KBabel's powerful dictionaries. KBabel will help you to translate fast and also keep consistent translations.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Features of the translation tool:&lt;br /&gt;
* Support for GNU gettext PO files (including plural forms) and Qt Linguist catalogs&lt;br /&gt;
* Experimental support for XLIFF 1.0 format&lt;br /&gt;
* Support for multiple translation projects&lt;br /&gt;
* Capability to open multiple files (or multiple views of the same file)&lt;br /&gt;
* Full editing functionality, accessible through the customizable graphic user interface as well as through user definable keyboard shortcuts&lt;br /&gt;
* Powerful spell checking functionality&lt;br /&gt;
* Capability to show diffs to older messages&lt;br /&gt;
* Full navigation capabilities (such as go to next fuzzy or untranslated string)&lt;br /&gt;
* Capability to save and read files in unicode encoding (utf-8)&lt;br /&gt;
* Unlimited undo capability&lt;br /&gt;
* Syntax highlighting&lt;br /&gt;
* Automatic file header updates&lt;br /&gt;
* Automatic change of &amp;quot;fuzzy&amp;quot; status of translated messages&lt;br /&gt;
* Support for easy insertion of tags and URLs&lt;br /&gt;
* Validation and highlighting of tags and XML entities&lt;br /&gt;
* A plugin framework for dictionaries, such as po compendium files, for consistency checks or translation suggestions&lt;br /&gt;
* A &amp;quot;rough translation&amp;quot; function to initialize untranslated messages with suggestion from a dictionary&lt;br /&gt;
* Automatic syntax check with msgfmt when saving and if an error occured easy navigation to messages, which contain errors&lt;br /&gt;
* Full Drag &amp;amp; Drop - support&lt;br /&gt;
* Configurable fonts for message editor&lt;br /&gt;
* Various methods to &amp;quot;see&amp;quot; whitespaces at end of lines&lt;br /&gt;
* Various methods to check consistency of translated messages, like comparing printf and Qt arguments in msgid and msgstr&lt;br /&gt;
* Quick overview over context in the po file&lt;br /&gt;
* Showing source code by references in message comments&lt;br /&gt;
* Sending the file using email&lt;br /&gt;
* Bookmarks for messages in a file&lt;br /&gt;
* Character selection tool integration&lt;br /&gt;
* A plugin framework for validation tools for consistency checks&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Features of the Catalog Manager:&lt;br /&gt;
*  File manager view for KDE's l10n module (or similarly structured) directories, which shows the present status of all PO files: if they are in need of a revision or not, how many fuzzies and untranslated strings are included etc. This view is always automatically updated and reflects all changes done to the files, including changes by programs other than KBabel.&lt;br /&gt;
* Integrated basic CVS and SVN support&lt;br /&gt;
* Various file open mechanisms for editing in KBabel: use Drag &amp;amp; Drop, double click, keyboard or context menu&lt;br /&gt;
* &amp;quot;Mark files&amp;quot; function (e.g. to identify POs that are in the responsibility of other translators)&lt;br /&gt;
* Powerful navigation using PO file statistics&lt;br /&gt;
* Automatic comparisons and statistics of POT and PO files for a quick overview which and how many files are translated (or not) and which files may be obsolete&lt;br /&gt;
* Syntax check (msgfmt --statistics) for existing files to control if the translated files will compile and, accordingly, work when distributed&lt;br /&gt;
* Free configurable commands, that can be executed from the Catalog Manager's context menu.&lt;br /&gt;
* Search/Replace functions in multiple files at once.&lt;br /&gt;
* Spellchecking of multiple files at once.&lt;br /&gt;
* Sending number of files using email.&lt;br /&gt;
* Doing &amp;quot;rough translation&amp;quot; for multiple files at once.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Notes&lt;br /&gt;
* under GNU GPL&lt;br /&gt;
* part of the kdesdk module&lt;br /&gt;
* it also has KBabelDict, plugin-based dictionaries (web-based but can be downloaded as a plain txt file), needs some Perl modules.&lt;br /&gt;
* runs only on linux&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Info from the official website of KBabel&lt;br /&gt;
[[http://l10n.kde.org/ click here for more]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On their website infos about Kartouche, a web-based php tool to help translation, is also available.&lt;br /&gt;
&lt;br /&gt;
From the infos available about this tool it looks like it's ideal to reach our goal, it has all we need and more.&lt;br /&gt;
&lt;br /&gt;
Advantages:&lt;br /&gt;
* Nice and easy to use interface&lt;br /&gt;
* Helps A LOT the translator&lt;br /&gt;
* Tool supported by the KBabel community&lt;br /&gt;
* GNU GPL&lt;br /&gt;
* Supports unicode&lt;br /&gt;
* Set of dictionaries&lt;br /&gt;
&lt;br /&gt;
Drawbacks:&lt;br /&gt;
* Runs on Linux systems only&lt;br /&gt;
* May need some work to adapt it for Eiffel&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== KTranslator ===&lt;br /&gt;
This tool helps the translation of single words, independently from the used application.&lt;br /&gt;
&lt;br /&gt;
Advantages:&lt;br /&gt;
* Application independant, used while running the program&lt;br /&gt;
&lt;br /&gt;
Drawbacks:&lt;br /&gt;
* Uses popups to display the translation of the word&lt;br /&gt;
* It works exclusively with dictionaries&lt;br /&gt;
* It isn't really a tool that can do big work of translation&lt;br /&gt;
&lt;br /&gt;
[http://ktranslator.sourceforge.net/index.html More]&lt;br /&gt;
&lt;br /&gt;
=== Other tools to watch ===&lt;br /&gt;
* xgettext&lt;br /&gt;
* poxml (Definition: tools for using PO-files to translate DocBook XML files This is a collection of tools that facilitate translating DocBook XML files using gettext message files (PO-files).)&lt;br /&gt;
* [http://po4a.alioth.debian.org/ po4a] (The po4a (po for anything) project goal is to ease translations (and more interestingly, the maintenance of translations) using gettext tools on areas where they were not expected like documentation.)&lt;br /&gt;
* xml2po&lt;br /&gt;
* [http://nlso-objects.sourceforge.net/ NLSO] (for Windows)&lt;br /&gt;
* Kartouche&lt;br /&gt;
&lt;br /&gt;
=== Conclusions ===&lt;br /&gt;
&lt;br /&gt;
== Writing our own tools ==&lt;br /&gt;
That could be a good idea to write our own tools to do these tasks, in particular for a distributed translation (everybody can help on internet).&lt;br /&gt;
With this I mean a little website that allows us to do the actual translation directly via the web, and it should automatically create the new version of the language file to be downloaded from all the users.&lt;br /&gt;
&lt;br /&gt;
Another thing that this tool can do for us is scanning the entire source code looking for new translations to be done, and propose them to the users... can be interesting because we than only have to click on a link and all the work (not the translations) is done for us.&lt;br /&gt;
&lt;br /&gt;
Advantages&lt;br /&gt;
* independent from the architecture&lt;br /&gt;
* independent from the language file format&lt;br /&gt;
Drawbacks&lt;br /&gt;
* can be a lot of work&lt;br /&gt;
&lt;br /&gt;
= Problems, Ideas, Further Development =&lt;br /&gt;
some problems/ideas that may go with the other parts of this project as well:&lt;br /&gt;
* The i18n can be put online as a database that everyone can update (thus helping translation in many more languages)&lt;br /&gt;
After the user has chosen a language the entries still untranslated will be displayed so that the user can insert his own version of the translated message&lt;br /&gt;
There may be the problem of some users who may have fun writing bad, strange, crazy, nonsense sentences, thus a solution is needed since it clearly can't be checked by the project team&lt;br /&gt;
* The main database can be updated as soon as something new for eiffel comes out (by updated here is meant simply adding the new messages, not their translations)&lt;br /&gt;
* A 2nd database can be placed on the user's pc and autoupdate Eiffel and the additional content one may have when needed (when a new version of Eiffel or a new tool is available for example), with this system one doesn't need to download every time a new file containing some information already downloaded before&lt;br /&gt;
* Unicode problem (maybe a collaboration with the Unicode group can help)&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/translation_function&amp;diff=3150</id>
		<title>Internationalization/translation function</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/translation_function&amp;diff=3150"/>
				<updated>2006-06-03T06:11:00Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Internationalization]]&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
The problem for the translation is that we need a way to translate three different types of string:&lt;br /&gt;
&lt;br /&gt;
* normal strings&lt;br /&gt;
 &amp;lt;code&amp;gt;[eiffel,N] &amp;quot;A normal string&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* composed string &lt;br /&gt;
 &amp;lt;code&amp;gt;[eiffel,N] &amp;quot;A string composed by &amp;quot;+count.out+&amp;quot; strings, like this or &amp;quot;+a_string+&amp;quot;%N&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* strings with plural form&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
 if n=1 then&lt;br /&gt;
     Result := &amp;quot;a string&amp;quot;&lt;br /&gt;
 else&lt;br /&gt;
    Result := &amp;quot;strings&amp;quot;&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another problem is that not all languages have the same rules for plural forms, see below and [[internationalization/plural_forms|here]] for more details.&lt;br /&gt;
&lt;br /&gt;
==Possible solution==&lt;br /&gt;
&lt;br /&gt;
I [[Talk:Internationalization/translation_function|'''propose''']] a solution, with four functions (I've got little fantasy for the function names):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
i18n (a_string : STRING) : STRING&lt;br /&gt;
    --Function for the translation of normal strings&lt;br /&gt;
&lt;br /&gt;
i18n_pl (strings : TUPLE[STRING]; form : INTEGER) : STRING&lt;br /&gt;
    --Function for the translation of normal strings&lt;br /&gt;
    -- with plural form&lt;br /&gt;
&lt;br /&gt;
i18n_comp (a_string : STRING; args : TUPLE) : STRING&lt;br /&gt;
    --Function for the translation of composit strings&lt;br /&gt;
&lt;br /&gt;
i18n_comp_pl (strings : TUPLE[STRING]; args : TUPLE; form : INTEGER) : STRING&lt;br /&gt;
    --Function for the translation of composit&lt;br /&gt;
    -- strings with plural forms&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With this solution, the programmer should write composit strings as (or in a similar way) he would do it for the C ''printf'' function. The composit string above would be somthing like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N] i18n_comp(&amp;quot;A string composed by %a1 strings, like this or %a2%N&amp;quot;, [count, a_string])&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where ''%a1'' 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.&lt;br /&gt;
&lt;br /&gt;
===An example===&lt;br /&gt;
&lt;br /&gt;
A complete example of how it could work.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Piece of code without internationalization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
if n = 1&lt;br /&gt;
io.put_string(&amp;quot;Remove file &amp;quot;+file_name.out+&amp;quot;?%N&amp;quot;)&lt;br /&gt;
else&lt;br /&gt;
io.put_string (&amp;quot;Delete following files?&amp;quot;+list.out+&amp;quot; there are &amp;quot;&lt;br /&gt;
                +list.count.out+&amp;quot;files%N&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Piece of code with internationalization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
io.put_string(i18n_comp_pl([&amp;quot;Remove file %a1?%N&amp;quot;,&lt;br /&gt;
                &amp;quot;Delete following files? %a2 there are %a3 files%N&amp;quot;],&lt;br /&gt;
                [file_name, list, list_count], n))&lt;br /&gt;
[...]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the content of the PO file would be:&lt;br /&gt;
&lt;br /&gt;
 #: A comment&lt;br /&gt;
 msgid &amp;quot;Remove file %a1?%N&amp;quot;&lt;br /&gt;
 msgid_plural &amp;quot;Delete following files? %a2 there are %a3 files%N&amp;quot;&lt;br /&gt;
 msgstr[0] &amp;quot;Rimuovere il file %a1?&amp;quot;&lt;br /&gt;
 msgstr[1] &amp;quot;Cancellare i seguenti file? %a2 ce ne sono %a3%N&amp;quot;&lt;br /&gt;
&lt;br /&gt;
You might ask yourself, ''why a function for all the pluralforms''?&lt;br /&gt;
&lt;br /&gt;
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). &lt;br /&gt;
But other language families have only one form or many forms. For example,&lt;br /&gt;
&lt;br /&gt;
In Polish the translation of file is plik, and the plural forms are: &lt;br /&gt;
 &lt;br /&gt;
:2,3,4 pliki&lt;br /&gt;
:5-21 pliko'w&lt;br /&gt;
:22-24 pliki&lt;br /&gt;
:25-31 pliko'w&lt;br /&gt;
:and so on...&lt;br /&gt;
&lt;br /&gt;
for more information about this topic go [http://www.gnu.org/software/gettext/manual/html_mono/gettext.html#SEC150 here]&lt;br /&gt;
&lt;br /&gt;
==Additional things==&lt;br /&gt;
&lt;br /&gt;
A nice thing whe could do, when parsing the source code of a program to internationalize, is to recognize comments about the string.&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
io.put_string(i18n_comp_pl([&amp;quot;Remove file %a1?%N&amp;quot;,&lt;br /&gt;
                &amp;quot;Delete following files? %a2 there are %a3 files%N&amp;quot;],&lt;br /&gt;
                [file_name, list, list_count], list_count))&lt;br /&gt;
--A comment of the author&lt;br /&gt;
[...]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
woud then look like this in the PO file:&lt;br /&gt;
&lt;br /&gt;
 #. A comment of the author&lt;br /&gt;
 #. Function name, class name, file path&lt;br /&gt;
 #. %a1 = file_name&lt;br /&gt;
 #. %a2 = list&lt;br /&gt;
 #. %a3 = list_count&lt;br /&gt;
 msgid &amp;quot;Remove file %a1?%N&amp;quot;&lt;br /&gt;
 msgid_plural &amp;quot;Delete following files? %a2 there are %a3 files%N&amp;quot;&lt;br /&gt;
 msgstr[0] &amp;quot;Rimuovere il file %a1?&amp;quot;&lt;br /&gt;
 msgstr[1] &amp;quot;Cancellare i seguenti file? %a2 ce ne sono %a3%N&amp;quot;&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/plural_forms&amp;diff=3114</id>
		<title>Internationalization/plural forms</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/plural_forms&amp;diff=3114"/>
				<updated>2006-05-31T16:51:30Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: added page to our category&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Projects]]&lt;br /&gt;
[[Category:Internationalization]]&lt;br /&gt;
&lt;br /&gt;
The information about the plural form selection has to be stored in the header entry of the PO file (the one with the empty msgid string). The plural form information looks like this: &lt;br /&gt;
::Plural-Forms: nplurals=2; plural=n == 1 ? 0 : 1;&lt;br /&gt;
&lt;br /&gt;
The ''nplurals'' value must be a decimal number which specifies how many different plural forms exist for this language. The string following plural is an expression which is using the C language syntax. Exceptions are that no negative numbers are allowed, numbers must be decimal, and the only variable allowed is ''n''. This expression will be evaluated whenever one of the [[internationalization/translation_function|translation function]] for a &amp;quot;plural form&amp;quot; is called. The numeric value passed to these functions is then substituted for all uses of the variable n in the expression. The resulting value then must be greater or equal to zero and smaller than the value given as the value of ''nplurals''.&lt;br /&gt;
&lt;br /&gt;
==Rules==&lt;br /&gt;
The (at this point) known rules are:&lt;br /&gt;
===Only one form===&lt;br /&gt;
&lt;br /&gt;
Some languages only require one single form. There is no distinction between the singular and plural form. An appropriate header entry would look like this: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=1; plural=0;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Finno-Ugric family &lt;br /&gt;
:*Hungarian &lt;br /&gt;
:*Asian family &lt;br /&gt;
:*Japanese, Korean &lt;br /&gt;
:*Turkic/Altaic family &lt;br /&gt;
:*Turkish &lt;br /&gt;
&lt;br /&gt;
===Two forms, singular used for one only===&lt;br /&gt;
&lt;br /&gt;
This is the form used in most existing programs since it is what English is using. A header entry would look like this: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=2; plural=n != 1;&lt;br /&gt;
:::(Note: this uses the feature of C expressions that boolean expressions have to value zero or one.) &lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Germanic family &lt;br /&gt;
:*Danish, Dutch, English, German, Norwegian, Swedish &lt;br /&gt;
:*Finno-Ugric family &lt;br /&gt;
:*Estonian, Finnish &lt;br /&gt;
:*Latin/Greek family &lt;br /&gt;
:*Greek &lt;br /&gt;
:*Semitic family &lt;br /&gt;
:*Hebrew &lt;br /&gt;
:*Romanic family &lt;br /&gt;
:*Italian, Portuguese, Spanish &lt;br /&gt;
:*Artificial &lt;br /&gt;
:*Esperanto &lt;br /&gt;
&lt;br /&gt;
===Two forms, singular used for zero and one===&lt;br /&gt;
&lt;br /&gt;
Exceptional case in the language family. The header entry would be: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=2; plural=n&amp;gt;1;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Romanic family &lt;br /&gt;
:*French, Brazilian Portuguese &lt;br /&gt;
&lt;br /&gt;
===Three forms, special case for zero===&lt;br /&gt;
&lt;br /&gt;
The header entry would be: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=3; plural=n%10==1 &amp;amp;&amp;amp; n%100!=11 ? 0 : n != 0 ? 1 : 2;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Baltic family &lt;br /&gt;
:*Latvian &lt;br /&gt;
&lt;br /&gt;
===Three forms, special cases for one and two===&lt;br /&gt;
The header entry would be: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=3; plural=n==1 ? 0 : n==2 ? 1 : 2;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Celtic &lt;br /&gt;
:*Gaeilge (Irish) &lt;br /&gt;
&lt;br /&gt;
===Three forms, special case for numbers ending in 1[2-9]===&lt;br /&gt;
&lt;br /&gt;
The header entry would look like this: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=3; \&lt;br /&gt;
::plural=n%10==1 &amp;amp;&amp;amp; n%100!=11 ? 0 : \&lt;br /&gt;
::::::::n%10&amp;gt;=2 &amp;amp;&amp;amp; (n%100&amp;lt;10 || n%100&amp;gt;=20) ? 1 : 2;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Baltic family &lt;br /&gt;
:*Lithuanian&lt;br /&gt;
&lt;br /&gt;
===Three forms, special cases for numbers ending in 1 and 2, 3, 4, except those ending in 1[1-4]===&lt;br /&gt;
&lt;br /&gt;
The header entry would look like this: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=3; \&lt;br /&gt;
::plural=n%10==1 &amp;amp;&amp;amp; n%100!=11 ? 0 : \&lt;br /&gt;
::::n%10&amp;gt;=2 &amp;amp;&amp;amp; n%10&amp;lt;=4 &amp;amp;&amp;amp; (n%100&amp;lt;10 || n%100&amp;gt;=20) ? 1 : 2;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Slavic family &lt;br /&gt;
:*Croatian, Czech, Russian, Slovak, Ukrainian &lt;br /&gt;
&lt;br /&gt;
===Three forms, special case for one and some numbers ending in 2, 3, or 4===&lt;br /&gt;
&lt;br /&gt;
The header entry would look like this: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=3; \&lt;br /&gt;
::plural=n==1 ? 0 : \&lt;br /&gt;
::::n%10&amp;gt;=2 &amp;amp;&amp;amp; n%10&amp;lt;=4 &amp;amp;&amp;amp; (n%100&amp;lt;10 || n%100&amp;gt;=20) ? 1 : 2;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Slavic family &lt;br /&gt;
:*Polish &lt;br /&gt;
&lt;br /&gt;
===Four forms, special case for one and all numbers ending in 02, 03, or 04===&lt;br /&gt;
&lt;br /&gt;
The header entry would look like this: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=4; \&lt;br /&gt;
::plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Slavic family &lt;br /&gt;
:*Slovenian&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/translation_function&amp;diff=3113</id>
		<title>Internationalization/translation function</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/translation_function&amp;diff=3113"/>
				<updated>2006-05-31T16:51:12Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: added page to our category&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Projects]]&lt;br /&gt;
[[Category:Internationalization]]&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
The problem for the translation is that we need a way to translate tree different types of string:&lt;br /&gt;
&lt;br /&gt;
* normal strings&lt;br /&gt;
 &amp;lt;code&amp;gt;[eiffel,N] &amp;quot;A normal string&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* composed string &lt;br /&gt;
 &amp;lt;code&amp;gt;[eiffel,N] &amp;quot;A string composed by &amp;quot;+count.out+&amp;quot; strings, like this or &amp;quot;+a_string+&amp;quot;%N&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* strings with plural form&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
 if n=1 then&lt;br /&gt;
     Result := &amp;quot;a string&amp;quot;&lt;br /&gt;
 else&lt;br /&gt;
    Result := &amp;quot;strings&amp;quot;&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An other problem is that not all languages have the same rule for plural forms, see below and [[internationalization/plural_forms|here]] for more details.&lt;br /&gt;
&lt;br /&gt;
==Possible solution==&lt;br /&gt;
&lt;br /&gt;
I [[Talk:Internationalization/translation_function|'''propose''']] a solution, with four functions (I've got little fantasy for the function names):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
i18n (a_string : STRING) : STRING&lt;br /&gt;
    --Function for the translation of normal strings&lt;br /&gt;
&lt;br /&gt;
i18n_pl (strings : TUPLE[STRING]; form : INTEGER) : STRING&lt;br /&gt;
    --Function for the translation of normal strings&lt;br /&gt;
    -- with plural form&lt;br /&gt;
&lt;br /&gt;
i18n_comp (a_string : STRING; args : TUPLE) : STRING&lt;br /&gt;
    --Function for the translation of composit strings&lt;br /&gt;
&lt;br /&gt;
i18n_comp_pl (strings : TUPLE[STRING]; args : TUPLE; form : INTEGER) : STRING&lt;br /&gt;
    --Function for the translation of composit&lt;br /&gt;
    -- strings with plural forms&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With this solution, the programmer should write composit strings as (or in a similar way) he would do it for the C ''printf'' function. The composit string above would be somthing like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N] i18n_comp(&amp;quot;A string composed by %a1 strings, like this or %a2%N&amp;quot;, [count, a_string])&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where ''%a1'' 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.&lt;br /&gt;
&lt;br /&gt;
===An example===&lt;br /&gt;
&lt;br /&gt;
A complete example of how it could work.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Piece of code without internationalization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
if n = 1&lt;br /&gt;
io.put_string(&amp;quot;Remove file &amp;quot;+file_name.out+&amp;quot;?%N&amp;quot;)&lt;br /&gt;
else&lt;br /&gt;
io.put_string (&amp;quot;Delete following files?&amp;quot;+list.out+&amp;quot; there are &amp;quot;&lt;br /&gt;
                +list.count.out+&amp;quot;files%N&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Piece of code with internationalization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
io.put_string([&amp;quot;Remove file %a1?%N&amp;quot;,&lt;br /&gt;
                &amp;quot;Delete following files? %a2 there are %a3 files%N&amp;quot;],&lt;br /&gt;
                [file_name, list, list_count], n)&lt;br /&gt;
[...]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the content of the PO file would be:&lt;br /&gt;
&lt;br /&gt;
 #: A comment&lt;br /&gt;
 msgid &amp;quot;Remove file %a1?%N&amp;quot;&lt;br /&gt;
 msgid_plural &amp;quot;Delete following files? %a2 there are %a3 files%N&amp;quot;&lt;br /&gt;
 msgstr[0] &amp;quot;Rimuovere il file %a1?&amp;quot;&lt;br /&gt;
 msgstr[1] &amp;quot;Cancellare i seguenti file? %a2 ce ne sono %a3%N&amp;quot;&lt;br /&gt;
&lt;br /&gt;
You might ask yourself, ''why a function for all the pluralforms''?&lt;br /&gt;
&lt;br /&gt;
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). &lt;br /&gt;
But other language families have only one form or many forms. For example,&lt;br /&gt;
&lt;br /&gt;
In Polish the translation of file is plik, and the plural forms are: &lt;br /&gt;
 &lt;br /&gt;
:2,3,4 pliki&lt;br /&gt;
:5-21 pliko'w&lt;br /&gt;
:22-24 pliki&lt;br /&gt;
:25-31 pliko'w&lt;br /&gt;
:and so on...&lt;br /&gt;
&lt;br /&gt;
for more information about this topic go [http://www.gnu.org/software/gettext/manual/html_mono/gettext.html#SEC150 here]&lt;br /&gt;
&lt;br /&gt;
==Additional things==&lt;br /&gt;
&lt;br /&gt;
A nice thing whe could do, when parsing the source code of a program to internationalize, is to recognize comments about the string.&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
io.put_string([&amp;quot;Remove file %a1?%N&amp;quot;,&lt;br /&gt;
                &amp;quot;Delete following files? %a2 there are %a3 files%N&amp;quot;],&lt;br /&gt;
                [file_name, list, list_count], n)&lt;br /&gt;
--A comment of the author&lt;br /&gt;
[...]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
woud then look like this in the PO file:&lt;br /&gt;
&lt;br /&gt;
 #. A comment of the author&lt;br /&gt;
 #. Function name, class name, file path&lt;br /&gt;
 #. %a1 = file_name&lt;br /&gt;
 #. %a2 = list&lt;br /&gt;
 #. %a3 = list_count&lt;br /&gt;
 msgid &amp;quot;Remove file %a1?%N&amp;quot;&lt;br /&gt;
 msgid_plural &amp;quot;Delete following files? %a2 there are %a3 files%N&amp;quot;&lt;br /&gt;
 msgstr[0] &amp;quot;Rimuovere il file %a1?&amp;quot;&lt;br /&gt;
 msgstr[1] &amp;quot;Cancellare i seguenti file? %a2 ce ne sono %a3%N&amp;quot;&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/code_parser&amp;diff=3112</id>
		<title>Internationalization/code parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/code_parser&amp;diff=3112"/>
				<updated>2006-05-31T16:50:39Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: added page to our category&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Projects]]&lt;br /&gt;
[[Category:Internationalization]]&lt;br /&gt;
&lt;br /&gt;
page moved to [[Internationalization/mo parser|mo parser]] because content didn't match title. --[[User:Carlo|Carlo]] 18:23, 7 May 2006 (CEST)&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/mo_parser&amp;diff=3111</id>
		<title>Internationalization/mo parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/mo_parser&amp;diff=3111"/>
				<updated>2006-05-31T16:50:27Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: added page to our category&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Projects]]&lt;br /&gt;
[[Category:Internationalization]]&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
That's what this part of the project should achieve:&lt;br /&gt;
* reading and parsing of MO files containing the strings and their translations&lt;br /&gt;
* organize the object collection in an incremental way: don't load the whole file if it's not needed&lt;br /&gt;
* give a simple interface to the localization class, so that the strings can be printed out without too much efforts&lt;br /&gt;
&lt;br /&gt;
==What is a mo file==&lt;br /&gt;
&lt;br /&gt;
MO stands for '''M'''achine '''O'''bject, as the name suggests, they are meant to be read by programs, and are binary in nature. The GNU program that creates them out of a PO file, is [http://www.scit.wlv.ac.uk/cgi-bin/mansec?1+msgfmt ''msgfmt''].&lt;br /&gt;
&lt;br /&gt;
== Reading and parsing ==&lt;br /&gt;
&lt;br /&gt;
=== Parser structure ===&lt;br /&gt;
&lt;br /&gt;
I'll propose the class structure of the parser, later.&lt;br /&gt;
&lt;br /&gt;
=== MO file structure ===&lt;br /&gt;
&lt;br /&gt;
As reported from the [http://www.gnu.org/software/gettext/manual/html_mono/gettext.html#SEC136 gettext manual].&lt;br /&gt;
&lt;br /&gt;
           byte&lt;br /&gt;
                +------------------------------------------+&lt;br /&gt;
             0  | magic number = 0x950412de                |&lt;br /&gt;
                |                                          |&lt;br /&gt;
             4  | file format revision = 0                 |&lt;br /&gt;
                |                                          |&lt;br /&gt;
             8  | number of strings                        |  == N&lt;br /&gt;
                |                                          |&lt;br /&gt;
            12  | offset of table with original strings    |  == O&lt;br /&gt;
                |                                          |&lt;br /&gt;
            16  | offset of table with translation strings |  == T&lt;br /&gt;
                |                                          |&lt;br /&gt;
            20  | size of hashing table                    |  == S&lt;br /&gt;
                |                                          |&lt;br /&gt;
            24  | offset of hashing table                  |  == H&lt;br /&gt;
                |                                          |&lt;br /&gt;
                .                                          .&lt;br /&gt;
                .    (possibly more entries later)         .&lt;br /&gt;
                .                                          .&lt;br /&gt;
                |                                          |&lt;br /&gt;
             O  | length &amp;amp; offset 0th string  ----------------.&lt;br /&gt;
         O + 8  | length &amp;amp; offset 1st string  ------------------.&lt;br /&gt;
                 ...                                    ...   | |&lt;br /&gt;
 O + ((N-1)*8)  | length &amp;amp; offset (N-1)th string           |  | |&lt;br /&gt;
                |                                          |  | |&lt;br /&gt;
             T  | length &amp;amp; offset 0th translation  ---------------.&lt;br /&gt;
         T + 8  | length &amp;amp; offset 1st translation  -----------------.&lt;br /&gt;
                 ...                                    ...   | | | |&lt;br /&gt;
 T + ((N-1)*8)  | length &amp;amp; offset (N-1)th translation      |  | | | |&lt;br /&gt;
                |                                          |  | | | |&lt;br /&gt;
             H  | start hash table                         |  | | | |&lt;br /&gt;
                 ...                                    ...   | | | |&lt;br /&gt;
     H + S * 4  | end hash table                           |  | | | |&lt;br /&gt;
                |                                          |  | | | |&lt;br /&gt;
                | NUL terminated 0th string  &amp;lt;----------------' | | |&lt;br /&gt;
                |                                          |    | | |&lt;br /&gt;
                | NUL terminated 1st string  &amp;lt;------------------' | |&lt;br /&gt;
                |                                          |      | |&lt;br /&gt;
                 ...                                    ...       | |&lt;br /&gt;
                |                                          |      | |&lt;br /&gt;
                | NUL terminated 0th translation  &amp;lt;---------------' |&lt;br /&gt;
                |                                          |        |&lt;br /&gt;
                | NUL terminated 1st translation  &amp;lt;-----------------'&lt;br /&gt;
                |                                          |&lt;br /&gt;
                 ...                                    ...&lt;br /&gt;
                |                                          |&lt;br /&gt;
                +------------------------------------------+&lt;br /&gt;
====Magic number====&lt;br /&gt;
&lt;br /&gt;
The magic number signals GNU MO files, it is stored in the byte order of the generating machine, so the magic number really is two numbers: 0x950412de and 0xde120495&lt;br /&gt;
&lt;br /&gt;
====Tables====&lt;br /&gt;
&lt;br /&gt;
In the tables, each string descriptor uses two 32 bits integers, the first for the string length, and the second for the offset of the string in the MO file, counting in bytes from the start of the file. The first table contains descriptors for the original strings, and is sorted in lexicographical order. The second table contains descriptors for the translated strings, and is parallel to the first table: to find the corresponding translation one has to access the array slot in the second array with the same index.&lt;br /&gt;
&lt;br /&gt;
====Hash table====&lt;br /&gt;
&lt;br /&gt;
The hash table is not contained in al Mo files, in this cases the size S is zero. It is sometimes better to not include the hash table because a precomputed hashing table takes disk space, and does not win that much speed. The hash table contains indices to the sorted array of strings in the MO file.&lt;br /&gt;
&lt;br /&gt;
==Hash Function==&lt;br /&gt;
&lt;br /&gt;
Here the description of the hash function used by gettext. I've taken it from it's source code [ftp://mirrors.kernel.org/gnu/gettext/gettext-0.14.5.tar.gz gettext-0.14.5].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Each string has an associate hashing value V computed by a fixed function (see below).  To locate the string, open addressing with double hashing is used. The first index will be V % S, where S is the size of the hashing table. If no entry is found, iterating with a second, independent hashing function takes place. This second value will be:&lt;br /&gt;
 1 + V % (S - 2).&lt;br /&gt;
The approximate number of probes will be&lt;br /&gt;
&lt;br /&gt;
:for unsuccessful search:  (1 - N / S) ^ -1&lt;br /&gt;
:for successful search:    - (N / S) ^ -1 * ln (1 - N / S)&lt;br /&gt;
::where N is the number of keys.&lt;br /&gt;
&lt;br /&gt;
If we now choose S to be the next prime bigger than 4 / 3 * N,&lt;br /&gt;
we get the values&lt;br /&gt;
:::4   and   1.85  resp.&lt;br /&gt;
Because unsuccessful searches are unlikely this is a good value.&lt;br /&gt;
Formulas: [Knuth, The Art of Computer Programming, Volume 3, Sorting and Searching, 1973, Addison Wesley]&lt;br /&gt;
&lt;br /&gt;
The hash function used to convert stings to an integer, is the so called ''hashpjw'' function by P.J. Weinberger [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools, 1986, 1987 Bell Telephone Laboratories, Inc.]&lt;br /&gt;
&lt;br /&gt;
The C code of the function comes from the source code of gettext (./gettext-0.14.5/gettext-runtime/intl/hash-string.h):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[c,N]&lt;br /&gt;
#define HASHWORDBITS 32&lt;br /&gt;
hash_string (const char *str_param) {&lt;br /&gt;
   unsigned long int hval, g;&lt;br /&gt;
   const char *str = str_param;&lt;br /&gt;
 &lt;br /&gt;
   /* Compute the hash value for the given string.  */&lt;br /&gt;
   hval = 0&lt;br /&gt;
   while (*str != '\0'&lt;br /&gt;
     {&lt;br /&gt;
       hval &amp;lt;&amp;lt;= 4;&lt;br /&gt;
       hval += (unsigned char) *str++;&lt;br /&gt;
       g = hval &amp;amp; ((unsigned long int) 0xf &amp;lt;&amp;lt; (HASHWORDBITS - 4));&lt;br /&gt;
       if (g != 0&lt;br /&gt;
 	{&lt;br /&gt;
 	  hval ^= g &amp;gt;&amp;gt; (HASHWORDBITS - 8);&lt;br /&gt;
 	  hval ^= g;&lt;br /&gt;
 	}&lt;br /&gt;
     }&lt;br /&gt;
   return hval;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the translated function in Eiffel:&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
hash_string (a_string: STRING): INTEGER is&lt;br /&gt;
    -- Compute the hash value for the given string&lt;br /&gt;
require&lt;br /&gt;
    valid_string: a_string /= Void&lt;br /&gt;
local&lt;br /&gt;
    position: INTEGER&lt;br /&gt;
    l_result, g: NATURAL_32&lt;br /&gt;
 do&lt;br /&gt;
    from&lt;br /&gt;
        position := 1&lt;br /&gt;
    invariant&lt;br /&gt;
        position &amp;gt;= 1&lt;br /&gt;
        position &amp;lt;= a_string.count + 1&lt;br /&gt;
    variant&lt;br /&gt;
        a_string.count + 1 - position&lt;br /&gt;
    until&lt;br /&gt;
        position &amp;gt; a_string.count&lt;br /&gt;
    loop&lt;br /&gt;
        l_result := l_result |&amp;lt;&amp;lt; 4&lt;br /&gt;
        l_result := l_result + a_string.code(position)&lt;br /&gt;
        g := l_result &amp;amp; ({NATURAL_32} 0xf |&amp;lt;&amp;lt; 28)&lt;br /&gt;
        if g /= 0 then&lt;br /&gt;
            l_result := l_result.bit_xor(g |&amp;gt;&amp;gt; 24)&lt;br /&gt;
            l_result := l_result.bit_xor(g)&lt;br /&gt;
        end&lt;br /&gt;
        position := position + 1&lt;br /&gt;
    end&lt;br /&gt;
    Result := l_result.as_integer_32&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/tool_evaluation&amp;diff=3110</id>
		<title>Internationalization/tool evaluation</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/tool_evaluation&amp;diff=3110"/>
				<updated>2006-05-31T16:50:13Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: added page to our category&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Projects]]&lt;br /&gt;
[[Category:Internationalization]]&lt;br /&gt;
&lt;br /&gt;
In this section it will be discussed which tool should be taken for the i18n work.&lt;br /&gt;
&lt;br /&gt;
= What should the tools be able to do =&lt;br /&gt;
* Search the source code for strings and other things that needs to be changed&lt;br /&gt;
* Create a file containing these results&lt;br /&gt;
* Enable the change of language and format of Eiffel&lt;br /&gt;
&lt;br /&gt;
= Tasks =&lt;br /&gt;
&lt;br /&gt;
The tools we should analyse have several tasks:&lt;br /&gt;
* find the strings into the source code and extract them&lt;br /&gt;
* find &amp;quot;information&amp;quot; about specific formats (time, measure units,...) in the code&lt;br /&gt;
* give the possibility to translate in a friendly environment&lt;br /&gt;
* replace the string with a function(string) construct&lt;br /&gt;
&lt;br /&gt;
Here you'll find the advantages and drawbacks of every tool we evaluate.&lt;br /&gt;
&lt;br /&gt;
== Tools to evaluate ==&lt;br /&gt;
Here is the list of existing tools we are now evaluating:&lt;br /&gt;
&lt;br /&gt;
=== GNU gettext ===&lt;br /&gt;
This set of tool is funded by the GNU community and is meant to help internationalize the C-Programs (and also C++, ObjectiveC, Pascal, PO, Python, Lisp, EmacsLisp, librep, Java, awk, YCP, Tcl, RST, Glade). As we are dealing with Eiffel this can be a bit harder to implement, but some tools can still be used.&lt;br /&gt;
&lt;br /&gt;
Advantages&lt;br /&gt;
* has tools to translate&lt;br /&gt;
* has tools to merge new strings into the actual catalog&lt;br /&gt;
* independent from the platform&lt;br /&gt;
Drawbacks&lt;br /&gt;
* uses only PO files (we should write a parser)&lt;br /&gt;
* has no runtime library for Eiffel&lt;br /&gt;
&lt;br /&gt;
=== poEdit ===&lt;br /&gt;
Yet another PO catalog editor.&lt;br /&gt;
&lt;br /&gt;
Advantages&lt;br /&gt;
* has tools to translate&lt;br /&gt;
* independent from the platform&lt;br /&gt;
Drawbacks&lt;br /&gt;
* uses only PO files (we should write a parser)&lt;br /&gt;
* has no runtime library for Eiffel&lt;br /&gt;
&lt;br /&gt;
[[http://www.poedit.org/ Visit the website for more information.]]&lt;br /&gt;
&lt;br /&gt;
=== KBabel ===&lt;br /&gt;
This is the tool used by the KDE community to translate the interface, it works with gettext and PO files.&lt;br /&gt;
From their [http://kbabel.kde.org/ website]:&lt;br /&gt;
&amp;quot;KBabel is a set of tools for editing and managing gettext PO files. Main part is a powerful and comfortable PO file editor which features full navigation capabilities, full editing functionality, possibility to search for translations in different dictionaries, spell and syntax checking, showing diffs and many more. Also included is a &amp;quot;Catalog Manager&amp;quot;, a file manager view which helps keeping an overview of PO files. Last but not least it includes a standalone dictionary application as an additional possibility to access KBabel's powerful dictionaries. KBabel will help you to translate fast and also keep consistent translations.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Features of the translation tool:&lt;br /&gt;
* Support for GNU gettext PO files (including plural forms) and Qt Linguist catalogs&lt;br /&gt;
* Experimental support for XLIFF 1.0 format&lt;br /&gt;
* Support for multiple translation projects&lt;br /&gt;
* Capability to open multiple files (or multiple views of the same file)&lt;br /&gt;
* Full editing functionality, accessible through the customizable graphic user interface as well as through user definable keyboard shortcuts&lt;br /&gt;
* Powerful spell checking functionality&lt;br /&gt;
* Capability to show diffs to older messages&lt;br /&gt;
* Full navigation capabilities (such as go to next fuzzy or untranslated string)&lt;br /&gt;
* Capability to save and read files in unicode encoding (utf-8)&lt;br /&gt;
* Unlimited undo capability&lt;br /&gt;
* Syntax highlighting&lt;br /&gt;
* Automatic file header updates&lt;br /&gt;
* Automatic change of &amp;quot;fuzzy&amp;quot; status of translated messages&lt;br /&gt;
* Support for easy insertion of tags and URLs&lt;br /&gt;
* Validation and highlighting of tags and XML entities&lt;br /&gt;
* A plugin framework for dictionaries, such as po compendium files, for consistency checks or translation suggestions&lt;br /&gt;
* A &amp;quot;rough translation&amp;quot; function to initialize untranslated messages with suggestion from a dictionary&lt;br /&gt;
* Automatic syntax check with msgfmt when saving and if an error occured easy navigation to messages, which contain errors&lt;br /&gt;
* Full Drag &amp;amp; Drop - support&lt;br /&gt;
* Configurable fonts for message editor&lt;br /&gt;
* Various methods to &amp;quot;see&amp;quot; whitespaces at end of lines&lt;br /&gt;
* Various methods to check consistency of translated messages, like comparing printf and Qt arguments in msgid and msgstr&lt;br /&gt;
* Quick overview over context in the po file&lt;br /&gt;
* Showing source code by references in message comments&lt;br /&gt;
* Sending the file using email&lt;br /&gt;
* Bookmarks for messages in a file&lt;br /&gt;
* Character selection tool integration&lt;br /&gt;
* A plugin framework for validation tools for consistency checks&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Features of the Catalog Manager:&lt;br /&gt;
*  File manager view for KDE's l10n module (or similarly structured) directories, which shows the present status of all PO files: if they are in need of a revision or not, how many fuzzies and untranslated strings are included etc. This view is always automatically updated and reflects all changes done to the files, including changes by programs other than KBabel.&lt;br /&gt;
* Integrated basic CVS and SVN support&lt;br /&gt;
* Various file open mechanisms for editing in KBabel: use Drag &amp;amp; Drop, double click, keyboard or context menu&lt;br /&gt;
* &amp;quot;Mark files&amp;quot; function (e.g. to identify POs that are in the responsibility of other translators)&lt;br /&gt;
* Powerful navigation using PO file statistics&lt;br /&gt;
* Automatic comparisons and statistics of POT and PO files for a quick overview which and how many files are translated (or not) and which files may be obsolete&lt;br /&gt;
* Syntax check (msgfmt --statistics) for existing files to control if the translated files will compile and, accordingly, work when distributed&lt;br /&gt;
* Free configurable commands, that can be executed from the Catalog Manager's context menu.&lt;br /&gt;
* Search/Replace functions in multiple files at once.&lt;br /&gt;
* Spellchecking of multiple files at once.&lt;br /&gt;
* Sending number of files using email.&lt;br /&gt;
* Doing &amp;quot;rough translation&amp;quot; for multiple files at once.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Notes&lt;br /&gt;
* under GNU GPL&lt;br /&gt;
* part of the kdesdk module&lt;br /&gt;
* it also has KBabelDict, plugin-based dictionaries (web-based but can be downloaded as a plain txt file), needs some Perl modules.&lt;br /&gt;
* runs only on linux&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Info from the official website of KBabel&lt;br /&gt;
[[http://l10n.kde.org/ click here for more]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On their website infos about Kartouche, a web-based php tool to help translation, is also available.&lt;br /&gt;
&lt;br /&gt;
From the infos available about this tool it looks like it's ideal to reach our goal, it has all we need and more.&lt;br /&gt;
&lt;br /&gt;
Advantages:&lt;br /&gt;
* Nice and easy to use interface&lt;br /&gt;
* Helps A LOT the translator&lt;br /&gt;
* Tool supported by the KBabel community&lt;br /&gt;
* GNU GPL&lt;br /&gt;
* Supports unicode&lt;br /&gt;
* Set of dictionaries&lt;br /&gt;
&lt;br /&gt;
Drawbacks:&lt;br /&gt;
* Runs on Linux systems only&lt;br /&gt;
* May need some work to adapt it for Eiffel&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== KTranslator ===&lt;br /&gt;
This tool helps the translation of single words, independently from the used application.&lt;br /&gt;
&lt;br /&gt;
Advantages:&lt;br /&gt;
* Application independant, used while running the program&lt;br /&gt;
&lt;br /&gt;
Drawbacks:&lt;br /&gt;
* Uses popups to display the translation of the word&lt;br /&gt;
* It works exclusively with dictionaries&lt;br /&gt;
* It isn't really a tool that can do big work of translation&lt;br /&gt;
&lt;br /&gt;
[http://ktranslator.sourceforge.net/index.html More]&lt;br /&gt;
&lt;br /&gt;
=== Other tools to watch ===&lt;br /&gt;
* xgettext&lt;br /&gt;
* poxml (Definition: tools for using PO-files to translate DocBook XML files This is a collection of tools that facilitate translating DocBook XML files using gettext message files (PO-files).)&lt;br /&gt;
* [http://po4a.alioth.debian.org/ po4a] (The po4a (po for anything) project goal is to ease translations (and more interestingly, the maintenance of translations) using gettext tools on areas where they were not expected like documentation.)&lt;br /&gt;
* xml2po&lt;br /&gt;
* [http://nlso-objects.sourceforge.net/ NLSO] (for Windows)&lt;br /&gt;
* Kartouche&lt;br /&gt;
&lt;br /&gt;
=== Conclusions ===&lt;br /&gt;
&lt;br /&gt;
== Writing our own tools ==&lt;br /&gt;
That could be a good idea to write our own tools to do these tasks, in particular for a distributed translation (everybody can help on internet).&lt;br /&gt;
With this I mean a little website that allows us to do the actual translation directly via the web, and it should automatically create the new version of the language file to be downloaded from all the users.&lt;br /&gt;
&lt;br /&gt;
Another thing that this tool can do for us is scanning the entire source code looking for new translations to be done, and propose them to the users... can be interesting because we than only have to click on a link and all the work (not the translations) is done for us.&lt;br /&gt;
&lt;br /&gt;
Advantages&lt;br /&gt;
* independent from the architecture&lt;br /&gt;
* independent from the language file format&lt;br /&gt;
Drawbacks&lt;br /&gt;
* can be a lot of work&lt;br /&gt;
&lt;br /&gt;
= Problems, Ideas, Further Development =&lt;br /&gt;
some problems/ideas that may go with the other parts of this project as well:&lt;br /&gt;
* The i18n can be put online as a database that everyone can update (thus helping translation in many more languages)&lt;br /&gt;
After the user has chosen a language the entries still untranslated will be displayed so that the user can insert his own version of the translated message&lt;br /&gt;
There may be the problem of some users who may have fun writing bad, strange, crazy, nonsense sentences, thus a solution is needed since it clearly can't be checked by the project team&lt;br /&gt;
* The main database can be updated as soon as something new for eiffel comes out (by updated here is meant simply adding the new messages, not their translations)&lt;br /&gt;
* A 2nd database can be placed on the user's pc and autoupdate Eiffel and the additional content one may have when needed (when a new version of Eiffel or a new tool is available for example), with this system one doesn't need to download every time a new file containing some information already downloaded before&lt;br /&gt;
* Unicode problem (maybe a collaboration with the Unicode group can help)&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/file_format&amp;diff=3109</id>
		<title>Internationalization/file format</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/file_format&amp;diff=3109"/>
				<updated>2006-05-31T16:49:29Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: added page to our category&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Projects]]&lt;br /&gt;
[[Category:Internationalization]]&lt;br /&gt;
&lt;br /&gt;
==Summary==&lt;br /&gt;
&lt;br /&gt;
Here [[Internationalization|we]] evaluate various file formats used for the translation of programs. For the moment we are considering:&lt;br /&gt;
&lt;br /&gt;
* XML&lt;br /&gt;
* po&lt;br /&gt;
* [http://transolution.python-hosting.com xliff] (good description in this homepage)&lt;br /&gt;
* create an own format&lt;br /&gt;
&lt;br /&gt;
==PO Files==&lt;br /&gt;
&lt;br /&gt;
===Format of PO files===&lt;br /&gt;
&lt;br /&gt;
A PO file has an entry for each string that has to be translated. There are two kind of them, a &amp;quot;normal&amp;quot; one and one that involves plural forms.&lt;br /&gt;
&lt;br /&gt;
====Normal entry====&lt;br /&gt;
&lt;br /&gt;
Here is the general structure of a &amp;quot;normal&amp;quot; entry:&lt;br /&gt;
&lt;br /&gt;
 white-space&lt;br /&gt;
 #  translator-comments&lt;br /&gt;
 #. automatic-comments&lt;br /&gt;
 #: reference...&lt;br /&gt;
 #, flag...&lt;br /&gt;
 msgid untranslated-string&lt;br /&gt;
 msgstr translated-string&lt;br /&gt;
&lt;br /&gt;
Where the ''translator-comments'' are created and maintained exclusively by the translator, this comments have some white space immediately following the #. The other comments are created by the program that created the PO file.&lt;br /&gt;
After the special comment &amp;quot;#,&amp;quot; there can be some ''flags'', as ''fuzzy'' shows that the msgstr string might not be a correct translation, i.e. the translator is not sure of his work.&lt;br /&gt;
The 'untranslated-string' is the untranslated string as it appears in the original program source. The ''translated-string'' is (as the name suggests) the translated string, if there is no translation it is an empty string.&lt;br /&gt;
&lt;br /&gt;
====Plural form entry====&lt;br /&gt;
&lt;br /&gt;
 white-space&lt;br /&gt;
 #  translator-comments&lt;br /&gt;
 #. automatic-comments&lt;br /&gt;
 #: reference...&lt;br /&gt;
 #, flag...&lt;br /&gt;
 msgid untranslated-string-singular&lt;br /&gt;
 msgid_plural untranslated-string-plural&lt;br /&gt;
 msgstr[0] translated-string-case-0&lt;br /&gt;
 ...&lt;br /&gt;
 msgstr[N] translated-string-case-n&lt;br /&gt;
&lt;br /&gt;
===Supported character encodings===&lt;br /&gt;
&lt;br /&gt;
character encodings that can be used are limited to those supported by both GNU libc and GNU libiconv. These are: ASCII, ISO-8859-1, ISO-8859-2, ISO-8859-3, ISO-8859-4, ISO-8859-5, ISO-8859-6, ISO-8859-7, ISO-8859-8, ISO-8859-9, ISO-8859-13, ISO-8859-15, KOI8-R, KOI8-U, CP850, CP866, CP874, CP932, CP949, CP950, CP1250, CP1251, CP1252, CP1253, CP1254, CP1255, CP1256, CP1257, GB2312, EUC-JP, EUC-KR, EUC-TW, BIG5, BIG5-HKSCS, GBK, GB18030, SHIFT_JIS, JOHAB, TIS-620, VISCII, UTF-8.&lt;br /&gt;
&lt;br /&gt;
I think they are a lot...&lt;br /&gt;
&lt;br /&gt;
===Po Editors===&lt;br /&gt;
&lt;br /&gt;
* poEdit&lt;br /&gt;
* KBabel&lt;br /&gt;
* Gtranslator&lt;br /&gt;
* LocFactoryEditor (XLIFF and PO editor for Mac OSX)&lt;br /&gt;
&lt;br /&gt;
===Positive aspects===&lt;br /&gt;
&lt;br /&gt;
* Powerful plural handling&lt;br /&gt;
* Format created for translation purpose&lt;br /&gt;
* Easy for humans to read&lt;br /&gt;
* Used by gettext, kbabel, rosetta and many other programs&lt;br /&gt;
* Support and elaboration tools for almost all plattforms&lt;br /&gt;
&lt;br /&gt;
===Negative aspects===&lt;br /&gt;
&lt;br /&gt;
* We have to write a PO parser&lt;br /&gt;
&lt;br /&gt;
==XML==&lt;br /&gt;
&lt;br /&gt;
===Format of XML===&lt;br /&gt;
&lt;br /&gt;
XML is used for example by Trolltech for their .ts files. Here an example of .ts file, generated my lupdate (a tool made by trolltech that extracts translatable text from the C++ source code of the Qt application, see [[Internationalization/tool evaluation|here]] for further information):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;!DOCTYPE TS&amp;gt;&amp;lt;TS&amp;gt;&lt;br /&gt;
     &amp;lt;context&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;MyExample&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;message&amp;gt;&lt;br /&gt;
             &amp;lt;source&amp;gt;i18n=Internationalization&amp;lt;/source&amp;gt;&lt;br /&gt;
             &amp;lt;translation type=&amp;quot;unfinished&amp;quot;&amp;gt;&amp;lt;/translation&amp;gt;&lt;br /&gt;
         &amp;lt;/message&amp;gt;&lt;br /&gt;
     &amp;lt;/context&amp;gt;&lt;br /&gt;
 &amp;lt;/TS&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And after the translation (for example with Qt Linguist) it would look like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;!DOCTYPE TS&amp;gt;&amp;lt;TS&amp;gt;&lt;br /&gt;
     &amp;lt;context&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;MyExample&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;message&amp;gt;&lt;br /&gt;
             &amp;lt;source&amp;gt;i18n=Internationalization&amp;lt;/source&amp;gt;&lt;br /&gt;
             &amp;lt;translation&amp;gt;i20e=Internazionalizzazione&amp;lt;/translation&amp;gt;&lt;br /&gt;
         &amp;lt;/message&amp;gt;&lt;br /&gt;
     &amp;lt;/context&amp;gt;&lt;br /&gt;
 &amp;lt;/TS&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Positive aspects===&lt;br /&gt;
&lt;br /&gt;
* full support for unicode character encodings&lt;br /&gt;
* There is already a parser in the EiffelBase&lt;br /&gt;
* In trolltech's opinion it's a human readable text&lt;br /&gt;
&lt;br /&gt;
===Negative aspects===&lt;br /&gt;
&lt;br /&gt;
* Not everybody knows it&lt;br /&gt;
* Microsoft seeks XML-related patents that could restrict the use of XML (there should be a &amp;quot;Very negative aspect&amp;quot; section)&lt;br /&gt;
:Thank you for that link, but the Microsoft Patents apply only on the Office dialect of XML, which it uses to save its own documents... they DON'T apply to the XML standard and general use (as we would create our format). [[User:Trosim|Trosim]]&lt;br /&gt;
* In my opinion it's not a human readable text (Fortunately not all human beings are Computer scientists)&lt;br /&gt;
&lt;br /&gt;
==New Format==&lt;br /&gt;
&lt;br /&gt;
===Format of our Format===&lt;br /&gt;
&lt;br /&gt;
* It doesn't exist yet, so we don't know how it looks like.&lt;br /&gt;
* We could give our own extension to the file format for example .et (eiffel translation) or .babe (babylon eiffel) or .eint (eiffel i18n) ... (''huge'' advantage)&lt;br /&gt;
&lt;br /&gt;
===Positive aspects===&lt;br /&gt;
&lt;br /&gt;
* Free to do what we want&lt;br /&gt;
* We don't have to care about licenses&lt;br /&gt;
* Possibility to make it the best human readable format&lt;br /&gt;
* So that we can say that we invented a new file format&lt;br /&gt;
* Better integrated and consistent with eiffel syntax&lt;br /&gt;
&lt;br /&gt;
===Negative aspects===&lt;br /&gt;
&lt;br /&gt;
* A new format? Why should we be different?&lt;br /&gt;
* Do more work as needed (there are already good formats)&lt;br /&gt;
* Long time until it becomes famous&lt;br /&gt;
&lt;br /&gt;
==Conclusions==&lt;br /&gt;
&lt;br /&gt;
Our decision is to use the po file format.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
* [http://www.gnu.org/software/gettext/manual/html_mono/gettext.html Gettext manual (for PO files)]&lt;br /&gt;
* [http://librarian.launchpad.net/2395419/it.po Example of a PO file (from rosetta)]&lt;br /&gt;
* [http://news.com.com/2100-1013_3-5146581.html Microsoft and XML]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/XML#Quick_syntax_tour XML syntax description on Wikipedia]&lt;br /&gt;
* [http://doc.trolltech.com/4.1/i18n.html Trolltech i18n]&lt;br /&gt;
* [http://translate.sourceforge.net/wiki/ open source i18n and l10n project]&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/feasibility&amp;diff=3108</id>
		<title>Internationalization/feasibility</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/feasibility&amp;diff=3108"/>
				<updated>2006-05-31T16:48:43Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: added page to our category&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Internationalization]]&lt;br /&gt;
&lt;br /&gt;
==Summary==&lt;br /&gt;
Our task is to find out the possible main difficulties that will be encoutered during both design and implementation of the [[internationalization|i18n]] framework.&lt;br /&gt;
&lt;br /&gt;
Main focuses are:&lt;br /&gt;
* state of the Unicode implementation&lt;br /&gt;
* strings usage in Vision2&lt;br /&gt;
* runtime generated/composed strings with variables&lt;br /&gt;
&lt;br /&gt;
==String types and their possible difficulties==&lt;br /&gt;
&lt;br /&gt;
===Constant String===&lt;br /&gt;
 Workbench_name: &amp;lt;font color=&amp;quot;Blue&amp;quot;&amp;gt;STRING is&amp;lt;/font&amp;gt; &amp;lt;font color=&amp;quot;Green&amp;quot;&amp;gt;&amp;quot;EiffelStudio&amp;quot;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Difficulties====&lt;br /&gt;
====Possible Solution====&lt;br /&gt;
&lt;br /&gt;
===String with label specific syntax===&lt;br /&gt;
 m_to_lower: &amp;lt;font color=&amp;quot;Blue&amp;quot;&amp;gt;STRING is&amp;lt;/font&amp;gt; &amp;lt;font color=&amp;quot;Green&amp;quot;&amp;gt;&amp;quot;Set to &amp;amp;Lowercase%TCtrl+Shift+U&amp;quot;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Difficulties====&lt;br /&gt;
* Bad readability for the traducer&lt;br /&gt;
* Shortcuts conflict&lt;br /&gt;
====Possible Solution====&lt;br /&gt;
&lt;br /&gt;
===Composed String===&lt;br /&gt;
 m_About:&amp;lt;font color=&amp;quot;Blue&amp;quot;&amp;gt;STRING is&amp;lt;/font&amp;gt;&lt;br /&gt;
   &amp;lt;font color=&amp;quot;Blue&amp;quot;&amp;gt;once&amp;lt;/font&amp;gt;&lt;br /&gt;
        &amp;lt;font color=&amp;quot;Blue&amp;quot;&amp;gt;Result&amp;lt;/font&amp;gt;:&amp;lt;font color=&amp;quot;Green&amp;quot;&amp;gt;&amp;quot;&amp;amp;About&amp;quot;&amp;lt;/font&amp;gt;&amp;lt;font color=&amp;quot;Red&amp;quot;&amp;gt;+&amp;lt;/font&amp;gt; Workbench_name &amp;lt;font color=&amp;quot;Red&amp;quot;&amp;gt;+&amp;lt;/font&amp;gt;&amp;lt;font color=&amp;quot;Green&amp;quot;&amp;gt; &amp;quot;...&amp;quot;&amp;lt;/font&amp;gt;&lt;br /&gt;
   &amp;lt;font color=&amp;quot;Blue&amp;quot;&amp;gt;end&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Difficulties====&lt;br /&gt;
====Possible Solution====&lt;br /&gt;
&lt;br /&gt;
===Runtime composed String containging queries===&lt;br /&gt;
 w_Project_directory_not_exist (file_name, dir_name: &amp;lt;font color=&amp;quot;Blue&amp;quot;&amp;gt;STRING&amp;lt;/font&amp;gt;):&amp;lt;font color=&amp;quot;Blue&amp;quot;&amp;gt;STRING is&amp;lt;/font&amp;gt;&lt;br /&gt;
   &amp;lt;font color=&amp;quot;Blue&amp;quot;&amp;gt;do&amp;lt;/font&amp;gt;&lt;br /&gt;
        &amp;lt;font color=&amp;quot;Blue&amp;quot;&amp;gt;create Result&amp;lt;/font&amp;gt;.make(256)&lt;br /&gt;
        &amp;lt;font color=&amp;quot;Blue&amp;quot;&amp;gt;Result&amp;lt;/font&amp;gt;.append (&amp;lt;font color=&amp;quot;Green&amp;quot;&amp;gt;&amp;quot;%NCannot open project '&amp;quot;&amp;lt;/font&amp;gt;)&lt;br /&gt;
        &amp;lt;font color=&amp;quot;Blue&amp;quot;&amp;gt;Result&amp;lt;/font&amp;gt;.append (file_name)&lt;br /&gt;
        &amp;lt;font color=&amp;quot;Blue&amp;quot;&amp;gt;Result&amp;lt;/font&amp;gt;.append (&amp;lt;font color=&amp;quot;Green&amp;quot;&amp;gt;&amp;quot;'.%N%NMake sure you have a complete EIFGEN directory in '&amp;quot;&amp;lt;/font&amp;gt;)&lt;br /&gt;
        &amp;lt;font color=&amp;quot;Blue&amp;quot;&amp;gt;Result&amp;lt;/font&amp;gt;.append (dir_name)&lt;br /&gt;
        &amp;lt;font color=&amp;quot;Blue&amp;quot;&amp;gt;Result&amp;lt;/font&amp;gt;.append (&amp;lt;font color=&amp;quot;Green&amp;quot;&amp;gt;&amp;quot;'.&amp;quot;&amp;lt;/font&amp;gt;)&lt;br /&gt;
   &amp;lt;font color=&amp;quot;Blue&amp;quot;&amp;gt;end&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Difficulties====&lt;br /&gt;
====Possible Solution====&lt;br /&gt;
==Important Classes==&lt;br /&gt;
&lt;br /&gt;
====Defining and formatting Strings====&lt;br /&gt;
&lt;br /&gt;
* INTERFACE_NAMES: Include all the strings of the ES interface (buttons, labels, shortcuts...)&lt;br /&gt;
* TEXT_FORMATTER: Text formatter for all text output formatting&lt;br /&gt;
* ERROR: Error object sent by the compiler to the workbench. Ancestor class of all error classes (WARNING, SYNTAX_ERROR, INTERRUPT_ERROR, LACE_ERROR,EIFFEL_ERROR...)&lt;br /&gt;
&lt;br /&gt;
====Implementations====&lt;br /&gt;
&lt;br /&gt;
* STRING_GENERAL: &amp;quot;Common ancestors to all STRING classes.&amp;quot; [base]&lt;br /&gt;
** STRING:  [base]&lt;br /&gt;
*** UC_STRING: Unicode strings [gobo]&lt;br /&gt;
**** UC_UTF8_STRING: Unicode strings with UTF-8 encoding&lt;br /&gt;
** STRING_32:  [base]&lt;br /&gt;
* UC_CHARACTER: Unicode characters [gobo]&lt;br /&gt;
&lt;br /&gt;
* KS_STRING: Portable interface for class STRING [Gobo]&lt;br /&gt;
* cluster: &amp;quot;gobo.kernel.unicode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* WIDE_CHARACTER: Unicode characters, with comparison operations [base]&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Category:Internationalization&amp;diff=3107</id>
		<title>Category:Internationalization</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Category:Internationalization&amp;diff=3107"/>
				<updated>2006-05-31T16:46:50Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;List of pages related to the [[internationalization]] project&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization&amp;diff=3106</id>
		<title>Internationalization</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization&amp;diff=3106"/>
				<updated>2006-05-31T16:45:13Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: created category of Internationalization project&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Projects]]&lt;br /&gt;
[[Category:Internationalization]]&lt;br /&gt;
[[Image:ebabylon.png|right|frame| Our Eiffel Tower of Babylon]]&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
&lt;br /&gt;
''&amp;quot;Many [people] would simply love seeing their computer screen showing a lot less of English, and far more of their own language.&amp;quot;'' -- gettext doc&lt;br /&gt;
&lt;br /&gt;
Our aim is not only to provide a framework to ease the translation of Eiffel-written applications, allowing the user to chose his/her preferred language at runtime, but also to let the developer access information and formats based on users' locale.&lt;br /&gt;
&lt;br /&gt;
==What is internationalisation?==&lt;br /&gt;
&lt;br /&gt;
The first thing that comes to mind is translation. But internationalisation isn't restricted to enabling translation: it includes making it possible to localise notations (time, date, numbers), measures, paper size, and much more.&lt;br /&gt;
&lt;br /&gt;
==What should we achieve?==&lt;br /&gt;
*Applications should be able to load localized strings at runtime and be provided with localized format strings (e.g date format).&lt;br /&gt;
*Developers can use tools that automagically extract strings from source code and can try to get them translated in a file to distribute along with the application.&lt;br /&gt;
*Users will still be unhappy and get depressed ''but in their own language'', which we can all agree is a significant step forward.&lt;br /&gt;
&lt;br /&gt;
==Who should do the achieving?==&lt;br /&gt;
It is clear that our [[User:Carlo|Glorious Leader]] should be credited with any achieving. However he will have to delegate things somewhat, as he is is not [http://en.wikipedia.org/wiki/Aleksei_Grigorievich_Stakhanov Stakhanov].&lt;br /&gt;
We can probably divide the project into the following parts, modulo preliminary research:&lt;br /&gt;
&lt;br /&gt;
''This should be probably be completed after we have got past M1''&lt;br /&gt;
&lt;br /&gt;
=Milestones=&lt;br /&gt;
&lt;br /&gt;
==M2: May 5 ==&lt;br /&gt;
* [[Internationalization/feasibility|feasibility]]: look at string classes (unicode and not) and how strings are used in EiffelStudio (creation, composition) ''(Ivano, Carlo, Leo, Hong)''&lt;br /&gt;
* [[Internationalization/file_format|file format]]: compare existing file formats for dictionaries ''(Etienne, Andreas)''&lt;br /&gt;
* [[Internationalization/tool_evaluation|tool evaluation]]: list and compare existing translation tools ''(Christian, Martino)''&lt;br /&gt;
&lt;br /&gt;
==M3: June ??? ==&lt;br /&gt;
* write an initial .po to start translating and have a .mo for testing ''(Leo, Carlo)''&lt;br /&gt;
* [[Internationalization/mo parser|mo parser]]: extract translated stings from .mo files ''([[User:etienner|Etienne]], [[User:Trosim|Martino]])''&lt;br /&gt;
* [[Internationalization/code_parser|code parser]]: extract strings to be translated from source code and generate .po file&lt;br /&gt;
* [[Internationalization/translation function|translation function]]: map hard-coded strings to translated strings&lt;br /&gt;
** find a solution with templates&lt;br /&gt;
** globality: how to implement, the object should be shared between all modules (see [[Internationalization/class_structure|class structure]])&lt;br /&gt;
* collaborate with the [[Vision2_and_Unicode]] team&lt;br /&gt;
* Test unicode support in Vision2 ''(Ivano)''&lt;br /&gt;
* compile a [[Internationalization/features list|list of basic features]] to provide (e.g. date/time format, system locale) ''[deferred]''&lt;br /&gt;
&lt;br /&gt;
= Possible future developments =&lt;br /&gt;
&lt;br /&gt;
* collaborate with the [[ESWizard]] team. Create wizards for programms with translation facilities.&lt;br /&gt;
&lt;br /&gt;
=Relevant Links=&lt;br /&gt;
[http://www.debian.org/doc/manuals/intro-i18n/ Introduction to i18n]&lt;br /&gt;
&lt;br /&gt;
==What other people have done==&lt;br /&gt;
[http://doc.trolltech.com/4.1/i18n.html internationalisation with QT]&lt;br /&gt;
&lt;br /&gt;
[http://oss.erdfunkstelle.de/kde-i18n/tiki-index.php?page=miniHowtoGui howto for internationalisation of KDE programs ]&lt;br /&gt;
&lt;br /&gt;
[http://l10n.kde.org/docs/translation-howto/ another KDE howto (doesn't Gnome do any internationalisation?)]&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&lt;br /&gt;
Everyone interested in this project is welcome to [http://origo.ethz.ch/cgi-bin/mailman/listinfo/es-i18n join our mailinglist] es-i18n@origo.ethz.ch&lt;br /&gt;
&lt;br /&gt;
* Project Leader: [[User:Carlo|Carlo Vanini]]&lt;br /&gt;
* [[User:leo| Leo Fellmann]]&lt;br /&gt;
* [[User:kiwi| Ivano Somaini]]&lt;br /&gt;
* [[User:murbi|Andreas Murbach]]&lt;br /&gt;
* [[User:etienner|Etienne Reichenbach]]&lt;br /&gt;
* [[User:hong |Hong Zhang]]&lt;br /&gt;
* [[User:cconti | Christian Conti]]&lt;br /&gt;
* [[User:Trosim |Martino Trosi]]&lt;br /&gt;
* [[User:Schoelle| Bernd Schoeller]]&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/plural_forms&amp;diff=3105</id>
		<title>Internationalization/plural forms</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/plural_forms&amp;diff=3105"/>
				<updated>2006-05-31T15:56:05Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: /* =Three forms, special case for numbers ending in 1[2-9] */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The information about the plural form selection has to be stored in the header entry of the PO file (the one with the empty msgid string). The plural form information looks like this: &lt;br /&gt;
::Plural-Forms: nplurals=2; plural=n == 1 ? 0 : 1;&lt;br /&gt;
&lt;br /&gt;
The ''nplurals'' value must be a decimal number which specifies how many different plural forms exist for this language. The string following plural is an expression which is using the C language syntax. Exceptions are that no negative numbers are allowed, numbers must be decimal, and the only variable allowed is ''n''. This expression will be evaluated whenever one of the [[internationalization/translation_function|translation function]] for a &amp;quot;plural form&amp;quot; is called. The numeric value passed to these functions is then substituted for all uses of the variable n in the expression. The resulting value then must be greater or equal to zero and smaller than the value given as the value of ''nplurals''.&lt;br /&gt;
&lt;br /&gt;
==Rules==&lt;br /&gt;
The (at this point) known rules are:&lt;br /&gt;
===Only one form===&lt;br /&gt;
&lt;br /&gt;
Some languages only require one single form. There is no distinction between the singular and plural form. An appropriate header entry would look like this: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=1; plural=0;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Finno-Ugric family &lt;br /&gt;
:*Hungarian &lt;br /&gt;
:*Asian family &lt;br /&gt;
:*Japanese, Korean &lt;br /&gt;
:*Turkic/Altaic family &lt;br /&gt;
:*Turkish &lt;br /&gt;
&lt;br /&gt;
===Two forms, singular used for one only===&lt;br /&gt;
&lt;br /&gt;
This is the form used in most existing programs since it is what English is using. A header entry would look like this: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=2; plural=n != 1;&lt;br /&gt;
:::(Note: this uses the feature of C expressions that boolean expressions have to value zero or one.) &lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Germanic family &lt;br /&gt;
:*Danish, Dutch, English, German, Norwegian, Swedish &lt;br /&gt;
:*Finno-Ugric family &lt;br /&gt;
:*Estonian, Finnish &lt;br /&gt;
:*Latin/Greek family &lt;br /&gt;
:*Greek &lt;br /&gt;
:*Semitic family &lt;br /&gt;
:*Hebrew &lt;br /&gt;
:*Romanic family &lt;br /&gt;
:*Italian, Portuguese, Spanish &lt;br /&gt;
:*Artificial &lt;br /&gt;
:*Esperanto &lt;br /&gt;
&lt;br /&gt;
===Two forms, singular used for zero and one===&lt;br /&gt;
&lt;br /&gt;
Exceptional case in the language family. The header entry would be: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=2; plural=n&amp;gt;1;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Romanic family &lt;br /&gt;
:*French, Brazilian Portuguese &lt;br /&gt;
&lt;br /&gt;
===Three forms, special case for zero===&lt;br /&gt;
&lt;br /&gt;
The header entry would be: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=3; plural=n%10==1 &amp;amp;&amp;amp; n%100!=11 ? 0 : n != 0 ? 1 : 2;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Baltic family &lt;br /&gt;
:*Latvian &lt;br /&gt;
&lt;br /&gt;
===Three forms, special cases for one and two===&lt;br /&gt;
The header entry would be: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=3; plural=n==1 ? 0 : n==2 ? 1 : 2;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Celtic &lt;br /&gt;
:*Gaeilge (Irish) &lt;br /&gt;
&lt;br /&gt;
===Three forms, special case for numbers ending in 1[2-9]===&lt;br /&gt;
&lt;br /&gt;
The header entry would look like this: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=3; \&lt;br /&gt;
::plural=n%10==1 &amp;amp;&amp;amp; n%100!=11 ? 0 : \&lt;br /&gt;
::::::::n%10&amp;gt;=2 &amp;amp;&amp;amp; (n%100&amp;lt;10 || n%100&amp;gt;=20) ? 1 : 2;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Baltic family &lt;br /&gt;
:*Lithuanian&lt;br /&gt;
&lt;br /&gt;
===Three forms, special cases for numbers ending in 1 and 2, 3, 4, except those ending in 1[1-4]===&lt;br /&gt;
&lt;br /&gt;
The header entry would look like this: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=3; \&lt;br /&gt;
::plural=n%10==1 &amp;amp;&amp;amp; n%100!=11 ? 0 : \&lt;br /&gt;
::::n%10&amp;gt;=2 &amp;amp;&amp;amp; n%10&amp;lt;=4 &amp;amp;&amp;amp; (n%100&amp;lt;10 || n%100&amp;gt;=20) ? 1 : 2;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Slavic family &lt;br /&gt;
:*Croatian, Czech, Russian, Slovak, Ukrainian &lt;br /&gt;
&lt;br /&gt;
===Three forms, special case for one and some numbers ending in 2, 3, or 4===&lt;br /&gt;
&lt;br /&gt;
The header entry would look like this: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=3; \&lt;br /&gt;
::plural=n==1 ? 0 : \&lt;br /&gt;
::::n%10&amp;gt;=2 &amp;amp;&amp;amp; n%10&amp;lt;=4 &amp;amp;&amp;amp; (n%100&amp;lt;10 || n%100&amp;gt;=20) ? 1 : 2;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Slavic family &lt;br /&gt;
:*Polish &lt;br /&gt;
&lt;br /&gt;
===Four forms, special case for one and all numbers ending in 02, 03, or 04===&lt;br /&gt;
&lt;br /&gt;
The header entry would look like this: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=4; \&lt;br /&gt;
::plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Slavic family &lt;br /&gt;
:*Slovenian&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/translation_function&amp;diff=3101</id>
		<title>Internationalization/translation function</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/translation_function&amp;diff=3101"/>
				<updated>2006-05-31T14:47:55Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: plural forms link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
&lt;br /&gt;
The problem for the translation is that we need a way to translate tree different types of string:&lt;br /&gt;
&lt;br /&gt;
* normal strings&lt;br /&gt;
 &amp;lt;code&amp;gt;[eiffel,N] &amp;quot;A normal string&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* composed string &lt;br /&gt;
 &amp;lt;code&amp;gt;[eiffel,N] &amp;quot;A string composed by &amp;quot;+count.out+&amp;quot; strings, like this or &amp;quot;+a_string+&amp;quot;%N&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* strings with plural form&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
 if n=1 then&lt;br /&gt;
     Result := &amp;quot;a string&amp;quot;&lt;br /&gt;
 else&lt;br /&gt;
    Result := &amp;quot;strings&amp;quot;&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An other problem is that not all languages have the same rule for plural forms, see below and [[internationalization/plural_forms|here]] for more details.&lt;br /&gt;
&lt;br /&gt;
==Possible solution==&lt;br /&gt;
&lt;br /&gt;
I [[Talk:Internationalization/translation_function|'''propose''']] a solution, with four functions (I've got little fantasy for the function names):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
i18n (a_string : STRING) : STRING&lt;br /&gt;
    --Function for the translation of normal strings&lt;br /&gt;
&lt;br /&gt;
i18n_pl (strings : TUPLE[STRING]; form : INTEGER) : STRING&lt;br /&gt;
    --Function for the translation of normal strings&lt;br /&gt;
    -- with plural form&lt;br /&gt;
&lt;br /&gt;
i18n_comp (a_string : STRING; args : TUPLE) : STRING&lt;br /&gt;
    --Function for the translation of composit strings&lt;br /&gt;
&lt;br /&gt;
i18n_comp_pl (strings : TUPLE[STRING]; args : TUPLE; form : INTEGER) : STRING&lt;br /&gt;
    --Function for the translation of composit&lt;br /&gt;
    -- strings with plural forms&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With this solution, the programmer should write composit strings as (or in a similar way) he would do it for the C ''printf'' function. The composit string above would be somthing like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N] i18n_comp(&amp;quot;A string composed by %a1 strings, like this or %a2%N&amp;quot;, [count, a_string])&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where ''%a1'' 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.&lt;br /&gt;
&lt;br /&gt;
===An example===&lt;br /&gt;
&lt;br /&gt;
A complete example of how it could work.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Piece of code without internationalization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
if n = 1&lt;br /&gt;
io.put_string(&amp;quot;Remove file &amp;quot;+file_name.out+&amp;quot;?%N&amp;quot;)&lt;br /&gt;
else&lt;br /&gt;
io.put_string (&amp;quot;Delete following files?&amp;quot;+list.out+&amp;quot; there are &amp;quot;&lt;br /&gt;
                +list.count.out+&amp;quot;files%N&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Piece of code with internationalization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
io.put_string([&amp;quot;Remove file %a1?%N&amp;quot;,&lt;br /&gt;
                &amp;quot;Delete following files? %a2 there are %a3 files%N&amp;quot;],&lt;br /&gt;
                [file_name, list, list_count], n)&lt;br /&gt;
[...]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the content of the PO file would be:&lt;br /&gt;
&lt;br /&gt;
 #: A comment&lt;br /&gt;
 msgid &amp;quot;Remove file %a1?%N&amp;quot;&lt;br /&gt;
 msgid_plural &amp;quot;Delete following files? %a2 there are %a3 files%N&amp;quot;&lt;br /&gt;
 msgstr[0] &amp;quot;Rimuovere il file %a1?&amp;quot;&lt;br /&gt;
 msgstr[1] &amp;quot;Cancellare i seguenti file? %a2 ce ne sono %a3%N&amp;quot;&lt;br /&gt;
&lt;br /&gt;
You might ask yourself, ''why a function for all the pluralforms''?&lt;br /&gt;
&lt;br /&gt;
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). &lt;br /&gt;
But other language families have only one form or many forms. For example,&lt;br /&gt;
&lt;br /&gt;
In Polish the translation of file is plik, and the plural forms are: &lt;br /&gt;
 &lt;br /&gt;
:2,3,4 pliki&lt;br /&gt;
:5-21 pliko'w&lt;br /&gt;
:22-24 pliki&lt;br /&gt;
:25-31 pliko'w&lt;br /&gt;
:and so on...&lt;br /&gt;
&lt;br /&gt;
for more information about this topic go [http://www.gnu.org/software/gettext/manual/html_mono/gettext.html#SEC150 here]&lt;br /&gt;
&lt;br /&gt;
==Additional things==&lt;br /&gt;
&lt;br /&gt;
A nice thing whe could do, when parsing the source code of a program to internationalize, is to recognize comments about the string.&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel,N]&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
io.put_string([&amp;quot;Remove file %a1?%N&amp;quot;,&lt;br /&gt;
                &amp;quot;Delete following files? %a2 there are %a3 files%N&amp;quot;],&lt;br /&gt;
                [file_name, list, list_count], n)&lt;br /&gt;
--A comment of the author&lt;br /&gt;
[...]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
woud then look like this in the PO file:&lt;br /&gt;
&lt;br /&gt;
 #. A comment of the author&lt;br /&gt;
 #. Function name, class name, file path&lt;br /&gt;
 #. %a1 = file_name&lt;br /&gt;
 #. %a2 = list&lt;br /&gt;
 #. %a3 = list_count&lt;br /&gt;
 msgid &amp;quot;Remove file %a1?%N&amp;quot;&lt;br /&gt;
 msgid_plural &amp;quot;Delete following files? %a2 there are %a3 files%N&amp;quot;&lt;br /&gt;
 msgstr[0] &amp;quot;Rimuovere il file %a1?&amp;quot;&lt;br /&gt;
 msgstr[1] &amp;quot;Cancellare i seguenti file? %a2 ce ne sono %a3%N&amp;quot;&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/plural_forms&amp;diff=3100</id>
		<title>Internationalization/plural forms</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/plural_forms&amp;diff=3100"/>
				<updated>2006-05-31T14:44:27Z</updated>
		
		<summary type="html">&lt;p&gt;Etienner: list of known forms&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The information about the plural form selection has to be stored in the header entry of the PO file (the one with the empty msgid string). The plural form information looks like this: &lt;br /&gt;
::Plural-Forms: nplurals=2; plural=n == 1 ? 0 : 1;&lt;br /&gt;
&lt;br /&gt;
The ''nplurals'' value must be a decimal number which specifies how many different plural forms exist for this language. The string following plural is an expression which is using the C language syntax. Exceptions are that no negative numbers are allowed, numbers must be decimal, and the only variable allowed is ''n''. This expression will be evaluated whenever one of the [[internationalization/translation_function|translation function]] for a &amp;quot;plural form&amp;quot; is called. The numeric value passed to these functions is then substituted for all uses of the variable n in the expression. The resulting value then must be greater or equal to zero and smaller than the value given as the value of ''nplurals''.&lt;br /&gt;
&lt;br /&gt;
==Rules==&lt;br /&gt;
The (at this point) known rules are:&lt;br /&gt;
===Only one form===&lt;br /&gt;
&lt;br /&gt;
Some languages only require one single form. There is no distinction between the singular and plural form. An appropriate header entry would look like this: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=1; plural=0;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Finno-Ugric family &lt;br /&gt;
:*Hungarian &lt;br /&gt;
:*Asian family &lt;br /&gt;
:*Japanese, Korean &lt;br /&gt;
:*Turkic/Altaic family &lt;br /&gt;
:*Turkish &lt;br /&gt;
&lt;br /&gt;
===Two forms, singular used for one only===&lt;br /&gt;
&lt;br /&gt;
This is the form used in most existing programs since it is what English is using. A header entry would look like this: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=2; plural=n != 1;&lt;br /&gt;
:::(Note: this uses the feature of C expressions that boolean expressions have to value zero or one.) &lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Germanic family &lt;br /&gt;
:*Danish, Dutch, English, German, Norwegian, Swedish &lt;br /&gt;
:*Finno-Ugric family &lt;br /&gt;
:*Estonian, Finnish &lt;br /&gt;
:*Latin/Greek family &lt;br /&gt;
:*Greek &lt;br /&gt;
:*Semitic family &lt;br /&gt;
:*Hebrew &lt;br /&gt;
:*Romanic family &lt;br /&gt;
:*Italian, Portuguese, Spanish &lt;br /&gt;
:*Artificial &lt;br /&gt;
:*Esperanto &lt;br /&gt;
&lt;br /&gt;
===Two forms, singular used for zero and one===&lt;br /&gt;
&lt;br /&gt;
Exceptional case in the language family. The header entry would be: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=2; plural=n&amp;gt;1;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Romanic family &lt;br /&gt;
:*French, Brazilian Portuguese &lt;br /&gt;
&lt;br /&gt;
===Three forms, special case for zero===&lt;br /&gt;
&lt;br /&gt;
The header entry would be: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=3; plural=n%10==1 &amp;amp;&amp;amp; n%100!=11 ? 0 : n != 0 ? 1 : 2;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Baltic family &lt;br /&gt;
:*Latvian &lt;br /&gt;
&lt;br /&gt;
===Three forms, special cases for one and two===&lt;br /&gt;
The header entry would be: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=3; plural=n==1 ? 0 : n==2 ? 1 : 2;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Celtic &lt;br /&gt;
:*Gaeilge (Irish) &lt;br /&gt;
&lt;br /&gt;
===Three forms, special case for numbers ending in 1[2-9]==&lt;br /&gt;
&lt;br /&gt;
The header entry would look like this: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=3; \&lt;br /&gt;
::plural=n%10==1 &amp;amp;&amp;amp; n%100!=11 ? 0 : \&lt;br /&gt;
::::::::n%10&amp;gt;=2 &amp;amp;&amp;amp; (n%100&amp;lt;10 || n%100&amp;gt;=20) ? 1 : 2;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Baltic family &lt;br /&gt;
:*Lithuanian &lt;br /&gt;
&lt;br /&gt;
===Three forms, special cases for numbers ending in 1 and 2, 3, 4, except those ending in 1[1-4]===&lt;br /&gt;
&lt;br /&gt;
The header entry would look like this: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=3; \&lt;br /&gt;
::plural=n%10==1 &amp;amp;&amp;amp; n%100!=11 ? 0 : \&lt;br /&gt;
::::n%10&amp;gt;=2 &amp;amp;&amp;amp; n%10&amp;lt;=4 &amp;amp;&amp;amp; (n%100&amp;lt;10 || n%100&amp;gt;=20) ? 1 : 2;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Slavic family &lt;br /&gt;
:*Croatian, Czech, Russian, Slovak, Ukrainian &lt;br /&gt;
&lt;br /&gt;
===Three forms, special case for one and some numbers ending in 2, 3, or 4===&lt;br /&gt;
&lt;br /&gt;
The header entry would look like this: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=3; \&lt;br /&gt;
::plural=n==1 ? 0 : \&lt;br /&gt;
::::n%10&amp;gt;=2 &amp;amp;&amp;amp; n%10&amp;lt;=4 &amp;amp;&amp;amp; (n%100&amp;lt;10 || n%100&amp;gt;=20) ? 1 : 2;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Slavic family &lt;br /&gt;
:*Polish &lt;br /&gt;
&lt;br /&gt;
===Four forms, special case for one and all numbers ending in 02, 03, or 04===&lt;br /&gt;
&lt;br /&gt;
The header entry would look like this: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=4; \&lt;br /&gt;
::plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Slavic family &lt;br /&gt;
:*Slovenian&lt;/div&gt;</summary>
		<author><name>Etienner</name></author>	</entry>

	</feed>