Ruby言語やLinuxのネタが多いです。
June 23, 2008 [おもひで]
■ [Misc] Gettextのpgettextとmsgctxt
Ruby-GetText-Packageでmsgctxtをサポートして欲しいという要望があった。パッチもついてたけど、msgctxtを使わなくするだけのパッチなのでそのまま取り込むのはよろしくなさそう。ってか、そもそも、msgctxtって何だろう。ということでちょっと調べてみた。
で、結論から言うと、GNU Gettextの最新マニュアルを細かく読むとすべて書いてあった。
msgctxt自体は2006/7のGNU Gettext 0.15からサポートされた比較的新しい機能で、pgettext(msgctxt, msgid)という関数で使われ、同じ名称のmsgidであっても使う場所によっては違う訳をつけたい場合に使用する(コンテクストごとにmsgidの訳をつけることができる。名前空間を分けるような感じ)。つまり、sgettext(), s_()を置き換えるものだと言える。
#実はsgettext()自体はGNU gettextの(古いバージョンの)マニュアル上でソースが記述されているサンプル的な関数にすぎなかった。
例えば、以下の2つはほぼ同じ意味で使用される(Rubyっぽく書いてみる)。
sgettext("File|Open")
pgettext("File", "Open")
これらは英語の場合、どちらも"Open"となり、翻訳時は"File" + "Open"に該当する翻訳文字列が使用される。pgettextでは"|"のような文字列ではなく関数の引数自体でコンテクストを分ける、というものだ。sgettextだと"|"を文字列として使いたい場合とかにちょっと困るしpgettextに比べ、多少曖昧さが残るもんね。
では、poファイル中ではどのようになるのか。
#: test2.c:3
msgid "File|Open"
msgstr "開く"
#: test2.c:4
msgctxt "File"
msgid "Open"
msgstr "開く"
msgctxt行というのが増えている。この行は翻訳対象では無いので、翻訳者はmsgctxt行とmsgstrを読んでOpenの適切な訳をつける。sgettextの"File|Open"形式だと不慣れな翻訳者は"ファイル|開く"と訳してしまう、なんてちょっと笑えない笑い話があったのだけど、そういった間違いは少なくなりそう。 ちなみに、現状のRuby-GetText-Packageではこのmsgctxt行でparse時にエラーとなってしまうので、今回のレポートが来たというわけだ。
■ では、実際、これはどのようにmoファイルの中で表現されているのだろう。答えは簡単で、sgettextのときに"File|Open"として表現されていた部分が"File\004Open"として区切り文字が"\004"(<EOT>)に変わっただけだ。なるほど、これなら比較的簡単にRuby-GetText-Packageにも適用できそうだ。
■ 余談。Ruby-GetText-Packageがsgettextを実装したのが2004/8で、GNU gettextでmsgctxtが実装されたのが2006/7だ。どおりで気づかなかったわけだ。他にも便利な機能がいくつか追加されているみたいだし見直さないといけないのかな。
