]> begriffs open source - ai-pg/blob - full-docs/txt/nls-programmer.txt
Convert HTML docs to more streamlined TXT
[ai-pg] / full-docs / txt / nls-programmer.txt
1
2 56.2. For the Programmer #
3
4    56.2.1. Mechanics
5    56.2.2. Message-Writing Guidelines
6
7 56.2.1. Mechanics #
8
9    This section describes how to implement native language support in a
10    program or library that is part of the PostgreSQL distribution.
11    Currently, it only applies to C programs.
12
13    Adding NLS Support to a Program
14     1. Insert this code into the start-up sequence of the program:
15 #ifdef ENABLE_NLS
16 #include <locale.h>
17 #endif
18
19 ...
20
21 #ifdef ENABLE_NLS
22 setlocale(LC_ALL, "");
23 bindtextdomain("progname", LOCALEDIR);
24 textdomain("progname");
25 #endif
26
27        (The progname can actually be chosen freely.)
28     2. Wherever a message that is a candidate for translation is found, a
29        call to gettext() needs to be inserted. E.g.:
30 fprintf(stderr, "panic level %d\n", lvl);
31
32        would be changed to:
33 fprintf(stderr, gettext("panic level %d\n"), lvl);
34
35        (gettext is defined as a no-op if NLS support is not configured.)
36        This tends to add a lot of clutter. One common shortcut is to use:
37 #define _(x) gettext(x)
38
39        Another solution is feasible if the program does much of its
40        communication through one or a few functions, such as ereport() in
41        the backend. Then you make this function call gettext internally on
42        all input strings.
43     3. Add a file nls.mk in the directory with the program sources. This
44        file will be read as a makefile. The following variable assignments
45        need to be made here:
46
47         CATALOG_NAME
48                 The program name, as provided in the textdomain() call.
49
50         GETTEXT_FILES
51                 List of files that contain translatable strings, i.e.,
52                 those marked with gettext or an alternative solution.
53                 Eventually, this will include nearly all source files of
54                 the program. If this list gets too long you can make the
55                 first “file” be a + and the second word be a file that
56                 contains one file name per line.
57
58         GETTEXT_TRIGGERS
59                 The tools that generate message catalogs for the
60                 translators to work on need to know what function calls
61                 contain translatable strings. By default, only gettext()
62                 calls are known. If you used _ or other identifiers you
63                 need to list them here. If the translatable string is not
64                 the first argument, the item needs to be of the form
65                 func:2 (for the second argument). If you have a function
66                 that supports pluralized messages, the item should look
67                 like func:1,2 (identifying the singular and plural message
68                 arguments).
69
70     4. Add a file po/LINGUAS, which will contain the list of provided
71        translations — initially empty.
72
73    The build system will automatically take care of building and
74    installing the message catalogs.
75
76 56.2.2. Message-Writing Guidelines #
77
78    Here are some guidelines for writing messages that are easily
79    translatable.
80      * Do not construct sentences at run-time, like:
81 printf("Files were %s.\n", flag ? "copied" : "removed");
82
83        The word order within the sentence might be different in other
84        languages. Also, even if you remember to call gettext() on each
85        fragment, the fragments might not translate well separately. It's
86        better to duplicate a little code so that each message to be
87        translated is a coherent whole. Only numbers, file names, and
88        such-like run-time variables should be inserted at run time into a
89        message text.
90      * For similar reasons, this won't work:
91 printf("copied %d file%s", n, n!=1 ? "s" : "");
92
93        because it assumes how the plural is formed. If you figured you
94        could solve it like this:
95 if (n==1)
96     printf("copied 1 file");
97 else
98     printf("copied %d files", n):
99
100        then be disappointed. Some languages have more than two forms, with
101        some peculiar rules. It's often best to design the message to avoid
102        the issue altogether, for instance like this:
103 printf("number of copied files: %d", n);
104
105        If you really want to construct a properly pluralized message,
106        there is support for this, but it's a bit awkward. When generating
107        a primary or detail error message in ereport(), you can write
108        something like this:
109 errmsg_plural("copied %d file",
110               "copied %d files",
111               n,
112               n)
113
114        The first argument is the format string appropriate for English
115        singular form, the second is the format string appropriate for
116        English plural form, and the third is the integer control value
117        that determines which plural form to use. Subsequent arguments are
118        formatted per the format string as usual. (Normally, the
119        pluralization control value will also be one of the values to be
120        formatted, so it has to be written twice.) In English it only
121        matters whether n is 1 or not 1, but in other languages there can
122        be many different plural forms. The translator sees the two English
123        forms as a group and has the opportunity to supply multiple
124        substitute strings, with the appropriate one being selected based
125        on the run-time value of n.
126        If you need to pluralize a message that isn't going directly to an
127        errmsg or errdetail report, you have to use the underlying function
128        ngettext. See the gettext documentation.
129      * If you want to communicate something to the translator, such as
130        about how a message is intended to line up with other output,
131        precede the occurrence of the string with a comment that starts
132        with translator, e.g.:
133 /* translator: This message is not what it seems to be. */
134
135        These comments are copied to the message catalog files so that the
136        translators can see them.