Go to main content
Oracle Solaris でのアプリケーションの国際化とローカライズ

印刷ビューの終了

更新: 2016 年 11 月
 
 

gettext API

ローカライズされるテキストメッセージは、アプリケーションのソースコードとは切り離して、個別のファイルに格納する必要があります。これらのファイルは、メッセージバンドルメッセージカタログ、または移植可能メッセージファイルと呼ばれます。各プログラミング言語には、これらのファイルを操作するためのツールセットが用意されています。たとえば、C、Python、Perl などのプログラミング言語では、メッセージを翻訳するための gettext 関数が提供されています。

移植可能メッセージファイルは gettext ユーティリティーを使用して作成します。これらのファイルはプレーンテキストで表示され、ファイル拡張子として .po が付きます。翻訳対象の移植可能メッセージファイルをトランスレータに送信し、トランスレータは翻訳済みのテキストでファイルを更新します。翻訳後の .po ファイルには、対応する翻訳済みのテキストとメッセージ ID が含まれます。例:

$ cat cs.po
.
.
#: code.c:37
#,c-format
msgid "My hovercraft is full of eels.\n"
msgstr "Moje vznášedlo je plné úhořů.\n"

ただし、移植可能オブジェクトファイルをメッセージオブジェクトファイルに変換することで、システムのパフォーマンスを向上できます。メッセージオブジェクトファイルにはファイル拡張子として .mo が付きます。移植可能オブジェクトファイルをメッセージオブジェクトファイルに変換するには、msgfmt ユーティリティーを使用します。


注 -  メッセージが gettext 関数でラップされると、現在のロケールに基づいて翻訳が実行されます。この方法では、元のテキストメッセージが、メッセージカタログに対するキーとして使用されます。

シェルスクリプトのローカライズ済みメッセージオブジェクトを生成する方法

  1. gettext ツールの GNU バージョンを使用するには、PATH 環境変数の前に /usr/gnu/bin を追加します。
  2. xgettext コマンドを使用して、シェルスクリプトからメッセージを抽出し、メッセージファイルテンプレートに配置します。
  3. msginit コマンドを使用して、翻訳言語に固有の移植可能メッセージ (.po) ファイルを作成します。
  4. .po ファイル内で作成されたメッセージを翻訳します。
  5. TEXTDOMAINDIR環境変数で指定したディレクトリに、LC_MESSAGES ディレクトリを作成します。
  6. シンボリックリンクを作成するか、LANGUAGE 変数を設定します。
  7. メッセージオブジェクト (.mo) ファイルを作成します。
使用例 7  シェルスクリプトのローカライズ済みメッセージオブジェクトの生成

この例は、シェルスクリプトのローカライズ済みメッセージオブジェクトを生成する方法を示しています。gettext 関数の呼び出しを含む、次のシェルスクリプトがあることを想定します。

#!/usr/bin/bash
#

# set TEXTDOMAIN and TEXTDOMAINDIR as per the gettext(1) manual page
TEXTDOMAIN=test_gettext_sh
export TEXTDOMAIN
TEXTDOMAINDIR=/home/xxxxx/lib/locale
export TEXTDOMAINDIR
PATH=/usr/gnu/bin:/usr/bin
export PATH

# source gettext.sh for using eval_gettext and eval_ngettext
. gettext.sh

f="filename.dat"
# Use eval_gettext or eval_ngettext if it refers to shell variables

# TRANSLATORS: $f is replaced with a file name
eval_gettext "\$f not found"; echo
gettext "file not found"; echo

echo "`eval_gettext "\\\$f not found"`"
echo "`gettext "file not found"`"

