gnustep-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Localization


From: Nicola Pero
Subject: Re: Localization
Date: Mon, 26 Feb 2001 01:23:31 +0100 (CET)

>    * _(): Saves typing, but again adds to the list of GNUstep-specific
> features.  

> Furthermore, this to me seems rather silly.  If you want to localize
> your program, you need to hand off the Localizable.strings file to your
> translators *with comments*. 

Ah ah - alarm bell - `rather silly' ? - nobody is forcing you to use it. 
Don't use it if you don't like it.  It's just a trivial macro, 

#define _(X) NSLocalizedString (X, nil)

About the necessity of comments, I don't agree.  Don't forget that all GNU
programs (non-GNUstep) are translated using gettext, which doesn't hand
off any comments to the translator.  The reason it works is - IMO - that
comments are often (but not always) useless.  The advantage of no comments
is that localization is simple and unexpensive for the programmer, because
you can localize without having to write a comment on each string in your
program - which is an expensive, tiring and boring activity.

Comments are a feature we have and they don't and we need to use it at our
advantage - not at our disadvantage - I think this means I should not
spend a huge amount of time adding a comment to each string in my programs
- that's wasting time - but instead selectively add a comment only to
strings which _do_ need a comment.  If I am adding a comment to the `Game
Over' string in a game, I am just wasting my time.  The same goes for
messages like `Sorry, you loose.' or `Great!  You win.' or `There are
unsaved files.  Quit anyway ?'.  These don't need any comment, and the
programmer is wasting time if she is adding comments to these obviously
clear messages.  Actually, in a good program, most strings should not need
any explanatory comment - because messages to the user should be clear and
understandable and should not need an additional comment to explain what
they mean.  There *are* exceptions, which are going mostly to be single
words or very short strings which are difficult to understand outside
context - for example, `Arrange' - how do you know what that mean if you
don't know it's in the Windows menu - and of course you can't translate a
string if you don't understand what the string mean.  We *must* use
comments in all these cases.  But I think it is good practice *not* to use
comments when they are useless - because you are sparing time which you
can use better.  Avoid spending time in useless tasks and concentrate on
the useful ones - this is a basic rule. 

Anyway - that's how *I* plan to work - you can do differently.  If you
want to use comments in all strings of your code - that's completely fine
to me - I respect your opinion that comments are essential and the way you
plan and organize your work.


> If you don't care yet about localization, why use a macro at all?

By using _(), I *do* care about localization.  Perhaps I don't have time
to add a comment to all strings, but I am localizing them. I am localizing
the program in the same way *any* standard GNU program is localized -
without comments.  Then - when I get more time - perhaps when I see the
program actually has users :-) and/or actually *is* being translated in
other languages by other people rather than only translated in my own
language by myself :-) - then I can spend the effort of adding comments to
strings difficult to understand outside context - to make my localization
better and help the translators if they need.  Perhaps they could ask me
about the strings they don't understand and we could add comments for
those particular strings.


>    * NSLocalizedStaticString(), and __(): No comment.  The utility of
> these functions escapes me. 

Ok - take for example GSTest.

There is a list of bundles - each bundle contains a test.  This list is
displayed in a submenu.  Now the list is contained in a file, testList.h. 
Code in another file loads the list - which is a statically allocated
array - and builds the menu from the list.  For each entry, it reads from
the list the bundle name and the string to display in the menu item. The
advantage is - to add or remove tests, you only edit the list in
testList.h - by just adding or removing the bundle name and the string to
display in the menu item - and all works immediately with one test more
(/less) without touching the code.

When I translate that to Italian, I could want to translate the strings
shown on the menu.  Up to now I wouldn't - because the strings are just
class names - but if someone adds a test, say, called `Cut & Paste' (to
test cut & paste, not such a remote possibility at all), I would certainly
want to translate this menu string in Italian, to `Taglia & Incolla'. 

How do I translate this ? 

The answer is - pure openstep can't do that - but gettext can.

You need to call NSLocalizedString on each menu string.  But you can't do
it inside the list in testList.h, because there the array is statically
created and you can't put a function call inside it.  So, you need to call
NSLocalizedString when the string is used - in the example, in main.m:

for (i = 0; i < TEST_NUMBER; i++)
  {
    NSString *title;

    title = NSLocalizedString (testList[i].menuName, nil);

    menuItem = [testMenu addItemWithTitle: title
                         action: @selector(startListedTest:)
                         keyEquivalent: @""];
    [menuItem setTag: i];
    testState[i].isStarted = NO;
  }

And this works, except that... the tool to generate the
Localizable.strings file can't find the strings! Because they are passed
to NSLocalizedString as a variable which points to the real string!  The
tool only looks for explicit @"xxx" arguments to NSLocalizedString, it
can't manage (of course) variables.  So, the tool will *not* find the
strings - will *not* put them into the Localizable.strings file - and they
will *not* be translated.  Which is what I mean when I say `pure openstep
can't do that'.

Now gettext can manage that with an elegant solution - so why can't we do
the same.  It's a trivial extension - if you don't want to use it - then
don't use it - but if I ever need to generate a Localizable.strings for my
testList, I want it to be possible, so I need it.

We need to mark in someway the strings inside the statically allocated
array as strings which need to be put in the Localizable.strings file. 
That we do with the no-op macro __() or NSLocalizedStaticString (). These
macros do nothing, but the tool which generates the Localizable.strings
file will look for those macros too, and add the strings to the
Localizable.strings file.  It is understood that this is needed because
the strings will be loaded somewhere else into a variable, and then passed
via the variable to a call to NSLocalizedString. 






reply via email to

[Prev in Thread] Current Thread [Next in Thread]