README.i18n 8.52 KB
Newer Older
1 2 3
This document exists to document the important things to care for
because of locale support. 
Actually this one is maintained by me, that is Daniel Egger 
Sven Neumann's avatar
Sven Neumann committed
4 5
(Daniel.Egger@rz.fh-muenchen.de).
	
6 7 8 9 10

1. Why localisation?

 Many persons from many countries start to get used to Linux.
 Unfortunately not everyone is able to understand English. But
Marc Lehmann's avatar
Marc Lehmann committed
11
 even those people sometimes like to use good and free software 
12
 without using a dictionary to get the unknown words.
13
 So why not simply localise the software to make it available to 
Marc Lehmann's avatar
Marc Lehmann committed
14 15
 the mass which isn't wholly English native? Of course this also
 eases the migration from PhotoX to GIMP. :))
16 17 18 19 20 21 22 23

2. How?

 GNU provides a very nice package called gettext. This one offers
 the possibility to translate chosen messages from the native language
 of the program into that one of the users if a necessary catalog is
 provided. Gettext therefor provides some easy tools to create and maintain
 such catalogs and a few functions which can be called by the program to
24 25 26
 enable automatic translation at runtime. The program gets linked to the 
 gettext library or glibc2 which already provides that functionality
 and everything is fine.
27 28 29 30 31 32
 By the way: gettext is a fixed part of glibc2 but will be shipped with
 GIMP and so can be automatically compiled on every platform GIMP itself
 runs on.

3. Deep inside...

33 34 35 36
 GIMP provides header files called gimpintl.h and stdplugins-intl.h in the 
 libgimp directory which check whether gettext is available on the system 
 which GIMP is compiled on and will deactivate language support if it's not.
 You CAN use such a compiled GIMP even without the catalogs or on a system
Marc Lehmann's avatar
Marc Lehmann committed
37
 which dosen't have language support.
38 39 40

 If the gettext system is there it will declare 3 functions which will be 
 described below.
41 42 43

3.1 _() [more correctly: char * _( char * )]

Marc Lehmann's avatar
Marc Lehmann committed
44 45 46
 This one is a macro for the function gettext(). You can wrap any text with
 it that is allowed to be a return value of a function. If you use it then
 libintl will try to translate it into the native language of the
47
 user according to his/her environmental settings. 
Marc Lehmann's avatar
Marc Lehmann committed
48
 The gettext() function will do a lookup in the hashed catalog which contains 
49 50 51
 all the translated texts.

 - If it is found a pointer to the string will be returned to the caller.
Marc Lehmann's avatar
Marc Lehmann committed
52
 - If not, the caller will receive a pointer to the original string.
53 54

 This way it is ensured that there isn't any harm caused to the program 
Marc Lehmann's avatar
Marc Lehmann committed
55
 (i.e. The GIMP) if no useful catalog is installed. 
56 57 58 59

 Please note that it is important to use _() directly (and not gettext())
 for simple messages because of reasons that will be mentioned below.

60 61
 NOTE: I know some of the developer like short functions like _() but
 for a better source understanding I suggest to use it consistently only
Marc Lehmann's avatar
Marc Lehmann committed
62 63
 for text (like _("That's text!")) and not for variables (like _(text) ) BUT
 gettext(text) instead.
64 65
 

Marc Lehmann's avatar
Marc Lehmann committed
66
3.2 N_() [more correctly: const char * ( const char * ) ]
67 68

 This one is a macro for the function gettext_noop(). As you can see and
Marc Lehmann's avatar
Marc Lehmann committed
69 70
 guess it doesn't really do anything in the programm i.e. it is a dummy
 macro but nevertheless important. As it isn't possible to call functions
71 72 73 74 75 76 77 78
 in a structure as seen here:

 struct blurb
 {
  _("This won't work\n");
 }

 you have to do it in some other way. In GIMP such structures are often used 
Marc Lehmann's avatar
Marc Lehmann committed
79 80 81 82
 to create menus or similar things very simply. Here you have to use the
 dummy to allow the generation of the template catalog which will be described 
 below. This one doesn't do anything but it marks the text as important to 
 the xgettext extractor.
83

Marc Lehmann's avatar
Marc Lehmann committed
84
 The text has to be translated manually with the next function.  
85 86 87 88
 
3.3 gettext()

 This function is the same as that mcaro in 3.1. But there is one big
89 90
 difference: The _()'s and N_()'s are the only expressions which get parsed
 by the template generator. 
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
 If you have strings that should be translated but are unfortunately in a
 structure you have to do that on your own which means that you have to
 parse the fields with the messages in a loop and translate the texts with
 this gettext() function.

 Please note that it may be necessary to free or allocate memory in this
 case!      