このシェルスクリプト用に、次の手順を使用して、ローカライズされたメッセージオブジェクトを作成できます。

  1. gettext ツールの GNU バージョンを使用するには、PATH 環境変数の前に usr/gnu/bin を追加します。

    $ PATH=/usr/gnu/bin:$PATH
  2. xgettext コマンドを使用して、シェルスクリプトからメッセージを抽出し、メッセージファイルテンプレートに配置します。

    $ xgettext -c"TRANSLATORS:" -L"Shell" test_gettext.sh

    messages.po という名前のファイルが作成されます。ここにはシェルスクリプトのヘッダー情報およびメッセージ文字列が含まれます。トランスレータ向けの説明コメントも含まれます。次の例は、messages.po ファイルからの抜粋を示しています。

    #. TRANSLATORS: $f is replaced with a file name
    #: test_gettext.sh:18 test_gettext.sh:21
    #, sh-format
    msgid "$f not found"
    msgstr ""
    
    #: test_gettext.sh:19 test_gettext.sh:22
    msgid "file not found"
    msgstr ""
  3. msginit コマンドを使用して、翻訳言語に固有の移植可能メッセージ (.po) ファイルを作成します。たとえば、日本語の ja_JP.UTF-8 ロケールでは、次のコマンドを使用して .po ファイルを作成します。

    $ msginit --no-translator --locale=ja_JP.UTF-8 --input=messages.po

    ja.po という名前のファイルが作成されます。

  4. ja.po ファイル内のメッセージを翻訳します。

  5. TEXTDOMAINDIR環境変数で指定したディレクトリに、LC_MESSAGES ディレクトリを作成します。

    $ mkdir -p lib/locale/ja/LC_MESSAGES
  6. シンボリックリンクを作成するか、LANGUAGE 変数を設定します。

    • シンボリックリンクを作成します。

      $ ln -s ja lib/locale/ja_JP.UTF-8
    • LANGUAGE 変数を設定します。

      $ LANGUAGE=ja_JP.UTF-8:ja
      $ export LANGUAGE
  7. メッセージオブジェクト (.mo) ファイルを作成します。

    $ msgfmt -o lib/locale/ja/LC_MESSAGES/test_gettext_sh.mo ja.po

C プログラムのローカライズ済みテキストメッセージを生成する方法

  1. PATH 環境変数の前に /usr/gnu/bin を追加します。
  2. xgettext コマンドを使用して、ソースコードからメッセージを抽出し、メッセージファイルテンプレートに配置します。
  3. LC_TIME ロケールカテゴリに .po ファイルをもう 1 つ作成します。
  4. msginit コマンドを使用して、翻訳言語に固有の移植可能メッセージ (.po) ファイルを作成します。
  5. 作成された .po ファイルを翻訳します。
  6. LOCALEDIR 変数で指定されているディレクトリに、LC_MESSAGES および LC_TIME ディレクトリを作成します。
  7. シンボリックリンクを作成するか、LANGUAGE 変数を設定します。
  8. メッセージオブジェクト (.mo) ファイルを作成します。
使用例 8  C プログラムのローカライズ済みテキストメッセージの生成

この例は、C プログラムのローカライズ済みメッセージオブジェクトを生成する方法を示しています。gettext 関数の呼び出しを含む、次の C プログラムがあることを想定します。

#include <stdio.h>
#include <sys/types.h>
#include <libintl.h>
#include <locale.h>
#include <time.h>



/*
 * _()   is used for the strings to extract messages.
 * N_()  is used for the string array message to extract messages.
 * T_()  is used for the strings to extract messages with working on LC_TIME
 */
#define _(String)      gettext (String)
#define gettext_noop(String)   String
#define N_(String)      gettext_noop (String)
#define T_(String)      gettext_noop (String)

#define LOCALEDIR      "/home/xxxxx/lib/locale"
#define PACKAGE         "test_gettext"

static const char *msg[] = {
   N_("The first message"),
   N_("The second message"),
};

int main(int ac, char **av)
{
   char *file = "test.dat";
   int line = 40;
   int column = 10;
   time_t tloc;
   char time_buf[BUFSIZ];

   setlocale(LC_ALL, "");
   bindtextdomain(PACKAGE, LOCALEDIR);
   textdomain(PACKAGE);
   /*
    * By default, the characters are converted to current locale's encoding.
    * If this is not desired, call bind_textdomain_codeset(). For example,
    * if you want "UTF-8" encoding, specify "UTF-8" in the second argument.
    *
    *   bind_textdomain_codeset("test_gettext", "UTF-8");
    */
   printf(_("This is a test\n"));

   printf("%s\n", _(msg[0]));
   printf("%s\n", _(msg[1]));
   /* TRANSLATORS:
      First %d is replaced by a line number.
      Second %d is replaced by a column number.
      %s is replaced by a file name. */
   printf(_("ERROR: invalid input at line %1$d, %2$d in %3$s\n"),
       line, column, file);

   /*
    * strftime() works with LC_TIME not LC_MESSAGES so to get properly
    * formatted time messages we have to call dcgettext() with LC_TIME category.
    */
   (void) time(&tloc);
   (void) strftime(time_buf, sizeof (time_buf),
       /* TRANSLATORS:
        This is time format used with strftime().
        Please modify time format to fit your locale by using
        date '+%a %b %e %H:%M:%S' */
       dcgettext(NULL, T_("%a %b %e %H:%M:%S"), LC_TIME),
       localtime(&tloc));
   printf("%s\n", time_buf);

   return(0);
}

