1*946379e7Schristos<HTML> 2*946379e7Schristos<HEAD> 3*946379e7Schristos<!-- This HTML file has been created by texi2html 1.52b 4*946379e7Schristos from gettext.texi on 27 November 2006 --> 5*946379e7Schristos 6*946379e7Schristos<META HTTP-EQUIV="content-type" CONTENT="text/html; charset=UTF-8"> 7*946379e7Schristos<TITLE>GNU gettext utilities - 15 Other Programming Languages</TITLE> 8*946379e7Schristos</HEAD> 9*946379e7Schristos<BODY> 10*946379e7SchristosGo to the <A HREF="gettext_1.html">first</A>, <A HREF="gettext_14.html">previous</A>, <A HREF="gettext_16.html">next</A>, <A HREF="gettext_25.html">last</A> section, <A HREF="gettext_toc.html">table of contents</A>. 11*946379e7Schristos<P><HR><P> 12*946379e7Schristos 13*946379e7Schristos 14*946379e7Schristos<H1><A NAME="SEC229" HREF="gettext_toc.html#TOC229">15 Other Programming Languages</A></H1> 15*946379e7Schristos 16*946379e7Schristos<P> 17*946379e7SchristosWhile the presentation of <CODE>gettext</CODE> focuses mostly on C and 18*946379e7Schristosimplicitly applies to C++ as well, its scope is far broader than that: 19*946379e7SchristosMany programming languages, scripting languages and other textual data 20*946379e7Schristoslike GUI resources or package descriptions can make use of the gettext 21*946379e7Schristosapproach. 22*946379e7Schristos 23*946379e7Schristos</P> 24*946379e7Schristos 25*946379e7Schristos 26*946379e7Schristos 27*946379e7Schristos<H2><A NAME="SEC230" HREF="gettext_toc.html#TOC230">15.1 The Language Implementor's View</A></H2> 28*946379e7Schristos<P> 29*946379e7Schristos<A NAME="IDX1111"></A> 30*946379e7Schristos<A NAME="IDX1112"></A> 31*946379e7Schristos 32*946379e7Schristos</P> 33*946379e7Schristos<P> 34*946379e7SchristosAll programming and scripting languages that have the notion of strings 35*946379e7Schristosare eligible to supporting <CODE>gettext</CODE>. Supporting <CODE>gettext</CODE> 36*946379e7Schristosmeans the following: 37*946379e7Schristos 38*946379e7Schristos</P> 39*946379e7Schristos 40*946379e7Schristos<OL> 41*946379e7Schristos<LI> 42*946379e7Schristos 43*946379e7SchristosYou should add to the language a syntax for translatable strings. In 44*946379e7Schristosprinciple, a function call of <CODE>gettext</CODE> would do, but a shorthand 45*946379e7Schristossyntax helps keeping the legibility of internationalized programs. For 46*946379e7Schristosexample, in C we use the syntax <CODE>_("string")</CODE>, and in GNU awk we use 47*946379e7Schristosthe shorthand <CODE>_"string"</CODE>. 48*946379e7Schristos 49*946379e7Schristos<LI> 50*946379e7Schristos 51*946379e7SchristosYou should arrange that evaluation of such a translatable string at 52*946379e7Schristosruntime calls the <CODE>gettext</CODE> function, or performs equivalent 53*946379e7Schristosprocessing. 54*946379e7Schristos 55*946379e7Schristos<LI> 56*946379e7Schristos 57*946379e7SchristosSimilarly, you should make the functions <CODE>ngettext</CODE>, 58*946379e7Schristos<CODE>dcgettext</CODE>, <CODE>dcngettext</CODE> available from within the language. 59*946379e7SchristosThese functions are less often used, but are nevertheless necessary for 60*946379e7Schristosparticular purposes: <CODE>ngettext</CODE> for correct plural handling, and 61*946379e7Schristos<CODE>dcgettext</CODE> and <CODE>dcngettext</CODE> for obeying other locale 62*946379e7Schristosenvironment variables than <CODE>LC_MESSAGES</CODE>, such as <CODE>LC_TIME</CODE> or 63*946379e7Schristos<CODE>LC_MONETARY</CODE>. For these latter functions, you need to make the 64*946379e7Schristos<CODE>LC_*</CODE> constants, available in the C header <CODE><locale.h></CODE>, 65*946379e7Schristosreferenceable from within the language, usually either as enumeration 66*946379e7Schristosvalues or as strings. 67*946379e7Schristos 68*946379e7Schristos<LI> 69*946379e7Schristos 70*946379e7SchristosYou should allow the programmer to designate a message domain, either by 71*946379e7Schristosmaking the <CODE>textdomain</CODE> function available from within the 72*946379e7Schristoslanguage, or by introducing a magic variable called <CODE>TEXTDOMAIN</CODE>. 73*946379e7SchristosSimilarly, you should allow the programmer to designate where to search 74*946379e7Schristosfor message catalogs, by providing access to the <CODE>bindtextdomain</CODE> 75*946379e7Schristosfunction. 76*946379e7Schristos 77*946379e7Schristos<LI> 78*946379e7Schristos 79*946379e7SchristosYou should either perform a <CODE>setlocale (LC_ALL, "")</CODE> call during 80*946379e7Schristosthe startup of your language runtime, or allow the programmer to do so. 81*946379e7SchristosRemember that gettext will act as a no-op if the <CODE>LC_MESSAGES</CODE> and 82*946379e7Schristos<CODE>LC_CTYPE</CODE> locale facets are not both set. 83*946379e7Schristos 84*946379e7Schristos<LI> 85*946379e7Schristos 86*946379e7SchristosA programmer should have a way to extract translatable strings from a 87*946379e7Schristosprogram into a PO file. The GNU <CODE>xgettext</CODE> program is being 88*946379e7Schristosextended to support very different programming languages. Please 89*946379e7Schristoscontact the GNU <CODE>gettext</CODE> maintainers to help them doing this. If 90*946379e7Schristosthe string extractor is best integrated into your language's parser, GNU 91*946379e7Schristos<CODE>xgettext</CODE> can function as a front end to your string extractor. 92*946379e7Schristos 93*946379e7Schristos<LI> 94*946379e7Schristos 95*946379e7SchristosThe language's library should have a string formatting facility where 96*946379e7Schristosthe arguments of a format string are denoted by a positional number or a 97*946379e7Schristosname. This is needed because for some languages and some messages with 98*946379e7Schristosmore than one substitutable argument, the translation will need to 99*946379e7Schristosoutput the substituted arguments in different order. See section <A HREF="gettext_4.html#SEC17">4.6 Special Comments preceding Keywords</A>. 100*946379e7Schristos 101*946379e7Schristos<LI> 102*946379e7Schristos 103*946379e7SchristosIf the language has more than one implementation, and not all of the 104*946379e7Schristosimplementations use <CODE>gettext</CODE>, but the programs should be portable 105*946379e7Schristosacross implementations, you should provide a no-i18n emulation, that 106*946379e7Schristosmakes the other implementations accept programs written for yours, 107*946379e7Schristoswithout actually translating the strings. 108*946379e7Schristos 109*946379e7Schristos<LI> 110*946379e7Schristos 111*946379e7SchristosTo help the programmer in the task of marking translatable strings, 112*946379e7Schristoswhich is sometimes performed using the Emacs PO mode (see section <A HREF="gettext_4.html#SEC16">4.5 Marking Translatable Strings</A>), 113*946379e7Schristosyou are welcome to 114*946379e7Schristoscontact the GNU <CODE>gettext</CODE> maintainers, so they can add support for 115*946379e7Schristosyour language to <TT>‘po-mode.el’</TT>. 116*946379e7Schristos</OL> 117*946379e7Schristos 118*946379e7Schristos<P> 119*946379e7SchristosOn the implementation side, three approaches are possible, with 120*946379e7Schristosdifferent effects on portability and copyright: 121*946379e7Schristos 122*946379e7Schristos</P> 123*946379e7Schristos 124*946379e7Schristos<UL> 125*946379e7Schristos<LI> 126*946379e7Schristos 127*946379e7SchristosYou may integrate the GNU <CODE>gettext</CODE>'s <TT>‘intl/’</TT> directory in 128*946379e7Schristosyour package, as described in section <A HREF="gettext_13.html#SEC196">13 The Maintainer's View</A>. This allows you to 129*946379e7Schristoshave internationalization on all kinds of platforms. Note that when you 130*946379e7Schristosthen distribute your package, it legally falls under the GNU General 131*946379e7SchristosPublic License, and the GNU project will be glad about your contribution 132*946379e7Schristosto the Free Software pool. 133*946379e7Schristos 134*946379e7Schristos<LI> 135*946379e7Schristos 136*946379e7SchristosYou may link against GNU <CODE>gettext</CODE> functions if they are found in 137*946379e7Schristosthe C library. For example, an autoconf test for <CODE>gettext()</CODE> and 138*946379e7Schristos<CODE>ngettext()</CODE> will detect this situation. For the moment, this test 139*946379e7Schristoswill succeed on GNU systems and not on other platforms. No severe 140*946379e7Schristoscopyright restrictions apply. 141*946379e7Schristos 142*946379e7Schristos<LI> 143*946379e7Schristos 144*946379e7SchristosYou may emulate or reimplement the GNU <CODE>gettext</CODE> functionality. 145*946379e7SchristosThis has the advantage of full portability and no copyright 146*946379e7Schristosrestrictions, but also the drawback that you have to reimplement the GNU 147*946379e7Schristos<CODE>gettext</CODE> features (such as the <CODE>LANGUAGE</CODE> environment 148*946379e7Schristosvariable, the locale aliases database, the automatic charset conversion, 149*946379e7Schristosand plural handling). 150*946379e7Schristos</UL> 151*946379e7Schristos 152*946379e7Schristos 153*946379e7Schristos 154*946379e7Schristos<H2><A NAME="SEC231" HREF="gettext_toc.html#TOC231">15.2 The Programmer's View</A></H2> 155*946379e7Schristos 156*946379e7Schristos<P> 157*946379e7SchristosFor the programmer, the general procedure is the same as for the C 158*946379e7Schristoslanguage. The Emacs PO mode marking supports other languages, and the GNU 159*946379e7Schristos<CODE>xgettext</CODE> string extractor recognizes other languages based on the 160*946379e7Schristosfile extension or a command-line option. In some languages, 161*946379e7Schristos<CODE>setlocale</CODE> is not needed because it is already performed by the 162*946379e7Schristosunderlying language runtime. 163*946379e7Schristos 164*946379e7Schristos</P> 165*946379e7Schristos 166*946379e7Schristos 167*946379e7Schristos<H2><A NAME="SEC232" HREF="gettext_toc.html#TOC232">15.3 The Translator's View</A></H2> 168*946379e7Schristos 169*946379e7Schristos<P> 170*946379e7SchristosThe translator works exactly as in the C language case. The only 171*946379e7Schristosdifference is that when translating format strings, she has to be aware 172*946379e7Schristosof the language's particular syntax for positional arguments in format 173*946379e7Schristosstrings. 174*946379e7Schristos 175*946379e7Schristos</P> 176*946379e7Schristos 177*946379e7Schristos 178*946379e7Schristos 179*946379e7Schristos<H3><A NAME="SEC233" HREF="gettext_toc.html#TOC233">15.3.1 C Format Strings</A></H3> 180*946379e7Schristos 181*946379e7Schristos<P> 182*946379e7SchristosC format strings are described in POSIX (IEEE P1003.1 2001), section 183*946379e7SchristosXSH 3 fprintf(), 184*946379e7Schristos<A HREF="http://www.opengroup.org/onlinepubs/007904975/functions/fprintf.html">http://www.opengroup.org/onlinepubs/007904975/functions/fprintf.html</A>. 185*946379e7SchristosSee also the fprintf() manual page, 186*946379e7Schristos<A HREF="http://www.linuxvalley.it/encyclopedia/ldp/manpage/man3/printf.3.php">http://www.linuxvalley.it/encyclopedia/ldp/manpage/man3/printf.3.php</A>, 187*946379e7Schristos<A HREF="http://informatik.fh-wuerzburg.de/student/i510/man/printf.html">http://informatik.fh-wuerzburg.de/student/i510/man/printf.html</A>. 188*946379e7Schristos 189*946379e7Schristos</P> 190*946379e7Schristos<P> 191*946379e7SchristosAlthough format strings with positions that reorder arguments, such as 192*946379e7Schristos 193*946379e7Schristos</P> 194*946379e7Schristos 195*946379e7Schristos<PRE> 196*946379e7Schristos"Only %2$d bytes free on '%1$s'." 197*946379e7Schristos</PRE> 198*946379e7Schristos 199*946379e7Schristos<P> 200*946379e7Schristoswhich is semantically equivalent to 201*946379e7Schristos 202*946379e7Schristos</P> 203*946379e7Schristos 204*946379e7Schristos<PRE> 205*946379e7Schristos"'%s' has only %d bytes free." 206*946379e7Schristos</PRE> 207*946379e7Schristos 208*946379e7Schristos<P> 209*946379e7Schristosare a POSIX/XSI feature and not specified by ISO C 99, translators can rely 210*946379e7Schristoson this reordering ability: On the few platforms where <CODE>printf()</CODE>, 211*946379e7Schristos<CODE>fprintf()</CODE> etc. don't support this feature natively, <TT>‘libintl.a’</TT> 212*946379e7Schristosor <TT>‘libintl.so’</TT> provides replacement functions, and GNU <CODE><libintl.h></CODE> 213*946379e7Schristosactivates these replacement functions automatically. 214*946379e7Schristos 215*946379e7Schristos</P> 216*946379e7Schristos<P> 217*946379e7Schristos<A NAME="IDX1113"></A> 218*946379e7Schristos<A NAME="IDX1114"></A> 219*946379e7SchristosAs a special feature for Farsi (Persian) and maybe Arabic, translators can 220*946379e7Schristosinsert an <SAMP>‘I’</SAMP> flag into numeric format directives. For example, the 221*946379e7Schristostranslation of <CODE>"%d"</CODE> can be <CODE>"%Id"</CODE>. The effect of this flag, 222*946379e7Schristoson systems with GNU <CODE>libc</CODE>, is that in the output, the ASCII digits are 223*946379e7Schristosreplaced with the <SAMP>‘outdigits’</SAMP> defined in the <CODE>LC_CTYPE</CODE> locale 224*946379e7Schristosfacet. On other systems, the <CODE>gettext</CODE> function removes this flag, 225*946379e7Schristosso that it has no effect. 226*946379e7Schristos 227*946379e7Schristos</P> 228*946379e7Schristos<P> 229*946379e7SchristosNote that the programmer should <EM>not</EM> put this flag into the 230*946379e7Schristosuntranslated string. (Putting the <SAMP>‘I’</SAMP> format directive flag into an 231*946379e7Schristos<VAR>msgid</VAR> string would lead to undefined behaviour on platforms without 232*946379e7Schristosglibc when NLS is disabled.) 233*946379e7Schristos 234*946379e7Schristos</P> 235*946379e7Schristos 236*946379e7Schristos 237*946379e7Schristos<H3><A NAME="SEC234" HREF="gettext_toc.html#TOC234">15.3.2 Objective C Format Strings</A></H3> 238*946379e7Schristos 239*946379e7Schristos<P> 240*946379e7SchristosObjective C format strings are like C format strings. They support an 241*946379e7Schristosadditional format directive: "$@", which when executed consumes an argument 242*946379e7Schristosof type <CODE>Object *</CODE>. 243*946379e7Schristos 244*946379e7Schristos</P> 245*946379e7Schristos 246*946379e7Schristos 247*946379e7Schristos<H3><A NAME="SEC235" HREF="gettext_toc.html#TOC235">15.3.3 Shell Format Strings</A></H3> 248*946379e7Schristos 249*946379e7Schristos<P> 250*946379e7SchristosShell format strings, as supported by GNU gettext and the <SAMP>‘envsubst’</SAMP> 251*946379e7Schristosprogram, are strings with references to shell variables in the form 252*946379e7Schristos<CODE>$<VAR>variable</VAR></CODE> or <CODE>${<VAR>variable</VAR>}</CODE>. References of the form 253*946379e7Schristos<CODE>${<VAR>variable</VAR>-<VAR>default</VAR>}</CODE>, 254*946379e7Schristos<CODE>${<VAR>variable</VAR>:-<VAR>default</VAR>}</CODE>, 255*946379e7Schristos<CODE>${<VAR>variable</VAR>=<VAR>default</VAR>}</CODE>, 256*946379e7Schristos<CODE>${<VAR>variable</VAR>:=<VAR>default</VAR>}</CODE>, 257*946379e7Schristos<CODE>${<VAR>variable</VAR>+<VAR>replacement</VAR>}</CODE>, 258*946379e7Schristos<CODE>${<VAR>variable</VAR>:+<VAR>replacement</VAR>}</CODE>, 259*946379e7Schristos<CODE>${<VAR>variable</VAR>?<VAR>ignored</VAR>}</CODE>, 260*946379e7Schristos<CODE>${<VAR>variable</VAR>:?<VAR>ignored</VAR>}</CODE>, 261*946379e7Schristosthat would be valid inside shell scripts, are not supported. The 262*946379e7Schristos<VAR>variable</VAR> names must consist solely of alphanumeric or underscore 263*946379e7SchristosASCII characters, not start with a digit and be nonempty; otherwise such 264*946379e7Schristosa variable reference is ignored. 265*946379e7Schristos 266*946379e7Schristos</P> 267*946379e7Schristos 268*946379e7Schristos 269*946379e7Schristos<H3><A NAME="SEC236" HREF="gettext_toc.html#TOC236">15.3.4 Python Format Strings</A></H3> 270*946379e7Schristos 271*946379e7Schristos<P> 272*946379e7SchristosPython format strings are described in 273*946379e7SchristosPython Library reference / 274*946379e7Schristos2. Built-in Types, Exceptions and Functions / 275*946379e7Schristos2.2. Built-in Types / 276*946379e7Schristos2.2.6. Sequence Types / 277*946379e7Schristos2.2.6.2. String Formatting Operations. 278*946379e7Schristos<A HREF="http://www.python.org/doc/2.2.1/lib/typesseq-strings.html">http://www.python.org/doc/2.2.1/lib/typesseq-strings.html</A>. 279*946379e7Schristos 280*946379e7Schristos</P> 281*946379e7Schristos 282*946379e7Schristos 283*946379e7Schristos<H3><A NAME="SEC237" HREF="gettext_toc.html#TOC237">15.3.5 Lisp Format Strings</A></H3> 284*946379e7Schristos 285*946379e7Schristos<P> 286*946379e7SchristosLisp format strings are described in the Common Lisp HyperSpec, 287*946379e7Schristoschapter 22.3 Formatted Output, 288*946379e7Schristos<A HREF="http://www.lisp.org/HyperSpec/Body/sec_22-3.html">http://www.lisp.org/HyperSpec/Body/sec_22-3.html</A>. 289*946379e7Schristos 290*946379e7Schristos</P> 291*946379e7Schristos 292*946379e7Schristos 293*946379e7Schristos<H3><A NAME="SEC238" HREF="gettext_toc.html#TOC238">15.3.6 Emacs Lisp Format Strings</A></H3> 294*946379e7Schristos 295*946379e7Schristos<P> 296*946379e7SchristosEmacs Lisp format strings are documented in the Emacs Lisp reference, 297*946379e7Schristossection Formatting Strings, 298*946379e7Schristos<A HREF="http://www.gnu.org/manual/elisp-manual-21-2.8/html_chapter/elisp_4.html#SEC75">http://www.gnu.org/manual/elisp-manual-21-2.8/html_chapter/elisp_4.html#SEC75</A>. 299*946379e7SchristosNote that as of version 21, XEmacs supports numbered argument specifications 300*946379e7Schristosin format strings while FSF Emacs doesn't. 301*946379e7Schristos 302*946379e7Schristos</P> 303*946379e7Schristos 304*946379e7Schristos 305*946379e7Schristos<H3><A NAME="SEC239" HREF="gettext_toc.html#TOC239">15.3.7 librep Format Strings</A></H3> 306*946379e7Schristos 307*946379e7Schristos<P> 308*946379e7Schristoslibrep format strings are documented in the librep manual, section 309*946379e7SchristosFormatted Output, 310*946379e7Schristos<A HREF="http://librep.sourceforge.net/librep-manual.html#Formatted%20Output">http://librep.sourceforge.net/librep-manual.html#Formatted%20Output</A>, 311*946379e7Schristos<A HREF="http://www.gwinnup.org/research/docs/librep.html#SEC122">http://www.gwinnup.org/research/docs/librep.html#SEC122</A>. 312*946379e7Schristos 313*946379e7Schristos</P> 314*946379e7Schristos 315*946379e7Schristos 316*946379e7Schristos<H3><A NAME="SEC240" HREF="gettext_toc.html#TOC240">15.3.8 Scheme Format Strings</A></H3> 317*946379e7Schristos 318*946379e7Schristos<P> 319*946379e7SchristosScheme format strings are documented in the SLIB manual, section 320*946379e7SchristosFormat Specification. 321*946379e7Schristos 322*946379e7Schristos</P> 323*946379e7Schristos 324*946379e7Schristos 325*946379e7Schristos<H3><A NAME="SEC241" HREF="gettext_toc.html#TOC241">15.3.9 Smalltalk Format Strings</A></H3> 326*946379e7Schristos 327*946379e7Schristos<P> 328*946379e7SchristosSmalltalk format strings are described in the GNU Smalltalk documentation, 329*946379e7Schristosclass <CODE>CharArray</CODE>, methods <SAMP>‘bindWith:’</SAMP> and 330*946379e7Schristos<SAMP>‘bindWithArguments:’</SAMP>. 331*946379e7Schristos<A HREF="http://www.gnu.org/software/smalltalk/gst-manual/gst_68.html#SEC238">http://www.gnu.org/software/smalltalk/gst-manual/gst_68.html#SEC238</A>. 332*946379e7SchristosIn summary, a directive starts with <SAMP>‘%’</SAMP> and is followed by <SAMP>‘%’</SAMP> 333*946379e7Schristosor a nonzero digit (<SAMP>‘1’</SAMP> to <SAMP>‘9’</SAMP>). 334*946379e7Schristos 335*946379e7Schristos</P> 336*946379e7Schristos 337*946379e7Schristos 338*946379e7Schristos<H3><A NAME="SEC242" HREF="gettext_toc.html#TOC242">15.3.10 Java Format Strings</A></H3> 339*946379e7Schristos 340*946379e7Schristos<P> 341*946379e7SchristosJava format strings are described in the JDK documentation for class 342*946379e7Schristos<CODE>java.text.MessageFormat</CODE>, 343*946379e7Schristos<A HREF="http://java.sun.com/j2se/1.4/docs/api/java/text/MessageFormat.html">http://java.sun.com/j2se/1.4/docs/api/java/text/MessageFormat.html</A>. 344*946379e7SchristosSee also the ICU documentation 345*946379e7Schristos<A HREF="http://oss.software.ibm.com/icu/apiref/classMessageFormat.html">http://oss.software.ibm.com/icu/apiref/classMessageFormat.html</A>. 346*946379e7Schristos 347*946379e7Schristos</P> 348*946379e7Schristos 349*946379e7Schristos 350*946379e7Schristos<H3><A NAME="SEC243" HREF="gettext_toc.html#TOC243">15.3.11 C# Format Strings</A></H3> 351*946379e7Schristos 352*946379e7Schristos<P> 353*946379e7SchristosC# format strings are described in the .NET documentation for class 354*946379e7Schristos<CODE>System.String</CODE> and in 355*946379e7Schristos<A HREF="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpConFormattingOverview.asp">http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpConFormattingOverview.asp</A>. 356*946379e7Schristos 357*946379e7Schristos</P> 358*946379e7Schristos 359*946379e7Schristos 360*946379e7Schristos<H3><A NAME="SEC244" HREF="gettext_toc.html#TOC244">15.3.12 awk Format Strings</A></H3> 361*946379e7Schristos 362*946379e7Schristos<P> 363*946379e7Schristosawk format strings are described in the gawk documentation, section 364*946379e7SchristosPrintf, 365*946379e7Schristos<A HREF="http://www.gnu.org/manual/gawk/html_node/Printf.html#Printf">http://www.gnu.org/manual/gawk/html_node/Printf.html#Printf</A>. 366*946379e7Schristos 367*946379e7Schristos</P> 368*946379e7Schristos 369*946379e7Schristos 370*946379e7Schristos<H3><A NAME="SEC245" HREF="gettext_toc.html#TOC245">15.3.13 Object Pascal Format Strings</A></H3> 371*946379e7Schristos 372*946379e7Schristos<P> 373*946379e7SchristosWhere is this documented? 374*946379e7Schristos 375*946379e7Schristos</P> 376*946379e7Schristos 377*946379e7Schristos 378*946379e7Schristos<H3><A NAME="SEC246" HREF="gettext_toc.html#TOC246">15.3.14 YCP Format Strings</A></H3> 379*946379e7Schristos 380*946379e7Schristos<P> 381*946379e7SchristosYCP sformat strings are described in the libycp documentation 382*946379e7Schristos<A HREF="file:/usr/share/doc/packages/libycp/YCP-builtins.html">file:/usr/share/doc/packages/libycp/YCP-builtins.html</A>. 383*946379e7SchristosIn summary, a directive starts with <SAMP>‘%’</SAMP> and is followed by <SAMP>‘%’</SAMP> 384*946379e7Schristosor a nonzero digit (<SAMP>‘1’</SAMP> to <SAMP>‘9’</SAMP>). 385*946379e7Schristos 386*946379e7Schristos</P> 387*946379e7Schristos 388*946379e7Schristos 389*946379e7Schristos<H3><A NAME="SEC247" HREF="gettext_toc.html#TOC247">15.3.15 Tcl Format Strings</A></H3> 390*946379e7Schristos 391*946379e7Schristos<P> 392*946379e7SchristosTcl format strings are described in the <TT>‘format.n’</TT> manual page, 393*946379e7Schristos<A HREF="http://www.scriptics.com/man/tcl8.3/TclCmd/format.htm">http://www.scriptics.com/man/tcl8.3/TclCmd/format.htm</A>. 394*946379e7Schristos 395*946379e7Schristos</P> 396*946379e7Schristos 397*946379e7Schristos 398*946379e7Schristos<H3><A NAME="SEC248" HREF="gettext_toc.html#TOC248">15.3.16 Perl Format Strings</A></H3> 399*946379e7Schristos 400*946379e7Schristos<P> 401*946379e7SchristosThere are two kinds format strings in Perl: those acceptable to the 402*946379e7SchristosPerl built-in function <CODE>printf</CODE>, labelled as <SAMP>‘perl-format’</SAMP>, 403*946379e7Schristosand those acceptable to the <CODE>libintl-perl</CODE> function <CODE>__x</CODE>, 404*946379e7Schristoslabelled as <SAMP>‘perl-brace-format’</SAMP>. 405*946379e7Schristos 406*946379e7Schristos</P> 407*946379e7Schristos<P> 408*946379e7SchristosPerl <CODE>printf</CODE> format strings are described in the <CODE>sprintf</CODE> 409*946379e7Schristossection of <SAMP>‘man perlfunc’</SAMP>. 410*946379e7Schristos 411*946379e7Schristos</P> 412*946379e7Schristos<P> 413*946379e7SchristosPerl brace format strings are described in the 414*946379e7Schristos<TT>‘Locale::TextDomain(3pm)’</TT> manual page of the CPAN package 415*946379e7Schristoslibintl-perl. In brief, Perl format uses placeholders put between 416*946379e7Schristosbraces (<SAMP>‘{’</SAMP> and <SAMP>‘}’</SAMP>). The placeholder must have the syntax 417*946379e7Schristosof simple identifiers. 418*946379e7Schristos 419*946379e7Schristos</P> 420*946379e7Schristos 421*946379e7Schristos 422*946379e7Schristos<H3><A NAME="SEC249" HREF="gettext_toc.html#TOC249">15.3.17 PHP Format Strings</A></H3> 423*946379e7Schristos 424*946379e7Schristos<P> 425*946379e7SchristosPHP format strings are described in the documentation of the PHP function 426*946379e7Schristos<CODE>sprintf</CODE>, in <TT>‘phpdoc/manual/function.sprintf.html’</TT> or 427*946379e7Schristos<A HREF="http://www.php.net/manual/en/function.sprintf.php">http://www.php.net/manual/en/function.sprintf.php</A>. 428*946379e7Schristos 429*946379e7Schristos</P> 430*946379e7Schristos 431*946379e7Schristos 432*946379e7Schristos<H3><A NAME="SEC250" HREF="gettext_toc.html#TOC250">15.3.18 GCC internal Format Strings</A></H3> 433*946379e7Schristos 434*946379e7Schristos<P> 435*946379e7SchristosThese format strings are used inside the GCC sources. In such a format 436*946379e7Schristosstring, a directive starts with <SAMP>‘%’</SAMP>, is optionally followed by a 437*946379e7Schristossize specifier <SAMP>‘l’</SAMP>, an optional flag <SAMP>‘+’</SAMP>, another optional flag 438*946379e7Schristos<SAMP>‘#’</SAMP>, and is finished by a specifier: <SAMP>‘%’</SAMP> denotes a literal 439*946379e7Schristospercent sign, <SAMP>‘c’</SAMP> denotes a character, <SAMP>‘s’</SAMP> denotes a string, 440*946379e7Schristos<SAMP>‘i’</SAMP> and <SAMP>‘d’</SAMP> denote an integer, <SAMP>‘o’</SAMP>, <SAMP>‘u’</SAMP>, <SAMP>‘x’</SAMP> 441*946379e7Schristosdenote an unsigned integer, <SAMP>‘.*s’</SAMP> denotes a string preceded by a 442*946379e7Schristoswidth specification, <SAMP>‘H’</SAMP> denotes a <SAMP>‘location_t *’</SAMP> pointer, 443*946379e7Schristos<SAMP>‘D’</SAMP> denotes a general declaration, <SAMP>‘F’</SAMP> denotes a function 444*946379e7Schristosdeclaration, <SAMP>‘T’</SAMP> denotes a type, <SAMP>‘A’</SAMP> denotes a function argument, 445*946379e7Schristos<SAMP>‘C’</SAMP> denotes a tree code, <SAMP>‘E’</SAMP> denotes an expression, <SAMP>‘L’</SAMP> 446*946379e7Schristosdenotes a programming language, <SAMP>‘O’</SAMP> denotes a binary operator, 447*946379e7Schristos<SAMP>‘P’</SAMP> denotes a function parameter, <SAMP>‘Q’</SAMP> denotes an assignment 448*946379e7Schristosoperator, <SAMP>‘V’</SAMP> denotes a const/volatile qualifier. 449*946379e7Schristos 450*946379e7Schristos</P> 451*946379e7Schristos 452*946379e7Schristos 453*946379e7Schristos<H3><A NAME="SEC251" HREF="gettext_toc.html#TOC251">15.3.19 Qt Format Strings</A></H3> 454*946379e7Schristos 455*946379e7Schristos<P> 456*946379e7SchristosQt format strings are described in the documentation of the QString class 457*946379e7Schristos<A HREF="file:/usr/lib/qt-3.0.5/doc/html/qstring.html">file:/usr/lib/qt-3.0.5/doc/html/qstring.html</A>. 458*946379e7SchristosIn summary, a directive consists of a <SAMP>‘%’</SAMP> followed by a digit. The same 459*946379e7Schristosdirective cannot occur more than once in a format string. 460*946379e7Schristos 461*946379e7Schristos</P> 462*946379e7Schristos 463*946379e7Schristos 464*946379e7Schristos<H3><A NAME="SEC252" HREF="gettext_toc.html#TOC252">15.3.20 Boost Format Strings</A></H3> 465*946379e7Schristos 466*946379e7Schristos<P> 467*946379e7SchristosBoost format strings are described in the documentation of the 468*946379e7Schristos<CODE>boost::format</CODE> class, at 469*946379e7Schristos<A HREF="http://www.boost.org/libs/format/doc/format.html">http://www.boost.org/libs/format/doc/format.html</A>. 470*946379e7SchristosIn summary, a directive has either the same syntax as in a C format string, 471*946379e7Schristossuch as <SAMP>‘%1$+5d’</SAMP>, or may be surrounded by vertical bars, such as 472*946379e7Schristos<SAMP>‘%|1$+5d|’</SAMP> or <SAMP>‘%|1$+5|’</SAMP>, or consists of just an argument number 473*946379e7Schristosbetween percent signs, such as <SAMP>‘%1%’</SAMP>. 474*946379e7Schristos 475*946379e7Schristos</P> 476*946379e7Schristos 477*946379e7Schristos 478*946379e7Schristos<H2><A NAME="SEC253" HREF="gettext_toc.html#TOC253">15.4 The Maintainer's View</A></H2> 479*946379e7Schristos 480*946379e7Schristos<P> 481*946379e7SchristosFor the maintainer, the general procedure differs from the C language 482*946379e7Schristoscase in two ways. 483*946379e7Schristos 484*946379e7Schristos</P> 485*946379e7Schristos 486*946379e7Schristos<UL> 487*946379e7Schristos<LI> 488*946379e7Schristos 489*946379e7SchristosFor those languages that don't use GNU gettext, the <TT>‘intl/’</TT> directory 490*946379e7Schristosis not needed and can be omitted. This means that the maintainer calls the 491*946379e7Schristos<CODE>gettextize</CODE> program without the <SAMP>‘--intl’</SAMP> option, and that he 492*946379e7Schristosinvokes the <CODE>AM_GNU_GETTEXT</CODE> autoconf macro via 493*946379e7Schristos<SAMP>‘AM_GNU_GETTEXT([external])’</SAMP>. 494*946379e7Schristos 495*946379e7Schristos<LI> 496*946379e7Schristos 497*946379e7SchristosIf only a single programming language is used, the <CODE>XGETTEXT_OPTIONS</CODE> 498*946379e7Schristosvariable in <TT>‘po/Makevars’</TT> (see section <A HREF="gettext_13.html#SEC203">13.4.3 <TT>‘Makevars’</TT> in <TT>‘po/’</TT></A>) should be adjusted to 499*946379e7Schristosmatch the <CODE>xgettext</CODE> options for that particular programming language. 500*946379e7SchristosIf the package uses more than one programming language with <CODE>gettext</CODE> 501*946379e7Schristossupport, it becomes necessary to change the POT file construction rule 502*946379e7Schristosin <TT>‘po/Makefile.in.in’</TT>. It is recommended to make one <CODE>xgettext</CODE> 503*946379e7Schristosinvocation per programming language, each with the options appropriate for 504*946379e7Schristosthat language, and to combine the resulting files using <CODE>msgcat</CODE>. 505*946379e7Schristos</UL> 506*946379e7Schristos 507*946379e7Schristos 508*946379e7Schristos 509*946379e7Schristos<H2><A NAME="SEC254" HREF="gettext_toc.html#TOC254">15.5 Individual Programming Languages</A></H2> 510*946379e7Schristos 511*946379e7Schristos 512*946379e7Schristos 513*946379e7Schristos<H3><A NAME="SEC255" HREF="gettext_toc.html#TOC255">15.5.1 C, C++, Objective C</A></H3> 514*946379e7Schristos<P> 515*946379e7Schristos<A NAME="IDX1115"></A> 516*946379e7Schristos 517*946379e7Schristos</P> 518*946379e7Schristos<DL COMPACT> 519*946379e7Schristos 520*946379e7Schristos<DT>RPMs 521*946379e7Schristos<DD> 522*946379e7Schristosgcc, gpp, gobjc, glibc, gettext 523*946379e7Schristos 524*946379e7Schristos<DT>File extension 525*946379e7Schristos<DD> 526*946379e7SchristosFor C: <CODE>c</CODE>, <CODE>h</CODE>. 527*946379e7Schristos<BR>For C++: <CODE>C</CODE>, <CODE>c++</CODE>, <CODE>cc</CODE>, <CODE>cxx</CODE>, <CODE>cpp</CODE>, <CODE>hpp</CODE>. 528*946379e7Schristos<BR>For Objective C: <CODE>m</CODE>. 529*946379e7Schristos 530*946379e7Schristos<DT>String syntax 531*946379e7Schristos<DD> 532*946379e7Schristos<CODE>"abc"</CODE> 533*946379e7Schristos 534*946379e7Schristos<DT>gettext shorthand 535*946379e7Schristos<DD> 536*946379e7Schristos<CODE>_("abc")</CODE> 537*946379e7Schristos 538*946379e7Schristos<DT>gettext/ngettext functions 539*946379e7Schristos<DD> 540*946379e7Schristos<CODE>gettext</CODE>, <CODE>dgettext</CODE>, <CODE>dcgettext</CODE>, <CODE>ngettext</CODE>, 541*946379e7Schristos<CODE>dngettext</CODE>, <CODE>dcngettext</CODE> 542*946379e7Schristos 543*946379e7Schristos<DT>textdomain 544*946379e7Schristos<DD> 545*946379e7Schristos<CODE>textdomain</CODE> function 546*946379e7Schristos 547*946379e7Schristos<DT>bindtextdomain 548*946379e7Schristos<DD> 549*946379e7Schristos<CODE>bindtextdomain</CODE> function 550*946379e7Schristos 551*946379e7Schristos<DT>setlocale 552*946379e7Schristos<DD> 553*946379e7SchristosProgrammer must call <CODE>setlocale (LC_ALL, "")</CODE> 554*946379e7Schristos 555*946379e7Schristos<DT>Prerequisite 556*946379e7Schristos<DD> 557*946379e7Schristos<CODE>#include <libintl.h></CODE> 558*946379e7Schristos<BR><CODE>#include <locale.h></CODE> 559*946379e7Schristos<BR><CODE>#define _(string) gettext (string)</CODE> 560*946379e7Schristos 561*946379e7Schristos<DT>Use or emulate GNU gettext 562*946379e7Schristos<DD> 563*946379e7SchristosUse 564*946379e7Schristos 565*946379e7Schristos<DT>Extractor 566*946379e7Schristos<DD> 567*946379e7Schristos<CODE>xgettext -k_</CODE> 568*946379e7Schristos 569*946379e7Schristos<DT>Formatting with positions 570*946379e7Schristos<DD> 571*946379e7Schristos<CODE>fprintf "%2$d %1$d"</CODE> 572*946379e7Schristos<BR>In C++: <CODE>autosprintf "%2$d %1$d"</CODE> 573*946379e7Schristos(see section ‘Introduction’ in <CITE>GNU autosprintf</CITE>) 574*946379e7Schristos 575*946379e7Schristos<DT>Portability 576*946379e7Schristos<DD> 577*946379e7Schristosautoconf (gettext.m4) and #if ENABLE_NLS 578*946379e7Schristos 579*946379e7Schristos<DT>po-mode marking 580*946379e7Schristos<DD> 581*946379e7Schristosyes 582*946379e7Schristos</DL> 583*946379e7Schristos 584*946379e7Schristos<P> 585*946379e7SchristosThe following examples are available in the <TT>‘examples’</TT> directory: 586*946379e7Schristos<CODE>hello-c</CODE>, <CODE>hello-c-gnome</CODE>, <CODE>hello-c++</CODE>, <CODE>hello-c++-qt</CODE>, 587*946379e7Schristos<CODE>hello-c++-kde</CODE>, <CODE>hello-c++-gnome</CODE>, <CODE>hello-c++-wxwidgets</CODE>, 588*946379e7Schristos<CODE>hello-objc</CODE>, <CODE>hello-objc-gnustep</CODE>, <CODE>hello-objc-gnome</CODE>. 589*946379e7Schristos 590*946379e7Schristos</P> 591*946379e7Schristos 592*946379e7Schristos 593*946379e7Schristos<H3><A NAME="SEC256" HREF="gettext_toc.html#TOC256">15.5.2 sh - Shell Script</A></H3> 594*946379e7Schristos<P> 595*946379e7Schristos<A NAME="IDX1116"></A> 596*946379e7Schristos 597*946379e7Schristos</P> 598*946379e7Schristos<DL COMPACT> 599*946379e7Schristos 600*946379e7Schristos<DT>RPMs 601*946379e7Schristos<DD> 602*946379e7Schristosbash, gettext 603*946379e7Schristos 604*946379e7Schristos<DT>File extension 605*946379e7Schristos<DD> 606*946379e7Schristos<CODE>sh</CODE> 607*946379e7Schristos 608*946379e7Schristos<DT>String syntax 609*946379e7Schristos<DD> 610*946379e7Schristos<CODE>"abc"</CODE>, <CODE>'abc'</CODE>, <CODE>abc</CODE> 611*946379e7Schristos 612*946379e7Schristos<DT>gettext shorthand 613*946379e7Schristos<DD> 614*946379e7Schristos<CODE>"`gettext \"abc\"`"</CODE> 615*946379e7Schristos 616*946379e7Schristos<DT>gettext/ngettext functions 617*946379e7Schristos<DD> 618*946379e7Schristos<A NAME="IDX1117"></A> 619*946379e7Schristos<A NAME="IDX1118"></A> 620*946379e7Schristos<CODE>gettext</CODE>, <CODE>ngettext</CODE> programs 621*946379e7Schristos<BR><CODE>eval_gettext</CODE>, <CODE>eval_ngettext</CODE> shell functions 622*946379e7Schristos 623*946379e7Schristos<DT>textdomain 624*946379e7Schristos<DD> 625*946379e7Schristos<A NAME="IDX1119"></A> 626*946379e7Schristosenvironment variable <CODE>TEXTDOMAIN</CODE> 627*946379e7Schristos 628*946379e7Schristos<DT>bindtextdomain 629*946379e7Schristos<DD> 630*946379e7Schristos<A NAME="IDX1120"></A> 631*946379e7Schristosenvironment variable <CODE>TEXTDOMAINDIR</CODE> 632*946379e7Schristos 633*946379e7Schristos<DT>setlocale 634*946379e7Schristos<DD> 635*946379e7Schristosautomatic 636*946379e7Schristos 637*946379e7Schristos<DT>Prerequisite 638*946379e7Schristos<DD> 639*946379e7Schristos<CODE>. gettext.sh</CODE> 640*946379e7Schristos 641*946379e7Schristos<DT>Use or emulate GNU gettext 642*946379e7Schristos<DD> 643*946379e7Schristosuse 644*946379e7Schristos 645*946379e7Schristos<DT>Extractor 646*946379e7Schristos<DD> 647*946379e7Schristos<CODE>xgettext</CODE> 648*946379e7Schristos 649*946379e7Schristos<DT>Formatting with positions 650*946379e7Schristos<DD> 651*946379e7Schristos--- 652*946379e7Schristos 653*946379e7Schristos<DT>Portability 654*946379e7Schristos<DD> 655*946379e7Schristosfully portable 656*946379e7Schristos 657*946379e7Schristos<DT>po-mode marking 658*946379e7Schristos<DD> 659*946379e7Schristos--- 660*946379e7Schristos</DL> 661*946379e7Schristos 662*946379e7Schristos<P> 663*946379e7SchristosAn example is available in the <TT>‘examples’</TT> directory: <CODE>hello-sh</CODE>. 664*946379e7Schristos 665*946379e7Schristos</P> 666*946379e7Schristos 667*946379e7Schristos 668*946379e7Schristos 669*946379e7Schristos<H4><A NAME="SEC257" HREF="gettext_toc.html#TOC257">15.5.2.1 Preparing Shell Scripts for Internationalization</A></H4> 670*946379e7Schristos<P> 671*946379e7Schristos<A NAME="IDX1121"></A> 672*946379e7Schristos 673*946379e7Schristos</P> 674*946379e7Schristos<P> 675*946379e7SchristosPreparing a shell script for internationalization is conceptually similar 676*946379e7Schristosto the steps described in section <A HREF="gettext_4.html#SEC11">4 Preparing Program Sources</A>. The concrete steps for shell 677*946379e7Schristosscripts are as follows. 678*946379e7Schristos 679*946379e7Schristos</P> 680*946379e7Schristos 681*946379e7Schristos<OL> 682*946379e7Schristos<LI> 683*946379e7Schristos 684*946379e7SchristosInsert the line 685*946379e7Schristos 686*946379e7Schristos 687*946379e7Schristos<PRE> 688*946379e7Schristos. gettext.sh 689*946379e7Schristos</PRE> 690*946379e7Schristos 691*946379e7Schristosnear the top of the script. <CODE>gettext.sh</CODE> is a shell function library 692*946379e7Schristosthat provides the functions 693*946379e7Schristos<CODE>eval_gettext</CODE> (see section <A HREF="gettext_15.html#SEC262">15.5.2.6 Invoking the <CODE>eval_gettext</CODE> function</A>) and 694*946379e7Schristos<CODE>eval_ngettext</CODE> (see section <A HREF="gettext_15.html#SEC263">15.5.2.7 Invoking the <CODE>eval_ngettext</CODE> function</A>). 695*946379e7SchristosYou have to ensure that <CODE>gettext.sh</CODE> can be found in the <CODE>PATH</CODE>. 696*946379e7Schristos 697*946379e7Schristos<LI> 698*946379e7Schristos 699*946379e7SchristosSet and export the <CODE>TEXTDOMAIN</CODE> and <CODE>TEXTDOMAINDIR</CODE> environment 700*946379e7Schristosvariables. Usually <CODE>TEXTDOMAIN</CODE> is the package or program name, and 701*946379e7Schristos<CODE>TEXTDOMAINDIR</CODE> is the absolute pathname corresponding to 702*946379e7Schristos<CODE>$prefix/share/locale</CODE>, where <CODE>$prefix</CODE> is the installation location. 703*946379e7Schristos 704*946379e7Schristos 705*946379e7Schristos<PRE> 706*946379e7SchristosTEXTDOMAIN=@PACKAGE@ 707*946379e7Schristosexport TEXTDOMAIN 708*946379e7SchristosTEXTDOMAINDIR=@LOCALEDIR@ 709*946379e7Schristosexport TEXTDOMAINDIR 710*946379e7Schristos</PRE> 711*946379e7Schristos 712*946379e7Schristos<LI> 713*946379e7Schristos 714*946379e7SchristosPrepare the strings for translation, as described in section <A HREF="gettext_4.html#SEC14">4.3 Preparing Translatable Strings</A>. 715*946379e7Schristos 716*946379e7Schristos<LI> 717*946379e7Schristos 718*946379e7SchristosSimplify translatable strings so that they don't contain command substitution 719*946379e7Schristos(<CODE>"`...`"</CODE> or <CODE>"$(...)"</CODE>), variable access with defaulting (like 720*946379e7Schristos<CODE>${<VAR>variable</VAR>-<VAR>default</VAR>}</CODE>), access to positional arguments 721*946379e7Schristos(like <CODE>$0</CODE>, <CODE>$1</CODE>, ...) or highly volatile shell variables (like 722*946379e7Schristos<CODE>$?</CODE>). This can always be done through simple local code restructuring. 723*946379e7SchristosFor example, 724*946379e7Schristos 725*946379e7Schristos 726*946379e7Schristos<PRE> 727*946379e7Schristosecho "Usage: $0 [OPTION] FILE..." 728*946379e7Schristos</PRE> 729*946379e7Schristos 730*946379e7Schristosbecomes 731*946379e7Schristos 732*946379e7Schristos 733*946379e7Schristos<PRE> 734*946379e7Schristosprogram_name=$0 735*946379e7Schristosecho "Usage: $program_name [OPTION] FILE..." 736*946379e7Schristos</PRE> 737*946379e7Schristos 738*946379e7SchristosSimilarly, 739*946379e7Schristos 740*946379e7Schristos 741*946379e7Schristos<PRE> 742*946379e7Schristosecho "Remaining files: `ls | wc -l`" 743*946379e7Schristos</PRE> 744*946379e7Schristos 745*946379e7Schristosbecomes 746*946379e7Schristos 747*946379e7Schristos 748*946379e7Schristos<PRE> 749*946379e7Schristosfilecount="`ls | wc -l`" 750*946379e7Schristosecho "Remaining files: $filecount" 751*946379e7Schristos</PRE> 752*946379e7Schristos 753*946379e7Schristos<LI> 754*946379e7Schristos 755*946379e7SchristosFor each translatable string, change the output command <SAMP>‘echo’</SAMP> or 756*946379e7Schristos<SAMP>‘$echo’</SAMP> to <SAMP>‘gettext’</SAMP> (if the string contains no references to 757*946379e7Schristosshell variables) or to <SAMP>‘eval_gettext’</SAMP> (if it refers to shell variables), 758*946379e7Schristosfollowed by a no-argument <SAMP>‘echo’</SAMP> command (to account for the terminating 759*946379e7Schristosnewline). Similarly, for cases with plural handling, replace a conditional 760*946379e7Schristos<SAMP>‘echo’</SAMP> command with an invocation of <SAMP>‘ngettext’</SAMP> or 761*946379e7Schristos<SAMP>‘eval_ngettext’</SAMP>, followed by a no-argument <SAMP>‘echo’</SAMP> command. 762*946379e7Schristos 763*946379e7SchristosWhen doing this, you also need to add an extra backslash before the dollar 764*946379e7Schristossign in references to shell variables, so that the <SAMP>‘eval_gettext’</SAMP> 765*946379e7Schristosfunction receives the translatable string before the variable values are 766*946379e7Schristossubstituted into it. For example, 767*946379e7Schristos 768*946379e7Schristos 769*946379e7Schristos<PRE> 770*946379e7Schristosecho "Remaining files: $filecount" 771*946379e7Schristos</PRE> 772*946379e7Schristos 773*946379e7Schristosbecomes 774*946379e7Schristos 775*946379e7Schristos 776*946379e7Schristos<PRE> 777*946379e7Schristoseval_gettext "Remaining files: \$filecount"; echo 778*946379e7Schristos</PRE> 779*946379e7Schristos 780*946379e7SchristosIf the output command is not <SAMP>‘echo’</SAMP>, you can make it use <SAMP>‘echo’</SAMP> 781*946379e7Schristosnevertheless, through the use of backquotes. However, note that inside 782*946379e7Schristosbackquotes, backslashes must be doubled to be effective (because the 783*946379e7Schristosbackquoting eats one level of backslashes). For example, assuming that 784*946379e7Schristos<SAMP>‘error’</SAMP> is a shell function that signals an error, 785*946379e7Schristos 786*946379e7Schristos 787*946379e7Schristos<PRE> 788*946379e7Schristoserror "file not found: $filename" 789*946379e7Schristos</PRE> 790*946379e7Schristos 791*946379e7Schristosis first transformed into 792*946379e7Schristos 793*946379e7Schristos 794*946379e7Schristos<PRE> 795*946379e7Schristoserror "`echo \"file not found: \$filename\"`" 796*946379e7Schristos</PRE> 797*946379e7Schristos 798*946379e7Schristoswhich then becomes 799*946379e7Schristos 800*946379e7Schristos 801*946379e7Schristos<PRE> 802*946379e7Schristoserror "`eval_gettext \"file not found: \\\$filename\"`" 803*946379e7Schristos</PRE> 804*946379e7Schristos 805*946379e7Schristos</OL> 806*946379e7Schristos 807*946379e7Schristos 808*946379e7Schristos 809*946379e7Schristos<H4><A NAME="SEC258" HREF="gettext_toc.html#TOC258">15.5.2.2 Contents of <CODE>gettext.sh</CODE></A></H4> 810*946379e7Schristos 811*946379e7Schristos<P> 812*946379e7Schristos<CODE>gettext.sh</CODE>, contained in the run-time package of GNU gettext, provides 813*946379e7Schristosthe following: 814*946379e7Schristos 815*946379e7Schristos</P> 816*946379e7Schristos 817*946379e7Schristos<UL> 818*946379e7Schristos<LI>$echo 819*946379e7Schristos 820*946379e7SchristosThe variable <CODE>echo</CODE> is set to a command that outputs its first argument 821*946379e7Schristosand a newline, without interpreting backslashes in the argument string. 822*946379e7Schristos 823*946379e7Schristos<LI>eval_gettext 824*946379e7Schristos 825*946379e7SchristosSee section <A HREF="gettext_15.html#SEC262">15.5.2.6 Invoking the <CODE>eval_gettext</CODE> function</A>. 826*946379e7Schristos 827*946379e7Schristos<LI>eval_ngettext 828*946379e7Schristos 829*946379e7SchristosSee section <A HREF="gettext_15.html#SEC263">15.5.2.7 Invoking the <CODE>eval_ngettext</CODE> function</A>. 830*946379e7Schristos</UL> 831*946379e7Schristos 832*946379e7Schristos 833*946379e7Schristos 834*946379e7Schristos<H4><A NAME="SEC259" HREF="gettext_toc.html#TOC259">15.5.2.3 Invoking the <CODE>gettext</CODE> program</A></H4> 835*946379e7Schristos 836*946379e7Schristos<P> 837*946379e7Schristos<A NAME="IDX1122"></A> 838*946379e7Schristos<A NAME="IDX1123"></A> 839*946379e7Schristos 840*946379e7Schristos<PRE> 841*946379e7Schristosgettext [<VAR>option</VAR>] [[<VAR>textdomain</VAR>] <VAR>msgid</VAR>] 842*946379e7Schristosgettext [<VAR>option</VAR>] -s [<VAR>msgid</VAR>]... 843*946379e7Schristos</PRE> 844*946379e7Schristos 845*946379e7Schristos<P> 846*946379e7Schristos<A NAME="IDX1124"></A> 847*946379e7SchristosThe <CODE>gettext</CODE> program displays the native language translation of a 848*946379e7Schristostextual message. 849*946379e7Schristos 850*946379e7Schristos</P> 851*946379e7Schristos<P> 852*946379e7Schristos<STRONG>Arguments</STRONG> 853*946379e7Schristos 854*946379e7Schristos</P> 855*946379e7Schristos<DL COMPACT> 856*946379e7Schristos 857*946379e7Schristos<DT><SAMP>‘-d <VAR>textdomain</VAR>’</SAMP> 858*946379e7Schristos<DD> 859*946379e7Schristos<DT><SAMP>‘--domain=<VAR>textdomain</VAR>’</SAMP> 860*946379e7Schristos<DD> 861*946379e7Schristos<A NAME="IDX1125"></A> 862*946379e7Schristos<A NAME="IDX1126"></A> 863*946379e7SchristosRetrieve translated messages from <VAR>textdomain</VAR>. Usually a <VAR>textdomain</VAR> 864*946379e7Schristoscorresponds to a package, a program, or a module of a program. 865*946379e7Schristos 866*946379e7Schristos<DT><SAMP>‘-e’</SAMP> 867*946379e7Schristos<DD> 868*946379e7Schristos<A NAME="IDX1127"></A> 869*946379e7SchristosEnable expansion of some escape sequences. This option is for compatibility 870*946379e7Schristoswith the <SAMP>‘echo’</SAMP> program or shell built-in. The escape sequences 871*946379e7Schristos<SAMP>‘\a’</SAMP>, <SAMP>‘\b’</SAMP>, <SAMP>‘\c’</SAMP>, <SAMP>‘\f’</SAMP>, <SAMP>‘\n’</SAMP>, <SAMP>‘\r’</SAMP>, <SAMP>‘\t’</SAMP>, 872*946379e7Schristos<SAMP>‘\v’</SAMP>, <SAMP>‘\\’</SAMP>, and <SAMP>‘\’</SAMP> followed by one to three octal digits, are 873*946379e7Schristosinterpreted like the System V <SAMP>‘echo’</SAMP> program did. 874*946379e7Schristos 875*946379e7Schristos<DT><SAMP>‘-E’</SAMP> 876*946379e7Schristos<DD> 877*946379e7Schristos<A NAME="IDX1128"></A> 878*946379e7SchristosThis option is only for compatibility with the <SAMP>‘echo’</SAMP> program or shell 879*946379e7Schristosbuilt-in. It has no effect. 880*946379e7Schristos 881*946379e7Schristos<DT><SAMP>‘-h’</SAMP> 882*946379e7Schristos<DD> 883*946379e7Schristos<DT><SAMP>‘--help’</SAMP> 884*946379e7Schristos<DD> 885*946379e7Schristos<A NAME="IDX1129"></A> 886*946379e7Schristos<A NAME="IDX1130"></A> 887*946379e7SchristosDisplay this help and exit. 888*946379e7Schristos 889*946379e7Schristos<DT><SAMP>‘-n’</SAMP> 890*946379e7Schristos<DD> 891*946379e7Schristos<A NAME="IDX1131"></A> 892*946379e7SchristosSuppress trailing newline. By default, <CODE>gettext</CODE> adds a newline to 893*946379e7Schristosthe output. 894*946379e7Schristos 895*946379e7Schristos<DT><SAMP>‘-V’</SAMP> 896*946379e7Schristos<DD> 897*946379e7Schristos<DT><SAMP>‘--version’</SAMP> 898*946379e7Schristos<DD> 899*946379e7Schristos<A NAME="IDX1132"></A> 900*946379e7Schristos<A NAME="IDX1133"></A> 901*946379e7SchristosOutput version information and exit. 902*946379e7Schristos 903*946379e7Schristos<DT><SAMP>‘[<VAR>textdomain</VAR>] <VAR>msgid</VAR>’</SAMP> 904*946379e7Schristos<DD> 905*946379e7SchristosRetrieve translated message corresponding to <VAR>msgid</VAR> from <VAR>textdomain</VAR>. 906*946379e7Schristos 907*946379e7Schristos</DL> 908*946379e7Schristos 909*946379e7Schristos<P> 910*946379e7SchristosIf the <VAR>textdomain</VAR> parameter is not given, the domain is determined from 911*946379e7Schristosthe environment variable <CODE>TEXTDOMAIN</CODE>. If the message catalog is not 912*946379e7Schristosfound in the regular directory, another location can be specified with the 913*946379e7Schristosenvironment variable <CODE>TEXTDOMAINDIR</CODE>. 914*946379e7Schristos 915*946379e7Schristos</P> 916*946379e7Schristos<P> 917*946379e7SchristosWhen used with the <CODE>-s</CODE> option the program behaves like the <SAMP>‘echo’</SAMP> 918*946379e7Schristoscommand. But it does not simply copy its arguments to stdout. Instead those 919*946379e7Schristosmessages found in the selected catalog are translated. 920*946379e7Schristos 921*946379e7Schristos</P> 922*946379e7Schristos 923*946379e7Schristos 924*946379e7Schristos<H4><A NAME="SEC260" HREF="gettext_toc.html#TOC260">15.5.2.4 Invoking the <CODE>ngettext</CODE> program</A></H4> 925*946379e7Schristos 926*946379e7Schristos<P> 927*946379e7Schristos<A NAME="IDX1134"></A> 928*946379e7Schristos<A NAME="IDX1135"></A> 929*946379e7Schristos 930*946379e7Schristos<PRE> 931*946379e7Schristosngettext [<VAR>option</VAR>] [<VAR>textdomain</VAR>] <VAR>msgid</VAR> <VAR>msgid-plural</VAR> <VAR>count</VAR> 932*946379e7Schristos</PRE> 933*946379e7Schristos 934*946379e7Schristos<P> 935*946379e7Schristos<A NAME="IDX1136"></A> 936*946379e7SchristosThe <CODE>ngettext</CODE> program displays the native language translation of a 937*946379e7Schristostextual message whose grammatical form depends on a number. 938*946379e7Schristos 939*946379e7Schristos</P> 940*946379e7Schristos<P> 941*946379e7Schristos<STRONG>Arguments</STRONG> 942*946379e7Schristos 943*946379e7Schristos</P> 944*946379e7Schristos<DL COMPACT> 945*946379e7Schristos 946*946379e7Schristos<DT><SAMP>‘-d <VAR>textdomain</VAR>’</SAMP> 947*946379e7Schristos<DD> 948*946379e7Schristos<DT><SAMP>‘--domain=<VAR>textdomain</VAR>’</SAMP> 949*946379e7Schristos<DD> 950*946379e7Schristos<A NAME="IDX1137"></A> 951*946379e7Schristos<A NAME="IDX1138"></A> 952*946379e7SchristosRetrieve translated messages from <VAR>textdomain</VAR>. Usually a <VAR>textdomain</VAR> 953*946379e7Schristoscorresponds to a package, a program, or a module of a program. 954*946379e7Schristos 955*946379e7Schristos<DT><SAMP>‘-e’</SAMP> 956*946379e7Schristos<DD> 957*946379e7Schristos<A NAME="IDX1139"></A> 958*946379e7SchristosEnable expansion of some escape sequences. This option is for compatibility 959*946379e7Schristoswith the <SAMP>‘gettext’</SAMP> program. The escape sequences 960*946379e7Schristos<SAMP>‘\a’</SAMP>, <SAMP>‘\b’</SAMP>, <SAMP>‘\c’</SAMP>, <SAMP>‘\f’</SAMP>, <SAMP>‘\n’</SAMP>, <SAMP>‘\r’</SAMP>, <SAMP>‘\t’</SAMP>, 961*946379e7Schristos<SAMP>‘\v’</SAMP>, <SAMP>‘\\’</SAMP>, and <SAMP>‘\’</SAMP> followed by one to three octal digits, are 962*946379e7Schristosinterpreted like the System V <SAMP>‘echo’</SAMP> program did. 963*946379e7Schristos 964*946379e7Schristos<DT><SAMP>‘-E’</SAMP> 965*946379e7Schristos<DD> 966*946379e7Schristos<A NAME="IDX1140"></A> 967*946379e7SchristosThis option is only for compatibility with the <SAMP>‘gettext’</SAMP> program. It has 968*946379e7Schristosno effect. 969*946379e7Schristos 970*946379e7Schristos<DT><SAMP>‘-h’</SAMP> 971*946379e7Schristos<DD> 972*946379e7Schristos<DT><SAMP>‘--help’</SAMP> 973*946379e7Schristos<DD> 974*946379e7Schristos<A NAME="IDX1141"></A> 975*946379e7Schristos<A NAME="IDX1142"></A> 976*946379e7SchristosDisplay this help and exit. 977*946379e7Schristos 978*946379e7Schristos<DT><SAMP>‘-V’</SAMP> 979*946379e7Schristos<DD> 980*946379e7Schristos<DT><SAMP>‘--version’</SAMP> 981*946379e7Schristos<DD> 982*946379e7Schristos<A NAME="IDX1143"></A> 983*946379e7Schristos<A NAME="IDX1144"></A> 984*946379e7SchristosOutput version information and exit. 985*946379e7Schristos 986*946379e7Schristos<DT><SAMP>‘<VAR>textdomain</VAR>’</SAMP> 987*946379e7Schristos<DD> 988*946379e7SchristosRetrieve translated message from <VAR>textdomain</VAR>. 989*946379e7Schristos 990*946379e7Schristos<DT><SAMP>‘<VAR>msgid</VAR> <VAR>msgid-plural</VAR>’</SAMP> 991*946379e7Schristos<DD> 992*946379e7SchristosTranslate <VAR>msgid</VAR> (English singular) / <VAR>msgid-plural</VAR> (English plural). 993*946379e7Schristos 994*946379e7Schristos<DT><SAMP>‘<VAR>count</VAR>’</SAMP> 995*946379e7Schristos<DD> 996*946379e7SchristosChoose singular/plural form based on this value. 997*946379e7Schristos 998*946379e7Schristos</DL> 999*946379e7Schristos 1000*946379e7Schristos<P> 1001*946379e7SchristosIf the <VAR>textdomain</VAR> parameter is not given, the domain is determined from 1002*946379e7Schristosthe environment variable <CODE>TEXTDOMAIN</CODE>. If the message catalog is not 1003*946379e7Schristosfound in the regular directory, another location can be specified with the 1004*946379e7Schristosenvironment variable <CODE>TEXTDOMAINDIR</CODE>. 1005*946379e7Schristos 1006*946379e7Schristos</P> 1007*946379e7Schristos 1008*946379e7Schristos 1009*946379e7Schristos<H4><A NAME="SEC261" HREF="gettext_toc.html#TOC261">15.5.2.5 Invoking the <CODE>envsubst</CODE> program</A></H4> 1010*946379e7Schristos 1011*946379e7Schristos<P> 1012*946379e7Schristos<A NAME="IDX1145"></A> 1013*946379e7Schristos<A NAME="IDX1146"></A> 1014*946379e7Schristos 1015*946379e7Schristos<PRE> 1016*946379e7Schristosenvsubst [<VAR>option</VAR>] [<VAR>shell-format</VAR>] 1017*946379e7Schristos</PRE> 1018*946379e7Schristos 1019*946379e7Schristos<P> 1020*946379e7Schristos<A NAME="IDX1147"></A> 1021*946379e7Schristos<A NAME="IDX1148"></A> 1022*946379e7Schristos<A NAME="IDX1149"></A> 1023*946379e7SchristosThe <CODE>envsubst</CODE> program substitutes the values of environment variables. 1024*946379e7Schristos 1025*946379e7Schristos</P> 1026*946379e7Schristos<P> 1027*946379e7Schristos<STRONG>Operation mode</STRONG> 1028*946379e7Schristos 1029*946379e7Schristos</P> 1030*946379e7Schristos<DL COMPACT> 1031*946379e7Schristos 1032*946379e7Schristos<DT><SAMP>‘-v’</SAMP> 1033*946379e7Schristos<DD> 1034*946379e7Schristos<DT><SAMP>‘--variables’</SAMP> 1035*946379e7Schristos<DD> 1036*946379e7Schristos<A NAME="IDX1150"></A> 1037*946379e7Schristos<A NAME="IDX1151"></A> 1038*946379e7SchristosOutput the variables occurring in <VAR>shell-format</VAR>. 1039*946379e7Schristos 1040*946379e7Schristos</DL> 1041*946379e7Schristos 1042*946379e7Schristos<P> 1043*946379e7Schristos<STRONG>Informative output</STRONG> 1044*946379e7Schristos 1045*946379e7Schristos</P> 1046*946379e7Schristos<DL COMPACT> 1047*946379e7Schristos 1048*946379e7Schristos<DT><SAMP>‘-h’</SAMP> 1049*946379e7Schristos<DD> 1050*946379e7Schristos<DT><SAMP>‘--help’</SAMP> 1051*946379e7Schristos<DD> 1052*946379e7Schristos<A NAME="IDX1152"></A> 1053*946379e7Schristos<A NAME="IDX1153"></A> 1054*946379e7SchristosDisplay this help and exit. 1055*946379e7Schristos 1056*946379e7Schristos<DT><SAMP>‘-V’</SAMP> 1057*946379e7Schristos<DD> 1058*946379e7Schristos<DT><SAMP>‘--version’</SAMP> 1059*946379e7Schristos<DD> 1060*946379e7Schristos<A NAME="IDX1154"></A> 1061*946379e7Schristos<A NAME="IDX1155"></A> 1062*946379e7SchristosOutput version information and exit. 1063*946379e7Schristos 1064*946379e7Schristos</DL> 1065*946379e7Schristos 1066*946379e7Schristos<P> 1067*946379e7SchristosIn normal operation mode, standard input is copied to standard output, 1068*946379e7Schristoswith references to environment variables of the form <CODE>$VARIABLE</CODE> or 1069*946379e7Schristos<CODE>${VARIABLE}</CODE> being replaced with the corresponding values. If a 1070*946379e7Schristos<VAR>shell-format</VAR> is given, only those environment variables that are 1071*946379e7Schristosreferenced in <VAR>shell-format</VAR> are substituted; otherwise all environment 1072*946379e7Schristosvariables references occurring in standard input are substituted. 1073*946379e7Schristos 1074*946379e7Schristos</P> 1075*946379e7Schristos<P> 1076*946379e7SchristosThese substitutions are a subset of the substitutions that a shell performs 1077*946379e7Schristoson unquoted and double-quoted strings. Other kinds of substitutions done 1078*946379e7Schristosby a shell, such as <CODE>${<VAR>variable</VAR>-<VAR>default</VAR>}</CODE> or 1079*946379e7Schristos<CODE>$(<VAR>command-list</VAR>)</CODE> or <CODE>`<VAR>command-list</VAR>`</CODE>, are not performed 1080*946379e7Schristosby the <CODE>envsubst</CODE> program, due to security reasons. 1081*946379e7Schristos 1082*946379e7Schristos</P> 1083*946379e7Schristos<P> 1084*946379e7SchristosWhen <CODE>--variables</CODE> is used, standard input is ignored, and the output 1085*946379e7Schristosconsists of the environment variables that are referenced in 1086*946379e7Schristos<VAR>shell-format</VAR>, one per line. 1087*946379e7Schristos 1088*946379e7Schristos</P> 1089*946379e7Schristos 1090*946379e7Schristos 1091*946379e7Schristos<H4><A NAME="SEC262" HREF="gettext_toc.html#TOC262">15.5.2.6 Invoking the <CODE>eval_gettext</CODE> function</A></H4> 1092*946379e7Schristos 1093*946379e7Schristos<P> 1094*946379e7Schristos<A NAME="IDX1156"></A> 1095*946379e7Schristos 1096*946379e7Schristos<PRE> 1097*946379e7Schristoseval_gettext <VAR>msgid</VAR> 1098*946379e7Schristos</PRE> 1099*946379e7Schristos 1100*946379e7Schristos<P> 1101*946379e7Schristos<A NAME="IDX1157"></A> 1102*946379e7SchristosThis function outputs the native language translation of a textual message, 1103*946379e7Schristosperforming dollar-substitution on the result. Note that only shell variables 1104*946379e7Schristosmentioned in <VAR>msgid</VAR> will be dollar-substituted in the result. 1105*946379e7Schristos 1106*946379e7Schristos</P> 1107*946379e7Schristos 1108*946379e7Schristos 1109*946379e7Schristos<H4><A NAME="SEC263" HREF="gettext_toc.html#TOC263">15.5.2.7 Invoking the <CODE>eval_ngettext</CODE> function</A></H4> 1110*946379e7Schristos 1111*946379e7Schristos<P> 1112*946379e7Schristos<A NAME="IDX1158"></A> 1113*946379e7Schristos 1114*946379e7Schristos<PRE> 1115*946379e7Schristoseval_ngettext <VAR>msgid</VAR> <VAR>msgid-plural</VAR> <VAR>count</VAR> 1116*946379e7Schristos</PRE> 1117*946379e7Schristos 1118*946379e7Schristos<P> 1119*946379e7Schristos<A NAME="IDX1159"></A> 1120*946379e7SchristosThis function outputs the native language translation of a textual message 1121*946379e7Schristoswhose grammatical form depends on a number, performing dollar-substitution 1122*946379e7Schristoson the result. Note that only shell variables mentioned in <VAR>msgid</VAR> or 1123*946379e7Schristos<VAR>msgid-plural</VAR> will be dollar-substituted in the result. 1124*946379e7Schristos 1125*946379e7Schristos</P> 1126*946379e7Schristos 1127*946379e7Schristos 1128*946379e7Schristos<H3><A NAME="SEC264" HREF="gettext_toc.html#TOC264">15.5.3 bash - Bourne-Again Shell Script</A></H3> 1129*946379e7Schristos<P> 1130*946379e7Schristos<A NAME="IDX1160"></A> 1131*946379e7Schristos 1132*946379e7Schristos</P> 1133*946379e7Schristos<P> 1134*946379e7SchristosGNU <CODE>bash</CODE> 2.0 or newer has a special shorthand for translating a 1135*946379e7Schristosstring and substituting variable values in it: <CODE>$"msgid"</CODE>. But 1136*946379e7Schristosthe use of this construct is <STRONG>discouraged</STRONG>, due to the security 1137*946379e7Schristosholes it opens and due to its portability problems. 1138*946379e7Schristos 1139*946379e7Schristos</P> 1140*946379e7Schristos<P> 1141*946379e7SchristosThe security holes of <CODE>$"..."</CODE> come from the fact that after looking up 1142*946379e7Schristosthe translation of the string, <CODE>bash</CODE> processes it like it processes 1143*946379e7Schristosany double-quoted string: dollar and backquote processing, like <SAMP>‘eval’</SAMP> 1144*946379e7Schristosdoes. 1145*946379e7Schristos 1146*946379e7Schristos</P> 1147*946379e7Schristos 1148*946379e7Schristos<OL> 1149*946379e7Schristos<LI> 1150*946379e7Schristos 1151*946379e7SchristosIn a locale whose encoding is one of BIG5, BIG5-HKSCS, GBK, GB18030, SHIFT_JIS, 1152*946379e7SchristosJOHAB, some double-byte characters have a second byte whose value is 1153*946379e7Schristos<CODE>0x60</CODE>. For example, the byte sequence <CODE>\xe0\x60</CODE> is a single 1154*946379e7Schristoscharacter in these locales. Many versions of <CODE>bash</CODE> (all versions 1155*946379e7Schristosup to bash-2.05, and newer versions on platforms without <CODE>mbsrtowcs()</CODE> 1156*946379e7Schristosfunction) don't know about character boundaries and see a backquote character 1157*946379e7Schristoswhere there is only a particular Chinese character. Thus it can start 1158*946379e7Schristosexecuting part of the translation as a command list. This situation can occur 1159*946379e7Schristoseven without the translator being aware of it: if the translator provides 1160*946379e7Schristostranslations in the UTF-8 encoding, it is the <CODE>gettext()</CODE> function which 1161*946379e7Schristoswill, during its conversion from the translator's encoding to the user's 1162*946379e7Schristoslocale's encoding, produce the dangerous <CODE>\x60</CODE> bytes. 1163*946379e7Schristos 1164*946379e7Schristos<LI> 1165*946379e7Schristos 1166*946379e7SchristosA translator could - voluntarily or inadvertently - use backquotes 1167*946379e7Schristos<CODE>"`...`"</CODE> or dollar-parentheses <CODE>"$(...)"</CODE> in her translations. 1168*946379e7SchristosThe enclosed strings would be executed as command lists by the shell. 1169*946379e7Schristos</OL> 1170*946379e7Schristos 1171*946379e7Schristos<P> 1172*946379e7SchristosThe portability problem is that <CODE>bash</CODE> must be built with 1173*946379e7Schristosinternationalization support; this is normally not the case on systems 1174*946379e7Schristosthat don't have the <CODE>gettext()</CODE> function in libc. 1175*946379e7Schristos 1176*946379e7Schristos</P> 1177*946379e7Schristos 1178*946379e7Schristos 1179*946379e7Schristos<H3><A NAME="SEC265" HREF="gettext_toc.html#TOC265">15.5.4 Python</A></H3> 1180*946379e7Schristos<P> 1181*946379e7Schristos<A NAME="IDX1161"></A> 1182*946379e7Schristos 1183*946379e7Schristos</P> 1184*946379e7Schristos<DL COMPACT> 1185*946379e7Schristos 1186*946379e7Schristos<DT>RPMs 1187*946379e7Schristos<DD> 1188*946379e7Schristospython 1189*946379e7Schristos 1190*946379e7Schristos<DT>File extension 1191*946379e7Schristos<DD> 1192*946379e7Schristos<CODE>py</CODE> 1193*946379e7Schristos 1194*946379e7Schristos<DT>String syntax 1195*946379e7Schristos<DD> 1196*946379e7Schristos<CODE>'abc'</CODE>, <CODE>u'abc'</CODE>, <CODE>r'abc'</CODE>, <CODE>ur'abc'</CODE>, 1197*946379e7Schristos<BR><CODE>"abc"</CODE>, <CODE>u"abc"</CODE>, <CODE>r"abc"</CODE>, <CODE>ur"abc"</CODE>, 1198*946379e7Schristos<BR><CODE>”'abc”'</CODE>, <CODE>u”'abc”'</CODE>, <CODE>r”'abc”'</CODE>, <CODE>ur”'abc”'</CODE>, 1199*946379e7Schristos<BR><CODE>"""abc"""</CODE>, <CODE>u"""abc"""</CODE>, <CODE>r"""abc"""</CODE>, <CODE>ur"""abc"""</CODE> 1200*946379e7Schristos 1201*946379e7Schristos<DT>gettext shorthand 1202*946379e7Schristos<DD> 1203*946379e7Schristos<CODE>_('abc')</CODE> etc. 1204*946379e7Schristos 1205*946379e7Schristos<DT>gettext/ngettext functions 1206*946379e7Schristos<DD> 1207*946379e7Schristos<CODE>gettext.gettext</CODE>, <CODE>gettext.dgettext</CODE>, 1208*946379e7Schristos<CODE>gettext.ngettext</CODE>, <CODE>gettext.dngettext</CODE>, 1209*946379e7Schristosalso <CODE>ugettext</CODE>, <CODE>ungettext</CODE> 1210*946379e7Schristos 1211*946379e7Schristos<DT>textdomain 1212*946379e7Schristos<DD> 1213*946379e7Schristos<CODE>gettext.textdomain</CODE> function, or 1214*946379e7Schristos<CODE>gettext.install(<VAR>domain</VAR>)</CODE> function 1215*946379e7Schristos 1216*946379e7Schristos<DT>bindtextdomain 1217*946379e7Schristos<DD> 1218*946379e7Schristos<CODE>gettext.bindtextdomain</CODE> function, or 1219*946379e7Schristos<CODE>gettext.install(<VAR>domain</VAR>,<VAR>localedir</VAR>)</CODE> function 1220*946379e7Schristos 1221*946379e7Schristos<DT>setlocale 1222*946379e7Schristos<DD> 1223*946379e7Schristosnot used by the gettext emulation 1224*946379e7Schristos 1225*946379e7Schristos<DT>Prerequisite 1226*946379e7Schristos<DD> 1227*946379e7Schristos<CODE>import gettext</CODE> 1228*946379e7Schristos 1229*946379e7Schristos<DT>Use or emulate GNU gettext 1230*946379e7Schristos<DD> 1231*946379e7Schristosemulate 1232*946379e7Schristos 1233*946379e7Schristos<DT>Extractor 1234*946379e7Schristos<DD> 1235*946379e7Schristos<CODE>xgettext</CODE> 1236*946379e7Schristos 1237*946379e7Schristos<DT>Formatting with positions 1238*946379e7Schristos<DD> 1239*946379e7Schristos<CODE>'...%(ident)d...' % { 'ident': value }</CODE> 1240*946379e7Schristos 1241*946379e7Schristos<DT>Portability 1242*946379e7Schristos<DD> 1243*946379e7Schristosfully portable 1244*946379e7Schristos 1245*946379e7Schristos<DT>po-mode marking 1246*946379e7Schristos<DD> 1247*946379e7Schristos--- 1248*946379e7Schristos</DL> 1249*946379e7Schristos 1250*946379e7Schristos<P> 1251*946379e7SchristosAn example is available in the <TT>‘examples’</TT> directory: <CODE>hello-python</CODE>. 1252*946379e7Schristos 1253*946379e7Schristos</P> 1254*946379e7Schristos 1255*946379e7Schristos 1256*946379e7Schristos<H3><A NAME="SEC266" HREF="gettext_toc.html#TOC266">15.5.5 GNU clisp - Common Lisp</A></H3> 1257*946379e7Schristos<P> 1258*946379e7Schristos<A NAME="IDX1162"></A> 1259*946379e7Schristos<A NAME="IDX1163"></A> 1260*946379e7Schristos<A NAME="IDX1164"></A> 1261*946379e7Schristos 1262*946379e7Schristos</P> 1263*946379e7Schristos<DL COMPACT> 1264*946379e7Schristos 1265*946379e7Schristos<DT>RPMs 1266*946379e7Schristos<DD> 1267*946379e7Schristosclisp 2.28 or newer 1268*946379e7Schristos 1269*946379e7Schristos<DT>File extension 1270*946379e7Schristos<DD> 1271*946379e7Schristos<CODE>lisp</CODE> 1272*946379e7Schristos 1273*946379e7Schristos<DT>String syntax 1274*946379e7Schristos<DD> 1275*946379e7Schristos<CODE>"abc"</CODE> 1276*946379e7Schristos 1277*946379e7Schristos<DT>gettext shorthand 1278*946379e7Schristos<DD> 1279*946379e7Schristos<CODE>(_ "abc")</CODE>, <CODE>(ENGLISH "abc")</CODE> 1280*946379e7Schristos 1281*946379e7Schristos<DT>gettext/ngettext functions 1282*946379e7Schristos<DD> 1283*946379e7Schristos<CODE>i18n:gettext</CODE>, <CODE>i18n:ngettext</CODE> 1284*946379e7Schristos 1285*946379e7Schristos<DT>textdomain 1286*946379e7Schristos<DD> 1287*946379e7Schristos<CODE>i18n:textdomain</CODE> 1288*946379e7Schristos 1289*946379e7Schristos<DT>bindtextdomain 1290*946379e7Schristos<DD> 1291*946379e7Schristos<CODE>i18n:textdomaindir</CODE> 1292*946379e7Schristos 1293*946379e7Schristos<DT>setlocale 1294*946379e7Schristos<DD> 1295*946379e7Schristosautomatic 1296*946379e7Schristos 1297*946379e7Schristos<DT>Prerequisite 1298*946379e7Schristos<DD> 1299*946379e7Schristos--- 1300*946379e7Schristos 1301*946379e7Schristos<DT>Use or emulate GNU gettext 1302*946379e7Schristos<DD> 1303*946379e7Schristosuse 1304*946379e7Schristos 1305*946379e7Schristos<DT>Extractor 1306*946379e7Schristos<DD> 1307*946379e7Schristos<CODE>xgettext -k_ -kENGLISH</CODE> 1308*946379e7Schristos 1309*946379e7Schristos<DT>Formatting with positions 1310*946379e7Schristos<DD> 1311*946379e7Schristos<CODE>format "~1@*~D ~0@*~D"</CODE> 1312*946379e7Schristos 1313*946379e7Schristos<DT>Portability 1314*946379e7Schristos<DD> 1315*946379e7SchristosOn platforms without gettext, no translation. 1316*946379e7Schristos 1317*946379e7Schristos<DT>po-mode marking 1318*946379e7Schristos<DD> 1319*946379e7Schristos--- 1320*946379e7Schristos</DL> 1321*946379e7Schristos 1322*946379e7Schristos<P> 1323*946379e7SchristosAn example is available in the <TT>‘examples’</TT> directory: <CODE>hello-clisp</CODE>. 1324*946379e7Schristos 1325*946379e7Schristos</P> 1326*946379e7Schristos 1327*946379e7Schristos 1328*946379e7Schristos<H3><A NAME="SEC267" HREF="gettext_toc.html#TOC267">15.5.6 GNU clisp C sources</A></H3> 1329*946379e7Schristos<P> 1330*946379e7Schristos<A NAME="IDX1165"></A> 1331*946379e7Schristos 1332*946379e7Schristos</P> 1333*946379e7Schristos<DL COMPACT> 1334*946379e7Schristos 1335*946379e7Schristos<DT>RPMs 1336*946379e7Schristos<DD> 1337*946379e7Schristosclisp 1338*946379e7Schristos 1339*946379e7Schristos<DT>File extension 1340*946379e7Schristos<DD> 1341*946379e7Schristos<CODE>d</CODE> 1342*946379e7Schristos 1343*946379e7Schristos<DT>String syntax 1344*946379e7Schristos<DD> 1345*946379e7Schristos<CODE>"abc"</CODE> 1346*946379e7Schristos 1347*946379e7Schristos<DT>gettext shorthand 1348*946379e7Schristos<DD> 1349*946379e7Schristos<CODE>ENGLISH ? "abc" : ""</CODE> 1350*946379e7Schristos<BR><CODE>GETTEXT("abc")</CODE> 1351*946379e7Schristos<BR><CODE>GETTEXTL("abc")</CODE> 1352*946379e7Schristos 1353*946379e7Schristos<DT>gettext/ngettext functions 1354*946379e7Schristos<DD> 1355*946379e7Schristos<CODE>clgettext</CODE>, <CODE>clgettextl</CODE> 1356*946379e7Schristos 1357*946379e7Schristos<DT>textdomain 1358*946379e7Schristos<DD> 1359*946379e7Schristos--- 1360*946379e7Schristos 1361*946379e7Schristos<DT>bindtextdomain 1362*946379e7Schristos<DD> 1363*946379e7Schristos--- 1364*946379e7Schristos 1365*946379e7Schristos<DT>setlocale 1366*946379e7Schristos<DD> 1367*946379e7Schristosautomatic 1368*946379e7Schristos 1369*946379e7Schristos<DT>Prerequisite 1370*946379e7Schristos<DD> 1371*946379e7Schristos<CODE>#include "lispbibl.c"</CODE> 1372*946379e7Schristos 1373*946379e7Schristos<DT>Use or emulate GNU gettext 1374*946379e7Schristos<DD> 1375*946379e7Schristosuse 1376*946379e7Schristos 1377*946379e7Schristos<DT>Extractor 1378*946379e7Schristos<DD> 1379*946379e7Schristos<CODE>clisp-xgettext</CODE> 1380*946379e7Schristos 1381*946379e7Schristos<DT>Formatting with positions 1382*946379e7Schristos<DD> 1383*946379e7Schristos<CODE>fprintf "%2$d %1$d"</CODE> 1384*946379e7Schristos 1385*946379e7Schristos<DT>Portability 1386*946379e7Schristos<DD> 1387*946379e7SchristosOn platforms without gettext, no translation. 1388*946379e7Schristos 1389*946379e7Schristos<DT>po-mode marking 1390*946379e7Schristos<DD> 1391*946379e7Schristos--- 1392*946379e7Schristos</DL> 1393*946379e7Schristos 1394*946379e7Schristos 1395*946379e7Schristos 1396*946379e7Schristos<H3><A NAME="SEC268" HREF="gettext_toc.html#TOC268">15.5.7 Emacs Lisp</A></H3> 1397*946379e7Schristos<P> 1398*946379e7Schristos<A NAME="IDX1166"></A> 1399*946379e7Schristos 1400*946379e7Schristos</P> 1401*946379e7Schristos<DL COMPACT> 1402*946379e7Schristos 1403*946379e7Schristos<DT>RPMs 1404*946379e7Schristos<DD> 1405*946379e7Schristosemacs, xemacs 1406*946379e7Schristos 1407*946379e7Schristos<DT>File extension 1408*946379e7Schristos<DD> 1409*946379e7Schristos<CODE>el</CODE> 1410*946379e7Schristos 1411*946379e7Schristos<DT>String syntax 1412*946379e7Schristos<DD> 1413*946379e7Schristos<CODE>"abc"</CODE> 1414*946379e7Schristos 1415*946379e7Schristos<DT>gettext shorthand 1416*946379e7Schristos<DD> 1417*946379e7Schristos<CODE>(_"abc")</CODE> 1418*946379e7Schristos 1419*946379e7Schristos<DT>gettext/ngettext functions 1420*946379e7Schristos<DD> 1421*946379e7Schristos<CODE>gettext</CODE>, <CODE>dgettext</CODE> (xemacs only) 1422*946379e7Schristos 1423*946379e7Schristos<DT>textdomain 1424*946379e7Schristos<DD> 1425*946379e7Schristos<CODE>domain</CODE> special form (xemacs only) 1426*946379e7Schristos 1427*946379e7Schristos<DT>bindtextdomain 1428*946379e7Schristos<DD> 1429*946379e7Schristos<CODE>bind-text-domain</CODE> function (xemacs only) 1430*946379e7Schristos 1431*946379e7Schristos<DT>setlocale 1432*946379e7Schristos<DD> 1433*946379e7Schristosautomatic 1434*946379e7Schristos 1435*946379e7Schristos<DT>Prerequisite 1436*946379e7Schristos<DD> 1437*946379e7Schristos--- 1438*946379e7Schristos 1439*946379e7Schristos<DT>Use or emulate GNU gettext 1440*946379e7Schristos<DD> 1441*946379e7Schristosuse 1442*946379e7Schristos 1443*946379e7Schristos<DT>Extractor 1444*946379e7Schristos<DD> 1445*946379e7Schristos<CODE>xgettext</CODE> 1446*946379e7Schristos 1447*946379e7Schristos<DT>Formatting with positions 1448*946379e7Schristos<DD> 1449*946379e7Schristos<CODE>format "%2$d %1$d"</CODE> 1450*946379e7Schristos 1451*946379e7Schristos<DT>Portability 1452*946379e7Schristos<DD> 1453*946379e7SchristosOnly XEmacs. Without <CODE>I18N3</CODE> defined at build time, no translation. 1454*946379e7Schristos 1455*946379e7Schristos<DT>po-mode marking 1456*946379e7Schristos<DD> 1457*946379e7Schristos--- 1458*946379e7Schristos</DL> 1459*946379e7Schristos 1460*946379e7Schristos 1461*946379e7Schristos 1462*946379e7Schristos<H3><A NAME="SEC269" HREF="gettext_toc.html#TOC269">15.5.8 librep</A></H3> 1463*946379e7Schristos<P> 1464*946379e7Schristos<A NAME="IDX1167"></A> 1465*946379e7Schristos 1466*946379e7Schristos</P> 1467*946379e7Schristos<DL COMPACT> 1468*946379e7Schristos 1469*946379e7Schristos<DT>RPMs 1470*946379e7Schristos<DD> 1471*946379e7Schristoslibrep 0.15.3 or newer 1472*946379e7Schristos 1473*946379e7Schristos<DT>File extension 1474*946379e7Schristos<DD> 1475*946379e7Schristos<CODE>jl</CODE> 1476*946379e7Schristos 1477*946379e7Schristos<DT>String syntax 1478*946379e7Schristos<DD> 1479*946379e7Schristos<CODE>"abc"</CODE> 1480*946379e7Schristos 1481*946379e7Schristos<DT>gettext shorthand 1482*946379e7Schristos<DD> 1483*946379e7Schristos<CODE>(_"abc")</CODE> 1484*946379e7Schristos 1485*946379e7Schristos<DT>gettext/ngettext functions 1486*946379e7Schristos<DD> 1487*946379e7Schristos<CODE>gettext</CODE> 1488*946379e7Schristos 1489*946379e7Schristos<DT>textdomain 1490*946379e7Schristos<DD> 1491*946379e7Schristos<CODE>textdomain</CODE> function 1492*946379e7Schristos 1493*946379e7Schristos<DT>bindtextdomain 1494*946379e7Schristos<DD> 1495*946379e7Schristos<CODE>bindtextdomain</CODE> function 1496*946379e7Schristos 1497*946379e7Schristos<DT>setlocale 1498*946379e7Schristos<DD> 1499*946379e7Schristos--- 1500*946379e7Schristos 1501*946379e7Schristos<DT>Prerequisite 1502*946379e7Schristos<DD> 1503*946379e7Schristos<CODE>(require 'rep.i18n.gettext)</CODE> 1504*946379e7Schristos 1505*946379e7Schristos<DT>Use or emulate GNU gettext 1506*946379e7Schristos<DD> 1507*946379e7Schristosuse 1508*946379e7Schristos 1509*946379e7Schristos<DT>Extractor 1510*946379e7Schristos<DD> 1511*946379e7Schristos<CODE>xgettext</CODE> 1512*946379e7Schristos 1513*946379e7Schristos<DT>Formatting with positions 1514*946379e7Schristos<DD> 1515*946379e7Schristos<CODE>format "%2$d %1$d"</CODE> 1516*946379e7Schristos 1517*946379e7Schristos<DT>Portability 1518*946379e7Schristos<DD> 1519*946379e7SchristosOn platforms without gettext, no translation. 1520*946379e7Schristos 1521*946379e7Schristos<DT>po-mode marking 1522*946379e7Schristos<DD> 1523*946379e7Schristos--- 1524*946379e7Schristos</DL> 1525*946379e7Schristos 1526*946379e7Schristos<P> 1527*946379e7SchristosAn example is available in the <TT>‘examples’</TT> directory: <CODE>hello-librep</CODE>. 1528*946379e7Schristos 1529*946379e7Schristos</P> 1530*946379e7Schristos 1531*946379e7Schristos 1532*946379e7Schristos<H3><A NAME="SEC270" HREF="gettext_toc.html#TOC270">15.5.9 GNU guile - Scheme</A></H3> 1533*946379e7Schristos<P> 1534*946379e7Schristos<A NAME="IDX1168"></A> 1535*946379e7Schristos<A NAME="IDX1169"></A> 1536*946379e7Schristos 1537*946379e7Schristos</P> 1538*946379e7Schristos<DL COMPACT> 1539*946379e7Schristos 1540*946379e7Schristos<DT>RPMs 1541*946379e7Schristos<DD> 1542*946379e7Schristosguile 1543*946379e7Schristos 1544*946379e7Schristos<DT>File extension 1545*946379e7Schristos<DD> 1546*946379e7Schristos<CODE>scm</CODE> 1547*946379e7Schristos 1548*946379e7Schristos<DT>String syntax 1549*946379e7Schristos<DD> 1550*946379e7Schristos<CODE>"abc"</CODE> 1551*946379e7Schristos 1552*946379e7Schristos<DT>gettext shorthand 1553*946379e7Schristos<DD> 1554*946379e7Schristos<CODE>(_ "abc")</CODE> 1555*946379e7Schristos 1556*946379e7Schristos<DT>gettext/ngettext functions 1557*946379e7Schristos<DD> 1558*946379e7Schristos<CODE>gettext</CODE>, <CODE>ngettext</CODE> 1559*946379e7Schristos 1560*946379e7Schristos<DT>textdomain 1561*946379e7Schristos<DD> 1562*946379e7Schristos<CODE>textdomain</CODE> 1563*946379e7Schristos 1564*946379e7Schristos<DT>bindtextdomain 1565*946379e7Schristos<DD> 1566*946379e7Schristos<CODE>bindtextdomain</CODE> 1567*946379e7Schristos 1568*946379e7Schristos<DT>setlocale 1569*946379e7Schristos<DD> 1570*946379e7Schristos<CODE>(catch #t (lambda () (setlocale LC_ALL "")) (lambda args #f))</CODE> 1571*946379e7Schristos 1572*946379e7Schristos<DT>Prerequisite 1573*946379e7Schristos<DD> 1574*946379e7Schristos<CODE>(use-modules (ice-9 format))</CODE> 1575*946379e7Schristos 1576*946379e7Schristos<DT>Use or emulate GNU gettext 1577*946379e7Schristos<DD> 1578*946379e7Schristosuse 1579*946379e7Schristos 1580*946379e7Schristos<DT>Extractor 1581*946379e7Schristos<DD> 1582*946379e7Schristos<CODE>xgettext -k_</CODE> 1583*946379e7Schristos 1584*946379e7Schristos<DT>Formatting with positions 1585*946379e7Schristos<DD> 1586*946379e7Schristos--- 1587*946379e7Schristos 1588*946379e7Schristos<DT>Portability 1589*946379e7Schristos<DD> 1590*946379e7SchristosOn platforms without gettext, no translation. 1591*946379e7Schristos 1592*946379e7Schristos<DT>po-mode marking 1593*946379e7Schristos<DD> 1594*946379e7Schristos--- 1595*946379e7Schristos</DL> 1596*946379e7Schristos 1597*946379e7Schristos<P> 1598*946379e7SchristosAn example is available in the <TT>‘examples’</TT> directory: <CODE>hello-guile</CODE>. 1599*946379e7Schristos 1600*946379e7Schristos</P> 1601*946379e7Schristos 1602*946379e7Schristos 1603*946379e7Schristos<H3><A NAME="SEC271" HREF="gettext_toc.html#TOC271">15.5.10 GNU Smalltalk</A></H3> 1604*946379e7Schristos<P> 1605*946379e7Schristos<A NAME="IDX1170"></A> 1606*946379e7Schristos 1607*946379e7Schristos</P> 1608*946379e7Schristos<DL COMPACT> 1609*946379e7Schristos 1610*946379e7Schristos<DT>RPMs 1611*946379e7Schristos<DD> 1612*946379e7Schristossmalltalk 1613*946379e7Schristos 1614*946379e7Schristos<DT>File extension 1615*946379e7Schristos<DD> 1616*946379e7Schristos<CODE>st</CODE> 1617*946379e7Schristos 1618*946379e7Schristos<DT>String syntax 1619*946379e7Schristos<DD> 1620*946379e7Schristos<CODE>'abc'</CODE> 1621*946379e7Schristos 1622*946379e7Schristos<DT>gettext shorthand 1623*946379e7Schristos<DD> 1624*946379e7Schristos<CODE>NLS ? 'abc'</CODE> 1625*946379e7Schristos 1626*946379e7Schristos<DT>gettext/ngettext functions 1627*946379e7Schristos<DD> 1628*946379e7Schristos<CODE>LcMessagesDomain>>#at:</CODE>, <CODE>LcMessagesDomain>>#at:plural:with:</CODE> 1629*946379e7Schristos 1630*946379e7Schristos<DT>textdomain 1631*946379e7Schristos<DD> 1632*946379e7Schristos<CODE>LcMessages>>#domain:localeDirectory:</CODE> (returns a <CODE>LcMessagesDomain</CODE> 1633*946379e7Schristosobject).<BR> 1634*946379e7SchristosExample: <CODE>I18N Locale default messages domain: 'gettext' localeDirectory: /usr/local/share/locale'</CODE> 1635*946379e7Schristos 1636*946379e7Schristos<DT>bindtextdomain 1637*946379e7Schristos<DD> 1638*946379e7Schristos<CODE>LcMessages>>#domain:localeDirectory:</CODE>, see above. 1639*946379e7Schristos 1640*946379e7Schristos<DT>setlocale 1641*946379e7Schristos<DD> 1642*946379e7SchristosAutomatic if you use <CODE>I18N Locale default</CODE>. 1643*946379e7Schristos 1644*946379e7Schristos<DT>Prerequisite 1645*946379e7Schristos<DD> 1646*946379e7Schristos<CODE>PackageLoader fileInPackage: 'I18N'!</CODE> 1647*946379e7Schristos 1648*946379e7Schristos<DT>Use or emulate GNU gettext 1649*946379e7Schristos<DD> 1650*946379e7Schristosemulate 1651*946379e7Schristos 1652*946379e7Schristos<DT>Extractor 1653*946379e7Schristos<DD> 1654*946379e7Schristos<CODE>xgettext</CODE> 1655*946379e7Schristos 1656*946379e7Schristos<DT>Formatting with positions 1657*946379e7Schristos<DD> 1658*946379e7Schristos<CODE>'%1 %2' bindWith: 'Hello' with: 'world'</CODE> 1659*946379e7Schristos 1660*946379e7Schristos<DT>Portability 1661*946379e7Schristos<DD> 1662*946379e7Schristosfully portable 1663*946379e7Schristos 1664*946379e7Schristos<DT>po-mode marking 1665*946379e7Schristos<DD> 1666*946379e7Schristos--- 1667*946379e7Schristos</DL> 1668*946379e7Schristos 1669*946379e7Schristos<P> 1670*946379e7SchristosAn example is available in the <TT>‘examples’</TT> directory: 1671*946379e7Schristos<CODE>hello-smalltalk</CODE>. 1672*946379e7Schristos 1673*946379e7Schristos</P> 1674*946379e7Schristos 1675*946379e7Schristos 1676*946379e7Schristos<H3><A NAME="SEC272" HREF="gettext_toc.html#TOC272">15.5.11 Java</A></H3> 1677*946379e7Schristos<P> 1678*946379e7Schristos<A NAME="IDX1171"></A> 1679*946379e7Schristos 1680*946379e7Schristos</P> 1681*946379e7Schristos<DL COMPACT> 1682*946379e7Schristos 1683*946379e7Schristos<DT>RPMs 1684*946379e7Schristos<DD> 1685*946379e7Schristosjava, java2 1686*946379e7Schristos 1687*946379e7Schristos<DT>File extension 1688*946379e7Schristos<DD> 1689*946379e7Schristos<CODE>java</CODE> 1690*946379e7Schristos 1691*946379e7Schristos<DT>String syntax 1692*946379e7Schristos<DD> 1693*946379e7Schristos"abc" 1694*946379e7Schristos 1695*946379e7Schristos<DT>gettext shorthand 1696*946379e7Schristos<DD> 1697*946379e7Schristos_("abc") 1698*946379e7Schristos 1699*946379e7Schristos<DT>gettext/ngettext functions 1700*946379e7Schristos<DD> 1701*946379e7Schristos<CODE>GettextResource.gettext</CODE>, <CODE>GettextResource.ngettext</CODE> 1702*946379e7Schristos 1703*946379e7Schristos<DT>textdomain 1704*946379e7Schristos<DD> 1705*946379e7Schristos---, use <CODE>ResourceBundle.getResource</CODE> instead 1706*946379e7Schristos 1707*946379e7Schristos<DT>bindtextdomain 1708*946379e7Schristos<DD> 1709*946379e7Schristos---, use CLASSPATH instead 1710*946379e7Schristos 1711*946379e7Schristos<DT>setlocale 1712*946379e7Schristos<DD> 1713*946379e7Schristosautomatic 1714*946379e7Schristos 1715*946379e7Schristos<DT>Prerequisite 1716*946379e7Schristos<DD> 1717*946379e7Schristos--- 1718*946379e7Schristos 1719*946379e7Schristos<DT>Use or emulate GNU gettext 1720*946379e7Schristos<DD> 1721*946379e7Schristos---, uses a Java specific message catalog format 1722*946379e7Schristos 1723*946379e7Schristos<DT>Extractor 1724*946379e7Schristos<DD> 1725*946379e7Schristos<CODE>xgettext -k_</CODE> 1726*946379e7Schristos 1727*946379e7Schristos<DT>Formatting with positions 1728*946379e7Schristos<DD> 1729*946379e7Schristos<CODE>MessageFormat.format "{1,number} {0,number}"</CODE> 1730*946379e7Schristos 1731*946379e7Schristos<DT>Portability 1732*946379e7Schristos<DD> 1733*946379e7Schristosfully portable 1734*946379e7Schristos 1735*946379e7Schristos<DT>po-mode marking 1736*946379e7Schristos<DD> 1737*946379e7Schristos--- 1738*946379e7Schristos</DL> 1739*946379e7Schristos 1740*946379e7Schristos<P> 1741*946379e7SchristosBefore marking strings as internationalizable, uses of the string 1742*946379e7Schristosconcatenation operator need to be converted to <CODE>MessageFormat</CODE> 1743*946379e7Schristosapplications. For example, <CODE>"file "+filename+" not found"</CODE> becomes 1744*946379e7Schristos<CODE>MessageFormat.format("file {0} not found", new Object[] { filename })</CODE>. 1745*946379e7SchristosOnly after this is done, can the strings be marked and extracted. 1746*946379e7Schristos 1747*946379e7Schristos</P> 1748*946379e7Schristos<P> 1749*946379e7SchristosGNU gettext uses the native Java internationalization mechanism, namely 1750*946379e7Schristos<CODE>ResourceBundle</CODE>s. There are two formats of <CODE>ResourceBundle</CODE>s: 1751*946379e7Schristos<CODE>.properties</CODE> files and <CODE>.class</CODE> files. The <CODE>.properties</CODE> 1752*946379e7Schristosformat is a text file which the translators can directly edit, like PO 1753*946379e7Schristosfiles, but which doesn't support plural forms. Whereas the <CODE>.class</CODE> 1754*946379e7Schristosformat is compiled from <CODE>.java</CODE> source code and can support plural 1755*946379e7Schristosforms (provided it is accessed through an appropriate API, see below). 1756*946379e7Schristos 1757*946379e7Schristos</P> 1758*946379e7Schristos<P> 1759*946379e7SchristosTo convert a PO file to a <CODE>.properties</CODE> file, the <CODE>msgcat</CODE> 1760*946379e7Schristosprogram can be used with the option <CODE>--properties-output</CODE>. To convert 1761*946379e7Schristosa <CODE>.properties</CODE> file back to a PO file, the <CODE>msgcat</CODE> program 1762*946379e7Schristoscan be used with the option <CODE>--properties-input</CODE>. All the tools 1763*946379e7Schristosthat manipulate PO files can work with <CODE>.properties</CODE> files as well, 1764*946379e7Schristosif given the <CODE>--properties-input</CODE> and/or <CODE>--properties-output</CODE> 1765*946379e7Schristosoption. 1766*946379e7Schristos 1767*946379e7Schristos</P> 1768*946379e7Schristos<P> 1769*946379e7SchristosTo convert a PO file to a ResourceBundle class, the <CODE>msgfmt</CODE> program 1770*946379e7Schristoscan be used with the option <CODE>--java</CODE> or <CODE>--java2</CODE>. To convert a 1771*946379e7SchristosResourceBundle back to a PO file, the <CODE>msgunfmt</CODE> program can be used 1772*946379e7Schristoswith the option <CODE>--java</CODE>. 1773*946379e7Schristos 1774*946379e7Schristos</P> 1775*946379e7Schristos<P> 1776*946379e7SchristosTwo different programmatic APIs can be used to access ResourceBundles. 1777*946379e7SchristosNote that both APIs work with all kinds of ResourceBundles, whether 1778*946379e7SchristosGNU gettext generated classes, or other <CODE>.class</CODE> or <CODE>.properties</CODE> 1779*946379e7Schristosfiles. 1780*946379e7Schristos 1781*946379e7Schristos</P> 1782*946379e7Schristos 1783*946379e7Schristos<OL> 1784*946379e7Schristos<LI> 1785*946379e7Schristos 1786*946379e7SchristosThe <CODE>java.util.ResourceBundle</CODE> API. 1787*946379e7Schristos 1788*946379e7SchristosIn particular, its <CODE>getString</CODE> function returns a string translation. 1789*946379e7SchristosNote that a missing translation yields a <CODE>MissingResourceException</CODE>. 1790*946379e7Schristos 1791*946379e7SchristosThis has the advantage of being the standard API. And it does not require 1792*946379e7Schristosany additional libraries, only the <CODE>msgcat</CODE> generated <CODE>.properties</CODE> 1793*946379e7Schristosfiles or the <CODE>msgfmt</CODE> generated <CODE>.class</CODE> files. But it cannot do 1794*946379e7Schristosplural handling, even if the resource was generated by <CODE>msgfmt</CODE> from 1795*946379e7Schristosa PO file with plural handling. 1796*946379e7Schristos 1797*946379e7Schristos<LI> 1798*946379e7Schristos 1799*946379e7SchristosThe <CODE>gnu.gettext.GettextResource</CODE> API. 1800*946379e7Schristos 1801*946379e7SchristosReference documentation in Javadoc 1.1 style format 1802*946379e7Schristosis in the <A HREF="javadoc1/tree.html">javadoc1 directory</A> and 1803*946379e7Schristosin Javadoc 2 style format 1804*946379e7Schristosin the <A HREF="javadoc2/index.html">javadoc2 directory</A>. 1805*946379e7Schristos 1806*946379e7SchristosIts <CODE>gettext</CODE> function returns a string translation. Note that when 1807*946379e7Schristosa translation is missing, the <VAR>msgid</VAR> argument is returned unchanged. 1808*946379e7Schristos 1809*946379e7SchristosThis has the advantage of having the <CODE>ngettext</CODE> function for plural 1810*946379e7Schristoshandling. 1811*946379e7Schristos 1812*946379e7Schristos<A NAME="IDX1172"></A> 1813*946379e7SchristosTo use this API, one needs the <CODE>libintl.jar</CODE> file which is part of 1814*946379e7Schristosthe GNU gettext package and distributed under the LGPL. 1815*946379e7Schristos</OL> 1816*946379e7Schristos 1817*946379e7Schristos<P> 1818*946379e7SchristosThree examples, using the second API, are available in the <TT>‘examples’</TT> 1819*946379e7Schristosdirectory: <CODE>hello-java</CODE>, <CODE>hello-java-awt</CODE>, <CODE>hello-java-swing</CODE>. 1820*946379e7Schristos 1821*946379e7Schristos</P> 1822*946379e7Schristos<P> 1823*946379e7SchristosNow, to make use of the API and define a shorthand for <SAMP>‘getString’</SAMP>, 1824*946379e7Schristosthere are three idioms that you can choose from: 1825*946379e7Schristos 1826*946379e7Schristos</P> 1827*946379e7Schristos 1828*946379e7Schristos<UL> 1829*946379e7Schristos<LI> 1830*946379e7Schristos 1831*946379e7Schristos(This one assumes Java 1.5 or newer.) 1832*946379e7SchristosIn a unique class of your project, say <SAMP>‘Util’</SAMP>, define a static variable 1833*946379e7Schristosholding the <CODE>ResourceBundle</CODE> instance and the shorthand: 1834*946379e7Schristos 1835*946379e7Schristos 1836*946379e7Schristos<PRE> 1837*946379e7Schristosprivate static ResourceBundle myResources = 1838*946379e7Schristos ResourceBundle.getBundle("domain-name"); 1839*946379e7Schristospublic static String _(String s) { 1840*946379e7Schristos return myResources.getString(s); 1841*946379e7Schristos} 1842*946379e7Schristos</PRE> 1843*946379e7Schristos 1844*946379e7SchristosAll classes containing internationalized strings then contain 1845*946379e7Schristos 1846*946379e7Schristos 1847*946379e7Schristos<PRE> 1848*946379e7Schristosimport static Util._; 1849*946379e7Schristos</PRE> 1850*946379e7Schristos 1851*946379e7Schristosand the shorthand is used like this: 1852*946379e7Schristos 1853*946379e7Schristos 1854*946379e7Schristos<PRE> 1855*946379e7SchristosSystem.out.println(_("Operation completed.")); 1856*946379e7Schristos</PRE> 1857*946379e7Schristos 1858*946379e7Schristos<LI> 1859*946379e7Schristos 1860*946379e7SchristosIn a unique class of your project, say <SAMP>‘Util’</SAMP>, define a static variable 1861*946379e7Schristosholding the <CODE>ResourceBundle</CODE> instance: 1862*946379e7Schristos 1863*946379e7Schristos 1864*946379e7Schristos<PRE> 1865*946379e7Schristospublic static ResourceBundle myResources = 1866*946379e7Schristos ResourceBundle.getBundle("domain-name"); 1867*946379e7Schristos</PRE> 1868*946379e7Schristos 1869*946379e7SchristosAll classes containing internationalized strings then contain 1870*946379e7Schristos 1871*946379e7Schristos 1872*946379e7Schristos<PRE> 1873*946379e7Schristosprivate static ResourceBundle res = Util.myResources; 1874*946379e7Schristosprivate static String _(String s) { return res.getString(s); } 1875*946379e7Schristos</PRE> 1876*946379e7Schristos 1877*946379e7Schristosand the shorthand is used like this: 1878*946379e7Schristos 1879*946379e7Schristos 1880*946379e7Schristos<PRE> 1881*946379e7SchristosSystem.out.println(_("Operation completed.")); 1882*946379e7Schristos</PRE> 1883*946379e7Schristos 1884*946379e7Schristos<LI> 1885*946379e7Schristos 1886*946379e7SchristosYou add a class with a very short name, say <SAMP>‘S’</SAMP>, containing just the 1887*946379e7Schristosdefinition of the resource bundle and of the shorthand: 1888*946379e7Schristos 1889*946379e7Schristos 1890*946379e7Schristos<PRE> 1891*946379e7Schristospublic class S { 1892*946379e7Schristos public static ResourceBundle myResources = 1893*946379e7Schristos ResourceBundle.getBundle("domain-name"); 1894*946379e7Schristos public static String _(String s) { 1895*946379e7Schristos return myResources.getString(s); 1896*946379e7Schristos } 1897*946379e7Schristos} 1898*946379e7Schristos</PRE> 1899*946379e7Schristos 1900*946379e7Schristosand the shorthand is used like this: 1901*946379e7Schristos 1902*946379e7Schristos 1903*946379e7Schristos<PRE> 1904*946379e7SchristosSystem.out.println(S._("Operation completed.")); 1905*946379e7Schristos</PRE> 1906*946379e7Schristos 1907*946379e7Schristos</UL> 1908*946379e7Schristos 1909*946379e7Schristos<P> 1910*946379e7SchristosWhich of the three idioms you choose, will depend on whether your project 1911*946379e7Schristosrequires portability to Java versions prior to Java 1.5 and, if so, whether 1912*946379e7Schristoscopying two lines of codes into every class is more acceptable in your project 1913*946379e7Schristosthan a class with a single-letter name. 1914*946379e7Schristos 1915*946379e7Schristos</P> 1916*946379e7Schristos 1917*946379e7Schristos 1918*946379e7Schristos<H3><A NAME="SEC273" HREF="gettext_toc.html#TOC273">15.5.12 C#</A></H3> 1919*946379e7Schristos<P> 1920*946379e7Schristos<A NAME="IDX1173"></A> 1921*946379e7Schristos 1922*946379e7Schristos</P> 1923*946379e7Schristos<DL COMPACT> 1924*946379e7Schristos 1925*946379e7Schristos<DT>RPMs 1926*946379e7Schristos<DD> 1927*946379e7Schristospnet, pnetlib 0.6.2 or newer, or mono 0.29 or newer 1928*946379e7Schristos 1929*946379e7Schristos<DT>File extension 1930*946379e7Schristos<DD> 1931*946379e7Schristos<CODE>cs</CODE> 1932*946379e7Schristos 1933*946379e7Schristos<DT>String syntax 1934*946379e7Schristos<DD> 1935*946379e7Schristos<CODE>"abc"</CODE>, <CODE>@"abc"</CODE> 1936*946379e7Schristos 1937*946379e7Schristos<DT>gettext shorthand 1938*946379e7Schristos<DD> 1939*946379e7Schristos_("abc") 1940*946379e7Schristos 1941*946379e7Schristos<DT>gettext/ngettext functions 1942*946379e7Schristos<DD> 1943*946379e7Schristos<CODE>GettextResourceManager.GetString</CODE>, 1944*946379e7Schristos<CODE>GettextResourceManager.GetPluralString</CODE> 1945*946379e7Schristos 1946*946379e7Schristos<DT>textdomain 1947*946379e7Schristos<DD> 1948*946379e7Schristos<CODE>new GettextResourceManager(domain)</CODE> 1949*946379e7Schristos 1950*946379e7Schristos<DT>bindtextdomain 1951*946379e7Schristos<DD> 1952*946379e7Schristos---, compiled message catalogs are located in subdirectories of the directory 1953*946379e7Schristoscontaining the executable 1954*946379e7Schristos 1955*946379e7Schristos<DT>setlocale 1956*946379e7Schristos<DD> 1957*946379e7Schristosautomatic 1958*946379e7Schristos 1959*946379e7Schristos<DT>Prerequisite 1960*946379e7Schristos<DD> 1961*946379e7Schristos--- 1962*946379e7Schristos 1963*946379e7Schristos<DT>Use or emulate GNU gettext 1964*946379e7Schristos<DD> 1965*946379e7Schristos---, uses a C# specific message catalog format 1966*946379e7Schristos 1967*946379e7Schristos<DT>Extractor 1968*946379e7Schristos<DD> 1969*946379e7Schristos<CODE>xgettext -k_</CODE> 1970*946379e7Schristos 1971*946379e7Schristos<DT>Formatting with positions 1972*946379e7Schristos<DD> 1973*946379e7Schristos<CODE>String.Format "{1} {0}"</CODE> 1974*946379e7Schristos 1975*946379e7Schristos<DT>Portability 1976*946379e7Schristos<DD> 1977*946379e7Schristosfully portable 1978*946379e7Schristos 1979*946379e7Schristos<DT>po-mode marking 1980*946379e7Schristos<DD> 1981*946379e7Schristos--- 1982*946379e7Schristos</DL> 1983*946379e7Schristos 1984*946379e7Schristos<P> 1985*946379e7SchristosBefore marking strings as internationalizable, uses of the string 1986*946379e7Schristosconcatenation operator need to be converted to <CODE>String.Format</CODE> 1987*946379e7Schristosinvocations. For example, <CODE>"file "+filename+" not found"</CODE> becomes 1988*946379e7Schristos<CODE>String.Format("file {0} not found", filename)</CODE>. 1989*946379e7SchristosOnly after this is done, can the strings be marked and extracted. 1990*946379e7Schristos 1991*946379e7Schristos</P> 1992*946379e7Schristos<P> 1993*946379e7SchristosGNU gettext uses the native C#/.NET internationalization mechanism, namely 1994*946379e7Schristosthe classes <CODE>ResourceManager</CODE> and <CODE>ResourceSet</CODE>. Applications 1995*946379e7Schristosuse the <CODE>ResourceManager</CODE> methods to retrieve the native language 1996*946379e7Schristostranslation of strings. An instance of <CODE>ResourceSet</CODE> is the in-memory 1997*946379e7Schristosrepresentation of a message catalog file. The <CODE>ResourceManager</CODE> loads 1998*946379e7Schristosand accesses <CODE>ResourceSet</CODE> instances as needed to look up the 1999*946379e7Schristostranslations. 2000*946379e7Schristos 2001*946379e7Schristos</P> 2002*946379e7Schristos<P> 2003*946379e7SchristosThere are two formats of <CODE>ResourceSet</CODE>s that can be directly loaded by 2004*946379e7Schristosthe C# runtime: <CODE>.resources</CODE> files and <CODE>.dll</CODE> files. 2005*946379e7Schristos 2006*946379e7Schristos</P> 2007*946379e7Schristos 2008*946379e7Schristos<UL> 2009*946379e7Schristos<LI> 2010*946379e7Schristos 2011*946379e7SchristosThe <CODE>.resources</CODE> format is a binary file usually generated through the 2012*946379e7Schristos<CODE>resgen</CODE> or <CODE>monoresgen</CODE> utility, but which doesn't support plural 2013*946379e7Schristosforms. <CODE>.resources</CODE> files can also be embedded in .NET <CODE>.exe</CODE> files. 2014*946379e7SchristosThis only affects whether a file system access is performed to load the message 2015*946379e7Schristoscatalog; it doesn't affect the contents of the message catalog. 2016*946379e7Schristos 2017*946379e7Schristos<LI> 2018*946379e7Schristos 2019*946379e7SchristosOn the other hand, the <CODE>.dll</CODE> format is a binary file that is compiled 2020*946379e7Schristosfrom <CODE>.cs</CODE> source code and can support plural forms (provided it is 2021*946379e7Schristosaccessed through the GNU gettext API, see below). 2022*946379e7Schristos</UL> 2023*946379e7Schristos 2024*946379e7Schristos<P> 2025*946379e7SchristosNote that these .NET <CODE>.dll</CODE> and <CODE>.exe</CODE> files are not tied to a 2026*946379e7Schristosparticular platform; their file format and GNU gettext for C# can be used 2027*946379e7Schristoson any platform. 2028*946379e7Schristos 2029*946379e7Schristos</P> 2030*946379e7Schristos<P> 2031*946379e7SchristosTo convert a PO file to a <CODE>.resources</CODE> file, the <CODE>msgfmt</CODE> program 2032*946379e7Schristoscan be used with the option <SAMP>‘--csharp-resources’</SAMP>. To convert a 2033*946379e7Schristos<CODE>.resources</CODE> file back to a PO file, the <CODE>msgunfmt</CODE> program can be 2034*946379e7Schristosused with the option <SAMP>‘--csharp-resources’</SAMP>. You can also, in some cases, 2035*946379e7Schristosuse the <CODE>resgen</CODE> program (from the <CODE>pnet</CODE> package) or the 2036*946379e7Schristos<CODE>monoresgen</CODE> program (from the <CODE>mono</CODE>/<CODE>mcs</CODE> package). These 2037*946379e7Schristosprograms can also convert a <CODE>.resources</CODE> file back to a PO file. But 2038*946379e7Schristosbeware: as of this writing (January 2004), the <CODE>monoresgen</CODE> converter is 2039*946379e7Schristosquite buggy and the <CODE>resgen</CODE> converter ignores the encoding of the PO 2040*946379e7Schristosfiles. 2041*946379e7Schristos 2042*946379e7Schristos</P> 2043*946379e7Schristos<P> 2044*946379e7SchristosTo convert a PO file to a <CODE>.dll</CODE> file, the <CODE>msgfmt</CODE> program can be 2045*946379e7Schristosused with the option <CODE>--csharp</CODE>. The result will be a <CODE>.dll</CODE> file 2046*946379e7Schristoscontaining a subclass of <CODE>GettextResourceSet</CODE>, which itself is a subclass 2047*946379e7Schristosof <CODE>ResourceSet</CODE>. To convert a <CODE>.dll</CODE> file containing a 2048*946379e7Schristos<CODE>GettextResourceSet</CODE> subclass back to a PO file, the <CODE>msgunfmt</CODE> 2049*946379e7Schristosprogram can be used with the option <CODE>--csharp</CODE>. 2050*946379e7Schristos 2051*946379e7Schristos</P> 2052*946379e7Schristos<P> 2053*946379e7SchristosThe advantages of the <CODE>.dll</CODE> format over the <CODE>.resources</CODE> format 2054*946379e7Schristosare: 2055*946379e7Schristos 2056*946379e7Schristos</P> 2057*946379e7Schristos 2058*946379e7Schristos<OL> 2059*946379e7Schristos<LI> 2060*946379e7Schristos 2061*946379e7SchristosFreedom to localize: Users can add their own translations to an application 2062*946379e7Schristosafter it has been built and distributed. Whereas when the programmer uses 2063*946379e7Schristosa <CODE>ResourceManager</CODE> constructor provided by the system, the set of 2064*946379e7Schristos<CODE>.resources</CODE> files for an application must be specified when the 2065*946379e7Schristosapplication is built and cannot be extended afterwards. 2066*946379e7Schristos 2067*946379e7Schristos<LI> 2068*946379e7Schristos 2069*946379e7SchristosPlural handling: A message catalog in <CODE>.dll</CODE> format supports the plural 2070*946379e7Schristoshandling function <CODE>GetPluralString</CODE>. Whereas <CODE>.resources</CODE> files can 2071*946379e7Schristosonly contain data and only support lookups that depend on a single string. 2072*946379e7Schristos 2073*946379e7Schristos<LI> 2074*946379e7Schristos 2075*946379e7SchristosThe <CODE>GettextResourceManager</CODE> that loads the message catalogs in 2076*946379e7Schristos<CODE>.dll</CODE> format also provides for inheritance on a per-message basis. 2077*946379e7SchristosFor example, in Austrian (<CODE>de_AT</CODE>) locale, translations from the German 2078*946379e7Schristos(<CODE>de</CODE>) message catalog will be used for messages not found in the 2079*946379e7SchristosAustrian message catalog. This has the consequence that the Austrian 2080*946379e7Schristostranslators need only translate those few messages for which the translation 2081*946379e7Schristosinto Austrian differs from the German one. Whereas when working with 2082*946379e7Schristos<CODE>.resources</CODE> files, each message catalog must provide the translations 2083*946379e7Schristosof all messages by itself. 2084*946379e7Schristos 2085*946379e7Schristos<LI> 2086*946379e7Schristos 2087*946379e7SchristosThe <CODE>GettextResourceManager</CODE> that loads the message catalogs in 2088*946379e7Schristos<CODE>.dll</CODE> format also provides for a fallback: The English <VAR>msgid</VAR> is 2089*946379e7Schristosreturned when no translation can be found. Whereas when working with 2090*946379e7Schristos<CODE>.resources</CODE> files, a language-neutral <CODE>.resources</CODE> file must 2091*946379e7Schristosexplicitly be provided as a fallback. 2092*946379e7Schristos</OL> 2093*946379e7Schristos 2094*946379e7Schristos<P> 2095*946379e7SchristosOn the side of the programmatic APIs, the programmer can use either the 2096*946379e7Schristosstandard <CODE>ResourceManager</CODE> API and the GNU <CODE>GettextResourceManager</CODE> 2097*946379e7SchristosAPI. The latter is an extension of the former, because 2098*946379e7Schristos<CODE>GettextResourceManager</CODE> is a subclass of <CODE>ResourceManager</CODE>. 2099*946379e7Schristos 2100*946379e7Schristos</P> 2101*946379e7Schristos 2102*946379e7Schristos<OL> 2103*946379e7Schristos<LI> 2104*946379e7Schristos 2105*946379e7SchristosThe <CODE>System.Resources.ResourceManager</CODE> API. 2106*946379e7Schristos 2107*946379e7SchristosThis API works with resources in <CODE>.resources</CODE> format. 2108*946379e7Schristos 2109*946379e7SchristosThe creation of the <CODE>ResourceManager</CODE> is done through 2110*946379e7Schristos 2111*946379e7Schristos<PRE> 2112*946379e7Schristos new ResourceManager(domainname, Assembly.GetExecutingAssembly()) 2113*946379e7Schristos</PRE> 2114*946379e7Schristos 2115*946379e7Schristos 2116*946379e7SchristosThe <CODE>GetString</CODE> function returns a string's translation. Note that this 2117*946379e7Schristosfunction returns null when a translation is missing (i.e. not even found in 2118*946379e7Schristosthe fallback resource file). 2119*946379e7Schristos 2120*946379e7Schristos<LI> 2121*946379e7Schristos 2122*946379e7SchristosThe <CODE>GNU.Gettext.GettextResourceManager</CODE> API. 2123*946379e7Schristos 2124*946379e7SchristosThis API works with resources in <CODE>.dll</CODE> format. 2125*946379e7Schristos 2126*946379e7SchristosReference documentation is in the 2127*946379e7Schristos<A HREF="csharpdoc/index.html">csharpdoc directory</A>. 2128*946379e7Schristos 2129*946379e7SchristosThe creation of the <CODE>ResourceManager</CODE> is done through 2130*946379e7Schristos 2131*946379e7Schristos<PRE> 2132*946379e7Schristos new GettextResourceManager(domainname) 2133*946379e7Schristos</PRE> 2134*946379e7Schristos 2135*946379e7SchristosThe <CODE>GetString</CODE> function returns a string's translation. Note that when 2136*946379e7Schristosa translation is missing, the <VAR>msgid</VAR> argument is returned unchanged. 2137*946379e7Schristos 2138*946379e7SchristosThe <CODE>GetPluralString</CODE> function returns a string translation with plural 2139*946379e7Schristoshandling, like the <CODE>ngettext</CODE> function in C. 2140*946379e7Schristos 2141*946379e7Schristos<A NAME="IDX1174"></A> 2142*946379e7SchristosTo use this API, one needs the <CODE>GNU.Gettext.dll</CODE> file which is part of 2143*946379e7Schristosthe GNU gettext package and distributed under the LGPL. 2144*946379e7Schristos</OL> 2145*946379e7Schristos 2146*946379e7Schristos<P> 2147*946379e7SchristosYou can also mix both approaches: use the 2148*946379e7Schristos<CODE>GNU.Gettext.GettextResourceManager</CODE> constructor, but otherwise use 2149*946379e7Schristosonly the <CODE>ResourceManager</CODE> type and only the <CODE>GetString</CODE> method. 2150*946379e7SchristosThis is appropriate when you want to profit from the tools for PO files, 2151*946379e7Schristosbut don't want to change an existing source code that uses 2152*946379e7Schristos<CODE>ResourceManager</CODE> and don't (yet) need the <CODE>GetPluralString</CODE> method. 2153*946379e7Schristos 2154*946379e7Schristos</P> 2155*946379e7Schristos<P> 2156*946379e7SchristosTwo examples, using the second API, are available in the <TT>‘examples’</TT> 2157*946379e7Schristosdirectory: <CODE>hello-csharp</CODE>, <CODE>hello-csharp-forms</CODE>. 2158*946379e7Schristos 2159*946379e7Schristos</P> 2160*946379e7Schristos<P> 2161*946379e7SchristosNow, to make use of the API and define a shorthand for <SAMP>‘GetString’</SAMP>, 2162*946379e7Schristosthere are two idioms that you can choose from: 2163*946379e7Schristos 2164*946379e7Schristos</P> 2165*946379e7Schristos 2166*946379e7Schristos<UL> 2167*946379e7Schristos<LI> 2168*946379e7Schristos 2169*946379e7SchristosIn a unique class of your project, say <SAMP>‘Util’</SAMP>, define a static variable 2170*946379e7Schristosholding the <CODE>ResourceManager</CODE> instance: 2171*946379e7Schristos 2172*946379e7Schristos 2173*946379e7Schristos<PRE> 2174*946379e7Schristospublic static GettextResourceManager MyResourceManager = 2175*946379e7Schristos new GettextResourceManager("domain-name"); 2176*946379e7Schristos</PRE> 2177*946379e7Schristos 2178*946379e7SchristosAll classes containing internationalized strings then contain 2179*946379e7Schristos 2180*946379e7Schristos 2181*946379e7Schristos<PRE> 2182*946379e7Schristosprivate static GettextResourceManager Res = Util.MyResourceManager; 2183*946379e7Schristosprivate static String _(String s) { return Res.GetString(s); } 2184*946379e7Schristos</PRE> 2185*946379e7Schristos 2186*946379e7Schristosand the shorthand is used like this: 2187*946379e7Schristos 2188*946379e7Schristos 2189*946379e7Schristos<PRE> 2190*946379e7SchristosConsole.WriteLine(_("Operation completed.")); 2191*946379e7Schristos</PRE> 2192*946379e7Schristos 2193*946379e7Schristos<LI> 2194*946379e7Schristos 2195*946379e7SchristosYou add a class with a very short name, say <SAMP>‘S’</SAMP>, containing just the 2196*946379e7Schristosdefinition of the resource manager and of the shorthand: 2197*946379e7Schristos 2198*946379e7Schristos 2199*946379e7Schristos<PRE> 2200*946379e7Schristospublic class S { 2201*946379e7Schristos public static GettextResourceManager MyResourceManager = 2202*946379e7Schristos new GettextResourceManager("domain-name"); 2203*946379e7Schristos public static String _(String s) { 2204*946379e7Schristos return MyResourceManager.GetString(s); 2205*946379e7Schristos } 2206*946379e7Schristos} 2207*946379e7Schristos</PRE> 2208*946379e7Schristos 2209*946379e7Schristosand the shorthand is used like this: 2210*946379e7Schristos 2211*946379e7Schristos 2212*946379e7Schristos<PRE> 2213*946379e7SchristosConsole.WriteLine(S._("Operation completed.")); 2214*946379e7Schristos</PRE> 2215*946379e7Schristos 2216*946379e7Schristos</UL> 2217*946379e7Schristos 2218*946379e7Schristos<P> 2219*946379e7SchristosWhich of the two idioms you choose, will depend on whether copying two lines 2220*946379e7Schristosof codes into every class is more acceptable in your project than a class 2221*946379e7Schristoswith a single-letter name. 2222*946379e7Schristos 2223*946379e7Schristos</P> 2224*946379e7Schristos 2225*946379e7Schristos 2226*946379e7Schristos<H3><A NAME="SEC274" HREF="gettext_toc.html#TOC274">15.5.13 GNU awk</A></H3> 2227*946379e7Schristos<P> 2228*946379e7Schristos<A NAME="IDX1175"></A> 2229*946379e7Schristos<A NAME="IDX1176"></A> 2230*946379e7Schristos 2231*946379e7Schristos</P> 2232*946379e7Schristos<DL COMPACT> 2233*946379e7Schristos 2234*946379e7Schristos<DT>RPMs 2235*946379e7Schristos<DD> 2236*946379e7Schristosgawk 3.1 or newer 2237*946379e7Schristos 2238*946379e7Schristos<DT>File extension 2239*946379e7Schristos<DD> 2240*946379e7Schristos<CODE>awk</CODE> 2241*946379e7Schristos 2242*946379e7Schristos<DT>String syntax 2243*946379e7Schristos<DD> 2244*946379e7Schristos<CODE>"abc"</CODE> 2245*946379e7Schristos 2246*946379e7Schristos<DT>gettext shorthand 2247*946379e7Schristos<DD> 2248*946379e7Schristos<CODE>_"abc"</CODE> 2249*946379e7Schristos 2250*946379e7Schristos<DT>gettext/ngettext functions 2251*946379e7Schristos<DD> 2252*946379e7Schristos<CODE>dcgettext</CODE>, missing <CODE>dcngettext</CODE> in gawk-3.1.0 2253*946379e7Schristos 2254*946379e7Schristos<DT>textdomain 2255*946379e7Schristos<DD> 2256*946379e7Schristos<CODE>TEXTDOMAIN</CODE> variable 2257*946379e7Schristos 2258*946379e7Schristos<DT>bindtextdomain 2259*946379e7Schristos<DD> 2260*946379e7Schristos<CODE>bindtextdomain</CODE> function 2261*946379e7Schristos 2262*946379e7Schristos<DT>setlocale 2263*946379e7Schristos<DD> 2264*946379e7Schristosautomatic, but missing <CODE>setlocale (LC_MESSAGES, "")</CODE> in gawk-3.1.0 2265*946379e7Schristos 2266*946379e7Schristos<DT>Prerequisite 2267*946379e7Schristos<DD> 2268*946379e7Schristos--- 2269*946379e7Schristos 2270*946379e7Schristos<DT>Use or emulate GNU gettext 2271*946379e7Schristos<DD> 2272*946379e7Schristosuse 2273*946379e7Schristos 2274*946379e7Schristos<DT>Extractor 2275*946379e7Schristos<DD> 2276*946379e7Schristos<CODE>xgettext</CODE> 2277*946379e7Schristos 2278*946379e7Schristos<DT>Formatting with positions 2279*946379e7Schristos<DD> 2280*946379e7Schristos<CODE>printf "%2$d %1$d"</CODE> (GNU awk only) 2281*946379e7Schristos 2282*946379e7Schristos<DT>Portability 2283*946379e7Schristos<DD> 2284*946379e7SchristosOn platforms without gettext, no translation. On non-GNU awks, you must 2285*946379e7Schristosdefine <CODE>dcgettext</CODE>, <CODE>dcngettext</CODE> and <CODE>bindtextdomain</CODE> 2286*946379e7Schristosyourself. 2287*946379e7Schristos 2288*946379e7Schristos<DT>po-mode marking 2289*946379e7Schristos<DD> 2290*946379e7Schristos--- 2291*946379e7Schristos</DL> 2292*946379e7Schristos 2293*946379e7Schristos<P> 2294*946379e7SchristosAn example is available in the <TT>‘examples’</TT> directory: <CODE>hello-gawk</CODE>. 2295*946379e7Schristos 2296*946379e7Schristos</P> 2297*946379e7Schristos 2298*946379e7Schristos 2299*946379e7Schristos<H3><A NAME="SEC275" HREF="gettext_toc.html#TOC275">15.5.14 Pascal - Free Pascal Compiler</A></H3> 2300*946379e7Schristos<P> 2301*946379e7Schristos<A NAME="IDX1177"></A> 2302*946379e7Schristos<A NAME="IDX1178"></A> 2303*946379e7Schristos<A NAME="IDX1179"></A> 2304*946379e7Schristos 2305*946379e7Schristos</P> 2306*946379e7Schristos<DL COMPACT> 2307*946379e7Schristos 2308*946379e7Schristos<DT>RPMs 2309*946379e7Schristos<DD> 2310*946379e7Schristosfpk 2311*946379e7Schristos 2312*946379e7Schristos<DT>File extension 2313*946379e7Schristos<DD> 2314*946379e7Schristos<CODE>pp</CODE>, <CODE>pas</CODE> 2315*946379e7Schristos 2316*946379e7Schristos<DT>String syntax 2317*946379e7Schristos<DD> 2318*946379e7Schristos<CODE>'abc'</CODE> 2319*946379e7Schristos 2320*946379e7Schristos<DT>gettext shorthand 2321*946379e7Schristos<DD> 2322*946379e7Schristosautomatic 2323*946379e7Schristos 2324*946379e7Schristos<DT>gettext/ngettext functions 2325*946379e7Schristos<DD> 2326*946379e7Schristos---, use <CODE>ResourceString</CODE> data type instead 2327*946379e7Schristos 2328*946379e7Schristos<DT>textdomain 2329*946379e7Schristos<DD> 2330*946379e7Schristos---, use <CODE>TranslateResourceStrings</CODE> function instead 2331*946379e7Schristos 2332*946379e7Schristos<DT>bindtextdomain 2333*946379e7Schristos<DD> 2334*946379e7Schristos---, use <CODE>TranslateResourceStrings</CODE> function instead 2335*946379e7Schristos 2336*946379e7Schristos<DT>setlocale 2337*946379e7Schristos<DD> 2338*946379e7Schristosautomatic, but uses only LANG, not LC_MESSAGES or LC_ALL 2339*946379e7Schristos 2340*946379e7Schristos<DT>Prerequisite 2341*946379e7Schristos<DD> 2342*946379e7Schristos<CODE>{$mode delphi}</CODE> or <CODE>{$mode objfpc}</CODE><BR><CODE>uses gettext;</CODE> 2343*946379e7Schristos 2344*946379e7Schristos<DT>Use or emulate GNU gettext 2345*946379e7Schristos<DD> 2346*946379e7Schristosemulate partially 2347*946379e7Schristos 2348*946379e7Schristos<DT>Extractor 2349*946379e7Schristos<DD> 2350*946379e7Schristos<CODE>ppc386</CODE> followed by <CODE>xgettext</CODE> or <CODE>rstconv</CODE> 2351*946379e7Schristos 2352*946379e7Schristos<DT>Formatting with positions 2353*946379e7Schristos<DD> 2354*946379e7Schristos<CODE>uses sysutils;</CODE><BR><CODE>format "%1:d %0:d"</CODE> 2355*946379e7Schristos 2356*946379e7Schristos<DT>Portability 2357*946379e7Schristos<DD> 2358*946379e7Schristos? 2359*946379e7Schristos 2360*946379e7Schristos<DT>po-mode marking 2361*946379e7Schristos<DD> 2362*946379e7Schristos--- 2363*946379e7Schristos</DL> 2364*946379e7Schristos 2365*946379e7Schristos<P> 2366*946379e7SchristosThe Pascal compiler has special support for the <CODE>ResourceString</CODE> data 2367*946379e7Schristostype. It generates a <CODE>.rst</CODE> file. This is then converted to a 2368*946379e7Schristos<CODE>.pot</CODE> file by use of <CODE>xgettext</CODE> or <CODE>rstconv</CODE>. At runtime, 2369*946379e7Schristosa <CODE>.mo</CODE> file corresponding to translations of this <CODE>.pot</CODE> file 2370*946379e7Schristoscan be loaded using the <CODE>TranslateResourceStrings</CODE> function in the 2371*946379e7Schristos<CODE>gettext</CODE> unit. 2372*946379e7Schristos 2373*946379e7Schristos</P> 2374*946379e7Schristos<P> 2375*946379e7SchristosAn example is available in the <TT>‘examples’</TT> directory: <CODE>hello-pascal</CODE>. 2376*946379e7Schristos 2377*946379e7Schristos</P> 2378*946379e7Schristos 2379*946379e7Schristos 2380*946379e7Schristos<H3><A NAME="SEC276" HREF="gettext_toc.html#TOC276">15.5.15 wxWidgets library</A></H3> 2381*946379e7Schristos<P> 2382*946379e7Schristos<A NAME="IDX1180"></A> 2383*946379e7Schristos 2384*946379e7Schristos</P> 2385*946379e7Schristos<DL COMPACT> 2386*946379e7Schristos 2387*946379e7Schristos<DT>RPMs 2388*946379e7Schristos<DD> 2389*946379e7SchristoswxGTK, gettext 2390*946379e7Schristos 2391*946379e7Schristos<DT>File extension 2392*946379e7Schristos<DD> 2393*946379e7Schristos<CODE>cpp</CODE> 2394*946379e7Schristos 2395*946379e7Schristos<DT>String syntax 2396*946379e7Schristos<DD> 2397*946379e7Schristos<CODE>"abc"</CODE> 2398*946379e7Schristos 2399*946379e7Schristos<DT>gettext shorthand 2400*946379e7Schristos<DD> 2401*946379e7Schristos<CODE>_("abc")</CODE> 2402*946379e7Schristos 2403*946379e7Schristos<DT>gettext/ngettext functions 2404*946379e7Schristos<DD> 2405*946379e7Schristos<CODE>wxLocale::GetString</CODE>, <CODE>wxGetTranslation</CODE> 2406*946379e7Schristos 2407*946379e7Schristos<DT>textdomain 2408*946379e7Schristos<DD> 2409*946379e7Schristos<CODE>wxLocale::AddCatalog</CODE> 2410*946379e7Schristos 2411*946379e7Schristos<DT>bindtextdomain 2412*946379e7Schristos<DD> 2413*946379e7Schristos<CODE>wxLocale::AddCatalogLookupPathPrefix</CODE> 2414*946379e7Schristos 2415*946379e7Schristos<DT>setlocale 2416*946379e7Schristos<DD> 2417*946379e7Schristos<CODE>wxLocale::Init</CODE>, <CODE>wxSetLocale</CODE> 2418*946379e7Schristos 2419*946379e7Schristos<DT>Prerequisite 2420*946379e7Schristos<DD> 2421*946379e7Schristos<CODE>#include <wx/intl.h></CODE> 2422*946379e7Schristos 2423*946379e7Schristos<DT>Use or emulate GNU gettext 2424*946379e7Schristos<DD> 2425*946379e7Schristosemulate, see <CODE>include/wx/intl.h</CODE> and <CODE>src/common/intl.cpp</CODE> 2426*946379e7Schristos 2427*946379e7Schristos<DT>Extractor 2428*946379e7Schristos<DD> 2429*946379e7Schristos<CODE>xgettext</CODE> 2430*946379e7Schristos 2431*946379e7Schristos<DT>Formatting with positions 2432*946379e7Schristos<DD> 2433*946379e7SchristoswxString::Format supports positions if and only if the system has 2434*946379e7Schristos<CODE>wprintf()</CODE>, <CODE>vswprintf()</CODE> functions and they support positions 2435*946379e7Schristosaccording to POSIX. 2436*946379e7Schristos 2437*946379e7Schristos<DT>Portability 2438*946379e7Schristos<DD> 2439*946379e7Schristosfully portable 2440*946379e7Schristos 2441*946379e7Schristos<DT>po-mode marking 2442*946379e7Schristos<DD> 2443*946379e7Schristosyes 2444*946379e7Schristos</DL> 2445*946379e7Schristos 2446*946379e7Schristos 2447*946379e7Schristos 2448*946379e7Schristos<H3><A NAME="SEC277" HREF="gettext_toc.html#TOC277">15.5.16 YCP - YaST2 scripting language</A></H3> 2449*946379e7Schristos<P> 2450*946379e7Schristos<A NAME="IDX1181"></A> 2451*946379e7Schristos<A NAME="IDX1182"></A> 2452*946379e7Schristos 2453*946379e7Schristos</P> 2454*946379e7Schristos<DL COMPACT> 2455*946379e7Schristos 2456*946379e7Schristos<DT>RPMs 2457*946379e7Schristos<DD> 2458*946379e7Schristoslibycp, libycp-devel, yast2-core, yast2-core-devel 2459*946379e7Schristos 2460*946379e7Schristos<DT>File extension 2461*946379e7Schristos<DD> 2462*946379e7Schristos<CODE>ycp</CODE> 2463*946379e7Schristos 2464*946379e7Schristos<DT>String syntax 2465*946379e7Schristos<DD> 2466*946379e7Schristos<CODE>"abc"</CODE> 2467*946379e7Schristos 2468*946379e7Schristos<DT>gettext shorthand 2469*946379e7Schristos<DD> 2470*946379e7Schristos<CODE>_("abc")</CODE> 2471*946379e7Schristos 2472*946379e7Schristos<DT>gettext/ngettext functions 2473*946379e7Schristos<DD> 2474*946379e7Schristos<CODE>_()</CODE> with 1 or 3 arguments 2475*946379e7Schristos 2476*946379e7Schristos<DT>textdomain 2477*946379e7Schristos<DD> 2478*946379e7Schristos<CODE>textdomain</CODE> statement 2479*946379e7Schristos 2480*946379e7Schristos<DT>bindtextdomain 2481*946379e7Schristos<DD> 2482*946379e7Schristos--- 2483*946379e7Schristos 2484*946379e7Schristos<DT>setlocale 2485*946379e7Schristos<DD> 2486*946379e7Schristos--- 2487*946379e7Schristos 2488*946379e7Schristos<DT>Prerequisite 2489*946379e7Schristos<DD> 2490*946379e7Schristos--- 2491*946379e7Schristos 2492*946379e7Schristos<DT>Use or emulate GNU gettext 2493*946379e7Schristos<DD> 2494*946379e7Schristosuse 2495*946379e7Schristos 2496*946379e7Schristos<DT>Extractor 2497*946379e7Schristos<DD> 2498*946379e7Schristos<CODE>xgettext</CODE> 2499*946379e7Schristos 2500*946379e7Schristos<DT>Formatting with positions 2501*946379e7Schristos<DD> 2502*946379e7Schristos<CODE>sformat "%2 %1"</CODE> 2503*946379e7Schristos 2504*946379e7Schristos<DT>Portability 2505*946379e7Schristos<DD> 2506*946379e7Schristosfully portable 2507*946379e7Schristos 2508*946379e7Schristos<DT>po-mode marking 2509*946379e7Schristos<DD> 2510*946379e7Schristos--- 2511*946379e7Schristos</DL> 2512*946379e7Schristos 2513*946379e7Schristos<P> 2514*946379e7SchristosAn example is available in the <TT>‘examples’</TT> directory: <CODE>hello-ycp</CODE>. 2515*946379e7Schristos 2516*946379e7Schristos</P> 2517*946379e7Schristos 2518*946379e7Schristos 2519*946379e7Schristos<H3><A NAME="SEC278" HREF="gettext_toc.html#TOC278">15.5.17 Tcl - Tk's scripting language</A></H3> 2520*946379e7Schristos<P> 2521*946379e7Schristos<A NAME="IDX1183"></A> 2522*946379e7Schristos<A NAME="IDX1184"></A> 2523*946379e7Schristos 2524*946379e7Schristos</P> 2525*946379e7Schristos<DL COMPACT> 2526*946379e7Schristos 2527*946379e7Schristos<DT>RPMs 2528*946379e7Schristos<DD> 2529*946379e7Schristostcl 2530*946379e7Schristos 2531*946379e7Schristos<DT>File extension 2532*946379e7Schristos<DD> 2533*946379e7Schristos<CODE>tcl</CODE> 2534*946379e7Schristos 2535*946379e7Schristos<DT>String syntax 2536*946379e7Schristos<DD> 2537*946379e7Schristos<CODE>"abc"</CODE> 2538*946379e7Schristos 2539*946379e7Schristos<DT>gettext shorthand 2540*946379e7Schristos<DD> 2541*946379e7Schristos<CODE>[_ "abc"]</CODE> 2542*946379e7Schristos 2543*946379e7Schristos<DT>gettext/ngettext functions 2544*946379e7Schristos<DD> 2545*946379e7Schristos<CODE>::msgcat::mc</CODE> 2546*946379e7Schristos 2547*946379e7Schristos<DT>textdomain 2548*946379e7Schristos<DD> 2549*946379e7Schristos--- 2550*946379e7Schristos 2551*946379e7Schristos<DT>bindtextdomain 2552*946379e7Schristos<DD> 2553*946379e7Schristos---, use <CODE>::msgcat::mcload</CODE> instead 2554*946379e7Schristos 2555*946379e7Schristos<DT>setlocale 2556*946379e7Schristos<DD> 2557*946379e7Schristosautomatic, uses LANG, but ignores LC_MESSAGES and LC_ALL 2558*946379e7Schristos 2559*946379e7Schristos<DT>Prerequisite 2560*946379e7Schristos<DD> 2561*946379e7Schristos<CODE>package require msgcat</CODE> 2562*946379e7Schristos<BR><CODE>proc _ {s} {return [::msgcat::mc $s]}</CODE> 2563*946379e7Schristos 2564*946379e7Schristos<DT>Use or emulate GNU gettext 2565*946379e7Schristos<DD> 2566*946379e7Schristos---, uses a Tcl specific message catalog format 2567*946379e7Schristos 2568*946379e7Schristos<DT>Extractor 2569*946379e7Schristos<DD> 2570*946379e7Schristos<CODE>xgettext -k_</CODE> 2571*946379e7Schristos 2572*946379e7Schristos<DT>Formatting with positions 2573*946379e7Schristos<DD> 2574*946379e7Schristos<CODE>format "%2\$d %1\$d"</CODE> 2575*946379e7Schristos 2576*946379e7Schristos<DT>Portability 2577*946379e7Schristos<DD> 2578*946379e7Schristosfully portable 2579*946379e7Schristos 2580*946379e7Schristos<DT>po-mode marking 2581*946379e7Schristos<DD> 2582*946379e7Schristos--- 2583*946379e7Schristos</DL> 2584*946379e7Schristos 2585*946379e7Schristos<P> 2586*946379e7SchristosTwo examples are available in the <TT>‘examples’</TT> directory: 2587*946379e7Schristos<CODE>hello-tcl</CODE>, <CODE>hello-tcl-tk</CODE>. 2588*946379e7Schristos 2589*946379e7Schristos</P> 2590*946379e7Schristos<P> 2591*946379e7SchristosBefore marking strings as internationalizable, substitutions of variables 2592*946379e7Schristosinto the string need to be converted to <CODE>format</CODE> applications. For 2593*946379e7Schristosexample, <CODE>"file $filename not found"</CODE> becomes 2594*946379e7Schristos<CODE>[format "file %s not found" $filename]</CODE>. 2595*946379e7SchristosOnly after this is done, can the strings be marked and extracted. 2596*946379e7SchristosAfter marking, this example becomes 2597*946379e7Schristos<CODE>[format [_ "file %s not found"] $filename]</CODE> or 2598*946379e7Schristos<CODE>[msgcat::mc "file %s not found" $filename]</CODE>. Note that the 2599*946379e7Schristos<CODE>msgcat::mc</CODE> function implicitly calls <CODE>format</CODE> when more than one 2600*946379e7Schristosargument is given. 2601*946379e7Schristos 2602*946379e7Schristos</P> 2603*946379e7Schristos 2604*946379e7Schristos 2605*946379e7Schristos<H3><A NAME="SEC279" HREF="gettext_toc.html#TOC279">15.5.18 Perl</A></H3> 2606*946379e7Schristos<P> 2607*946379e7Schristos<A NAME="IDX1185"></A> 2608*946379e7Schristos 2609*946379e7Schristos</P> 2610*946379e7Schristos<DL COMPACT> 2611*946379e7Schristos 2612*946379e7Schristos<DT>RPMs 2613*946379e7Schristos<DD> 2614*946379e7Schristosperl 2615*946379e7Schristos 2616*946379e7Schristos<DT>File extension 2617*946379e7Schristos<DD> 2618*946379e7Schristos<CODE>pl</CODE>, <CODE>PL</CODE>, <CODE>pm</CODE>, <CODE>cgi</CODE> 2619*946379e7Schristos 2620*946379e7Schristos<DT>String syntax 2621*946379e7Schristos<DD> 2622*946379e7Schristos 2623*946379e7Schristos<UL> 2624*946379e7Schristos 2625*946379e7Schristos<LI><CODE>"abc"</CODE> 2626*946379e7Schristos 2627*946379e7Schristos<LI><CODE>'abc'</CODE> 2628*946379e7Schristos 2629*946379e7Schristos<LI><CODE>qq (abc)</CODE> 2630*946379e7Schristos 2631*946379e7Schristos<LI><CODE>q (abc)</CODE> 2632*946379e7Schristos 2633*946379e7Schristos<LI><CODE>qr /abc/</CODE> 2634*946379e7Schristos 2635*946379e7Schristos<LI><CODE>qx (/bin/date)</CODE> 2636*946379e7Schristos 2637*946379e7Schristos<LI><CODE>/pattern match/</CODE> 2638*946379e7Schristos 2639*946379e7Schristos<LI><CODE>?pattern match?</CODE> 2640*946379e7Schristos 2641*946379e7Schristos<LI><CODE>s/substitution/operators/</CODE> 2642*946379e7Schristos 2643*946379e7Schristos<LI><CODE>$tied_hash{"message"}</CODE> 2644*946379e7Schristos 2645*946379e7Schristos<LI><CODE>$tied_hash_reference->{"message"}</CODE> 2646*946379e7Schristos 2647*946379e7Schristos<LI>etc., issue the command <SAMP>‘man perlsyn’</SAMP> for details 2648*946379e7Schristos 2649*946379e7Schristos</UL> 2650*946379e7Schristos 2651*946379e7Schristos<DT>gettext shorthand 2652*946379e7Schristos<DD> 2653*946379e7Schristos<CODE>__</CODE> (double underscore) 2654*946379e7Schristos 2655*946379e7Schristos<DT>gettext/ngettext functions 2656*946379e7Schristos<DD> 2657*946379e7Schristos<CODE>gettext</CODE>, <CODE>dgettext</CODE>, <CODE>dcgettext</CODE>, <CODE>ngettext</CODE>, 2658*946379e7Schristos<CODE>dngettext</CODE>, <CODE>dcngettext</CODE> 2659*946379e7Schristos 2660*946379e7Schristos<DT>textdomain 2661*946379e7Schristos<DD> 2662*946379e7Schristos<CODE>textdomain</CODE> function 2663*946379e7Schristos 2664*946379e7Schristos<DT>bindtextdomain 2665*946379e7Schristos<DD> 2666*946379e7Schristos<CODE>bindtextdomain</CODE> function 2667*946379e7Schristos 2668*946379e7Schristos<DT>bind_textdomain_codeset 2669*946379e7Schristos<DD> 2670*946379e7Schristos<CODE>bind_textdomain_codeset</CODE> function 2671*946379e7Schristos 2672*946379e7Schristos<DT>setlocale 2673*946379e7Schristos<DD> 2674*946379e7SchristosUse <CODE>setlocale (LC_ALL, "");</CODE> 2675*946379e7Schristos 2676*946379e7Schristos<DT>Prerequisite 2677*946379e7Schristos<DD> 2678*946379e7Schristos<CODE>use POSIX;</CODE> 2679*946379e7Schristos<BR><CODE>use Locale::TextDomain;</CODE> (included in the package libintl-perl 2680*946379e7Schristoswhich is available on the Comprehensive Perl Archive Network CPAN, 2681*946379e7Schristoshttp://www.cpan.org/). 2682*946379e7Schristos 2683*946379e7Schristos<DT>Use or emulate GNU gettext 2684*946379e7Schristos<DD> 2685*946379e7Schristosplatform dependent: gettext_pp emulates, gettext_xs uses GNU gettext 2686*946379e7Schristos 2687*946379e7Schristos<DT>Extractor 2688*946379e7Schristos<DD> 2689*946379e7Schristos<CODE>xgettext -k__ -k\$__ -k%__ -k__x -k__n:1,2 -k__nx:1,2 -k__xn:1,2 -kN__ -k</CODE> 2690*946379e7Schristos 2691*946379e7Schristos<DT>Formatting with positions 2692*946379e7Schristos<DD> 2693*946379e7SchristosBoth kinds of format strings support formatting with positions. 2694*946379e7Schristos<BR><CODE>printf "%2\$d %1\$d", ...</CODE> (requires Perl 5.8.0 or newer) 2695*946379e7Schristos<BR><CODE>__expand("[new] replaces [old]", old => $oldvalue, new => $newvalue)</CODE> 2696*946379e7Schristos 2697*946379e7Schristos<DT>Portability 2698*946379e7Schristos<DD> 2699*946379e7SchristosThe <CODE>libintl-perl</CODE> package is platform independent but is not 2700*946379e7Schristospart of the Perl core. The programmer is responsible for 2701*946379e7Schristosproviding a dummy implementation of the required functions if the 2702*946379e7Schristospackage is not installed on the target system. 2703*946379e7Schristos 2704*946379e7Schristos<DT>po-mode marking 2705*946379e7Schristos<DD> 2706*946379e7Schristos--- 2707*946379e7Schristos 2708*946379e7Schristos<DT>Documentation 2709*946379e7Schristos<DD> 2710*946379e7SchristosIncluded in <CODE>libintl-perl</CODE>, available on CPAN 2711*946379e7Schristos(http://www.cpan.org/). 2712*946379e7Schristos 2713*946379e7Schristos</DL> 2714*946379e7Schristos 2715*946379e7Schristos<P> 2716*946379e7SchristosAn example is available in the <TT>‘examples’</TT> directory: <CODE>hello-perl</CODE>. 2717*946379e7Schristos 2718*946379e7Schristos</P> 2719*946379e7Schristos<P> 2720*946379e7Schristos<A NAME="IDX1186"></A> 2721*946379e7Schristos 2722*946379e7Schristos</P> 2723*946379e7Schristos<P> 2724*946379e7SchristosThe <CODE>xgettext</CODE> parser backend for Perl differs significantly from 2725*946379e7Schristosthe parser backends for other programming languages, just as Perl 2726*946379e7Schristositself differs significantly from other programming languages. The 2727*946379e7SchristosPerl parser backend offers many more string marking facilities than 2728*946379e7Schristosthe other backends but it also has some Perl specific limitations, the 2729*946379e7Schristosworst probably being its imperfectness. 2730*946379e7Schristos 2731*946379e7Schristos</P> 2732*946379e7Schristos 2733*946379e7Schristos 2734*946379e7Schristos 2735*946379e7Schristos<H4><A NAME="SEC280" HREF="gettext_toc.html#TOC280">15.5.18.1 General Problems Parsing Perl Code</A></H4> 2736*946379e7Schristos 2737*946379e7Schristos<P> 2738*946379e7SchristosIt is often heard that only Perl can parse Perl. This is not true. 2739*946379e7SchristosPerl cannot be <EM>parsed</EM> at all, it can only be <EM>executed</EM>. 2740*946379e7SchristosPerl has various built-in ambiguities that can only be resolved at runtime. 2741*946379e7Schristos 2742*946379e7Schristos</P> 2743*946379e7Schristos<P> 2744*946379e7SchristosThe following example may illustrate one common problem: 2745*946379e7Schristos 2746*946379e7Schristos</P> 2747*946379e7Schristos 2748*946379e7Schristos<PRE> 2749*946379e7Schristosprint gettext "Hello World!"; 2750*946379e7Schristos</PRE> 2751*946379e7Schristos 2752*946379e7Schristos<P> 2753*946379e7SchristosAlthough this example looks like a bullet-proof case of a function 2754*946379e7Schristosinvocation, it is not: 2755*946379e7Schristos 2756*946379e7Schristos</P> 2757*946379e7Schristos 2758*946379e7Schristos<PRE> 2759*946379e7Schristosopen gettext, ">testfile" or die; 2760*946379e7Schristosprint gettext "Hello world!" 2761*946379e7Schristos</PRE> 2762*946379e7Schristos 2763*946379e7Schristos<P> 2764*946379e7SchristosIn this context, the string <CODE>gettext</CODE> looks more like a 2765*946379e7Schristosfile handle. But not necessarily: 2766*946379e7Schristos 2767*946379e7Schristos</P> 2768*946379e7Schristos 2769*946379e7Schristos<PRE> 2770*946379e7Schristosuse Locale::Messages qw (:libintl_h); 2771*946379e7Schristosopen gettext ">testfile" or die; 2772*946379e7Schristosprint gettext "Hello world!"; 2773*946379e7Schristos</PRE> 2774*946379e7Schristos 2775*946379e7Schristos<P> 2776*946379e7SchristosNow, the file is probably syntactically incorrect, provided that the module 2777*946379e7Schristos<CODE>Locale::Messages</CODE> found first in the Perl include path exports a 2778*946379e7Schristosfunction <CODE>gettext</CODE>. But what if the module 2779*946379e7Schristos<CODE>Locale::Messages</CODE> really looks like this? 2780*946379e7Schristos 2781*946379e7Schristos</P> 2782*946379e7Schristos 2783*946379e7Schristos<PRE> 2784*946379e7Schristosuse vars qw (*gettext); 2785*946379e7Schristos 2786*946379e7Schristos1; 2787*946379e7Schristos</PRE> 2788*946379e7Schristos 2789*946379e7Schristos<P> 2790*946379e7SchristosIn this case, the string <CODE>gettext</CODE> will be interpreted as a file 2791*946379e7Schristoshandle again, and the above example will create a file <TT>‘testfile’</TT> 2792*946379e7Schristosand write the string “Hello world!” into it. Even advanced 2793*946379e7Schristoscontrol flow analysis will not really help: 2794*946379e7Schristos 2795*946379e7Schristos</P> 2796*946379e7Schristos 2797*946379e7Schristos<PRE> 2798*946379e7Schristosif (0.5 < rand) { 2799*946379e7Schristos eval "use Sane"; 2800*946379e7Schristos} else { 2801*946379e7Schristos eval "use InSane"; 2802*946379e7Schristos} 2803*946379e7Schristosprint gettext "Hello world!"; 2804*946379e7Schristos</PRE> 2805*946379e7Schristos 2806*946379e7Schristos<P> 2807*946379e7SchristosIf the module <CODE>Sane</CODE> exports a function <CODE>gettext</CODE> that does 2808*946379e7Schristoswhat we expect, and the module <CODE>InSane</CODE> opens a file for writing 2809*946379e7Schristosand associates the <EM>handle</EM> <CODE>gettext</CODE> with this output 2810*946379e7Schristosstream, we are clueless again about what will happen at runtime. It is 2811*946379e7Schristoscompletely unpredictable. The truth is that Perl has so many ways to 2812*946379e7Schristosfill its symbol table at runtime that it is impossible to interpret a 2813*946379e7Schristosparticular piece of code without executing it. 2814*946379e7Schristos 2815*946379e7Schristos</P> 2816*946379e7Schristos<P> 2817*946379e7SchristosOf course, <CODE>xgettext</CODE> will not execute your Perl sources while 2818*946379e7Schristosscanning for translatable strings, but rather use heuristics in order 2819*946379e7Schristosto guess what you meant. 2820*946379e7Schristos 2821*946379e7Schristos</P> 2822*946379e7Schristos<P> 2823*946379e7SchristosAnother problem is the ambiguity of the slash and the question mark. 2824*946379e7SchristosTheir interpretation depends on the context: 2825*946379e7Schristos 2826*946379e7Schristos</P> 2827*946379e7Schristos 2828*946379e7Schristos<PRE> 2829*946379e7Schristos# A pattern match. 2830*946379e7Schristosprint "OK\n" if /foobar/; 2831*946379e7Schristos 2832*946379e7Schristos# A division. 2833*946379e7Schristosprint 1 / 2; 2834*946379e7Schristos 2835*946379e7Schristos# Another pattern match. 2836*946379e7Schristosprint "OK\n" if ?foobar?; 2837*946379e7Schristos 2838*946379e7Schristos# Conditional. 2839*946379e7Schristosprint $x ? "foo" : "bar"; 2840*946379e7Schristos</PRE> 2841*946379e7Schristos 2842*946379e7Schristos<P> 2843*946379e7SchristosThe slash may either act as the division operator or introduce a 2844*946379e7Schristospattern match, whereas the question mark may act as the ternary 2845*946379e7Schristosconditional operator or as a pattern match, too. Other programming 2846*946379e7Schristoslanguages like <CODE>awk</CODE> present similar problems, but the consequences of a 2847*946379e7Schristosmisinterpretation are particularly nasty with Perl sources. In <CODE>awk</CODE> 2848*946379e7Schristosfor instance, a statement can never exceed one line and the parser 2849*946379e7Schristoscan recover from a parsing error at the next newline and interpret 2850*946379e7Schristosthe rest of the input stream correctly. Perl is different, as a 2851*946379e7Schristospattern match is terminated by the next appearance of the delimiter 2852*946379e7Schristos(the slash or the question mark) in the input stream, regardless of 2853*946379e7Schristosthe semantic context. If a slash is really a division sign but 2854*946379e7Schristosmis-interpreted as a pattern match, the rest of the input file is most 2855*946379e7Schristosprobably parsed incorrectly. 2856*946379e7Schristos 2857*946379e7Schristos</P> 2858*946379e7Schristos<P> 2859*946379e7SchristosIf you find that <CODE>xgettext</CODE> fails to extract strings from 2860*946379e7Schristosportions of your sources, you should therefore look out for slashes 2861*946379e7Schristosand/or question marks preceding these sections. You may have come 2862*946379e7Schristosacross a bug in <CODE>xgettext</CODE>'s Perl parser (and of course you 2863*946379e7Schristosshould report that bug). In the meantime you should consider to 2864*946379e7Schristosreformulate your code in a manner less challenging to <CODE>xgettext</CODE>. 2865*946379e7Schristos 2866*946379e7Schristos</P> 2867*946379e7Schristos 2868*946379e7Schristos 2869*946379e7Schristos<H4><A NAME="SEC281" HREF="gettext_toc.html#TOC281">15.5.18.2 Which keywords will xgettext look for?</A></H4> 2870*946379e7Schristos<P> 2871*946379e7Schristos<A NAME="IDX1187"></A> 2872*946379e7Schristos 2873*946379e7Schristos</P> 2874*946379e7Schristos<P> 2875*946379e7SchristosUnless you instruct <CODE>xgettext</CODE> otherwise by invoking it with one 2876*946379e7Schristosof the options <CODE>--keyword</CODE> or <CODE>-k</CODE>, it will recognize the 2877*946379e7Schristosfollowing keywords in your Perl sources: 2878*946379e7Schristos 2879*946379e7Schristos</P> 2880*946379e7Schristos 2881*946379e7Schristos<UL> 2882*946379e7Schristos 2883*946379e7Schristos<LI><CODE>gettext</CODE> 2884*946379e7Schristos 2885*946379e7Schristos<LI><CODE>dgettext</CODE> 2886*946379e7Schristos 2887*946379e7Schristos<LI><CODE>dcgettext</CODE> 2888*946379e7Schristos 2889*946379e7Schristos<LI><CODE>ngettext:1,2</CODE> 2890*946379e7Schristos 2891*946379e7SchristosThe first (singular) and the second (plural) argument will be 2892*946379e7Schristosextracted. 2893*946379e7Schristos 2894*946379e7Schristos<LI><CODE>dngettext:1,2</CODE> 2895*946379e7Schristos 2896*946379e7SchristosThe first (singular) and the second (plural) argument will be 2897*946379e7Schristosextracted. 2898*946379e7Schristos 2899*946379e7Schristos<LI><CODE>dcngettext:1,2</CODE> 2900*946379e7Schristos 2901*946379e7SchristosThe first (singular) and the second (plural) argument will be 2902*946379e7Schristosextracted. 2903*946379e7Schristos 2904*946379e7Schristos<LI><CODE>gettext_noop</CODE> 2905*946379e7Schristos 2906*946379e7Schristos<LI><CODE>%gettext</CODE> 2907*946379e7Schristos 2908*946379e7SchristosThe keys of lookups into the hash <CODE>%gettext</CODE> will be extracted. 2909*946379e7Schristos 2910*946379e7Schristos<LI><CODE>$gettext</CODE> 2911*946379e7Schristos 2912*946379e7SchristosThe keys of lookups into the hash reference <CODE>$gettext</CODE> will be extracted. 2913*946379e7Schristos 2914*946379e7Schristos</UL> 2915*946379e7Schristos 2916*946379e7Schristos 2917*946379e7Schristos 2918*946379e7Schristos<H4><A NAME="SEC282" HREF="gettext_toc.html#TOC282">15.5.18.3 How to Extract Hash Keys</A></H4> 2919*946379e7Schristos<P> 2920*946379e7Schristos<A NAME="IDX1188"></A> 2921*946379e7Schristos 2922*946379e7Schristos</P> 2923*946379e7Schristos<P> 2924*946379e7SchristosTranslating messages at runtime is normally performed by looking up the 2925*946379e7Schristosoriginal string in the translation database and returning the 2926*946379e7Schristostranslated version. The “natural” Perl implementation is a hash 2927*946379e7Schristoslookup, and, of course, <CODE>xgettext</CODE> supports such practice. 2928*946379e7Schristos 2929*946379e7Schristos</P> 2930*946379e7Schristos 2931*946379e7Schristos<PRE> 2932*946379e7Schristosprint __"Hello world!"; 2933*946379e7Schristosprint $__{"Hello world!"}; 2934*946379e7Schristosprint $__->{"Hello world!"}; 2935*946379e7Schristosprint $$__{"Hello world!"}; 2936*946379e7Schristos</PRE> 2937*946379e7Schristos 2938*946379e7Schristos<P> 2939*946379e7SchristosThe above four lines all do the same thing. The Perl module 2940*946379e7Schristos<CODE>Locale::TextDomain</CODE> exports by default a hash <CODE>%__</CODE> that 2941*946379e7Schristosis tied to the function <CODE>__()</CODE>. It also exports a reference 2942*946379e7Schristos<CODE>$__</CODE> to <CODE>%__</CODE>. 2943*946379e7Schristos 2944*946379e7Schristos</P> 2945*946379e7Schristos<P> 2946*946379e7SchristosIf an argument to the <CODE>xgettext</CODE> option <CODE>--keyword</CODE>, 2947*946379e7Schristosresp. <CODE>-k</CODE> starts with a percent sign, the rest of the keyword is 2948*946379e7Schristosinterpreted as the name of a hash. If it starts with a dollar 2949*946379e7Schristossign, the rest of the keyword is interpreted as a reference to a 2950*946379e7Schristoshash. 2951*946379e7Schristos 2952*946379e7Schristos</P> 2953*946379e7Schristos<P> 2954*946379e7SchristosNote that you can omit the quotation marks (single or double) around 2955*946379e7Schristosthe hash key (almost) whenever Perl itself allows it: 2956*946379e7Schristos 2957*946379e7Schristos</P> 2958*946379e7Schristos 2959*946379e7Schristos<PRE> 2960*946379e7Schristosprint $gettext{Error}; 2961*946379e7Schristos</PRE> 2962*946379e7Schristos 2963*946379e7Schristos<P> 2964*946379e7SchristosThe exact rule is: You can omit the surrounding quotes, when the hash 2965*946379e7Schristoskey is a valid C (!) identifier, i.e. when it starts with an 2966*946379e7Schristosunderscore or an ASCII letter and is followed by an arbitrary number 2967*946379e7Schristosof underscores, ASCII letters or digits. Other Unicode characters 2968*946379e7Schristosare <EM>not</EM> allowed, regardless of the <CODE>use utf8</CODE> pragma. 2969*946379e7Schristos 2970*946379e7Schristos</P> 2971*946379e7Schristos 2972*946379e7Schristos 2973*946379e7Schristos<H4><A NAME="SEC283" HREF="gettext_toc.html#TOC283">15.5.18.4 What are Strings And Quote-like Expressions?</A></H4> 2974*946379e7Schristos<P> 2975*946379e7Schristos<A NAME="IDX1189"></A> 2976*946379e7Schristos 2977*946379e7Schristos</P> 2978*946379e7Schristos<P> 2979*946379e7SchristosPerl offers a plethora of different string constructs. Those that can 2980*946379e7Schristosbe used either as arguments to functions or inside braces for hash 2981*946379e7Schristoslookups are generally supported by <CODE>xgettext</CODE>. 2982*946379e7Schristos 2983*946379e7Schristos</P> 2984*946379e7Schristos 2985*946379e7Schristos<UL> 2986*946379e7Schristos<LI><STRONG>double-quoted strings</STRONG> 2987*946379e7Schristos 2988*946379e7Schristos<BR> 2989*946379e7Schristos 2990*946379e7Schristos<PRE> 2991*946379e7Schristosprint gettext "Hello World!"; 2992*946379e7Schristos</PRE> 2993*946379e7Schristos 2994*946379e7Schristos<LI><STRONG>single-quoted strings</STRONG> 2995*946379e7Schristos 2996*946379e7Schristos<BR> 2997*946379e7Schristos 2998*946379e7Schristos<PRE> 2999*946379e7Schristosprint gettext 'Hello World!'; 3000*946379e7Schristos</PRE> 3001*946379e7Schristos 3002*946379e7Schristos<LI><STRONG>the operator qq</STRONG> 3003*946379e7Schristos 3004*946379e7Schristos<BR> 3005*946379e7Schristos 3006*946379e7Schristos<PRE> 3007*946379e7Schristosprint gettext qq |Hello World!|; 3008*946379e7Schristosprint gettext qq <E-mail: <guido\@imperia.net>>; 3009*946379e7Schristos</PRE> 3010*946379e7Schristos 3011*946379e7SchristosThe operator <CODE>qq</CODE> is fully supported. You can use arbitrary 3012*946379e7Schristosdelimiters, including the four bracketing delimiters (round, angle, 3013*946379e7Schristossquare, curly) that nest. 3014*946379e7Schristos 3015*946379e7Schristos<LI><STRONG>the operator q</STRONG> 3016*946379e7Schristos 3017*946379e7Schristos<BR> 3018*946379e7Schristos 3019*946379e7Schristos<PRE> 3020*946379e7Schristosprint gettext q |Hello World!|; 3021*946379e7Schristosprint gettext q <E-mail: <guido@imperia.net>>; 3022*946379e7Schristos</PRE> 3023*946379e7Schristos 3024*946379e7SchristosThe operator <CODE>q</CODE> is fully supported. You can use arbitrary 3025*946379e7Schristosdelimiters, including the four bracketing delimiters (round, angle, 3026*946379e7Schristossquare, curly) that nest. 3027*946379e7Schristos 3028*946379e7Schristos<LI><STRONG>the operator qx</STRONG> 3029*946379e7Schristos 3030*946379e7Schristos<BR> 3031*946379e7Schristos 3032*946379e7Schristos<PRE> 3033*946379e7Schristosprint gettext qx ;LANGUAGE=C /bin/date; 3034*946379e7Schristosprint gettext qx [/usr/bin/ls | grep '^[A-Z]*']; 3035*946379e7Schristos</PRE> 3036*946379e7Schristos 3037*946379e7SchristosThe operator <CODE>qx</CODE> is fully supported. You can use arbitrary 3038*946379e7Schristosdelimiters, including the four bracketing delimiters (round, angle, 3039*946379e7Schristossquare, curly) that nest. 3040*946379e7Schristos 3041*946379e7SchristosThe example is actually a useless use of <CODE>gettext</CODE>. It will 3042*946379e7Schristosinvoke the <CODE>gettext</CODE> function on the output of the command 3043*946379e7Schristosspecified with the <CODE>qx</CODE> operator. The feature was included 3044*946379e7Schristosin order to make the interface consistent (the parser will extract 3045*946379e7Schristosall strings and quote-like expressions). 3046*946379e7Schristos 3047*946379e7Schristos<LI><STRONG>here documents</STRONG> 3048*946379e7Schristos 3049*946379e7Schristos<BR> 3050*946379e7Schristos 3051*946379e7Schristos<PRE> 3052*946379e7Schristosprint gettext <<'EOF'; 3053*946379e7Schristosprogram not found in $PATH 3054*946379e7SchristosEOF 3055*946379e7Schristos 3056*946379e7Schristosprint ngettext <<EOF, <<"EOF"; 3057*946379e7Schristosone file deleted 3058*946379e7SchristosEOF 3059*946379e7Schristosseveral files deleted 3060*946379e7SchristosEOF 3061*946379e7Schristos</PRE> 3062*946379e7Schristos 3063*946379e7SchristosHere-documents are recognized. If the delimiter is enclosed in single 3064*946379e7Schristosquotes, the string is not interpolated. If it is enclosed in double 3065*946379e7Schristosquotes or has no quotes at all, the string is interpolated. 3066*946379e7Schristos 3067*946379e7SchristosDelimiters that start with a digit are not supported! 3068*946379e7Schristos 3069*946379e7Schristos</UL> 3070*946379e7Schristos 3071*946379e7Schristos 3072*946379e7Schristos 3073*946379e7Schristos<H4><A NAME="SEC284" HREF="gettext_toc.html#TOC284">15.5.18.5 Invalid Uses Of String Interpolation</A></H4> 3074*946379e7Schristos<P> 3075*946379e7Schristos<A NAME="IDX1190"></A> 3076*946379e7Schristos 3077*946379e7Schristos</P> 3078*946379e7Schristos<P> 3079*946379e7SchristosPerl is capable of interpolating variables into strings. This offers 3080*946379e7Schristossome nice features in localized programs but can also lead to 3081*946379e7Schristosproblems. 3082*946379e7Schristos 3083*946379e7Schristos</P> 3084*946379e7Schristos<P> 3085*946379e7SchristosA common error is a construct like the following: 3086*946379e7Schristos 3087*946379e7Schristos</P> 3088*946379e7Schristos 3089*946379e7Schristos<PRE> 3090*946379e7Schristosprint gettext "This is the program $0!\n"; 3091*946379e7Schristos</PRE> 3092*946379e7Schristos 3093*946379e7Schristos<P> 3094*946379e7SchristosPerl will interpolate at runtime the value of the variable <CODE>$0</CODE> 3095*946379e7Schristosinto the argument of the <CODE>gettext()</CODE> function. Hence, this 3096*946379e7Schristosargument is not a string constant but a variable argument (<CODE>$0</CODE> 3097*946379e7Schristosis a global variable that holds the name of the Perl script being 3098*946379e7Schristosexecuted). The interpolation is performed by Perl before the string 3099*946379e7Schristosargument is passed to <CODE>gettext()</CODE> and will therefore depend on 3100*946379e7Schristosthe name of the script which can only be determined at runtime. 3101*946379e7SchristosConsequently, it is almost impossible that a translation can be looked 3102*946379e7Schristosup at runtime (except if, by accident, the interpolated string is found 3103*946379e7Schristosin the message catalog). 3104*946379e7Schristos 3105*946379e7Schristos</P> 3106*946379e7Schristos<P> 3107*946379e7SchristosThe <CODE>xgettext</CODE> program will therefore terminate parsing with a fatal 3108*946379e7Schristoserror if it encounters a variable inside of an extracted string. In 3109*946379e7Schristosgeneral, this will happen for all kinds of string interpolations that 3110*946379e7Schristoscannot be safely performed at compile time. If you absolutely know 3111*946379e7Schristoswhat you are doing, you can always circumvent this behavior: 3112*946379e7Schristos 3113*946379e7Schristos</P> 3114*946379e7Schristos 3115*946379e7Schristos<PRE> 3116*946379e7Schristosmy $know_what_i_am_doing = "This is program $0!\n"; 3117*946379e7Schristosprint gettext $know_what_i_am_doing; 3118*946379e7Schristos</PRE> 3119*946379e7Schristos 3120*946379e7Schristos<P> 3121*946379e7SchristosSince the parser only recognizes strings and quote-like expressions, 3122*946379e7Schristosbut not variables or other terms, the above construct will be 3123*946379e7Schristosaccepted. You will have to find another way, however, to let your 3124*946379e7Schristosoriginal string make it into your message catalog. 3125*946379e7Schristos 3126*946379e7Schristos</P> 3127*946379e7Schristos<P> 3128*946379e7SchristosIf invoked with the option <CODE>--extract-all</CODE>, resp. <CODE>-a</CODE>, 3129*946379e7Schristosvariable interpolation will be accepted. Rationale: You will 3130*946379e7Schristosgenerally use this option in order to prepare your sources for 3131*946379e7Schristosinternationalization. 3132*946379e7Schristos 3133*946379e7Schristos</P> 3134*946379e7Schristos<P> 3135*946379e7SchristosPlease see the manual page <SAMP>‘man perlop’</SAMP> for details of strings and 3136*946379e7Schristosquote-like expressions that are subject to interpolation and those 3137*946379e7Schristosthat are not. Safe interpolations (that will not lead to a fatal 3138*946379e7Schristoserror) are: 3139*946379e7Schristos 3140*946379e7Schristos</P> 3141*946379e7Schristos 3142*946379e7Schristos<UL> 3143*946379e7Schristos 3144*946379e7Schristos<LI>the escape sequences <CODE>\t</CODE> (tab, HT, TAB), <CODE>\n</CODE> 3145*946379e7Schristos 3146*946379e7Schristos(newline, NL), <CODE>\r</CODE> (return, CR), <CODE>\f</CODE> (form feed, FF), 3147*946379e7Schristos<CODE>\b</CODE> (backspace, BS), <CODE>\a</CODE> (alarm, bell, BEL), and <CODE>\e</CODE> 3148*946379e7Schristos(escape, ESC). 3149*946379e7Schristos 3150*946379e7Schristos<LI>octal chars, like <CODE>\033</CODE> 3151*946379e7Schristos 3152*946379e7Schristos<BR> 3153*946379e7SchristosNote that octal escapes in the range of 400-777 are translated into a 3154*946379e7SchristosUTF-8 representation, regardless of the presence of the <CODE>use utf8</CODE> pragma. 3155*946379e7Schristos 3156*946379e7Schristos<LI>hex chars, like <CODE>\x1b</CODE> 3157*946379e7Schristos 3158*946379e7Schristos<LI>wide hex chars, like <CODE>\x{263a}</CODE> 3159*946379e7Schristos 3160*946379e7Schristos<BR> 3161*946379e7SchristosNote that this escape is translated into a UTF-8 representation, 3162*946379e7Schristosregardless of the presence of the <CODE>use utf8</CODE> pragma. 3163*946379e7Schristos 3164*946379e7Schristos<LI>control chars, like <CODE>\c[</CODE> (CTRL-[) 3165*946379e7Schristos 3166*946379e7Schristos<LI>named Unicode chars, like <CODE>\N{LATIN CAPITAL LETTER C WITH CEDILLA}</CODE> 3167*946379e7Schristos 3168*946379e7Schristos<BR> 3169*946379e7SchristosNote that this escape is translated into a UTF-8 representation, 3170*946379e7Schristosregardless of the presence of the <CODE>use utf8</CODE> pragma. 3171*946379e7Schristos</UL> 3172*946379e7Schristos 3173*946379e7Schristos<P> 3174*946379e7SchristosThe following escapes are considered partially safe: 3175*946379e7Schristos 3176*946379e7Schristos</P> 3177*946379e7Schristos 3178*946379e7Schristos<UL> 3179*946379e7Schristos 3180*946379e7Schristos<LI><CODE>\l</CODE> lowercase next char 3181*946379e7Schristos 3182*946379e7Schristos<LI><CODE>\u</CODE> uppercase next char 3183*946379e7Schristos 3184*946379e7Schristos<LI><CODE>\L</CODE> lowercase till \E 3185*946379e7Schristos 3186*946379e7Schristos<LI><CODE>\U</CODE> uppercase till \E 3187*946379e7Schristos 3188*946379e7Schristos<LI><CODE>\E</CODE> end case modification 3189*946379e7Schristos 3190*946379e7Schristos<LI><CODE>\Q</CODE> quote non-word characters till \E 3191*946379e7Schristos 3192*946379e7Schristos</UL> 3193*946379e7Schristos 3194*946379e7Schristos<P> 3195*946379e7SchristosThese escapes are only considered safe if the string consists of 3196*946379e7SchristosASCII characters only. Translation of characters outside the range 3197*946379e7Schristosdefined by ASCII is locale-dependent and can actually only be performed 3198*946379e7Schristosat runtime; <CODE>xgettext</CODE> doesn't do these locale-dependent translations 3199*946379e7Schristosat extraction time. 3200*946379e7Schristos 3201*946379e7Schristos</P> 3202*946379e7Schristos<P> 3203*946379e7SchristosExcept for the modifier <CODE>\Q</CODE>, these translations, albeit valid, 3204*946379e7Schristosare generally useless and only obfuscate your sources. If a 3205*946379e7Schristostranslation can be safely performed at compile time you can just as 3206*946379e7Schristoswell write what you mean. 3207*946379e7Schristos 3208*946379e7Schristos</P> 3209*946379e7Schristos 3210*946379e7Schristos 3211*946379e7Schristos<H4><A NAME="SEC285" HREF="gettext_toc.html#TOC285">15.5.18.6 Valid Uses Of String Interpolation</A></H4> 3212*946379e7Schristos<P> 3213*946379e7Schristos<A NAME="IDX1191"></A> 3214*946379e7Schristos 3215*946379e7Schristos</P> 3216*946379e7Schristos<P> 3217*946379e7SchristosPerl is often used to generate sources for other programming languages 3218*946379e7Schristosor arbitrary file formats. Web applications that output HTML code 3219*946379e7Schristosmake a prominent example for such usage. 3220*946379e7Schristos 3221*946379e7Schristos</P> 3222*946379e7Schristos<P> 3223*946379e7SchristosYou will often come across situations where you want to intersperse 3224*946379e7Schristoscode written in the target (programming) language with translatable 3225*946379e7Schristosmessages, like in the following HTML example: 3226*946379e7Schristos 3227*946379e7Schristos</P> 3228*946379e7Schristos 3229*946379e7Schristos<PRE> 3230*946379e7Schristosprint gettext <<EOF; 3231*946379e7Schristos<h1>My Homepage</h1> 3232*946379e7Schristos<script language="JavaScript"><!-- 3233*946379e7Schristosfor (i = 0; i < 100; ++i) { 3234*946379e7Schristos alert ("Thank you so much for visiting my homepage!"); 3235*946379e7Schristos} 3236*946379e7Schristos//--></script> 3237*946379e7SchristosEOF 3238*946379e7Schristos</PRE> 3239*946379e7Schristos 3240*946379e7Schristos<P> 3241*946379e7SchristosThe parser will extract the entire here document, and it will appear 3242*946379e7Schristosentirely in the resulting PO file, including the JavaScript snippet 3243*946379e7Schristosembedded in the HTML code. If you exaggerate with constructs like 3244*946379e7Schristosthe above, you will run the risk that the translators of your package 3245*946379e7Schristoswill look out for a less challenging project. You should consider an 3246*946379e7Schristosalternative expression here: 3247*946379e7Schristos 3248*946379e7Schristos</P> 3249*946379e7Schristos 3250*946379e7Schristos<PRE> 3251*946379e7Schristosprint <<EOF; 3252*946379e7Schristos<h1>$gettext{"My Homepage"}</h1> 3253*946379e7Schristos<script language="JavaScript"><!-- 3254*946379e7Schristosfor (i = 0; i < 100; ++i) { 3255*946379e7Schristos alert ("$gettext{'Thank you so much for visiting my homepage!'}"); 3256*946379e7Schristos} 3257*946379e7Schristos//--></script> 3258*946379e7SchristosEOF 3259*946379e7Schristos</PRE> 3260*946379e7Schristos 3261*946379e7Schristos<P> 3262*946379e7SchristosOnly the translatable portions of the code will be extracted here, and 3263*946379e7Schristosthe resulting PO file will begrudgingly improve in terms of readability. 3264*946379e7Schristos 3265*946379e7Schristos</P> 3266*946379e7Schristos<P> 3267*946379e7SchristosYou can interpolate hash lookups in all strings or quote-like 3268*946379e7Schristosexpressions that are subject to interpolation (see the manual page 3269*946379e7Schristos<SAMP>‘man perlop’</SAMP> for details). Double interpolation is invalid, however: 3270*946379e7Schristos 3271*946379e7Schristos</P> 3272*946379e7Schristos 3273*946379e7Schristos<PRE> 3274*946379e7Schristos# TRANSLATORS: Replace "the earth" with the name of your planet. 3275*946379e7Schristosprint gettext qq{Welcome to $gettext->{"the earth"}}; 3276*946379e7Schristos</PRE> 3277*946379e7Schristos 3278*946379e7Schristos<P> 3279*946379e7SchristosThe <CODE>qq</CODE>-quoted string is recognized as an argument to <CODE>xgettext</CODE> in 3280*946379e7Schristosthe first place, and checked for invalid variable interpolation. The 3281*946379e7Schristosdollar sign of hash-dereferencing will therefore terminate the parser 3282*946379e7Schristoswith an “invalid interpolation” error. 3283*946379e7Schristos 3284*946379e7Schristos</P> 3285*946379e7Schristos<P> 3286*946379e7SchristosIt is valid to interpolate hash lookups in regular expressions: 3287*946379e7Schristos 3288*946379e7Schristos</P> 3289*946379e7Schristos 3290*946379e7Schristos<PRE> 3291*946379e7Schristosif ($var =~ /$gettext{"the earth"}/) { 3292*946379e7Schristos print gettext "Match!\n"; 3293*946379e7Schristos} 3294*946379e7Schristoss/$gettext{"U. S. A."}/$gettext{"U. S. A."} $gettext{"(dial +0)"}/g; 3295*946379e7Schristos</PRE> 3296*946379e7Schristos 3297*946379e7Schristos 3298*946379e7Schristos 3299*946379e7Schristos<H4><A NAME="SEC286" HREF="gettext_toc.html#TOC286">15.5.18.7 When To Use Parentheses</A></H4> 3300*946379e7Schristos<P> 3301*946379e7Schristos<A NAME="IDX1192"></A> 3302*946379e7Schristos 3303*946379e7Schristos</P> 3304*946379e7Schristos<P> 3305*946379e7SchristosIn Perl, parentheses around function arguments are mostly optional. 3306*946379e7Schristos<CODE>xgettext</CODE> will always assume that all 3307*946379e7Schristosrecognized keywords (except for hashes and hash references) are names 3308*946379e7Schristosof properly prototyped functions, and will (hopefully) only require 3309*946379e7Schristosparentheses where Perl itself requires them. All constructs in the 3310*946379e7Schristosfollowing example are therefore ok to use: 3311*946379e7Schristos 3312*946379e7Schristos</P> 3313*946379e7Schristos 3314*946379e7Schristos<PRE> 3315*946379e7Schristosprint gettext ("Hello World!\n"); 3316*946379e7Schristosprint gettext "Hello World!\n"; 3317*946379e7Schristosprint dgettext ($package => "Hello World!\n"); 3318*946379e7Schristosprint dgettext $package, "Hello World!\n"; 3319*946379e7Schristos 3320*946379e7Schristos# The "fat comma" => turns the left-hand side argument into a 3321*946379e7Schristos# single-quoted string! 3322*946379e7Schristosprint dgettext smellovision => "Hello World!\n"; 3323*946379e7Schristos 3324*946379e7Schristos# The following assignment only works with prototyped functions. 3325*946379e7Schristos# Otherwise, the functions will act as "greedy" list operators and 3326*946379e7Schristos# eat up all following arguments. 3327*946379e7Schristosmy $anonymous_hash = { 3328*946379e7Schristos planet => gettext "earth", 3329*946379e7Schristos cakes => ngettext "one cake", "several cakes", $n, 3330*946379e7Schristos still => $works, 3331*946379e7Schristos}; 3332*946379e7Schristos# The same without fat comma: 3333*946379e7Schristosmy $other_hash = { 3334*946379e7Schristos 'planet', gettext "earth", 3335*946379e7Schristos 'cakes', ngettext "one cake", "several cakes", $n, 3336*946379e7Schristos 'still', $works, 3337*946379e7Schristos}; 3338*946379e7Schristos 3339*946379e7Schristos# Parentheses are only significant for the first argument. 3340*946379e7Schristosprint dngettext 'package', ("one cake", "several cakes", $n), $discarded; 3341*946379e7Schristos</PRE> 3342*946379e7Schristos 3343*946379e7Schristos 3344*946379e7Schristos 3345*946379e7Schristos<H4><A NAME="SEC287" HREF="gettext_toc.html#TOC287">15.5.18.8 How To Grok with Long Lines</A></H4> 3346*946379e7Schristos<P> 3347*946379e7Schristos<A NAME="IDX1193"></A> 3348*946379e7Schristos 3349*946379e7Schristos</P> 3350*946379e7Schristos<P> 3351*946379e7SchristosThe necessity of long messages can often lead to a cumbersome or 3352*946379e7Schristosunreadable coding style. Perl has several options that may prevent 3353*946379e7Schristosyou from writing unreadable code, and 3354*946379e7Schristos<CODE>xgettext</CODE> does its best to do likewise. This is where the dot 3355*946379e7Schristosoperator (the string concatenation operator) may come in handy: 3356*946379e7Schristos 3357*946379e7Schristos</P> 3358*946379e7Schristos 3359*946379e7Schristos<PRE> 3360*946379e7Schristosprint gettext ("This is a very long" 3361*946379e7Schristos . " message that is still" 3362*946379e7Schristos . " readable, because" 3363*946379e7Schristos . " it is split into" 3364*946379e7Schristos . " multiple lines.\n"); 3365*946379e7Schristos</PRE> 3366*946379e7Schristos 3367*946379e7Schristos<P> 3368*946379e7SchristosPerl is smart enough to concatenate these constant string fragments 3369*946379e7Schristosinto one long string at compile time, and so is 3370*946379e7Schristos<CODE>xgettext</CODE>. You will only find one long message in the resulting 3371*946379e7SchristosPOT file. 3372*946379e7Schristos 3373*946379e7Schristos</P> 3374*946379e7Schristos<P> 3375*946379e7SchristosNote that the future Perl 6 will probably use the underscore 3376*946379e7Schristos(<SAMP>‘_’</SAMP>) as the string concatenation operator, and the dot 3377*946379e7Schristos(<SAMP>‘.’</SAMP>) for dereferencing. This new syntax is not yet supported by 3378*946379e7Schristos<CODE>xgettext</CODE>. 3379*946379e7Schristos 3380*946379e7Schristos</P> 3381*946379e7Schristos<P> 3382*946379e7SchristosIf embedded newline characters are not an issue, or even desired, you 3383*946379e7Schristosmay also insert newline characters inside quoted strings wherever you 3384*946379e7Schristosfeel like it: 3385*946379e7Schristos 3386*946379e7Schristos</P> 3387*946379e7Schristos 3388*946379e7Schristos<PRE> 3389*946379e7Schristosprint gettext ("<em>In HTML output 3390*946379e7Schristosembedded newlines are generally no 3391*946379e7Schristosproblem, since adjacent whitespace 3392*946379e7Schristosis always rendered into a single 3393*946379e7Schristosspace character.</em>"); 3394*946379e7Schristos</PRE> 3395*946379e7Schristos 3396*946379e7Schristos<P> 3397*946379e7SchristosYou may also consider to use here documents: 3398*946379e7Schristos 3399*946379e7Schristos</P> 3400*946379e7Schristos 3401*946379e7Schristos<PRE> 3402*946379e7Schristosprint gettext <<EOF; 3403*946379e7Schristos<em>In HTML output 3404*946379e7Schristosembedded newlines are generally no 3405*946379e7Schristosproblem, since adjacent whitespace 3406*946379e7Schristosis always rendered into a single 3407*946379e7Schristosspace character.</em> 3408*946379e7SchristosEOF 3409*946379e7Schristos</PRE> 3410*946379e7Schristos 3411*946379e7Schristos<P> 3412*946379e7SchristosPlease do not forget that the line breaks are real, i.e. they 3413*946379e7Schristostranslate into newline characters that will consequently show up in 3414*946379e7Schristosthe resulting POT file. 3415*946379e7Schristos 3416*946379e7Schristos</P> 3417*946379e7Schristos 3418*946379e7Schristos 3419*946379e7Schristos<H4><A NAME="SEC288" HREF="gettext_toc.html#TOC288">15.5.18.9 Bugs, Pitfalls, And Things That Do Not Work</A></H4> 3420*946379e7Schristos<P> 3421*946379e7Schristos<A NAME="IDX1194"></A> 3422*946379e7Schristos 3423*946379e7Schristos</P> 3424*946379e7Schristos<P> 3425*946379e7SchristosThe foregoing sections should have proven that 3426*946379e7Schristos<CODE>xgettext</CODE> is quite smart in extracting translatable strings from 3427*946379e7SchristosPerl sources. Yet, some more or less exotic constructs that could be 3428*946379e7Schristosexpected to work, actually do not work. 3429*946379e7Schristos 3430*946379e7Schristos</P> 3431*946379e7Schristos<P> 3432*946379e7SchristosOne of the more relevant limitations can be found in the 3433*946379e7Schristosimplementation of variable interpolation inside quoted strings. Only 3434*946379e7Schristossimple hash lookups can be used there: 3435*946379e7Schristos 3436*946379e7Schristos</P> 3437*946379e7Schristos 3438*946379e7Schristos<PRE> 3439*946379e7Schristosprint <<EOF; 3440*946379e7Schristos$gettext{"The dot operator" 3441*946379e7Schristos . " does not work" 3442*946379e7Schristos . "here!"} 3443*946379e7SchristosLikewise, you cannot @{[ gettext ("interpolate function calls") ]} 3444*946379e7Schristosinside quoted strings or quote-like expressions. 3445*946379e7SchristosEOF 3446*946379e7Schristos</PRE> 3447*946379e7Schristos 3448*946379e7Schristos<P> 3449*946379e7SchristosThis is valid Perl code and will actually trigger invocations of the 3450*946379e7Schristos<CODE>gettext</CODE> function at runtime. Yet, the Perl parser in 3451*946379e7Schristos<CODE>xgettext</CODE> will fail to recognize the strings. A less obvious 3452*946379e7Schristosexample can be found in the interpolation of regular expressions: 3453*946379e7Schristos 3454*946379e7Schristos</P> 3455*946379e7Schristos 3456*946379e7Schristos<PRE> 3457*946379e7Schristoss/<!--START_OF_WEEK-->/gettext ("Sunday")/e; 3458*946379e7Schristos</PRE> 3459*946379e7Schristos 3460*946379e7Schristos<P> 3461*946379e7SchristosThe modifier <CODE>e</CODE> will cause the substitution to be interpreted as 3462*946379e7Schristosan evaluable statement. Consequently, at runtime the function 3463*946379e7Schristos<CODE>gettext()</CODE> is called, but again, the parser fails to extract the 3464*946379e7Schristosstring “Sunday”. Use a temporary variable as a simple workaround if 3465*946379e7Schristosyou really happen to need this feature: 3466*946379e7Schristos 3467*946379e7Schristos</P> 3468*946379e7Schristos 3469*946379e7Schristos<PRE> 3470*946379e7Schristosmy $sunday = gettext "Sunday"; 3471*946379e7Schristoss/<!--START_OF_WEEK-->/$sunday/; 3472*946379e7Schristos</PRE> 3473*946379e7Schristos 3474*946379e7Schristos<P> 3475*946379e7SchristosHash slices would also be handy but are not recognized: 3476*946379e7Schristos 3477*946379e7Schristos</P> 3478*946379e7Schristos 3479*946379e7Schristos<PRE> 3480*946379e7Schristosmy @weekdays = @gettext{'Sunday', 'Monday', 'Tuesday', 'Wednesday', 3481*946379e7Schristos 'Thursday', 'Friday', 'Saturday'}; 3482*946379e7Schristos# Or even: 3483*946379e7Schristos@weekdays = @gettext{qw (Sunday Monday Tuesday Wednesday Thursday 3484*946379e7Schristos Friday Saturday) }; 3485*946379e7Schristos</PRE> 3486*946379e7Schristos 3487*946379e7Schristos<P> 3488*946379e7SchristosThis is perfectly valid usage of the tied hash <CODE>%gettext</CODE> but the 3489*946379e7Schristosstrings are not recognized and therefore will not be extracted. 3490*946379e7Schristos 3491*946379e7Schristos</P> 3492*946379e7Schristos<P> 3493*946379e7SchristosAnother caveat of the current version is its rudimentary support for 3494*946379e7Schristosnon-ASCII characters in identifiers. You may encounter serious 3495*946379e7Schristosproblems if you use identifiers with characters outside the range of 3496*946379e7Schristos'A'-'Z', 'a'-'z', '0'-'9' and the underscore '_'. 3497*946379e7Schristos 3498*946379e7Schristos</P> 3499*946379e7Schristos<P> 3500*946379e7SchristosMaybe some of these missing features will be implemented in future 3501*946379e7Schristosversions, but since you can always make do without them at minimal effort, 3502*946379e7Schristosthese todos have very low priority. 3503*946379e7Schristos 3504*946379e7Schristos</P> 3505*946379e7Schristos<P> 3506*946379e7SchristosA nasty problem are brace format strings that already contain braces 3507*946379e7Schristosas part of the normal text, for example the usage strings typically 3508*946379e7Schristosencountered in programs: 3509*946379e7Schristos 3510*946379e7Schristos</P> 3511*946379e7Schristos 3512*946379e7Schristos<PRE> 3513*946379e7Schristosdie "usage: $0 {OPTIONS} FILENAME...\n"; 3514*946379e7Schristos</PRE> 3515*946379e7Schristos 3516*946379e7Schristos<P> 3517*946379e7SchristosIf you want to internationalize this code with Perl brace format strings, 3518*946379e7Schristosyou will run into a problem: 3519*946379e7Schristos 3520*946379e7Schristos</P> 3521*946379e7Schristos 3522*946379e7Schristos<PRE> 3523*946379e7Schristosdie __x ("usage: {program} {OPTIONS} FILENAME...\n", program => $0); 3524*946379e7Schristos</PRE> 3525*946379e7Schristos 3526*946379e7Schristos<P> 3527*946379e7SchristosWhereas <SAMP>‘{program}’</SAMP> is a placeholder, <SAMP>‘{OPTIONS}’</SAMP> 3528*946379e7Schristosis not and should probably be translated. Yet, there is no way to teach 3529*946379e7Schristosthe Perl parser in <CODE>xgettext</CODE> to recognize the first one, and leave 3530*946379e7Schristosthe other one alone. 3531*946379e7Schristos 3532*946379e7Schristos</P> 3533*946379e7Schristos<P> 3534*946379e7SchristosThere are two possible work-arounds for this problem. If you are 3535*946379e7Schristossure that your program will run under Perl 5.8.0 or newer (these 3536*946379e7SchristosPerl versions handle positional parameters in <CODE>printf()</CODE>) or 3537*946379e7Schristosif you are sure that the translator will not have to reorder the arguments 3538*946379e7Schristosin her translation -- for example if you have only one brace placeholder 3539*946379e7Schristosin your string, or if it describes a syntax, like in this one --, you can 3540*946379e7Schristosmark the string as <CODE>no-perl-brace-format</CODE> and use <CODE>printf()</CODE>: 3541*946379e7Schristos 3542*946379e7Schristos</P> 3543*946379e7Schristos 3544*946379e7Schristos<PRE> 3545*946379e7Schristos# xgettext: no-perl-brace-format 3546*946379e7Schristosdie sprintf ("usage: %s {OPTIONS} FILENAME...\n", $0); 3547*946379e7Schristos</PRE> 3548*946379e7Schristos 3549*946379e7Schristos<P> 3550*946379e7SchristosIf you want to use the more portable Perl brace format, you will have to do 3551*946379e7Schristosput placeholders in place of the literal braces: 3552*946379e7Schristos 3553*946379e7Schristos</P> 3554*946379e7Schristos 3555*946379e7Schristos<PRE> 3556*946379e7Schristosdie __x ("usage: {program} {[}OPTIONS{]} FILENAME...\n", 3557*946379e7Schristos program => $0, '[' => '{', ']' => '}'); 3558*946379e7Schristos</PRE> 3559*946379e7Schristos 3560*946379e7Schristos<P> 3561*946379e7SchristosPerl brace format strings know no escaping mechanism. No matter how this 3562*946379e7Schristosescaping mechanism looked like, it would either give the programmer a 3563*946379e7Schristoshard time, make translating Perl brace format strings heavy-going, or 3564*946379e7Schristosresult in a performance penalty at runtime, when the format directives 3565*946379e7Schristosget executed. Most of the time you will happily get along with 3566*946379e7Schristos<CODE>printf()</CODE> for this special case. 3567*946379e7Schristos 3568*946379e7Schristos</P> 3569*946379e7Schristos 3570*946379e7Schristos 3571*946379e7Schristos<H3><A NAME="SEC289" HREF="gettext_toc.html#TOC289">15.5.19 PHP Hypertext Preprocessor</A></H3> 3572*946379e7Schristos<P> 3573*946379e7Schristos<A NAME="IDX1195"></A> 3574*946379e7Schristos 3575*946379e7Schristos</P> 3576*946379e7Schristos<DL COMPACT> 3577*946379e7Schristos 3578*946379e7Schristos<DT>RPMs 3579*946379e7Schristos<DD> 3580*946379e7Schristosmod_php4, mod_php4-core, phpdoc 3581*946379e7Schristos 3582*946379e7Schristos<DT>File extension 3583*946379e7Schristos<DD> 3584*946379e7Schristos<CODE>php</CODE>, <CODE>php3</CODE>, <CODE>php4</CODE> 3585*946379e7Schristos 3586*946379e7Schristos<DT>String syntax 3587*946379e7Schristos<DD> 3588*946379e7Schristos<CODE>"abc"</CODE>, <CODE>'abc'</CODE> 3589*946379e7Schristos 3590*946379e7Schristos<DT>gettext shorthand 3591*946379e7Schristos<DD> 3592*946379e7Schristos<CODE>_("abc")</CODE> 3593*946379e7Schristos 3594*946379e7Schristos<DT>gettext/ngettext functions 3595*946379e7Schristos<DD> 3596*946379e7Schristos<CODE>gettext</CODE>, <CODE>dgettext</CODE>, <CODE>dcgettext</CODE>; starting with PHP 4.2.0 3597*946379e7Schristosalso <CODE>ngettext</CODE>, <CODE>dngettext</CODE>, <CODE>dcngettext</CODE> 3598*946379e7Schristos 3599*946379e7Schristos<DT>textdomain 3600*946379e7Schristos<DD> 3601*946379e7Schristos<CODE>textdomain</CODE> function 3602*946379e7Schristos 3603*946379e7Schristos<DT>bindtextdomain 3604*946379e7Schristos<DD> 3605*946379e7Schristos<CODE>bindtextdomain</CODE> function 3606*946379e7Schristos 3607*946379e7Schristos<DT>setlocale 3608*946379e7Schristos<DD> 3609*946379e7SchristosProgrammer must call <CODE>setlocale (LC_ALL, "")</CODE> 3610*946379e7Schristos 3611*946379e7Schristos<DT>Prerequisite 3612*946379e7Schristos<DD> 3613*946379e7Schristos--- 3614*946379e7Schristos 3615*946379e7Schristos<DT>Use or emulate GNU gettext 3616*946379e7Schristos<DD> 3617*946379e7Schristosuse 3618*946379e7Schristos 3619*946379e7Schristos<DT>Extractor 3620*946379e7Schristos<DD> 3621*946379e7Schristos<CODE>xgettext</CODE> 3622*946379e7Schristos 3623*946379e7Schristos<DT>Formatting with positions 3624*946379e7Schristos<DD> 3625*946379e7Schristos<CODE>printf "%2\$d %1\$d"</CODE> 3626*946379e7Schristos 3627*946379e7Schristos<DT>Portability 3628*946379e7Schristos<DD> 3629*946379e7SchristosOn platforms without gettext, the functions are not available. 3630*946379e7Schristos 3631*946379e7Schristos<DT>po-mode marking 3632*946379e7Schristos<DD> 3633*946379e7Schristos--- 3634*946379e7Schristos</DL> 3635*946379e7Schristos 3636*946379e7Schristos<P> 3637*946379e7SchristosAn example is available in the <TT>‘examples’</TT> directory: <CODE>hello-php</CODE>. 3638*946379e7Schristos 3639*946379e7Schristos</P> 3640*946379e7Schristos 3641*946379e7Schristos 3642*946379e7Schristos<H3><A NAME="SEC290" HREF="gettext_toc.html#TOC290">15.5.20 Pike</A></H3> 3643*946379e7Schristos<P> 3644*946379e7Schristos<A NAME="IDX1196"></A> 3645*946379e7Schristos 3646*946379e7Schristos</P> 3647*946379e7Schristos<DL COMPACT> 3648*946379e7Schristos 3649*946379e7Schristos<DT>RPMs 3650*946379e7Schristos<DD> 3651*946379e7Schristosroxen 3652*946379e7Schristos 3653*946379e7Schristos<DT>File extension 3654*946379e7Schristos<DD> 3655*946379e7Schristos<CODE>pike</CODE> 3656*946379e7Schristos 3657*946379e7Schristos<DT>String syntax 3658*946379e7Schristos<DD> 3659*946379e7Schristos<CODE>"abc"</CODE> 3660*946379e7Schristos 3661*946379e7Schristos<DT>gettext shorthand 3662*946379e7Schristos<DD> 3663*946379e7Schristos--- 3664*946379e7Schristos 3665*946379e7Schristos<DT>gettext/ngettext functions 3666*946379e7Schristos<DD> 3667*946379e7Schristos<CODE>gettext</CODE>, <CODE>dgettext</CODE>, <CODE>dcgettext</CODE> 3668*946379e7Schristos 3669*946379e7Schristos<DT>textdomain 3670*946379e7Schristos<DD> 3671*946379e7Schristos<CODE>textdomain</CODE> function 3672*946379e7Schristos 3673*946379e7Schristos<DT>bindtextdomain 3674*946379e7Schristos<DD> 3675*946379e7Schristos<CODE>bindtextdomain</CODE> function 3676*946379e7Schristos 3677*946379e7Schristos<DT>setlocale 3678*946379e7Schristos<DD> 3679*946379e7Schristos<CODE>setlocale</CODE> function 3680*946379e7Schristos 3681*946379e7Schristos<DT>Prerequisite 3682*946379e7Schristos<DD> 3683*946379e7Schristos<CODE>import Locale.Gettext;</CODE> 3684*946379e7Schristos 3685*946379e7Schristos<DT>Use or emulate GNU gettext 3686*946379e7Schristos<DD> 3687*946379e7Schristosuse 3688*946379e7Schristos 3689*946379e7Schristos<DT>Extractor 3690*946379e7Schristos<DD> 3691*946379e7Schristos--- 3692*946379e7Schristos 3693*946379e7Schristos<DT>Formatting with positions 3694*946379e7Schristos<DD> 3695*946379e7Schristos--- 3696*946379e7Schristos 3697*946379e7Schristos<DT>Portability 3698*946379e7Schristos<DD> 3699*946379e7SchristosOn platforms without gettext, the functions are not available. 3700*946379e7Schristos 3701*946379e7Schristos<DT>po-mode marking 3702*946379e7Schristos<DD> 3703*946379e7Schristos--- 3704*946379e7Schristos</DL> 3705*946379e7Schristos 3706*946379e7Schristos 3707*946379e7Schristos 3708*946379e7Schristos<H3><A NAME="SEC291" HREF="gettext_toc.html#TOC291">15.5.21 GNU Compiler Collection sources</A></H3> 3709*946379e7Schristos<P> 3710*946379e7Schristos<A NAME="IDX1197"></A> 3711*946379e7Schristos 3712*946379e7Schristos</P> 3713*946379e7Schristos<DL COMPACT> 3714*946379e7Schristos 3715*946379e7Schristos<DT>RPMs 3716*946379e7Schristos<DD> 3717*946379e7Schristosgcc 3718*946379e7Schristos 3719*946379e7Schristos<DT>File extension 3720*946379e7Schristos<DD> 3721*946379e7Schristos<CODE>c</CODE>, <CODE>h</CODE>. 3722*946379e7Schristos 3723*946379e7Schristos<DT>String syntax 3724*946379e7Schristos<DD> 3725*946379e7Schristos<CODE>"abc"</CODE> 3726*946379e7Schristos 3727*946379e7Schristos<DT>gettext shorthand 3728*946379e7Schristos<DD> 3729*946379e7Schristos<CODE>_("abc")</CODE> 3730*946379e7Schristos 3731*946379e7Schristos<DT>gettext/ngettext functions 3732*946379e7Schristos<DD> 3733*946379e7Schristos<CODE>gettext</CODE>, <CODE>dgettext</CODE>, <CODE>dcgettext</CODE>, <CODE>ngettext</CODE>, 3734*946379e7Schristos<CODE>dngettext</CODE>, <CODE>dcngettext</CODE> 3735*946379e7Schristos 3736*946379e7Schristos<DT>textdomain 3737*946379e7Schristos<DD> 3738*946379e7Schristos<CODE>textdomain</CODE> function 3739*946379e7Schristos 3740*946379e7Schristos<DT>bindtextdomain 3741*946379e7Schristos<DD> 3742*946379e7Schristos<CODE>bindtextdomain</CODE> function 3743*946379e7Schristos 3744*946379e7Schristos<DT>setlocale 3745*946379e7Schristos<DD> 3746*946379e7SchristosProgrammer must call <CODE>setlocale (LC_ALL, "")</CODE> 3747*946379e7Schristos 3748*946379e7Schristos<DT>Prerequisite 3749*946379e7Schristos<DD> 3750*946379e7Schristos<CODE>#include "intl.h"</CODE> 3751*946379e7Schristos 3752*946379e7Schristos<DT>Use or emulate GNU gettext 3753*946379e7Schristos<DD> 3754*946379e7SchristosUse 3755*946379e7Schristos 3756*946379e7Schristos<DT>Extractor 3757*946379e7Schristos<DD> 3758*946379e7Schristos<CODE>xgettext -k_</CODE> 3759*946379e7Schristos 3760*946379e7Schristos<DT>Formatting with positions 3761*946379e7Schristos<DD> 3762*946379e7Schristos--- 3763*946379e7Schristos 3764*946379e7Schristos<DT>Portability 3765*946379e7Schristos<DD> 3766*946379e7SchristosUses autoconf macros 3767*946379e7Schristos 3768*946379e7Schristos<DT>po-mode marking 3769*946379e7Schristos<DD> 3770*946379e7Schristosyes 3771*946379e7Schristos</DL> 3772*946379e7Schristos 3773*946379e7Schristos 3774*946379e7Schristos 3775*946379e7Schristos<H2><A NAME="SEC292" HREF="gettext_toc.html#TOC292">15.6 Internationalizable Data</A></H2> 3776*946379e7Schristos 3777*946379e7Schristos<P> 3778*946379e7SchristosHere is a list of other data formats which can be internationalized 3779*946379e7Schristosusing GNU gettext. 3780*946379e7Schristos 3781*946379e7Schristos</P> 3782*946379e7Schristos 3783*946379e7Schristos 3784*946379e7Schristos 3785*946379e7Schristos<H3><A NAME="SEC293" HREF="gettext_toc.html#TOC293">15.6.1 POT - Portable Object Template</A></H3> 3786*946379e7Schristos 3787*946379e7Schristos<DL COMPACT> 3788*946379e7Schristos 3789*946379e7Schristos<DT>RPMs 3790*946379e7Schristos<DD> 3791*946379e7Schristosgettext 3792*946379e7Schristos 3793*946379e7Schristos<DT>File extension 3794*946379e7Schristos<DD> 3795*946379e7Schristos<CODE>pot</CODE>, <CODE>po</CODE> 3796*946379e7Schristos 3797*946379e7Schristos<DT>Extractor 3798*946379e7Schristos<DD> 3799*946379e7Schristos<CODE>xgettext</CODE> 3800*946379e7Schristos</DL> 3801*946379e7Schristos 3802*946379e7Schristos 3803*946379e7Schristos 3804*946379e7Schristos<H3><A NAME="SEC294" HREF="gettext_toc.html#TOC294">15.6.2 Resource String Table</A></H3> 3805*946379e7Schristos<P> 3806*946379e7Schristos<A NAME="IDX1198"></A> 3807*946379e7Schristos 3808*946379e7Schristos</P> 3809*946379e7Schristos<DL COMPACT> 3810*946379e7Schristos 3811*946379e7Schristos<DT>RPMs 3812*946379e7Schristos<DD> 3813*946379e7Schristosfpk 3814*946379e7Schristos 3815*946379e7Schristos<DT>File extension 3816*946379e7Schristos<DD> 3817*946379e7Schristos<CODE>rst</CODE> 3818*946379e7Schristos 3819*946379e7Schristos<DT>Extractor 3820*946379e7Schristos<DD> 3821*946379e7Schristos<CODE>xgettext</CODE>, <CODE>rstconv</CODE> 3822*946379e7Schristos</DL> 3823*946379e7Schristos 3824*946379e7Schristos 3825*946379e7Schristos 3826*946379e7Schristos<H3><A NAME="SEC295" HREF="gettext_toc.html#TOC295">15.6.3 Glade - GNOME user interface description</A></H3> 3827*946379e7Schristos 3828*946379e7Schristos<DL COMPACT> 3829*946379e7Schristos 3830*946379e7Schristos<DT>RPMs 3831*946379e7Schristos<DD> 3832*946379e7Schristosglade, libglade, glade2, libglade2, intltool 3833*946379e7Schristos 3834*946379e7Schristos<DT>File extension 3835*946379e7Schristos<DD> 3836*946379e7Schristos<CODE>glade</CODE>, <CODE>glade2</CODE> 3837*946379e7Schristos 3838*946379e7Schristos<DT>Extractor 3839*946379e7Schristos<DD> 3840*946379e7Schristos<CODE>xgettext</CODE>, <CODE>libglade-xgettext</CODE>, <CODE>xml-i18n-extract</CODE>, <CODE>intltool-extract</CODE> 3841*946379e7Schristos</DL> 3842*946379e7Schristos 3843*946379e7Schristos<P><HR><P> 3844*946379e7SchristosGo to the <A HREF="gettext_1.html">first</A>, <A HREF="gettext_14.html">previous</A>, <A HREF="gettext_16.html">next</A>, <A HREF="gettext_25.html">last</A> section, <A HREF="gettext_toc.html">table of contents</A>. 3845*946379e7Schristos</BODY> 3846*946379e7Schristos</HTML> 3847