バージョンごとのドキュメント一覧

55.2. プログラマへ #

<title>For the Programmer</title>

55.2.1. 仕組み #

<title>Mechanics</title>

This section describes how to implement native language support in a program or library that is part of the <productname>PostgreSQL</productname> distribution. Currently, it only applies to C programs. 本節では、PostgreSQL配布物の一部であるプログラムやライブラリにおける各国語サポートの実装方法を説明します。 現在はCプログラムにのみ適用できます。

プログラムにNLSサポートを追加する

<title>Adding NLS Support to a Program</title>
  1. Insert this code into the start-up sequence of the program: プログラムの起動処理に以下のコードを追加してください。

    #ifdef ENABLE_NLS
    #include <locale.h>
    #endif
    
    ...
    
    #ifdef ENABLE_NLS
    setlocale(LC_ALL, "");
    bindtextdomain("progname", LOCALEDIR);
    textdomain("progname");
    #endif
    

    (The <replaceable>progname</replaceable> can actually be chosen freely.) prognameは実際には自由に選択できます。)

  2. Wherever a message that is a candidate for translation is found, a call to <function>gettext()</function> needs to be inserted. E.g.: どこであろうと翻訳の候補となるメッセージが見つかったら、gettext()の呼び出しが追加される必要があります。 例えば、

    fprintf(stderr, "panic level %d\n", lvl);
    

    would be changed to: は、次のように変更されます。

    fprintf(stderr, gettext("panic level %d\n"), lvl);
    

    (<symbol>gettext</symbol> is defined as a no-op if NLS support is not configured.) (NLSサポートが組み込まれていない場合、gettextはノーオペレーション命令として定義されます。)

    This tends to add a lot of clutter. One common shortcut is to use: これは混乱しがちになります。一般的なショートカットは以下のものです。

    #define _(x) gettext(x)
    

    Another solution is feasible if the program does much of its communication through one or a few functions, such as <function>ereport()</function> in the backend. Then you make this function call <function>gettext</function> internally on all input strings. 他の解決方法は、バックエンドにおけるereport()のように、そのプログラムが通信のほとんどを1つまたは数個の関数で行っている場合有効です。 その場合、この関数の内部で全ての入力文字列に対しgettextを呼び出すようにすることになります。

  3. Add a file <filename>nls.mk</filename> in the directory with the program sources. This file will be read as a makefile. The following variable assignments need to be made here: プログラムのソースのあるディレクトリにnls.mkを追加してください。 これはmakefileとして読まれます。 以下の変数への代入をここで設定する必要があります。

    CATALOG_NAME

    The program name, as provided in the <function>textdomain()</function> call. textdomain()の呼び出しに使用されるプログラム名です。

    GETTEXT_FILES

    List of files that contain translatable strings, i.e., those marked with <function>gettext</function> or an alternative solution. Eventually, this will include nearly all source files of the program. If this list gets too long you can make the first <quote>file</quote> be a <literal>+</literal> and the second word be a file that contains one file name per line. 翻訳可能文字列を含むファイルの一覧です。 つまり、これらはgettextもしくは他の解決法として印が付けられます。 結局、これはプログラムのほとんど全てのソースファイルを含むことになります。 この一覧があまりに長くなる場合、最初のfile+とし、2番目の単語を1行に対して1つのファイル名を持ったファイルとすることができます。

    GETTEXT_TRIGGERS

    The tools that generate message catalogs for the translators to work on need to know what function calls contain translatable strings. By default, only <function>gettext()</function> calls are known. If you used <function>_</function> or other identifiers you need to list them here. If the translatable string is not the first argument, the item needs to be of the form <literal>func:2</literal> (for the second argument). If you have a function that supports pluralized messages, the item should look like <literal>func:1,2</literal> (identifying the singular and plural message arguments). 翻訳者が作業を行う上で、どの関数呼び出しが翻訳可能文字列を含むかを知る必要に迫られた場合に、メッセージカタログを生成するツールです。 デフォルトでは、gettext()呼び出しのみを認識します。 _や他の識別子を使用した場合、ここに記載しなければなりません。 翻訳可能文字列がその最初の引数ではない場合、その項目は(例えば2番目の引数の場合)func:2という形式でなければなりません。 複数形メッセージをサポートする関数がある場合、その項目は(単一形および複数形メッセージ引数を特定する)func:1,2のようになります。

  4. Add a file <filename>po/LINGUAS</filename>, which will contain the list of provided translations &mdash; initially empty. 提供された翻訳のリストを含むファイルpo/LINGUASを追加します。初めは空です。