この C プログラム用に、次の手順を使用して、ローカライズされたメッセージオブジェクトを作成できます。

  1. PATH 環境変数の前に /usr/gnu/bin を追加します。

    $ PATH=/usr/gnu/bin:$PATH
  2. xgettext コマンドを使用して、ソースコードからメッセージを抽出し、メッセージファイルテンプレートに配置します。

    $ xgettext -c"TRANSLATORS:" -k -k"_" -k"N_" -L"C" test_gettext.c

    messages.po ファイルが LC_MESSAGES ロケールカテゴリに対して作成されます。ここには、ヘッダー情報やメッセージ文字列が格納され、トランスレータ向けの説明コメントも含まれています。次の例は、messages.po ファイルからの抜粋を示しています。

    #: test_gettext.c:21
    msgid "The first message"
    msgstr ""
    
    #: test_gettext.c:22
    msgid "The second message"
    msgstr ""
    
    #: test_gettext.c:43
    #, c-format
    msgid "This is a test\n"
    msgstr ""
    
    #. TRANSLATORS:
    #. First %d is replaced by a line number.
    #. Second %d is replaced by a column number.
    #. %s is replaced by a file name.
    #: test_gettext.c:51
    #, c-format
    msgid "ERROR: invalid input at line %1$d, %2$d in %3$s\n"
    msgstr ""
  3. LC_TIME ロケールカテゴリに .po ファイルをもう 1 つ作成します。

    $ xgettext -c"TRANSLATORS:" -k -k"T_" -L"C" -o messages_t.po test_gettext.c

    messages_t.po ファイルが LC_TIME ロケールカテゴリに対して作成されます。

  4. msginit コマンドを使用して、翻訳言語に固有の移植可能メッセージ (.po) ファイルを作成します。

    たとえば、日本語の ja_JP.UTF-8 ロケールでは、次のコマンドを使用して移植可能ファイルメッセージを作成します。

    $ msginit --no-translator --locale=ja_JP.UTF-8
     --input=messages.po
    $ msginit --no-translator --locale=ja_JP.UTF-8 --input=messages_t.po
     --output-file=ja_t.po
    

    ja.po および ja_t.po ファイルが作成されます。

  5. 作成された ja.po および ja_t.po ファイルを翻訳します。

  6. LOCALEDIR 変数で指定されているディレクトリに、LC_MESSAGES および LC_TIME ディレクトリを作成します。

    $ mkdir -p lib/locale/ja/LC_MESSAGES lib/locale/ja/LC_TIME
  7. シンボリックリンクを作成するか、LANGUAGE 変数を設定します。

    • シンボリックリンクを作成します。

      $ ln -s ja lib/locale/ja_JP.UTF-8
    • LANGUAGE 変数を設定します。

      $ LANGUAGE=ja_JP.UTF-8:ja
      $ export LANGUAGE
  8. メッセージオブジェクト (.mo) ファイルを作成します。

    $ msgfmt -o lib/locale/ja/LC_MESSAGES/test_gettext.mo ja.po
    $ msgfmt -o lib/locale/ja/LC_TIME/test_gettext.mo ja_t.po

メッセージオブジェクトファイルの形式

メッセージオブジェクトファイルは、次の形式で作成されます。

/usr/lib/locale/locale/category/textdomain.mo

このパスには複数のコンポーネントがあります。

/usr/lib/locale

