On 23/05/13 11:23, Adam D. Ruppe wrote:
I've never actually done i18n so I might be full of crap, but I think a
nice way to do it would be something along these lines:

1) (optionally) all printing functions actually take a different type
than just plain string, forcing you to use the translation function

Not all strings should be translated. So you need a way to say which ones do need to be translated. Many schemes have been invented over the years (by Sun, Microsoft, etc.) but most of them died when gettext() came along as they were all very complex compared to gettext() and usually involved creating digests and giving strings id numbers etc. which rapidly became a maintenance nightmare.

The key simplicity of gettext() is the each string is its own identifier and notification that a string needs translating and doing the translation call is the one piece of code.

There is a minor complication with using strings declared as variables in COMPILED languages as the translation can't be done at compile time so they have two notations:

1. what I described above it gettext('string') means mark 'string' for translation and also return me the translation of 'string' i.e. a compile time meaning and a runtime meaning 2. a second template gettext_noop('string') which just means mark the string for translation and that's all. In C and C++ this is usually just a macro that does nothing. Then when you need the string variable later on you use gettext(<variable name>) to get the translation. NB down in the guts it's just the contents of the string that is used as the key in the translation mechanism and there's no need to track the fact that it contains a translatable string. Gettext() never fails and if it's called with a string that it cant find the translation for it just returns its argument unchanged. In D, I imagine the best way to do this would be to have some sort of qualifier that could be used as part of the string variable declaration to tag it as a target for translation.

One of the things that is useful when doing i18n is having writef, etc. have the ability to specify which arguments should be placed where in the format string as it sometimes necessary to reorder them in order to make a translation that makes sense in the target language (as not all languages have a subject-verb-object grammar e.g. Yoda).

An example of how I would envisage gettext being used in D is:

writefln(gettext("%s: unknown variable at line %s"), filename, linenumber);

It is a common practice, to define a macro (or equivalent) _(arg) as an alias for gettext(arg) (and N_(arg) for gettext_noop(arg)) because people like brevity.

I would suggest using the gettext() functionality for i18n but design the notation used within programs (to access that functionality) according to what best suits the D paradigm.

Peter


Reply via email to