Next: , Previous: , Up: Sources   [Contents][Index]


4.4 ソース内でマークはどのように見えるか

Cソース中で翻訳される文字列は、すべてマークする必要があります。マーキングは翻訳可能な文字列を、関数やプリプロセッサーのマクロに、単独の引数として引き渡す方法で行われます。翻訳のために利用可できる関数またはマクロは少なく、マーキングのキーワードとしてそれらの名前が使用されます。マーキングは翻訳される文字列自体に何かを行うよりは、文字列にアタッチすることによりマーキングを行なう方法が、より多く使用されます。明らかな例としては、書式文字列によりエラーメッセージを生成する場合です。書式文字列は翻訳する必要があり、フォーマット文字列の‘%s’で指定した箇所に挿入される文字列も同様だとすると、たとえばsprintfの結果には、‘error_string_out()’のようなルーチンからなる、多くの異なるインスタンスが含まれることになり、これらをすべてリストするのは非現実的です。

マーキングには2つの目的があります。1つ目は実行時に翻訳を取得するトリガーとなることです。キーワードは引数となる文字列にたいして、可能なかぎり(そして望む限り)、動的に適切なトランスレーションを返すルーチンへと解決されます。ローカライズ可能な文字列は、変数にあてがわれていたり、関数の引数になっている場合がほとんどです。しかし翻訳可能な文字列が構造体の初期化時に使用される等の例外もあります。Special casesを参照してください。

2つ目の目的は、xgettextが、一連のプログラムソースをスキャンしてPOファイルのテンプレートを生成するときに、翻訳可能な文字列を適切に抽出する手助けをすることです。

翻訳可能な文字列をマークするための標準的なキーワードは‘gettext’で、これはGNU gettextパッケージの名前の由来にもなっています。パッケージで少量の‘gettext’キーワードやマクロ、関数をそのまま使うのは簡単です。しかしgettextインターフェースを多用するパッケージの場合、主要なキーワードには目立つ名前ではなく、より簡潔な名前を使用する方が便利です。キーワードはパッケージ内のすべての文字列の箇所に記述されますが、プログラマーは通常、彼らのプログラムのソースがインターナショナライズされるものだといつも強制的に思い出したいとは望みませんし、その必要もありません。また長いキーワードはより多くの文字数を使用するので、ソースの1行を79から80文字にインデントするための労力が余分にかかるという欠点もあります。

多くのパッケージはキーワードとして‘_’(単なるアンダーライン)を使用して、‘gettext ("Translatable string")’を、‘_("Translatable string")’のように記述しています。またGNU標準のコーディング規約は実際、この特定の用途のためにキーワードと開き括弧の間に、余白としてスペースを要求しています。これにより翻訳可能な文字列のためにかかる文字的なオーバーヘッドは、アンダーラインと2つの括弧というたった3文字に短縮されます。たとえGNU gettextがこの方式を内部的に使用していたとしても、これは公式な提案ではありません。正式なキーワードはあくまでも本物の‘gettext’です。しかし‘gettext’のかわりに‘_’を使用したい人は、以下のように定義すると簡単になります。

#include <libintl.h>
#define _(String) gettext (String)

単に‘#include <libintl.h>’とするのではなく、上記のようにすれば簡単に使用できます。

マーキングのためのキーワードである‘gettext’と‘_’ は、翻訳可能文字列を単一の引数とします。他の位置に引数をするマーキング用の関数を定義することもできます。関数が呼び出されたときの引数の合計数にもとづいた位置のマーク用引数を作ることもできます(通常はC++の場合)。これはxgettextの‘--keyword’により実現されます。xgettextにこのような引数を渡すにはgettextizeが使用されます、その方法についてはpo/MakevarsAM_XGETTEXT_OPTIONで説明します。

長い文字列は複数行に分けられることに注意してください。コンパイル時にはISO CおよびISO C++にもとづく文字列の自動連結が行われますが、xgettextもこの構文をサポートしています。

後でメンテナンスするのも簡単になります。もしあなたがプログラマーで、文字列を追加、変更した場合、その文字列が翻訳される必要があると考えた場合は、‘_()’でマークすればよいのです。たとえば‘"%s"’は、翻訳しない文字列だとします。しかし‘"%s: %d"’は翻訳するような場合です(Frenchの場合は通常、Englishとは異なり、コロンの前にスペースを挿入する翻訳が必要になります)。