Provided by: po4a_0.47-2_all bug

名前

       po4a - ドキュメントやその他の翻訳フレームワーク

概要

       po4a (PO for anything) プロジェクトは、gettext ツールが想定していないドキュメントのような
       領域で翻訳をしやすくすること (またより興味深いのは、翻訳文の保守がしやすくなること) を目標
       にしています。

目次

       このドキュメントは以下のような構成となっています。

       1 なぜ po4a を使うのでしょうか? なにがよいのでしょうか?
           この導入の章では、プロジェクトの動機とその哲学について説明します。翻訳を行うに当たって
           po4a を評価中であるなら、まずこの章を読んでください。

       2 po4a の使い方は?
           この章は、処理全体を理解していただけるように、ユーザの質問に答える形のリファレンスマ
           ニュアルの一種です。po4a をどのように使用するかを紹介し、特定のツールのドキュメントに
           導入する方法を提供します。

           新規翻訳を始めるには?
           翻訳をドキュメントファイルに適用するには?
           po4a 翻訳を更新するには?
           既存の訳を po4a にコンバートするには?
           翻訳におまけのテキスト (翻訳者名など) を追加するには?
           一度のプログラム実行でこのすべてを行うには?
           po4a をカスタマイズするには?
       3 どのように動作しますか?
           この章では、保守改良を自信を持って助けていただけるよう、po4a 内部の概要を説明しま
           す。また、何故思ったように動作しないか、どのように問題を解決すればいいかを理解する助け
           になるかもしれません。

       4 FAQ
           本章ではよく訊かれる質問を分類します。実際、以下のような形でほとんどの質問を定型化でき
           ました。「なぜああではなく、このような設計をしたのですか?」 po4a がドキュメントを翻訳
           する正しい方法ではないと感じたら、この節を読むようにするべきです。あなたの疑問への答え
           にならないなら、<po4a-devel@lists.alioth.debian.org> メーリングリストで私たちにお問い
           合わせください。私たちはフィードバックが大好きです。

       5 モジュール固有の記述
           この章では、翻訳者とオリジナルの作者の視点で、それぞれのモジュールの仕様を示していま
           す。翻訳生活をより楽にするために、このモジュールで翻訳する際に遭遇する文法や、オリジナ
           ルのドキュメントが従わなければならないルールについて学ぶには、これをお読みください。

           実際、この節は本ドキュメント本来の部分ではなく、各モジュールのドキュメントにありま
           す。これにより、ドキュメントとコードを共に保守し、確実に情報が最新となるのを助けます。

なぜ po4a を使わなくてはならないのでしょう? 何かいいことがありますか?

       誰でもソフトウェアやそのソースコードにアクセスできるようにする、オープンソースの考え方が私
       は好きです。しかしフランス人であり、ソフトウェアのオープン度がライセンスのみでないことをよ
       く意識しています。翻訳されていないフリーソフトウェアは、非英語圏の人々には役に立たないので
       す。ですから本当に誰でも利用できるように、まだ作業を行っています。

       オープンソース活動家のこの状況の認知度は、最近劇的に向上しました。翻訳者として最初の戦いに
       勝利し、翻訳の重要性を周知できました。しかし残念ながら、これはまだ簡単な部類でした。今度
       は、すべてを翻訳するよう作業しなければなりません。

       実際には、オープンソースソフトウェア自身は、すばらしい gettext ツール群のおかげで、かなり
       きちんと翻訳の恩恵にあずかっています。これはプログラムから翻訳する文字列を抽出し、翻訳者に
       決まった形で提供し、実行時には、作業の成果である翻訳済みのメッセージをユーザに表示できま
       す。

       But the situation is rather different when it comes to documentation. Too often, the
       translated documentation is not visible enough (not distributed as a part of the program),
       only partial, or not up to date. This last situation is by far the worst possible one.
       Outdated translation can turn out to be worse than no translation at all to the users by
       describing old program behavior which are not in use anymore.

   問題解決
       ドキュメントの翻訳は、本来そんなに難しくありません。テキストはプログラムのメッセージよりも
       ずっと長く、訳了するのに時間がかかりますが、技術スキルが本当に必要というわけではないので
       す。難しい部分は成果物を保守しようとしたときに現れます。変更箇所や更新すべき箇所を探し出す
       のは非常に難しく、誤りやすく、苦痛をともなう作業です。世の中にこんなにも時代遅れなドキュメ
       ントが存在しているのは、これが原因だと考えています。

   po4a の解
       以上より、po4a の全体の目標は、ドキュメントの翻訳を 保守できる ようにする事です。この新し
       い分野に gettext の方法論を再利用しようと考えています。gettext のように、オリジナルの場所
       からテキストを抽出し、決まったフォーマットで翻訳者に提示します。古典的な gettext ツールは
       オリジナルが新しくリリースされると、更新するのを助けてくれます。しかし、古典的な gettext
       モデルとは異なり、翻訳したものをオリジナルの構造に再度注入して、英語版と同じように処理・配
       布できるようにします。

       このおかげで、ドキュメントのどこが変更されて、修正する必要があるかを見つけるのが、非常に簡
       単になりました。他の長所としては、オリジナルドキュメントの構造が根本的に再編成されて、章が
       移動・結合・分割されたとしても、ほとんどすべての作業をツールが行うということもあります。翻
       訳用にドキュメント構造からテキストを抽出することで、複雑なテキストフォーマットに触らず、ド
       キュメントを壊すといった状況になる可能性を (完全になくすというわけには行きませんが) 低くで
       きます。

       このアプローチの利点と欠点のより完全な一覧は、このドキュメント下部の FAQ をご覧ください。

   サポートするフォーマット
       現在、このアプローチで実装に成功しているのは、以下のテキスト整形フォーマットです。

       man

       たくさんのプログラムで使われている、古き良きマニュアルページのフォーマットです。このフォー
       マットはいくらか難しく、初心者には本当に易しくないので po4a のサポートは非常に歓迎されてい
       ます。Locale::Po4a::Man(3pm) モジュールは、BSD man ページ (Linux でも本当に一般的) で使用
       されている mdoc フォーマットもサポートしています。

       pod

       Perl のオンラインドキュメントフォーマットです。言語や拡張は、既存の Perl スクリプトと同じ
       ように記述されています。同じファイルに組み込んで、実際のコードのそばにドキュメントを記述し
       保守しやすくしています。プログラマーの生活は楽になりますが、残念ながら翻訳者の生活は楽には
       なりません。

       sgml

       このごろは XML によっていくらか取って代わられましたが、このフォーマットは長い間かなり多く
       のドキュメントで使用されています。これで完全な本を作ることができます。あまりにもドキュメン
       トが長いため、翻訳を更新するのはまさしく悪夢といえます。また、オリジナルドキュメントを更新
       すると、インデントが再構成されるため、diff もあまり役に立ちません。幸い、po4a はこの処理で
       も助けになります。

       現在、DebianDoc と DocBook DTD のみサポートしていますが、新しくサポートするものを追加する
       のは、本当に簡単です。また、コマンドラインに必要な情報を与え、コードを変更せずに未知の
       SGML DTD を po4a で使用することもできます。詳細は Locale::Po4a::Sgml(3pm) をご覧ください。

       TeX / LaTeX

       LaTeX フォーマットはフリーソフトウェア界や出版界で使われている有名なフォーマットで
       す。Locale::Po4a::LaTeX(3pm) モジュールは Python のドキュメントや書籍、各種発表でテストさ
       れています。

       texinfo

       GNU のドキュメントはすべてこのフォーマットで書かれています (公式 GNU プロジェクトになる必
       要条件の一つです)。po4a のLocale::Po4a::Texinfo(3pm) サポートは始まったばかりです。バグ報
       告や機能のリクエストをお願いします。

       xml

       XML フォーマットは多くのドキュメントフォーマットの基礎になっています。

       現在、po4a では DocBook の DTD をサポートしています。詳細は、Locale::Po4a::Docbook(3pm) を
       ご覧ください。

       その他

       po4a は、カーネル 2.4.x のコンパイルオプションのドキュメントや、dia ツールで使用する図と
       いった、もっとレアだったり特殊なフォーマットもサポートしています。新しいものを追加するのは
       非常に簡単で、目標フォーマットのパーサを追加するのが主なタスクとなっています。この詳細情報
       は Locale::Po4a::TransTractor(3pm) をご覧ください。

   サポート外のフォーマット
       残念ながら、po4a はいくつかのドキュメントフォーマットのサポートが欠けています。

       ドキュメントだけではなく、po4a でサポートしたい他のフォーマットがたくさんあります。まさし
       く私たちは、古典的な gettext ツールが残した「市場の穴」を埋めるのを目標としています。パッ
       ケージの説明 (deb や rpm)や、パッケージのインストールスクリプトの質問、パッケージの
       changelog、ゲームのシナリオや wine リソースファイルといったプログラムが使用するすべての特
       殊ファイルを取り込みます。

