1 <?xml version="1.0" encoding="UTF-8"?>
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
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.
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">
22 <refname>gettext</refname>
23 <refpurpose>indexes or/and translates some indexed english messages</refpurpose>
25 <refnamediv xml:id="_">
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, ..)
43 <title>Arguments</title>
46 <term>"The literal reference message"</term>
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 "%".
55 Only standard ASCII characters can be used. Any other extended ASCII or
56 UTF-8 characters would make gettext() failing.
65 single or array of case-sensitive messages identifiers (in english) to be
66 translated, in a variable.
69 Only standard ASCII characters can be used.
75 <term>translated</term>
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
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.
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
99 <varname>domain</varname> can indifferently be a literal or a variable.
100 It is case-sensitive.
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).
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>.
118 <title>Description</title>
120 <title>Harvesting messages and overall processing</title>
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
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>.
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.
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:
153 <th>#</th><th>Syntax</th><th>Status</th>
154 <th align="left">Harvesting results</th>
158 <td style="white-space:nowrap">
159 <literal>gettext("To be translated")</literal>
162 <td>standard syntax</td>
166 <td style="white-space:pre"><screen><![CDATA[
167 msg = "To be translated";
168 gettext(msg)]]></screen>
172 The text is in a variable. It is not a literal.
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>.
181 <td style="white-space:nowrap">
182 <literal>gettext("To be" + " translated")</literal>
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.
193 <td style="white-space:pre"><screen><![CDATA[
195 " translated")]]></screen>
202 <td style="white-space:nowrap">
203 <literal>gettext(["item#1", "item#2"])</literal>
206 <td>Only "item#1" is collected. "item#2" is ignored.</td>
210 <td style="white-space:nowrap">
211 <literal>gettext(["item#1" "item#2"])</literal>
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.
222 <td style="white-space:pre"><screen><![CDATA[
224 "item#2"])]]></screen>
231 <td style="white-space:nowrap">
232 <literal>gettext(["item#1" ; "item#2"])</literal>
235 <td>"item#1" and "item#2" are indexed as separate msgids.</td>
239 <td style="white-space:pre"><screen><![CDATA[
241 "item#2"])]]></screen>
245 Same as #8. Please take care of the semi-colon. Without it,
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.
258 Harvesting does not need to beforehand declare the
259 <varname>domain</varname> with
260 <literal>addlocalizationdomain()</literal>
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
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
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.
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.
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>
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
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
321 Limitations: There is no way to translate a message
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.
333 from a translated version rather than from the message id in english.
339 <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
341 <title>msgid messages</title>
343 To be correctly processed, english messages must comply with a few rules:
347 Literal harvestable messages may be indifferently delimited with single
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
356 For instance, <literal>_(my_domain, My message)</literal>
357 will be used instead of <literal>_("my_domain", "My message")</literal>.
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>.
370 Double quotes must be avoided in the body of messages. Please use single quotes.
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.
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.
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>.
393 <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
395 <title>msgstr translated messages</title>
397 This section will be more useful for translaters than for actual users.
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>.
407 This is of first importance for translaters, when writing the corresponding
408 <varname>translated</varname> message:
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):
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.
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."
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):
434 msgid "%s: Wrong number of input argument: %d to %d expected.\n"
435 msgstr "%1$s: 入力引数で不正な数: %3$d への %2$d を想定します。\n"
438 msprintf(gettext("%s: Wrong number of input argument: %d to %d expected.\n"), "myFun", 2, 5)
440 will return in a Scilab session set to english
441 "myFun: Wrong number of input argument: 2 to 5 expected."
443 while, in a Scilab session set to japanese
444 "myFun: 入力引数で不正な数: 5 への 2 を想定します。"
453 <title>Examples</title>
454 <programlisting role="example"><![CDATA[
457 // Messages ids are case-sensitive:
458 // "monday" is not an indexed native msgid, while "Monday" is:
459 gettext(["monday" ; "Monday"])
461 //_() is an alias of gettext():
464 // In Scilab, messages ids are in english:
466 _("Dimanche") // The french version can't be used as msgid
470 --> gettext(["monday" ; "Monday"])
479 --> setlanguage("ru");
489 Using a domain: Here, "tbx" is a predefined domain used to test translation features:
491 <programlisting role="example"><![CDATA[
493 msg = "%s: something not in Scilab.\n"; // unknown in the main native Scilab domain:
494 gettext(msg) // So, it is returned as is.
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.
500 // So, let's declare the domain:
501 addlocalizationdomain("tbx", "SCI/modules/localization/tests/unit_tests/locale");
502 gettext("tbx", msg) // Now it works
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.
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)]
513 --> msg = "%s: something not in Scilab.\n"; // unknown in the main native Scilab domain:
516 %s: something not in Scilab.\n
518 --> // Scilab does not know yet where to find the translation:
519 --> gettext("tbx", msg)
521 %s: something not in Scilab.\n
523 --> // We declare the domain:
524 --> addlocalizationdomain("tbx", "SCI/modules/localization/tests/unit_tests/locale");
525 --> gettext("tbx", msg) // Now it works
527 %s : it is true, that is not in Scilab.\n
529 --> msg = "%s: No more memory.\n";
530 --> [_(msg) ; _("tbx", msg)]
532 !%s : Plus de mémoire disponible.\n !
533 !%s : Overwrite Scilab translation.\n !
537 Messages with numbered C-like placeholders:
539 <programlisting role="example"><![CDATA[
541 msg = "%s: Unknown value %s for %s option"; // has already some translations
544 msprintf(t, "setdiff", "''f''", "''direction''")
548 msprintf(t, "setdiff", "''f''", "''direction''")
553 --> setlanguage("en");
556 "%s: Unknown value %s for %s option"
558 --> msprintf(t, "setdiff", "''f''", "''direction''")
560 "setdiff: Unknown value 'f' for 'direction' option"
563 --> setlanguage("ja");
566 "%1$s: %3$s オプション の未知の値 %2$s"
568 --> msprintf(t, "setdiff", "''f''", "''direction''")
570 "setdiff: 'direction' オプション の未知の値 'f'"
573 <refsection role="see also">
574 <title>See also</title>
575 <simplelist type="inline">
577 <link linkend="msprintf">msprintf</link>
580 <link linkend="setlanguage">setlanguage</link>
583 <link linkend="addlocalizationdomain">addlocalizationdomain</link>
586 <link linkend="tbx_generate_pofile">tbx_generate_pofile</link>
589 <link linkend="tbx_make">tbx_make . localization</link>
592 <link linkend="tbx_build_localization">tbx_build_localization</link>
595 <ulink url="https://www.gnu.org/software/gettext/">GNU gettext website</ulink>
600 <title>History</title>
603 <revnumber>5.5.0</revnumber>
604 <revdescription>Domain management added.</revdescription>
607 <revnumber>6.1.0</revnumber>
609 C-like placeholders in messages can now be numbered.