1*946379e7Schristos<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML i18n//EN"> 2*946379e7Schristos 3*946379e7Schristos<!--Converted with jLaTeX2HTML 2002-2-1 (1.70) JA patch-1.4 4*946379e7Schristospatched version by: Kenshi Muto, Debian Project. 5*946379e7SchristosLaTeX2HTML 2002-2-1 (1.70), 6*946379e7Schristosoriginal version by: Nikos Drakos, CBLU, University of Leeds 7*946379e7Schristos* revised and updated by: Marcus Hennecke, Ross Moore, Herb Swan 8*946379e7Schristos* with significant contributions from: 9*946379e7Schristos Jens Lippmann, Marek Rouchal, Martin Wilck and others --> 10*946379e7Schristos<HTML> 11*946379e7Schristos<HEAD> 12*946379e7Schristos<TITLE>A tutorial on Native Language Support using GNU gettext</TITLE> 13*946379e7Schristos<META NAME="description" CONTENT="A tutorial on Native Language Support using GNU gettext"> 14*946379e7Schristos<META NAME="keywords" CONTENT="memo"> 15*946379e7Schristos<META NAME="resource-type" CONTENT="document"> 16*946379e7Schristos<META NAME="distribution" CONTENT="global"> 17*946379e7Schristos 18*946379e7Schristos<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8"> 19*946379e7Schristos<META NAME="Generator" CONTENT="jLaTeX2HTML v2002-2-1 JA patch-1.4"> 20*946379e7Schristos<META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css"> 21*946379e7Schristos 22*946379e7Schristos<!-- 23*946379e7Schristos<LINK REL="STYLESHEET" HREF="memo.css"> 24*946379e7Schristos--> 25*946379e7Schristos 26*946379e7Schristos</HEAD> 27*946379e7Schristos 28*946379e7Schristos<BODY > 29*946379e7Schristos 30*946379e7Schristos<!--Navigation Panel 31*946379e7Schristos<DIV CLASS="navigation"> 32*946379e7Schristos<IMG WIDTH="81" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next_inactive" 33*946379e7Schristos SRC="file:/usr/share/latex2html/icons/nx_grp_g.png"> 34*946379e7Schristos<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up" 35*946379e7Schristos SRC="file:/usr/share/latex2html/icons/up_g.png"> 36*946379e7Schristos<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous" 37*946379e7Schristos SRC="file:/usr/share/latex2html/icons/prev_g.png"> 38*946379e7Schristos<BR> 39*946379e7Schristos<BR><BR></DIV> 40*946379e7SchristosEnd of Navigation Panel--> 41*946379e7Schristos 42*946379e7Schristos<H1 ALIGN="CENTER">A tutorial on Native Language Support using GNU gettext</H1><DIV CLASS="author_info"> 43*946379e7Schristos 44*946379e7Schristos<P ALIGN="CENTER"><STRONG>G. Mohanty</STRONG></P> 45*946379e7Schristos<P ALIGN="CENTER"><STRONG>Revision 0.3: 24 July 2004</STRONG></P> 46*946379e7Schristos</DIV> 47*946379e7Schristos 48*946379e7Schristos<H3>Abstract:</H3> 49*946379e7Schristos<DIV CLASS="ABSTRACT"> 50*946379e7Schristos The use of the GNU <TT>gettext</TT> utilities to implement support for native 51*946379e7Schristoslanguages is described here. Though, the language to be supported is 52*946379e7Schristosconsidered to be Oriya, the method is generally applicable. Likewise, while 53*946379e7SchristosLinux was used as the platform here, any system using GNU <TT>gettext</TT> should work 54*946379e7Schristosin a similar fashion. 55*946379e7Schristos 56*946379e7Schristos<P> 57*946379e7SchristosWe go through a step-by-step description of how to make on-screen messages 58*946379e7Schristosfrom a toy program to appear in Oriya instead of English; starting from the 59*946379e7Schristosprogramming and ending with the user's viewpoint. Some discussion is also made 60*946379e7Schristosof how to go about the task of translation. 61*946379e7Schristos</DIV> 62*946379e7Schristos<P> 63*946379e7Schristos<H1><A NAME="SECTION00010000000000000000"> 64*946379e7SchristosIntroduction</A> 65*946379e7Schristos</H1> 66*946379e7SchristosCurrently, both commercial and free computer software is typically written and 67*946379e7Schristosdocumented in English. Till recently, little effort was expended towards 68*946379e7Schristosallowing them to interact with the user in languages other than English, thus 69*946379e7Schristosleaving the non-English speaking world at a disadvantage. However, that 70*946379e7Schristoschanged with the release of the GNU <TT>gettext</TT> utilities, and nowadays most GNU 71*946379e7Schristosprograms are written within a framework that allows easy translation of the 72*946379e7Schristosprogram message to languages other than English. Provided that translations 73*946379e7Schristosare available, the language used by the program to interact with the user can 74*946379e7Schristosbe set at the time of running it. <TT>gettext</TT> manages to achieve this seemingly 75*946379e7Schristosmiraculous task in a manner that simplifies the work of both the programmer 76*946379e7Schristosand the translator, and, more importantly, allows them to work independently 77*946379e7Schristosof each other. 78*946379e7Schristos 79*946379e7Schristos<P> 80*946379e7SchristosThis article describes how to support native languages under a system using 81*946379e7Schristosthe GNU <TT>gettext</TT> utilities. While it should be applicable to other versions of 82*946379e7Schristos<TT>gettext</TT>, the one actually used for the examples here is version 83*946379e7Schristos0.12.1. Another system, called <TT>catgets</TT>, described in the X/Open 84*946379e7SchristosPortability Guide, is also in use, but we shall not discuss that here. 85*946379e7Schristos 86*946379e7Schristos<P> 87*946379e7Schristos 88*946379e7Schristos<H1><A NAME="SECTION00020000000000000000"> 89*946379e7SchristosA simple example</A> 90*946379e7Schristos</H1> 91*946379e7Schristos<A NAME="sec:simple"></A>Our first example of using <TT>gettext</TT> will be the good old Hello World program, 92*946379e7Schristoswhose sole function is to print the phrase ``Hello, world!'' to the terminal. 93*946379e7SchristosThe internationalized version of this program might be saved in hello.c as: 94*946379e7Schristos<PRE> 95*946379e7Schristos1 #include <libintl.h> 96*946379e7Schristos2 #include <locale.h> 97*946379e7Schristos3 #include <stdio.h> 98*946379e7Schristos4 #include <stdlib.h> 99*946379e7Schristos5 int main(void) 100*946379e7Schristos6 { 101*946379e7Schristos7 setlocale( LC_ALL, "" ); 102*946379e7Schristos8 bindtextdomain( "hello", "/usr/share/locale" ); 103*946379e7Schristos9 textdomain( "hello" ); 104*946379e7Schristos10 printf( gettext( "Hello, world!\n" ) ); 105*946379e7Schristos11 exit(0); 106*946379e7Schristos12 } 107*946379e7Schristos</PRE> 108*946379e7SchristosOf course, a real program would check the return values of the functions and 109*946379e7Schristostry to deal with any errors, but we have omitted that part of the code for 110*946379e7Schristosclarity. Compile as usual with <TT>gcc -o hello hello.c</TT>. The program should 111*946379e7Schristosbe linked to the GNU libintl library, but as this is part of the GNU C 112*946379e7Schristoslibrary, this is done automatically for you under Linux, and other systems 113*946379e7Schristosusing glibc. 114*946379e7Schristos 115*946379e7Schristos<H2><A NAME="SECTION00021000000000000000"> 116*946379e7SchristosThe programmer's viewpoint</A> 117*946379e7Schristos</H2> 118*946379e7Schristos As expected, when the <TT>hello</TT> executable is run under the default locale 119*946379e7Schristos(usually the C locale) it prints ``Hello, world!'' in the terminal. Besides 120*946379e7Schristossome initial setup work, the only additional burden faced by the programmer is 121*946379e7Schristosto replace any string to be printed with <TT>gettext(string)</TT>, i.e., to 122*946379e7Schristosinstead pass the string as an argument to the <TT>gettext</TT> function. For lazy 123*946379e7Schristospeople like myself, the amount of extra typing can be reduced even further by 124*946379e7Schristosa CPP macro, e.g., put this at the beginning of the source code file, 125*946379e7Schristos<PRE> 126*946379e7Schristos #define _(STRING) gettext(STRING) 127*946379e7Schristos</PRE> 128*946379e7Schristosand then use <TT>_(string)</TT> instead of <TT>gettext(string)</TT>. 129*946379e7Schristos 130*946379e7Schristos<P> 131*946379e7SchristosLet us dissect the program line-by-line. 132*946379e7Schristos 133*946379e7Schristos<OL> 134*946379e7Schristos<LI><TT>locale.h</TT> defines C data structures used to hold locale 135*946379e7Schristos information, and is needed by the <TT>setlocale</TT> function. <TT>libintl.h</TT> 136*946379e7Schristos prototypes the GNU text utilities functions, and is needed here by 137*946379e7Schristos <TT>bindtextdomain</TT>, <TT>gettext</TT>, and <TT>textdomain</TT>. 138*946379e7Schristos</LI> 139*946379e7Schristos<LI>The call to <TT>setlocale</TT> () on line 7, with LC_ALL as the first argument 140*946379e7Schristos and an empty string as the second one, initializes the entire current locale 141*946379e7Schristos of the program as per environment variables set by the user. In other words, 142*946379e7Schristos the program locale is initialized to match that of the user. For details see 143*946379e7Schristos ``man <TT>setlocale</TT>.'' 144*946379e7Schristos</LI> 145*946379e7Schristos<LI>The <TT>bindtextdomain</TT> function on line 8 sets the base directory for the 146*946379e7Schristos message catalogs for a given message domain. A message domain is a set of 147*946379e7Schristos translatable messages, with every software package typically having its own 148*946379e7Schristos domain. Here, we have used ``hello'' as the name of the message domain for 149*946379e7Schristos our toy program. As the second argument, /usr/share/locale, is the default 150*946379e7Schristos system location for message catalogs, what we are saying here is that we are 151*946379e7Schristos going to place the message catalog in the default system directory. Thus, we 152*946379e7Schristos could have dispensed with the call to <TT>bindtextdomain</TT> here, and this 153*946379e7Schristos function is useful only if the message catalogs are installed in a 154*946379e7Schristos non-standard place, e.g., a packaged software distribution might have 155*946379e7Schristos the catalogs under a po/ directory under its own main directory. See ``man 156*946379e7Schristos <TT>bindtextdomain</TT>'' for details. 157*946379e7Schristos</LI> 158*946379e7Schristos<LI>The <TT>textdomain</TT> call on line 9 sets the message domain of the current 159*946379e7Schristos program to ``hello,'' i.e., the name that we are using for our example 160*946379e7Schristos program. ``man textdomain'' will give usage details for the function. 161*946379e7Schristos</LI> 162*946379e7Schristos<LI>Finally, on line 10, we have replaced what would normally have been, 163*946379e7Schristos<PRE> 164*946379e7Schristos printf( "Hello, world!\n" ); 165*946379e7Schristos</PRE> 166*946379e7Schristoswith, 167*946379e7Schristos<PRE> 168*946379e7Schristos printf( gettext( "Hello, world!\n" ) ); 169*946379e7Schristos</PRE> 170*946379e7Schristos(If you are unfamiliar with C, the <!-- MATH 171*946379e7Schristos $\backslash$ 172*946379e7Schristos --> 173*946379e7Schristos<SPAN CLASS="MATH">\</SPAN>n at the end of the string 174*946379e7Schristosproduces a newline at the end of the output.) This simple modification to all 175*946379e7Schristostranslatable strings allows the translator to work independently from the 176*946379e7Schristosprogrammer. <TT>gettextize</TT> eases the task of the programmer in adapting a 177*946379e7Schristospackage to use GNU <TT>gettext</TT> for the first time, or to upgrade to a newer 178*946379e7Schristosversion of <TT>gettext</TT>. 179*946379e7Schristos</LI> 180*946379e7Schristos</OL> 181*946379e7Schristos 182*946379e7Schristos<H2><A NAME="SECTION00022000000000000000"> 183*946379e7SchristosExtracting translatable strings</A> 184*946379e7Schristos</H2> 185*946379e7Schristos Now, it is time to extract the strings to be translated from the program 186*946379e7Schristossource code. This is achieved with <TT>xgettext</TT>, which can be invoked as follows: 187*946379e7Schristos<PRE><FONT color="red"> 188*946379e7Schristos xgettext -d hello -o hello.pot hello.c 189*946379e7Schristos</FONT></PRE> 190*946379e7SchristosThis processes the source code in hello.c, saving the output in hello.pot (the 191*946379e7Schristosargument to the -o option). 192*946379e7SchristosThe message domain for the program should be specified as the argument 193*946379e7Schristosto the -d option, and should match the domain specified in the call to 194*946379e7Schristos<TT>textdomain</TT> (on line 9 of the program source). Other details on how to use 195*946379e7Schristos<TT>gettext</TT> can be found from ``man gettext.'' 196*946379e7Schristos 197*946379e7Schristos<P> 198*946379e7SchristosA .pot (portable object template) file is used as the basis for translating 199*946379e7Schristosprogram messages into any language. To start translation, one can simply copy 200*946379e7Schristoshello.pot to oriya.po (this preserves the template file for later translation 201*946379e7Schristosinto a different language). However, the preferred way to do this is by 202*946379e7Schristosuse of the <TT>msginit</TT> program, which takes care of correctly setting up some 203*946379e7Schristosdefault values, 204*946379e7Schristos<PRE><FONT color="red"> 205*946379e7Schristos msginit -l or_IN -o oriya.po -i hello.pot 206*946379e7Schristos</FONT></PRE> 207*946379e7SchristosHere, the -l option defines the locale (an Oriya locale should have been 208*946379e7Schristosinstalled on your system), and the -i and -o options define the input and 209*946379e7Schristosoutput files, respectively. If there is only a single .pot file in the 210*946379e7Schristosdirectory, it will be used as the input file, and the -i option can be 211*946379e7Schristosomitted. For me, the oriya.po file produced by <TT>msginit</TT> would look like: 212*946379e7Schristos<PRE> 213*946379e7Schristos # Oriya translations for PACKAGE package. 214*946379e7Schristos # Copyright (C) 2004 THE PACKAGE'S COPYRIGHT HOLDER 215*946379e7Schristos # This file is distributed under the same license as the PACKAGE package. 216*946379e7Schristos # Gora Mohanty <gora_mohanty@yahoo.co.in>, 2004. 217*946379e7Schristos # 218*946379e7Schristos msgid "" 219*946379e7Schristos msgstr "" 220*946379e7Schristos "Project-Id-Version: PACKAGE VERSION\n" 221*946379e7Schristos "Report-Msgid-Bugs-To: \n" 222*946379e7Schristos "POT-Creation-Date: 2004-06-22 02:22+0530\n" 223*946379e7Schristos "PO-Revision-Date: 2004-06-22 02:38+0530\n" 224*946379e7Schristos "Last-Translator: Gora Mohanty <gora_mohanty@yahoo.co.in>\n" 225*946379e7Schristos "Language-Team: Oriya\n" 226*946379e7Schristos "MIME-Version: 1.0\n" 227*946379e7Schristos "Content-Type: text/plain; charset=UTF-8\n" 228*946379e7Schristos "Content-Transfer-Encoding: 8bit\n" 229*946379e7Schristos 230*946379e7Schristos #: hello.c:10 231*946379e7Schristos msgid "Hello, world!\n" 232*946379e7Schristos msgstr "" 233*946379e7Schristos</PRE> 234*946379e7Schristos<TT>msginit</TT> prompted for my email address, and probably obtained my real name 235*946379e7Schristosfrom the system password file. It also filled in values such as the revision 236*946379e7Schristosdate, language, character set, presumably using information from the or_IN 237*946379e7Schristoslocale. 238*946379e7Schristos 239*946379e7Schristos<P> 240*946379e7SchristosIt is important to respect the format of the entries in the .po (portable 241*946379e7Schristosobject) file. Each entry has the following structure: 242*946379e7Schristos<PRE> 243*946379e7Schristos WHITE-SPACE 244*946379e7Schristos # TRANSLATOR-COMMENTS 245*946379e7Schristos #. AUTOMATIC-COMMENTS 246*946379e7Schristos #: REFERENCE... 247*946379e7Schristos #, FLAG... 248*946379e7Schristos msgid UNTRANSLATED-STRING 249*946379e7Schristos msgstr TRANSLATED-STRING 250*946379e7Schristos</PRE> 251*946379e7Schristoswhere, the initial white-space (spaces, tabs, newlines,...), and all 252*946379e7Schristoscomments might or might not exist for a particular entry. Comment lines start 253*946379e7Schristoswith a '#' as the first character, and there are two kinds: (i) manually 254*946379e7Schristosadded translator comments, that have some white-space immediately following the 255*946379e7Schristos'#,' and (ii) automatic comments added and maintained by the <TT>gettext</TT> tools, 256*946379e7Schristoswith a non-white-space character after the '#.' The <TT>msgid</TT> line contains 257*946379e7Schristosthe untranslated (English) string, if there is one for that PO file entry, and 258*946379e7Schristosthe <TT>msgstr</TT> line is where the translated string is to be entered. More on 259*946379e7Schristosthis later. For details on the format of PO files see gettext::Basics::PO 260*946379e7SchristosFiles:: in the Emacs info-browser (see Appdx. <A HREF="#sec:emacs-info">A</A> for an 261*946379e7Schristosintroduction to using the info-browser in Emacs). 262*946379e7Schristos 263*946379e7Schristos<H2><A NAME="SECTION00023000000000000000"> 264*946379e7SchristosMaking translations</A> 265*946379e7Schristos</H2> 266*946379e7Schristos The oriya.po file can then be edited to add the translated Oriya 267*946379e7Schristosstrings. While the editing can be carried out in any editor if one is careful 268*946379e7Schristosto follow the PO file format, there are several editors that ease the task of 269*946379e7Schristosediting PO files, among them being po-mode in Emacs, <TT>kbabel</TT>, gtranslator, 270*946379e7Schristospoedit, etc. Appdx. <A HREF="#sec:pofile-editors">B</A> describes features of some of 271*946379e7Schristosthese editors. 272*946379e7Schristos 273*946379e7Schristos<P> 274*946379e7SchristosThe first thing to do is fill in the comments at the beginning and the header 275*946379e7Schristosentry, parts of which have already been filled in by <TT>msginit</TT>. The lines in 276*946379e7Schristosthe header entry are pretty much self-explanatory, and details can be found in 277*946379e7Schristosthe gettext::Creating::Header Entry:: info node. After that, the remaining 278*946379e7Schristoswork consists of typing the Oriya text that is to serve as translations for 279*946379e7Schristosthe corresponding English string. For the <TT>msgstr</TT> line in each of the 280*946379e7Schristosremaining entries, add the translated Oriya text between the double quotes; 281*946379e7Schristosthe translation corresponding to the English phrase in the <TT>msgid</TT> string 282*946379e7Schristosfor the entry. For example, for the phrase ``Hello world!<!-- MATH 283*946379e7Schristos $\backslash$ 284*946379e7Schristos --> 285*946379e7Schristos<SPAN CLASS="MATH">\</SPAN>n'' in 286*946379e7Schristosoriya.po, we could enter ``ନମସ୍କାର<!-- MATH 287*946379e7Schristos $\backslash$ 288*946379e7Schristos --> 289*946379e7Schristos<SPAN CLASS="MATH">\</SPAN>n''. The final 290*946379e7Schristosoriya.po file might look like: 291*946379e7Schristos<PRE> 292*946379e7Schristos # Oriya translations for hello example package. 293*946379e7Schristos # Copyright (C) 2004 Gora Mohanty 294*946379e7Schristos # This file is distributed under the same license as the hello example package. 295*946379e7Schristos # Gora Mohanty <gora_mohanty@yahoo.co.in>, 2004. 296*946379e7Schristos # 297*946379e7Schristos msgid "" 298*946379e7Schristos msgstr "" 299*946379e7Schristos "Project-Id-Version: oriya\n" 300*946379e7Schristos "Report-Msgid-Bugs-To: \n" 301*946379e7Schristos "POT-Creation-Date: 2004-06-22 02:22+0530\n" 302*946379e7Schristos "PO-Revision-Date: 2004-06-22 10:54+0530\n" 303*946379e7Schristos "Last-Translator: Gora Mohanty <gora_mohanty@yahoo.co.in>\n" 304*946379e7Schristos "Language-Team: Oriya\n" 305*946379e7Schristos "MIME-Version: 1.0\n" 306*946379e7Schristos "Content-Type: text/plain; charset=UTF-8\n" 307*946379e7Schristos "Content-Transfer-Encoding: 8bit\n" 308*946379e7Schristos "X-Generator: KBabel 1.3\n" 309*946379e7Schristos 310*946379e7Schristos #: hello.c:10 311*946379e7Schristos msgid "Hello, world!\n" 312*946379e7Schristos msgstr "ନମସ୍କାର\n" 313*946379e7Schristos</PRE> 314*946379e7Schristos 315*946379e7Schristos<P> 316*946379e7SchristosFor editing PO files, I have found the <TT>kbabel</TT> editor suits me the best. The 317*946379e7Schristosonly problem is that while Oriya text can be entered directly into <TT>kbabel</TT> 318*946379e7Schristosusing the xkb Oriya keyboard layouts [<A 319*946379e7Schristos HREF="memo.html#xkb-oriya-layout">1</A>] and the entries 320*946379e7Schristosare saved properly, the text is not displayed correctly in the <TT>kbabel</TT> window 321*946379e7Schristosif it includes conjuncts. Emacs po-mode is a little restrictive, but strictly 322*946379e7Schristosenforces conformance with the PO file format. The main problem with it is that 323*946379e7Schristosit does not seem currently possible to edit Oriya text in Emacs. <TT>yudit</TT> 324*946379e7Schristosis the best at editing Oriya text, but does not ensure that the PO file format 325*946379e7Schristosis followed. You can play around a bit with these editors to find one that 326*946379e7Schristossuits your personal preferences. One possibility might be to first edit the 327*946379e7Schristosheader entry with <TT>kbabel</TT> or Emacs po-mode, and then use <TT>yudit</TT> to enter 328*946379e7Schristosthe Oriya text on the <TT>msgstr</TT> lines. 329*946379e7Schristos 330*946379e7Schristos<H2><A NAME="SECTION00024000000000000000"> 331*946379e7SchristosMessage catalogs</A> 332*946379e7Schristos</H2> 333*946379e7Schristos <A NAME="sec:catalog"></A>After completing the translations in the oriya.po file, it must be compiled to 334*946379e7Schristosa binary format that can be quickly loaded by the <TT>gettext</TT> tools. To do that, 335*946379e7Schristosuse: 336*946379e7Schristos<PRE><FONT color="red"> 337*946379e7Schristos msgfmt -c -v -o hello.mo oriya.po 338*946379e7Schristos</FONT></PRE> 339*946379e7SchristosThe -c option does detailed checking of the PO file format, -v makes the 340*946379e7Schristosprogram verbose, and the output filename is given by the argument to the -o 341*946379e7Schristosoption. Note that the base of the output filename should match the message 342*946379e7Schristosdomain given in the first arguments to <TT>bindtextdomain</TT> and <TT>textdomain</TT> on 343*946379e7Schristoslines 8 and 9 of the example program in Sec. <A HREF="#sec:simple">2</A>. The .mo 344*946379e7Schristos(machine object) file should be stored in the location whose base directory is 345*946379e7Schristosgiven by the second argument to <TT>bindtextdomain</TT>. The final location of the 346*946379e7Schristosfile will be in the sub-directory LL/LC_MESSAGES or LL_CC/LC_MESSAGES under 347*946379e7Schristosthe base directory, where LL stands for a language, and CC for a country. For 348*946379e7Schristosexample, as we have chosen the standard location, /usr/share/locale, for our 349*946379e7Schristosbase directory, and for us the language and country strings are ``or'' and 350*946379e7Schristos``IN,'' respectively, we will place hello.mo in /usr/share/locale/or_IN. Note 351*946379e7Schristosthat you will need super-user privilege to copy hello.mo to this system 352*946379e7Schristosdirectory. Thus, 353*946379e7Schristos<PRE><FONT color="red"> 354*946379e7Schristos mkdir -p /usr/share/locale/or_IN/LC_MESSAGES 355*946379e7Schristos cp hello.mo /usr/share/locale/or_IN/LC_MESSAGES 356*946379e7Schristos</FONT></PRE> 357*946379e7Schristos 358*946379e7Schristos<H2><A NAME="SECTION00025000000000000000"> 359*946379e7SchristosThe user's viewpoint</A> 360*946379e7Schristos</H2> 361*946379e7Schristos Once the message catalogs have been properly installed, any user on the system 362*946379e7Schristoscan use the Oriya version of the Hello World program, provided an Oriya locale 363*946379e7Schristosis available. First, change your locale with, 364*946379e7Schristos<PRE><FONT color="red"> 365*946379e7Schristos echo $LANG 366*946379e7Schristos export LANG=or_IN 367*946379e7Schristos</FONT></PRE> 368*946379e7SchristosThe first statement shows you the current setting of your locale (this is 369*946379e7Schristosusually en_US, and you will need it to reset the default locale at the end), 370*946379e7Schristoswhile the second one sets it to an Oriya locale. 371*946379e7Schristos 372*946379e7Schristos<P> 373*946379e7SchristosA Unicode-capable terminal emulator is needed to view Oriya output 374*946379e7Schristosdirectly. The new versions of both gnome-terminal and konsole (the KDE 375*946379e7Schristosterminal emulator) are Unicode-aware. I will focus on gnome-terminal as it 376*946379e7Schristosseems to have better support for internationalization. gnome-terminal needs to 377*946379e7Schristosbe told that the bytes arriving are UTF-8 encoded multibyte sequences. This 378*946379e7Schristoscan be done by (a) choosing Terminal <TT>-></TT> Character Coding <TT>-></TT> 379*946379e7SchristosUnicode (UTF-8), or (b) typing ``/bin/echo -n -e 380*946379e7Schristos'<!-- MATH 381*946379e7Schristos $\backslash$ 382*946379e7Schristos --> 383*946379e7Schristos<SPAN CLASS="MATH">\</SPAN>033%<!-- MATH 384*946379e7Schristos $\backslash$ 385*946379e7Schristos --> 386*946379e7Schristos<SPAN CLASS="MATH">\</SPAN>G''' in the terminal, or (c) by running 387*946379e7Schristos/bin/unicode_start. Likewise, you can revert to the default locale by (a) 388*946379e7Schristoschoosing Terminal <TT>-></TT> Character Coding <TT>-></TT> Current Locale 389*946379e7Schristos(ISO-8859-1), or (b) ``/bin/echo -n -e '<!-- MATH 390*946379e7Schristos $\backslash$ 391*946379e7Schristos --> 392*946379e7Schristos<SPAN CLASS="MATH">\</SPAN>033%<!-- MATH 393*946379e7Schristos $\backslash$ 394*946379e7Schristos --> 395*946379e7Schristos<SPAN CLASS="MATH">\</SPAN>@','' or 396*946379e7Schristos(c) by running /bin/unicode_stop. Now, running the example program (after 397*946379e7Schristoscompiling with gcc as described in Sec. <A HREF="#sec:simple">2</A>) with, 398*946379e7Schristos<PRE><FONT color="red"> 399*946379e7Schristos ./hello 400*946379e7Schristos</FONT></PRE> 401*946379e7Schristosshould give you output in Oriya. Please note that conjuncts will most likely 402*946379e7Schristosbe displayed with a ``halant'' as the terminal probably does not render Indian 403*946379e7Schristoslanguage fonts correctly. Also, as most terminal emulators assume fixed-width 404*946379e7Schristosfonts, the results are hardly likely to be aesthetically appealing. 405*946379e7Schristos 406*946379e7Schristos<P> 407*946379e7SchristosAn alternative is to save the program output in a file, and view it with 408*946379e7Schristos<TT>yudit</TT> which will render the glyphs correctly. Thus, 409*946379e7Schristos<PRE><FONT color="red"> 410*946379e7Schristos ./hello > junk 411*946379e7Schristos yudit junk 412*946379e7Schristos</FONT></PRE> 413*946379e7SchristosDo not forget to reset the locale before resuming usual work in the 414*946379e7Schristosterminal. Else, your English characters might look funny. 415*946379e7Schristos 416*946379e7Schristos<P> 417*946379e7SchristosWhile all this should give the average user some pleasure in being able to see 418*946379e7SchristosOriya output from a program without a whole lot of work, it should be kept in 419*946379e7Schristosmind that we are still far from our desired goal. Hopefully, one day the 420*946379e7Schristossituation will be such that rather than deriving special pleasure from it, 421*946379e7Schristosusers take it for granted that Oriya should be available and are upset 422*946379e7Schristosotherwise. 423*946379e7Schristos 424*946379e7Schristos<P> 425*946379e7Schristos 426*946379e7Schristos<H1><A NAME="SECTION00030000000000000000"> 427*946379e7SchristosAdding complications: program upgrade</A> 428*946379e7Schristos</H1> 429*946379e7SchristosThe previous section presented a simple example of how Oriya language support 430*946379e7Schristoscould be added to a C program. Like all programs, we might now wish to further 431*946379e7Schristosenhance it. For example, we could include a greeting to the user by adding 432*946379e7Schristosanother <TT>printf</TT> statement after the first one. Our new hello.c source 433*946379e7Schristoscode might look like this: 434*946379e7Schristos<PRE> 435*946379e7Schristos1 #include <libintl.h> 436*946379e7Schristos2 #include <locale.h> 437*946379e7Schristos3 #include <stdio.h> 438*946379e7Schristos4 #include <stdlib.h> 439*946379e7Schristos5 int main(void) 440*946379e7Schristos6 { 441*946379e7Schristos7 setlocale( LC_ALL, "" ); 442*946379e7Schristos8 bindtextdomain( "hello", "/usr/share/locale" ); 443*946379e7Schristos9 textdomain( "hello" ); 444*946379e7Schristos10 printf( gettext( "Hello, world!\n" ) ); 445*946379e7Schristos11 printf( gettext( "How are you\n" ) ); 446*946379e7Schristos12 exit(0); 447*946379e7Schristos13 } 448*946379e7Schristos</PRE> 449*946379e7SchristosFor such a small change, it would be simple enough to just repeat the above 450*946379e7Schristoscycle of extracting the relevant English text, translating it to Oriya, and 451*946379e7Schristospreparing a new message catalog. We can even simplify the work by cutting and 452*946379e7Schristospasting most of the old oriya.po file into the new one. However, real programs 453*946379e7Schristoswill have thousands of such strings, and we would like to be able to translate 454*946379e7Schristosonly the changed strings, and have the <TT>gettext</TT> utilities handle the drudgery 455*946379e7Schristosof combining the new translations with the old ones. This is indeed possible. 456*946379e7Schristos 457*946379e7Schristos<H2><A NAME="SECTION00031000000000000000"> 458*946379e7SchristosMerging old and new translations</A> 459*946379e7Schristos</H2> 460*946379e7Schristos As before, extract the translatable strings from hello.c to a new portable 461*946379e7Schristosobject template file, hello-new.pot, using <TT>xgettext</TT>, 462*946379e7Schristos<PRE><FONT color="red"> 463*946379e7Schristos xgettext -d hello -o hello-new.pot hello.c 464*946379e7Schristos</FONT></PRE> 465*946379e7SchristosNow, we use a new program, <TT>msgmerge</TT>, to merge the existing .po file with 466*946379e7Schristostranslations into the new template file, viz., 467*946379e7Schristos<PRE><FONT color="red"> 468*946379e7Schristos msgmerge -U oriya.po hello-new.pot 469*946379e7Schristos</FONT></PRE> 470*946379e7SchristosThe -U option updates the existing 471*946379e7Schristos.po file, oriya.po. We could have chosen to instead create a new .po file by 472*946379e7Schristosusing ``-o <SPAN CLASS="MATH"><</SPAN>filename<SPAN CLASS="MATH">></SPAN>'' instead of -U. The updated .po file will still 473*946379e7Schristoshave the old translations embedded in it, and new entries with untranslated 474*946379e7Schristos<TT>msgid</TT> lines. For us, the new lines in oriya.po will look like, 475*946379e7Schristos<PRE> 476*946379e7Schristos #: hello.c:11 477*946379e7Schristos msgid "How are you?\n" 478*946379e7Schristos msgstr "" 479*946379e7Schristos</PRE> 480*946379e7SchristosFor the new translation, we could use, ``ଆପଣ 481*946379e7Schristosକିପରି ଅଛନ୍ତି?'' in 482*946379e7Schristosplace of the English phrase ``How are you?'' The updated oriya.po file, 483*946379e7Schristosincluding the translation might look like: 484*946379e7Schristos<PRE> 485*946379e7Schristos # Oriya translations for hello example package. 486*946379e7Schristos # Copyright (C) 2004 Gora Mohanty 487*946379e7Schristos # This file is distributed under the same license as the hello examplepackage. 488*946379e7Schristos # Gora Mohanty <gora_mohanty@yahoo.co.in>, 2004. 489*946379e7Schristos # 490*946379e7Schristos msgid "" 491*946379e7Schristos msgstr "" 492*946379e7Schristos "Project-Id-Version: oriya\n" 493*946379e7Schristos "Report-Msgid-Bugs-To: \n" 494*946379e7Schristos "POT-Creation-Date: 2004-06-23 14:30+0530\n" 495*946379e7Schristos "PO-Revision-Date: 2004-06-22 10:54+0530\n" 496*946379e7Schristos "Last-Translator: Gora Mohanty <gora_mohanty@yahoo.co.in>\n" 497*946379e7Schristos "Language-Team: Oriya\n" 498*946379e7Schristos "MIME-Version: 1.0\n" 499*946379e7Schristos "Content-Type: text/plain; charset=UTF-8\n" 500*946379e7Schristos "Content-Transfer-Encoding: 8bit\n" 501*946379e7Schristos "X-Generator: KBabel 1.3\n" 502*946379e7Schristos 503*946379e7Schristos #: hello.c:10 504*946379e7Schristos msgid "Hello, world!\n" 505*946379e7Schristos msgstr "ନମସ୍କାର\n" 506*946379e7Schristos 507*946379e7Schristos #: hello.c:11 508*946379e7Schristos msgid "How are you?\n" 509*946379e7Schristos msgstr "ଆପଣ କିପରି ଅଛନ୍ତି?\n" 510*946379e7Schristos</PRE> 511*946379e7Schristos 512*946379e7Schristos<P> 513*946379e7SchristosCompile oriya.po to a machine object file, and install in the appropriate 514*946379e7Schristosplace as in Sec. <A HREF="#sec:catalog">2.4</A>. Thus, 515*946379e7Schristos<PRE><FONT color="red"> 516*946379e7Schristos msgfmt -c -v -o hello.mo oriya.po 517*946379e7Schristos mkdir -p /usr/share/locale/or_IN/LC_MESSAGES 518*946379e7Schristos cp hello.mo /usr/share/locale/or_IN/LC_MESSAGES 519*946379e7Schristos</FONT></PRE> 520*946379e7SchristosYou can test the Oriya output as above, after recompiling hello.c and running 521*946379e7Schristosit in an Oriya locale. 522*946379e7Schristos 523*946379e7Schristos<P> 524*946379e7Schristos 525*946379e7Schristos<H1><A NAME="SECTION00040000000000000000"> 526*946379e7SchristosMore about <TT>gettext</TT> </A> 527*946379e7Schristos</H1> 528*946379e7SchristosThe GNU <TT>gettext</TT> info pages provide a well-organized and complete description 529*946379e7Schristosof the <TT>gettext</TT> utilities and their usage for enabling Native Language 530*946379e7SchristosSupport. One should, at the very least, read the introductory material at 531*946379e7Schristosgettext::Introduction::, and the suggested references in 532*946379e7Schristosgettext::Conclusion::References::. Besides the <TT>gettext</TT> utilities described in 533*946379e7Schristosthis document, various other programs to manipulate .po files are discussed in 534*946379e7Schristosgettext:Manipulating::. Finally, support for programming languages other than 535*946379e7SchristosC/C++ is discussed in gettext::Programming Languages::. 536*946379e7Schristos 537*946379e7Schristos<P> 538*946379e7Schristos 539*946379e7Schristos<H1><A NAME="SECTION00050000000000000000"> 540*946379e7SchristosThe work of translation</A> 541*946379e7Schristos</H1> 542*946379e7Schristos Besides the obvious program message strings that have been the sole focus of 543*946379e7Schristosour discussion here, there are many other things that require translation, 544*946379e7Schristosincluding GUI messages, command-line option strings, configuration files, 545*946379e7Schristosprogram documentation, etc. Besides these obvious aspects, there are a 546*946379e7Schristossignificant number of programs and/or scripts that are automatically generated 547*946379e7Schristosby other programs. These generated programs might also themselves require 548*946379e7Schristostranslation. So, in any effort to provide support for a given native language, 549*946379e7Schristoscarrying out the translation and keeping up with program updates becomes a 550*946379e7Schristosmajor part of the undertaking, requiring a continuing commitment from the 551*946379e7Schristoslanguage team. A plan has been outlined for the Oriya localization 552*946379e7Schristosproject [<A 553*946379e7Schristos HREF="memo.html#url:oriya-trans-plan">2</A>]. 554*946379e7Schristos 555*946379e7Schristos<P> 556*946379e7Schristos 557*946379e7Schristos<H1><A NAME="SECTION00060000000000000000"> 558*946379e7SchristosAcknowledgments</A> 559*946379e7Schristos</H1> 560*946379e7SchristosExtensive use has obviously been made of the GNU <TT>gettext</TT> manual in preparing 561*946379e7Schristosthis document. I have also been helped by an article in the Linux 562*946379e7SchristosJournal [<A 563*946379e7Schristos HREF="memo.html#url:lj-translation">3</A>]. 564*946379e7Schristos 565*946379e7Schristos<P> 566*946379e7SchristosThis work is part of the project for enabling the use of Oriya under Linux. I 567*946379e7Schristosthank my uncle, N. M. Pattnaik, for conceiving of the project. We have all 568*946379e7Schristosbenefited from the discussions amidst the group of people working on this 569*946379e7Schristosproject. On the particular issue of translation, the help of H. R. Pansari, 570*946379e7SchristosA. Nayak, and M. Chand is much appreciated. 571*946379e7Schristos 572*946379e7Schristos<H1><A NAME="SECTION00070000000000000000"> 573*946379e7SchristosThe Emacs info browser</A> 574*946379e7Schristos</H1> 575*946379e7Schristos<A NAME="sec:emacs-info"></A>You can start up Emacs from the command-line by typing ``emacs,'' or ``emacs 576*946379e7Schristos<SPAN CLASS="MATH"><</SPAN>filename<SPAN CLASS="MATH">></SPAN>.'' It can be started from the menu in some desktops, e.g., on 577*946379e7Schristosmy GNOME desktop, it is under Main Menu <TT>-></TT> Programming <TT>-></TT> 578*946379e7SchristosEmacs. If you are unfamiliar with Emacs, a tutorial can be started by typing 579*946379e7Schristos``C-h t'' in an Emacs window, or from the Help item in the menubar at the 580*946379e7Schristostop. Emacs makes extensive use of the Control (sometimes labelled as ``CTRL'' 581*946379e7Schristosor ``CTL'') and Meta (sometimes labelled as ``Edit'' or ``Alt'') keys. In 582*946379e7SchristosEmacs parlance, a hyphenated sequence, such as ``C-h'' means to press the 583*946379e7SchristosControl and `h' key simultaneously, while ``C-h t'' would mean to press the 584*946379e7SchristosControl and `h' key together, release them, and press the `t' key. Similarly, 585*946379e7Schristos``M-x'' is used to indicate that the Meta and `x' keys should be pressed at 586*946379e7Schristosthe same time. 587*946379e7Schristos 588*946379e7Schristos<P> 589*946379e7SchristosThe info browser can be started by typing ``C-h i'' in Emacs. The first time 590*946379e7Schristosyou do this, it will briefly list some commands available inside the info 591*946379e7Schristosbrowser, and present you with a menu of major topics. Each menu item, or 592*946379e7Schristoscross-reference is hyperlinked to the appropriate node, and you can visit that 593*946379e7Schristosnode either by moving the cursor to the item and pressing Enter, or by 594*946379e7Schristosclicking on it with the middle mouse button. To get to the <TT>gettext</TT> menu items, 595*946379e7Schristosyou can either scroll down to the line, 596*946379e7Schristos<PRE> 597*946379e7Schristos * gettext: (gettext). GNU gettext utilities. 598*946379e7Schristos</PRE> 599*946379e7Schristosand visit that node. Or, as it is several pages down, you can locate it using 600*946379e7Schristos``I-search.'' Type ``C-s'' to enter ``I-search'' which will then prompt you 601*946379e7Schristosfor a string in the mini-buffer at the bottom of the window. This is an 602*946379e7Schristosincremental search, so that Emacs will keep moving you forward through the 603*946379e7Schristosbuffer as you are entering your search string. If you have reached the last 604*946379e7Schristosoccurrence of the search string in the current buffer, you will get a message 605*946379e7Schristossaying ``Failing I-search: ...'' on pressing ``C-s.'' At that point, press 606*946379e7Schristos``C-s'' again to resume the search at the beginning of the buffer. Likewise, 607*946379e7Schristos``C-r'' incrementally searches backwards from the present location. 608*946379e7Schristos 609*946379e7Schristos<P> 610*946379e7SchristosInfo nodes are listed in this document with a ``::'' separator, so 611*946379e7Schristosthat one can go to the gettext::Creating::Header Entry:: by visiting the 612*946379e7Schristos``gettext'' node from the main info menu, navigating to the ``Creating'' 613*946379e7Schristosnode, and following that to the ``Header Entry'' node. 614*946379e7Schristos 615*946379e7Schristos<P> 616*946379e7SchristosA stand-alone info browser, independent of Emacs, is also available on many 617*946379e7Schristossystems. Thus, the <TT>gettext</TT> info page can also be accessed by typing 618*946379e7Schristos``info gettext'' in a terminal. <TT>xinfo</TT> is an X application serving as an 619*946379e7Schristosinfo browser, so that if it is installed, typing ``xinfo gettext'' from the 620*946379e7Schristoscommand line will open a new browser window with the <TT>gettext</TT> info page. 621*946379e7Schristos 622*946379e7Schristos<P> 623*946379e7Schristos 624*946379e7Schristos<H1><A NAME="SECTION00080000000000000000"> 625*946379e7SchristosPO file editors</A> 626*946379e7Schristos</H1> 627*946379e7Schristos<A NAME="sec:pofile-editors"></A>While the <TT>yudit</TT> editor is adequate for our present purposes, and we are 628*946379e7Schristosplanning on using that as it is platform-independent, and currently the best 629*946379e7Schristosat rendering Oriya. This section describes some features of some editors that 630*946379e7Schristosare specialized for editing PO files under Linux. This is still work in 631*946379e7Schristosprogress, as I am in the process of trying out different editors before 632*946379e7Schristossettling on one. The ones considered here are: Emacs in po-mode, <TT>poedit</TT>, 633*946379e7Schristos<TT>kbabel</TT>, and <TT>gtranslator</TT>. 634*946379e7Schristos 635*946379e7Schristos<H2><A NAME="SECTION00081000000000000000"> 636*946379e7SchristosEmacs PO mode</A> 637*946379e7Schristos</H2> 638*946379e7Schristos Emacs should automatically enter po-mode when you load a .po file, as 639*946379e7Schristosindicated by ``PO'' in the modeline at the bottom. The window is made 640*946379e7Schristosread-only, so that you can edit the .po file only through special commands. A 641*946379e7Schristosdescription of Emacs po-mode can be found under the gettext::Basics info node, 642*946379e7Schristosor type `h' or `?' in a po-mode window for a list of available commands. While 643*946379e7SchristosI find Emacs po-mode quite restrictive, this is probably due to unfamiliarity 644*946379e7Schristoswith it. Its main advantage is that it imposes rigid conformance to the PO 645*946379e7Schristosfile format, and checks the file format when closing the .po file 646*946379e7Schristosbuffer. Emacs po-mode is not useful for Oriya translation, as I know of no way 647*946379e7Schristosto directly enter Oriya text under Emacs. 648*946379e7Schristos 649*946379e7Schristos<H2><A NAME="SECTION00082000000000000000"> 650*946379e7Schristospoedit</A> 651*946379e7Schristos</H2> 652*946379e7Schristos XXX: in preparation. 653*946379e7Schristos 654*946379e7Schristos<H2><A NAME="SECTION00083000000000000000"> 655*946379e7SchristosKDE: the kbabel editor</A> 656*946379e7Schristos</H2> 657*946379e7Schristos <TT>kbabel</TT> [<A 658*946379e7Schristos HREF="memo.html#url:kbabel">4</A>] is a more user-friendly and configurable editor than 659*946379e7Schristoseither of Emacs po-mode or <TT>poedit</TT>. It is integrated into KDE, and offers 660*946379e7Schristosextensive contextual help. Besides support for various PO file features, it 661*946379e7Schristoshas a plugin framework for dictionaries, that allows consistency checks and 662*946379e7Schristostranslation suggestions. 663*946379e7Schristos 664*946379e7Schristos<H2><A NAME="SECTION00084000000000000000"> 665*946379e7SchristosGNOME: the gtranslator editor</A> 666*946379e7Schristos</H2> 667*946379e7Schristos XXX: in preparation. 668*946379e7Schristos 669*946379e7Schristos<H2><A NAME="SECTION00090000000000000000"> 670*946379e7SchristosBibliography</A> 671*946379e7Schristos</H2><DL COMPACT><DD><P></P><DT><A NAME="xkb-oriya-layout">1</A> 672*946379e7Schristos<DD> 673*946379e7SchristosG. Mohanty, 674*946379e7Schristos<BR>A practical primer for using Oriya under Linux, v0.3, 675*946379e7Schristos<BR><TT><A NAME="tex2html1" 676*946379e7Schristos HREF="http://oriya.sarovar.org/docs/getting_started/index.html">http://oriya.sarovar.org/docs/getting_started/index.html</A></TT>, 2004, 677*946379e7Schristos<BR>Sec. 6.2 describes the xkb layouts for Oriya. 678*946379e7Schristos 679*946379e7Schristos<P></P><DT><A NAME="url:oriya-trans-plan">2</A> 680*946379e7Schristos<DD> 681*946379e7SchristosG. Mohanty, 682*946379e7Schristos<BR>A plan for Oriya localization, v0.1, 683*946379e7Schristos<BR><TT><A NAME="tex2html2" 684*946379e7Schristos HREF="http://oriya.sarovar.org/docs/translation_plan/index.html">http://oriya.sarovar.org/docs/translation_plan/index.html</A></TT>, 685*946379e7Schristos 2004. 686*946379e7Schristos 687*946379e7Schristos<P></P><DT><A NAME="url:lj-translation">3</A> 688*946379e7Schristos<DD> 689*946379e7SchristosLinux Journal article on internationalization, 690*946379e7Schristos<BR><TT><A NAME="tex2html3" 691*946379e7Schristos HREF="http://www.linuxjournal.com/article.php?sid=3023">http://www.linuxjournal.com/article.php?sid=3023</A></TT>. 692*946379e7Schristos 693*946379e7Schristos<P></P><DT><A NAME="url:kbabel">4</A> 694*946379e7Schristos<DD> 695*946379e7SchristosFeatures of the kbabel editor, 696*946379e7Schristos<BR><TT><A NAME="tex2html4" 697*946379e7Schristos HREF="http://i18n.kde.org/tools/kbabel/features.html">http://i18n.kde.org/tools/kbabel/features.html</A></TT>. 698*946379e7Schristos</DL> 699*946379e7Schristos 700*946379e7Schristos<H1><A NAME="SECTION000100000000000000000"> 701*946379e7SchristosAbout this document ...</A> 702*946379e7Schristos</H1> 703*946379e7Schristos <STRONG>A tutorial on Native Language Support using GNU gettext</STRONG><P> 704*946379e7SchristosThis document was generated using the 705*946379e7Schristos<A HREF="http://www.latex2html.org/"><STRONG>LaTeX</STRONG>2<tt>HTML</tt></A> translator Version 2002-2-1 (1.70) 706*946379e7Schristos<P> 707*946379e7SchristosCopyright © 1993, 1994, 1995, 1996, 708*946379e7Schristos<A HREF="http://cbl.leeds.ac.uk/nikos/personal.html">Nikos Drakos</A>, 709*946379e7SchristosComputer Based Learning Unit, University of Leeds. 710*946379e7Schristos<BR>Copyright © 1997, 1998, 1999, 711*946379e7Schristos<A HREF="http://www.maths.mq.edu.au/~ross/">Ross Moore</A>, 712*946379e7SchristosMathematics Department, Macquarie University, Sydney. 713*946379e7Schristos<P> 714*946379e7SchristosThe command line arguments were: <BR> 715*946379e7Schristos <STRONG>latex2html</STRONG> <TT>-no_math -html_version 4.0,math,unicode,i18n,tables -split 0 memo</TT> 716*946379e7Schristos<P> 717*946379e7SchristosThe translation was initiated by Gora Mohanty on 2004-07-24 718*946379e7Schristos<DIV CLASS="navigation"><HR> 719*946379e7Schristos 720*946379e7Schristos<!--Navigation Panel 721*946379e7Schristos<IMG WIDTH="81" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next_inactive" 722*946379e7Schristos SRC="file:/usr/share/latex2html/icons/nx_grp_g.png"> 723*946379e7Schristos<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up" 724*946379e7Schristos SRC="file:/usr/share/latex2html/icons/up_g.png"> 725*946379e7Schristos<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous" 726*946379e7Schristos SRC="file:/usr/share/latex2html/icons/prev_g.png"> 727*946379e7Schristos<BR></DIV> 728*946379e7SchristosEnd of Navigation Panel--> 729*946379e7Schristos 730*946379e7Schristos<ADDRESS> 731*946379e7SchristosGora Mohanty 732*946379e7Schristos2004-07-24 733*946379e7Schristos</ADDRESS> 734*946379e7Schristos</BODY> 735*946379e7Schristos</HTML> 736