Sphinxのi18nを実際に試してみた

2011年1月29日に行われた、PyConMini JPにて、IanさんがSphinxi18n機能の紹介をしてくださいました。(http://www.slideshare.net/IanMLewis/sphinx-11-i18n)

というわけで、実際に試してみました。まずは英語->日本語をやってみます。

なお、環境は

で行いました。LinuxなどではLOCALEの扱いが違うかもしれませんが、おそらく同じです。

1. buildで.potファイルを作成
% make gettext # build/locale/index.pot ができる
2. poファイルを作る
% cd build/locale/
% msginit --locale=ja --input=index.pot # potからja.poを作成

できあがったpoファイルの一部を抜粋するとこんな感じ。

# 6f21b715e3be42b4b4e21a05aaa4a2a9
msgid "This is a test index.rst file."
msgstr ""
3. poファイルを翻訳

で、このja.poファイルを翻訳する。

# 6f21b715e3be42b4b4e21a05aaa4a2a9
msgid "This is a test index.rst file."
msgstr "これはテスト用のindex.rstファイルです。"
4. LocaleのDirecotryを作る

トップディレクトリに戻り、.moファイルを置く場所を作ります。

% cd ../../
% mkdir -p source/translated/ja/LC_MESSAGES/

ぼくの流儀でsourceとbuildを分けているのでsource以下にtranslatedを作成しましたが、そうでなければトップディレクトリでいいと思います。

5. conf.pyに設定を書く
locale_dirs= ["translated/"] # []が重要
language="ja"
6. 翻訳した.poファイルから.moファイルを作ります。
% msgfmt build/locale/ja.po -o source/translated/en/LC_MESSAGES/index.mo
7. あとは普通にbuildします。
% make html
注意点
  • .poファイルは最初build以下にできます。うっかり make cleanとかするとまるごと消えるので注意。sourceディレクトリに移してしておくと安全かも
  • index.rstを書き換えても、index.potが書き換わるだけ。msginitで.poファイルを書き出す時に既にあるよと怒られます。なので、せっかく翻訳した.poファイルを書き潰す心配はありません。
  • sphinxは.rstファイルだけを見て変化があれば書き出していますが、.rstファイルに変更がなければ変更されません。従って、いくら.poや.moを作成しなおしてもsphinxは見てくれず、いつまでも同じ結果が出るようです。

ここであれれという事態。

追記: これは完全にぼくの勘違いでした…ちゃんとindex.rstをtouchしたら直りました…ごめんなさい。

さて、というわけで、英語->日本語が分かったところで日本語->英語に。


と思って作業してたら意外な事実が発覚…
sphinx/localeには"en"がない…なので、locale情報を読んでくれないっぽい。従って、en.poを作り、en/LC_MESSAGES/ を作ってもちゃんと読んでくれなかった。しょんぼりだ。

さては標準だと思ってるから?しょうがないので、sphinx/locale/にenというディレクトリを作ってlocaleにenを追加してあげれば良い。とりあえずes(スペイン語)のlocaleをコピった。

そしたら(もちろん説明はスペイン語だけど)ちゃんと英語で表示されました。「日本語msgidは無理」という話もありましたが、手元の環境ではきちんとできるようです。ただ、環境依存なことも考えられるので、もう少し検証が必要かもしれません。

あとはmsgidの順番

また、.poファイルで翻訳する時に.rstファイルの順番と変わって来てしまうという問題があるという話がありました。

見たところ、sphinxが.potファイルを書き出すときにすでに順番がおかしくなっています。これはsphinx/builders/gettext.py でself.catalogsがdefaultdictになってるからだと思います。これを順序を気にするものに入れ替えればいいような気がします。

issueに上げておくかなぁ。