1111 lines
50 KiB
Plaintext
1111 lines
50 KiB
Plaintext
This is Info file gettext.info, produced by Makeinfo version 1.68 from
|
||
the input file gettext.texi.
|
||
|
||
INFO-DIR-SECTION GNU Gettext Utilities
|
||
START-INFO-DIR-ENTRY
|
||
* Gettext: (gettext). GNU gettext utilities.
|
||
* gettextize: (gettext)gettextize Invocation. Prepare a package for gettext.
|
||
* msgfmt: (gettext)msgfmt Invocation. Make MO files out of PO files.
|
||
* msgmerge: (gettext)msgmerge Invocation. Update two PO files into one.
|
||
* xgettext: (gettext)xgettext Invocation. Extract strings into a PO file.
|
||
END-INFO-DIR-ENTRY
|
||
|
||
This file provides documentation for GNU `gettext' utilities. It
|
||
also serves as a reference for the free Translation Project.
|
||
|
||
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
|
||
|
||
Permission is granted to make and distribute verbatim copies of this
|
||
manual provided the copyright notice and this permission notice are
|
||
preserved on all copies.
|
||
|
||
Permission is granted to copy and distribute modified versions of
|
||
this manual under the conditions for verbatim copying, provided that
|
||
the entire resulting derived work is distributed under the terms of a
|
||
permission notice identical to this one.
|
||
|
||
Permission is granted to copy and distribute translations of this
|
||
manual into another language, under the above conditions for modified
|
||
versions, except that this permission notice may be stated in a
|
||
translation approved by the Foundation.
|
||
|
||
|
||
File: gettext.info, Node: Optimized gettext, Prev: Locating Catalogs, Up: gettext
|
||
|
||
Optimization of the *gettext functions
|
||
--------------------------------------
|
||
|
||
At this point of the discussion we should talk about an advantage of
|
||
the GNU `gettext' implementation. Some readers might have pointed out
|
||
that an internationalized program might have a poor performance if some
|
||
string has to be translated in an inner loop. While this is unavoidable
|
||
when the string varies from one run of the loop to the other it is
|
||
simply a waste of time when the string is always the same. Take the
|
||
following example:
|
||
|
||
{
|
||
while (...)
|
||
{
|
||
puts (gettext ("Hello world"));
|
||
}
|
||
}
|
||
|
||
When the locale selection does not change between two runs the resulting
|
||
string is always the same. One way to use this is:
|
||
|
||
{
|
||
str = gettext ("Hello world");
|
||
while (...)
|
||
{
|
||
puts (str);
|
||
}
|
||
}
|
||
|
||
But this solution is not usable in all situation (e.g. when the locale
|
||
selection changes) nor is it good readable.
|
||
|
||
The GNU C compiler, version 2.7 and above, provide another solution
|
||
for this. To describe this we show here some lines of the
|
||
`intl/libgettext.h' file. For an explanation of the expression command
|
||
block see *Note Statements and Declarations in Expressions:
|
||
(gcc)Statement Exprs.
|
||
|
||
# if defined __GNUC__ && __GNUC__ == 2 && __GNUC_MINOR__ >= 7
|
||
extern int _nl_msg_cat_cntr;
|
||
# define dcgettext(domainname, msgid, category) \
|
||
(__extension__ \
|
||
({ \
|
||
char *result; \
|
||
if (__builtin_constant_p (msgid)) \
|
||
{ \
|
||
static char *__translation__; \
|
||
static int __catalog_counter__; \
|
||
if (! __translation__ \
|
||
|| __catalog_counter__ != _nl_msg_cat_cntr) \
|
||
{ \
|
||
__translation__ = \
|
||
dcgettext__ ((domainname), (msgid), (category)); \
|
||
__catalog_counter__ = _nl_msg_cat_cntr; \
|
||
} \
|
||
result = __translation__; \
|
||
} \
|
||
else \
|
||
result = dcgettext__ ((domainname), (msgid), (category)); \
|
||
result; \
|
||
}))
|
||
# endif
|
||
|
||
The interesting thing here is the `__builtin_constant_p' predicate.
|
||
This is evaluated at compile time and so optimization can take place
|
||
immediately. Here two cases are distinguished: the argument to
|
||
`gettext' is not a constant value in which case simply the function
|
||
`dcgettext__' is called, the real implementation of the `dcgettext'
|
||
function.
|
||
|
||
If the string argument *is* constant we can reuse the once gained
|
||
translation when the locale selection has not changed. This is exactly
|
||
what is done here. The `_nl_msg_cat_cntr' variable is defined in the
|
||
`loadmsgcat.c' which is available in `libintl.a' and is changed
|
||
whenever a new message catalog is loaded.
|
||
|
||
|
||
File: gettext.info, Node: Comparison, Next: Using libintl.a, Prev: gettext, Up: Programmers
|
||
|
||
Comparing the Two Interfaces
|
||
============================
|
||
|
||
The following discussion is perhaps a little bit colored. As said
|
||
above we implemented GNU `gettext' following the Uniforum proposal and
|
||
this surely has its reasons. But it should show how we came to this
|
||
decision.
|
||
|
||
First we take a look at the developing process. When we write an
|
||
application using NLS provided by `gettext' we proceed as always. Only
|
||
when we come to a string which might be seen by the users and thus has
|
||
to be translated we use `gettext("...")' instead of `"..."'. At the
|
||
beginning of each source file (or in a central header file) we define
|
||
|
||
#define gettext(String) (String)
|
||
|
||
Even this definition can be avoided when the system supports the
|
||
`gettext' function in its C library. When we compile this code the
|
||
result is the same as if no NLS code is used. When you take a look at
|
||
the GNU `gettext' code you will see that we use `_("...")' instead of
|
||
`gettext("...")'. This reduces the number of additional characters per
|
||
translatable string to *3* (in words: three).
|
||
|
||
When now a production version of the program is needed we simply
|
||
replace the definition
|
||
|
||
#define _(String) (String)
|
||
|
||
by
|
||
|
||
#include <libintl.h>
|
||
#define _(String) gettext (String)
|
||
|
||
Additionally we run the program `xgettext' on all source code file
|
||
which contain translatable strings and that's it: we have a running
|
||
program which does not depend on translations to be available, but which
|
||
can use any that becomes available.
|
||
|
||
The same procedure can be done for the `gettext_noop' invocations
|
||
(*note Special cases::.). First you can define `gettext_noop' to a
|
||
no-op macro and later use the definition from `libintl.h'. Because
|
||
this name is not used in Suns implementation of `libintl.h', you should
|
||
consider the following code for your project:
|
||
|
||
#ifdef gettext_noop
|
||
# define N_(String) gettext_noop (String)
|
||
#else
|
||
# define N_(String) (String)
|
||
#endif
|
||
|
||
`N_' is a short form similar to `_'. The `Makefile' in the `po/'
|
||
directory of GNU gettext knows by default both of the mentioned short
|
||
forms so you are invited to follow this proposal for your own ease.
|
||
|
||
Now to `catgets'. The main problem is the work for the programmer.
|
||
Every time he comes to a translatable string he has to define a number
|
||
(or a symbolic constant) which has also be defined in the message
|
||
catalog file. He also has to take care for duplicate entries,
|
||
duplicate message IDs etc. If he wants to have the same quality in the
|
||
message catalog as the GNU `gettext' program provides he also has to
|
||
put the descriptive comments for the strings and the location in all
|
||
source code files in the message catalog. This is nearly a Mission:
|
||
Impossible.
|
||
|
||
But there are also some points people might call advantages speaking
|
||
for `catgets'. If you have a single word in a string and this string
|
||
is used in different contexts it is likely that in one or the other
|
||
language the word has different translations. Example:
|
||
|
||
printf ("%s: %d", gettext ("number"), number_of_errors)
|
||
|
||
printf ("you should see %d %s", number_count,
|
||
number_count == 1 ? gettext ("number") : gettext ("numbers"))
|
||
|
||
Here we have to translate two times the string `"number"'. Even if
|
||
you do not speak a language beside English it might be possible to
|
||
recognize that the two words have a different meaning. In German the
|
||
first appearance has to be translated to `"Anzahl"' and the second to
|
||
`"Zahl"'.
|
||
|
||
Now you can say that this example is really esoteric. And you are
|
||
right! This is exactly how we felt about this problem and decide that
|
||
it does not weight that much. The solution for the above problem could
|
||
be very easy:
|
||
|
||
printf ("%s %d", gettext ("number:"), number_of_errors)
|
||
|
||
printf (number_count == 1 ? gettext ("you should see %d number")
|
||
: gettext ("you should see %d numbers"),
|
||
number_count)
|
||
|
||
We believe that we can solve all conflicts with this method. If it
|
||
is difficult one can also consider changing one of the conflicting
|
||
string a little bit. But it is not impossible to overcome.
|
||
|
||
Translator note: It is perhaps appropriate here to tell those English
|
||
speaking programmers that the plural form of a noun cannot be formed by
|
||
appending a single `s'. Most other languages use different methods.
|
||
Even the above form is not general enough to cope with all languages.
|
||
Rafal Maszkowski <rzm@mat.uni.torun.pl> reports:
|
||
|
||
In Polish we use e.g. plik (file) this way:
|
||
1 plik
|
||
2,3,4 pliki
|
||
5-21 pliko'w
|
||
22-24 pliki
|
||
25-31 pliko'w
|
||
and so on (o' means 8859-2 oacute which should be rather okreska,
|
||
similar to aogonek).
|
||
|
||
A workable approach might be to consider methods like the one used
|
||
for `LC_TIME' in the POSIX.2 standard. The value of the `alt_digits'
|
||
field can be up to 100 strings which represent the numbers 1 to 100.
|
||
Using this in a situation of an internationalized program means that an
|
||
array of translatable strings should be indexed by the number which
|
||
should represent. A small example:
|
||
|
||
void
|
||
print_month_info (int month)
|
||
{
|
||
const char *month_pos[12] =
|
||
{ N_("first"), N_("second"), N_("third"), N_("fourth"),
|
||
N_("fifth"), N_("sixth"), N_("seventh"), N_("eighth"),
|
||
N_("ninth"), N_("tenth"), N_("eleventh"), N_("twelfth") };
|
||
printf (_("%s is the %s month\n"), nl_langinfo (MON_1 + month),
|
||
_(month_pos[month]));
|
||
}
|
||
|
||
It should be obvious that this method is only reasonable for small
|
||
ranges of numbers.
|
||
|
||
|
||
File: gettext.info, Node: Using libintl.a, Next: gettext grok, Prev: Comparison, Up: Programmers
|
||
|
||
Using libintl.a in own programs
|
||
===============================
|
||
|
||
Starting with version 0.9.4 the library `libintl.h' should be
|
||
self-contained. I.e., you can use it in your own programs without
|
||
providing additional functions. The `Makefile' will put the header and
|
||
the library in directories selected using the `$(prefix)'.
|
||
|
||
One exception of the above is found on HP-UX systems. Here the C
|
||
library does not contain the `alloca' function (and the HP compiler does
|
||
not generate it inlined). But it is not intended to rewrite the whole
|
||
library just because of this dumb system. Instead include the `alloca'
|
||
function in all package you use the `libintl.a' in.
|
||
|
||
|
||
File: gettext.info, Node: gettext grok, Next: Temp Programmers, Prev: Using libintl.a, Up: Programmers
|
||
|
||
Being a `gettext' grok
|
||
======================
|
||
|
||
To fully exploit the functionality of the GNU `gettext' library it
|
||
is surely helpful to read the source code. But for those who don't want
|
||
to spend that much time in reading the (sometimes complicated) code here
|
||
is a list comments:
|
||
|
||
* Changing the language at runtime
|
||
|
||
For interactive programs it might be useful to offer a selection
|
||
of the used language at runtime. To understand how to do this one
|
||
need to know how the used language is determined while executing
|
||
the `gettext' function. The method which is presented here only
|
||
works correctly with the GNU implementation of the `gettext'
|
||
functions. It is not possible with underlying `catgets' functions
|
||
or `gettext' functions from the systems C library. The exception
|
||
is of course the GNU C Library which uses the GNU `gettext'
|
||
Library for message handling.
|
||
|
||
In the function `dcgettext' at every call the current setting of
|
||
the highest priority environment variable is determined and used.
|
||
Highest priority means here the following list with decreasing
|
||
priority:
|
||
|
||
1. `LANGUAGE'
|
||
|
||
2. `LC_ALL'
|
||
|
||
3. `LC_xxx', according to selected locale
|
||
|
||
4. `LANG'
|
||
|
||
Afterwards the path is constructed using the found value and the
|
||
translation file is loaded if available.
|
||
|
||
What is now when the value for, say, `LANGUAGE' changes. According
|
||
to the process explained above the new value of this variable is
|
||
found as soon as the `dcgettext' function is called. But this
|
||
also means the (perhaps) different message catalog file is loaded.
|
||
In other words: the used language is changed.
|
||
|
||
But there is one little hook. The code for gcc-2.7.0 and up
|
||
provides some optimization. This optimization normally prevents
|
||
the calling of the `dcgettext' function as long as no new catalog
|
||
is loaded. But if `dcgettext' is not called the program also
|
||
cannot find the `LANGUAGE' variable be changed (*note Optimized
|
||
gettext::.). A solution for this is very easy. Include the
|
||
following code in the language switching function.
|
||
|
||
/* Change language. */
|
||
setenv ("LANGUAGE", "fr", 1);
|
||
|
||
/* Make change known. */
|
||
{
|
||
extern int _nl_msg_cat_cntr;
|
||
++_nl_msg_cat_cntr;
|
||
}
|
||
|
||
The variable `_nl_msg_cat_cntr' is defined in `loadmsgcat.c'. The
|
||
programmer will find himself in need for a construct like this only
|
||
when developing programs which do run longer and provide the user
|
||
to select the language at runtime. Non-interactive programs (like
|
||
all these little Unix tools) should never need this.
|
||
|
||
|
||
File: gettext.info, Node: Temp Programmers, Prev: gettext grok, Up: Programmers
|
||
|
||
Temporary Notes for the Programmers Chapter
|
||
===========================================
|
||
|
||
* Menu:
|
||
|
||
* Temp Implementations:: Temporary - Two Possible Implementations
|
||
* Temp catgets:: Temporary - About `catgets'
|
||
* Temp WSI:: Temporary - Why a single implementation
|
||
* Temp Notes:: Temporary - Notes
|
||
|
||
|
||
File: gettext.info, Node: Temp Implementations, Next: Temp catgets, Prev: Temp Programmers, Up: Temp Programmers
|
||
|
||
Temporary - Two Possible Implementations
|
||
----------------------------------------
|
||
|
||
There are two competing methods for language independent messages:
|
||
the X/Open `catgets' method, and the Uniforum `gettext' method. The
|
||
`catgets' method indexes messages by integers; the `gettext' method
|
||
indexes them by their English translations. The `catgets' method has
|
||
been around longer and is supported by more vendors. The `gettext'
|
||
method is supported by Sun, and it has been heard that the COSE
|
||
multi-vendor initiative is supporting it. Neither method is a POSIX
|
||
standard; the POSIX.1 committee had a lot of disagreement in this area.
|
||
|
||
Neither one is in the POSIX standard. There was much disagreement
|
||
in the POSIX.1 committee about using the `gettext' routines vs.
|
||
`catgets' (XPG). In the end the committee couldn't agree on anything,
|
||
so no messaging system was included as part of the standard. I believe
|
||
the informative annex of the standard includes the XPG3 messaging
|
||
interfaces, "...as an example of a messaging system that has been
|
||
implemented..."
|
||
|
||
They were very careful not to say anywhere that you should use one
|
||
set of interfaces over the other. For more on this topic please see
|
||
the Programming for Internationalization FAQ.
|
||
|
||
|
||
File: gettext.info, Node: Temp catgets, Next: Temp WSI, Prev: Temp Implementations, Up: Temp Programmers
|
||
|
||
Temporary - About `catgets'
|
||
---------------------------
|
||
|
||
There have been a few discussions of late on the use of `catgets' as
|
||
a base. I think it important to present both sides of the argument and
|
||
hence am opting to play devil's advocate for a little bit.
|
||
|
||
I'll not deny the fact that `catgets' could have been designed a lot
|
||
better. It currently has quite a number of limitations and these have
|
||
already been pointed out.
|
||
|
||
However there is a great deal to be said for consistency and
|
||
standardization. A common recurring problem when writing Unix software
|
||
is the myriad portability problems across Unix platforms. It seems as
|
||
if every Unix vendor had a look at the operating system and found parts
|
||
they could improve upon. Undoubtedly, these modifications are probably
|
||
innovative and solve real problems. However, software developers have
|
||
a hard time keeping up with all these changes across so many platforms.
|
||
|
||
And this has prompted the Unix vendors to begin to standardize their
|
||
systems. Hence the impetus for Spec1170. Every major Unix vendor has
|
||
committed to supporting this standard and every Unix software developer
|
||
waits with glee the day they can write software to this standard and
|
||
simply recompile (without having to use autoconf) across different
|
||
platforms.
|
||
|
||
As I understand it, Spec1170 is roughly based upon version 4 of the
|
||
X/Open Portability Guidelines (XPG4). Because `catgets' and friends
|
||
are defined in XPG4, I'm led to believe that `catgets' is a part of
|
||
Spec1170 and hence will become a standardized component of all Unix
|
||
systems.
|
||
|
||
|
||
File: gettext.info, Node: Temp WSI, Next: Temp Notes, Prev: Temp catgets, Up: Temp Programmers
|
||
|
||
Temporary - Why a single implementation
|
||
---------------------------------------
|
||
|
||
Now it seems kind of wasteful to me to have two different systems
|
||
installed for accessing message catalogs. If we do want to remedy
|
||
`catgets' deficiencies why don't we try to expand `catgets' (in a
|
||
compatible manner) rather than implement an entirely new system.
|
||
Otherwise, we'll end up with two message catalog access systems
|
||
installed with an operating system - one set of routines for packages
|
||
using GNU `gettext' for their internationalization, and another set of
|
||
routines (catgets) for all other software. Bloated?
|
||
|
||
Supposing another catalog access system is implemented. Which do we
|
||
recommend? At least for Linux, we need to attract as many software
|
||
developers as possible. Hence we need to make it as easy for them to
|
||
port their software as possible. Which means supporting `catgets'. We
|
||
will be implementing the `glocale' code within our `libc', but does
|
||
this mean we also have to incorporate another message catalog access
|
||
scheme within our `libc' as well? And what about people who are going
|
||
to be using the `glocale' + non-`catgets' routines. When they port
|
||
their software to other platforms, they're now going to have to include
|
||
the front-end (`glocale') code plus the back-end code (the non-`catgets'
|
||
access routines) with their software instead of just including the
|
||
`glocale' code with their software.
|
||
|
||
Message catalog support is however only the tip of the iceberg.
|
||
What about the data for the other locale categories. They also have a
|
||
number of deficiencies. Are we going to abandon them as well and
|
||
develop another duplicate set of routines (should `glocale' expand
|
||
beyond message catalog support)?
|
||
|
||
Like many parts of Unix that can be improved upon, we're stuck with
|
||
balancing compatibility with the past with useful improvements and
|
||
innovations for the future.
|
||
|
||
|
||
File: gettext.info, Node: Temp Notes, Prev: Temp WSI, Up: Temp Programmers
|
||
|
||
Temporary - Notes
|
||
-----------------
|
||
|
||
X/Open agreed very late on the standard form so that many
|
||
implementations differ from the final form. Both of my system (old
|
||
Linux catgets and Ultrix-4) have a strange variation.
|
||
|
||
OK. After incorporating the last changes I have to spend some time
|
||
on making the GNU/Linux `libc' `gettext' functions. So in future
|
||
Solaris is not the only system having `gettext'.
|
||
|
||
|
||
File: gettext.info, Node: Translators, Next: Maintainers, Prev: Programmers, Up: Top
|
||
|
||
The Translator's View
|
||
*********************
|
||
|
||
* Menu:
|
||
|
||
* Trans Intro 0:: Introduction 0
|
||
* Trans Intro 1:: Introduction 1
|
||
* Discussions:: Discussions
|
||
* Organization:: Organization
|
||
* Information Flow:: Information Flow
|
||
|
||
|
||
File: gettext.info, Node: Trans Intro 0, Next: Trans Intro 1, Prev: Translators, Up: Translators
|
||
|
||
Introduction 0
|
||
==============
|
||
|
||
GNU is going international! The Translation Project is a way to get
|
||
maintainers, translators and users all together, so GNU will gradually
|
||
become able to speak many native languages.
|
||
|
||
The GNU `gettext' tool set contains *everything* maintainers need
|
||
for internationalizing their packages for messages. It also contains
|
||
quite useful tools for helping translators at localizing messages to
|
||
their native language, once a package has already been
|
||
internationalized.
|
||
|
||
To achieve the Translation Project, we need many interested people
|
||
who like their own language and write it well, and who are also able to
|
||
synergize with other translators speaking the same language. If you'd
|
||
like to volunteer to *work* at translating messages, please send mail
|
||
to your translating team.
|
||
|
||
Each team has its own mailing list, courtesy of Linux International.
|
||
You may reach your translating team at the address `LL@li.org',
|
||
replacing LL by the two-letter ISO 639 code for your language.
|
||
Language codes are *not* the same as country codes given in ISO 3166.
|
||
The following translating teams exist:
|
||
|
||
Chinese `zh', Czech `cs', Danish `da', Dutch `nl', Esperanto `eo',
|
||
Finnish `fi', French `fr', Irish `ga', German `de', Greek `el',
|
||
Italian `it', Japanese `ja', Indonesian `in', Norwegian `no',
|
||
Polish `pl', Portuguese `pt', Russian `ru', Spanish `es', Swedish
|
||
`sv' and Turkish `tr'.
|
||
|
||
For example, you may reach the Chinese translating team by writing to
|
||
`zh@li.org'. When you become a member of the translating team for your
|
||
own language, you may subscribe to its list. For example, Swedish
|
||
people can send a message to `sv-request@li.org', having this message
|
||
body:
|
||
|
||
subscribe
|
||
|
||
Keep in mind that team members should be interested in *working* at
|
||
translations, or at solving translational difficulties, rather than
|
||
merely lurking around. If your team does not exist yet and you want to
|
||
start one, please write to `gnu-translation@prep.ai.mit.edu'; you will
|
||
then reach the GNU coordinator for all translator teams.
|
||
|
||
A handful of GNU packages have already been adapted and provided
|
||
with message translations for several languages. Translation teams
|
||
have begun to organize, using these packages as a starting point. But
|
||
there are many more packages and many languages for which we have no
|
||
volunteer translators. If you would like to volunteer to work at
|
||
translating messages, please send mail to
|
||
`gnu-translation@prep.ai.mit.edu' indicating what language(s) you can
|
||
work on.
|
||
|
||
|
||
File: gettext.info, Node: Trans Intro 1, Next: Discussions, Prev: Trans Intro 0, Up: Translators
|
||
|
||
Introduction 1
|
||
==============
|
||
|
||
This is now official, GNU is going international! Here is the
|
||
announcement submitted for the January 1995 GNU Bulletin:
|
||
|
||
A handful of GNU packages have already been adapted and provided
|
||
with message translations for several languages. Translation
|
||
teams have begun to organize, using these packages as a starting
|
||
point. But there are many more packages and many languages for
|
||
which we have no volunteer translators. If you'd like to
|
||
volunteer to work at translating messages, please send mail to
|
||
`gnu-translation@prep.ai.mit.edu' indicating what language(s) you
|
||
can work on.
|
||
|
||
This document should answer many questions for those who are curious
|
||
about the process or would like to contribute. Please at least skim
|
||
over it, hoping to cut down a little of the high volume of e-mail
|
||
generated by this collective effort towards GNU internationalization.
|
||
|
||
Most free programming which is widely shared is done in English, and
|
||
currently, English is used as the main communicating language between
|
||
national communities collaborating to the GNU project. This very
|
||
document is written in English. This will not change in the
|
||
foreseeable future.
|
||
|
||
However, there is a strong appetite from national communities for
|
||
having more software able to write using national language and habits,
|
||
and there is an on-going effort to modify GNU software in such a way
|
||
that it becomes able to do so. The experiments driven so far raised an
|
||
enthusiastic response from pretesters, so we believe that GNU
|
||
internationalization is dedicated to succeed.
|
||
|
||
For suggestion clarifications, additions or corrections to this
|
||
document, please e-mail to `gnu-translation@prep.ai.mit.edu'.
|
||
|
||
|
||
File: gettext.info, Node: Discussions, Next: Organization, Prev: Trans Intro 1, Up: Translators
|
||
|
||
Discussions
|
||
===========
|
||
|
||
Facing this internationalization effort, a few users expressed their
|
||
concerns. Some of these doubts are presented and discussed, here.
|
||
|
||
* Smaller groups
|
||
|
||
Some languages are not spoken by a very large number of people, so
|
||
people speaking them sometimes consider that there may not be all
|
||
that much demand such versions of free software packages.
|
||
Moreover, many people being *into computers*, in some countries,
|
||
generally seem to prefer English versions of their software.
|
||
|
||
On the other end, people might enjoy their own language a lot, and
|
||
be very motivated at providing to themselves the pleasure of
|
||
having their beloved free software speaking their mother tongue.
|
||
They do themselves a personal favor, and do not pay that much
|
||
attention to the number of people beneficiating of their work.
|
||
|
||
* Misinterpretation
|
||
|
||
Other users are shy to push forward their own language, seeing in
|
||
this some kind of misplaced propaganda. Someone thought there
|
||
must be some users of the language over the networks pestering
|
||
other people with it.
|
||
|
||
But any spoken language is worth localization, because there are
|
||
people behind the language for whom the language is important and
|
||
dear to their hearts.
|
||
|
||
* Odd translations
|
||
|
||
The biggest problem is to find the right translations so that
|
||
everybody can understand the messages. Translations are usually a
|
||
little odd. Some people get used to English, to the extent they
|
||
may find translations into their own language "rather pushy,
|
||
obnoxious and sometimes even hilarious." As a French speaking
|
||
man, I have the experience of those instruction manuals for goods,
|
||
so poorly translated in French in Korea or Taiwan...
|
||
|
||
The fact is that we sometimes have to create a kind of national
|
||
computer culture, and this is not easy without the collaboration of
|
||
many people liking their mother tongue. This is why translations
|
||
are better achieved by people knowing and loving their own
|
||
language, and ready to work together at improving the results they
|
||
obtain.
|
||
|
||
* Dependencies over the GPL
|
||
|
||
Some people wonder if using GNU `gettext' necessarily brings their
|
||
package under the protective wing of the GNU General Public
|
||
License, when they do not want to make their program free, or want
|
||
other kinds of freedom. The simplest answer is yes.
|
||
|
||
The mere marking of localizable strings in a package, or
|
||
conditional inclusion of a few lines for initialization, is not
|
||
really including GPL'ed code. However, the localization routines
|
||
themselves are under the GPL and would bring the remainder of the
|
||
package under the GPL if they were distributed with it. So, I
|
||
presume that, for those for which this is a problem, it could be
|
||
circumvented by letting to the end installers the burden of
|
||
assembling a package prepared for localization, but not providing
|
||
the localization routines themselves.
|
||
|
||
|
||
File: gettext.info, Node: Organization, Next: Information Flow, Prev: Discussions, Up: Translators
|
||
|
||
Organization
|
||
============
|
||
|
||
On a larger scale, the true solution would be to organize some kind
|
||
of fairly precise set up in which volunteers could participate. I gave
|
||
some thought to this idea lately, and realize there will be some touchy
|
||
points. I thought of writing to Richard Stallman to launch such a
|
||
project, but feel it might be good to shake out the ideas between
|
||
ourselves first. Most probably that Linux International has some
|
||
experience in the field already, or would like to orchestrate the
|
||
volunteer work, maybe. Food for thought, in any case!
|
||
|
||
I guess we have to setup something early, somehow, that will help
|
||
many possible contributors of the same language to interlock and avoid
|
||
work duplication, and further be put in contact for solving together
|
||
problems particular to their tongue (in most languages, there are many
|
||
difficulties peculiar to translating technical English). My Swedish
|
||
contributor acknowledged these difficulties, and I'm well aware of them
|
||
for French.
|
||
|
||
This is surely not a technical issue, but we should manage so the
|
||
effort of locale contributors be maximally useful, despite the national
|
||
team layer interface between contributors and maintainers.
|
||
|
||
The Translation Project needs some setup for coordinating language
|
||
coordinators. Localizing evolving programs will surely become a
|
||
permanent and continuous activity in the free software community, once
|
||
well started. The setup should be minimally completed and tested
|
||
before GNU `gettext' becomes an official reality. The e-mail address
|
||
`translation@iro.umontreal.ca' has been setup for receiving offers from
|
||
volunteers and general e-mail on these topics. This address reaches
|
||
the Translation Project coordinator.
|
||
|
||
* Menu:
|
||
|
||
* Central Coordination:: Central Coordination
|
||
* National Teams:: National Teams
|
||
* Mailing Lists:: Mailing Lists
|
||
|
||
|
||
File: gettext.info, Node: Central Coordination, Next: National Teams, Prev: Organization, Up: Organization
|
||
|
||
Central Coordination
|
||
--------------------
|
||
|
||
I also think GNU will need sooner than it thinks, that someone setup
|
||
a way to organize and coordinate these groups. Some kind of group of
|
||
groups. My opinion is that it would be good that GNU delegates this
|
||
task to a small group of collaborating volunteers, shortly. Perhaps in
|
||
`gnu.announce' a list of this national committee's can be published.
|
||
|
||
My role as coordinator would simply be to refer to Ulrich any German
|
||
speaking volunteer interested to localization of free software
|
||
packages, and maybe helping national groups to initially organize,
|
||
while maintaining national registries for until national groups are
|
||
ready to take over. In fact, the coordinator should ease volunteers to
|
||
get in contact with one another for creating national teams, which
|
||
should then select one coordinator per language, or country
|
||
(regionalized language). If well done, the coordination should be
|
||
useful without being an overwhelming task, the time to put delegations
|
||
in place.
|
||
|
||
|
||
File: gettext.info, Node: National Teams, Next: Mailing Lists, Prev: Central Coordination, Up: Organization
|
||
|
||
National Teams
|
||
--------------
|
||
|
||
I suggest we look for volunteer coordinators/editors for individual
|
||
languages. These people will scan contributions of translation files
|
||
for various programs, for their own languages, and will ensure high and
|
||
uniform standards of diction.
|
||
|
||
From my current experience with other people in these days, those who
|
||
provide localizations are very enthusiastic about the process, and are
|
||
more interested in the localization process than in the program they
|
||
localize, and want to do many programs, not just one. This seems to
|
||
confirm that having a coordinator/editor for each language is a good
|
||
idea.
|
||
|
||
We need to choose someone who is good at writing clear and concise
|
||
prose in the language in question. That is hard--we can't check it
|
||
ourselves. So we need to ask a few people to judge each others'
|
||
writing and select the one who is best.
|
||
|
||
I announce my prerelease to a few dozen people, and you would not
|
||
believe all the discussions it generated already. I shudder to think
|
||
what will happen when this will be launched, for true, officially,
|
||
world wide. Who am I to arbitrate between two Czekolsovak users
|
||
contradicting each other, for example?
|
||
|
||
I assume that your German is not much better than my French so that
|
||
I would not be able to judge about these formulations. What I would
|
||
suggest is that for each language there is a group for people who
|
||
maintain the PO files and judge about changes. I suspect there will be
|
||
cultural differences between how such groups of people will behave.
|
||
Some will have relaxed ways, reach consensus easily, and have anyone of
|
||
the group relate to the maintainers, while others will fight to death,
|
||
organize heavy administrations up to national standards, and use strict
|
||
channels.
|
||
|
||
The German team is putting out a good example. Right now, they are
|
||
maybe half a dozen people revising translations of each other and
|
||
discussing the linguistic issues. I do not even have all the names.
|
||
Ulrich Drepper is taking care of coordinating the German team. He
|
||
subscribed to all my pretest lists, so I do not even have to warn him
|
||
specifically of incoming releases.
|
||
|
||
I'm sure, that is a good idea to get teams for each language working
|
||
on translations. That will make the translations better and more
|
||
consistent.
|
||
|
||
* Menu:
|
||
|
||
* Sub-Cultures:: Sub-Cultures
|
||
* Organizational Ideas:: Organizational Ideas
|
||
|
||
|
||
File: gettext.info, Node: Sub-Cultures, Next: Organizational Ideas, Prev: National Teams, Up: National Teams
|
||
|
||
Sub-Cultures
|
||
............
|
||
|
||
Taking French for example, there are a few sub-cultures around
|
||
computers which developed diverging vocabularies. Picking volunteers
|
||
here and there without addressing this problem in an organized way,
|
||
soon in the project, might produce a distasteful mix of
|
||
internationalized programs, and possibly trigger endless quarrels among
|
||
those who really care.
|
||
|
||
Keeping some kind of unity in the way French localization of
|
||
internationalized programs is achieved is a difficult (and delicate)
|
||
job. Knowing the latin character of French people (:-), if we take this
|
||
the wrong way, we could end up nowhere, or spoil a lot of energies.
|
||
Maybe we should begin to address this problem seriously *before* GNU
|
||
`gettext' become officially published. And I suspect that this means
|
||
soon!
|
||
|
||
|
||
File: gettext.info, Node: Organizational Ideas, Prev: Sub-Cultures, Up: National Teams
|
||
|
||
Organizational Ideas
|
||
....................
|
||
|
||
I expect the next big changes after the official release. Please
|
||
note that I use the German translation of the short GPL message. We
|
||
need to set a few good examples before the localization goes out for
|
||
true in the free software community. Here are a few points to discuss:
|
||
|
||
* Each group should have one FTP server (at least one master).
|
||
|
||
* The files on the server should reflect the latest version (of
|
||
course!) and it should also contain a RCS directory with the
|
||
corresponding archives (I don't have this now).
|
||
|
||
* There should also be a ChangeLog file (this is more useful than the
|
||
RCS archive but can be generated automatically from the later by
|
||
Emacs).
|
||
|
||
* A "core group" should judge about questionable changes (for now
|
||
this group consists solely by me but I ask some others
|
||
occasionally; this also seems to work).
|
||
|
||
|
||
File: gettext.info, Node: Mailing Lists, Prev: National Teams, Up: Organization
|
||
|
||
Mailing Lists
|
||
-------------
|
||
|
||
If we get any inquiries about GNU `gettext', send them on to:
|
||
|
||
`translation@iro.umontreal.ca'
|
||
|
||
The `*-pretest' lists are quite useful to me, maybe the idea could
|
||
be generalized to many GNU, and non-GNU packages. But each maintainer
|
||
his/her way!
|
||
|
||
Franc,ois, we have a mechanism in place here at `gnu.ai.mit.edu' to
|
||
track teams, support mailing lists for them and log members. We have a
|
||
slight preference that you use it. If this is OK with you, I can get
|
||
you clued in.
|
||
|
||
Things are changing! A few years ago, when Daniel Fekete and I
|
||
asked for a mailing list for GNU localization, nested at the FSF, we
|
||
were politely invited to organize it anywhere else, and so did we. For
|
||
communicating with my pretesters, I later made a handful of mailing
|
||
lists located at iro.umontreal.ca and administrated by `majordomo'.
|
||
These lists have been *very* dependable so far...
|
||
|
||
I suspect that the German team will organize itself a mailing list
|
||
located in Germany, and so forth for other countries. But before they
|
||
organize for true, it could surely be useful to offer mailing lists
|
||
located at the FSF to each national team. So yes, please explain me
|
||
how I should proceed to create and handle them.
|
||
|
||
We should create temporary mailing lists, one per country, to help
|
||
people organize. Temporary, because once regrouped and structured, it
|
||
would be fair the volunteers from country bring back *their* list in
|
||
there and manage it as they want. My feeling is that, in the long run,
|
||
each team should run its own list, from within their country. There
|
||
also should be some central list to which all teams could subscribe as
|
||
they see fit, as long as each team is represented in it.
|
||
|
||
|
||
File: gettext.info, Node: Information Flow, Prev: Organization, Up: Translators
|
||
|
||
Information Flow
|
||
================
|
||
|
||
There will surely be some discussion about this messages after the
|
||
packages are finally released. If people now send you some proposals
|
||
for better messages, how do you proceed? Jim, please note that right
|
||
now, as I put forward nearly a dozen of localizable programs, I receive
|
||
both the translations and the coordination concerns about them.
|
||
|
||
If I put one of my things to pretest, Ulrich receives the
|
||
announcement and passes it on to the German team, who make last minute
|
||
revisions. Then he submits the translation files to me *as the
|
||
maintainer*. For free packages I do not maintain, I would not even
|
||
hear about it. This scheme could be made to work for the whole
|
||
Translation Project, I think. For security reasons, maybe Ulrich
|
||
(national coordinators, in fact) should update central registry kept at
|
||
the Translation Project (Jim, me, or Len's recruits) once in a while.
|
||
|
||
In December/January, I was aggressively ready to internationalize
|
||
all of GNU, giving myself the duty of one small GNU package per week or
|
||
so, taking many weeks or months for bigger packages. But it does not
|
||
work this way. I first did all the things I'm responsible for. I've
|
||
nothing against some missionary work on other maintainers, but I'm also
|
||
loosing a lot of energy over it--same debates over again.
|
||
|
||
And when the first localized packages are released we'll get a lot of
|
||
responses about ugly translations :-). Surely, and we need to have
|
||
beforehand a fairly good idea about how to handle the information flow
|
||
between the national teams and the package maintainers.
|
||
|
||
Please start saving somewhere a quick history of each PO file. I
|
||
know for sure that the file format will change, allowing for comments.
|
||
It would be nice that each file has a kind of log, and references for
|
||
those who want to submit comments or gripes, or otherwise contribute.
|
||
I sent a proposal for a fast and flexible format, but it is not
|
||
receiving acceptance yet by the GNU deciders. I'll tell you when I
|
||
have more information about this.
|
||
|
||
|
||
File: gettext.info, Node: Maintainers, Next: Conclusion, Prev: Translators, Up: Top
|
||
|
||
The Maintainer's View
|
||
*********************
|
||
|
||
The maintainer of a package has many responsibilities. One of them
|
||
is ensuring that the package will install easily on many platforms, and
|
||
that the magic we described earlier (*note Users::.) will work for
|
||
installers and end users.
|
||
|
||
Of course, there are many possible ways by which GNU `gettext' might
|
||
be integrated in a distribution, and this chapter does not cover them
|
||
in all generality. Instead, it details one possible approach which is
|
||
especially adequate for many free software distributions following GNU
|
||
standards, or even better, Gnits standards, because GNU `gettext' is
|
||
purposely for helping the internationalization of the whole GNU
|
||
project, and as many other good free packages as possible. So, the
|
||
maintainer's view presented here presumes that the package already has
|
||
a `configure.in' file and uses GNU Autoconf.
|
||
|
||
Nevertheless, GNU `gettext' may surely be useful for free packages
|
||
not following GNU standards and conventions, but the maintainers of such
|
||
packages might have to show imagination and initiative in organizing
|
||
their distributions so `gettext' work for them in all situations.
|
||
There are surely many, out there.
|
||
|
||
Even if `gettext' methods are now stabilizing, slight adjustments
|
||
might be needed between successive `gettext' versions, so you should
|
||
ideally revise this chapter in subsequent releases, looking for changes.
|
||
|
||
* Menu:
|
||
|
||
* Flat and Non-Flat:: Flat or Non-Flat Directory Structures
|
||
* Prerequisites:: Prerequisite Works
|
||
* gettextize Invocation:: Invoking the `gettextize' Program
|
||
* Adjusting Files:: Files You Must Create or Alter
|
||
|
||
|
||
File: gettext.info, Node: Flat and Non-Flat, Next: Prerequisites, Prev: Maintainers, Up: Maintainers
|
||
|
||
Flat or Non-Flat Directory Structures
|
||
=====================================
|
||
|
||
Some free software packages are distributed as `tar' files which
|
||
unpack in a single directory, these are said to be "flat" distributions.
|
||
Other free software packages have a one level hierarchy of
|
||
subdirectories, using for example a subdirectory named `doc/' for the
|
||
Texinfo manual and man pages, another called `lib/' for holding
|
||
functions meant to replace or complement C libraries, and a
|
||
subdirectory `src/' for holding the proper sources for the package.
|
||
These other distributions are said to be "non-flat".
|
||
|
||
For now, we cannot say much about flat distributions. A flat
|
||
directory structure has the disadvantage of increasing the difficulty
|
||
of updating to a new version of GNU `gettext'. Also, if you have many
|
||
PO files, this could somewhat pollute your single directory. In the
|
||
GNU `gettext' distribution, the `misc/' directory contains a shell
|
||
script named `combine-sh'. That script may be used for combining all
|
||
the C files of the `intl/' directory into a pair of C files (one `.c'
|
||
and one `.h'). Those two generated files would fit more easily in a
|
||
flat directory structure, and you will then have to add these two files
|
||
to your project.
|
||
|
||
Maybe because GNU `gettext' itself has a non-flat structure, we have
|
||
more experience with this approach, and this is what will be described
|
||
in the remaining of this chapter. Some maintainers might use this as
|
||
an opportunity to unflatten their package structure. Only later, once
|
||
gained more experience adapting GNU `gettext' to flat distributions, we
|
||
might add some notes about how to proceed in flat situations.
|
||
|
||
|
||
File: gettext.info, Node: Prerequisites, Next: gettextize Invocation, Prev: Flat and Non-Flat, Up: Maintainers
|
||
|
||
Prerequisite Works
|
||
==================
|
||
|
||
There are some works which are required for using GNU `gettext' in
|
||
one of your package. These works have some kind of generality that
|
||
escape the point by point descriptions used in the remainder of this
|
||
chapter. So, we describe them here.
|
||
|
||
* Before attempting to use you should install some other packages
|
||
first. Ensure that recent versions of GNU `m4', GNU Autoconf and
|
||
GNU `gettext' are already installed at your site, and if not,
|
||
proceed to do this first. If you got to install these things,
|
||
beware that GNU `m4' must be fully installed before GNU Autoconf
|
||
is even *configured*.
|
||
|
||
To further ease the task of a package maintainer the `automake'
|
||
package was designed and implemented. GNU `gettext' now uses this
|
||
tool and the `Makefile's in the `intl/' and `po/' therefore know
|
||
about all the goals necessary for using `automake' and `libintl'
|
||
in one project.
|
||
|
||
Those four packages are only needed to you, as a maintainer; the
|
||
installers of your own package and end users do not really need
|
||
any of GNU `m4', GNU Autoconf, GNU `gettext', or GNU `automake'
|
||
for successfully installing and running your package, with messages
|
||
properly translated. But this is not completely true if you
|
||
provide internationalized shell scripts within your own package:
|
||
GNU `gettext' shall then be installed at the user site if the end
|
||
users want to see the translation of shell script messages.
|
||
|
||
* Your package should use Autoconf and have a `configure.in' file.
|
||
If it does not, you have to learn how. The Autoconf documentation
|
||
is quite well written, it is a good idea that you print it and get
|
||
familiar with it.
|
||
|
||
* Your C sources should have already been modified according to
|
||
instructions given earlier in this manual. *Note Sources::.
|
||
|
||
* Your `po/' directory should receive all PO files submitted to you
|
||
by the translator teams, each having `LL.po' as a name. This is
|
||
not usually easy to get translation work done before your package
|
||
gets internationalized and available! Since the cycle has to
|
||
start somewhere, the easiest for the maintainer is to start with
|
||
absolutely no PO files, and wait until various translator teams
|
||
get interested in your package, and submit PO files.
|
||
|
||
It is worth adding here a few words about how the maintainer should
|
||
ideally behave with PO files submissions. As a maintainer, your role is
|
||
to authentify the origin of the submission as being the representative
|
||
of the appropriate translating teams of the Translation Project (forward
|
||
the submission to `translation@iro.umontreal.ca' in case of doubt), to
|
||
ensure that the PO file format is not severely broken and does not
|
||
prevent successful installation, and for the rest, to merely to put
|
||
these PO files in `po/' for distribution.
|
||
|
||
As a maintainer, you do not have to take on your shoulders the
|
||
responsibility of checking if the translations are adequate or
|
||
complete, and should avoid diving into linguistic matters. Translation
|
||
teams drive themselves and are fully responsible of their linguistic
|
||
choices for the Translation Project. Keep in mind that translator
|
||
teams are *not* driven by maintainers. You can help by carefully
|
||
redirecting all communications and reports from users about linguistic
|
||
matters to the appropriate translation team, or explain users how to
|
||
reach or join their team. The simplest might be to send them the
|
||
`ABOUT-NLS' file.
|
||
|
||
Maintainers should *never ever* apply PO file bug reports
|
||
themselves, short-cutting translation teams. If some translator has
|
||
difficulty to get some of her points through her team, it should not be
|
||
an issue for her to directly negotiate translations with maintainers.
|
||
Teams ought to settle their problems themselves, if any. If you, as a
|
||
maintainer, ever think there is a real problem with a team, please
|
||
never try to *solve* a team's problem on your own.
|
||
|
||
|
||
File: gettext.info, Node: gettextize Invocation, Next: Adjusting Files, Prev: Prerequisites, Up: Maintainers
|
||
|
||
Invoking the `gettextize' Program
|
||
=================================
|
||
|
||
Some files are consistently and identically needed in every package
|
||
internationalized through GNU `gettext'. As a matter of convenience,
|
||
the `gettextize' program puts all these files right in your package.
|
||
This program has the following synopsis:
|
||
|
||
gettextize [ OPTION... ] [ DIRECTORY ]
|
||
|
||
and accepts the following options:
|
||
|
||
`-c'
|
||
`--copy'
|
||
Copy the needed files instead of making symbolic links. Using
|
||
links would allow the package to always use the latest `gettext'
|
||
code available on the system, but it might disturb some mechanism
|
||
the maintainer is used to apply to the sources. Because running
|
||
`gettextize' is easy there shouldn't be problems with using copies.
|
||
|
||
`-f'
|
||
`--force'
|
||
Force replacement of files which already exist.
|
||
|
||
`-h'
|
||
`--help'
|
||
Display this help and exit.
|
||
|
||
`--version'
|
||
Output version information and exit.
|
||
|
||
If DIRECTORY is given, this is the top level directory of a package
|
||
to prepare for using GNU `gettext'. If not given, it is assumed that
|
||
the current directory is the top level directory of such a package.
|
||
|
||
The program `gettextize' provides the following files. However, no
|
||
existing file will be replaced unless the option `--force' (`-f') is
|
||
specified.
|
||
|
||
1. The `ABOUT-NLS' file is copied in the main directory of your
|
||
package, the one being at the top level. This file gives the main
|
||
indications about how to install and use the Native Language
|
||
Support features of your program. You might elect to use a more
|
||
recent copy of this `ABOUT-NLS' file than the one provided through
|
||
`gettextize', if you have one handy. You may also fetch a more
|
||
recent copy of file `ABOUT-NLS' from Translation Project sites,
|
||
and from most GNU archive sites.
|
||
|
||
2. A `po/' directory is created for eventually holding all
|
||
translation files, but initially only containing the file
|
||
`po/Makefile.in.in' from the GNU `gettext' distribution. (beware
|
||
the double `.in' in the file name). If the `po/' directory already
|
||
exists, it will be preserved along with the files it contains, and
|
||
only `Makefile.in.in' will be overwritten.
|
||
|
||
3. A `intl/' directory is created and filled with most of the files
|
||
originally in the `intl/' directory of the GNU `gettext'
|
||
distribution. Also, if option `--force' (`-f') is given, the
|
||
`intl/' directory is emptied first.
|
||
|
||
|
||
If your site support symbolic links, `gettextize' will not actually
|
||
copy the files into your package, but establish symbolic links instead.
|
||
This avoids duplicating the disk space needed in all packages. Merely
|
||
using the `-h' option while creating the `tar' archive of your
|
||
distribution will resolve each link by an actual copy in the
|
||
distribution archive. So, to insist, you really should use `-h' option
|
||
with `tar' within your `dist' goal of your main `Makefile.in'.
|
||
|
||
It is interesting to understand that most new files for supporting
|
||
GNU `gettext' facilities in one package go in `intl/' and `po/'
|
||
subdirectories. One distinction between these two directories is that
|
||
`intl/' is meant to be completely identical in all packages using GNU
|
||
`gettext', while all newly created files, which have to be different,
|
||
go into `po/'. There is a common `Makefile.in.in' in `po/', because
|
||
the `po/' directory needs its own `Makefile', and it has been designed
|
||
so it can be identical in all packages.
|
||
|