pandoc + sphinx + transifex で既存ドキュメントの翻訳を行う
この間の Sphinx+翻訳 Hack-a-thon で話題に上がった件について調査してみた。
お題は以下のとおり。
- 元の文書は markdown で記述されている
- Sphinx を使って翻訳してみようと思っている
- 元の文書が更新された時に差分管理できるとよい
その場で出た案はタイトルの通りで、
- pandoc で reST 形式に変換して
- Sphinx を使って gettext 化して
- sphinx-intl を使って transifex にアップロードして
- transifex で翻訳をすると良さそう
というもの。
gettext 化を挟むことで、翻訳しやすく、また原文の変化を追いかけやすいそうな。
というわけで、実際に試してみました。
環境を作る
お題は redis-doc。
まずはワークスペースを作る。
$ mkdir redis-doc $ cd redis-doc $ git init $ virtualenv . $ . bin/activate $ pip install --pre sphinx sphinx-intl transifex-client $ pip freeze > requirements.txt $ rehash $ git submodule add https://github.com/antirez/redis-doc
virutalenv で環境を作って、その中に Sphinx, sphinx-intl, transifex-client を入れてます*1。
そして、翻訳対象の文書を git の submodule として管理します。
Sphinx 環境を作る
つづいて Sphinx 環境を作ります。
translated ディレクトリ以下にプロジェクトを作ります。
$ sphinx-quickstart translated $ vi translated/source/conf.py language = 'ja' locale_dirs = ['locale/'] gettext_compact = False $ vi Makefile html: tx pull -l ja sphinx-intl build --pot-dir build/locale --locale-dir source/locale $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html $ cat > .gitignore bin/ include/ lib/ translated/build ^D $ git add . $ git commit -m 'Initial commit'
conf.py では language, locale_dirs, gettext_compact の設定をしています。翻訳する上で必要最低限の設定です*2。
また、Makefile の html ターゲットには tx pull と sphinx-intl build の実行を追加しています。
make html する際に transifex から最新の翻訳カタログを取ってくるようにするものです。
しばらく時間を開けるとコマンドを忘れてしまいがちなので、忘れないように記述を追加しておきます。
pandoc, transifex を使うための準備
続いて transifex 上に(アカウントと)プロジェクトを作成します。
サイトにアクセスすると大体わかると思うので説明は省略します。
そして、transifex-client(txコマンド)を使って transifex にアップロードする準備をします。
$ cd translated $ tx init $ echo 'type = PO' >> .tx/config $ cd ..
transifex ディレクトリにて tx init を実行して、設定ファイルを生成しておきます。
また、0.11系では .tx/config ファイルに type オプションが指定されていないので、書き加えておきます。
最後に markdown ファイルを pandoc で reST に変換して、transifex にアップロードするためのスクリプトを用意します。
#!/bin/bash TRANSIFEX_PROJECT_NAME=redis-doc mkdir -p translated/source/commands mkdir -p translated/source/topics cd redis-doc find . -name "*.md" -print0 | while read -r -d '' md; do CONVERTED="../translated/source/${md%.*}.rst" echo -n "Translating $md ... " if [ "$md" -nt "$CONVERTED" ]; then pandoc "$md" -o "$CONVERTED" touch -r "$CONVERTED" "$md" echo "done." else echo "skipped." fi done find . \( -name "*.jpg" -or -name "*.png" -or -name "*.gif" \) -print0 | while read -r -d '' img; do COPIED="../translated/source/$img" echo -n "Copying $img ... " if [ "$img" -nt "$COPIED" ]; then cp -a "$img" "$COPIED" echo "done." else echo "skipped." fi done cd ../translated make html sphinx-intl update --locale-dir source/locale --pot-dir build/locale sphinx-intl update-txconfig-resources --transifex-project-name=$TRANSIFEX_PROJECT_NAME --locale-dir source/locale --pot-dir build/locale tx push -s
このスクリプトを実行すると、
- pandoc を使って markdown ファイルを reST 形式に変換して translated/ ディレクトリに配置
- 画像類も適当にコピー
- Sphinx を使って gettext 化を実施
- sphinx-intl を使ってリソース登録
- transifex-client (txコマンド) を使って、翻訳カタログを transifex に転送
という一連の手順を実行します。
transifex で翻訳する
ひたすら翻訳してください。
HTML に変換する
transifex で翻訳が一息ついたら HTML に変換してみましょう。
変換する前に、目次となる index.rst を作っておきます。:glob: オプションを使って簡易的に並べています。
Redis Documentation (Japanese) =============================== .. toctree:: :glob: README topics/* commands/*
準備段階で Makefile をいじっているので make html を実行するだけで ok です。
$ cd translated
$ make html
元の文章が新しくなった場合は submodule を更新し、スクリプトを再実行すれば ok です。
この方法の問題点
この方法を試したところ、いくつか問題がありました。
- pandoc で適切に変換できない文章がある
- HTML から変換する際など、うまく変換できないことがありました
- redis-doc では見出しのないファイルがあるため、HTML に変換するときに toctree に含まれないという問題がありました
- sphinx-intl はファイル名に空白を含んでいるとうまく扱えない
- あとで pull request 送ります…