xref: /netbsd-src/external/gpl2/gettext/dist/gettext-tools/doc/gettext_15.html (revision 946379e7b37692fc43f68eb0d1c10daa0a7f3b6c)
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>&#60;locale.h&#62;</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>&lsquo;po-mode.el&rsquo;</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>&lsquo;intl/&rsquo;</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>&lsquo;libintl.a&rsquo;</TT>
212*946379e7Schristosor <TT>&lsquo;libintl.so&rsquo;</TT> provides replacement functions, and GNU <CODE>&#60;libintl.h&#62;</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>&lsquo;I&rsquo;</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>&lsquo;outdigits&rsquo;</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>&lsquo;I&rsquo;</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>&lsquo;envsubst&rsquo;</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>&lsquo;bindWith:&rsquo;</SAMP> and
330*946379e7Schristos<SAMP>&lsquo;bindWithArguments:&rsquo;</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>&lsquo;%&rsquo;</SAMP> and is followed by <SAMP>&lsquo;%&rsquo;</SAMP>
333*946379e7Schristosor a nonzero digit (<SAMP>&lsquo;1&rsquo;</SAMP> to <SAMP>&lsquo;9&rsquo;</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>&lsquo;%&rsquo;</SAMP> and is followed by <SAMP>&lsquo;%&rsquo;</SAMP>
384*946379e7Schristosor a nonzero digit (<SAMP>&lsquo;1&rsquo;</SAMP> to <SAMP>&lsquo;9&rsquo;</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>&lsquo;format.n&rsquo;</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>&lsquo;perl-format&rsquo;</SAMP>,
403*946379e7Schristosand those acceptable to the <CODE>libintl-perl</CODE> function <CODE>__x</CODE>,
404*946379e7Schristoslabelled as <SAMP>&lsquo;perl-brace-format&rsquo;</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>&lsquo;man perlfunc&rsquo;</SAMP>.
410*946379e7Schristos
411*946379e7Schristos</P>
412*946379e7Schristos<P>
413*946379e7SchristosPerl brace format strings are described in the
414*946379e7Schristos<TT>&lsquo;Locale::TextDomain(3pm)&rsquo;</TT> manual page of the CPAN package
415*946379e7Schristoslibintl-perl.  In brief, Perl format uses placeholders put between
416*946379e7Schristosbraces (<SAMP>&lsquo;{&rsquo;</SAMP> and <SAMP>&lsquo;}&rsquo;</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>&lsquo;phpdoc/manual/function.sprintf.html&rsquo;</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>&lsquo;%&rsquo;</SAMP>, is optionally followed by a
437*946379e7Schristossize specifier <SAMP>&lsquo;l&rsquo;</SAMP>, an optional flag <SAMP>&lsquo;+&rsquo;</SAMP>, another optional flag
438*946379e7Schristos<SAMP>&lsquo;#&rsquo;</SAMP>, and is finished by a specifier: <SAMP>&lsquo;%&rsquo;</SAMP> denotes a literal
439*946379e7Schristospercent sign, <SAMP>&lsquo;c&rsquo;</SAMP> denotes a character, <SAMP>&lsquo;s&rsquo;</SAMP> denotes a string,
440*946379e7Schristos<SAMP>&lsquo;i&rsquo;</SAMP> and <SAMP>&lsquo;d&rsquo;</SAMP> denote an integer, <SAMP>&lsquo;o&rsquo;</SAMP>, <SAMP>&lsquo;u&rsquo;</SAMP>, <SAMP>&lsquo;x&rsquo;</SAMP>
441*946379e7Schristosdenote an unsigned integer, <SAMP>&lsquo;.*s&rsquo;</SAMP> denotes a string preceded by a
442*946379e7Schristoswidth specification, <SAMP>&lsquo;H&rsquo;</SAMP> denotes a <SAMP>&lsquo;location_t *&rsquo;</SAMP> pointer,
443*946379e7Schristos<SAMP>&lsquo;D&rsquo;</SAMP> denotes a general declaration, <SAMP>&lsquo;F&rsquo;</SAMP> denotes a function
444*946379e7Schristosdeclaration, <SAMP>&lsquo;T&rsquo;</SAMP> denotes a type, <SAMP>&lsquo;A&rsquo;</SAMP> denotes a function argument,
445*946379e7Schristos<SAMP>&lsquo;C&rsquo;</SAMP> denotes a tree code, <SAMP>&lsquo;E&rsquo;</SAMP> denotes an expression, <SAMP>&lsquo;L&rsquo;</SAMP>
446*946379e7Schristosdenotes a programming language, <SAMP>&lsquo;O&rsquo;</SAMP> denotes a binary operator,
447*946379e7Schristos<SAMP>&lsquo;P&rsquo;</SAMP> denotes a function parameter, <SAMP>&lsquo;Q&rsquo;</SAMP> denotes an assignment
448*946379e7Schristosoperator, <SAMP>&lsquo;V&rsquo;</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>&lsquo;%&rsquo;</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>&lsquo;%1$+5d&rsquo;</SAMP>, or may be surrounded by vertical bars, such as
472*946379e7Schristos<SAMP>&lsquo;%|1$+5d|&rsquo;</SAMP> or <SAMP>&lsquo;%|1$+5|&rsquo;</SAMP>, or consists of just an argument number
473*946379e7Schristosbetween percent signs, such as <SAMP>&lsquo;%1%&rsquo;</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>&lsquo;intl/&rsquo;</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>&lsquo;--intl&rsquo;</SAMP> option, and that he
492*946379e7Schristosinvokes the <CODE>AM_GNU_GETTEXT</CODE> autoconf macro via
493*946379e7Schristos<SAMP>&lsquo;AM_GNU_GETTEXT([external])&rsquo;</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>&lsquo;po/Makevars&rsquo;</TT> (see section <A HREF="gettext_13.html#SEC203">13.4.3  <TT>&lsquo;Makevars&rsquo;</TT> in <TT>&lsquo;po/&rsquo;</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>&lsquo;po/Makefile.in.in&rsquo;</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 &#60;libintl.h&#62;</CODE>
558*946379e7Schristos<BR><CODE>#include &#60;locale.h&#62;</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>&lsquo;examples&rsquo;</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>&lsquo;examples&rsquo;</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>&lsquo;echo&rsquo;</SAMP> or
756*946379e7Schristos<SAMP>&lsquo;$echo&rsquo;</SAMP> to <SAMP>&lsquo;gettext&rsquo;</SAMP> (if the string contains no references to
757*946379e7Schristosshell variables) or to <SAMP>&lsquo;eval_gettext&rsquo;</SAMP> (if it refers to shell variables),
758*946379e7Schristosfollowed by a no-argument <SAMP>&lsquo;echo&rsquo;</SAMP> command (to account for the terminating
759*946379e7Schristosnewline). Similarly, for cases with plural handling, replace a conditional
760*946379e7Schristos<SAMP>&lsquo;echo&rsquo;</SAMP> command with an invocation of <SAMP>&lsquo;ngettext&rsquo;</SAMP> or
761*946379e7Schristos<SAMP>&lsquo;eval_ngettext&rsquo;</SAMP>, followed by a no-argument <SAMP>&lsquo;echo&rsquo;</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>&lsquo;eval_gettext&rsquo;</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>&lsquo;echo&rsquo;</SAMP>, you can make it use <SAMP>&lsquo;echo&rsquo;</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>&lsquo;error&rsquo;</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>&lsquo;-d <VAR>textdomain</VAR>&rsquo;</SAMP>
858*946379e7Schristos<DD>
859*946379e7Schristos<DT><SAMP>&lsquo;--domain=<VAR>textdomain</VAR>&rsquo;</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>&lsquo;-e&rsquo;</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>&lsquo;echo&rsquo;</SAMP> program or shell built-in.  The escape sequences
871*946379e7Schristos<SAMP>&lsquo;\a&rsquo;</SAMP>, <SAMP>&lsquo;\b&rsquo;</SAMP>, <SAMP>&lsquo;\c&rsquo;</SAMP>, <SAMP>&lsquo;\f&rsquo;</SAMP>, <SAMP>&lsquo;\n&rsquo;</SAMP>, <SAMP>&lsquo;\r&rsquo;</SAMP>, <SAMP>&lsquo;\t&rsquo;</SAMP>,
872*946379e7Schristos<SAMP>&lsquo;\v&rsquo;</SAMP>, <SAMP>&lsquo;\\&rsquo;</SAMP>, and <SAMP>&lsquo;\&rsquo;</SAMP> followed by one to three octal digits, are
873*946379e7Schristosinterpreted like the System V <SAMP>&lsquo;echo&rsquo;</SAMP> program did.
874*946379e7Schristos
875*946379e7Schristos<DT><SAMP>&lsquo;-E&rsquo;</SAMP>
876*946379e7Schristos<DD>
877*946379e7Schristos<A NAME="IDX1128"></A>
878*946379e7SchristosThis option is only for compatibility with the <SAMP>&lsquo;echo&rsquo;</SAMP> program or shell
879*946379e7Schristosbuilt-in.  It has no effect.
880*946379e7Schristos
881*946379e7Schristos<DT><SAMP>&lsquo;-h&rsquo;</SAMP>
882*946379e7Schristos<DD>
883*946379e7Schristos<DT><SAMP>&lsquo;--help&rsquo;</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>&lsquo;-n&rsquo;</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>&lsquo;-V&rsquo;</SAMP>
896*946379e7Schristos<DD>
897*946379e7Schristos<DT><SAMP>&lsquo;--version&rsquo;</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>&lsquo;[<VAR>textdomain</VAR>] <VAR>msgid</VAR>&rsquo;</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>&lsquo;echo&rsquo;</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>&lsquo;-d <VAR>textdomain</VAR>&rsquo;</SAMP>
947*946379e7Schristos<DD>
948*946379e7Schristos<DT><SAMP>&lsquo;--domain=<VAR>textdomain</VAR>&rsquo;</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>&lsquo;-e&rsquo;</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>&lsquo;gettext&rsquo;</SAMP> program.  The escape sequences
960*946379e7Schristos<SAMP>&lsquo;\a&rsquo;</SAMP>, <SAMP>&lsquo;\b&rsquo;</SAMP>, <SAMP>&lsquo;\c&rsquo;</SAMP>, <SAMP>&lsquo;\f&rsquo;</SAMP>, <SAMP>&lsquo;\n&rsquo;</SAMP>, <SAMP>&lsquo;\r&rsquo;</SAMP>, <SAMP>&lsquo;\t&rsquo;</SAMP>,
961*946379e7Schristos<SAMP>&lsquo;\v&rsquo;</SAMP>, <SAMP>&lsquo;\\&rsquo;</SAMP>, and <SAMP>&lsquo;\&rsquo;</SAMP> followed by one to three octal digits, are
962*946379e7Schristosinterpreted like the System V <SAMP>&lsquo;echo&rsquo;</SAMP> program did.
963*946379e7Schristos
964*946379e7Schristos<DT><SAMP>&lsquo;-E&rsquo;</SAMP>
965*946379e7Schristos<DD>
966*946379e7Schristos<A NAME="IDX1140"></A>
967*946379e7SchristosThis option is only for compatibility with the <SAMP>&lsquo;gettext&rsquo;</SAMP> program.  It has
968*946379e7Schristosno effect.
969*946379e7Schristos
970*946379e7Schristos<DT><SAMP>&lsquo;-h&rsquo;</SAMP>
971*946379e7Schristos<DD>
972*946379e7Schristos<DT><SAMP>&lsquo;--help&rsquo;</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>&lsquo;-V&rsquo;</SAMP>
979*946379e7Schristos<DD>
980*946379e7Schristos<DT><SAMP>&lsquo;--version&rsquo;</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>&lsquo;<VAR>textdomain</VAR>&rsquo;</SAMP>
987*946379e7Schristos<DD>
988*946379e7SchristosRetrieve translated message from <VAR>textdomain</VAR>.
989*946379e7Schristos
990*946379e7Schristos<DT><SAMP>&lsquo;<VAR>msgid</VAR> <VAR>msgid-plural</VAR>&rsquo;</SAMP>
991*946379e7Schristos<DD>
992*946379e7SchristosTranslate <VAR>msgid</VAR> (English singular) / <VAR>msgid-plural</VAR> (English plural).
993*946379e7Schristos
994*946379e7Schristos<DT><SAMP>&lsquo;<VAR>count</VAR>&rsquo;</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>&lsquo;-v&rsquo;</SAMP>
1033*946379e7Schristos<DD>
1034*946379e7Schristos<DT><SAMP>&lsquo;--variables&rsquo;</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>&lsquo;-h&rsquo;</SAMP>
1049*946379e7Schristos<DD>
1050*946379e7Schristos<DT><SAMP>&lsquo;--help&rsquo;</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>&lsquo;-V&rsquo;</SAMP>
1057*946379e7Schristos<DD>
1058*946379e7Schristos<DT><SAMP>&lsquo;--version&rsquo;</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>&lsquo;eval&rsquo;</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>&lsquo;examples&rsquo;</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>&lsquo;examples&rsquo;</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>&lsquo;examples&rsquo;</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>&lsquo;examples&rsquo;</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&#62;&#62;#at:</CODE>, <CODE>LcMessagesDomain&#62;&#62;#at:plural:with:</CODE>
1629*946379e7Schristos
1630*946379e7Schristos<DT>textdomain
1631*946379e7Schristos<DD>
1632*946379e7Schristos<CODE>LcMessages&#62;&#62;#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&#62;&#62;#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>&lsquo;examples&rsquo;</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>&lsquo;examples&rsquo;</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>&lsquo;getString&rsquo;</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>&lsquo;Util&rsquo;</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>&lsquo;Util&rsquo;</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>&lsquo;S&rsquo;</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>&lsquo;--csharp-resources&rsquo;</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>&lsquo;--csharp-resources&rsquo;</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>&lsquo;examples&rsquo;</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>&lsquo;GetString&rsquo;</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>&lsquo;Util&rsquo;</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>&lsquo;S&rsquo;</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>&lsquo;examples&rsquo;</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>&lsquo;examples&rsquo;</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 &#60;wx/intl.h&#62;</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>&lsquo;examples&rsquo;</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>&lsquo;examples&rsquo;</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-&#62;{"message"}</CODE>
2646*946379e7Schristos
2647*946379e7Schristos<LI>etc., issue the command <SAMP>&lsquo;man perlsyn&rsquo;</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 =&#62; $oldvalue, new =&#62; $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>&lsquo;examples&rsquo;</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, "&#62;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 "&#62;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>&lsquo;testfile&rsquo;</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 &#60; 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 $__-&#62;{"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 &#60;E-mail: &#60;guido\@imperia.net&#62;&#62;;
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 &#60;E-mail: &#60;guido@imperia.net&#62;&#62;;
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 &#60;&#60;'EOF';
3053*946379e7Schristosprogram not found in $PATH
3054*946379e7SchristosEOF
3055*946379e7Schristos
3056*946379e7Schristosprint ngettext &#60;&#60;EOF, &#60;&#60;"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>&lsquo;man perlop&rsquo;</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 &#60;&#60;EOF;
3231*946379e7Schristos&#60;h1&#62;My Homepage&#60;/h1&#62;
3232*946379e7Schristos&#60;script language="JavaScript"&#62;&#60;!--
3233*946379e7Schristosfor (i = 0; i &#60; 100; ++i) {
3234*946379e7Schristos    alert ("Thank you so much for visiting my homepage!");
3235*946379e7Schristos}
3236*946379e7Schristos//--&#62;&#60;/script&#62;
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 &#60;&#60;EOF;
3252*946379e7Schristos&#60;h1&#62;$gettext{"My Homepage"}&#60;/h1&#62;
3253*946379e7Schristos&#60;script language="JavaScript"&#62;&#60;!--
3254*946379e7Schristosfor (i = 0; i &#60; 100; ++i) {
3255*946379e7Schristos    alert ("$gettext{'Thank you so much for visiting my homepage!'}");
3256*946379e7Schristos}
3257*946379e7Schristos//--&#62;&#60;/script&#62;
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>&lsquo;man perlop&rsquo;</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-&#62;{"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 =&#62; "Hello World!\n");
3318*946379e7Schristosprint dgettext $package, "Hello World!\n";
3319*946379e7Schristos
3320*946379e7Schristos# The "fat comma" =&#62; turns the left-hand side argument into a
3321*946379e7Schristos# single-quoted string!
3322*946379e7Schristosprint dgettext smellovision =&#62; "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 =&#62; gettext "earth",
3329*946379e7Schristos   cakes =&#62; ngettext "one cake", "several cakes", $n,
3330*946379e7Schristos   still =&#62; $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>&lsquo;_&rsquo;</SAMP>) as the string concatenation operator, and the dot
3377*946379e7Schristos(<SAMP>&lsquo;.&rsquo;</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 ("&#60;em&#62;In HTML output
3390*946379e7Schristosembedded newlines are generally no
3391*946379e7Schristosproblem, since adjacent whitespace
3392*946379e7Schristosis always rendered into a single
3393*946379e7Schristosspace character.&#60;/em&#62;");
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 &#60;&#60;EOF;
3403*946379e7Schristos&#60;em&#62;In HTML output
3404*946379e7Schristosembedded newlines are generally no
3405*946379e7Schristosproblem, since adjacent whitespace
3406*946379e7Schristosis always rendered into a single
3407*946379e7Schristosspace character.&#60;/em&#62;
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 &#60;&#60;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/&#60;!--START_OF_WEEK--&#62;/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/&#60;!--START_OF_WEEK--&#62;/$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 =&#62; $0);
3524*946379e7Schristos</PRE>
3525*946379e7Schristos
3526*946379e7Schristos<P>
3527*946379e7SchristosWhereas <SAMP>&lsquo;{program}&rsquo;</SAMP> is a placeholder, <SAMP>&lsquo;{OPTIONS}&rsquo;</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 =&#62; $0, '[' =&#62; '{', ']' =&#62; '}');
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>&lsquo;examples&rsquo;</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