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


4.3 翻訳可能な文字列の準備

文字列が翻訳可能とマークされる前に、調整が必要なこともあります。翻訳可能な文字列の準備は、その文字列をマーク(次のセクションで説明)する前に行います。文字列を準備する際に留意すべきは以下の点です。

上記のガイドラインにたいする例を、いくつか見てみましょう。

翻訳可能な文字列は、正しいEnglishスタイルである必要があります。言語特有のスラングや省略語が使用されている場合、翻訳者がメッセージを理解できずに不適切な翻訳を作成してしまうことがあります。

"%s: is parameter\n"

このメッセージはほとんど翻訳不可能です。表示されるアイテムはa parameter(任意のparameter)なのでしょうか、the parameter(特定のparameter)なのでしょうか?

"No match"

メッセージに含まれるあいまいさにより、メッセージが理解できなくなっています。プログラムはファイルに何かをセットしようとしているのでしょうか? "The given object does not match the template(与えられたオブジェクトがテンプレートにマッチしない)"なのでしょうか、それとも "The template does not fit for any of the objects(そのテンプレートは任意のオブジェクトに適合しない)"なのでしょうか?

どちらのケースも、メッセージに単語を追加することにより、翻訳者とEnglishを話すユーザーの両方を助けることができます。

翻訳可能な文字列は、センテンス全体を含む必要があります。単独の動詞や形容詞を、すべてのメッセージに代替できるように翻訳するのは不可能な場合があります。

printf ("File %s is %s protected", filename, rw ? "write" : "read");

ほとんどの翻訳者はソースを見ないので、"File %s is %s protected"という、それだけでは理解できない文字列しか目にしません。これを以下のように変更します。

printf (rw ? "File %s is write protected" : "File %s is read protected",
        filename);

この方法なら翻訳者はメッセージを理解するだけでなく、適切な文法の組み立て方を見つけることが出きます。たとえばFrenchの翻訳者なら"write protected"を"protected against writing"のように翻訳するでしょう。

多くの言語では、センテンスの他の場所にある性別や数(単数形/複数形)によって、あるセンテンスの単語が変わることがあるという理由からも、センテンス全体を含めることが重要になります。Englishより強い単語間の相互関係を持つ言語もあります。たとえEnglishではうまく動作しても、多くの言語では半分に分割した2つのセンテンスを翻訳者に翻訳してもらってから、2つの翻訳を機械的に結合しても、満足な翻訳とはなりません。これが翻訳者がセンテンス全体を処理する必要がある理由です。

センテンスが1つの行に対応しない場合もあります。これは以下のように、printfステートメントを使って2つの出力により、1つのセンテンスを出力しているような場合です。

printf ("Locale charset \"%s\" is different from\n", lcharset);
printf ("input file charset \"%s\".\n", fcharset);

翻訳者は2つのセンテンスを翻訳する必要があるでしょうが、POTファイル内には2つのセンテンスが分割された1つのセンテンスだと、彼女に教える情報はありません。2つのprintfステートメントを1つにする必要があります。そうすれば翻訳者がセンテンスを一括して処理できるので、翻訳をどの位置で改行すべきか決められるようなります。

printf ("Locale charset \"%s\" is different from\n\
input file charset \"%s\".\n", lcharset, fcharset);

では以下のような隣接した2つのセンテンスの場合はどうなるでしょうか:

puts ("Apollo 13 scenario: Stack overflow handling failed.");
puts ("On the next stack overflow we will crash!!!");

上記の2つのセンテンスは、1つにまとめる必要があるでしょうか? このような場合、2つのセンテンスが互いに関連していて、一緒にしたほうが翻訳者が理解・翻訳しやすくなるようなら、マージすることをお勧めします。一方、2つのメッセージのうち1つが定型的なもので、他の場所でも使用されるようなメッセージの場合は、マージしないほうが翻訳者にとって有益です(同じメッセージが複数の箇所に出現する場合、xgettextがそれらをまとめるので、翻訳者は1度だけそのメッセージを翻訳すればよくなります)。

翻訳可能な文字列は、単一のパラグラフ(段落)に制限すべきです。1つのメッセージの長さは、10行以内にしましょう。その理由は、翻訳可能な文字列が変更されたとき、翻訳者は翻訳済み文字列全体を更新しなければならないからです。たとえ1つの単語を変更しただけでも、(現在の翻訳ツールでは)翻訳者にはそれがわからないので、彼女はメッセージ全体を校正しなければならなくなってしまいます。

