[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Pnet-developers] RFC: GNU gettext support for C#
From: |
Bruno Haible |
Subject: |
[Pnet-developers] RFC: GNU gettext support for C# |
Date: |
Mon, 29 Dec 2003 13:17:30 +0100 |
User-agent: |
KMail/1.5 |
Hi,
Before I release gettext 0.14 with support for C#, I'd like to present
the planned (and already implemented) features. Comments and suggestions
are very welcome.
NEWS:
=============================================================================
* Programming languages support:
- C#:
xgettext now also supports C#.
New library: GNU.Gettext.dll contains the runtime for using GNU gettext
message catalogs in C#.
msgfmt can create (and msgunfmt can dump) message catalogs for C#.
* Documentation:
- New documentation section: C#.
- Complete examples illustrating the use of gettext in C# (in text mode and
in Forms applications) have been added.
=============================================================================
Documentation:
=============================================================================
C#
--
RPMs
pnet, pnetlib
File extension
`cs'
String syntax
`"abc"', `@"abc"'
gettext shorthand
_("abc")
gettext/ngettext functions
`GettextResourceManager.GetString',
`GettextResourceManager.GetPluralString'
textdomain
`new GettextResourceManager(domain)'
bindtextdomain
--, compiled message catalogs are located in subdirectories of the
directory containing the executable
setlocale
automatic
Prerequisite
--
Use or emulate GNU gettext
--, uses a C# specific message catalog format
Extractor
`xgettext -k_'
Formatting with positions
`String.Format "{1} {0}"'
Portability
fully portable
po-mode marking
--
Before marking strings as internationalizable, uses of the string
concatenation operator need to be converted to `String.Format'
invocations. For example, `"file "+filename+" not found"' becomes
`String.Format("file {0} not found", filename)'. Only after this is
done, can the strings be marked and extracted.
GNU gettext uses the native C#/.NET internationalization mechanism,
namely the classes `ResourceManager' and `ResourceSet'. Applications
use the `ResourceManager' methods to retrieve the native language
translation of strings. An instance of `ResourceSet' is the in-memory
representation of a message catalog file. The `ResourceManager' loads
and accesses `ResourceSet' instances as needed to look up the
translations.
There are two formats of `ResourceSet's that can be directly loaded
by the C# runtime: `.resources' files and `.dll' files.
* The `.resources' format is a binary file usually generated through
the `resgen' or `monoresgen' utility, but which doesn't support
plural forms. `.resources' files can also be embedded in .NET
`.exe' files. This only affects whether a file system access is
performed to load the message catalog; it doesn't affect the
contents of the message catalog.
* On the other hand, the `.dll' format is a binary file that is
compiled from `.cs' source code and can support plural forms
(provided it is accessed through the GNU gettext API, see below).
Note that these .NET `.dll' and `.exe' files are not tied to a
particular platform; their file format and GNU gettext for C# can be
used on any platform.
To convert a PO file to a `.resources' file, the `msgfmt' program
can be used with the option `--csharp-resources'. To convert a
`.resources' file back to a PO file, the `msgunfmt' program can be used
with the option `--csharp-resources'. You can also, in some cases, use
the `resgen' program (from the `pnet' package) or the `monoresgen'
program (from the `mono'/`mcs' package). These programs can also
convert a `.resources' file back to a PO file. But beware: as of this
writing (December 2003), these two converters are quite buggy.
To convert a PO file to a `.dll' file, the `msgfmt' program can be
used with the option `--csharp'. The result will be a `.dll' file
containing a subclass of `GettextResourceSet', which itself is a
subclass of `ResourceSet'. To convert a `.dll' file containing a
`GettextResourceSet' subclass back to a PO file, the `msgunfmt' program
can be used with the option `--csharp'.
The advantages of the `.dll' format over the `.resources' format are:
1. Freedom to localize: Users can add their own translations to an
application after it has been built and distributed. Whereas when
the programmer uses a `ResourceManager' constructor provided by
the system, the set of `.resources' files for an application must
be specified when the application is built and cannot be extended
afterwards.
2. Plural handling: A message catalog in `.dll' format supports the
plural handling function `GetPluralString'. Whereas `.resources'
files can only contain data and only support lookups that depend
on a single string.
3. The `GettextResourceManager' that loads the message catalogs in
`.dll' format also provides for inheritance on a per-message basis.
For example, in Austrian (`de_AT') locale, translations from the
German (`de') message catalog will be used for messages not found
in the Austrian message catalog. This has the consequence that
the Austrian translators need only translate those few messages
for which the translation into Austrian differs from the German
one. Whereas when working with `.resources' files, each message
catalog must provide the translations of all messages by itself.
4. The `GettextResourceManager' that loads the message catalogs in
`.dll' format also provides for a fallback: The English MSGID is
returned when no translation can be found. Whereas when working
with `.resources' files, a language-neutral `.resources' file must
explicitly be provided as a fallback.
On the side of the programmatic APIs, the programmer can use either
the standard `ResourceManager' API and the GNU `GettextResourceManager'
API. The latter is an extension of the former, because
`GettextResourceManager' is a subclass of `ResourceManager'.
1. The `System.Resources.ResourceManager' API.
This API works with resources in `.resources' format.
The creation of the `ResourceManager' is done through
new ResourceManager(domainname, Assembly.GetExecutingAssembly())
The `GetString' function returns a string's translation. Note
that this function returns null when a translation is missing
(i.e. not even found in the fallback resource file).
2. The `GNU.Gettext.GettextResourceManager' API.
This API works with resources in `.dll' format.
Reference documentation is in the csharpdoc directory
(csharpdoc/index.html).
The creation of the `ResourceManager' is done through
new GettextResourceManager(domainname)
The `GetString' function returns a string's translation. Note
that when a translation is missing, the MSGID argument is returned
unchanged.
The `GetPluralString' function returns a string translation with
plural handling, like the `ngettext' function in C.
To use this API, one needs the `GNU.Gettext.dll' file which is
part of the GNU gettext package and distributed under the LGPL.
You can also mix both approaches: use the
`GNU.Gettext.GettextResourceManager' constructor, but otherwise use
only the `ResourceManager' type and only the `GetString' method. This
is appropriate when you want to profit from the tools for PO files, but
don't want to change an existing source code that uses
`ResourceManager' and don't (yet) need the `GetPluralString' method.
Two examples, using the second API, are available in the `examples'
directory: `hello-csharp', `hello-csharp-forms'.
=============================================================================
Example program (now you see why all my bugreports have the name hello.cs :-))
============================= hello.cs ==================================
using System; /* String, Console */
using GNU.Gettext; /* GettextResourceManager */
using System.Diagnostics; /* Process */
public class Hello {
public static void Main (String[] args) {
GettextResourceManager catalog =
new GettextResourceManager("hello-csharp");
Console.WriteLine(catalog.GetString("Hello, world!"));
Console.WriteLine(
String.Format(
catalog.GetString("This program is running as process number {0}."),
Process.GetCurrentProcess().Id));
}
}
============================================================================
Comments?
Bruno
- [Pnet-developers] RFC: GNU gettext support for C#,
Bruno Haible <=