メッセージオブジェクトファイルを断定するデフォルトパス。たとえば、テキストドメインの衝突が発生した場合、bindtextdomain() 関数の呼び出しによってパスが指定されます。サードパーティソフトウェアの場合、メッセージオブジェクトファイルは /usr/share/locale ディレクトリで使用できます。

locale

ロケールディレクトリ。

category

ロケールのカテゴリ。

textdomain.mo

textdomain() 関数の呼び出しで指定されるテキストドメイン。メッセージカタログの一意の識別子とファイル名です。

次の例を考えてみましょう。

/usr/lib/locale/it_IT.UTF-8/LC_MESSAGES/mymessages.mo

ここでは:

it_IT.UTF-8

ロケールディレクトリ。このメッセージオブジェクトにはイタリア語の翻訳が含まれており、このロケールと、このディレクトリへのシンボリックリンクとなるその他のロケールで使用されます。

LC_MESSAGES

ロケールのカテゴリ。


注 -  通常、メッセージは LC_MESSAGES および LC_TIME カテゴリにあります。
mymessages

メッセージカタログ名。

Oracle Solaris および GNU 互換の gettext インタフェース

Oracle Solaris gettext API は、Oracle Solaris と GNU 互換のメッセージカタログファイルの両方をサポートします。ただし、一部の gettext API は、GNU 互換のメッセージカタログファイルに固有のものです。Solaris および GNU 互換の gettext インタフェースは次のとおりです。

gettext()

メッセージカタログからテキスト文字列を取得します

dgettext()

特定のドメインのメッセージカタログからメッセージを取得します

textdomain()

現在のドメインを設定して問い合わせます

bindtextdomain()

メッセージドメインのパスをバインドします

dcgettext()

特定のドメインおよびカテゴリのメッセージカタログからメッセージを取得します

GNU gettext インタフェース

GNU 互換のメッセージカタログファイルでのみ機能する gettext API は次のとおりです。

ngettext()

メッセージカタログからテキスト文字列を取得して複数形を選択します

dngettext()

特定のドメインのメッセージカタログからテキスト文字列を取得して、複数形を選択します

bind_textdomain_codeset()

ドメインのメッセージカタログの出力 codeset を指定します

dcngettext()

特定のドメインおよびカテゴリのメッセージカタログからテキスト文字列を取得して、複数形を選択します

GNU テキストメッセージ処理の詳細は、GNU gettext リファレンス (http://www.gnu.org/software/gettext/manual/gettext.html)を参照してください。

gettext 関数の詳細は、msgfmt(1)、xgettext(1)、gettext(1) のマニュアルページを参照してください。

メッセージ処理ツール

gettext は、メッセージオブジェクトファイルを作成して処理するための関数とコマンド行ツールを提供しています。Oracle Solaris メッセージオブジェクトは、GNU gettext メッセージオブジェクトとは異なる形式です。メッセージを処理するためのコマンド行ツールの Oracle Solaris バリアントは次のとおりです。

/usr/bin/gettext

メッセージカタログからテキスト文字列を取得します

/usr/bin/msgfmt

移植可能メッセージファイルからメッセージオブジェクトを作成します

/usr/bin/xgettext

gettext 文字列への呼び出しを C プログラムから取得します

メッセージを処理するためのコマンド行ツールの GNU バリアントは次のとおりです。

/usr/bin/ggettext

メッセージカタログからテキスト文字列を取得します

/usr/bin/gmsgfmt

メッセージファイルからメッセージオブジェクトを作成します。

/usr/bin/gxgettext

gettext 呼び出し文字列を取得します

Oracle Solaris ツールと区別するために、GNU バリアントツールには g という文字が接頭辞として付き、/usr/gnu/bin ディレクトリへのシンボリックリンクになっています。たとえば、/usr/bin/ggettext/usr/gnu/bin/gettext へのシンボリックリンクです。

GNU gettext ツールは text/gnu-gettext パッケージの一部で、このパッケージにはメッセージカタログの処理用のその他のユーティリティーも含まれています。


注 -  Python の gettext 実装では、GNU gettext メッセージオブジェクト形式のみがサポートされます。したがって、Python プログラムでは、GNU 互換のメッセージオブジェクトを作成する必要があります。

詳細は、msgcat(1)、msgcmp(1)、msgmerge(1) のマニュアルページを参照してください。