po4a の使い方は?

       この章は、処理全体を理解していただけるように、ユーザの質問に答える形のリファレンスマニュア
       ルの一種です。po4a をどのように使用するかを紹介し、特定のツールのドキュメントに導入する方
       法を提供します。

   概要図
       以下の図は po4a を用いたドキュメント翻訳過程の概要です。複雑になってしまいましたが、おじけ
       づかないでください。処理の 全体 を表そうとして、このようになってしまいました。いったんプロ
       ジェクトを po4a に変換すると図の右の部分のみが関係します。

       翻訳する文書の例として master.doc をとり、対応する翻訳済み文書を translation.doc としま
       す。拡張子は、フォーマットにより .pod, .xml, .sgml となります。図の各部の詳細は、次節で説
       明します。

                                          master.doc
                                              |
                                              V
            +<-----<----+<-----<-----<--------+------->-------->-------+
            :           |                     |                        :
          {翻訳}        |            { master.doc の更新 }             :
            :           |                     |                        :
          XX.doc        |                     V                        V
       (オプション)     |                 master.doc ->-------->------>+
            :           |                    (新)                      |
            V           V                     |                        |
         [po4a-gettextize]   doc.XX.po--->+   |                        |
                 |             (旧)       |   |                        |
                 |              ^         V   V                        |
                 |              |     [po4a-updatepo]                  |
                 V              |           |                          V
          translation.pot       ^           V                          |
                 |              |         doc.XX.po                    |
                 |              |         (fuzzy)                      |
              { 翻訳 }          |           |                          |
                 |              ^           V                          V
                 |              |       {手動編集}                     |
                 |              |           |                          |
                 V              |           V                          V
             doc.XX.po --->---->+<---<---- doc.XX.po   addendum     master.doc
               (初期)                      (最新化)  (オプション)    (最新化)
                 :                          |            |             |
                 :                          V            |             |
                 +----->----->----->------> +            |             |
                                            |            |             |
                                            V            V             V
                                            +------>-----+------<------+
                                                         |
                                                         V
                                                  [po4a-translate]
                                                         |
                                                         V
                                                       XX.doc
                                                      (最新化)

       左側で、po4a を使用していない翻訳のこのシステムへの変換を表します。右側の先頭でオリジナル
       の作者の行動 (ドキュメントの更新) を描いています。右側の中盤で po4a が自動で行う動作を描い
       ています。新しい要素を抽出し、既存の翻訳と比較しています。変更のなかった部分には以前の翻訳
       を使います。一部変更がある部分には、以前の翻訳を使いますが、翻訳を更新する必要があるという
       マークが付きます。図の下部は、整形済みドキュメントがどのように組み立てられるかを示していま
       す。

       実際には、翻訳者として、唯一手で操作しなければならないのは、{手動編集} と印が付いている部
       分です。あぁ申し訳ありません。po4a は翻訳の助けにはなりますが、翻訳をしてくれるわけではあ
       りません……

   新規翻訳を始めるには?
       この節では、po4a で新しく翻訳を始めるのに必要な手順を説明します。既存プロジェクトをこのシ
       ステムに変換する方法は、関連セクションで詳しく取り扱います。

       po4a を用いて新しく翻訳を始めるには、以下の手順を行う必要があります。

       - オリジナルの <master.doc> ドキュメントから、翻訳するテキストを新しい翻訳テンプレート
         <translation.pot> ファイル (gettext フォーマット) に抽出します。これには po4a-gettextize
         プログラムを以下のように使います。

           $ po4a-gettextize -f <format> -m <master.doc> -p <translation.pot>

         <format> は、通常 master.doc ドキュメントで使用しているフォーマットです。おそら
         く、translation.pot に出力されます。オプションについての詳細は po4a-gettextize(1) をご覧
         ください。

       - 翻訳すべき箇所を、実際に翻訳してください。これには POT ファイルの名前を、例えば
         doc.XX.po (XX は翻訳する ISO639 の言語コード。例: フランス語は fr) と変更し、そのファイ
         ルを編集します。プログラムのメッセージに対する翻訳と混同しないように、XX.po と言う名前を
         付けないようにするのが良い方法ですが、これはあなた次第です。PO ファイルのヘッダの編集を
         忘れないでください。これが重要です。

         実際の翻訳は、Emacs や Vi の PO mode や Lokalize (KDE 由来)、Gtranslator (GNOME 由
         来)、またはお好みのプログラムを用いて行えます (例、Virtaal)。

         これについてもっと学ぶのなら、gettext-doc パッケージにある gettext のドキュメントを決定
         版として参照する必要があります。

   翻訳をドキュメントファイルに適用するには?
       翻訳が終わったら、翻訳したドキュメントを、オリジナルのものと併せてユーザに提供しましょ
       う。これには以下のように po4a-translate(1) プログラムを使用してください (XX は言語コードで
       す)。

         $ po4a-translate -f <format> -m <master.doc> -p <doc.XX.po> -l <XX.doc>

       先ほどと同様に、<format> は master.doc ドキュメントで使用しているフォーマットです。しかし
       今度は、-p フラグで指定する PO ファイルが入力部にあります。これはあなたが訳したもので
       す。XX.doc に出力します。

       詳細は po4a-translate(1) をご覧ください。

   po4a 翻訳を更新するには?
       オリジナルの master.doc ファイルが変更された時に訳を更新するには、 po4a-updatepo(1) を以下
       のように使用します。

         $ po4a-updatepo -f <format> -m <new_master.doc> -p <old_doc.XX.po>

       (詳細は po4a-updatepo(1) をご覧ください)

       当然、ドキュメントの新しい段落が、この操作で魔法のように PO ファイルで翻訳されている、とい
       うことはありません。PO ファイルを手で更新する必要があります。同様に、多少変更があった段落
       についても、再度翻訳する必要があります。変更を見逃さないように、この修正の間、"fuzzy" マー
       カが付き、po4a-translate を使用する前にそのマーカを消さなければなりません。初期翻訳と同様
       にお好みの PO エディタを使用するのが最善です。

       未訳部や fuzzy な部分を取り除いて、PO ファイルを再度最新にしたら、前節で説明したように翻訳
       済みドキュメントファイルを生成できます。

   既存の訳を po4a にコンバートするには?
       オリジナルの master.doc ドキュメントが大きく再編成されるまでは、手で翻訳するのに不満はな
       かったでしょう。diff のようなツールがうまくいかなくなったから、po4a に乗り換えようとしてい
       るのだと思います。もちろん、この処理で既存の翻訳を失いたくはありません。ご心配なく。この場
       合も po4a では扱えます。これを gettext 化と呼びます。

       ここでのキーは、ツールが内容のすりあわせを行えるように、訳したドキュメントとオリジナルド
       キュメントが同じ構造をしていることです。

       あなたがツイていれば (例えば両方のドキュメントの構造が完全に一致するとか)、シームレスに一
       瞬で完了します。そうでなければ、この手順に何故こんなひどい名前が付いているのか理解するで
       しょう。とはいえこんなひどい作業でも準備しておくに越したことはありません。いずれにし
       ろ、po4a で後々楽になるために支払う価値があると思ってください。ありがたいことに一回だけや
       ればいいのです。

       このことは、どれだけ強調しても、しすぎということはないでしょう。処理を簡単にするのに、翻訳
       の元にした完全なバージョンを見つけるのが重要です。最高の状況は翻訳に使用した VCS のリビ
       ジョンを控えておき、翻訳の中でそれを変更していないことです。この場合、それを利用できます。

       更新されたオリジナルテキストを古い翻訳と一緒に使用するのは、うまくいきません。そういったこ
       ともできますが、本当に大変で、できれば避けた方がいいでしょう。事実上、もう一度オリジナルテ
       キストを見つけられないなら、一番いいのはあなたのために gettext 化してくれる人を見つけるこ
       とでしょう。(あ、いや、私じゃないですよ ;)

       おそらくドラマチックすぎるでしょうが、何か問題があるとしても、すべてをもう一度翻訳し直すよ
       りは速いと思います。既存の Perl ドキュメントフランス語訳を gettext 化するのに、問題も あり
       ました が、1 日でできました。これは 2MB のテキストで、新規に翻訳するには数ヶ月を要したで
       しょう。

       ではまず、手順の基本を説明します。それから何か問題があれば、戻ってきてヒントを示したいと思
       います。理解しやすいように、もう一度上記の例を使用しましょう。

       翻訳した XX.doc に対応する、古い master.doc をもう一度用意すると、translation.pot ファイル
       を手で訳さなくても、PO ファイル doc.XX.po を、直接 gettext 化できます。

        $ po4a-gettextize -f <format> -m <old_master.doc> -l <XX.doc> -p <doc.XX.po>

       ツイているならこれで完了です。古い翻訳を po4a に変換し、すぐに更新タスクを行えます。数節前
       に説明した、最新のオリジナルドキュメントと PO ファイルの同期を取る手順に従い、翻訳を更新し
       てください。

       うまくいっているように見えても、この処理に誤りの入り込む余地があることに注意してくださ
       い。ポイントは po4a が、オリジナルと翻訳が一致しているかどうかを理解できないということで
       す。この処理の結果、すべての文字列に "fuzzy" マークが付いてしまうのはこういうわけで
       す。マーカを削除する前に、注意してチェックする必要があります。

       しばしば、ドキュメント構造が完全に一致する、というわけには行きません。この場合ゲームの内容
       は、構造を一致させるのにファイルを編集する、ということになります。

       後にある gettext 化: どのように動作しますか?  節を読むと参考になると思います。内部処理を理
       解することは、この作業の助けになります。po4a-gettextize の利点は、何か問題が発生すると、詳
       しく教えてくれることです。まず、ドキュメントに構造上の食い違いがある場合、その箇所を指摘し
       ます。これで一致しない文字列や、テキスト中の箇所、それらの型が分かります。さらに、そこまで
       で生成した PO ファイルは、gettextization.failed.po に書き出してあります。

       -   翻訳者名や、翻訳に貢献した人々への謝辞といった、翻訳で追加した箇所を取り除いてくださ
           い。次節で説明する追加内容に後で改めて追加できます。

       -   遠慮なくオリジナルと翻訳の両方を編集してください。最も重要なのは PO ファイルを手に入れ
           ることです。これを後から更新できます。双方 gettext 化してしまえば、楽になりますの
           で、翻訳の編集をすると良いといわれています。

       -   必要であれば、翻訳されていない部分を、オリジナルから削ってください。後でドキュメントを
           PO と同期を取るときに自分自身で復元します。

       -   構造を少しだけ変えた (2 つの段落をまとめたとか、1 つの段落を分けたとか)のなら、その変
           更を元に戻してください。オリジナルに問題があるなら、オリジナルの作者に連絡するべきで
           しょう。コミュニティの一部だけのために翻訳で修正していたとして、その上で po4a を使うの
           は無理です ;)

       -   時には、段落の内容は一致するけれども、型があわない場合があります。その修正法はフォー
           マットに依存します。POD や man では、片方の行は空白で始まっているのに、もう片方はそう
           ではない、ということが実際にあります。こういったフォーマットでは、そのような段落は改行
           できず、別の型となります。そのようなときは空白を削除してください。おそらくタグ名のタイ
           プミスでしょう。

           Likewise, two paragraphs may get merged together in POD when the separating line
           contains some spaces, or when there is no empty line between the =item line and the
           content of the item.

       -   時々、ファイル間で同期が取れておらず、翻訳が間違った段落に割り当てられることがありま
           す。これはファイルに以前から問題があったことを示しています。gettextization.failed.po
           をチェックして、同期が取れない箇所を探し、修正してください。

       -   時々、po4a がオリジナルや翻訳のテキスト部分を、食べてしまったと強く思うかもしれませ
           ん。gettextization.failed.po に緩く一致した箇所が、どちらも記録されます。その後、前後
           の正しいものと一致するかを試して gettext 化は失敗し、正しいものが見えなくなります。初
           めて私の身に起きたとき、私がしたように、po4a を盛大に罵ってください。

           この不幸な状況は、同じ段落がドキュメント中で繰り返されているときに起こります。この場
           合、PO ファイルに新しいエントリは追加されませんが、既存のエントリに参照が追加されま
           す。

           So, when the same paragraph appears twice in the original but both are not translated
           in the exact same way each time, you will get the feeling that a paragraph of the
           original disappeared. Just kill the new translation. If you prefer to kill the first
           translation instead when the second one was actually better, remove the second one
           from where it is and put the first one in the place of the second one.

           反対に、2 つの似て非なる段落が、全く同じように翻訳されていると、翻訳した段落が見えなく
           なったと感じることでしょう。その場合は、無駄な文字列をオリジナルの段落に追加すると解決
           します ("I'm different" など)。これは同期中に見えなくなりますが、気にしないでくださ
           い。テキストが十分短ければ、gettext は翻訳と既存のテキストをマッチします。(fuzzy にし
           ますが、gettext 化した後は、すべての文字列が fuzzy になるので気にすることはありません)

       うまくいけば、以上の tips は gettext 化作業を助け、大事な PO ファイルをもたらすでしょ
       う。ファイルの同期や、翻訳を始める準備ができています。大きなテキストの場合、最初の同期が長
       時間にわたる場合があることに注意してください。

       例えば、初めてフランス語版 Perl ドキュメント (5.5 MB の PO ファイル) に po4a-updatepo を実
       行したとき、1GHz G5 コンピュータでまるまる 2 日かかりました。ええ、48 時間です。しかしその
       後は、私の古いノートパソコンで十数秒しかかかりません。これは初回の実行で、PO ファイルのほ
       とんどの msgid が POT ファイルのものと一致しなかったからです。このため gettext は、もっと
       も近いものを探すのに、実行コストの高い文字列近接アルゴリズムを使わなくてはなりません。

   翻訳におまけのテキスト (翻訳者名など) を追加するには?
       gettext アプローチ故に、po4a でのテキストの追加は、単にオリジナルのものに沿って新しいファ
       イルを編集するよりも難しくなっています。しかし、いわゆる 追加内容 のおかげで追加できます。

       追加内容を、処理後のローカライズしたドキュメントに適用するパッチの類として見なすとわかりや
       すいでしょう。通常のパッチとは非常に異なっています (1 行だけの文章、Perlの正規表現を埋め込
       み、削除できず新しいテキストの追加のみ) が、機能的には同じです。

       目標は、オリジナルドキュメントにない内容を、翻訳したドキュメントに追加できるようにすること
       です。よくある使用法は、翻訳自体に関する節や、貢献者リスト、翻訳についてのバグレポートのし
       かたを追加することです。

       追加内容は別個のファイルで提供されなければなりません。最初の行では、生成したドキュメントの
       どこに配置するかといったことを記述します。追加内容ファイルの残りは、結果のドキュメントの決
       まった場所へ、逐次追加されます。

       ヘッダには、以下のようにかなり厳密な文法があります。PO4A-HEADER: で始めなければならず、セ
       ミコロン (;) 区切りの key=value フィールドが続きます。空白が重要です。セミコロン (;) を値
       に使用できず、クォートが役に立たないことに注意してください。

       また恐ろしげに聞こえますが、以下の例は、必要なヘッダ行の記述法を見つける手助けになるでしょ
       う。議論の前提として、"About this document" 節の後に "About this translation" 節を追加する
       こととします。

       以下に有効なヘッダキーを挙げます。

       position (必須)
           正規表現です。追加内容をこの正規表現でマッチした行のそばに配置します。ここではオリジナ
           ルドキュメントではなく、翻訳済みドキュメントについて説明していることに注意してくださ
           い。この正規表現にマッチする行が複数ある (もしくはない) 場合、追加に失敗します。実際の
           ところ、追加内容を間違った場所に挿入してしまうより、エラーを報告した方がよいでしょう。

           以下この行を position point と呼びます。追加内容を追加するポイントを insertion point
           と呼びます。この二つのポイントはお互い近くにありますが、同じではありません。例えば、新
           しい節を挿入する場合、position point を前節のタイトルとして、po4a にはその節の最後に挿
           入するよう指示するのが簡単です (position point は特定の行がマッチするような正規表現で
           表すことを覚えておいてください)。

           position point に対する insertion point の地域化は、以下で説明する mode,
           beginboundary, endboundary の各フィールドで制御します。

           この場合、以下のようになります。

                position=<title>About this document</title>

       mode (必須)
           beforeafter という文字が入り、position point からの 追加内容の位置を指定します。

           新しいセクションを、マッチした箇所の次に配置したい場合、以下のようにします。

                mode=after

       beginboundary (mode=after の時のみ使用。この場合必須)
       endboundary (同上)
           追加内容を後ろに続けるセクションの、最後にマッチする正規表現です。

           mode=after の場合、insertion pointposition point の後になりますが、すぐ後ではあり
           ません! position point で始まるセクションの後ろになります。なお、???boundary 引数と行
           の前 (ないし後) とがマッチします。どちらになるかは beginboundary ないし endboundary で
           決まります。

           この場合、以下のように追加して、セクションの終わりに一致するように指定できます。

              endboundary=</section>

           また、以下のようにして次のセクションの直前を指定できます。

              beginboundary=<section>

           どちらの場合でも、</section> の後で、<section> の前に追加内容を配置します。ドキュメン
           トが再構成されても動作するので、前者の方がいいでしょう。

           どちらの形態もあるのは、ドキュメントフォーマットが異なるからです。その中には、 (ちょう
           ど使用した </section> のような) セクションの終わりを示すもの、(man のような) 明確なセ
           クションの終わりを表さないものがあります。前者の場合は、boundaryセクションの最後
           に一致するので、insertion point はその後になります。後者の場合は、boundary次のセク
           ションの先頭 に一致するので、insertion point はその前になります。

       これは分かりにくいですが、次の例はよく分かると思います。

       今まで説明したことをまとめると、SGML ドキュメントの "About this document" の後に "About
       this translation" を追加するには、以下のヘッダ行のどちらかを使用できます。
          PO4A-HEADER: mode=after; position=About this document; endboundary=</section>
          PO4A-HEADER: mode=after; position=About this document; beginboundary=<section>

       以下の nroff セクションの後に何か追加したいとします。
           .SH "AUTHORS"

         position はこの行にマッチし、beginboundary は次のセクションの先頭 (例 ^\.SH) にマッチす
         べきでしょう。そこで、追加内容をこの position point で、beginboundary にマッチした
         先頭行の 直前 に追加します。以下のようになります。

          PO4A-HEADER:mode=after;position=AUTHORS;beginboundary=\.SH

       セクション全体を追加するのではなく、セクション内 ("Copyright Big Dude" の後など) に何か追
       加したい場合、position はこの行にマッチするように与え、beginboundary は任意の行にマッチす
       るように与えます。
          PO4A-HEADER:mode=after;position=Copyright Big Dude, 2004;beginboundary=^

       ドキュメントの最後に何か追加したい場合、position はドキュメントの任意の行 (しかし 1 行の
       み。ユニークでないと po4a は処理しません) にマッチするように与え、endboundary は何もマッチ
       しないように与えます。"EOF" のような単純な文字列を使用せず、ドキュメントにたまたま含まれて
       いるものを使用してください。
          PO4A-HEADER:mode=after;position=<title>About</title>;beginboundary=FakePo4aBoundary

       いずれの場合にも、正規表現であることを忘れないでください。例えば、次の行で終わってい
       る、nroff セクションの最後にマッチしたい場合を考えます。

         .fi

       ここでは、.fiendboundary として使用しないでください。明らかに想定していない、"the[
       fi]le" にもマッチしてしまいます。正しい endboundary は、この場合  ^\.fi$ となります。

       追加内容が想定通りにうまく動作しない場合、-vv 引数をツールに渡してみてください。追加内容を
       配置する際の挙動を、表示してくれます

       もっと詳細な例

       オリジナルドキュメント (POD フォーマット)

        |=head1 NAME
        |
        |dummy - a dummy program
        |
        |=head1 AUTHOR
        |
        |me

       さらに、以下の翻訳者についての(フランス語の)節を追加する追加内容をファイルの最後に追加しま
       す。(フランス語で "TRADUCTEUR" は "TRANSLATOR"、"moi" は "me" の意味です)

        |PO4A-HEADER:mode=after;position=AUTEUR;beginboundary=^=head
        |
        |=head1 TRADUCTEUR
        |
        |moi

       AUTHOR の前に追加内容を追加するには、以下のヘッダを使用してください。

        PO4A-HEADER:mode=after;position=NOM;beginboundary=^=head1

       これは、"NAME" セクション (フランス語では "NOM") の後にある、beginboundary /^=head1/ に
       マッチした次の行が作者を定義している、ということで動作します。そのため、両方のセクションの
       間に追加内容が挿入されます。

   一度のプログラム実行でこのすべてを行うには?
       po4a を使うことは、それぞれ 3 つ以上の引数が必要な 2 つの異なるプログラムを、ユーザが正し
       い順番 (po4a-updatepo のあとに po4a-translate) で実行しなければならないということ
       で、少々誤る傾向にあるということがわかりました。その上で、複数のフォーマットが使われている
       すべてのドキュメントを、一つだけの PO ファイルにするのは、このシステムでは難しいことでし
       た。

       この難しさを解消するために、po4a(1) プログラムは設計されました。一度このシステムに移行すれ
       ば、どこに翻訳したファイルがあるか (PO と POT)? オリジナルドキュメントがどこにあるか? その
       フォーマットは? 翻訳はどこに置くべきか?  を説明するシンプルな設定ファイルを書くことになり
       ます。

       そして、このファイルで po4a(1) を呼ぶことで、PO ファイルがオリジナルドキュメントに対して同
       期が取れており、翻訳済みドキュメントが適切に生成されることを保証できます。もちろん、このプ
       ログラムを二度呼びたくなるかも知れません。一度目は編集前に PO ファイルを更新するために、二
       度目はその後で、完璧に更新された翻訳済みドキュメントを得るために。しかし一つのコマンドライ
       ンしか覚えておく必要はありません。

   po4a をカスタマイズするには?
       po4a モジュールは、モジュールの挙動を変更するオプション (-o オプションで指定) があります。

       モジュールをカスタマイズしたり、新規 / 派生 / 変更モジュールを lib/Locale/Po4a/ に配置でき
       ます。また、PERLLIB 環境や PERL5LIB 環境で指定されるパスに、lib に追加することもできます。

          PERLLIB=$PWD/lib po4a --previous po4a/po4a.cfg

       注: lib ディレクトリの実際の名前は重要ではありません。