多くのGNUプログラムは、‘--help’オプションにより複数画面にまたがる出力を生成します。そのようなメッセージを、1つが5行から10行のメッセージに分割するのは、翻訳者にたいする礼儀です。ドキュメント化するオプションを、入力オプションと出力オプション、情報を出力するオプションのようにグループ分けしてもよいでしょう。グループ分けすることにより、オプションを探すすべてのユーザーを助けることができます。

ハードコーディングされた文字列の結合により、English文字列を生成することがあります:

strcpy (s, "Replace ");
strcat (s, object1);
strcat (s, " with ");
strcat (s, object2);
strcat (s, "?");

翻訳者にセンテンス全体を表示するためという理由だけではなく、object1object2の順番が入れ替わるような言語もあるので、これは以下のような書式文字列を使用するように変更する必要があります:

sprintf (s, "Replace %s with %s?", object1, object2);

似たようなケースとして、コンパイル時の文字列結合があります。ISO C 99のインクルードファイルである<inttypes.h>には、printfで整数型‘int64_t’を出力するためのPRId64マクロが含まれています。このマクロは通常、プラットフォームに応じて "d"、"ld"、"lld" のような文字列定数に展開されます。以下のようなコードがあるとします。

printf ("The amount is %0" PRId64 "\n", number);

gettextツールとライブラリーには、これら<inttypes.h>のマクロにたいする特別なサポートがあるので、上記のような場合は単に以下のように書くことができます。

printf (gettext ("The amount is %0" PRId64 "\n"), number);

この場合、POファイルには"The amount is %0<PRId64>\n"という文字列が含まれます。翻訳者は同様に"%0<PRId64>"と翻訳すれば、実行時にgettext関数が、"d"、"ld"、"lld" などから適切な文字列定数に変換します。

これは事前に定義された<inttypes.h>マクロにたいしてのみ機能します。あなたが‘MYPRId64’のような似たようなマクロを定義した場合、xgettextはそれを知ることができないので、コードを以下のように変更してください:

char buf1[100];
sprintf (buf1, "%0" MYPRId64, number);
printf (gettext ("The amount is %s\n"), buf1);

これでプラットフォームに依存するコードと、インターナショナリゼーションのコードは、別のステートメントに分けられました。バッファーの長さは100バイト以内でよいことに注意してください。なぜなら利用可能なすべてのハードウェアーの整数型は128ビットに制限されており、128ビット整数を出力するには、10進、8進、16進に関わらず最大で54バイトあればよいからです。

これは他のプログラム言語には適用できます。JavaとC#では文字列結合は、それらのコンパイラーのビルトイン操作なのでとても頻繁に使用されます。以下のようなCやJavaのコードがあるとします

System.out.println("Replace "+object1+" with "+object2+"?");

これを以下のような書式師弟文字列を含むステートメントに変更します:

System.out.println(
    MessageFormat.format("Replace {0} with {1}?",
                         new Object[] { object1, object2 }));

C#の場合は以下のように変更します

Console.WriteLine("Replace "+object1+" with "+object2+"?");

これを以下のような書式師弟文字列を含むステートメントに変更します:

Console.WriteLine(
    String.Format("Replace {0} with {1}?", object1, object2));

通常使用しないようなマークアップや制御文字は、翻訳可能な文字列の中に含めるべきではありません。翻訳者はマークアップや制御文字がもつ特別な意味は理解しません。

たとえば‘|’の右側と左側とで何らかのGUI要素を分ける規則があるような場合、翻訳者は特別なコメントなしではその規則を理解することはできません。このような場合は、翻訳者が右側と左側の文字列を個別に翻訳できるようにするのがよいでしょう。

他の例としては、‘argp’で制御文字‘\v’(vertical tab)を使用する場合の規則です。これは1つの文字列を2つのセクションに分ける場合に使用されます。このような文字列をそのまま翻訳可能文字列とするには問題があります。翻訳者によっては、これを単純に改行や空行に置き換えてしまうかもしれません。POファイルエディターの中には、制御文字のvertical tabを入力するのが困難なものもあります。上記の理由により、あなたは翻訳文字列の対応する位置に、‘\v’文字があることを期待できません。この問題にたいする解決策は、繰り返しになりますが、翻訳者が個別に文字列を翻訳できるようにしておいて、実行時に2つの翻訳された文字列を、規則が要求する‘\v’で結合することです。

HTMLマークアップは十分に一般的なマークアップなので、翻訳可能文字列を使用しても大丈夫でしょう。しかしGNU gettextツールは、翻訳された文字列がwell-formedなHTMLであるかは検証しないことに留意してください。


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