Zope3とgettext
Zope3 は多言語対応に gettext を利用しています。 アプリケーションでメッセージを表示する際は、プログラムやテンプレートに直接日本語を埋め込まず、適当なメッセージ ID を振り、翻訳されたものを表示させます。
したがって開発中は
- メッセージカタログを作成し(.pot ファイルの更新)、
- それを翻訳し(.po ファイルの更新)、
- コンパイルする(.mo ファイルの更新)
というフローを何度も繰り返します。
そこで今回は、このフローで役にたつコマンドを2つ紹介したいと思います。
メッセージカタログのソート
メッセージカタログは常に辞書順にソートしておくようにすると、差分をとったときに変更点がわかりやすくなり、メッセージ ID の検索も楽になります。
しかしながら、.pot(.po)ファイルは、手動で更新された場合や、抽出プログラムによっては、そのようにソートされていないことがあります。 そこで、たびたびメッセージカタログをソートさせる必要が出てきます。
.pot(.po) ファイルは
# メッセージ ID が埋め込まれたファイルのパス msgid "" msgstr ""
の複数行で1つの意味を持ったブロックを形成しているため、単純に行単位でソートするわけにはいきません。 そこで役に立つのが msgcat コマンドです。msgcat は -s オプションでファイルを辞書順にソートさせることが出来ます。
$ cat sort.pot msgid "" msgstr "" #. Default: "" #: lib/python/foo/view.py:54 msgid "zodiac" msgstr "" #. Default: "Washington Column" #: lib/python/foo/bar.html msgid "Washington Column" msgstr "" #. Default: "shield" #: lib/python/foo/bar.html msgid "shield" msgstr "" #: lib/python/foo/view.py:16 msgid "cosmic debris" msgstr "" $ msgcat -s sort.pot msgid "" msgstr "" #. Default: "Washington Column" #: lib/python/foo/bar.html msgid "Washington Column" msgstr "" #: lib/python/foo/view.py:16 msgid "cosmic debris" msgstr "" #. Default: "shield" #: lib/python/foo/bar.html msgid "shield" msgstr "" #. Default: "" #: lib/python/foo/view.py:54 msgid "zodiac" msgstr ""
メッセージカタログのマージ
すでに翻訳された .po ファイルがあり、メッセージカタログを更新した場合、各メッセージ ID を確認して、翻訳メッセージのコピーや削除するのはさすがに面倒です。 そこで役に立つのが msgmerge コマンドです。 msgmerge は -U オプションで既存の翻訳済みメッセージカタログと新しいメッセージカタログをマージしてくれます。
$ cat orig.po # 翻訳済み po ファイル msgid "" msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Default: "Washington Column" #: lib/python/foo/bar.html msgid "Washington Column" msgstr "ワシントン・コラム" #: lib/python/foo/view.py:16 msgid "cosmic debris" msgstr "コズミック・デブリ" #. Default: "" #: lib/python/foo/view.py:54 msgid "zodiac" msgstr "十二宮" $ cat new.pot # 新しいメッセージカタログ msgid "" msgstr "" #. Default: "Washington Column" #: lib/python/foo/bar.html msgid "Washington Column" msgstr "" #: lib/python/foo/view.py:16 msgid "debris" msgstr "" #. Default: "shield" #: lib/python/foo/bar.html msgid "shie $ msgmerge -U orig.po new.pot # マージ .. done. $ cat orig.po # 更新された翻訳済み po ファイル msgid "" msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Default: "Washington Column" #: lib/python/foo/bar.html msgid "Washington Column" msgstr "ワシントン・コラム" #: lib/python/foo/view.py:16 #, fuzzy msgid "debris" msgstr "コズミック・デブリ" #. Default: "shield" #: lib/python/foo/bar.html msgid "shield" msgstr "" #~ msgid "zodiac"
orig.po ファイルは次のように更新されています。
- 既存の翻訳された msgstr は引き継がれています
- 新しいメッセージ ID "shield" が追加されています
- 削除された msgid は #~ でコメントアウトされています("zodiac")
- 完全一致はしないけれども、部分一致するメッセージID("cosmic debris" が "debris" に変更)に対しては、 fuzzy マークが付いています
- orig.po~ というバックアップファイルが作成されます。
まとめ
今回は msgcat を使ったソートと msgmerge を使ったマージについて解説しました。msg* ファミリーには、今回紹介した msgcat、 msgmerge 以外にも、
- msgattrib
- msgcmp
- msgcomm
- msgconv
- msgen
- msgexec
- msgfilter
- msgfmt
- msggrep
- msginit
- msgunfmt
- msguniq
といろいろいるようです。