どのように動作しますか?

       この章では、保守改良を自信を持って助けていただけるよう、po4a 内部の概要を説明します。ま
       た、何故思ったように動作しないか、どのように問題を解決すればいいかを理解する助けになるかも
       しれません。

   この大きな絵はなんですか?
       po4a のアーキテクチャはオブジェクト指向です (Perl で。きちんとしていませんか?)。すべての
       パーサクラス共通の派生元は、TransTractor と呼ばれています。このヘンな名前は、ドキュメント
       の翻訳と文字列の抽出を同時に行うところから付けられています。

       もっと形式張っていうと、入力として翻訳するドキュメントと訳文が入っている PO ファイルを取
       り、結果を以下の 2 つに分けて出力します。別の PO ファイル (入力ドキュメントから翻訳可能な
       文字列を抽出した結果) と、翻訳済みドキュメント (入力したファイルと同じ構造ですが、翻訳可能
       な文字列は入力 PO ファイルの内容で置換されているファイル) です。以下に図示します。

          入力ドキュメント-\                             /---> 出力ドキュメント
                            \      TransTractor::       /          (翻訳済)
                             +-->--   parse()  --------+
                            /                           \
          入力 PO ---------/                             \---> 出力 PO
                                                                (抽出済)

       この小さな骨状の絵は、po4a アーキテクチャのすべてのコアを表しています。入力 PO や出力ド
       キュメントを省略すると、po4a-gettextize になります。両方の入力を行い、出力 PO を無視する
       と、po4a-translate になります。

       TransTractor::parse() は各モジュールで実装されている仮想関数です。どのように動作するかを説
       明するのに、簡単なサンプルがあります。これは、先頭に <p> が付いた段落のリストをパースしま
       す。

         1 sub parse {
         2   PARAGRAPH: while (1) {
         3     $my ($paragraph,$pararef,$line,$lref)=("","","","");
         4     $my $first=1;
         5     while (($line,$lref)=$document->shiftline() && defined($line)) {
         6       if ($line =~ m/<p>/ && !$first--; ) {
         7         $document->unshiftline($line,$lref);
         8
         9         $paragraph =~ s/^<p>//s;
        10         $document->pushline("<p>".$document->translate($paragraph,$pararef));
        11
        12         next PARAGRAPH;
        13       } else {
        14         $paragraph .= $line;
        15         $pararef = $lref unless(length($pararef));
        16       }
        17     }
        18     return; # Did not got a defined line? End of input file.
        19   }
        20 }

       6 行目で、2 回目の <p> が現れました。これは次の段落である印です。そこで、得た行をオリジナ
       ルドキュメントに戻し (7 行目)、これまで生成した paragraph を出力に push します。9 行目で先
       頭の <p> を削除した後、このタグと残りの段落を翻訳したものを結合して push します。

       translate() 関数はとてもクールです。引数を出力 PO ファイル (抽出済) に挿入し、入力 PO ファ
       イル (翻訳) で見つかった翻訳を返します。pushline() の引数の一部で使用するため、この翻訳が
       出力ドキュメントに定着します。

       クールじゃないですか? 十分シンプルなフォーマットなら、完全な po4a のモジュールを 20 行以下
       で作成できます……

       Locale::Po4a::TransTractor(3pm) で、これについてもっと知ることができます。

   gettext 化: どのように動作しますか?
       ここでの考え方は、オリジナルドキュメントとその翻訳を取り、翻訳から抽出した N 番目の文字列
       は、オリジナルから抽出した N 番目の文字列の翻訳であると言うことです。動作するには、双方の
       ファイルの構造がまったく同じでなければなりません。例えば、ファイルが以下の構造を持つ場
       合、残念ながら翻訳の 4 番目の文字列 (型が「章」) は、オリジナルの 4 番目の文字列 (型が「段
       落」) の翻訳となります。

           オリジナル       翻訳

         章                 章
           段落               段落
           段落               段落
           段落             章
         章                   段落
           段落               段落

       これについては、po4a のパーサはオリジナルファイルと翻訳ファイルの双方で、PO ファイルを抽出
       するのに使用されます。オリジナルファイル由来の PO ファイルにある文字列の翻訳が、翻訳ファイ
       ル由来の PO ファイルの文字列であるとして、新しく PO ファイルを生成します。出力した文字列が
       実際にそれぞれの翻訳となっているかをチェックするために、po4a のドキュメントパーサは、ド
       キュメントから抽出した文字列の構文タイプ情報を出力すべきです (既存のものはすべてそうします
       し、あなたのものもそうするべきです)。さらにその情報を、双方のドキュメントが同じ構文である
       かどうかを確認するのに使用します。先の例では、4 番目の文字列は片方では段落ですが、もう片方
       では章見出しであることを検出し、問題を報告できます。

       理論上、問題を検出した後でファイルを (ちょうど diff がするように) 再同期することは可能で
       す。しかし、非同期の前にある、再同期するべき文字列は明確ではなく、何度もまずい結果に終わる
       でしょう。以上が、何かまずい場合、現在の実装では再同期を行わず、失敗について詳しく出力する
       理由です。問題の修正にはファイルの手修正が必要です。

       これだけ用心していても、この部分は非常に間違いやすいです。そのため、このように推測された翻
       訳すべてを fuzzy とマークし、翻訳者のレビューと確認を行うようにしています。

   追加内容: どのように動作しますか?
       さて、これはかなり簡単です。すべての追加内容が適用されるまで、翻訳済みドキュメントは、直接
       ディスクに書かれていませんが、メモリに保管されています。ここに関わるアルゴリズムはかなり率
       直です。position 正規表現にマッチする行を探し、mode=before の場合はその前に追加内容を挿入
       します。そうでなければ、boundary にマッチする次の行を探し、それが endboundary の場合はその
       行の後に、beginboundary の場合はその行の前に追加内容を挿入します。

