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

Re: 使用CV時中文過大



Wan Hing Wah wrote:

> Also I would like have som programming in linux but I'm not familiar
> in the UNIX/Linux programmering environment..What really locale is in
> programmer's approach?And is there any internet resource for it?

I got some experience on GTK+ gettext. Maybe I could help.
Quick start guide:
1. In *.c add:
#include <libintl.h>
#define _(String) gettext (String)
Of course, you may include these in a header file.

2. In main() function, add these lines after declaring variables but before
gtk_init():
        gtk_set_locale();
        bindtextdomain("myPackage","/usr/share/locale");
        textdomain("myPackage");
Where myPackage is the name to indentify your program(don't mix up with other
programs....) and /usr/share/locale is the path of locale data.

3. "Markup your program"
Do markup for all the strings that you would like to translate. Use _() to
enclose the string that you want to translate.
e.g. puts("hello");  --> puts(_("hello"));

4. xgettext
Use a command:
xgettext --keyword=_ source.c
where source.c is your sourcecode. you may put muiltple files in the command
line here. It will generate "message.po", which has some untranslated messages.

5. for convinence, mkdir po/ , put message.po into po/ , leave a origanal copy
of message.po, translate it.
e.g.
msgid "Message"
msgstr "訊息"

6. use command:
msgfmt filename.po -o filename.mo
Compiling it into machine code.

7. copy filename.mo to /usr/share/locale/zh_TW.Big5/LC_MESSAGES/myPackage.mo
where filename is the output file by msgfmt. change zh_TW.Big5 if necessary.
(e.g. zh_HK.Big5 ;^)

8. Compile your program as usual.

For details, take a look on Anthony Wong's gettext-mini-howto ^_^

By the way, check out the previous post here(just serveral days ago), a program
called MuLi can help you. ;^)
Wait for stable release and Debian package

--
Kam Tik

>
>
> Thx...(I seem so troublesome asking so many question)...
>
> --
> To UNSUBSCRIBE, email to debian-chinese-request@lists.debian.org
> with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Abstract
--------

This mini-HOWTO is to help someone who have never used GNU's gettext
utilities to 'gettextize' their existing C programs as quick as
possible. This mini-HOWTO doesn't teach you how to install the gettext
package, it just tell you how to use it, _briefly_.

I assume that you already know how to program in C and how to write
Makefiles.

Let's start
-----------

Step 0.

Add these lines into your C programs:

#include <libintl.h>
#define _(String) gettext (String)

Step 1.

At the beginning of the main function, add these lines:

    setlocale (LC_ALL, "");
    bindtextdomain (PACKAGE, LOCALEDIR);
    textdomain (PACKAGE);

Depending on your need, you may not need something as 'strong' as
LC_ALL, you may only want to set LC_MESSAGES, for instance:
    setlocale (LC_MESSAGES, "");

But for most translations LC_MESSAGES suffices.

If you are only working on a small project, you can replace PACKAGE
with a string reflecting your project, and LOCALEDIR with your
system's locale directory, such as:

    bindtextdomain ("mypackage", "/usr/share/locale");
    textdomain ("mypackage");

and you can then skip the next step.

Step 2.

Define 'PACKAGE' and 'LOCALEDIR' to the suitable values somewhere,
possible in your Makefile or a header file, such as config.h, that
your C program uses.

Here's a simple example to do this in Makefile, but remember there're
tens of other ways to achieve the same result:

    PACKAGE=\"mypackage\"
    LOCALEDIR=\"/usr/share/locale\"
    ...

    prog: prog.c
            $(CC) -DPACKAGE=$(PACKAGE) -DLOCALEDIR=$(LOCALEDIR) $^

You may be able to put '-DPACKAGE=${PACKAGE} -D LOCALEDIR=${LOCALEDIR}' 
in CFLAGS too.

If you want to put it in a header file, just add these two lines:

    #define PACKAGES mypackage
    #define LOCALEDIR /usr/share/locale

Remember to #include this header file!

Step 3.

Wrap all static strings with "_(" and ")", this is called "marking".

Exaples:
    From:   printf ("Hello world!");
    To:     printf (_("Hello world!"));

    From:   sprintf (str, "<H1>Translate as little as possible</H1>\n);
    To:     sprintf (str, "<H1>%s</H1>\n, _("Translate as little as possible"));

    From:   printf ("Hello %s, nice to meet you", name);
    To:     printf (_("Hello %s, nice to meet you"), name);


There is a special case that you must pay attention to during this
'marking' step, that is, how to deal with strings in a static array:

Example:
        static const char *messages[] = {
            "some very meaningful message",
            "and another one"
        };
        ...
        puts(messages[i]);

The solution is to first #define gettext_noop, and mark all strings in
the array with gettext_noop, and finally use gettext on where the
array will be used, like this:

        #define gettext_noop(String) (String)

        ...
        static const char *messages[] = {
            gettext_noop ("some very meaningful message"),
            gettext_noop ("and another one")
        };
        ...
        puts (gettext( messages[i]));

Step 4:

Extract all marked strings to a '.po' (Portable Object) file, like this:

        % xgettext --keyword=_ main.c config.c <... and more file ...>

An initial '.po' is generated as 'messages.po'. As this file contain
untranslated messages, and hence it's temporary, the convention is to
rename it to PACKAGE.pot ('t' stands for temporary).

Step 5.

It's now ready to be translated. Give the '.pot' file to translators.
Lines beginning with '#' are comments. Lines that are ready to be
translated are those that begin with 'msgstr', which correspond to the
line above (that begins with 'msgid').

The translated '.po' file should be named as 'LANGUAGE.po', such as
DE.po and zh_TW.po, and store in the po/ directory in your source.
(ref: Country Codes in info pages)

Warning:
   What if positions of format specifiers in printf-like functions are
   different in different languages:

   e.g.
   In English:
       printf (gettext ("String `%s' has %d characters\n"), s, strlen (s));
   But in German:
       "%d Zeichen lang ist die Zeichenkette `%s'"

   Solution:
   Use this for German:
       "%2$d Zeichen lang ist die Zeichenkette `%1$s'"

Step 6.

Convert the '.po' file into '.mo' (Machine Object) file, which is a
binary file that contains the translated strings for retrieval during
program execution. Use the command like:

    % msgfmt -o de.mo de.po

Step 7.

Install the '.mo' file in /usr/share/locale/<locale> with renaming the
file to be your package's name, like this:

    % cp de.mo /usr/share/locale/de/mypackage.mo
    % cp fr.mo /usr/share/locale/fr/mypackage.mo

Step 8.

Compile your program as usual, then you're done! Remember to set the
locale you want before executing your program.


Updating the translation
------------------------
Use 'xgettext' as in Step 4 above to generate a new '.po' file. This
file, of course, contains no translations.

Then you use 'msgmerge' to combine the old and new '.po' files
together, like this:

    % msgmerge -o <combined.po> <old.po> <new.po> 

'msgmerge' can intelligently merge the two '.po' files into one. You
can now replace the old '.po' with the newly combined one, and
translate it.

The other procedures are the same as the above.


Wrap up
-------
For more information, read the gettext info page by 'info gettext'.

I wrote this when I was stilling a beginner in using gettext, so
improvement, corrections, enhancement, updates, suggestions are all
welcome. You're welcome to modify this document and submit me patch
too.

Copyright 1999 Anthony Wong <ypwong@debian.org>

Reply to: