gettext: Mark Keywords

1 
1 4.4 How Marks Appear in Sources
1 ===============================
1 
1    All strings requiring translation should be marked in the C sources.
1 Marking is done in such a way that each translatable string appears to
1 be the sole argument of some function or preprocessor macro.  There are
1 only a few such possible functions or macros meant for translation, and
1 their names are said to be marking keywords.  The marking is attached to
1 strings themselves, rather than to what we do with them.  This approach
1 has more uses.  A blatant example is an error message produced by
1 formatting.  The format string needs translation, as well as some
1 strings inserted through some ‘%s’ specification in the format, while
1 the result from ‘sprintf’ may have so many different instances that it
1 is impractical to list them all in some ‘error_string_out()’ routine,
1 say.
1 
1    This marking operation has two goals.  The first goal of marking is
1 for triggering the retrieval of the translation, at run time.  The
1 keyword is possibly resolved into a routine able to dynamically return
1 the proper translation, as far as possible or wanted, for the argument
1 string.  Most localizable strings are found in executable positions,
1 that is, attached to variables or given as parameters to functions.  But
1 this is not universal usage, and some translatable strings appear in
1 structured initializations.  ⇒Special cases.
1 
1    The second goal of the marking operation is to help ‘xgettext’ at
1 properly extracting all translatable strings when it scans a set of
1 program sources and produces PO file templates.
1 
1    The canonical keyword for marking translatable strings is ‘gettext’,
1 it gave its name to the whole GNU ‘gettext’ package.  For packages
1 making only light use of the ‘gettext’ keyword, macro or function, it is
1 easily used _as is_.  However, for packages using the ‘gettext’
1 interface more heavily, it is usually more convenient to give the main
1 keyword a shorter, less obtrusive name.  Indeed, the keyword might
1 appear on a lot of strings all over the package, and programmers usually
1 do not want nor need their program sources to remind them forcefully,
1 all the time, that they are internationalized.  Further, a long keyword
1 has the disadvantage of using more horizontal space, forcing more
1 indentation work on sources for those trying to keep them within 79 or
1 80 columns.
1 
1    Many packages use ‘_’ (a simple underline) as a keyword, and write
1 ‘_("Translatable string")’ instead of ‘gettext ("Translatable string")’.
1 Further, the coding rule, from GNU standards, wanting that there is a
1 space between the keyword and the opening parenthesis is relaxed, in
1 practice, for this particular usage.  So, the textual overhead per
1 translatable string is reduced to only three characters: the underline
1 and the two parentheses.  However, even if GNU ‘gettext’ uses this
1 convention internally, it does not offer it officially.  The real,
1 genuine keyword is truly ‘gettext’ indeed.  It is fairly easy for those
1 wanting to use ‘_’ instead of ‘gettext’ to declare:
1 
1      #include <libintl.h>
1      #define _(String) gettext (String)
1 
1 instead of merely using ‘#include <libintl.h>’.
1 
1    The marking keywords ‘gettext’ and ‘_’ take the translatable string
1 as sole argument.  It is also possible to define marking functions that
1 take it at another argument position.  It is even possible to make the
1 marked argument position depend on the total number of arguments of the
1 function call; this is useful in C++.  All this is achieved using
1 ‘xgettext’’s ‘--keyword’ option.  How to pass such an option to
11 ‘xgettext’, assuming that ‘gettextize’ is used, is described in ⇒
 po/Makevars and ⇒AM_XGETTEXT_OPTION.
1 
1    Note also that long strings can be split across lines, into multiple
1 adjacent string tokens.  Automatic string concatenation is performed at
1 compile time according to ISO C and ISO C++; ‘xgettext’ also supports
1 this syntax.
1 
1    Later on, the maintenance is relatively easy.  If, as a programmer,
1 you add or modify a string, you will have to ask yourself if the new or
1 altered string requires translation, and include it within ‘_()’ if you
1 think it should be translated.  For example, ‘"%s"’ is an example of
1 string _not_ requiring translation.  But ‘"%s: %d"’ _does_ require
1 translation, because in French, unlike in English, it’s customary to put
1 a space before a colon.
1