4. Some magic...

 As you have seen we only did the programming part until now but this isn't
 all by far. 
 To use catalogs we'll have to create them. Now there are 3 different files
 which are importart:

 gimp.pot:
 
 This one is the so called template. It contains the messages which are
 extracted from the sources and empty fields which have to get filled by the
 author. It is used to start a new catalog or to update the an already
 available one. 

 The Makefile will automatically call the program gettext which will extract
 all messages that are wrapped by a _() or a N_() (but NOT gettext()) and
 concat them to this template.

 [language].po: 

 This file has to be an edited gimp.pot and contains the original messages 
 plus the translated ones. This file will be delivered together with GIMP
 and is the base for the final catalog.

 [language].mo:

 This file is a compiled version of [language.po] which will be
126
 automatically compiled by the Makefile system and installed in the locale
127 128 129 130 131 132 133 134 135
 directory of the system. It contains everything that the .po file
 contains except not translated messages, comments and other overhead.
 For maximum speed it is also hashed to allow gettext a faster search.

5. Tools and how to use them...

 As mentioned the to get translated string are extracted directly from the
 source and written to the template. 
 I guess many of you will now ask if it is necessary to add new strings
136 137
 directly to the template or if there's a tool to achieve that. 
 I think I can calm down those of you who fear lots of had work just to
138 139
 update the language files. There's a program called msgmerge which will 
 add all strings that are in the template but not in the uncompiled catalog 
140 141
 to it. Msgmerge does this job very nicely and also tries to use some kind
 of fuzzy logic method for already translated strings for possible reduction
Marc Lehmann's avatar
Marc Lehmann committed
142
 of translators work: If a original string seems similar to a new one 
143
 and it already has a translation, it will be taken over to the new catalog
144
 together with a remark that this one may not necessarily fit.
145
 
Sven Neumann's avatar
Sven Neumann committed
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
6. Gimp is different

 Gimp is a complex application which has a bunch of scripts and plug-ins 
 that all want to be internationalized. Therefore there is not one catalog
 but many. For a full translation of the GIMP's UI, you will have to add
 translations for the following catalogs:

	 po/gimp.pot		          --  the core
	 po-libgimp/gimp-libgimp.pot	  --  the libgimp library
	 po-plugins/gimp-std-plugins.pot  --  most of the plug-ins
	 plug-ins/perl/po/gimp-perl.pot   --  the gimp-perl scripts
	 po-script-fu/gimp-script-fu.pot  --  the script-fu scripts

 When translating menu_paths, please do not translate the name of the
 item_factory (that is the one in brackets at the front), e.g. 
 <Image>/Edit/Copy  should _not_ be translated to <Bild>/Bearbeiten/Kopieren,
 but to <Image>/Bearbeiten/Kopieren. If you get this wrong, Gimp will warn you 
 at startup about bad translations. So do always test your translations and
 watch the console for output.

7. Adding additional textdomains

 Third-party plug-ins (plug-ins that are not distributed with The GIMP) can't 
 have their messages in the gimp-std-plugins textdomain. We have therefore 
 provided a mechanism that allows plug-ins to install their own message
 catalogs and tell The GIMP to bind to that textdomain. This is necessary so 
 that The GIMP can correctly translate the menupaths the plug-in registers. 
 Basically the plug-in has to call  gimp_plugin_domain_add() or 
 gimp_domain_plugin_add_with_path() before it registers any functions. Have a 
 look at the script-fu plug-in to see how it is done in detail.

177 178 179 180 181 182 183 184 185 186 187 188 189
8. Tip of the Day messages

 In addition to message catalogs Gimp provides a file with tips that are
 displayed in a Tip of The Day window. Tips in English language are located
 in tips/gimp_tips.txt. Translated tips should go into
 gimp_tips.<lang>.txt. There is one more thing: You need to make sure you
 have the right reference set up in po/<lang>.po file something like this:  

 #: app/tips_dialog.c:72
 msgid "gimp_tips.txt"
 msgstr "gimp_tips.<lang>.txt"

9. And more?
190 191 192

 I hope I mentioned everything that is worth it and hope that this document
 will clarify some things. If it doesn't please write me a mail and tell me
Marc Lehmann's avatar
Marc Lehmann committed
193
 what you want to know. This text of course contains errors, so if you find one
194 195
 tell it to me, too....

196

197
Happy Gimping. Yours,
Marc Lehmann's avatar
Marc Lehmann committed
198 199
                     Daniel Egger

Sven Neumann's avatar
Sven Neumann committed
200 201 202 203


Sections (6) and (7) were added by Sven Neumann <sven@gimp.org>. He is the one
to blame for errors in there...