[doc] gettext printf_conversion mprintf msprintf mfprintf pages updated & fixed
[scilab.git] / scilab / modules / localization / help / en_US / gettext.xml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!--
3  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
4  * Copyright (C) 2007 - INRIA - Allan CORNET
5  * Copyright (C) 2007 - INRIA - Sylvestre LEDRU
6  * Copyright (C) 2012 - 2016 - Scilab Enterprises
7  * Copyright (C) 2018 - 2021 - Samuel GOUGEON
8  *
9  * This file is hereby licensed under the terms of the GNU GPL v2.0,
10  * pursuant to article 5.3.4 of the CeCILL v.2.1.
11  * This file was originally licensed under the terms of the CeCILL v2.1,
12  * and continues to be available under such terms.
13  * For more information, see the COPYING file which you should have received
14  * along with this program.
15  *
16  -->
17 <refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"
18         xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML"
19         xmlns:db="http://docbook.org/ns/docbook" xmlns:scilab="http://www.scilab.org"
20         xml:lang="en" xml:id="gettext">
21     <refnamediv>
22         <refname>gettext</refname>
23         <refpurpose>indexes or/and translates some indexed english messages</refpurpose>
24     </refnamediv>
25     <refnamediv xml:id="_">
26         <refname>_</refname>
27         <refpurpose>
28             Alias of gettext().
29         </refpurpose>
30     </refnamediv>
31     <refsynopsisdiv>
32         <title>Syntax</title>
33         <synopsis>
34             gettext("The literal reference message")
35             gettext(["item #1" ; "item#2"])
36             translated = gettext("The literal reference message")
37             translated = gettext(["item #1" ; "item#2"])
38             translated = gettext(msgid)
39             .. gettext(domain, ..)
40         </synopsis>
41     </refsynopsisdiv>
42     <refsection>
43         <title>Arguments</title>
44         <variablelist>
45             <varlistentry>
46                 <term>"The literal reference message"</term>
47                 <listitem>
48                     <para>
49                         Single case-sensitive literal text of an english message to be indexed or/and
50                         translated. A column of literal texts explicitly separated with
51                         semi-colons may also be specified. Messages can include some
52                         <link linkend="printf_conversion">C-like placeholders</link> starting with "%".
53                     </para>
54                     <warning>
55                         Only standard ASCII characters can be used. Any other extended ASCII or
56                         UTF-8 characters would make gettext() failing.
57                     </warning>
58                     <para/>
59                 </listitem>
60             </varlistentry>
61             <varlistentry>
62                 <term>msgid</term>
63                 <listitem>
64                     <para>
65                         single or array of case-sensitive messages identifiers (in english) to be
66                         translated, in a variable.
67                     </para>
68                     <warning>
69                         Only standard ASCII characters can be used.
70                     </warning>
71                     <para/>
72                 </listitem>
73             </varlistentry>
74             <varlistentry>
75                 <term>translated</term>
76                 <listitem>
77                     <para>
78                         Input messages translated in the current language of the Scilab session.
79                         If no translated version is available for an input message, the input
80                         version in english is returned. The input and output arrays have
81                         the same sizes.
82                     </para>
83                     <note>
84                         These messages are labelled <literal>msgstr</literal> and defined in
85                         the ./locales/*.po files. They can include extended ASCII or UTF-8 characters.
86                     </note>
87                     <para/>
88                 </listitem>
89             </varlistentry>
90             <varlistentry>
91                 <term>domain</term>
92                 <listitem>
93                     <para>
94                         word of text: the name of a domain. When localizing an external module,
95                         <varname>domain</varname> may be usually set to the technical name of the
96                         module.
97                     </para>
98                     <para>
99                         <varname>domain</varname> can indifferently be a literal or a variable.
100                         It is case-sensitive.
101                     </para>
102                     <para>
103                         <varname>domain</varname> is required by
104                         <literal>tbx_generate_pofile()</literal> to make the literal msgid string
105                         indexed (harvesting stage. See below).
106                     </para>
107                     <para>
108                         When <literal>gettext(domain, msgid)</literal> is used to retrieve the
109                         translated version, <varname>domain</varname> is used to get the path
110                         to the directory where translations are stored, as beforehand registered
111                         with <literal>addlocalizationdomain(domain, path)</literal>.
112                     </para>
113                 </listitem>
114             </varlistentry>
115         </variablelist>
116     </refsection>
117     <refsection>
118         <title>Description</title>
119         <refsect3>
120         <title>Harvesting messages and overall processing</title>
121         <para>
122             <emphasis role="italic">gettext</emphasis> is a free and open external application
123             shipped within Scilab to support multilinguism for messages. This support consists in
124             4 main stages:
125             <orderedlist>
126                 <listitem>
127                     <para>
128                         <emphasis role="bold">Harvesting</emphasis> messages among the code and
129                         <emphasis role="bold">indexing</emphasis> them to be
130                         translated. For an external module, this is explicitly performed with the
131                         <literal>xgettext</literal> external binary, that is part of the
132                         <literal>gettext</literal> external application, and that is called by the
133                         <link linkend="tbx_generate_pofile">tbx_generate_pofile</link> Scilab function.
134                         In Scilab, it is also possible to use <literal>tbx_build_localization(..)</literal>
135                         or <literal>tbx_make . localization</literal>, that both call
136                         <literal>tbx_generate_pofile(..)</literal>.
137                     </para>
138                     <para>
139                         Each collected message is considered as an identifier (a message id, = msgid)
140                         for all its forthcoming translations. In Scilab, the reference language for
141                         identifiers is <emphasis role="italic">english</emphasis>.
142                         Therefore, the msgids to be indexed must be written in english.
143                     </para>
144                     <para>
145                         Only <emphasis role="bold">single literal and in one piece messages</emphasis>
146                         being as <literal>gettext</literal> input argument are collected. Hence,
147                         the following syntaxes and cases won't index the considered message, and no
148                         further translated versions will be available:
149                     </para>
150                     <para>
151                         <table>
152                             <tr>
153                                 <th>#</th><th>Syntax</th><th>Status</th>
154                                 <th align="left">Harvesting results</th>
155                             </tr>
156                             <tr valign="top">
157                                 <th>1</th>
158                                 <td style="white-space:nowrap">
159                                     <literal>gettext("To be translated")</literal>
160                                 </td>
161                                 <td>OK</td>
162                                 <td>standard syntax</td>
163                             </tr>
164                             <tr valign="top">
165                                 <th>2</th>
166                                 <td style="white-space:pre"><screen><![CDATA[
167 msg = "To be translated";
168 gettext(msg)]]></screen>
169                                 </td>
170                                 <td>NOK</td>
171                                 <td>
172                                     The text is in a variable. It is not a literal.
173                                     It won't be indexed.
174                                     Nevertheless, this syntax will work to <emphasis>retrieve</emphasis>
175                                     the translated version, <emphasis>provided that the message
176                                     has been collected elsewhere in a right way</emphasis>.
177                                 </td>
178                             </tr>
179                             <tr valign="top">
180                                 <th>3</th>
181                                 <td style="white-space:nowrap">
182                                     <literal>gettext("To be" + " translated")</literal>
183                                 </td>
184                                 <td>NOK</td>
185                                 <td>
186                                     "To be" and " translated" are indexed as 2 separate msgid.
187                                     Then, since the concatenated msgid "To be translated" does not exist,
188                                     retrieving its translation will fail.
189                                 </td>
190                             </tr>
191                             <tr valign="top">
192                                 <th>4</th>
193                                 <td style="white-space:pre"><screen><![CDATA[
194 gettext("To be" + ..
195         " translated")]]></screen>
196                                 </td>
197                                 <td>NOK</td>
198                                 <td>Same as #3</td>
199                             </tr>
200                             <tr valign="top">
201                                 <th>5</th>
202                                 <td style="white-space:nowrap">
203                                     <literal>gettext(["item#1", "item#2"])</literal>
204                                 </td>
205                                 <td>NOK</td>
206                                 <td>Only "item#1" is collected. "item#2" is ignored.</td>
207                             </tr>
208                             <tr valign="top">
209                                 <th>6</th>
210                                 <td style="white-space:nowrap">
211                                     <literal>gettext(["item#1"  "item#2"])</literal>
212                                 </td>
213                                 <td>NOK</td>
214                                 <td>
215                                     "item#1item#2" is indexed. Then, since "item#1" and "item#2"
216                                     are unknown separate msgid, retrieving their respective
217                                     translation will fail.
218                                 </td>
219                             </tr>
220                             <tr valign="top">
221                                 <th>7</th>
222                                 <td style="white-space:pre"><screen><![CDATA[
223 gettext(["item#1"
224          "item#2"])]]></screen>
225                                 </td>
226                                 <td>NOK</td>
227                                 <td>Same as #6</td>
228                             </tr>
229                             <tr valign="top">
230                                 <th>8</th>
231                                 <td style="white-space:nowrap">
232                                     <literal>gettext(["item#1" ; "item#2"])</literal>
233                                 </td>
234                                 <td>OK</td>
235                                 <td>"item#1" and "item#2" are indexed as separate msgids.</td>
236                             </tr>
237                             <tr valign="top">
238                                 <th>9</th>
239                                 <td style="white-space:pre"><screen><![CDATA[
240 gettext(["item#1" ;
241          "item#2"])]]></screen>
242                                 </td>
243                                 <td>OK</td>
244                                 <td>
245                                     Same as #8. Please take care of the semi-colon. Without it,
246                                     the case #7 fails.
247                                 </td>
248                             </tr>
249                         </table>
250                     </para>
251                     <important>
252                         For an external module,
253                         <link linkend="tbx_generate_pofile">tbx_generate_pofile()</link>
254                         harvests only <literal>gettext</literal> occurrences that specify a
255                         <varname>domain</varname>. It ignores any call to <literal>gettext</literal>
256                         with only one input argument.
257                         <para>
258                             Harvesting does not need to beforehand declare the
259                             <varname>domain</varname> with
260                             <literal>addlocalizationdomain()</literal>
261                         </para>
262                     </important>
263                     <para/>
264                 </listitem>
265                 <listitem>
266                     <para>
267                         All indexed texts are then translated by the author of the code or by some
268                         contributors. Anyway, by some humans. Good translation tools are also available
269                         online.
270                     </para>
271                     <para/>
272                 </listitem>
273                 <listitem>
274                     <para>
275                         All translated versions are bundled in a way that <literal>gettext(..)</literal>
276                         becomes efficient to retrieve the version in the current session's language.
277                         This is done by running <literal>tbx_generate_pofile()</literal> another
278                         time.
279                     </para>
280                     <para/>
281                 </listitem>
282                 <listitem>
283                     <para>
284                         Finally, some calls like <literal>gettext(message)</literal> or
285                         <literal>gettext("The message content")</literal> are used to retrieve and
286                         return the translated version.
287                     </para>
288                     <para>
289                         When the message is not a native Scilab one (for instance it is specific
290                         to an external module), the <varname>domain</varname> where the message
291                         and its translations can be found must be specified, as in
292                         <literal>gettext(domain, message)</literal>
293                         or <literal>gettext(domain, "The message content")</literal>.
294                         In this case, <literal>addlocalizationdomain(domain, path)</literal> must
295                         be run before, in order to indicate to Scilab the directory where
296                         the translated messages of the given <varname>domain</varname> are stored.
297                     </para>
298                 </listitem>
299             </orderedlist>
300         </para>
301         <para>
302             Most often, a message is declared to be harvested and is used to retrieve its
303             translated version through the same <literal>gettext("The literal message")</literal>
304             call.
305             However, it is not mandatory. Hence, a piece of code like
306             <literal>if %F, gettext("The literal message"), end</literal> will never execute
307             the <literal>gettext</literal> call, but is nevertherless meaningfull: It is here only
308             to make the message visible to the <literal>xgettext</literal> scanner/harvester.
309             Then, somewhere else in the code, it will be possible to use
310             <literal>msg = "The literal message"; gettext(msg)</literal> to return the translated
311             version.
312         </para>
313         <para>
314             As well, using several times the same literal
315             <literal>gettext("The literal message")</literal> call won't be rare, for example to
316             retrieve the translation in several files. In this case, the <literal>xgettext</literal>
317             harvester will collect the message only once, and the same translation will be returned
318             for all calls.
319         </para>
320         <warning>
321             Limitations: There is no way to translate a message
322             <itemizedlist>
323                 <listitem>
324                     <para>
325                     in a language other than the current session's one. If this is really required,
326                     the session's language will have to be temporarily switched to the desired
327                     language, then <literal>gettext()</literal> called, and at last the initial
328                     session's language restored.
329                     </para>
330                 </listitem>
331                 <listitem>
332                     <para>
333                         from a translated version rather than from the message id in english.
334                     </para>
335                 </listitem>
336             </itemizedlist>
337         </warning>
338         </refsect3>
339         <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
340         <refsect3>
341             <title>msgid messages</title>
342             <para>
343                 To be correctly processed, english messages must comply with a few rules:
344                 <itemizedlist>
345                     <listitem>
346                         <para>
347                             Literal harvestable messages may be indifferently delimited with single
348                             or double quotes.
349                         </para>
350                         <warning>
351                             When <literal>gettext()</literal> or <literal>_()</literal> is used in
352                             a XML or XSL file such as in the preferences files of an external module,
353                             the literal domain string and the literal message id must no longer be
354                             delimited.
355                             <para/>
356                             For instance, <literal>_(my_domain, My message)</literal>
357                             will be used instead of <literal>_("my_domain", "My message")</literal>.
358                             <para>
359                                 In addition, spaces before and after the messageID are then never
360                                 taken into account and never belong to the message. For example,
361                                 the actual message ID corresponding to
362                                 <literal>_(my_domain, My message:  )</literal> is
363                                 <literal>"My message:"</literal>, not
364                                 <literal>" My message:  "</literal>.
365                             </para>
366                         </warning>
367                     </listitem>
368                     <listitem>
369                         <para>
370                         Double quotes must be avoided in the body of messages. Please use single quotes.
371                         </para>
372                     </listitem>
373                     <listitem>
374                         <para>
375                         Inner escaped sequences like "\t" "\n" etc are not interpreted, neither by
376                         the <literal>xgettext</literal> scanner nor by the <literal>gettext</literal>
377                         function. They are collected and stored as is in the messages.
378                         </para>
379                     </listitem>
380                     <listitem>
381                         <para>
382                             msgid messages often include some "%" C-like placeholders
383                             aiming to be replaced with some custom input data through
384                             <literal>msprintf()</literal> at run time.
385                             For instance,
386                             <literal>msprintf("Hi %s, could you come at %s today?", "John", "12:30")</literal>
387                             will return <literal>"Hi John, could you come at 12:30 today?"</literal>.
388                         </para>
389                     </listitem>
390                 </itemizedlist>
391             </para>
392         </refsect3>
393         <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
394         <refsect3>
395             <title>msgstr translated messages</title>
396             <para>
397                 This section will be more useful for translaters than for actual users.
398             </para>
399             <para>
400                 When an english msgid message includes some C-like placeholders,
401                 this always means that in the code the <varname>translated</varname> message
402                 is processed with msprintf() to replace placeholders with actual values.
403                 Hence, <emphasis>the order and type of placeholders indicate the order and
404                 types of actual input values when calling msprintf</emphasis>.
405                 </para>
406                 <para>
407                 This is of first importance for translaters, when writing the corresponding
408                 <varname>translated</varname> message:
409                 <itemizedlist>
410                     <listitem>
411                         If placeholders are not numbered: they must be in the same order and
412                         types in the <varname>translated</varname> <literal>msgstr</literal>
413                         message than in the <varname>msgid</varname> message. Example (english to french):
414                         <screen>
415 msgid  "%s is %d year old.\n"
416 msgstr "%s a %d ans.\n"
417 // first %s (a string), second %d (a decimal number), in both strings.
418
419 Then, from a Scilab session set to french, we will get
420 gettext("%s is %d year old.\n") // => "%s a %d ans.\n"
421 // and                                     first v      v second
422 t = msprintf(gettext("%s is %d year old.\n"), "Peter", 18)
423 // => "Peter a 18 ans."
424 </screen>
425                     </listitem>
426                     <listitem>
427                         <para>
428                             Otherwise,
429                             <emphasis>All</emphasis> placeholders must be numbered in the
430                             <varname>translated</varname> message. Each numbered placeholder can
431                                                         be used only once in the format (Scilab limitation).
432                             Example (english to japanese):
433                             <screen>
434 msgid "%s: Wrong number of input argument: %d to %d expected.\n"
435 msgstr "%1$s: 入力引数で不正な数: %3$d への %2$d を想定します。\n"
436
437 Then,
438 msprintf(gettext("%s: Wrong number of input argument: %d to %d expected.\n"), "myFun", 2, 5)
439
440 will return in a Scilab session set to english
441 "myFun: Wrong number of input argument: 2 to 5 expected."
442
443 while, in a Scilab session set to japanese
444 "myFun: 入力引数で不正な数: 5 への 2 を想定します。"
445 </screen>
446                         </para>
447                     </listitem>
448                 </itemizedlist>
449             </para>
450         </refsect3>
451     </refsection>
452     <refsection>
453         <title>Examples</title>
454         <programlisting role="example"><![CDATA[
455 setlanguage("fr");
456
457 // Messages ids are case-sensitive:
458 // "monday" is not an indexed native msgid, while "Monday" is:
459 gettext(["monday" ; "Monday"])
460
461 //_() is an alias of gettext():
462 _("Sunday")
463
464 // In Scilab, messages ids are in english:
465 setlanguage("ru");
466 _("Dimanche")       // The french version can't be used as msgid
467 _("Sunday")
468  ]]></programlisting>
469     <screen><![CDATA[
470 --> gettext(["monday" ; "Monday"])
471  ans  =
472 !monday  !
473 !Lundi   !
474
475 --> _("Sunday")
476  ans  =
477  Dimanche
478
479 --> setlanguage("ru");
480 --> _("Dimanche")
481  ans  =
482  Dimanche
483
484 --> _("Sunday")
485  ans  =
486  Воскресенье
487 ]]></screen>
488     <para>
489         Using a domain: Here, "tbx" is a predefined domain used to test translation features:
490     </para>
491         <programlisting role="example"><![CDATA[
492 setlanguage("fr");
493 msg = "%s: something not in Scilab.\n";  // unknown in the main native Scilab domain:
494 gettext(msg)          // So, it is returned as is.
495
496 //  If we use the domain without having declared it before,
497 //  Scilab does not know where to find the translation:
498 gettext("tbx", msg)   // The input message is still returned as is.
499
500 // So, let's declare the domain:
501 addlocalizationdomain("tbx", "SCI/modules/localization/tests/unit_tests/locale");
502 gettext("tbx", msg)   // Now it works
503
504 // The answer is a joke: Here it is still in english (while french is expected).
505 // The point is that it has been set as the french translation of the input msgid.
506
507 // The same msgid can be used as a native Scilab one with its native translations,
508 // and in one or several domains, with other translations:
509 msg = "%s: No more memory.\n";
510 [_(msg) ; _("tbx", msg)]
511  ]]></programlisting>
512     <screen><![CDATA[
513 --> msg = "%s: something not in Scilab.\n"; // unknown in the main native Scilab domain:
514 --> gettext(msg)
515  ans  =
516  %s: something not in Scilab.\n
517
518 --> //  Scilab does not know yet where to find the translation:
519 --> gettext("tbx", msg)
520  ans  =
521  %s: something not in Scilab.\n
522
523 --> // We declare the domain:
524 --> addlocalizationdomain("tbx", "SCI/modules/localization/tests/unit_tests/locale");
525 --> gettext("tbx", msg)   // Now it works
526  ans  =
527  %s : it is true, that is not in Scilab.\n
528
529 --> msg = "%s: No more memory.\n";
530 --> [_(msg) ; _("tbx", msg)]
531  ans  =
532 !%s : Plus de mémoire disponible.\n    !
533 !%s : Overwrite Scilab translation.\n  !
534 ]]></screen>
535     <para/>
536     <para>
537         Messages with numbered C-like placeholders:
538     </para>
539         <programlisting role="example"><![CDATA[
540 in = getlanguage();
541 msg = "%s: Unknown value %s for %s option"; // has already some translations
542 setlanguage("en");
543 t = gettext(msg)
544 msprintf(t, "setdiff", "''f''", "''direction''")
545
546 setlanguage("ja");
547 t = gettext(msg)
548 msprintf(t, "setdiff", "''f''", "''direction''")
549
550 setlanguage(in);
551  ]]></programlisting>
552     <screen><![CDATA[
553 --> setlanguage("en");
554 --> t = gettext(msg)
555  t  =
556   "%s: Unknown value %s for %s option"
557
558 --> msprintf(t, "setdiff", "''f''", "''direction''")
559  ans  =
560   "setdiff: Unknown value 'f' for 'direction' option"
561
562
563 --> setlanguage("ja");
564 --> t = gettext(msg)
565  t  =
566   "%1$s: %3$s オプション の未知の値 %2$s"
567
568 --> msprintf(t, "setdiff", "''f''", "''direction''")
569  ans  =
570   "setdiff: 'direction' オプション の未知の値 'f'"
571 ]]></screen>
572     </refsection>
573     <refsection role="see also">
574         <title>See also</title>
575         <simplelist type="inline">
576             <member>
577                 <link linkend="msprintf">msprintf</link>
578             </member>
579             <member>
580                 <link linkend="setlanguage">setlanguage</link>
581             </member>
582             <member>
583                 <link linkend="addlocalizationdomain">addlocalizationdomain</link>
584             </member>
585             <member>
586                 <link linkend="tbx_generate_pofile">tbx_generate_pofile</link>
587             </member>
588             <member>
589                 <link linkend="tbx_make">tbx_make . localization</link>
590             </member>
591             <member>
592                 <link linkend="tbx_build_localization">tbx_build_localization</link>
593             </member>
594             <member>
595                 <ulink url="https://www.gnu.org/software/gettext/">GNU gettext website</ulink>
596             </member>
597         </simplelist>
598     </refsection>
599     <refsection>
600         <title>History</title>
601         <revhistory>
602             <revision>
603                 <revnumber>5.5.0</revnumber>
604                 <revdescription>Domain management added.</revdescription>
605             </revision>
606             <revision>
607                 <revnumber>6.1.0</revnumber>
608                 <revdescription>
609                     C-like placeholders in messages can now be numbered.
610                 </revdescription>
611             </revision>
612         </revhistory>
613     </refsection>
614 </refentry>