DOC HOME SITE MAP MAN PAGES GNU INFO SEARCH
 

(gettext.info.gz) Contexts

Info Catalog (gettext.info.gz) Charset conversion (gettext.info.gz) gettext (gettext.info.gz) Plural forms
 
 11.2.5 Using contexts for solving ambiguities
 ---------------------------------------------
 
 One place where the `gettext' functions, if used normally, have big
 problems is within programs with graphical user interfaces (GUIs).  The
 problem is that many of the strings which have to be translated are very
 short.  They have to appear in pull-down menus which restricts the
 length.  But strings which are not containing entire sentences or at
 least large fragments of a sentence may appear in more than one
 situation in the program but might have different translations.  This is
 especially true for the one-word strings which are frequently used in
 GUI programs.
 
    As a consequence many people say that the `gettext' approach is
 wrong and instead `catgets' should be used which indeed does not have
 this problem.  But there is a very simple and powerful method to handle
 this kind of problems with the `gettext' functions.
 
    Contexts can be added to strings to be translated.  A context
 dependent translation lookup is when a translation for a given string
 is searched, that is limited to a given context.  The translation for
 the same string in a different context can be different.  The different
 translations of the same string in different contexts can be stored in
 the in the same MO file, and can be edited by the translator in the
 same PO file.
 
    The `gettext.h' include file contains the lookup macros for strings
 with contexts.  They are implemented as thin macros and inline functions
 over the functions from `<libintl.h>'.
 
      const char *pgettext (const char *msgctxt, const char *msgid);
 
    In a call of this macro, MSGCTXT and MSGID must be string literals.
 The macro returns the translation of MSGID, restricted to the context
 given by MSGCTXT.
 
    The MSGCTXT string is visible in the PO file to the translator.  You
 should try to make it somehow canonical and never changing.  Because
 every time you change an MSGCTXT, the translator will have to review
 the translation of MSGID.
 
    Finding a canonical MSGCTXT string that doesn't change over time can
 be hard.  But you shouldn't use the file name or class name containing
 the `pgettext' call - because it is a common development task to rename
 a file or a class, and it shouldn't cause translator work.  Also you
 shouldn't use a comment in the form of a complete English sentence as
 MSGCTXT - because orthography or grammar changes are often applied to
 such sentences, and again, it shouldn't force the translator to do a
 review.
 
    The `p' in `pgettext' stands for "particular": `pgettext' fetches a
 particular translation of the MSGID.
 
      const char *dpgettext (const char *domain_name,
                             const char *msgctxt, const char *msgid);
      const char *dcpgettext (const char *domain_name,
                              const char *msgctxt, const char *msgid,
                              int category);
 
    These are generalizations of `pgettext'.  They behave similarly to
 `dgettext' and `dcgettext', respectively.  The DOMAIN_NAME argument
 defines the translation domain.  The CATEGORY argument allows to use
 another locale facet than `LC_MESSAGES'.
 
    As as example consider the following fictional situation.  A GUI
 program has a menu bar with the following entries:
 
      +------------+------------+--------------------------------------+
      | File       | Printer    |                                      |
      +------------+------------+--------------------------------------+
      | Open     | | Select   |
      | New      | | Open     |
      +----------+ | Connect  |
                   +----------+
 
    To have the strings `File', `Printer', `Open', `New', `Select', and
 `Connect' translated there has to be at some point in the code a call
 to a function of the `gettext' family.  But in two places the string
 passed into the function would be `Open'.  The translations might not
 be the same and therefore we are in the dilemma described above.
 
    What distinguishes the two places is the menu path from the menu
 root to the particular menu entries:
 
      Menu|File
      Menu|Printer
      Menu|File|Open
      Menu|File|New
      Menu|Printer|Select
      Menu|Printer|Open
      Menu|Printer|Connect
 
    The context is thus the menu path without its last part.  So, the
 calls look like this:
 
      pgettext ("Menu|", "File")
      pgettext ("Menu|", "Printer")
      pgettext ("Menu|File|", "Open")
      pgettext ("Menu|File|", "New")
      pgettext ("Menu|Printer|", "Select")
      pgettext ("Menu|Printer|", "Open")
      pgettext ("Menu|Printer|", "Connect")
 
    Whether or not to use the `|' character at the end of the context is
 a matter of style.
 
    For more complex cases, where the MSGCTXT or MSGID are not string
 literals, more general macros are available:
 
      const char *pgettext_expr (const char *msgctxt, const char *msgid);
      const char *dpgettext_expr (const char *domain_name,
                                  const char *msgctxt, const char *msgid);
      const char *dcpgettext_expr (const char *domain_name,
                                   const char *msgctxt, const char *msgid,
                                   int category);
 
    Here MSGCTXT and MSGID can be arbitrary string-valued expressions.
 These macros are more general.  But in the case that both argument
 expressions are string literals, the macros without the `_expr' suffix
 are more efficient.
 
Info Catalog (gettext.info.gz) Charset conversion (gettext.info.gz) gettext (gettext.info.gz) Plural forms
automatically generated byinfo2html