FAQ

       本章ではよく訊かれる質問を分類します。実際、以下のような形でほとんどの質問を定型化できまし
       た。「なぜああではなく、このような設計をしたのですか?」 po4a がドキュメントを翻訳する正し
       い方法ではないと感じたら、この節を読むようにするべきです。あなたの疑問への答えにならないな
       ら、<po4a-devel@lists.alioth.debian.org> メーリングリストで私たちにお問い合わせくださ
       い。私たちはフィードバックが大好きです。

   何故段落ごとに分割して翻訳するのでしょうか?
       はい、po4a は段落ごとに区切って翻訳しています (実際、各モジュールはこの様に判断しています
       が、既存のモジュールがすべてそうとは限りませんし、あなたのものもそうです)。この方法には二
       つの主な利点があります。

       • 場面からドキュメントの技術的な部分を隠すと、翻訳者はそこを弄ることができません。翻訳者に
         提示するマーカが少なければ少ないほど、間違いにくくなります。

       • ドキュメントを切るのは、オリジナルドキュメントの変更点を隔離する助けになります。オリジナ
         ルが変更されたとき、このプロセスにより、翻訳のどの部分が更新が必要なのかを探しやすくなり
         ます。

       以上の利点をもってしても、段落ごとに区切って翻訳するというアイディアが気に入らない人はいま
       す。彼らが恐れていることに対して、以下のように、いくつか回答を用意しています。

       • このアプローチは、KDE プロジェクトで成功が実証されました。またそこで翻訳の巨大なコーパス
         を作成し、私の知る限りドキュメントを更新しています。

       • 翻訳者は翻訳の際に、PO ファイル内の文字列が、オリジナルドキュメントと同じ順番であるた
         め、まだ文脈を利用できます。そのため、po4a を使う使わないにかかわらず、 順番通り訳してい
         くのはかなり比較しやすいです。いずれの場合でも、これは私見ですが、テキストフォーマット
         は、真に読みやすいわけではないので、印刷可能なフォーマットにドキュメントを変換できる状態
         にしておくのが、文脈を把握する最善の方法だと思います。

       • このアプローチは、プロの翻訳者が採用しています。確かに、彼らはオープンソース翻訳者とは異
         なる目標を持っています。例えば、内容が変更されるのはまれなので、保守がそれほど重要という
         わけではありません。

   文レベル (またはそれ以下) で分割しないのは何故ですか?
       プロ仕様の翻訳ツールは、ドキュメントを文レベルで分割し、以前の翻訳を最大限再利用し、作業の
       スピードアップを図るものがあります。これは同じ文を、文脈に応じて複数の翻訳にする場合に問題
       になります。

       段落は、その定義上、文よりも長いです。これにより、二つのドキュメントの同じ段落は、それぞれ
       の文脈に関係なく、同じ意味 (と翻訳) になることが、おそらく保証できるでしょう。

       文よりも小さい単位で分割するのは、非常にまずいでしょう。なぜまずいのかは、ここで説明するに
       は少々長いので、興味のある方は、例えば Locale::Maketext::TPJ13(3pm) の man ページ (Perl の
       ドキュメントに同梱) をご覧ください。短くするにしろ、各言語は特定の構文規則を持ち、既存の全
       言語で (話者の多い 10 言語のうち 5 言語やそれ以下でも) 動作するような、文の一部を集めて文
       を組み立てる方法はありません。

   Why not put the original as comment along with translation (or the other way around)?
       一見したところ、gettext はすべての種類の翻訳に適合できるようには見えません。例え
       ば、debconf (すべての Debian パッケージが使用する、インストール時の対話インターフェース)
       には適合できるようには見えませんでした。この場合、翻訳するテキストはかなり短く (パッケージ
       ごとに 1 ダース)、パッケージのインストール前に有効にならなければならない、特化したファイル
       に翻訳を挿入するのは難しいものでした。

       これが debconf の開発者が、オリジナルよりも翻訳を同じファイルに配置するという別解の実装を
       決定した理由です。これはかなり魅力的です。XML に対してはそのようにしたがってさえいます。例
       えば以下のように見えます。

        <section>
         <title lang="en">My title</title>
         <title lang="fr">Mon titre</title>

         <para>
          <text lang="en">My text.</text>
          <text lang="fr">Mon texte.</text>
         </para>
        </section>

       しかしこれには問題があるため、現在は PO ベースのアプローチを採用しています。ファイルではオ
       リジナルしか編集できず、翻訳はマスターテンプレートから抽出した PO ファイルに置かなければな
       りません (そしてパッケージコンパイル時に配置します)。古いシステムは以下のいくつかの理由で
       非推奨です。

       •   保守の問題

           複数の翻訳者が同時にパッチを提供した場合、それらをマージするのは大変です。

           翻訳を適用する必要のある、オリジナルからの変更をどのように検出したらよいでしょ
           う?diffを使用するには、どの版を元にして翻訳を行ったか記しておかねばなりません。言い換
           えると、あなたのファイルには PO ファイルが必要です ;)

       •   エンコーディングの問題

           この解は、ヨーロッパの言語だけが関わる場合には有効ですが、韓国語、ロシア語、アラビア語
           (訳注: もちろん日本語も) の導入は、本当に構図を複雑にします。UTF は解になり得ます
           が、まだ問題があります。

           さらに、この問題を検出するのが難しいのです (言い換えると、「ロシア語の翻訳者のせい
           で」韓国語のエンコードが壊れていることを検出するのは、韓国人の読者のみです)。

       gettext はこの問題をすべて解決します。

   しかし、gettext はこんな用途向けには設計されていません!
       そうですね。しかし現在のところ他にもっといい方法がないのです。唯一の代替手段が手動翻訳であ
       り、それには保守の問題があります。

   gettext を使ったドキュメント翻訳ツールは他に何がありますか?
       知る限りでは、以下の 2 つしかありません。

       poxml
           KDE の人たちが、DocBook XML を扱うために開発したツールです。知る限りでは、ドキュメント
           から PO ファイルへ翻訳する文字列を抽出し、翻訳後に注入する初めてのプログラムです。

           これは XML のみ、さらに特定の DTD のみを扱えます。一つの大きな msgid になってしまうた
           め、私はリストの扱いにかなり不満があります。リストが大きくなると、ひとかたまりの構造を
           つかみにくくなります。

       po-debiandoc
           このプログラムは、Denis Barbier によって作られた、多少の異論があるとはいえ po4a SGML
           モジュールの先駆けといえます。名前の通り、少々非推奨の DTD である DebianDoc DTD のみを
           扱います。

       以上に対する po4a の主な利点は、簡単に内容を追加できること (欠点かもしれませんが)
       と、gettext 化が簡単なことです。

   翻訳についての開発者教育
       ドキュメントやプログラムの翻訳を行う際、3 つの問題に行き当たります。言語について (皆が 2
       つの言語で話せるわけではありません)、技術について (po4a が存在する理由です)、人との連携に
       ついてです。すべての開発者が、翻訳の必要性について理解しているわけではありません。立派な意
       志があったとしても、翻訳者が作業しやすいやり方を無視する可能性もあります。これを補助するの
       に、po4a は参照可能なたくさんのドキュメントを用意しています。

       その他の重要な点として、このファイルが何で、どのように使用するのか、を示す短いコメント
       で、各翻訳済みファイルが始まるということがあります。これは、話すのも困難な言語の洪水におぼ
       れている哀れな開発者を助け、ファイルを正しく扱う助けとなるはずです。

       po4a プロジェクトでは、翻訳済みドキュメントはもうソースファイルではありません。SGML ファイ
       ルは慣習的にソースファイルですが、これは簡単な誤りです。これが、すべてのファイルに以下の
       ヘッダを表示する理由です。

        |       *****************************************************
        |       *           GENERATED FILE, DO NOT EDIT             *
        |       * THIS IS NO SOURCE FILE, BUT RESULT OF COMPILATION *
        |       *****************************************************
        |
        | This file was generated by po4a-translate(1). Do not store it (in VCS,
        | for example), but store the PO file used as source file by po4a-translate.
        |
        | In fact, consider this as a binary, and the PO file as a regular source file:
        | If the PO gets lost, keeping this translation up-to-date will be harder ;)

       同様に、gettext の通常の PO ファイルは、po/ ディレクトリにコピーされる必要があるだけで
       す。しかし、これは po4a によって操作されたものの例ではありません。ここには、開発者が、ド
       キュメントの翻訳がある、自分のプログラムの既存の翻訳を削除するという、大きな危険があります
       (双方を同じ PO ファイルに納めることはできません。これは、ドキュメントはコンパイル時にのみ
       翻訳が必要であるのに対して、プログラムは翻訳を mo ファイルとしてインストールしなければなら
       ないからです)。以上が、po-debiandoc モジュールが以下のヘッダをつけて PO ファイルを提供する
       理由です。

        #
        #  ADVISES TO DEVELOPERS:
        #    - you do not need to manually edit POT or PO files.
        #    - this file contains the translation of your debconf templates.
        #      Do not replace the translation of your program with this !!
        #        (or your translators will get very upset)
        #
        #  ADVISES TO TRANSLATORS:
        #    If you are not familiar with the PO format, gettext documentation
        #     is worth reading, especially sections dedicated to this format.
        #    For example, run:
        #         info -n '(gettext)PO Files'
        #         info -n '(gettext)Header Entry'
        #
        #    Some information specific to po-debconf are available at
        #            /usr/share/doc/po-debconf/README-trans
        #         or http://www.debian.org/intl/l10n/po-debconf/README-trans
        #

   gettext ベースアプローチの利点まとめ
       • 翻訳はオリジナルと同時には格納されません。これにより翻訳の更新が遅れていることがわかりま
         す。

       • 翻訳はそれぞれ分割したファイルに格納され、異なる言語の翻訳者がパッチの提供やエンコードレ
         ベルの干渉を、互いに受けないようにします。

       • 内部的には gettext をベースにしています (が、po4a は非常にシンプルなインターフェースを提
         供するので、内部で使用していることを理解する必要はありません)。そんなところで車輪の再実
         装をする必要はなく、これが広く用いられているために、それらのツールには多かれ少なかれバグ
         がないと考えられます。

       • エンドユーザにとっては何も変化ありません (事実は置いておいて、願わくば翻訳がよりよく保守
         されますように :)。ドキュメントファイルが分配した結果になるのは、まったく同じです。

       • 翻訳者は、新しいファイルの文法を学習する必要はなく、好みの PO ファイルエディタ (Emacs の
         PO mode や、Lokalize、Gtranslator など) でうまく動作します。

       • gettext は、何が完了しており、何をレビュー・更新すべきで、何がまだ作業中なのかといった統
         計を取得する簡単な方法を提供しています。以下のアドレスでいくつか例を見つけることができま
         す。

          - http://kv-53.narod.ru/kaider1.png
          - http://www.debian.org/intl/l10n/

       しかし、すべて問題ないわけではありません。このアプローチには対処するべき欠点もあります。

       • 追加内容は……一見して、変です

       • 翻訳したテキストを、この段落を分割するとか、あの二つの段落を結合するといった、あなたの好
         みに合わせることができません。しかし、オリジナルに問題があるのであれば、とりあえずバグと
         して報告すべきだ、という意見もあります。

       • 簡単なインターフェースですが、学習が必要な新しいツールのままです。

         私の夢の一つは Gtranslator や Lokalize に何らかの形で統合することです。SGML ファイルを開
         くと、文字列を自動的に抽出します。保存すると、翻訳済み SGML ファイルをディスクに書き込み
         ます。MS Word (TM) モジュール (少なくとも RTF) でこれができれば、プロの翻訳家もこれを
         使ってくれるかも知れません。

著者

        Denis Barbier <barbier,linuxfr.org>
        Martin Quinson (mquinson#debian.org)

訳者

        倉澤 望 <nabetaro@debian.or.jp>
        Debian JP Documentation ML <debian-doc@debian.or.jp>