gettextによる多言語化
目次
1.gettextによる多言語化の基本的な処理手順
2.サンプル
3.懸念事項
1.gettextによる多言語化の基本的な処理手順
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
(1) ソースコードに、"xgettext"で検出する為のマクロ定義を埋め込む。
setlocale()など必要な前処理やヘッダファイルインクルードを組み込む。
(2) xgettextでメッセージを抽出し、翻訳のためのテンプレートファイル(.potファイル)を作成
(3) テンプレートファイルを基に各言語に翻訳し、テンプレートカタログ(.poファイル)を作成
(4) メッセージカタログをバイナリファイル(.moファイル)に変換する
(5) 作成したバイナリファイルをロケール用ディレクトリに置く。
2.サンプル
 ̄ ̄ ̄ ̄ ̄ ̄
以下のソースを多言語化してみる。
【test.c】
#include <stdio.h> char *msg = "GNU gettext excersize"; int main() { puts("Hello, World!"); puts(msg); return 0; }
(1) ソースコードに、"xgettext"で検出する為のマクロ定義を埋め込む。
setlocale()など必要な前処理やヘッダファイルインクルードを組み込む。
【test.c】
#include <stdio.h> /* setlocale() */ #include <locale.h> /* bindtextdomain(), textdomain() */ #include <libintl.h> #define _(String) gettext(String) #define N_(String) gettext_noop(String) #define gettext_noop(String) (String) char *msg = N_("練習サンプル"); int main() { /* ロカール名を環境変数から取得 */ setlocale(LC_ALL, ""); /* ドメイン名"test"のメッセージカタログディレクトリをカレントディレクトリに設定 */ bindtextdomain("test", "."); /* ドメイン名を"test"に設定 */ textdomain("test"); puts(_("こんにちは、世界!")); puts(_(msg)); return 0; }
$ gcc -Wall -o test test.c $ ./test
(2) xgettextでメッセージを抽出し、、翻訳のためのテンプレートファイル(.potファイル)を作成する
$ xgettext -k"_" -k"N_" -o test.pot test.c --from-code=UTF-8 $ ./test
※キーワードに"_", "N_"の二種類を指定することで、両方のマクロが適用された翻訳対象文字列を抽出できる。
(3) テンプレートファイルを基に各言語に翻訳し、テンプレートカタログ(.poファイル)を作成する
$ cp test.pot en.po
en.poを編集して英訳する。
【en.po】
"Content-Type: text/plain; charset=UTF-8\n" ※今回のサンプルではUTF-8を指定した。 ... #: test.c:13 msgid "練習サンプル" msgstr "GNU gettext excersize" #: test.c:23 msgid "こんにちは、世界!" msgstr "Hello, World!"
(4) メッセージカタログをバイナリファイル(.moファイル)に変換する
$ msgfmt -o test.mo en.po
(5) 作成したバイナリファイルをロケール用ディレクトリに置く。
$ mkdir -p ja/LC_MESSAGES $ cp test.mo en/LC_MESSAGES/test.mo
(6) 動作確認
$ LANG=C ./test こんにちは、世界! 練習サンプル $ LANG=en_US.UTF-8 ./test Hello, World! GNU gettext excersize
3.懸念事項
 ̄ ̄ ̄ ̄ ̄ ̄
(1) LANG=Cの場合の表示。
「LANG=C」では、動作的にはmsgidがそのまま出力されます。
今回は、_("日本語")のメッセージカタログを持つことになるので
「LANG=C」だと日本語リテラルで出力されます.
(2) ソースの文字コード
ソースファイルの文字コードは統一しておく必要があります。
既存ソースの文字コードが統一されていない場合は文字コードの変更が必要です。