nginx をネタに po4a で翻訳管理を始めてみる例

はじめに
=======

なんとなく、某氏のエントリでプレッシャーを感じたので、いっちょ書かねばなるまいと思った次第です。
いまさらこんな話かよ、と思っても笑顔でスルーしてくださいませ。

翻訳が間違ってる!!
===============

翻訳されたドキュメントを読んでいると、書いてあることが実際の挙動と違ったりしたことはないでしょうか。
よくよく気をつけて読んでみると、実は過去のバージョンについて書かれていたりします。

これもひとえに、ドキュメントを訳し続けるのは大変である、ということに尽きます。
ある程度まとまったドキュメントを訳すには時間がかかりますし、原文が頻繁に更新されてしまうと、追随するのも大変です。
更新に着いて行けなくなった訳文は、時が経つにつれて嘘となっていきます。そしていつかこう言われます。
「訳が使えないから、英語で読む」
大変不幸なことだと思います。

対策のひとつ po4a
=================

さて、「訳が着いて行けなくなったら、その部分は原文で表示したほうがいい」と思う、私のような人は他にも居ました。その成果のひとつが [po4a (po for anything)](http://po4a.alioth.debian.org) です。
po4aについて[OSCで紹介した時のスライド](http://www.slideshare.net/nabetaro/po-7177145)もありますので、良かったら参照してみてください。

po4aには以下の特徴があります。

* 訳文をgettextのpoファイルで管理する。
  * 訳されていない文は原文となる。
  * 豊富なgettext用ツールがそのまま使える。
  * poを適用して訳文を作るところまでをサポート。
* 良くも悪くも原文と同じ文書構成となる。
  * 訳文独自の部分を追加可能。
* 対応フォーマットがたくさんある。
  * DocBook XML, manpage, TeX, etc...
  * フォーマットのタグなどをなるべく除くことで、タグを誤って壊す事故を防げる。

po4aのツール群
==============

po4aはいくつかのperlスクリプトからなるツール群です。よく使うものは次のものではないでしょうか。

* po4a-gettextize: 原文や訳文をpoファイルへ変換
* po4a-translate: poファイルから訳文生成
* po4a: 複数のファイルに対して、po更新と訳文生成の一括処理

このうち、お手軽に始めるには po4a コマンドが楽だと思います。
今回は po4a コマンドを使う方向にします。
では、どんなふうに使っていくか試しにやってみます。

po4a化サンプル: nginx
==================

po4a化するに、自分の中でタイムリーなのでnginxのドキュメントを素材にします。

まずは、nginxのドキュメントのソースツリーを取得します。

```
$ hg clone http://hg.nginx.org/nginx.org
```

ルートディレクトリは以下の構成となっていました。

```
BSDmakefile
GNUmakefile
binary
dtd
sources
text
umasked.sh
xml
xsls
xslt
```

どうやらドキュメントのありそうなディレクトリは text と xml のようです。
ひとまず、xml 以下を訳せるようにしましょう。軌道に乗ったら、text についても手を広げればいいでしょう。

ここに、以下の設定ファイルと翻訳管理ディレクトリを作成することにします。
またルートディレクトリで po4a コマンドを実行することとします。

| パス | 用途 |
|---------| -----------------------------|
| po4a/ | 翻訳管理ディレクトリ |
| po4a/po/ | pot, poファイル格納ディレクトリ |
| po4a/add/ | 追加内容ファイル格納ディレクトリ |
| po4a.cfg   | 設定ファイル |

po4aの設定ファイル作成
--------------------------------

po4a コマンドは設定ファイルをもとに翻訳を行います。
設定ファイルの書式は po4a(1) を参照してください。まず、最小限のサンプルを以下のように作ります。

```
[po_directory] po4a/po

[type: xml] xml/en/index.xml $lang:xml/$lang/index.xml add_$lang:?po4a/add/addendum.$lang.add
```

[po_directory] に指定したディレクトリ内の potファイルや 言語コード.po ファイルを、自動的に翻訳対象にします。
[type: xml] で、ファイル形式をxmlに指定します。$lang は各言語の言語コードに展開されます。
上記の行でja.poを処理すると、xml/en/index.xml を xml/ja/index.xml に翻訳し、po4a/add/addendum.ja.add ファイルの内容を追加します。

potファイルとpoファイルの作成
--------------------------------

何はなくともpotファイルがなければ訳せません。
po4a/po にあるpotファイルが翻訳対象なのですが、まだありません。
po4aは設定ファイルから自動で生成できますが、ファイル名がわからないのです。
なので、空ファイルを作成します。ここでは nginx.pot としましょう。
作成したら、強制的に更新するフラグをつけてpo4aを起動します。

```
$ touch po4a/po/nginx.pot
$ po4a po4a.cfg -f
```

改めてpo4a/po/nginx.potを確認してください。potファイルができていると思います。
potファイルができたら、通常のgettextと同じ翻訳フローになります。

```
$ cd po4a/po/
$ msginit -i nginx.pot
```

po4a/po/ja.po ができていると思いますが、ファイル名が違う場合は ja.poになるようにしてください。
以上で、翻訳の準備が完了です。

……ちょっとまって。
ja.poのmsgidを見ると、グチャグチャじゃないですか?
実は po4a の xml の処理系は、タグをすべて段落として扱ってしまうため、ひとかたまりで扱いたいところでも別エントリにバラバラにしてしまうのです。
このあたりをpo4aのxml処理系に渡すオプションで調整します。


文書構造に合わせてオプション設定
-----------------------------------

nginxのドキュメントはarticleとmoduleという、2つのDTDで定義されたxmlで書かれているようです。
オプションをpo4a.cfgの[type: xml]に、ファイルごとに指定してもいいのですが、同じ記述を何度もするのは面倒です。
articleとmoduleでオプションをまとめて書きたいですね。
このようなときには、エイリアスを指定して、設定をまとめてしまいます。
po4a.cfgを以下のように更新します。module で扱うファイルも追加して確認しながらやっていきましょう。

```
[po_directory] po4a/po

[po4a_alias:article] xml opt:"-o \"inline=<link>\""
[po4a_alias:module] xml opt:"-o \"inline=<link> <value> <literal> <syntax> <c-func> <command>\" -o \"placeholder=<note>\""

[type: article] xml/en/index.xml $lang:xml/$lang/index.xml add_$lang:?po4a/add/addendum.$lang.add

[type: module] xml/en/docs/http/ngx_http_auth_basic_module.xml $lang:xml/$lang/docs/http/ngx_http_auth_basic_module.xml add_$lang:?po4a/add/addendum.$lang.add
```

正直に言うと、私もこのあたりはいつも試行錯誤するところになります。
本当はDTDをもとにきちんと書くのが良いのでしょう。

ファイルを列挙する
-------------------------

前節までで、曲がりなりにもpoファイルを翻訳できそうなところまで行くと思います。
あとは、DOCTYPEがarticleのものやmoduleのものを、xml/en/index.xml や xml/en/docs/http/ngx_http_auth_basic_module.xml と同様に列挙していきます。

grepで検索してあげればいいでしょうかね。

すみませんがこのあたりは省略します。

po4aを適用しながらja.poを翻訳
-----------------------------------------

あとは、ja.poを好きなpoエディタで編集して po4a コマンドで訳文を生成してください。
poエディタには好きなものを使用できるのが、po形式で訳す利点と言えます。
このあたりは豊富なgettext周辺ツールが、ほぼそのまま利用できます。

ただ問題も多々あるはずです。私が確認している問題点は、potファイルにある原文の参照位置が違うという問題があります。
このあたりのメリット、デメリットを天秤にかけて使っていただければいいのではないかと思います。

おわりに
========

駆け足に見てきましたが、ずいぶん長くなってしまいました。
こうしてみるとあまり使いやすいツールとは言えないですね (汗)。

あまりドキュメントが揃っているとは言えず、またその訳もアレなところが多々あると思います。
できれば、改善の提案をいただけるとありがたいです (翻訳の提案は、私宛で結構です)。

このエントリが、何かの役に立つと嬉しいのですが……