The build system will automatically take care of building and installing the message catalogs. ビルドシステムは、自動的にメッセージカタログの構築およびインストールを行います。

55.2.2. メッセージ記述の指針 #

<title>Message-Writing Guidelines</title>

Here are some guidelines for writing messages that are easily translatable. メッセージの翻訳を簡単にするために以下に指針をいくつか示します。

  • Do not construct sentences at run-time, like: 以下のように実行時に文章を構築することはしないでください。

    printf("Files were %s.\n", flag ? "copied" : "removed");
    

    The word order within the sentence might be different in other languages. Also, even if you remember to call <function>gettext()</function> on each fragment, the fragments might not translate well separately. It's better to duplicate a little code so that each message to be translated is a coherent whole. Only numbers, file names, and such-like run-time variables should be inserted at run time into a message text. 文章内の単語の順番は言語によって異なる可能性があります。 さらに全ての断章に対してgettext()を呼び出すことを覚えていたとしても、断章が個別に的確に翻訳されるわけではありません。 それぞれのメッセージが全て調和して翻訳されるかどうか、ちょっとしたコードの複製を用意するとよいかもしません。 番号、ファイル名、および実行時変数のみメッセージテキストに実行時に挿入するべきです。

  • For similar reasons, this won't work: 同様の理由で、以下も上手くいきません。

    printf("copied %d file%s", n, n!=1 ? "s" : "");
    

    because it assumes how the plural is formed. If you figured you could solve it like this: これは複数形がどのように形成されるかを決めてかかっているからです。 もし、以下のようにして回避できたと考えると、

    if (n==1)
        printf("copied 1 file");
    else
        printf("copied %d files", n):
    

    then be disappointed. Some languages have more than two forms, with some peculiar rules. It's often best to design the message to avoid the issue altogether, for instance like this: 失望することになります。 言語の中には、独特の規則によって2つ以上の形式になるものもあります。 問題全体を回避するためこのメッセージを設計することが最善です。たとえば以下のようにします。

    printf("number of copied files: %d", n);
    

    If you really want to construct a properly pluralized message, there is support for this, but it's a bit awkward. When generating a primary or detail error message in <function>ereport()</function>, you can write something like this: 適切に複数形を持つメッセージを構築したいと本当に思うのなら、これに対するサポートがありますが、多少厄介です。 ereport()内の主たる、または詳細なエラーメッセージを生成する場合、以下のように書くことができます。

    errmsg_plural("copied %d file",
                  "copied %d files",
                  n,
                  n)
    

    The first argument is the format string appropriate for English singular form, the second is the format string appropriate for English plural form, and the third is the integer control value that determines which plural form to use. Subsequent arguments are formatted per the format string as usual. (Normally, the pluralization control value will also be one of the values to be formatted, so it has to be written twice.) In English it only matters whether <replaceable>n</replaceable> is 1 or not 1, but in other languages there can be many different plural forms. The translator sees the two English forms as a group and has the opportunity to supply multiple substitute strings, with the appropriate one being selected based on the run-time value of <replaceable>n</replaceable>. 最初の引数は英文の単数形に適切な書式文字列で、二番目は英文の複数形に適切な書式文字列、そして三番目はどの複数形を使用するのかを決定する整数制御値です。 引き続く引数はいつものように書式文字列毎に書式化されます。 (通常、複数化制御値は書式化されるべき値の内の1つでもありますので、2回書かなければなりません。) 英語ではnが1であるか、そうでないかのみ重要ですが、他の言語では数多くの複数書式が存在します。 翻訳者にはグループとして2つの英文書式を参照し、nの実行時の値に基づいて選択される適切な1つでもって、複数の代替文字列を供給する機会があります。

    If you need to pluralize a message that isn't going directly to an <function>errmsg</function> or <function>errdetail</function> report, you have to use the underlying function <function>ngettext</function>. See the gettext documentation. errmsgあるいはerrdetail報告に直接行かない複数形メッセージが必要であれば、基礎となっている関数、ngettextを使用する必要があります。 gettextのドキュメントを参照してください。

  • If you want to communicate something to the translator, such as about how a message is intended to line up with other output, precede the occurrence of the string with a comment that starts with <literal>translator</literal>, e.g.: メッセージをどのように他の出力と合わせる予定なのかなど翻訳者と何か連絡を取り合いたい場合、translatorで始まるコメントを最初に付けてどうなるかを知らせてください。 以下のようにします。

    /* translator: This message is not what it seems to be. */
    

    These comments are copied to the message catalog files so that the translators can see them. これらのコメントはメッセージカタログにコピーされますので翻訳者は参照できます。