   Copyright (C) 2013-2016 Ayanokoji Takesi <ayanokoji.takesi@gmail.com>
Copyright (C) 1997-2001 Rue. SATOH(佐藤竜一) / Koichi KIMURA(木村浩一)
Copyright (C) 1995-1998, 2001-2012 Free Software Foundation, Inc.

   このマニュアルは、フリーのドキュメント(free documentation)です。この
マニュアルは、GNU FDLとGNU GPLの両方でライセンスされています。これは、あ
なたがこのマニュアルをこれら2つのライセンスのどちらか一方を選択して、再
配布できることを意味します。

   このマニュアルは、GNU FDLにより保護されています。このドキュメントを、
Free Documentation License(FDL)の バージョン1.2、または(オプションで
)Free Software Foundation(FSF)により公表された、より新しいバージョンの元
で、コピー、変更または変更したものの配布にたいする許可が与えられます。変
更不可能なセクション、表紙のテキスト、裏表紙のテキストはありません。この
ライセンスののコピーは、*note GNU FDL::に含まれています。

   このマニュアルは、GNU GPLにより保護されています。このマニュアルを、
GNU General Public License(GPL)のバージョン2、または(オプションで)Free
Software Foundation (FSF)により公表された、より新しいバージョンの条件下
で、再配布、および／または再配布することができます。このライセンスのコピ
ーは、*note GNU GPL::に含まれています。

   このファイルはGNU ‘gettext’ユーティリティーのドキュメントを提供します
。またフリーの翻訳プロジェクト(Translation Project)にたいする参照の役割
も果たします。

GNU ‘gettext’ utilities
***********************

   This manual documents the GNU gettext tools and the GNU libintl
library, version 0.18.3.

 — The Detailed Node Listing —

Introduction

The User’s View

Setting the POSIX Locale

Preparing Program Sources

Making the PO Template File

Creating a New PO File

Updating Existing PO Files

Editing PO Files

Emacs’s PO File Editor

Using Translation Compendia

Manipulating PO Files

Highlighting parts of PO files

Producing Binary MO Files

The Programmer’s View

About ‘catgets’

About ‘gettext’

Temporary Notes for the Programmers Chapter

The Translator’s View

Organization

National Teams

The Maintainer’s View

Files You Must Create or Alter

Autoconf macros for use in ‘configure.ac’

Integrating with CVS

Other Programming Languages

The Translator’s View

Individual Programming Languages

sh - Shell Script

Perl

Internationalizable Data

Concluding Remarks

Language Codes

Licenses

1 イントロダクション
********************

   このチャプターでは、GNU ‘gettext’が作られた目的と、フリーの翻訳プロジ
ェクトについて説明します。それから、ネイティブ言語サポート(NLS: Native
Language Support)にまつわる広義の概念をいくつか説明します。また国や文化
の差異を他の側面から考慮した際に、翻訳したメッセージをプログラムに適用す
ることが、どのような位置づけになるかを説明します。さらに翻訳に使用される
ファイルを説明し、最初の翻訳において様々なツールがそれらのファイルをどの
ように生成、相互作用するのか、そして通常のメンテナンスサイクルにおいてど
のように処理されるかについて説明します。

   このマニュアルでは、プログラマーやメンテナーを指すときには_彼_という
言葉を使用します。そして翻訳者を指すときは_彼女_、翻訳されたプログラムを
インストールする人やエンドユーザーのことを指すときは_彼ら_という言葉を使
用します。これの目的はドキュメントを明解にするのが唯一の目的であり、決し
て各々の役割が男性、もしくは女性に適しているという意味では_まったく_あり
ません。あなたが想像するように、GNU ‘gettext’は性別、人種、宗教、国籍に
関わらず、コンピュータを使用する人にとって有用なものなのです!

   提案や訂正は下記にメールしてください:

     Internet address:
         bug-gnu-gettext@gnu.org

メールのメッセージに、マニュアルのバージョン番号と更新日付を記入してくだ
さい。

1.1 GNU ‘gettext’の目的
=======================

   プログラムは通常、英語でドキュメントされており、実行時にユーザーと相
互作用する場合にも英語が使用されます。これはGNUソフトウェアに限らず、多
くのフリーソフトウェアにも当てはまる話です。開発者やメンテナー、すべての
国々のユーザー同士でコミュニケーションする場合、共通の言語を使用するほう
が便利です。一方、ほとんどの人は英語より自分の母国語を好み、日々の仕事に
も可能な限り母国語を使用しています。単純に言うと、ほとんどの人は英語より
母国語がコンピューターのスクリーンに表示されるのを_愛する_のです。

   しかし多くの人にとって、これは時間をかけて考える価値がないと片付けて
しまう夢かもしれません。彼らは結局、この夢を実現できる自信がないのです。
しかし希望を失わずに、組織を作った人たちもいます。この翻訳プロジェクトは
、これらの希望を作業可能な形に形式化して、私たちのすべてが真の多言語機能
を兼ね揃えたプログラムと呼べるものを手にするチャンスなのです。

   GNU ‘gettext’は、他の多くのステップを構築する資産であり、翻訳プロジェ
クトにとって重要なステップです。このパッケージは、プログラマー、翻訳者、
そしてユーザーにたいして、統合されたツールとドキュメントを提供します。特
に GNU ‘gettext’ユーティリティーは、他のパッケージに多言語化されたメッセ
ージを生成するためのフレームワークを提供するツール群です。このツールには
以下のものが含まれます:

   • メッセージカタログをサポートするために、プログラムをどのように記述
     すべきかの規則。

   • メッセージカタログのディレクトリーやファイル名の命名方式。

   • 翻訳されたメッセージの取得をサポートする実行時ライブラリー。

   • 翻訳可能なメッセージや、既に翻訳されたメッセージを取り扱うための、
     スタンドアローンプログラム群。

   • 翻訳可能なメッセージが含まれたファイルの解析、生成をサポートするラ
     イブラリー。

   • これらのセットを準備して最新の状態に保つための、Emacs(1)用のスペシ
     ャルモード。

   GNU ‘gettext’は、プログラムのソースを国際化する際の影響を最小化し、そ
の影響を可能な限り小さく保つようにデザインされています。プログラムソース
を見たときに、その影響が軽微、または少なくとも軽微に見えることにより、国
際化が成功する可能性が高くなります。

   翻訳プロジェクトは、翻訳プロジェクトの構造や手法を記述する手段として
も、GNU ‘gettext’ディストリビューションを使用しています。これは、この文
書がGNU ‘gettext’の技術面に限定して適切に記述された文書であることを超え
るものであることを意味します。そうすることにより、翻訳者は翻訳作業を適切
に行うために知る必要のあるすべてのことを、可能な限り単一の場所で見つける
ことができます。この補足的な文書により、プログラマーさらに好奇心のあるユ
ーザーは、GNU ‘gettext’が翻訳プロジェクト以外の場所とどのように関連して
いるかを理解し、_大きな絵_を垣間見ることができます。

   ---------- Footnotes ----------

   (1) このマニュアルでEmacsという言葉を使用するときは、FSF Emacsとも呼
ばれるGNU EmacsとXEmacs、そしてLucid Emacsを指します。

1.2 i18n、l10n、などなど
========================

   プログラムによるネイティブ言語サポートを議論する際に、2つの長い単語が
出現します。これらの単語には正確な意味づけがあり、このドキュメントでも使
用する単語なので、ここで説明しておきましょう。使用される2つの長い単語と
は、_インターナショナリゼーション(internationalization)_と_ローカリゼー
ション(localization)_です。これらの単語を何度も何度も書くうちに、多くの
人たちが“i18n”や“l10n”と記述するようになりました。この表現は単語の最初と
最後の文字と、それらの文字の間にある文字数によって、それぞれの単語を略記
したものです。しかしこのマニュアルではわかりやすくするために、略記を用い
ずに正式な単語を使用することにします。

   “インターナショナリゼーション(国際化)”とは、プログラムやパッケージに
含まれるプログラムのセットが多言語を認識しサポートする操作のことを指しま
す。インターナショナリゼーションとは、英語の文字列でしかプログラムがを呼
び出せないとか、英語以外の特定の言語の持つ習慣に縛られるといったことなく
、同じ操作を一般的な方法で結びつけさせるための汎化のプロセスです。プログ
ラムの開発者は、彼のプログラムをインターナショナライズするために様々なテ
クニックを使うことでしょう。それらのいくつかは標準化されています。そのう
ちの1つが GNU ‘gettext’なのです。Programmersを参照してください。

   “ローカリゼーション(地域化)”とは、それを行うことによりすでにインター
ナショナライズされた一連のプログラムが必要とするすべての情報を受けとるこ
とができ、任意のネイティブ言語や文化的な習慣に従った方法による入出力に適
応させることができるような操作のことを意味します。ローカリゼーションとは
、一般的なメソッドを実装済みのインターナショナライズされたプログラムを特
定の方法で使用する、特化のプロセスです。プログラミング環境はプログラマー
にたいして、実行時に設定できるいくつかの機能を提供します。翻訳対象の単位
として同じネイティブ言語同士をまとめた、任意の国がもつ特定の文化的な習慣
の形式的な説明を、その言語や国の“locale”と呼びます。ローカライズされたプ
ログラムを使用するユーザーは、プログラムを実行する前にプログラムがどの
localeを使用するべきかを、特定の環境変数に設定します。

   実際にはlocaleメッセージのサポートとは、特定のlocaleを形成する文化的
なデータの単一のコンポーネントのことです。インターナショナライズされたソ
フトウェアを開発するプログラマーを支援するために、特定のlocale に保存さ
れたデータにアクセスできるルーチンと関数を提供するライブラリーがあります
。誰かが特定のlocaleを参照する場合には、特定のlocaleに保存されているデー
タを参照することになります。同様に、プログラマーが “locale ルーチンへの
アクセス” を参照するということは、すべてのlocale情報にアクセスできる完全
なルーチンの一式を参照するのと同じです。

   ネイティブ言語サポート(“Native Language Support”、または単にNLS)とい
う表現は、インターナショナリゼーションとローカリゼーションの両方により、
プログラムが多言語と相互作用できる動作や機能の全体を指すときに使用します
。一言で言うと、インターナショナリゼーションとはローカリゼーションを可能
にする操作とも言えます。

   大まかに言うと、多言語によるメッセージを処理する場合、インターナショ
ナリゼーションはプログラマーによって処理され、ローカリゼーションは翻訳者
によって処理されるとも言えます。

1.3 ネイティブ言語サポートの側面
================================

   完全な多言語ディストリビューションを配付するためには、出力メッセージ
の翻訳以外に多くの事柄があります。

   • 現在の GNU ‘gettext’が提供するのは、Cプログラムが出力するメッセージ
     を翻訳するための完全なツールセットです。しかしperlスクリプトとシェ
     ルスクリプトも同様に翻訳される必要があります。現在これらを翻訳する
     ための方法があったとしても、本来あるべき形での統合はされていません
     。

   • ‘autoconf’や‘bison’のような一部のプログラムは、他のプログラム(また
     はスクリプト)を生成することができます。たとえプログラムを生成するプ
     ログラムがインターナショナライズされていても、生成されたプログラム
     は独自にインターナショナリゼーションする必要がありますが、これらの
     間接的に行われるインターナショナリゼーションは生成プログラムで自動
     化できるはずです。しかし実際は生成するプログラムと生成されるプログ
     ラムは、それぞれ独自にインターナショナライズされるのが極めて一般的
     です。

   • 数は多くありませんが、プログラム自体に含まれた文字列とは別に、翻訳
     が必要となるテキストのテーブルを含むプログラムもあります。例えば
     RFC 1345は、‘recode’プログラムが実行時に文字を再構築するための、文
     字に対応する説明的な英語名を提供します。これらの説明的な名前はRFCか
     ら機械的に取り出されるため、RFC自体を事前に翻訳する必要があります。

   • 大抵のプログラムにはオプションを指定することができますが、多くの場
     合は英語を読める人にたいして説明的なものが使用されています。このよ
     うプログラムのオプションについても、翻訳されたバージョンを提供する
     ことを考慮する必要があります。

   • 多くのプログラムは、本質的には翻訳可能な何かを、読み込み、解釈、コ
     ンパイルしたり、そのようなキーワードや識別子のテキストを含む入力フ
     ァイルによって何かを行ったり、応答を返したりします。例えば‘gcc’に識
     別子の文字を区別できるようにさせたり、‘rm -i’が‘y’や‘n’ではない、翻
     訳された応答をユーザーから受け取れるようにしたいと思うかもしれませ
     ん。最終的にプログラムのほとんどの出力が他言語によるものだったとし
     ても、入力の構文やオプションに指定できる値などを、ローカライズ可能
     かそうでないかを決定したいと思うかもしれません。

   • パッケージに付随するマニュアル、及びディストリビューションのドキュ
     メントファイルも同様に、翻訳される可能性があります。マニュアルの翻
     訳と、それ以降のアップデートは、一般的にはそれ自体が主要な作業です
     。

   すでに述べたように、翻訳とはlocaleの1つの側面に過ぎません。インターナ
ショナリゼーションの他の側面にはシステムのサービスがあり、これは GNU
‘libc’により処理されます。国々の文化的な慣習を定義するための多くの属性が
あります。これらの属性には、国々のネイティブ言語に即した日付や、時刻書式
と数値表記、通貨記号などが含まれます。これらの地域的な“ルール”は、その国
のlocaleと呼ばれます。localeとは、その国のネイティブな属性をサポートする
ために必要となる知識を表します。

   国ごとの差異にしたがってlocaleを記述しなければならない、主要な領域が
いくつかあります。以下のリストは、localeに関連したその他のタスクの適切な
コンテキストにおいて、多言語メッセージを配置する手助けになるでしょう。詳
細については GNU ‘libc’のマニュアルを参照してください。

_文字とコードセット_

     米国や世界中の、英語を話す地域で最も一般的に使用されるコードセット
     は、ASCIIコードセットです。しかしこのコードセットには、様々な
     localeで必要とされる文字が含まれていません。8ビット ISO 8859-1コー
     ドセットは主要なヨーロッパの言語で処理する必要がある特殊文字をほと
     んど持っているにもかかわらず、主要なヨーロッパの通貨を処理すること
     ができない等、多くの場合はISO 8859-1を選択するだけでは十分ではない
     のです。したがってそれぞれのlocaleは、使用するコードセットの選択と
     、そしてそのコードセットに対処するための適切な文字列処理ルーチンが
     必要になります。

_通貨_

     通貨記号は国ごとに異なり、それぞれの通貨記号の使用する位置も異なり
     ます。それぞれのlocaleにたいするネイティブモードで、ソフトウェアは
     それを意識させずに通貨の数字を表示できる必要があります。

_日付_

     日付の書式はlocaleごとに異なります。例えば1994年のクリスマスは、米
     国では12/25/94と記述し、オーストラリアでは25/12/94、それ以外の国で
     はISO 8601の日付書式を使用する、といった具合です。

     1日の中で使用される時刻も、HH:MM、HH.MM、などのように記述されます。
     あるlocaleでは時刻はAM/PMではなく、24時間制で指定する必要があります
     。しかも夏時間の補正は国ごとに大きく異なります。

_数値_

     数値の表記はlocaleごとに異なります。以下はそれぞれのlocaleに対応す
     る、正しい数値表記の例です:

          12,345.67       English
          12.345,67       German
           12345,67       French
          1,2345.67       Asia

     メートル法とポンドヤード法のように異なる単位系を使用したり、それら
     の変種で数値表記する方法を採用しているプログラムもあります。

_メッセージ_

     localeによる言語サポートにおいて、最も明確な領域です。GNU
     ‘gettext’は、localeでのメッセージのサポートという領域において、ソフ
     トウェアがユーザーとコミュニケーションするときに使用する言語を、開
     発者とユーザーが簡単に変更する手段を提供します。

   これらの文化的な慣習の領域は、_localeカテゴリー(locale categories)_と
呼ばれます。この用語は、_localeの側面(locale aspects)_や_locale機能のカ
テゴリー(locale feature categories)_といった用語よりも劣っているのが残念
です。なぜならそれぞれの“localeカテゴリー”は、ローカリゼーションが要求さ
れる、ある領域やタスクについて記述するからです。そのような領域や特定の文
化にたいして、文化的な慣習を説明する具体的なデータも_localeカテゴリー_と
呼ばれます。この意味では、localeとは、コードセットを定義するlocaleカテゴ
リー、数値の書式を定義するlocaleカテゴリー、翻訳されたメッセージを定義す
るlocaleカテゴリー、などのように、いくつかのlocaleカテゴリーから構成され
ているといえます。

   メッセージ処理以外のlocaleコンポーネントは、標準ISO CとPOSIX:2001標準
(SUSV3 specificationとも呼ばれる)です。GNU ‘libc’はこれを完全に実装して
おり、その他の現代的なシステムも、欠けているコンポーネントにたいする、必
要最小限のより実用的なサポートを提供しています。

1.4 翻訳を伝達するファイル
==========================

   ‘.po’ファイルのPOはPortable Objectの頭文字であり、‘.mo’ファイルのMOは
Machine Objectの頭文字です。このパラダイムはPOファイルのフォーマットと同
様に、Uniforumで開発されたNLS標準にもとづき、SunのSolarisシステムで実装
されたものです。

   POファイルは人間が読んだり編集することを意図しており、あるパッケージ
の特定のターゲット言語のための、翻訳可能なオリジナル文字列の集まりです。
1つの言語にたいして、1つのPOファイルが割り当てられます。パッケージが複数
の言語をサポートする場合、サポートする言語ごとにPOファイルを持ち、パッケ
ージごとにパッケージがサポートする言語ごとのPOファイルを持っています。こ
れらのPOファイルは‘xgettext’プログラムによって作成され、アップデートや更
新はmsgmergeプログラムによって行われます。‘xgettext’プログラムはCファイ
ルからマークされたメッセージを抽出し、空の翻訳文字列で初期化されたPOファ
イルを作成します。‘msgmerge’プログラムは、リリースの間に変更されたソース
ファイルにたいして、不要なエントリーのコメント化や新しい文字列の初期化、
および参照するソース行を更新したりします。この種のファイルは配布物中にの
‘.pot’という拡張子のファイルとして含まれ、書式はPOファイルと同じです。

   MOファイルは、プログラムが読み込むことを意図した、バイナリーのフォー
マットのファイルです。ネイティブ言語サポートの一部として、MOファイルを作
成したり処理することのできる既存のシステムもいくつかありますが、MOファイ
ルのフォーマットがシステムごとに異なっているため可搬性がありません。また
、これらのシステムが提供する既存のツールは、GNU ‘gettext’のすべての機能
をサポートしていません。そのためGNU ‘gettext’は、MOファイルに独自のフォ
ーマットを使用しています。拡張子‘.gmo’が実際のMOファイルで、これらのファ
イルはGNUのフォーマットを使用しています。

1.5 GNU ‘gettext’の概要
=======================

   以下は、GNU ‘gettext’で処理されるファイル群の関連と、それらを処理する
ツールをまとめたダイアグラムです。以降の詳細な説明は、このダイアグラムを
見ながら読み進めてください。これらのファイルやツールの相互作用への明確な
理解は、プログラマー、翻訳者、メンテナーにとって確実に役に立つものです。

     Original C Sources ---> Preparation ---> Marked C Sources ---.
                                                                  |
                   .---------<--- GNU gettext Library             |
     .--- make <---+                                              |
     |             `---------<--------------------+---------------'
     |                                            |
     |   .-----<--- PACKAGE.pot <--- xgettext <---'   .---<--- PO Compendium
     |   |                                            |              ^
     |   |                                            `---.          |
     |   `---.                                            +---> PO editor ---.
     |       +----> msgmerge ------> LANG.po ---->--------'                  |
     |   .---'                                                               |
     |   |                                                                   |
     |   `-------------<---------------.                                     |
     |                                 +--- New LANG.po <--------------------'
     |   .--- LANG.gmo <--- msgfmt <---'
     |   |
     |   `---> install ---> /.../LANG/PACKAGE.mo ---.
     |                                              +---> "Hello world!"
     `-------> install ---> /.../bin/PROGRAM -------'

   プログラマーが自分のパッケージにGNU ‘gettext’を導入するときに最初に行
うことは、Cソース中のどの文字列が翻訳可能で、どの文字列が翻訳不可かを識
別することです。この退屈な作業は、emacsのPO modeを使用することにより多少
は快適になりますが、Cソースを編集するのに、あなた自身が慣れ親しんだもの
を使用することもできます。その他に必要となる標準的な変更としては、翻訳用
のライブラリーを正しく初期化することなどです。これらに関する詳細は
Sourcesを参照してください。

   新しく記述するソフトウェアについては、ソフトウェアを記述するときにそ
のような文字列をマークできますし、そうするべきでしょう。このような文字列
にたいする‘gettext’のアプローチ方法としては、手始めに各ファイルの先頭ま
たは中心的なヘッダーファイルに、以下の行を追加するという、非常に簡単なも
のです:

     #define _(String) (String)
     #define N_(String) String
     #define textdomain(Domain)
     #define bindtextdomain(Package, Directory)

これで、インターナショナリゼーションのためのソースの準備ができました。後
で実際に‘gettext’を使う準備ができたら、これらを以下の定義で置き換えてく
ださい:

     #include <libintl.h>
     #define _(String) gettext (String)
     #define gettext_noop(String) String
     #define N_(String) gettext_noop (String)

‘libintl.a’と‘libintl.so’にリンクする必要もあります。GNUシステムでは、
‘gettext’ライブラリーの関数はGNU libcにすでに含まれているので、
‘libintl’にリンクする必要がないことに注意してください。

   一度Cソースが変更されると、翻訳可能なすべての文字列を検索、抽出してPO
templateファイルに出力するのに、‘xgettext’が使用されます。この
‘PACKAGE.pot’ファイルには、オリジナルのプログラムのすべての文字列が含ま
れています。これらの文字列は、その文字列がCソース中で使用されている場所
へのポインターを持っており、すべての翻訳文字列は空文字列に初期化されてい
ます。‘.pot’の‘t’という文字は、このファイルがテンプレート(Template)の
POファイルであり、まだ特定の言語用ではないことを示します。どのように
‘xgettext’プログラムが呼び出されるかについては、see xgettext Invocation
を参照してください。もしあなたが_本当_に怠け者の場合、少し手
間をかけてディストリビューション全体をセットアップするのに興味があるかも
しれません(see Maintainersを参照してください)。この方法では、
‘xgettext’コマンドをタイプするのを省略して‘make’とタイプするだけで、自動
的に適切なものを生成することができます。

   最初はまだ‘LANG.po’がないので、‘msgmerge’のステップはとばして、単に
‘PACKAGE.pot’が‘LANG.po’としてコピーされます。ここでLANGは対象となる言語
です。詳細については、see Creatingを参照してください。

   次はメッセージの最初の翻訳です。翻訳それ自身が全体として今だ人手に頼
らねばならないものであり、その複雑さはこのマニュアルの取り扱う範囲を超え
るものです。翻訳チームに連絡したり、チームの一員になって、同じネイティブ
言語を作業対象とする他の人たちとあなたの翻訳を共有する方法等、いくつかの
ヒントについては、このマニュアルの他のチャプターで触れています(see
Translatorsを参照してください)。

   POファイル‘LANG.po’に翻訳したメッセージを追加するときに、POファイル編
集用のエディター(see Editingを参照してください)を使用していない場合
は、POファイルのフォーマットに合わせて作業したり、文字列を引用符で括る規
則など(see PO Filesを参照してください)について自分で気を遣わなければ
なりません。これは不可能な作業ではなく、実際に1995年頃には多くの人がPOフ
ァイルを取り扱っていた方法です。一方、POファイルエディターは、POファイル
エディター自身の使い方を覚える必要はありますが、あなたにかわってエディタ
ーがPOファイルに関する詳細を取り扱ってくれます。

   既に何らかの翻訳がCompendium POファイルに保存されている場合、翻訳者は
POモードを使って翻訳されていないエントリーをCompendiumから初期化したり、
翻訳を選択してCompendiumに保存したり更新することができます(see
Compendiumを参照してください)。Compendiumファイルは、翻訳チームのメン
バー間で共有するように意図されたものです。

   プログラムやプログラムのパッケージは、ユーザーがバグ報告や改良のため
の提案をして、メンテナーが様々な方法でプログラムを変更して対応するという
、動的な性質を持ちます。パッケージがすでにインターナショナライズされてい
るという事実により、メンテナーがパッケージに文字列を追加したり、すでに翻
訳された文字列を変更することをためらうようにさせるべきではありません。彼
らは、彼ら自身がスムーズに作業できるようにベストを尽くすだけです。メンテ
ナーはすでに負荷の掛かった双肩に、翻訳に関する心配事を背負いこまなないよ
うにしてください。そして翻訳者はプログラミングの心配事からは自由でいるよ
うにしてください。

   メンテナーが心配すべきなのは、文字列が翻訳されるべきときに翻訳可能で
あるように文字列をマークすることであり、文字列がいつ翻訳されるかについて
は、適切な時がくれば翻訳されるものだと割り切るべきです。‘xgettext’は、時
間をかけて進化してきた‘PACKAGE.pot’を再び構築し、その結果、翻訳を含んだ
‘LANG.po’は徐々に古くなっていきます。

   翻訳者(そしてメンテナー)にとって重要なのは、パッケージの翻訳はパッケ
ージが誕生した時に1度行えばよいというものではなく、パッケージの生涯にお
いて繰り替えされる継続的なプロセスだと理解することです。あるパッケージに
たいして最初の翻訳を行った後、時々手入れをすることが必要です。なぜなら翻
訳が必要な新しい未翻訳の文字列が出現することにより、翻訳された文字列があ
ちこちで古くなっていくからです。

   ‘msgmerge’プログラムは、すでに存在する‘LANG.po’ファイルを、
‘xgettext’で最新の C ソースから抽出された、より新しい‘PACKAGE.pot’テンプ
レートファイルと比較して更新するという目的を持っています。更新の処理はプ
ログラムの変更により変更された、Cソース中の文字列の位置にたいする参照を
調整します。同様に、‘msgmerge’はすでに翻訳されているがプログラムのソース
に存在しなくなった、古い翻訳のコメントアウトも行います(see Obsolete Entries
を参照してください)。そして最後に新しい文字列を未翻訳の文字列と
して、結果であるPOファイルに挿入します(see Untranslated Entriesを参
照してください)。msgmergeが実際に何を行うかについては、see msgmerge Invocation
を参照してください。

   目的に至る経路と手段が何であれ、翻訳のためのすべての文字列を提供する
更新された‘LANG.po’がゴールなのです。

   POファイルが変動し流動する一時的なものであるという性質は、翻訳という
ゲームでの不可欠な部分であり、よく理解して受け入れる必要があります。翻訳
プロジェクトに参加する人はこの性質に苦労し、他の翻訳プロジェクトのメンバ
ーに苦労をかけることもあるのです! 特にメンテナーは、たとえ最近は更新され
ていないディストリビューションでも、翻訳チームに早く仕事を終えるようにプ
レッシャーを与えず、リラックスして利用可能でオフィシャルなすべてのPOファ
イルをディストリビューションに含めましょう。プレッシャーを与えるのはむし
ろ、特定の言語を話すコミュニティーのユーザーなので、メンテナー自身も安心
して翻訳ファイルの妥当性を考慮するべきです。一方翻訳者は、パッケージがオ
フィシャルのディストリビューションに向けた事前テストを行っているときに、
自分が担当するPOファイルを合理的に更新する事を試みる必要があります。

   1度POファイルが完成して信頼できる物になると、POファイルは‘msgfmt’プロ
グラムによって、パッケージのプログラムが実行時に必要な時はいつでも効率的
に翻訳を取得できるよう、マシン向けのフォーマットに変換されます(see MO Files
を参照してください)。‘msgfmt’プログラムのすべての実行モードについ
ては、see msgfmt Invocationを参照してください。

   最後に、変更およびマークされたCソースがコンパイルされて、GNU
‘gettext’ライブラリーとリンクされます。これは通常、プロジェクトのための
適切な‘Makefile’と共に、‘make’コマンドを実行することにより行われ、結果と
してユーザーが見つけることのできる場所に実行可能ファイルがインストールさ
れます。MOファイル自身も適切にインストールされる必要があります。これで適
切な環境変数(see Setting the POSIX Localeを参照してください)をセット
すると、プログラムを実行すればいつでも自分で自動的にローカライズするよう
になります。

   このマニュアルの残りの部分では、上述の様々なステップを掘り下げて説明
することを目的とします。

2 ユーザーの視点
****************

   最近では、ユーザーがコンピューターにログインしたときには通常、プログ
ラムがネイティブ言語でメッセージを表示するのを目にすることができます – 少
なくともフリーソフトウェアやGNUプロジェクトに関わる人が少ないHindiや
Filipinoなどの言語ではない、FrenchやGermanなどの言語による活発なフリーソ
フトウェアコミュニティーのユーザーは目にすることができるでしょう。

   これはどのような仕組みで動くのでしょう? ユーザーはどのようにして、プ
ログラムで使用する言語にたいして影響を与えることができるのでしょうか? こ
のチャプターではこれらの疑問にお答えします。

2.1 オペレーティングシステムのインストール
==========================================

   デフォルトで使用する言語は、すでにオペレーティングシステムのインスト
ールの時点で決定されている場合があります。オペレーティングシステムがイン
ストールされるときは通常、インストーラーがインストール中に使用する言語と
は別に、インストールされるシステムで使用する言語を尋ねます。言語を1度し
か尋ねないOSインストーラーもあります。

   これにより、すべてのユーザーにたいする、システム全体でのデフォルト言
語が決定されます。追加の言語としてデフォルト言語以外のローカリゼーション
を指定できるインストーラーもあります。たとえばKDE(K Desktop
Environment)のローカリゼーションやOpenOffice.orgは、言語ごとにインストー
ルできるパッケージが個別にバンドルされています。

   これはマシンの使用目的を考える、よい機会です。個人的に使用するマシン
の場合、追加のローカリゼーションはおそらく必要ありません。国際的なつなが
りをもつ組織や企業で使用するマシンの場合、ゲストユーザーのことも考えられ
ます。海外から1週間程度の予定でゲストを迎える場合、彼のお好みのlocaleは
何でしょうか? そのコストがディスクスペースを少し余分に消費するだけならば
、あらかじめ追加のローカリゼーションをインストールする価値があるかもしれ
ません。

   システム全体のデフォルト言語は、新しいアカウントを作成するときの
locale設定で使用されます。しかしユーザーは同じマシンの他のユーザーとは異
なる、自分自身のlocale設定を持つことができます。次のセクションで説明する
ようにユーザーは通常、最初のログイン後に自分のlocaleを指定することができ
ます。

2.2 GUIプログラムを使用したlocaleのセッティング
===============================================

   すぐに利用可能なプログラムは、“デスクトップ環境”とも呼ばれるユーザー
のデスクトップで、それにはウィンドウマネージャーやウェブブラウザー、それ
にテキストエディターなどが含まれます。一般的なデスクトップとしてはKDE、
GNOME、Xfceなどがあります。

   デスクトップ環境のGUIプログラムで使用されるlocaleは、“control
center”、“language settings”、“country settings”などと呼ばれる設定画面で
指定できます。

   デスクトップ環境に属さない個別のGUIプログラムは、設定パネルや環境変数
を通じて、自身のlocaleを持つことができます。

   環境変数を通じてlocaleを指定できるプログラムには、デスクトップの
localeとは異なるlocaleを指定できるものもあります。これはプログラムをメニ
ューやファイルシステムから起動するかわりに、コマンドラインから環境変数を
指定した後にプログラムを起動するということです。環境変数の設定については
、次のセクション(see Setting the POSIX Locale)で説明します。ただし
KDEのあるバージョンでは、localeを‘LANG’や‘LC_ALL’ではなく‘KDE_LANG’で設
定します。

2.3 環境変数を通じたlocaleのセッティング
========================================

   もっとも単純なケースは、あなたの言語がこのパッケージにしたがってイン
ストールされている場合で、環境変数‘LANG’に適切な‘LL_CC’の組み合わせを指
定するだけです。たとえばあなたがGermanyに住んでいてGermanを話すとしまし
ょう。この場合はシェルプロンプトで単に、‘setenv LANG de_DE’(‘csh’の場合
)、‘export LANG=de_DE’(‘sh’の場合)、‘export LANG=de_DE’(‘bash’の場合)と
実行します。1度これを‘.login’や‘.profile’に記述しておけば、毎回適用する
ことができます。

2.3.1 locale名
--------------

   localeの名前は通常、‘LL_CC’という形式で表されます。ここで‘LL’は
ISO 639による2文字の言語コード、‘CC’はISO 3166による国コードを記述します
。たとえば国がGermany、言語がGermanの場合、LLは‘de’、CCは‘DE’となります
。言語コードと国コードについては、付表Language Codesと付表
Country Codesを参照してください。

   国コードも指定するのは冗長だと思うかもしれません。しかし、実際にいく
つかの言語は国ごとに方言をもつものがあります。たとえば、‘de_AT’は
Austria、‘pt_BR’はBrazilで使用されます。国コードはこの様な方言を区別する
のに役立つのです。

   多くのlocale名は‘LL_CC.ENCODING’という拡張形式で文字のエンコーディン
グを指定できます。これは多くのユーザーが2000年から2005年にかけてUTF-8に
移行したためです。たとえば現在のglibcシステムのGerman localeは
‘de_DE.UTF-8’です。‘de_DE’という古いlocale名は、2000年時点で使用されてい
たISO-8859-1(ユーロ通貨記号を持たない)が格納された文字列を参照するのに現
在も使用されます。

   ‘LL_CC’のかわりに、‘LL_CC.@VARIANT’を使うlocale名もあります。
‘@VARIANT’により、言語(LL)と国(CC)では提供できないような特性を示すことが
できます。これにより特定の通貨単位を示すことができます。たとえばglibcシ
ステムでは‘de_DE@euro’は、2002年以前の通貨記号で使用されていた‘de_DE’で
はなく、ユーロ通貨を使用するlocaleを示します。また、言語の方言や筆記に使
用される方法(たとえば‘sr_RS@latin’は、‘sr_RS’によりSerbianをCyrillicで筆
記するのに、Latin筆記を使用することを示す)、正書法(orthography rule)を使
用するか、などを示すことができます。

   その他のシステムでは、単に‘LL’と指定したりする等、このスキームの様々
なバリエーションが使用されています。あなたの言語でサポートされている
localeの一覧は、‘locale -a | grep '^LL'’を実行して取得することができます
。

   ‘C’と呼ばれる特別なlocaleもあります。これはすべてのlocaleを無効にする
ときに使用します。このlocaleでは、すべてのプログラムがPOSIX標準で指定さ
れた英語のメッセージと、指定されていない不特定の文字(たいていは
US-ASCIIですが、オペレーティングシステムによってはISO-8859-1やUTF-8のと
きもあります)を使用します。

2.3.2 localeの環境変数
----------------------

   localeは複数の_localeカテゴリー(locale categories)_から構成されていま
す(see Aspectsを参照してください)。プログラムがlocaleに依存する値を
参照する場合は、以下の環境変数を優先度順に参照します:

  1. ‘LANGUAGE’
  2. ‘LC_ALL’
  3. ‘LC_xxx’は、xxxに対応するlocaleカテゴリーです: ‘LC_CTYPE’,
     ‘LC_NUMERIC’, ‘LC_TIME’, ‘LC_COLLATE’, ‘LC_MONETARY’,
     ‘LC_MESSAGES’, ...
  4. ‘LANG’

   変数に空の値がセットされている場合は、無視されます。

   ‘LANG’はlocaleを指定するときに通常使われる環境変数で、通常はユーザー
もこの変数にlocaleを設定します(他の変数がシステムにより設定されていなけ
れば、‘/etc/profile’またはそれに類する初期化ファイルで設定します)。

   ‘LC_CTYPE’、‘LC_NUMERIC’、‘LC_TIME’、‘LC_COLLATE’、‘LC_MONETARY’、
‘LC_MESSAGES’等は、対応するlocaleのカテゴリーで‘LANG’の設定をオーバーラ
イドするときに使用されます。たとえば、あなたがSpainに住むSwedishのユーザ
ーで、プログラムに数値や日付についてはSpanishの規則で表示し、メッセージ
だけをSwedishで表示させたいと仮定します。その場合には‘localedef’プログラ
ムで、‘sv_ES’または‘sv_ES.UTF-8’という名前のlocaleを作成する必要がありま
す。しかし、単に‘LANG’変数に‘es_ES.UTF-8’を設定し、‘LC_MESSAGES’変数に
‘sv_SE.UTF-8’という、オペレーティングシステムに事前にインストールされて
いる2つのlocaleを設定することで、同じ効果を得ることができます。

   ‘LC_ALL’は、これらのすべてをオーバーライドするための変数です。これは
通常、特定のプログラムを実行するスクリプトで使用されます。たとえばGNU
autoconfにより生成された‘LC_ALL’スクリプトは、configurationのテストが
localeに依存した方法で行われないように、‘LC_ALL’を使用します。

   残念ながらいくつかのシステムでは、‘/etc/profile’等の初期化ファイルで
‘LC_ALL’が設定されています。したがって‘LANG’を設定する場合、ユーザーはま
ずこの設定を解除し、必要なら他の‘LC_xxx’も解除しなければなりません。

   ‘LANGUAGE’変数については、つぎのセクションで説明します。

2.3.3 言語の優先リストを指定する
--------------------------------

   すべてのプログラムが、すべての言語に翻訳されている訳ではありません。
翻訳されたメッセージが存在しない場合、デフォルトでは英語のメッセージが表
示されます。あなたが他の言語を理解できる場合は、言語の優先順位のリストを
設定することができます。これは‘LANGUAGE’と呼ばれる環境変数で行います。
GNU ‘gettext’はメッセージを処理するために、‘LC_ALL’や‘LANG’に加え、
‘LANGUAGE’による設定を提供します。しかし他のシステムライブラリーで必要と
なるため、‘LANG’(または‘LC_ALL’)によるプライマリー言語の設定は、依然とし
て必要です。たとえば、あるSwedishのユーザーは、Swedishの翻訳が存在しない
とき、EnglishよりもGermanに翻訳されたものが読みたいとします。そのような
場合は、‘LANG’の値は‘sv_SE’のまま、‘LANGUAGE’の値を‘sv:de’に設定します。

   Norwegianのユーザーのためのアドバイス: Norwegian言語(bokmål)は最近
(2003年)、‘no’から‘nb’に変更されました。移行期間中、いくつかのこの言語の
メッセージカタログは、‘nb’と、古い‘no’にインストールされるので、
Norwegianユーザーは新旧どちらの翻訳も使用できるように、‘LANGUAGE’を
‘nb:no’に設定することをお勧めします。

   他の環境変数とは異なり、‘LANGUAGE’環境変数では、‘LL_CC’を‘LL’と省略す
ることにより、その言語で主に使用される方言であることを示します。この事情
により、たとえば‘de’は‘de_DE’(Germanyで話されるGermany)、‘pt’は
‘pt_PT’(Portugalで話されるPortuguese)と同義です。

   注意: ‘LANGUAGE’変数は、localeが‘C’に設定されている場合は無視されます
。つまり、最初にローカリゼーションを利用可能にする時に、‘LANGUAGE’変数で
言語の優先順位リストを使用する前に、まず‘LANG’(または‘LC_ALL’) を‘C’以外
に設定する必要があります。

2.4 特定のプログラムにたいして翻訳をインストールする
====================================================

   GNU ‘gettext’を使用するすべてのパッケージが、各言語にたいして同様のサ
ポートを提供している訳ではなく、翻訳は時間をかけて個々に追加されます。パ
ッケージをインストールした後は通常、オペレーティングシステムか個々のパッ
ケージに同梱された翻訳を使用することになります。しかし新しいローカリゼー
ションを直接インストールすることもできます。これを行うには、ローカリゼー
ションの各ファイルがファイルシステム上でどのように保存されているかを理解
する必要があります。

   翻訳プロジェクトに参加しているプログラムは、
<http://translationproject.org/team/index.html>で見つけることができます
。この情報のスナップショットは、GNU gettextに同梱されている‘ABOUT-NLS’で
確認することもできます。

   KDEプロジェクトのプログラムを探す場合の出発点: <http://i18n.kde.org/>

   GNOMEプロジェクトのプログラムを探す場合の出発点:
<http://www.gnome.org/i18n/>

   他のプログラムに関しては、プログラムのソースコードパッケージに
‘LL.po’のようなファイルが含まれているかどうかでチェックすることができま
す(‘po/’というディレクトリーに保存されているときもあります)。各‘LL.po’に
は、LLで略記された言語の翻訳されたメッセージが含まれています。

3 POファイルのフォーマット
**************************

   GNU ‘gettext’ツールセットは、プログラマーや翻訳者が翻訳のためのファイ
ルを生成、更新、使用する手助けをし、それらのPOファイルは主としてテキスト
形式で編集可能なファイルです。このチャプターでは、POファイルのフォーマッ
トについて説明します。

   POファイルは多くのエントリーから成り立っており、それぞれのエントリー
には翻訳される前の原文の文字列と、それに対応する翻訳された文字列との関連
が保持されています。あるPOファイルに含まれるすべてのエントリーは通常、ひ
とつのプロジェクトに関連し、翻訳されたすべての文字列もひとつの言語を対象
に翻訳されたものです。一般的なPOファイルの“エントリー”は、以下のような構
造を持ちます:

     WHITE-SPACE
     #  TRANSLATOR-COMMENTS
     #. EXTRACTED-COMMENTS
     #: REFERENCE...
     #, FLAG...
     #| msgid PREVIOUS-UNTRANSLATED-STRING
     msgid UNTRANSLATED-STRING
     msgstr TRANSLATED-STRING

   翻訳者は、POファイルの一般的な構造を十分に理解する必要があります。
emacsのPOモードを使用すれば、フォーマットの詳細に関する最小限の知識を理
解するだけで、あとはPOモードが彼女にかわって面倒を見てくれます。

   以下は簡単なエントリの例です：

     #: lib/error.c:116
     msgid "Unknown system error"
     msgstr "Error desconegut del sistema"

   エントリーは任意の個数の空白文字から開始することができます。GNU
‘gettext’ツールで生成された場合、エントリーとエントリーの間には通常、1つ
の空行があります。‘#’の文字で始まる行はすべてコメント行として扱われます
。コメントには2種類のコメントがあります。1つ目はTRANSLATOR COMMENTS(翻訳
者コメント)で、‘#’の直後にいくつかの空白文字があり、これらのコメントは翻
訳者により保守、保守されます。2つ目のコメントはAUTOMATIC COMMENTS(自動コ
メント)で、これらのコメントはGNU ‘gettext’ツールにより自動的に挿入、保守
されるもので、‘#’の直後に空白文字以外の文字があります。‘#.’で始まるコメ
ントはプログラマーによる翻訳者に向けたコメントを含んでいます。これらのコ
メントは‘xgettext’プログラムによりプログラムのソースから抽出(extract)さ
れるため、EXTRACTED COMMENTS(抽出コメント)と呼ばれます。‘#:’で始まるコメ
ントには、プログラムのソースコードへの参照(references)が含まれます。
‘#,’で始まるコメントにはフラグ(flags)が含まれています。これらのフラグに
ついては以下で説明します。‘#|’で始まるコメントには、以前のバージョンの翻
訳済みメッセージに対応する翻訳前の文字列(previous untranslated string)が
含まれています。

   すべてのコメントは、オプションです。

   空白文字とコメントの後には、2つの文字列を表すための文字列があります。
最初の文字列は翻訳前の文字列で、これらの文字列のオリジナルはプログラムの
ソース中に出現する文字列です。その次の文字列は、この翻訳前の文字列に対応
する翻訳後の文字列です。オリジナルの文字列は‘msgid’というキーワードで識
別され、翻訳は‘msgstr’というキーワードで識別されます。これらの翻訳前と翻
訳後の2つの文字列は、POファイル中で‘"’区切りや‘\’エスケープにより、様々
な方法で引用されていますが、文字列の引用などについてはPOモードが彼女にか
わり面倒をすべて見てくれるので、翻訳者はそれらの正確な引用形式に注意を払
う必要がなくなります。

   msgidの文字列も自動生成されたコメントと同様、GNU ‘gettext’の他のツー
ルにより生成、管理されるので、POモードは翻訳者がそれらを変更するような操
作を提供しません。それらの文字列にたいして彼女にできることは、単にそれを
削除することだけで、しかもエントリー全体を削除できるだけです。一方、
‘msgstr’の文字列については、実際に翻訳者が編集するための翻訳者コメントな
ので、POモードは彼女の必要に応じて、完全な制御を提供します。

   ‘#,’で始まるコメントは、一般的なコメントとは違いプログラムにより完全
に無視されるものではないという点で、特別なコメントです。カンマで区切られ
たFLAGのリストは、ユーザーのためにより良い診断メッセージを提供するために
、‘msgfmt’プログラムにより使用されます。現時点では2つの形式のflagが定義
されています:

‘fuzzy’
     このフラグは‘msgmerge’プログラムにより生成されるか、翻訳者自身によ
     り挿入され、‘msgstr’の文字列が、(もはや)正しい翻訳ではないことを示
     します。翻訳をさらに修正する必要があるか、そのまま適用できるかは、
     翻訳者だけが判断できます。翻訳を完成したら、彼女は‘fuzzy’属性を取り
     除きます。‘msgmerge’は、あいまい検索(fuzzy search)により‘msgid’と
     ‘msgstr’エントリーを結びつけた場合のみ、このフラグを挿入します。
     Fuzzy Entriesを参照してください。

‘c-format’
‘no-c-format’
     これらは人間によって追加されるフラグではなく、‘xgettext’プログラム
     だけが挿入するフラグです。ここで提案しているようなPOファイルを自動
     生成するシステムでは、ユーザーが変更を行っても、‘xgettext’プログラ
     ムが新しいテンプレートファイルを生成するたびに、変更は上書きされて
     しまいます。

     ‘c-format’フラグは、翻訳前の文字列と翻訳された文字列が、C形式の文字
     列であることを示します。‘no-c-format’フラグは逆に、文字列が一見して
     (‘%’ディレクティブによる)C形式の文字列に見えても、C形式ではないこと
     を示します。

     文字列に‘c-format’フラグが設定されていると、‘msgfmt’プログラムは、
     翻訳にたいして妥当性チェックのテストを追加で行います。See msgfmt Invocation
     、およびc-format Flagとc-formatを参照し
     てください。

‘objc-format’
‘no-objc-format’
     Objective Cの場合も同様です。objc-formatを参照してください
     。

‘sh-format’
‘no-sh-format’
     shellの場合も同様です。sh-formatを参照してください。

‘python-format’
‘no-python-format’
     Pythonの場合も同様です。python-formatを参照してください。

‘python-brace-format’
‘no-python-brace-format’
     Python braceの場合も同様です。python-formatを参照してくださ
     い。

‘lisp-format’
‘no-lisp-format’
     Lispの場合も同様です。lisp-formatを参照してください。

‘elisp-format’
‘no-elisp-format’
     Emacs Lispの場合も同様です。elisp-formatを参照してください
     。

‘librep-format’
‘no-librep-format’
     librepの場合も同様です。librep-formatを参照してください。

‘scheme-format’
‘no-scheme-format’
     Schemeの場合も同様です。scheme-formatを参照してください。

‘smalltalk-format’
‘no-smalltalk-format’
     Smalltalkの場合も同様です。smalltalk-formatを参照してくださ
     い。

‘java-format’
‘no-java-format’
     Javaの場合も同様です。java-formatを参照してください。

‘csharp-format’
‘no-csharp-format’
     C#の場合も同様です。csharp-formatを参照してください。

‘awk-format’
‘no-awk-format’
     awkの場合も同様です。awk-formatを参照してください。

‘object-pascal-format’
‘no-object-pascal-format’
     Object Pascalの場合も同様です。object-pascal-formatを参照し
     てください。

‘ycp-format’
‘no-ycp-format’
     YCPの場合も同様です。ycp-formatを参照してください。

‘tcl-format’
‘no-tcl-format’
     Tclの場合も同様です。tcl-formatを参照してください。

‘perl-format’
‘no-perl-format’
     Perlの場合も同様です。perl-formatを参照してください。

‘perl-brace-format’
‘no-perl-brace-format’
     Perl braceの場合も同様です。perl-formatを参照してください。

‘php-format’
‘no-php-format’
     PHPの場合も同様です。php-formatを参照してください。

‘gcc-internal-format’
‘no-gcc-internal-format’
     GCCソースの場合も同様です。gcc-internal-formatを参照してく
     ださい。

‘gfc-internal-format’
‘no-gfc-internal-format’
     GNU Fortranコンパイラーのソースの場合も同様です。
     gfc-internal-formatを参照してください。

‘qt-format’
‘no-qt-format’
     Qtの場合も同様です。qt-formatを参照してください。

‘qt-plural-format’
‘no-qt-plural-format’
     Qt plural形式の場合も同様です。qt-plural-formatを参照してく
     ださい。

‘kde-format’
‘no-kde-format’
     KDEの場合も同様です。kde-formatを参照してください。

‘boost-format’
‘no-boost-format’
     Boostの場合も同様です。boost-formatを参照してください。

‘lua-format’
‘no-lua-format’
     Luaの場合も同様です。lua-formatを参照してください。

‘javascript-format’
‘no-javascript-format’
     JavaScriptの場合も同様です。javascript-formatを参照してくだ
     さい。

   以下のように、context specifier(コンテキスト指定子)をともなうエントリ
ーも使用することができます:

     WHITE-SPACE
     #  TRANSLATOR-COMMENTS
     #. EXTRACTED-COMMENTS
     #: REFERENCE...
     #, FLAG...
     #| msgctxt PREVIOUS-CONTEXT
     #| msgid PREVIOUS-UNTRANSLATED-STRING
     msgctxt CONTEXT
     msgid UNTRANSLATED-STRING
     msgstr TRANSLATED-STRING

   コンテキスト(context)は、同じUNTRANSLATED-STRINGのあいまいさをなくす
ために提供されます。これによりPOファイルの中で、異なるCONTEXTで、同じ
UNTRANSLATED-STRINGを複数もつことが可能になります。CONTEXTに空の文字列を
指定するのと、‘msgctxt’の行を指定しないのは、同じではないことに注意して
ください。

   他にも、複数形式(plural form)を含む翻訳のために使用されるエントリーが
あります。

     WHITE-SPACE
     #  TRANSLATOR-COMMENTS
     #. EXTRACTED-COMMENTS
     #: REFERENCE...
     #, FLAG...
     #| msgid PREVIOUS-UNTRANSLATED-STRING-SINGULAR
     #| msgid_plural PREVIOUS-UNTRANSLATED-STRING-PLURAL
     msgid UNTRANSLATED-STRING-SINGULAR
     msgid_plural UNTRANSLATED-STRING-PLURAL
     msgstr[0] TRANSLATED-STRING-CASE-0
     ...
     msgstr[N] TRANSLATED-STRING-CASE-N

   以下はエントリーの例です:

     #: src/msgcmp.c:338 src/po-lex.c:699
     #, c-format
     msgid "found %d fatal error"
     msgid_plural "found %d fatal errors"
     msgstr[0] "s'ha trobat %d error fatal"
     msgstr[1] "s'han trobat %d errors fatals"

   ‘msgid’の前に、前述した‘msgctxt’コンテキストを指定することもできます
。

   ここで追加のフラグを使用できます:

‘range:’
     このフラグは正の数値範囲をともない、‘range:
     MINIMUM-VALUE..MAXIMUM-VALUE’という書式で使用します。この範囲には、
     メッセージが受けとることができる数値を指定します。たとえばある言語
     では、事前に値が0から10だとわかっていれば、よりよい翻訳を生成できま
     す。

   PREVIOUS-UNTRANSLATED-STRINGは、‘msgmerge’がメッセージをfuzzyとしてマ
ークするとき同時にオプションとして挿入されます。これは開発者が、
UNTRANSLATED-STRINGにたいしてどのような変更を行ったかを、翻訳者が知る助
けになります。

   これは、POファイルの最後のエントリーに続けて、何らかの行(通常は空白文
字やコメント)があるときに発生します。これらの行は、どのエントリーの一部
でもなく、POファイルがツールにより処理されるときに捨てられるか、POファイ
ルエディターの動作を妨げるときもあります。

   このチャプターの残りの部分は、POファイルの正確な書式にたいしてよいア
イデアを持つ人は興味があるかもしれませんが、POファイルエディターを使用す
る場合はスキップして構いません。しかし、POファイルを手で変更したい場合は
、注意して読む必要があります。

   空のUNTRANSLATED-STRINGは、メタ情報が含まれたヘッダーエントリー(see
Header Entryを参照してください)のために予約されています。このヘッダー
エントリーはファイルの最初のエントリーにすべきです。空の
UNTRANSLATED-STRINGは、この目的のために予約されているので、他の場所で使
用することはできません。

   UNTRANSLATED-STRINGとTRANSLATED-STRINGはCの文法に従い、それには文字列
の括り方やバックスラッシュによるエスケープシーケンスも含まれます。複数行
のメッセージを記述するときは、エスケープされた改行文字を使用せずに、改行
する行末の最後の文字で引用符を閉じて、POファイルの次の行で再び引用を開始
します:

     msgid ""
     "Here is an example of how one might continue a very long string\n"
     "for the common case the string represents multi-line output.\n"

この例の最初の行には、‘for’の‘f’という文字の上に‘Here’の‘H’を揃えるため
に、空の文字列が使用されています。また、キーワード‘msgid’の後ろには3つの
文字列があり、それらの文字列は連結して使用されます。空の文字列と連結する
ことにより文字列全体は変更されませんが、‘msgid’の行に連結される文字列を
、複数行の表示を維持しつつ左揃え表示して、配置を明確にさせるための方法で
す。空の文字列は省略できますがその場合、‘msgid’の後ろに記述する最初の行
は‘Here’で開始しなければなりません(1)。それぞれの文字列の括りの終端を改
行(‘\n’)の直後にしている理由は、そうしても支障がないからというだけで、
_任意の_文字の後で括りを終端して構いません。

   文字列の括りの_内側_にある、行末を示す‘\n’は文字列の一部で、文字列の
括りの外側の改行はPOファイル自身の行末を示し、文字列に影響を与えない点に
注意してください。

   文字列の外側では、空白文字とコメントを自由に使うことができます。行頭
の‘#’から、その行の行末までがコメントとなります。翻訳者が記入するコメン
トは‘#’の後ろに空白文字をいくつか記述する必要があります。‘#’の後ろに空白
文字がない場合、それは特定のGNUツールで生成・管理されるコメントとみなさ
れ、POファイルが‘msgmerge’で処理されるとき、予期せず削除される可能性があ
ります。

   ---------- Footnotes ----------

   (1) これは GNU ‘gettext’の制限ではなく、Solarisの‘msgfmt’との互換性に
よる制限です。

4 プログラムソースの準備
************************

   プログラマーのために、Cのソースコードの変更を3つにカテゴリーに分けま
す。1番目は、ローカリゼーション関数にメッセージ翻訳を必要とするすべての
モジュールを教えることです。2番目は、プログラムの初期化(通常はmain関数の
内部)で、GNU ‘gettext’の操作を的確にトリガーすることです。3番目に、翻訳
が必要なプログラム内のすべての文字列定数を識別・調整・マークする必要があ
ります。

4.1 ‘gettext’宣言のインポート
=============================

   GNU ‘gettext’が必要とするすべてのファイルが利用可能で、‘Makefile’ファ
イルも調整済み(see Maintainersを参照してください)だとすると、翻訳対
象の文字列を含むCモジュールには以下の行を含める必要があります:

     #include <libintl.h>

   翻訳可能なCの書式指定文字列(他のCモジュールで文字列が定義されている場
合も含まれます)を引数として呼び出される、‘printf()’/‘fprintf()’/...を含
むCモジュールにも以下の行を含める必要があります:

     #include <libintl.h>

4.2 ‘gettext’処理のトリガー
===========================

   すべてのプログラムで、以下で示すようなlocaleデータの初期化の類が必要
となります:

     int
     main (int argc, char *argv[])
     {
       ...
       setlocale (LC_ALL, "");
       bindtextdomain (PACKAGE, LOCALEDIR);
       textdomain (PACKAGE);
       ...
     }

   PACKAGEとLOCALEDIRは、‘config.h’かMakefileで提供される必要があります
。詳細については、‘gettext’やGNU ‘hello’のソースを眺めてみるとよいでしょ
う。

   この場合、‘LC_ALL’の使用は適切ではないでしょう。LC_ALL‘LC_ALL’にはす
べてのlocaleカテゴリー、特に‘LC_CTYPE’が含まれます。この後者のカテゴリー
は、プログラムのために‘ctype.h’で定義されている、‘isalnum’関数などで処理
する文字列クラスを決定することに責任をもっており、入力される文字列の言語
によってはうまく動作しません。たとえばソースコードでç(c-cedilla文字)が使
用されている場合、このプログラムはFranceでは問題ありませんがU.S.では動作
しません。

   ‘LC_ALL’というlocaleカテゴリーに他のlocaleが使用された場合、‘scanf’関
数による数字の解析に問題が生じるシステムもあります。標準では、このような
場合は‘"C"’というlocaleとして知られる追加の書式が認識されるでしょう。し
かし‘"C"’というlocaleの書式では、数値を受け付けないシステムもあるようで
す。状況によっては数値の表示が‘"C"’というlocaleなのか、それともlocalのフ
ォーマットかにより認識できないこともあります。これは千単位の桁区切り文字
を使用するときに発生します。いくつかのlocale定義ではnational conventionに
従い、桁区切り文字として‘'.'’を使用しますが、この文字は‘"C"’という
localeでは小数点として使用されます。

   これらの理由により、上記のコードの‘LC_ALL’の行は、‘setlocale’による行
に分けることが必要な場合もあります。

     {
       ...
       setlocale (LC_CTYPE, "");
       setlocale (LC_MESSAGES, "");
       ...
     }

POSIX互換のすべてのシステムでは、‘LC_CTYPE’、‘LC_MESSAGES’、
‘LC_COLLATE’、‘LC_MONETARY’、‘LC_NUMERIC’および‘LC_TIME’が利用できます。
ISO C準拠のみのシステムも存在し、それらのシステムには‘LC_MESSAGES’があり
ませんが、これらの不足にたいする代替は GNU gettextの‘<libintl.h>’と、GNU
gnulibの‘<locale.h>’で定義されています。

   ‘LC_CTYPE’を変更すると、‘<ctype.h>’という標準ヘッダーファイルで定義さ
れている関数、および‘<string.h>’と‘<stdlib.h>’という標準ヘッダーファイル
で定義されているいくつかの関数が影響をうけることに注意してください。これ
が望ましくない場合(例えばコンパイラーのパーサー)、GNU gnulibのソースディ
ストリビューションにある‘c-ctype’、‘c-strcase’、‘c-strcasestr’、
‘c-strtod’、‘c-strtold’モジュールの、C localeでハードコーディングされて
いる代替の関数を使用することができます。

   環境に依存したlocaleとC localeを切り替えて使用することもできますが、
この方法は‘setlocale’の呼び出しが高価であること、広大なプログラムのソー
ス中でlocaleを切り替える場所を決定するのが退屈であること、localeの切り替
えがスレッドセーフではないこと等の理由により、通常は行われません。

4.3 翻訳可能な文字列の準備
==========================

   文字列が翻訳可能とマークされる前に、調整が必要なこともあります。翻訳
可能な文字列の準備は、その文字列をマーク(次のセクションで説明)する前に行
います。文字列を準備する際に留意すべきは以下の点です。

   • Englishスタイルとして正常であること。

   • センテンス全体が含まれていること。

   • パラグラフで分割されていること。

   • 文字列を連結するのではなく、書式文字列を使用すること。

   • 特殊なマークアップや制御文字を使用しないこと。

上記のガイドラインにたいする例を、いくつか見てみましょう。

   翻訳可能な文字列は、正しいEnglishスタイルである必要があります。言語特
有のスラングや省略語が使用されている場合、翻訳者がメッセージを理解できず
に不適切な翻訳を作成してしまうことがあります。

     "%s: is parameter\n"

このメッセージはほとんど翻訳不可能です。表示されるアイテムは_a_
parameter(任意のparameter)なのでしょうか、_the_ parameter(特定の
parameter)なのでしょうか?

     "No match"

メッセージに含まれるあいまいさにより、メッセージが理解できなくなっていま
す。プログラムはファイルに何かをセットしようとしているのでしょうか?
"The given object does not match the template(与えられたオブジェクトがテ
ンプレートにマッチしない)"なのでしょうか、それとも "The template does
not fit for any of the objects(そのテンプレートは任意のオブジェクトに適
合しない)"なのでしょうか?

   どちらのケースも、メッセージに単語を追加することにより、翻訳者と
Englishを話すユーザーの両方を助けることができます。

   翻訳可能な文字列は、センテンス全体を含む必要があります。単独の動詞や
形容詞を、すべてのメッセージに代替できるように翻訳するのは不可能な場合が
あります。

     printf ("File %s is %s protected", filename, rw ? "write" : "read");

ほとんどの翻訳者はソースを見ないので、‘"File %s is %s protected"’という
、それだけでは理解できない文字列しか目にしません。これを以下のように変更
します。

     printf (rw ? "File %s is write protected" : "File %s is read protected",
             filename);

この方法なら翻訳者はメッセージを理解するだけでなく、適切な文法の組み立て
方を見つけることが出きます。たとえばFrenchの翻訳者なら"write protected"を
"protected against writing"のように翻訳するでしょう。

   多くの言語では、センテンスの他の場所にある性別や数(単数形/複数形)によ
って、あるセンテンスの単語が変わることがあるという理由からも、センテンス
全体を含めることが重要になります。Englishより強い単語間の相互関係を持つ
言語もあります。たとえEnglishではうまく動作しても、多くの言語では半分に
分割した2つのセンテンスを翻訳者に翻訳してもらってから、2つの翻訳を機械的
に結合しても、満足な翻訳とはなりません。これが翻訳者がセンテンス全体を処
理する必要がある理由です。

   センテンスが1つの行に対応しない場合もあります。これは以下のように、
‘printf’ステートメントを使って2つの出力により、1つのセンテンスを出力して
いるような場合です。

     printf ("Locale charset \"%s\" is different from\n", lcharset);
     printf ("input file charset \"%s\".\n", fcharset);

翻訳者は2つのセンテンスを翻訳する必要があるでしょうが、POTファイル内には
2つのセンテンスが分割された1つのセンテンスだと、彼女に教える情報はありま
せん。2つの‘printf’ステートメントを1つにする必要があります。そうすれば翻
訳者がセンテンスを一括して処理できるので、翻訳をどの位置で改行すべきか決
められるようなります。

     printf ("Locale charset \"%s\" is different from\n\
     input file charset \"%s\".\n", lcharset, fcharset);

   では以下のような隣接した2つのセンテンスの場合はどうなるでしょうか:

     puts ("Apollo 13 scenario: Stack overflow handling failed.");
     puts ("On the next stack overflow we will crash!!!");

上記の2つのセンテンスは、1つにまとめる必要があるでしょうか? このような場
合、2つのセンテンスが互いに関連していて、一緒にしたほうが翻訳者が理解・
翻訳しやすくなるようなら、マージすることをお勧めします。一方、2つのメッ
セージのうち1つが定型的なもので、他の場所でも使用されるようなメッセージ
の場合は、マージしないほうが翻訳者にとって有益です(同じメッセージが複数
の箇所に出現する場合、xgettextがそれらをまとめるので、翻訳者は1度だけそ
のメッセージを翻訳すればよくなります)。

   翻訳可能な文字列は、単一のパラグラフ(段落)に制限すべきです。1つのメッ
セージの長さは、10行以内にしましょう。その理由は、翻訳可能な文字列が変更
されたとき、翻訳者は翻訳済み文字列全体を更新しなければならないからです。
たとえ1つの単語を変更しただけでも、(現在の翻訳ツールでは)翻訳者にはそれ
がわからないので、彼女はメッセージ全体を校正しなければならなくなってしま
います。

   多くのGNUプログラムは、‘--help’オプションにより複数画面にまたがる出力
を生成します。そのようなメッセージを、1つが5行から10行のメッセージに分割
するのは、翻訳者にたいする礼儀です。ドキュメント化するオプションを、入力
オプションと出力オプション、情報を出力するオプションのようにグループ分け
してもよいでしょう。グループ分けすることにより、オプションを探すすべての
ユーザーを助けることができます。

   ハードコーディングされた文字列の結合により、English文字列を生成するこ
とがあります:

     strcpy (s, "Replace ");
     strcat (s, object1);
     strcat (s, " with ");
     strcat (s, object2);
     strcat (s, "?");

翻訳者にセンテンス全体を表示するためという理由だけではなく、‘object1’と
‘object2’の順番が入れ替わるような言語もあるので、これは以下のような書式
文字列を使用するように変更する必要があります:

     sprintf (s, "Replace %s with %s?", object1, object2);

   似たようなケースとして、コンパイル時の文字列結合があります。ISO C 99の
インクルードファイルである‘<inttypes.h>’には、‘printf’で整数型
‘int64_t’を出力するための‘PRId64’マクロが含まれています。このマクロは通
常、プラットフォームに応じて "d"、"ld"、"lld" のような文字列定数に展開さ
れます。以下のようなコードがあるとします。

     printf ("The amount is %0" PRId64 "\n", number);

‘gettext’ツールとライブラリーには、これら‘<inttypes.h>’のマクロにたいす
る特別なサポートがあるので、上記のような場合は単に以下のように書くことが
できます。

     printf (gettext ("The amount is %0" PRId64 "\n"), number);

この場合、POファイルには"The amount is %0<PRId64>\n"という文字列が含まれ
ます。翻訳者は同様に"%0<PRId64>"と翻訳すれば、実行時に‘gettext’関数が、
"d"、"ld"、"lld" などから適切な文字列定数に変換します。

   これは事前に定義された‘<inttypes.h>’マクロにたいしてのみ機能します。
あなたが‘MYPRId64’のような似たようなマクロを定義した場合、‘xgettext’はそ
れを知ることができないので、コードを以下のように変更してください:

     char buf1[100];
     sprintf (buf1, "%0" MYPRId64, number);
     printf (gettext ("The amount is %s\n"), buf1);

   これでプラットフォームに依存するコードと、インターナショナリゼーショ
ンのコードは、別のステートメントに分けられました。バッファーの長さは
100バイト以内でよいことに注意してください。なぜなら利用可能なすべてのハ
ードウェアーの整数型は128ビットに制限されており、128ビット整数を出力する
には、10進、8進、16進に関わらず最大で54バイトあればよいからです。

   これは他のプログラム言語には適用できます。JavaとC#では文字列結合は、
それらのコンパイラーのビルトイン操作なのでとても頻繁に使用されます。以下
のようなCやJavaのコードがあるとします

     System.out.println("Replace "+object1+" with "+object2+"?");

これを以下のような書式師弟文字列を含むステートメントに変更します:

     System.out.println(
         MessageFormat.format("Replace {0} with {1}?",
                              new Object[] { object1, object2 }));

C#の場合は以下のように変更します

     Console.WriteLine("Replace "+object1+" with "+object2+"?");

これを以下のような書式師弟文字列を含むステートメントに変更します:

     Console.WriteLine(
         String.Format("Replace {0} with {1}?", object1, object2));

   通常使用しないようなマークアップや制御文字は、翻訳可能な文字列の中に
含めるべきではありません。翻訳者はマークアップや制御文字がもつ特別な意味
は理解しません。

   たとえば‘|’の右側と左側とで何らかのGUI要素を分ける規則があるような場
合、翻訳者は特別なコメントなしではその規則を理解することはできません。こ
のような場合は、翻訳者が右側と左側の文字列を個別に翻訳できるようにするの
がよいでしょう。

   他の例としては、‘argp’で制御文字‘\v’(vertical tab)を使用する場合の規
則です。これは1つの文字列を2つのセクションに分ける場合に使用されます。こ
のような文字列をそのまま翻訳可能文字列とするには問題があります。翻訳者に
よっては、これを単純に改行や空行に置き換えてしまうかもしれません。POファ
イルエディターの中には、制御文字のvertical tabを入力するのが困難なものも
あります。上記の理由により、あなたは翻訳文字列の対応する位置に、‘\v’文字
があることを期待できません。この問題にたいする解決策は、繰り返しになりま
すが、翻訳者が個別に文字列を翻訳できるようにしておいて、実行時に2つの翻
訳された文字列を、規則が要求する‘\v’で結合することです。

   HTMLマークアップは十分に一般的なマークアップなので、翻訳可能文字列を
使用しても大丈夫でしょう。しかしGNU gettextツールは、翻訳された文字列が
well-formedなHTMLであるかは検証しないことに留意してください。

4.4 ソース内でマークはどのように見えるか
========================================

   Cソース中で翻訳される文字列は、すべてマークする必要があります。マーキ
ングは翻訳可能な文字列を、関数やプリプロセッサーのマクロに、単独の引数と
して引き渡す方法で行われます。翻訳のために利用可できる関数またはマクロは
少なく、マーキングのキーワードとしてそれらの名前が使用されます。マーキン
グは翻訳される文字列自体に何かを行うよりは、文字列にアタッチすることによ
りマーキングを行なう方法が、より多く使用されます。明らかな例としては、フ
ォーマット文字列によりエラーメッセージを生成する場合です。フォーマット文
字列は翻訳する必要があり、フォーマット文字列の‘%s’で指定した箇所に挿入さ
れる文字列も同様だとすると、たとえば‘sprintf’の結果には、
‘error_string_out()’のようなルーチンからなる、多くの異なるインスタンスが
含まれることになり、これらをすべてリストするのは非現実的です。

   マーキングには2つの目的があります。1つ目は実行時に翻訳を取得するトリ
ガーとなることです。キーワードは引数となる文字列にたいして、可能なかぎり
(そして望む限り)、動的に適切なトランスレーションを返すルーチンへと解決さ
れます。ローカライズ可能な文字列は、変数にあてがわれていたり、関数の引数
になっている場合がほとんどです。しかし翻訳可能な文字列が構造体の初期化時
に使用される等の例外もあります。Special casesを参照してください
。

   2つ目の目的は、‘xgettext’が、一連のプログラムソースをスキャンしてPOフ
ァイルのテンプレートを生成するときに、翻訳可能な文字列を適切に抽出する手
助けをすることです。

   翻訳可能な文字列をマークするための標準的なキーワードは‘gettext’で、こ
れはGNU ‘gettext’パッケージの名前の由来にもなっています。パッケージで少
量の‘gettext’キーワードやマクロ、関数を_そのまま_使うのは簡単です。しか
し‘gettext’インターフェースを多用するパッケージの場合、主要なキーワード
には目立つ名前ではなく、より簡潔な名前を使用する方が便利です。キーワード
はパッケージ内のすべての文字列の箇所に記述されますが、プログラマーは通常
、彼らのプログラムのソースがインターナショナライズされるものだといつも強
制的に思い出したいとは望みませんし、その必要もありません。また長いキーワ
ードはより多くの文字数を使用するので、ソースの1行を79から80文字にインデ
ントするための労力が余分にかかるという欠点もあります。

   多くのパッケージはキーワードとして‘_’(単なるアンダーライン)を使用して
、‘gettext ("Translatable string")’を、‘_("Translatable string")’のよう
に記述しています。またGNU標準のコーディング規約は実際、この特定の用途の
ためにキーワードと開き括弧の間に、余白としてスペースを要求しています。こ
れにより翻訳可能な文字列のためにかかる文字的なオーバーヘッドは、アンダー
ラインと2つの括弧というたった3文字に短縮されます。たとえGNU ‘gettext’が
この方式を内部的に使用していたとしても、これは公式な提案ではありません。
正式なキーワードはあくまでも本物の‘gettext’です。しかし‘gettext’のかわり
に‘_’を使用したい人は、以下のように定義すると簡単になります。

     #include <libintl.h>
     #define _(String) gettext (String)

単に‘#include <libintl.h>’とするのではなく、上記のようにすれば簡単に使用
できます。

   マーキングのためのキーワードである‘gettext’と‘_’ は、翻訳可能文字列を
単一の引数とします。他の位置に引数をするマーキング用の関数を定義すること
もできます。関数が呼び出されたときの引数の合計数にもとづいた位置のマーク
用引数を作ることもできます(通常はC++の場合)。これは‘xgettext’の
‘--keyword’により実現されます。‘xgettext’にこのような引数を渡すには
‘gettextize’が使用されます、その方法についてはpo/Makevarsと
AM_XGETTEXT_OPTIONで説明します。

   長い文字列は複数行に分けられることに注意してください。コンパイル時に
はISO CおよびISO C++にもとづく文字列の自動連結が行われますが、
‘xgettext’もこの構文をサポートしています。

   後でメンテナンスするのも簡単になります。もしあなたがプログラマーで、
文字列を追加、変更した場合、その文字列が翻訳される必要があると考えた場合
は、‘_()’でマークすればよいのです。たとえば‘"%s"’は、翻訳しない文字列だ
とします。しかし‘"%s: %d"’は翻訳するような場合です(Frenchの場合は通常、
Englishとは異なり、コロンの前にスペースを挿入する翻訳が必要になります)。

4.5 翻訳可能文字列のマーク
==========================

   POモードには、翻訳者向けというよりはプログラマー向けの一連の機能があ
ります。それらの機能により彼は、プログラムのソース中の文字列が、翻訳可能
かどうか、対話的にマークすることができます。彼が選んだ他のエディターでも
、それらの文字列を探してマークするのは、プログラマーにとって簡単な作業か
もしれませんが、POモードはこれらの作業をより快適にしてくれます。またPOモ
ードは、プログラマーの素養を持つ翻訳者、または翻訳者の素養を持つプログラ
マーにたいして、プログラムのソース中の翻訳可能な文字列をマークするツール
を与えてくれると同時に、インターナショナライズされるパッケージにたいする
翻訳を生成するツールを与えてくれるのです。

   以下で説明するPOモードのコマンドが対象とするプログラムのソースは、
POファイルのコマンドを使う前に、プロジェクト用のEmacs tagsテーブルを生成
する必要があります。これは簡単です。任意のシェルウィンドウでプロジェクト
のルートディレクトリに移動して、以下のようなコマンドを実行してください:

     etags src/*.[hc] lib/*.[hc]

ここでは‘src/’、および‘lib/’ディレクトリーにあるすべての‘.h’と‘.c’ファイ
ルを処理したいとします。このコマンドは指定されたすべてのファイルを検索し
て、プロジェクトのルートディレクトリーに‘TAGS’という、Emacsが解釈できる
要約された形式のファイルを作成します。

   GNUコーディング規約に従うパッケージには、すべてのディレクトリーとソー
スコードを含んだすべてのファイルにたいして、‘tags’、または‘TAGS’ファイル
を作成するという目標があります。

   1度‘TAGS’を準備すれば、以下のコマンドが彼のソース中の翻訳可能な文字列
をマークする手助けをしてくれます。これらのコマンドはPOファイルのウィンド
ウから実行される必要がありますが、POファイルはまだ作成されていません。し
かし新しいウィンドウで空のPOファイルを新規に作成して、そこからコマンドを
実行すれば問題ありません。この空のPOファイルの内容は、プログラムのソース
中の文字列を翻訳可能にマークするにつれて、徐々に増えていきます。

‘,’
     翻訳候補となりそうな文字列をプログラムのソースから検索します
     (‘po-tags-search’)。

‘M-,’
     検索された最後の文字列を‘_()’でマークします
     (‘po-mark-translatable’)。

‘M-.’
     検索された最後の文字列を、利用可能なキーワードによりマークします。
     プレフィックスと一緒にこのコマンドを使うことにより、キーワードを管
     理することができます(‘po-select-mark-and-mark’)。

   ‘,’ (‘po-tags-search’)コマンドは、翻訳候補と思われるような次の文字列
を検索して、プログラムのソースをEmacsの他のウィンドウで表示します(その文
字列がウィンドウの上部にくるように表示されます)。文字列が長くてウィンド
ウに収まらないような場合は、文字列の最後の部分が表示されます。カーソルは
常にPOファイルのウィンドウにあります。その文字列が他の言語に翻訳されたほ
うがよいと判断したら、‘M-,’、または‘M-.’により文字列をマークします。翻訳
する必要がないと判断した場合は、単に‘,’コマンドで次の文字列を検索してく
ださい。

   3つ以上の文字の並びは、翻訳候補となります。1行の文字の並びが最大で2つ
でも、文字の数が非文字より多い場合は、翻訳候補と判断します。文字を含まな
い文字列、または 孤立した文字だけの文字列は無視されます。コメント文字列
、およびPOモードが把握しているキーワード(以下を参照してください)ですでに
マークされている文字列も無視されます。

   Emacsにたいして‘TAGS’を指定していない場合、最初にこのコマンドを使うと
きにミニバッファー(minibuffer)に入力を求められます。‘TAGS’ファイルは、
Emacsの標準コマンドである‘M-x visit-tags-table’を入力して、正しい
‘TAGS’ファイルを入力することにより、後から変更することができます。See
Tag Tables (emacs).を参照してください。

   ‘,’コマンドは毎回、前回に検索した箇所から検索を再開し、‘TAGS’に従って
すべてのプログラムソースを処理するまで検索します。コマンド(‘C-u ,’)にプ
レフィクス引数( prefix argument)を与えることにより、プログラムのソースの
先頭から検索を再開させることができます。この場合、前回マークした翻訳可能
な文字列は自動的にスキップされます。

   ‘,’コマンドを使用することにより、Emacsの標準コマンドが使用できなくな
ることはありません。たとえば、標準の‘tags-search’、および
‘tags-query-replace’コマンドは、‘,’のサーチ順序とは独立して、中断される
ことなく使用できます。しかし、_最初_の‘,’コマンド(またはコマンド引数をと
もなう‘,’コマンド)は、Emacsの標準的なtags検索を最初のtagsにリセットして
しまうよう実装されているので、この再初期化は除きます。

   ‘M-,’ (‘po-mark-translatable’)コマンドは、前回検索された文字列を、キ
ーワード‘_’でマークします。‘M-.’ (‘po-select-mark-and-mark’)コマンドは、
ミニバッファーでキーワードの入力を求めて、文字列をマークするのにそのキー
ワードを使用します。どちらのコマンドも、マークした文字列に対応する新しい
未翻訳のエントリーをPOファイルに作成して、そのエントリーをカレントのエン
トリーとします(そのエントリーをすぐに翻訳するのが簡単になります)。
‘M-,’や‘M-.’によるプログラムソースの変更により、ソース1行の文字数が80文
字を超えてしまうような場合もありますが、これにたいする再インデントなどは
別の作業になります。プログラムソースのウィンドウから、Emacsの別のウィン
ドウに移ったりするために、POモードから‘O’コマンドを使う場合もあるでしょ
う。‘,’コマンドに次の文字列を告げるような場合、POファイルのウィンドウに
カーソルを戻すには、なんらかのEmacsの標準コマンドを使う必要があります。

   ‘M-.’には、キーワードをいちいち全部入力しなくてもよいような、スピード
アップのための機能がいくつかあります。1つ目は、プロンプトで単に‘<RET>’を
押すだけで、_好ましいキーワード_が表示されるというスピードアップ機能です
。2つ目は、入力したいキーワードにたいして、そのキーワードの先頭部分を一
意に特定できる分だけ入力すれば、コマンドが残りの部分を補完してくれるスピ
ードアップ機能です。これはPOモードが利用可能なキーワードを_知って_いて、
ミスタイプによる誤ったキーワードは受け付けられないことを意味します。

   キーワードの入力を求められたときに‘?’を入力すると、コマンドは既知のキ
ーワードのリストを表示し、そこから選択して入力することができます。
(‘C-u M-.’)によりコマンドが引数が指定された場合、単純なキーワード管理以
外による、プログラムのソースとPOファイルのバッファーの更新が禁じられます
。この場合、コマンドはキーワードの完全な入力を求め、そのキーワードは以降
の‘M-.’コマンドで使用されます。さらに、この新しいキーワードは自動的に、
以降のコマンド用の_お好み_のキーワードに追加されます。‘C-u M-.’にたいし
て既知のキーワードを答えた場合、単にお勧めのキーワードが1つ変更されるだ
けで、他には何もしません。

   ‘M-.’により認識されるすべてのキーワードは、‘,’コマンドによる文字列検
索時に再編成されます。この時、これらのキーワードですでにマークされている
文字列は自動的にスキップされます。同時に複数のPOファイルを開いている場合
、それぞれが個別に既知のキーワードを保有します。現在のところPOモードにキ
ーワードを削除するための機能はないので、(‘q’を使用するなどして)ファイル
を一旦閉じてから、再度開く必要があります。Emacs のウィンドウにPOファイル
を新規に開いたときは、‘gettext’と‘_’だけがキーワードで、‘M-.’コマンドの
お好みのキーワードは‘gettext’になっています。実際のところ、‘_’はビルトイ
ンの‘M-,’コマンドに割り当てられているので、お勧めにするには便利ではあり
ません。

4.6 キーワードの前の特別なコメント
==================================

   Cプログラム中の文字列は、しばしば‘printf’ファミリーと呼ばれる関数呼び
出しで使用されます。これらで使用される書式指定文字列に関して特筆すべきは
、‘%’で始まる書式指定子が含まれていることです。以下のようなコードがある
としましょう。

     printf (gettext ("String `%s' has %d characters\n"), s, strlen (s));

上記の文字列にたいして、以下のようなGermanの翻訳が考えられます:

     "%d Zeichen lang ist die Zeichenkette `%s'"

   Germanを話せないCプログラマーでも、まずい点があることに気がつくでしょ
う。文字列中の書式指定子の順序が変更されていますが、‘printf’の引数の順序
は変更されません。一番問題なのは、文字列のアドレスが期待されている箇所に
、文字列の長さが渡していることです。

   翻訳に起因する実行時のエラーを防ぐために、‘msgfmt’は翻訳前の文字列と
、翻訳後の文字列に含まれる引数のタイプと数を、静的にチェックすることがで
きます。このチェックを満足しないような場合、‘msgfmt’に‘-c’が指定されてい
ると、‘msgfmt’はエラーを発生させてMOファイルを生成しません。‘msgfmt -c’を
使用することにより、エラーを事前に検出して、実行時の問題を防ぐことができ
ます。

Germanの翻訳で上述の単語順が正しい場合は、以下のように記述する必要があり
ます

     "%2$d Zeichen lang ist die Zeichenkette `%1$s'"

‘msgfmt’ルーチンは、この特別な表記法を認識できます。

   プログラムのすべての文字列が書式文字列というわけではないので、‘.po’フ
ァイルの中のすべての文字列を‘msgfmt’がテストする必要はありません。また文
字列の中に書式指定子と似た文字列が含まれるが、その文字列が‘printf’で使わ
れる文字列ではないような場合は、問題が発生します。

   そのため‘xgettext’は、それらの書式文字列と思われるメッセージに特別な
タグを付与します。このタグ付けは絶対的なルールではなく、発見的なルールで
す。‘.po’ファイルの中のそれらのエントリーには、‘#,’によるコメント行で、
‘c-format’というフラグによりマークされます(see PO Filesを参照してく
ださい)。

   注意深い読者は、まだ問題があると気づくでしょう。発見されたものが間違
っている場合です。これは真実であり、そのために‘xgettext’は、プログラマー
が意志決定すべき特別な種類のコメントを認識することができるのです。
‘gettext’キーワードと同じ行、またはそれに続く行に‘xgettext:c-format’とい
う単語を含むコメントを発見すると、‘xgettext’はどのような場合であれ、文字
列を‘c-format’フラグでマークします。この種のコメントは、‘xgettext’が文字
列を書式文字列と認識しない場合(テストしてみて実際に認識されない場合)に使
う必要があります。‘gettext’キーワードと同じ行にコメントがある場合、翻訳
される前にコメントを挿入しなければならないことに注意してください。

   このような状況は頻繁に発生します。‘printf’関数にわたされる文字列に書
式指定子が含まれない場合もあります。そのようなケースでは通常、‘fputs’を
使用するのでしょうが、それでもこのような状況はあり得ます。このような場合
、‘xgettext’はそれを書式文字列として認識しませんが、翻訳に書式指定子とし
て認識されるような文字列が含まれていると何が起こるでしょうか?  ‘printf’関
数はパラメーターにアクセスしようとしますが、翻訳前の文字列には何も引数が
わたされないため、パラメーターは存在しません。

   もちろん他の原因により、‘xgettext’が間違って書式文字列ではない文字列
を、書式文字列と認識することがあります。このような場合、‘msgfmt’は多くの
警告を出力し、‘.po’ファイルへの変換は失敗します。このように間違って書式
文字列と認識されるのを防ぐには、上記と同様に‘xgettext:no-c-format’という
文字列を含むコメントを使用します。

   文字列が‘c-format’と間違ってマークされている場合、ユーザーは何が原因
なのか調べることができます。‘--debug’オプション使用して、どのように問題
を解決するかについては、see xgettext Invocationを参照してください。

4.7 翻訳可能文字列の特別なケース
================================

   注意深い読者なら、常に翻訳可能な文字列を‘gettext’(または同様のもの)で
マークすることはできないことに気づくでしょう。たとえば以下のようなケース
です:

     {
       static const char *messages[] = {
         "some very meaningful message",
         "and another one"
       };
       const char *string;
       ...
       string
         = index > 1 ? "a default message" : messages[index];

       fputs (string);
       ...
     }

   文字列‘"a default message"’にたいするマーク付けは問題ありませんが、配
列‘messages’を初期化する文字列はマークできません。どうすればよいのでしょ
うか? このような場合は2つのタスクを達成する必要があります。最初に
‘xgettext’プログラムが文字列を見つけ出せるように文字列をマークします
(see xgettext Invocationを参照してください)。次に実行時に文字列を出
力する前に、文字列を翻訳するのです。

   最初のタスクは、no-opという新しいキーワードを作ることにより達成できま
す。2番目のタスクは、配列の文字列にたいするすべてのアクセスポイントをマ
ークします。考えられる解決策の1つは、以下のようなものです:

     #define gettext_noop(String) String

     {
       static const char *messages[] = {
         gettext_noop ("some very meaningful message"),
         gettext_noop ("and another one")
       };
       const char *string;
       ...
       string
         = index > 1 ? gettext ("a default message") : gettext (messages[index]);

       fputs (string);
       ...
     }

   どのようなケースでも、‘fputs’に記述された文字列は翻訳されると思ってく
ださい。どのようにして‘xgettext’が、追加のキーワード‘gettext_noop’を認識
するかについては、see xgettext Invocationを参照してください。

   もちろん、これが唯一の解決策という訳ではありません。以下の方法のうち
のいずれかを使用することもできます:

     #define gettext_noop(String) String

     {
       static const char *messages[] = {
         gettext_noop ("some very meaningful message",
         gettext_noop ("and another one")
       };
       const char *string;
       ...
       string
         = index > 1 ? gettext_noop ("a default message") : messages[index];

       fputs (gettext (string));
       ...
     }

   しかしこの方法には欠点があります。プログラマーは文字列‘"a default
message"’にも‘gettext_noop’を使うよう留意する必要があります。‘gettext’を
使用することにより、予期しない結果となる場合もあります。

   利点の1つは、どのようなケースでも出力が翻訳されるようにするために、制
御フローを分析する必要がないことです。この分析は一般的に難しいものではあ
りませんが、これにあてはまらないような状況では、2番目の方法を使用するこ
ともできます。

4.8 翻訳バグの報告をユーザーに奨励する
======================================

   コードにはバグが付き物ですが、翻訳も同様です。ユーザーがそれらのバグ
を報告できるようにする必要があります。メンテナーが同時に翻訳者であるよう
な場合を除き、メンテナーが翻訳を変更することはないため、プログラマーやパ
ッケージのメンテナーに翻訳のバグを報告するのは得策ではありません。したが
って翻訳のバグは翻訳者に報告されなければなりません。

   ここで紹介する方法で組織化することにより、メンテナーが翻訳のバグ報告
をどこかへ転送したり、翻訳者や翻訳チームのアドレスのリストを維持する必要
もなくなります。

   すべてのプログラムには、バグを報告するためのアドレスを示す場所があり
ます。GNUプログラムの場合、“–help”オプションにより表示される、“usage”(使
用方法)とよばれる機能が該当する場所です。この場所に翻訳のバグ報告のため
のアドレスを追加するよう、翻訳者に示すのです。たとえば以下のようなコード
があるとします

     printf (_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);

   以下のように、翻訳者への指示を追加することができます：

     /* TRANSLATORS: The placeholder indicates the bug-reporting address
        for this package.  Please add _another line_ saying
        "Report translation bugs to <...>\n" with the address for translation
        bugs (typically your translation team's web or email address).  */
     printf (_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);

   これらは‘xgettext’により抽出され、以下のようなエントリーを含む.potフ
ァイルとなります:

     #. TRANSLATORS: The placeholder indicates the bug-reporting address
     #. for this package.  Please add _another line_ saying
     #. "Report translation bugs to <...>\n" with the address for translation
     #. bugs (typically your translation team's web or email address).
     #: src/hello.c:178
     #, c-format
     msgid "Report bugs to <%s>.\n"
     msgstr ""

4.9 翻訳にたいして正確な名前をマークする
========================================

   人や都市、場所の名前などは翻訳用にマークする必要があるでしょうか?
Latin文字で記述する言語(English、Spanish、French、German等)しか知らない
人は、“no”と言いたいでしょう。なぜなら通常は、それらの言語間で名前は変更
されないからです。しかし一般的には、ある文字体系から他の文字体系に変換す
るときには、音声表記や音訳により名前も変換されます。たとえばRussianや
Greekの名前は、Englishに変換されるときにLatinのアルファベットに変換され
、EnglishやFrenchがJapaneseに変換されるときはKatakana文字に変換されます
。対象となる言語を話す人たちは、一般的には翻訳前の文字で記述された元の名
前を読めないので、これらの変換が必要になります。

   それゆえプログラマーとしては、名前を翻訳用にマークするとともに、翻訳
者にたいしてそれが元の正確な名前であることと、どのように取り扱うかについ
ての特別なコメントを付与する必要があります。以下は簡単な例です:

     printf (_("Written by %s.\n"),
             /* TRANSLATORS: This is a proper name.  See the gettext
                manual, section Names.  Note this is actually a non-ASCII
                name: The first name is (with Unicode escapes)
                "Fran\u00e7ois" or (with HTML entities) "Fran&ccedil;ois".
                Pronunciation is like "fraa-swa pee-nar".  */
             _("Francois Pinard"));

GNU gnulibは、オリジナル名にカッコ内に翻訳された名前を自動的に追加する
‘propername’
(<http://www.gnu.org/software/gnulib/MODULES.html#module=propername>)と
いうモジュールを提供しています。これによりスクリプトを変更しなくてもよい
ような場合には、翻訳者がASCIIで記述できないような名前にたいして、適切な
非ASCII文字を入力するというタスクから開放されます。この、より快適な形式
は以下のようなものです:

     printf (_("Written by %s and %s.\n"),
             proper_name ("Ulrich Drepper"),
             /* TRANSLATORS: This is a proper name.  See the gettext
                manual, section Names.  Note this is actually a non-ASCII
                name: The first name is (with Unicode escapes)
                "Fran\u00e7ois" or (with HTML entities) "Fran&ccedil;ois".
                Pronunciation is like "fraa-swa pee-nar".  */
             proper_name_utf8 ("Francois Pinard", "Fran\303\247ois Pinard"));

元の名前を、(UnicodeエスケープやHTMLエンティティーとしてではなく)直接
Unicodeで記述して、IPA(International Phonetic Alphabet: 国際音標文字。
<http://www.wikipedia.org/wiki/International_Phonetic_Alphabet>)を参照し
てください)により発音を示すこともできます。

   翻訳者としては、名前を翻訳するときは注意深く行う必要があります。なぜ
なら名前がバラバラに翻訳されたり、間違って翻訳されることは、人を不快にさ
せるからです。

   あなたの言語がLatin文字を使用している場合、必要なのはその言語で普段使
用している文字で名前を再構築することだけです。これはc-cedilla文字を含む
翻訳を提供するような場合です。あなたの言語がLatin文字とは異なる文字を使
用していて、人がそれを通常Latin文字として読まれるようには話していない場
合、それは翻訳を意味しています。プログラマーが簡単な方法を使用している場
合でも、Latin文字を読む人のために、括弧付きで元の名前を記述する必要があ
ります。プログラマーが上述の‘propername’モジュールを使用している場合は、
元の名前を括弧付きで記述するのはプログラムが行うので、あなたが記述する必
要はありません。以下は対象言語がGreekの場合の例です:

     #. This is a proper name.  See the gettext
     #. manual, section Names.  Note this is actually a non-ASCII
     #. name: The first name is (with Unicode escapes)
     #. "Fran\u00e7ois" or (with HTML entities) "Fran&ccedil;ois".
     #. Pronunciation is like "fraa-swa pee-nar".
     msgid "Francois Pinard"
     msgstr "\phi\rho\alpha\sigma\omicron\alpha \pi\iota\nu\alpha\rho"
            " (Francois Pinard)"

   このように名前の翻訳は微妙な領域に属する話題なので、翻訳を提出する前
にテストすることをお勧めします。

4.10 ライブラリーソースの準備
=============================

   あなたがプログラムではなくライブラリーを作成する場合、‘gettext’の使用
方法にはわずかな違いしかありません。ここでは前提として、ライブラリーが自
分自身の翻訳ドメインとPOTファイルを持つとします(ライブラリーがメインプロ
グラムの翻訳ドメインとPOTファイルを使用する場合は、前のセクションを変更
なしに適用できます)。

  1. ライブラリーのコードでは、‘setlocale (LC_ALL, "")’を呼び出しません
     。localeのセットはメインプログラムの責任です。ライブラリーのドキュ
     メントにはこの事実を明記して、ライブラリーを使用するプログラム開発
     者が認識できるようにする必要があります。

  2. ライブラリーのコードでは、‘textdomain (PACKAGE)’を呼び出しません。
     text domainのセットはメインプログラムの責任です。

  3. プログラムのための初期化は以下のようなコードでした

            setlocale (LC_ALL, "");
            bindtextdomain (PACKAGE, LOCALEDIR);
            textdomain (PACKAGE);

     ライブラリーの場合は以下のコードだけになります

            bindtextdomain (PACKAGE, LOCALEDIR);

     ライブラリーのAPIにまだ初期化の関数が無いなら、‘bindtextdomain’呼び
     出しを含む初期化関数を作成する必要があります。しかし通常、この初期
     化関数をエクスポートしたりドキュメント化する必要はありません。初期
     化関数がまだ呼び出されていない場合は、ライブラリーのすべてのエント
     リーポイントとなる関数から初期化関数を呼び出すだけで十分です。これ
     を満足するような典型的な例は、初期化関数が呼び出し済みかどうかを保
     持するブール値の静的な変数を使用する方法です:

          static bool libfoo_initialized;

          static void
          libfoo_initialize (void)
          {
            bindtextdomain (PACKAGE, LOCALEDIR);
            libfoo_initialized = true;
          }

          /* This function is part of the exported API.  */
          struct foo *
          create_foo (...)
          {
            /* Must ensure the initialization is performed.  */
            if (!libfoo_initialized)
              libfoo_initialize ();
            ...
          }

          /* This function is part of the exported API.  The argument must be
             non-NULL and have been created through create_foo().  */
          int
          foo_refcount (struct foo *argument)
          {
            /* No need to invoke the initialization function here, because
               create_foo() must already have been called before.  */
            ...
          }

  4. プログラムでは通常、各ソースファイル中で、以下のように‘_’マクロを定
     義しました

          #include <libintl.h>
          #define _(String) gettext (String)

     自身の翻訳ドメインを持つライブラリーの場合は、以下のようになります:

          #include <libintl.h>
          #define _(String) dgettext (PACKAGE, String)

     別の言い方をすると、‘gettext’のかわりに‘dgettext’を使用するというこ
     とです。同様に、‘ngettext’が使用される箇所には、‘dngettext’を使用す
     る必要があります。

5 POテンプレートファイルのマーク
********************************

   ソースの準備ができたら、プログラマーはPOテンプレートファイルを作成し
ます。このセクションでは、その目的のために‘xgettext’をどのように使用する
かについて説明します。

   ‘xgettext’は、‘DOMAINNAME.po’という名前のファイルを作成します。あなた
はそれを‘DOMAINNAME.pot’という名前にリネームする必要があります
(‘xgettext’は、どうして直接‘DOMAINNAME.pot’を作成しないのでしょうか? こ
れは歴史的な理由からです。‘xgettext’が設計されたときはPOファイルとPOテン
プレートファイルの区別があいまいで、拡張子の‘.pot’も使用されていなかった
からです)。

5.1 ‘xgettext’プログラムの呼び出し
==================================

     xgettext [OPTION] [INPUTFILE] ...

   ‘xgettext’プログラムは、与えられた入力ファイルから、翻訳可能な文字列
を抽出します。

5.1.1 入力ファイルの位置
------------------------

‘INPUTFILE ...’
     入力ファイルを指定します。

‘-f FILE’
‘--files-from=FILE’
     入力ファイルの名前を、コマンドラインからではなく、FILEから読み込み
     ます。

‘-D DIRECTORY’
‘--directory=DIRECTORY’
     ディレクトリーのリストにDIRECTORYを追加します。このディレクトリーの
     リストからソースファイルを検索します。しかし‘.po’ファイルが出力され
     るのは、カレントディレクトリーです。

   INPUTFILEに‘-’が指定された場合は、標準入力から読み込みます。

5.1.2 出力ファイルの位置
------------------------

‘-d NAME’
‘--default-domain=NAME’
     出力ファイルとして、(‘messages.po’のかわりに)‘NAME.po’を使用します
     。

‘-o FILE’
‘--output=FILE’
     (‘NAME.po’や‘messages.po’ではなく)指定されたファイルに出力を書き込
     みます。

‘-p DIR’
‘--output-dir=DIR’
     ファイルはDIRに出力されます。

   出力のFILEに‘-’または‘/dev/stdout’が指定された場合、出力は標準出力に
書き込まれます。

5.1.3 入力ファイルの言語の選択
------------------------------

‘-L NAME’
‘--language=NAME’
     入力ファイルの言語を指定します。サポートされている言語は、‘C’、
     ‘C++’、‘ObjectiveC’、‘PO’、‘Shell’、‘Python’、‘Lisp’、‘EmacsLisp’、
     ‘librep’、‘Scheme’、‘Smalltalk’、‘Java’、‘JavaProperties’、‘C#’、
     ‘awk’、‘YCP’、‘Tcl’、‘Perl’、‘PHP’、‘GCC-source’、‘NXStringTable’、
     ‘RST’、‘Glade’、‘Lua’、‘JavaScript’、‘Vala’です。

‘-C’
‘--c++’
     ‘--language=C++’の省略指定です。

   デフォルトでは、入力ファイルの言語は拡張子により推測されます。

5.1.4 入力ファイルの解釈
------------------------

‘--from-code=NAME’
     入力ファイルのエンコーディングを指定します。このオプションはメッセ
     ージ文字列や、それらのコメントに非ASCII文字が含まれている場合のみ必
     要です。TclとGladeの入力ファイルは、このオプションの指定に関わらず
     、UTF-8が想定されることに注意してください。

   デフォルトでは、入力ファイルのエンコーディングはASCIIであると仮定され
ます。

5.1.5 オペレーションモード
--------------------------

‘-j’
‘--join-existing’
     既存のファイルのメッセージを結合します。

‘-x FILE’
‘--exclude-file=FILE’
     FILEのエントリーは抽出されません。FILEには、POファイルかPOTファイル
     を指定します。

‘-c[TAG]’
‘--add-comments[=TAG]’
     TAGで始まるコメントブロックを、出力ファイル中のキーワード行の前に配
     置します。このオプションでTAGを指定しない場合には、出力ファイル中の
     すべてのキーワード行の前にコメントブロックが配置されます。

5.1.6 言語特有のオプション
--------------------------

‘-a’
‘--extract-all’
     すべての文字列を抽出します。

     このオプションはほとんどの言語、すなわち、C、C++、Objective-C、
     Shell、Python、Lisp、EmacsLisp、librep、Java、C#、awk、Tcl、Perl、
     PHP、GCC-source、Glade、Lua、JavaScript、Valaに影響を与えます。

‘-k[KEYWORDSPEC]’
‘--keyword[=KEYWORDSPEC]’
     検索する追加のキーワードをKEYWORDSPECに指定します。KEYWORDSPECを指
     定しない場合には、デフォルトのキーワードを使用しないことを意味しま
     す。

     KEYWORDSPECとして指定されたIDがCのものだった場合、‘xgettext’は関数
     (またはマクロ)IDの各呼び出しの最初の引数から文字列を検索します。
     KEYWORDSPECが‘ID:ARGNUM’という形式で指定された場合、‘xgettext’は呼
     び出しのARGNUM番目の引数を探します。KEYWORDSPECが
     ‘ID:ARGNUM1,ARGNUM2’の形式で指定された場合、‘xgettext’は呼び出しの
     ARGNUM1番目とARGNUM2番目の引数から文字列を探して、複数形として処理
     すべきメッセージのsingular(単数形)とplural(複数形)として扱います。
     同様に、KEYWORDSPECが‘ID:CONTEXTARGNUMc,ARGNUM’や
     ‘ID:ARGNUM,CONTEXTARGNUMc’という形式で指定された場合、‘xgettext’は
     CONTEXTARGNUM番目の引数の文字列をコンテキスト指定子(context
     specifier)として扱います。そして GNOME のための特別なサポートとして
     、keywordspecが‘id:argnumg’という形式で指定された場合、xgettextは
     argnum番目の引数がcontextを伴う文字列と認識して、GNOME glibの
     ‘"msgctxt|msgid"’という構文を使用します。そしてGNOMEのための特別な
     サポートとして、KEYWORDSPECが‘ID:ARGNUMg’という形式で指定された場合
     、‘xgettext’はARGNUM番目の引数がcontextを伴う文字列と認識して、
     GNOME ‘glib’の‘"msgctxt|msgid"’という構文を使用します。
     またKEYWORDSPECが‘ID:...,TOTALNUMARGSt’という形式で指定された場合、
     ‘xgettext’は実際の引数の数がTOTALNUMARGSと等しい場合のみ、この引数
     指定を処理します。これはC++でのオーバーロードされた関数の呼び出しな
     どで便利です。
     最後に、もしKEYWORDSPECが‘ID:ARGNUM...,"XCOMMENT"’という形式で指定
     された場合、‘xgettext’は指定された引数から文字列を抽出するときに、
     追加のコメントとしてXCOMMENTをメッセージに追加します。通常のシェル
     のコマンドラインから使用する場合は、XCOMMENTを括るダブルクォーテー
     ションはエスケープする必要があることに注意してください。

     このオプションはほとんどの言語、すなわち、C、C++、Objective-C、
     Shell、Python、Lisp、EmacsLisp、librep、Java、C#、awk、Tcl、Perl、
     PHP、GCC-source、Glade、Lua、JavaScript、Valaに影響を与えます。

     明示的に無効化されていない限り、常に検索されるデフォルトキーワード
     の指定は、言語に依存します:

        • C、C++、GCC-sourceの場合: ‘gettext’、‘dgettext:2’、
          ‘dcgettext:2’、‘ngettext:1,2’、‘dngettext:2,3’、
          ‘dcngettext:2,3’、‘gettext_noop’、そして‘pgettext:1c,2’、
          ‘dpgettext:2c,3’、‘dcpgettext:2c,3’、‘npgettext:1c,2,3’、
          ‘dnpgettext:2c,3,4’、‘dcnpgettext:2c,3,4’。

        • Objective C: Cと同様です。‘NSLocalizedString’、‘_’、
          ‘NSLocalizedStaticString’、‘__’も該当します。

        • shellスクリプトの場合: ‘gettext’、‘ngettext:1,2’、
          ‘eval_gettext’、‘eval_ngettext:1,2’。

        • Pythonの場合: ‘gettext’、‘ugettext’、‘dgettext:2’、
          ‘ngettext:1,2’、‘ungettext:1,2’、‘dngettext:2,3’、‘_’。

        • Lispの場合: ‘gettext’、‘ngettext:1,2’、‘gettext-noop’。

        • EmacsLispの場合: ‘_’。

        • librepの場合: ‘_’。

        • Schemeの場合: ‘gettext’、‘ngettext:1,2’、‘gettext-noop’。

        • Javaの場合: ‘GettextResource.gettext:2’、
          ‘GettextResource.ngettext:2,3’、
          ‘GettextResource.pgettext:2c,3’、
          ‘GettextResource.npgettext:2c,3,4’、‘gettext’、
          ‘ngettext:1,2’、‘pgettext:1c,2’、‘npgettext:1c,2,3’、
          ‘getString’。

        • C#の場合: ‘GetString’、‘GetPluralString:1,2’、
          ‘GetParticularString:1c,2’、
          ‘GetParticularPluralString:1c,2,3’。

        • awkの場合: ‘dcgettext’、‘dcngettext:1,2’。

        • Tclの場合: ‘::msgcat::mc’。

        • Perlの場合: ‘gettext’、‘%gettext’、‘$gettext’、‘dgettext:2’、
          ‘dcgettext:2’、‘ngettext:1,2’、‘dngettext:2,3’、
          ‘dcngettext:2,3’、‘gettext_noop’。

        • PHPの場合: ‘_’、‘gettext’、‘dgettext:2’、‘dcgettext:2’、
          ‘ngettext:1,2’、‘dngettext:2,3’、‘dcngettext:2,3’。

        • Glade 1の場合: ‘label’、‘title’、‘text’、‘format’、
          ‘copyright’、‘comments’、‘preview_text’、‘tooltip’。

        • Luaの場合: ‘_’、‘gettext.gettext’、‘gettext.dgettext:2’、
          ‘gettext.dcgettext:2’、‘gettext.ngettext:1,2’、
          ‘gettext.dngettext:2,3’、‘gettext.dcngettext:2,3’。

        • JavaScriptの場合: ‘_’、‘gettext’、‘dgettext:2’、
          ‘dcgettext:2’、‘ngettext:1,2’、‘dngettext:2,3’、
          ‘pgettext:1c,2’、‘dpgettext:2c,3’。

        • Valaの場合: ‘_’、‘Q_’、‘N_’、‘NC_’、‘dgettext:2’、
          ‘dcgettext:2’、‘ngettext:1,2’、‘dngettext:2,3’、
          ‘dpgettext:2c,3’、‘dpgettext2:2c,3’。

     デフォルトキーワードの指定は、‘-k’オプション、‘--keyword’を指定する
     か、KEYWORDSPECを指定せずに‘--keyword=’として無効にすることができま
     す。

‘--flag=WORD:ARG:FLAG’
     関数WORDの、ARG番目の引数の一部となるような文字列のための、追加のフ
     ラグを指定します。‘c-format’や、それの反対の‘no-c-format’のような、
     利用可能な書式文字列を示すフラグを利用でき、‘pass-’を前置して指定す
     ることもできます。
     ‘--flag=FUNCTION:ARG:LANG-format’は、言語LANGの関数FUNCTIONのARG番
     目の引数を書式文字列とみなすという意味です(GCC関数の属性に慣れてい
     る人は、‘--flag=FUNCTION:ARG:c-format’が、Cソース中の関数 FUNCTIONに
     付記される‘__attribute__ ((__format__ (__printf__, ARG, ...)))’宣言
     と同様だと思えばよいでしょう)。たとえばGNU libcから、関数‘error’を
     使用する場合、それの振る舞いについて‘--flag=error:3:c-format’のよう
     に指定することができます。この指定により‘xgettext’は、すべての
     ‘gettext’呼び出しのFUNCTIONのARG番目の引数に出現する文字列を、書式
     指定文字列としてマークします。これは書式指定子が含まれていないよう
     な文字列にたいして‘msgfmt -c’によりチェックを行う場合に便利です。こ
     れにより翻訳者が実行時のクラッシュを引き起こすような書式指定子を意
     図せずに使ってしまうことを防ぐことができます。
     ‘--flag=FUNCTION:ARG:pass-LANG-format’は、言語LANGにおいて、書式文
     字列が出現しなければいけない位置にFUNCTION呼び出しがある場合、その
     関数のARG番目の引数には、同じタイプの書式文字列となければならないと
     いう意味です。(GCC関数の属性を知っている人は、
     ‘--flag=FUNCTION:ARG:pass-c-format’が、Cソース中の関数FUNCTIONに付
     記される‘__attribute__ ((__format_arg__ (ARG)))’宣言と同様だと思え
     ばよいでしょう)。たとえば‘gettext’関数の略記である‘_’を使用している
     場合は、‘--flag=_:1:pass-c-format’を使う必要があります。この指定に
     より‘xgettext’は、‘_("string")’呼び出しの最初の引数‘"string"’には書
     式指定文字列が必要だと伝えるために、その文字列を書式指定文字列とし
     てマークします。これは書式指定子が含まれていないような文字列にたい
     して‘msgfmt -c’によりチェックを行う場合に便利です。これにより翻訳者
     が実行時のクラッシュを引き起こすような書式指定子を意図せずに使って
     しまうことを防ぐことができます。
     このオプションは、C、C++、ObjectiveC、Shell、Python、Lisp、
     EmacsLisp、librep、Scheme、Java、C#、awk、YCP、Tcl、Perl、PHP、
     GCC-source、Lua、JavaScript、Vala(つまり、ほとんどの言語)に影響を与
     えます。

‘-T’
‘--trigraphs’
     入力におけるANSI Cの三連表記(trigraph)を理解します。
     このオプションは言語がC、C++、ObjectiveCの場合のみ効果があります。

‘--qt’
     Qtの書式指定文字列を認識します。
     このオプションは言語がC++の場合のみ効果があります。

‘--kde’
     KDE 4の書式指定文字列を認識します。
     このオプションは言語がC++の場合のみ効果があります。

‘--boost’
     Boostの書式指定文字列を認識します。
     このオプションは言語がC++の場合のみ効果があります。

‘--debug’
     メッセージ中の書式指定文字列を、‘c-format’や‘possible-c-format’フラ
     グでマークすることにより、誰がマークしたかを表示します。後者の形式
     は、‘xgettext’が決定したときに使用され、前者はプログラマーが決定し
     たときに使用されます。

     デフォルトでは‘c-format’形式だけが使用されます。翻訳者はそれらの詳
     細について気にする必要はありません。

   この‘xgettext’の実装は、プリプロセッサーのマクロの中の文字列や、
ANSIによる隣接した文字列の結合、エスケープ文字による行の継続等の厄介なケ
ースを処理することができます。

5.1.7 出力の詳細
----------------

‘--color’
‘--color=WHEN’
     色や色以外のテキスト属性を使うか、いつ使うかを指定します。詳細は
     The --color optionを参照してください。

‘--style=STYLE_FILE’
     ‘--color’にたいしてCSS style ruleファイルを使うかを指定します。詳細
     はThe --style optionを参照してください。

‘--force-po’
     何もメッセージが定義されていない場合でも、常に出力ファイルに書き込
     みます。

‘-i’
‘--indent’
     インデントされた形式で.poファイルを書き込みます。

‘--no-location’
     ‘#: FILENAME:LINE’のような行を書き込みません。このオプションを使用
     することにより、熟練した翻訳者が、どのようなコンテキストでメッセー
     ジが使用されるのかを理解するのが困難になることに注意してください。

‘-n’
‘--add-location’
     ‘#: FILENAME:LINE’という行を生成します(デフォルト)。

‘--strict’
     Uniforumに厳密に準拠したPOファイルを出力します。このUniforum形式は
     GNUの拡張をサポートしないため避けたほうがよいでしょう。

‘--properties-output’
     Javaの‘.properties’の書式で、Java ResourceBundleを出力します。この
     ファイル形式はplural formをサポートせず、廃止されたメッセージを暗黙
     で除去することに注意してください。

‘--stringtable-output’
     ‘.strings’の書式で、NeXTstep/GNUstepのローカライズされたリソースフ
     ァイルを出力します。このファイル形式はplural formをサポートしないこ
     とに注意してください。

‘-w NUMBER’
‘--width=NUMBER’
     出力ページの幅をセットします。これにより出力ファイル中の長い文字列
     が指定した幅(例:スクリーンの列数)に収まるように、各行の長さが
     NUMBER以下のような複数の行に分割されます。

‘--no-wrap’
     長いメッセージ行を分割しません。出力ページの幅を超えるようなメッセ
     ージ行も、複数行に分割されません。出力ページの幅を超えるファイル参
     照行だけが分割されます。

‘-s’
‘--sort-output’
     ソートされた出力を生成します。このオプションを使用することにより翻
     訳者が、メッセージがどのようなコンテキストで使用されるかを理解する
     のが、困難になることに注意してください。

‘-F’
‘--sort-by-file’
     ファイルの場所により出力をソートします。

‘--omit-header’
     ‘msgid ""’というエントリーにたいして、ヘッダーを書き込みません。

     これはソースファイルの変更をテストする等の目的で、‘.gmo’ファイルを
     生成するときに便利です。‘--omit-header’を使用すると、同じファイルに
     たいして、同じオプションで‘xgettext’を実行すれば、実行した時が異な
     っていても同じ結果を得ることができます。

     このオプションをASCII以外の文字が含まれたファイルにたいして使用した
     場合、エラーとなることに注意してください。

‘--copyright-holder=STRING’
     出力に著作権所有者(copyright holder)をセットします。STRINGにはパッ
     ケージの著作権所有者を指定する必要があります(パッケージのソースから
     抽出されたmsgstr文字列の著作権は、パッケージの著作権所有者に帰属す
     ることに注意してください)。翻訳者は、翻訳物の著作権を譲渡、もしくは
     放棄することが望まれます。これによりパッケージのメンテナーは法的な
     リスクなしでそれらを配布できるのです。STRINGが空の場合、出力ファイ
     ルはパブリックドメインに属するとマークされます。この場合も翻訳者は
     著作権を譲渡、もしくは放棄することが望まれます。繰り返しになります
     が、そうすることによりパッケージのメンテナーは法的なリスクなしでそ
     れらを配布できるのです。

     STRINGのデフォルト値はFree Software Foundation, Inc.です。これは単
     に‘xgettext’が最初に使用されたのが GNU プロジェクトであることが理由
     です。

‘--foreign-user’
     出力からFSFの著作権を省略します。これは‘--copyright-holder=''’とす
     るのと同じです。これはGNUプロジェクト以外で、翻訳物をパブリックドメ
     インにしたいときに便利です。

‘--package-name=PACKAGE’
     出力のヘッダーに、パッケージ名をセットします。

‘--package-version=VERSION’
     出力のヘッダーにパッケージのバージョンをセットします。このオプショ
     ンは、同時に‘--package-name’を指定したときだけ効果があります。

‘--msgid-bugs-address=EMAIL@ADDRESS’
     msgidに関するバグの報告先アドレスをセットします。このアドレスは、翻
     訳者が未翻訳文字列のバグを報告するための電子メールのアドレス、また
     はURLです。

        - センテンス全体となっていないような文字列。メンテナーのためのガ
          イドライン Preparing Stringsを参照してください。
        - 不明な用語を使用したり、追加のコンテキストを理解することが必要
          とする文字列 。
        - 日付・時刻・通貨の表記で、無効な仮定をしている文字列 。
        - plural化に関する問題。
        - 間違ったEnglishのスペル。
        - 間違った書式。

     このアドレスは、あなたのメールアドレスでも構いませんし、翻訳者が登
     録しなくても投稿できるメーリングリストのアドレスや、翻訳者があなた
     に連絡をとることができるウェブページのアドレスにすることもできます
     。

     デフォルトは空文字列が設定されており、これは翻訳者にはこれらの情報
     が分からないことを意味します! このオプションを指定するのを忘れない
     でください。

‘-m[STRING]’
‘--msgstr-prefix[=STRING]’
     msgstrの値に前置する文字列としてSTRING(指定されていない場合は"")を
     使用します。

‘-M[STRING]’
‘--msgstr-suffix[=STRING]’
     msgstrの値に後置する文字列としてSTRING(指定されていない場合は"")を
     使用します。

5.1.8 情報的な出力
------------------

‘-h’
‘--help’
     このヘルプを表示して終了します。

‘-V’
‘--version’
     バージョン情報を表示して終了します。

6 新しいPOファイルの作成
************************

   新しい翻訳を開始する場合、翻訳者は‘PACKAGE.pot’の初期コメント(ファイ
ルの先頭にあります)とヘッダーのエントリー(最初のエントリーで、これもファ
イルの先頭付近にあります)に変更を加えたものをコピーして、‘LANG.po’を作成
します。

   これを行う一番簡単な方法は、‘msginit’を使うことです:

     $ cd PACKAGE-VERSION
     $ cd po
     $ msginit

   かわりにコピーしてから手で変更する方法もあります。この場合、翻訳者は
‘PACKAGE.pot’を‘LANG.po’というファイル名でコピーしてから、ファイル内の初
期コメントとヘッダーエントリーを修正します。

6.1 ‘msginit’プログラムの呼び出し
=================================

     msginit [OPTION]

   ‘msginit’プログラムは、新しいPOファイルを作成して、メタ情報をユーザー
の環境にもとづいて初期化します。

6.1.1 入力ファイルの位置
------------------------

‘-i INPUTFILE’
‘--input=INPUTFILE’
     入力となるPOTファイルです。

   INPUTFILEが指定されなかった場合、カレントディレクトリからPOTファイル
を検索します。‘-’を指定すると、標準入力から読み込みます。

6.1.2 出力ファイルの位置
------------------------

‘-o FILE’
‘--output-file=FILE’
     指定されたPOファイルに出力を書き込みます。

   出力ファイルが指定されなかった場合は、ユーザーのロケール設定の
‘--locale’オプションに依存します。‘-’を指定すると、出力は標準出力に書き
込まれます。

6.1.3 入力ファイルの構文
------------------------

‘-P’
‘--properties-input’
     入力ファイルがPOファイルの構文ではなく、Javaの‘.properties’の構文に
     のっとったJava ResourceBundleファイルだとみなします。

‘--stringtable-input’
     入力ファイルがPOファイルの構文ではなく、NeXTstep/GNUstepのlocalized
     resourceの‘.strings’の構文にのっとったファイルだとみなします。

6.1.4 出力の詳細
----------------

‘-l LL_CC’
‘--locale=LL_CC’
     対象のlocaleを設定します。LLにはlanguage codeを、CCにはcountry
     codeを設定する必要があります。インストールされているすべての
     localeのリストを出力するには、‘locale -a’コマンドを使用できます。デ
     フォルトはユーザーのlocale設定が使用されます。

‘--no-translator’
     POファイルが翻訳者の手で作成されたものではなく、自動的に生成された
     ものであることを宣言します。

‘--color’
‘--color=WHEN’
     色や色以外のテキスト属性を使うか、いつ使うかを指定します。詳細は
     The --color optionを参照してください。

‘--style=STYLE_FILE’
     ‘--color’にたいしてCSS style ruleファイルを使うかを指定します。詳細
     はThe --style optionを参照してください。

‘-p’
‘--properties-output’
     Javaの‘.properties’の書式で、Java ResourceBundleを出力します。この
     ファイル形式はplural formをサポートせず、廃止されたメッセージを暗黙
     で除去することに注意してください。

‘--stringtable-output’
     ‘.strings’の書式で、NeXTstep/GNUstepのローカライズされたリソースフ
     ァイルを出力します。このファイル形式はplural formをサポートしないこ
     とに注意してください。

‘-w NUMBER’
‘--width=NUMBER’
     出力ページの幅をセットします。これにより出力ファイル中の長い文字列
     が指定した幅(例:スクリーンの列数)に収まるように、各行の長さが
     NUMBER以下のような複数の行に分割されます。

‘--no-wrap’
     長いメッセージ行を分割しません。出力ページの幅を超えるようなメッセ
     ージ行も、複数行に分割されません。出力ページの幅を超えるファイル参
     照行だけが分割されます。

6.1.5 情報的な出力
------------------

‘-h’
‘--help’
     このヘルプを表示して終了します。

‘-V’
‘--version’
     バージョン情報を表示して終了します。

6.2 ヘッダーエントリーを入力する
================================

   新規作成したときに初期値として入力されている、"SOME DESCRIPTIVE
TITLE"、"YEAR"、および"FIRST AUTHOR <EMAIL@ADDRESS>、YEAR"などのコメント
は、意味のある情報に書き換えるべきです。これはテキストエディターにより行
うこともできますが、Emacsを使っていれば(拡張子を識別して)自動的にPOモー
ドに切り替わります。これは‘M-x fundamental-mode’と入力して無効にすること
ができます。

   ヘッダーのエントリーの変更も、POモードで行うことができます。Emacsで、
‘M-x po-mode RET’と入力して、さらに‘RET’を押すと、エントリーの編集が開始
できるので、以下のフィールドに入力してください。

Project-Id-Version
     パッケージの名前とバージョンです。‘xgettext’により入力されていない
     場合は入力してください。

Report-Msgid-Bugs-To
     これは‘xgettext’によってすでに入力されています。未翻訳の文字列に関
     するバグを報告するための、電子メールアドレスかURLが含まれています:

        - センテンス全体となっていないような文字列。メンテナーのためのガ
          イドライン Preparing Stringsを参照してください。
        - 不明な用語を使用したり、追加のコンテキストを理解することが必要
          とする文字列 。
        - 日付・時刻・通貨の表記で、無効な仮定をしている文字列 。
        - plural化に関する問題。
        - 間違ったEnglishのスペル。
        - 間違った書式。

POT-Creation-Date
     これは‘xgettext’によってすでに入力されています。

PO-Revision-Date
     これはPOファイルのためのエディターが、ファイルを保存するときに入力
     される項目なので、あなたは入力する必要はありません。

Last-Translator
     名前と電子メールアドレス（ダブルクォーテーションなし）を入力してく
     ださい。

Language-Team
     言語の英語名と、あなたが所属するlanguage teamの電子メールアドレスか
     、ホームページのURLを入力してください。

     重複して作業するの防ぐためだけではなく、言語に関する難しい問題を調
     整するためにも、翻訳を開始する前にtranslation teamに連絡することを
     お勧めします。

     フリーな翻訳プロジェクトでは、それぞれの翻訳チームが、チーム自身の
     メーリングリストを持っています。チームの最新のメーリングリスト一覧
     は、Free Translation Projectのホームページ
     (<http://translationproject.org/>) の"Teams"という場所にあります。

Language
     あなたの言語の言語コードを入力してください。以下の3つの形式のいずれ
     かになります:

        - ‘LL’: ISO 639の2文字(小文字)の言語コードです。コードの一覧は
          Language Codesを参照してください。

        - ‘LL_CC’: ‘LL’はISO 639の2文字(小文字)のlanguage code、‘CC’は
          ISO 3166の2文字(大文字)のcountry codeです。いくつかの
          languageは、異なるcountryで使用される方言を持っていますが、
          country codeの仕様に冗長性はありません。たとえば‘de_AT’は
          Austriaで使用され、‘pt_BR’はBrazilで使用されます。country
          codeは方言を区別するために提供されています。コードの一覧につい
          てはLanguage CodesとCountry Codesを参照してく
          ださい。

        - ‘LL_CC@VARIANT’: ‘LL’はISO 639の2文字(小文字)のlanguage code、
          ‘CC’はISO 3166の2文字(大文字)のcountry code、‘VARIANT’は
          variant designatorです。variant designator(小文字)には、
          ‘latin’や‘cyrillic’のようなscript designatorを指定することもで
          きます。

     ‘LL_CC’の命名規則は、システムがGNU libcにもとづいてlocale名を決定す
     る方法でもありますが、重要な違いが3つあります。

        • POファイルのこの項目はlocale名とは異なり、‘LL_CC’という組み合
          わせは、languageの主たる方言であることを示す‘LL’という略記であ
          らわされます。たとえば、このコンテキストでは‘de’は
          ‘de_DE’(Germanyで話されるGerman) と等しく、‘pt’は
          ‘pt_PT’(Portugalで話されるPortuguese)と同じです。

        • POファイルのこの項目では、‘.ENCODING’のような接尾辞は使用しま
          せん。

        • POファイルのこの項目では、メッセージの翻訳とは関係のない、
          ‘@euro’のようなvariant designatorは使用しません。

     そのため、あなたのlocale名が‘de_DE.UTF-8’の場合、POファイルの
     language specificationは‘de’だけになります。

Content-Type
     ‘CHARSET’を、あなたのlocaleのlanguageで使用するcharacter encodingか
     UTF-8で置き換えてください。この項目は、‘msgmerge’と‘msgfmt’の正しい
     動作のために必要です。同様にlocaleのcharacter encodingが、あなたの
     ものとは異なるユーザーにとっても必要です(see Charset conversion
     を参照してください)。

     localeのcharacter encodingは、シェルのコマンド‘locale charmap’を実
     行して得ることができます。このコマンドの結果が‘C’や
     ‘ANSI_X3.4-1968’の場合のcharacter encodingは‘ASCII’(=‘US-ASCII’) と
     なり、これはあなたのlocaleが正しく設定されていないことを意味します
     。そのような場合は、あなたの属するtranslation teamに、どのcharset を
     使用すればよいのか尋ねてください。‘ASCII’は、Latin 以外の language
     には適用できません。

     POファイルは、オペレーティングシステムの高度なインターナショナリゼ
     ーションの利便性に依存せずに可搬性を持たなければならないため、使用
     できるcharacter encodingsは GNU ‘libc’と GNU ‘libiconv’でサポートさ
     れるものに限定されています。使用できるcharacter encodingは‘ASCII’、
     ‘ISO-8859-1’、‘ISO-8859-2’、‘ISO-8859-3’、‘ISO-8859-4’、
     ‘ISO-8859-5’、‘ISO-8859-6’、‘ISO-8859-7’、‘ISO-8859-8’、
     ‘ISO-8859-9’、‘ISO-8859-13’、‘ISO-8859-14’、‘ISO-8859-15’、
     ‘KOI8-R’、‘KOI8-U’、‘KOI8-T’、‘CP850’、‘CP866’、‘CP874’、‘CP932’、
     ‘CP949’、‘CP950’、‘CP1250’、‘CP1251’、‘CP1252’、‘CP1253’、
     ‘CP1254’、‘CP1255’、‘CP1256’、‘CP1257’、‘GB2312’、‘EUC-JP’、
     ‘EUC-KR’、‘EUC-TW’、‘BIG5’、‘BIG5-HKSCS’、‘GBK’、‘GB18030’、
     ‘SHIFT_JIS’、‘JOHAB’、‘TIS-620’、‘VISCII’、‘GEORGIAN-PS’、‘UTF-8’で
     す。

     GNUシステムでは、対応する言語にたいして以下のエンコーディングが頻繁
     に使用されます。

        • ‘ISO-8859-1’: Afrikaans、Albanian、Basque、Breton、Catalan、
          Cornish、Danish、Dutch、English、Estonian、Faroese、Finnish、
          French、Galician、German、Greenlandic、Icelandic、Indonesian、
          Irish、Italian、Malay、Manx、Norwegian、Occitan、Portuguese、
          Spanish、Swedish、Tagalog、Uzbek、Walloon
        • ‘ISO-8859-2’: Bosnian、Croatian、Czech、Hungarian、Polish、
          Romanian、Serbian、Slovak、Slovenian
        • ‘ISO-8859-3’: Maltese
        • ‘ISO-8859-5’: Macedonian、Serbian
        • ‘ISO-8859-6’: Arabic
        • ‘ISO-8859-7’: Greek
        • ‘ISO-8859-8’: Hebrew
        • ‘ISO-8859-9’: Turkish
        • ‘ISO-8859-13’: Latvian、Lithuanian、Maori
        • ‘ISO-8859-14’: Welsh
        • ‘ISO-8859-15’: Basque、Catalan、Dutch、English、Finnish、
          French、Galician、German、Irish、Italian、Portuguese、
          Spanish、Swedish、Walloon
        • ‘KOI8-R’: Russian
        • ‘KOI8-U’: Ukrainian
        • ‘KOI8-T’: Tajik
        • ‘CP1251’: Bulgarian、Belarusian
        • ‘GB2312’、‘GBK’、‘GB18030’: Chineseの簡略表記
        • ‘BIG5’、‘BIG5-HKSCS’: Chineseの伝統的表記
        • ‘EUC-JP’: Japanese
        • ‘EUC-KR’: Korean
        • ‘TIS-620’: Thai
        • ‘GEORGIAN-PS’: Georgian
        • ‘UTF-8’: 上記の言語を含む任意の言語

     あなたの言語の翻訳に、その言語の1重引用符か2重引用符が使用されてお
     り、そのlocaleのencodingが ISO-8859-* のいずれかの場合は、POファイ
     ルはlocaleのencodingではなくUTF-8 encodingで作成するのが最善です。
     これはUTF-8では、ISO-8859-*が持っていない実際の引用文字(1重引用符は
     U+2018とU+2019、2重引用符はU+201CとU+201D)が表現可能だからです。
     UTF-8のlocale のユーザーは実際の引用符文字列を見ることができますが
     、ISO-8859-*のlocaleでは垂直方向のアポストロフィーと垂直方向のダブ
     ルクォーテーションが(文字セットの変換により)代用で表示されます。

     X11でこれらの引用文字を入力するために、xmodmapプログラムでキーボー
     ドのマッピングを使用することができます。この場合、X11 での引用文字
     の名前は"leftsinglequotemark"、"rightsinglequotemark"、
     "leftdoublequotemark"、"rightdoublequotemark"、
     "singlelowquotemark"、"doublelowquotemark"になります。

     UTF-8 encodingは、新しいバージョンのGNU Emacsでだけサポートされてい
     ることに注意してください。たとえばEmacs 20 with Mule-UCSやEmacs 21で
     はUTF-8 encodingがサポートされていますが、2001年1月時点のXEmacsでは
     サポートされていません。

     文字のエンコーディング名は、大文字または小文字で記述することができ
     ますが、通常は大文字が好まれます。

Content-Transfer-Encoding
     ‘8bit’にセットしてください。

Plural-Forms
     このフィールドはオプションで、POファイルにplural formがあるときだけ
     必要です。これは‘msgid_plural’というキーワードを検索すればわかりま
     す。plural formのフィールドの書式についてはPlural formsと
     Translating plural formsを参照してください。

7 既存のPOファイルの更新
************************

7.1 ‘msgmerge’プログラムの呼び出し
==================================

     msgmerge [OPTION] DEF.po REF.pot

   ‘msgmerge’プログラムは、Uniforumスタイルの2つの.poファイルをマージし
て1つにします。DEF.poファイルは既存のPOファイルで、メッセージが一致して
いれば既存の翻訳は新しいファイルに引き継がれます。その際、コメントは残さ
れますが、抽出されたコメントやファイル内の位置などは破棄されます。
REF.potは、最新のソースより作られたPOファイルですが、古い翻訳や、(通常は
‘xgettext’により作成された)PO Templateファイルを参照するため、ドットコメ
ント(訳注:プログラマーから翻訳者へのコメント#.のこと)やファイル内の位置
情報は保存されますが、ファイル内のいくつかの翻訳やコメントは、破棄される
でしょう。完全に一致するメッセージが見つからない場合、より良い結果を生成
するためにfuzzy一致が使用されます。

7.1.1 入力ファイルの位置
------------------------

‘DEF.po’
     古いソースを参照する翻訳です。

‘REF.pot’
     新しいソースへの参照です。

‘-D DIRECTORY’
‘--directory=DIRECTORY’
     ディレクトリーのリストにDIRECTORYを追加します。このディレクトリーの
     リストよりソースファイルを検索します。しかし‘.po’ファイルが出力され
     るのは、カレントディレクトリーです。

‘-C FILE’
‘--compendium=FILE’
     メッセージを翻訳するための追加のライブラリーを指定します。
     Compendiumを参照してください。このオプションは複数指定することが
     できます。

7.1.2 オペレーションモード
--------------------------

‘-U’
‘--update’
     DEF.poファイルを更新します。すでにDEF.poが最新の場合は何もしません
     。

7.1.3 出力ファイルの位置
------------------------

‘-o FILE’
‘--output-file=FILE’
     指定されたファイルに出力を書き込みます。

   出力ファイルが指定されていない、または‘-’が指定された場合、結果は標準
出力に出力されます。

7.1.4 更新モードでの出力ファイルの位置
--------------------------------------

   処理結果はDEF.poファイルに書き戻されます。

‘--backup=CONTROL’
     DEF.poのバックアップを作成します。

‘--suffix=SUFFIX’
     通常使用されるバックアップの接尾辞を上書きします。

   ‘--backup’オプション、もしくは環境変数‘VERSION_CONTROL’を通じてバージ
ョン管理の方式を選択します。以下の値が指定できます:

‘none’
‘off’
     (‘--backup’オプションが指定されていたとしても)バックアップを作成し
     ません。

‘numbered’
‘t’
     番号付きのバックアップを作成します。

‘existing’
‘nil’
     このファイルの番号付きのバックアップがすでに存在する場合、番号付き
     バックアップを作成し、そうでなければ単純なバックアップを作成します
     。

‘simple’
‘never’
     常に単純なバックアップを作成します。

   ‘--suffix’または環境変数‘SIMPLE_BACKUP_SUFFIX’が設定されていない場合
は、バックアップの接尾辞として‘~’を使用します。

7.1.5 オペレーションの修飾
--------------------------

‘-m’
‘--multi-domain’
     DEF.po内の各ドメインにたいして、REF.potを適用します。

‘-N’
‘--no-fuzzy-matching’
     完全に一致するものが見つからない場合、fuzzyマッチングを行いません。
     これにより処理のスピードが大幅に改善されます。

‘--previous’
     翻訳されたメッセージをもつ古いmsgidにたいしてfuzzyマーカーを追加す
     るときに、‘#|’マークをつけて古いメッセージを保持します。

7.1.6 入力ファイルの構文
------------------------

‘-P’
‘--properties-input’
     入力ファイルがPOファイルの構文ではなく、Javaの‘.properties’の構文に
     のっとったJava ResourceBundleファイルだとみなします。

‘--stringtable-input’
     入力ファイルがPOファイルの構文ではなく、NeXTstep/GNUstepのlocalized
     resourceの‘.strings’の構文にのっとったファイルだとみなします。

7.1.7 出力の詳細
----------------

‘--lang=CATALOGNAME’
     ヘッダーのエントリーで使用される‘Language’フィールドを指定します。
     このフィールドの意味についてはHeader Entryを参照してくださ
     い。‘Language-Team’と‘Plural-Forms’のフィールドは変更されないことに
     注意してください。このオプションを指定しない場合、‘Language-Team’フ
     ィールドから最適なものを推測して、‘Language’フィールドに入力します
     。

‘--color’
‘--color=WHEN’
     色や色以外のテキスト属性を使うか、いつ使うかを指定します。詳細は
     The --color optionを参照してください。

‘--style=STYLE_FILE’
     ‘--color’にたいしてCSS style ruleファイルを使うかを指定します。詳細
     はThe --style optionを参照してください。

‘--force-po’
     メッセージが何も含まれていない場合でも、常に出力ファイルに書き込み
     ます。

‘-i’
‘--indent’
     インデントされた形式で.poファイルを書き込みます。

‘--no-location’
     ‘#: FILENAME:LINE’という行を書き込みません。

‘--add-location’
     ‘#: FILENAME:LINE’という行を生成します(デフォルト)。

‘--strict’
     Uniforumに厳密に準拠したPOファイルを出力します。このUniforum形式は
     GNUの拡張をサポートしないため避けたほうがよいでしょう。

‘-p’
‘--properties-output’
     Javaの‘.properties’の書式で、Java ResourceBundleを出力します。この
     ファイル形式はplural formをサポートせず、廃止されたメッセージを暗黙
     で除去することに注意してください。

‘--stringtable-output’
     ‘.strings’の書式で、NeXTstep/GNUstepのローカライズされたリソースフ
     ァイルを出力します。このファイル形式はplural formをサポートしないこ
     とに注意してください。

‘-w NUMBER’
‘--width=NUMBER’
     出力ページの幅をセットします。これにより出力ファイル中の長い文字列
     が指定した幅(例:スクリーンの列数)に収まるように、各行の長さが
     NUMBER以下のような複数の行に分割されます。

‘--no-wrap’
     長いメッセージ行を分割しません。出力ページの幅を超えるようなメッセ
     ージ行も、複数行に分割されません。出力ページの幅を超えるファイル参
     照行だけが分割されます。

‘-s’
‘--sort-output’
     ソートされた出力を生成します。このオプションを使用することにより翻
     訳者が、メッセージがどのようなコンテキストで使用されるかを理解する
     のが、困難になることに注意してください。

‘-F’
‘--sort-by-file’
     ファイルの場所により出力をソートします。

7.1.8 情報的な出力
------------------

‘-h’
‘--help’
     このヘルプを表示して終了します。

‘-V’
‘--version’
     バージョン情報を表示して終了します。

‘-v’
‘--verbose’
     診断レベルを上げます。

‘-q’
‘--quiet’
‘--silent’
     プログレスインジケーターを表示しません。

8 POファイルの編集
******************

8.1 KDEのPOファイルエディター
=============================

8.2 GNOMEのPOファイルエディター
===============================

8.3 EmacsのPOファイルエディター
===============================

   幸運にもあなたがEmacsのユーザーならば、POファイルの編集・変更のための
快適な環境を提供するために特別に作成されたPOモードがあります。POファイル
を編集するときPOモードを使えば、追加のPOファイルやcompendium POファイル
を閲覧したり、POファイルの元となるCプログラムのソースへの参照を追跡する
のが簡単になります。またプログラム中の文字列にたいして対話的に翻訳可能の
マークをつけたり、POファイルを検証してエラーのある行を再配置するための特
別な機能があります。

   POモードを使うにはまず、主要なPOモードのコマンド(see Main PO Commands
を参照してください)以外に、エントリー間の移動(see Entry Positioning
を参照してください)や、翻訳されていないエントリーの処理方法
(see Untranslated Entriesを参照してください)を理解する必要があります
。

8.3.1 GNU ‘gettext’のインストールを完了する
-------------------------------------------

   1度GNU ‘gettext’ディストリビューションを入手して解凍し、configure、コ
ンパイルしてしまえば、‘make install’コマンドで‘xgettext’、‘msgfmt’、
‘gettext’、‘msgmerge’などのプログラムや、それらが利用できるメッセージの
カタログを所定の場所に配置することができます。快適なインストールの締めく
くりとして、EmacsのユーザーのためにPOモードを利用できるようにしましょう
。

   POモードをインストールしているうちに、あなたは‘.emacs’ファイルを修正
して、以下のような行を追加したいと思うことでしょう:

     (setq auto-mode-alist
           (cons '("\\.po\\'\\|\\.po\\." . po-mode) auto-mode-alist))
     (autoload 'po-mode "po-mode" "Major mode for translators to edit PO files" t)

   こうしておけば以後、‘.po’のようなファイルや、ファイル名に‘.po.’という
文字列が含まれるファイルを編集するとき、Emacs が必要に応じて
‘po-mode.elc’(または‘po-mode.el’)をロードして、割り当てられたバッファー
にたいするPOモードのコマンドが自動的に利用可能になります。POモードがアク
ティブな任意のバッファーのモードラインには、_PO_という文字が表示されます
。単一のEmacsセッションで、1度に複数のPOファイルをアクティブにすることが
できます。

   Emacsのバージョン20以上を使用していて、システムに適切なインターナショ
ナルフォントがインストールされているなら、様々なPOファイルにたいして自動
的にcoding systemを決定する方法をEmacsに指定することもできます。これは
Emacsのスクリーンに翻訳を表示する時にしばしば、必要なフォントがロードさ
れ使用されるということです(常にではありませんが)。これを実現するためには
、あなたの‘.emacs’ファイルに以下の行を追加します:

     (modify-coding-system-alist 'file "\\.po\\'\\|\\.po\\."
                                 'po-find-file-coding-system)
     (autoload 'po-find-file-coding-system "po-mode")

これでもまだinternationalなcharacterのかわりに四角が表示されるようなら、
(Shiftキーを押しながらマウスボタン1をクリックして)違うフォントセットを試
してみてください。

8.3.2 主要なPOモードのコマンド
------------------------------

   Installationで説明されているような行を追加してEmacsを設定した
後は、POファイルを検知するとEmacsがそのウィンドウにたいしてPOモードを有
効にします。これによりそのウィンドウは読み取り専用となり、po-mode-mapが
設定されます。これはテキストモードから継承されたのではなく、純粋な
Emacsのモードです。もし‘po-mode-hook’に指定された関数があれば、実行され
ます。

   あるウィンドウにたいしてPOモードが有効になると、‘PO’という文字が、そ
のウィンドウのモードラインに表示されます。モードラインにはPOファイルに含
まれている各種エントリーがいくつあるかも表示されます。たとえば
‘132t+3f+10u+2o’という文字列が表示されている場合、POモードには132個の翻
訳済みのエントリー(see Translated Entriesを参照してください)と、3個
のfuzzyエントリー(see Fuzzy Entriesを参照してください)、それに10個の
未翻訳のエントリー(see Untranslated Entriesを参照してください)と、
2個の廃止されたエントリー(see Obsolete Entriesを参照してください)が
含まれていることを翻訳者に示しています。この際、エントリーが0個のものは
表示されません。この例にならうと、fuzzyエントリーが解消され、未翻訳のエ
ントリーが翻訳され、廃止されたエントリーが削除されれば、モードラインには
‘145t’だけが表示されることになります。

   主要なPOコマンドの中には、以下のセクションのカテゴリー分けに適合しな
いものもあります。それらのコマンドとは、POモードやPOモードが管理するウィ
ンドウを、特別な方法で終了する方法などです。

‘_’
     POファイルにたいする最後の変更を取り消します(‘po-undo’)。

‘Q’
     処理を終了してPOファイルを保存します(‘po-quit’)。

‘q’
     問い合わせの後に処理を終了します(‘po-confirm-and-quit’)。

‘0’
     一時的にPOファイルのウィンドウを離れます(‘po-other-window’)。

‘?’
‘h’
     POモードのヘルプを表示します(‘po-help’)。

‘=’
     POファイルに関する統計情報を取得します(‘po-statistics’)。

‘V’
     POファイル全体のフォーマットを検証します(‘po-validate’)。

   ‘_’コマンド(‘po-undo’)は、Emacsの_undo_機能と連携します。See
Undoing Changes (emacs).を参照してください。‘_’を入力する度に、翻訳
者がPOファイルにたいして行った変更が少しずつ取り消されていきます。取り消
し機能を実現するために、POモードのコマンドはアトミックになっています。こ
れは特に‘<RET>’コマンドにたいして当てはまります。このコマンドを使用して
行った1度の変更は、編集がいくつかの操作により行われたものだったとしても
、1度の取り消しで元に戻ります。しかし編集中のウィンドウでは、作業をより
小さい単位で取り消すことができます。

   ‘Q’コマンド(‘po-quit’)と、‘q’コマンド(‘po-confirm-and-quit’)は、翻訳
者がPOファイルにたいする作業を終了するときに使用します。後者のコマンドは
前者のコマンドに比べると冗長なコマンドです。ファイルが変更されていた場合
、まずディスクにファイルが保存されます。ファイルが変更されていない場合で
も、コマンドはまずPOファイルに未翻訳のメッセージが残されていないかをチェ
ックして、もしそのようなメッセージが残っていた場合、翻訳者は本当にこの
POファイルにたいする作業を終了したいのか尋ねられます。これはEmacsのPOフ
ァイルにたいするバッファーを離れるときに望ましい方法です。単にバッファー
をkillする通常の‘C-x k’コマンド(‘kill-buffer’))は、好ましい方法ではあり
ません。

   ‘0’コマンド(‘po-other-window’)は、POモードを一時的に離れるときに使用
する、よりソフトな方法です。このコマンドはカーソルをEmacsの他のウィンド
ウに移動して、他のウィンドウを表示します。たとえば翻訳者が、メッセージの
ソース文脈中での箇所を探して、ソースのバグを修正するためだけにPOモードを
開いている場合などに使用します。このコマンドにより翻訳者たる彼女は、プロ
グラマーたる_彼_へと性転換を遂げ、修正したいプログラムを表示しているウィ
ンドウにカーソルを移すことができます。後でPOファイルのウィンドウにカーソ
ルを戻すか、このファイルをもう一度編集するかをEmacsに指定した時に、POモ
ードが復元されます。

   ‘h’コマンド(‘po-help’)は、POモードで利用可能なすべてのコマンドの要約
が表示されます。翻訳者が任意の文字を入力することにより、通常のPOモードの
操作に戻ることができます。‘?’コマンドでも、‘h’コマンドと同じ結果を得るこ
とができます。

   ‘=’コマンド(‘po-statistics’)は、POファイルのすべてのエントリーを集計
し、現在のエントリーが先頭から数えて何番目かと、未翻訳のエントリー数、廃
止されたエントリー数等のすべての数を表示します。

   ‘V’コマンド(‘po-validate’)は、‘msgfmt’のverbose modeにより、編集中の
POファイルをチェックします。このコマンドは最初に編集中のPOファイルをディ
スクに保存します。GNU ‘gettext’の‘msgfmt’は、POファイルの出力としてMOフ
ァイルを生成するツールで、POモードがPOファイル全体の書式や個々のエントリ
ーの書式をチェックするのに、このプログラムの機能が使用されています。

   ‘msgfmt’プログラムはEmacsと非同期で実行されるので、POファイルの評価が
終わっていなくても、制御はすぐに翻訳者に戻されます。標準エラー出力への出
力はEmacsにより収集されて、他のウィンドウの‘*compilation*’バッファーに表
示されます。Emacsの通常コマンドの‘C-x`’(‘next-error’)や、その他の同様の
コンパイル時のコマンドにより、翻訳者は素早くPOファイル中の提示された位置
に移動することができます。カーソルがエラーのある行に移動すると、翻訳者が
エラーを修正するためのPOモードのコマンドを選択することができます。

8.3.3 エントリーの決定
----------------------

   POファイルのウィンドウの中のカーソルは、ほとんど常にエントリ一部とな
ります。唯一の例外は、カーソルがファイルの最後のエントリーの後ろにあった
り、POファイルが空だったりという、特別なケースのときだけです。カーソルの
ある位置のエントリーのことを、カレントエントリーと呼びます。POモードのコ
マンドの多くは、カレントエントリーにたいして操作を行うので、翻訳者にとっ
てカーソルを動かすことはPOファイルを閲覧できるだけでなく、エントリーに作
用するコマンドの対象エントリーを選択することでもあるのです。

   POモードのコマンドには、特別な方法によりカーソルの位置を変更するもの
があります。それらの特別な目的に対応する位置へカーソルを動かす方法につい
ては、ここで説明します。他の方法については、以降のセクションで説明します
(‘C-h m’で完全な一覧を得ることもできます)。

‘.’
     カレントエントリーを再表示します(‘po-current-entry’)。

‘n’
     カレントエントリーの次のエントリーを選択します(‘po-next-entry’)。

‘p’
     カレントエントリーの前のエントリーを選択します
     (‘po-previous-entry’)。

‘<’
     POファイルの最初のエントリーを選択します(‘po-first-entry’)。

‘>’
     POファイルの最後のエントリーを選択します(‘po-last-entry’)。

‘m’
     後で利用できるように、現在のエントリーの場所を記録します
     (‘po-push-location’)。

‘r’
     以前に記録したエントリーの場所に戻ります(‘po-pop-location’)。

‘x’
     現在のエントリーの場所と、以前に記録したエントリーの場所を交換しま
     す(‘po-exchange-location’)。

   Emacsのカーソル位置を変更するための、文字、行、paragraph、画面単位で
の移動や検索などのコマンドは、POモードでカレントエントリを選択するのに使
用できます。しかしPOモードには、通常のEmacsでカーソルを移動するコマンド
には無いような、カレントエントリーを表示するための標準的な方法があります
。‘.’コマンド(‘po-current-entry’)は、Emacsの画面が変更されたときなどPOモ
ード以外の方法やでカレントエントリーが変更された時に、カレントエントリー
を適切に再表示するという単一の目的のためのコマンドです。

   翻訳者が作業をしているときに、POモードによりウィンドウ配置を厳格に強
制されることが、彼女を助けるものなのか、それともイライラさせるものなのか
は未だ不明です。私たちは当初、ウィンドウがどのように振る舞うべきかについ
て明確なアイデアを持っていました。しかしその一方で、Emacsを使うとき自分
で完全にコントロールできるほうを好む人もいます。固定されたウィンドウ配置
は、翻訳者が有効・無効を選択できるようにPOモードのオプションとして、実験
的な機能として提供されるべきでしょう。もしこの機能を使う必要性や、記述す
る衝動をもつ人がだれもいないなら、私たちはこのアイデアを放棄するべきなの
でしょう。これを行うには、プログラマーよりも翻訳者からの動機が必要です。
私にとって、経験を積んだ翻訳者の意見は、他者がどうやって翻訳するか想像す
るしかないプログラマーの意見にくらべて、より価値があるからです。

   ‘n’コマンド(‘po-next-entry’)と‘p’コマンド(‘po-previous-entry’)は、カ
ーソルをカレントエントリーの前または後のエントリーに移動します。POファイ
ルの最後のエントリーにカーソルがあるときに‘n’を押したり、最初のエントリ
ーにカーソルがあるときに‘p’を押しても、移動は行われません。

   ‘<’コマンド(‘po-first-entry’)と‘>’コマンド(‘po-last-entry’)は、POファ
イルの最初のエントリー、または最後のエントリーにカーソルを移動します。
POモードのほとんどのコマンドは、POファイルの最後のエントリー以降にカーソ
ルがあるときは、‘After last entry’のようなエラーを戻します。‘<’コマンド
と‘>’コマンドは、カーソルがPOファイルのエントリーにない場合でも動作する
特性があるので、このような状況をうまく解決するのに使う人もいます。しかし
これらのコマンドも、POファイルが空の場合は失敗します。ソースから対話的に
空のPOファイルにエントリーを追加していくようにPOモードを開発するプランも
あります。Markingを参照してください。

   翻訳者が特定のエントリーを翻訳する前には、そのエントリーに関連する用
語や言い回しを探すために、POファイルの残りの部分を参照する必要があるかも
しれません。もちろん彼女はEmacsの標準的な慣例にしたがって、カレントカー
ソルの位置をレジスターなどに保存して、後でその場所に戻るのにそのレジスタ
ーを使ったり、場所を記憶するためのリングバッファーを使うこともできます。

   これらの方法にたいして、POモードは特別なスタックにカーソルの場所を保
存するという、別の方法を提供します。‘m’コマンド(‘po-push-location’)は、
スタック上に既に保存してあるカーソル位置の情報の上に、カレントエントリー
をpushします。‘r’コマンド(‘po-pop-location’)は、スタックの最上部の要素を
popして、カーソルをその要素に関連付けられた位置へと移動します。これによ
りpopされた要素の位置情報は失われ、次の‘r’コマンドでは、その要素の1つ前
に保存された位置にカーソルが移動します。これはスタックに保存された位置の
情報がなくなるまで同じように動作します。

   翻訳者がスタックの最上位の要素に関連付けられているエントリーの位置を
確認してから他の場所に移動して、後で元の場所に戻る等の理由で、エントリー
の場所をスタックに保存したいとき、彼女は‘r’の直後に‘m’を使うべきです。

   ‘x’コマンド(‘po-exchange-location’)は、カーソルをスタックの最上位の要
素に関連付けられた位置に再配置すると同時に、移動する前のカレントエントリ
ーの位置を最上位の要素に保存します。つまり、‘x’コマンドを繰り返し使うと
、それら2つのエントリーを行き来することができます。これを行うにはまず、
最初のエントリーにカーソルを移動してから‘m’コマンドを使用し、その後2番目
のエントリーで‘x’コマンドを使えば、2つのエントリー間を行き来することがで
きます。

8.3.4 エントリー内の文字列の正規化
----------------------------------

   特定の文字列をPOファイルのエントリーにエンコードする場合、複数行を分
割したり括ったりする方法、さらには特殊な文字をバックスラッシュでエスケー
プする方法までもが異なっている等、とても多くの方法があります。POモードに
は、特定のエンコードの文字列を‘msgid’フィールドに挿入するために、既存の
POファイルをスキャンする機能があります。POモードにはこれらを簡単に認識す
るためのビルトイン機能が内部的に存在しますが、これを高速に行うのは技術的
に困難です。この効率に関する問題の解決を容易にするために、わたしたちは文
字列の正規表現を採択しました。

   POファイル内の文字列の標準的な表現方法については現在も議論されていま
すが、POモードでは正規表現を実験的に採用しています。‘xgettext’とPOモード
で、同じ文字列を統一された方法で表示するのは、POモードで必要となる内部的
な正規化が、GNU ‘gettext’からの‘xgettext’の使用をも自動的に満たすので便
利なのです。明示的なPOモードの正規化は、POファイルが他の場所からインポー
トされたときや、慣例そのものが変更されたときに必要です。

   正規表現が必要なPOファイルの文字列を正規化するために、以下のPOモード
のコマンドが利用可能です:

‘M-x po-normalize’
     エントリーをより標準化することにより、PO ファイル全体を整理します。

   特別なコマンドである‘M-x po-normalize’コマンド(キーは関連付けられてい
ません)は、未翻訳のエントリーおよび翻訳済みのエントリー両方を、POファイ
ル内部の標準的な引用符で括って、すべてのエントリーを修正します。このコマ
ンドは最後のエントリーより後ろにあるゴミも削除します。このコマンドは、他
の場所からインポートしたPOファイルを新たにインポートするときや、わたした
ち自身がこの正規化された引用書式を改善していけるならば、有用となるでしょ
う。この正規化された書式はPOファイルを整理するだけでなく、ほかのPOモード
のコマンドが‘msgid’から文字列を検索する処理のスピードを大幅に改善します
。

   ‘M-x po-normalize’は、エントリーにたいして3パスの処理を行います。最初
のパスで、複数行の‘msgid’と‘msgstr’に、K&R CスタイルのC文字列書式を使用
しているGNU ‘gettext’ 0.6以前のPOファイルを発見して変換します。この発見
的な処理は、廃止されたエントリーに関連付けられておらず、バックスラッシュ
で終端されたコメントでは失敗します。これは後続のパスで、廃止されたコメン
トに続くコメントを完成させる処理に依存します。この最初のパスは、すべての
古いPOファイルの調整後は行われません。2番目と3番目のパスでは、すべての
‘msgid’と‘msgstr’の文字列を、それぞれ正規化していきます。これらのパスで
はXViewの‘msgfmt’の継続行のためのバックスラッシュも除去します。

   このように明示的に正規化を指定するコマンドは、他のソースからPOファイ
ルをインポートするときだけではなく、現在使われている慣用句や美的観点によ
る改善を容易にします。正規化コマンドで提案された調整を後で行うのは簡単で
、最終的には他のGNU ‘gettext’ツールも、この適合を自動化する必要がありま
す。Emacsを持っていないが、それでもPOファイルを上手に手作りしたい人のた
めに、以下では正規化された文字列の書式を説明します。

   POモードの文字列は単一行か複数行になります。文字列内に_埋め込まれた
_改行が存在するとき、すなわち‘[^\n]\n+[^\n]’というパターンにマッチする文
字列は複数行になります。例えば以下のような文字列があったとします:

     msgstr "\n\nHello, world!\n\n\n"

   この文字列の空白を改行に置き換えると、以下のような文字列になります:

     msgstr ""
     "\n"
     "\n"
     "Hello,\n"
     "world!\n"
     "\n"
     "\n"

   ここでは問題点を明確にするために、カリカチュアーされた例を使用して議
論していきます。通常、複数行の体裁は悪いものではありません。これを処理す
るための実装は多分、次のような提言にしたがったものになるでしょう。すべて
の改行、および空行を表す改行を空文字列の中にまとめます(N > 1からN-1番目
の改行は文字列を区切る改行です)。これにより文字列は以下のようになります:

     msgstr "\n\n"
     "Hello,\n"
     "world!\n"
     "\n\n"

   文字列の初期化に関しては、まだ未解決の点もあります。これらの問題につ
いては、解決されたものからこのドキュメントに記載されるでしょう。

8.3.5 翻訳済みのエントリー
--------------------------

   POファイル中のエントリーの‘msgstr’が翻訳されて、fuzzy(see Fuzzy Entries
を参照してください)もマークされていない場合、そのエントリーを翻
訳済みのエントリーと呼びます。以後の処理では、翻訳済みのエントリーだけが
GNU ‘msgfmt’でコンパイルされて、プログラムで利用できるようになります。他
の種類のエントリーは除外され、それらにたいする翻訳は出力されません。

   翻訳済みのエントリーを処理するためのコマンドがいくつかあります。

‘t’
     次の翻訳済みエントリーを検索します(‘po-next-translated-entry’)。

‘T’
     前の翻訳済みのエントリーを検索します
     (‘po-previous-translated-entry’)。

   ‘t’コマンド(‘po-next-translated-entry’)と‘T’コマンド
(‘po-previous-translated-entry’)は、翻訳済みのエントリーを見つけて、前方
または後方に移動するためのコマンドです。翻訳済みのエントリーが見つからな
かった場合、POファイルのバッファーの先頭または終端に戻って検索します。

   翻訳済みのエントリーは通常、翻訳者が翻訳を編集した結果です。
Modifying Translationsを参照してください。ただし変数
‘po-auto-fuzzy-on-edit’が‘nil’でない場合、新しく翻訳されたエントリーは、
公式な翻訳となる前に、最初はfuzzyエントリーになります。この場合、後でこ
のfuzzyエントリーのfuzzyを解消して、正式な翻訳済みのエントリーにする必要
があります。Fuzzy Entriesを参照してください。

8.3.6 fuzzyエントリー
---------------------

   POファイルのエントリーは、一連の“属性”を持っています。それらは名前か
ら得られるような性質をもち、翻訳に関するシステムコメントを明示するために
使用されます。その属性1つが‘fuzzy’で、この属性をもつエントリーがfuzzy(あ
いまいな)な翻訳であることを示します。この属性がつけられたエントリーのこ
とを、fuzzyエントリーと呼びます。

   通常fuzzyエントリーは、おおよそ目的にあった翻訳であるような翻訳済みエ
ントリーにたいして、翻訳者が見直しのために使用するものです。これらの
fuzzyエントリーは、古い翻訳済みのPOファイルを新しいPOテンプレートファイ
ルに対応して更新するために、‘msgmerge’プログラムを適用することにより生成
されることもあり、それはこのツールが、新しい‘msgid’が、古いものをわずか
に修正したものであって、新しい修正されたエントリーに古い翻訳を選択できる
と推測したときです。元の文字列(‘msgid’文字列)にたいするわずかな変更は、
翻訳にも影響を与える場合があり、これは翻訳者による判断が必要です。あるエ
ントリーにたいして‘msgmerge’がfuzzyのマークを付与するのには、このような
理由があるのです。

   翻訳者が後で再検討する必要があるエントリーを覚えておくために、彼女自
身の都合でエントリーをfuzzyとすることもあります。したがって特にfuzzyエン
トリーを処理するためのコマンドが、いくつかあります。

‘f’
     次のfuzzyエントリーを検索します(‘po-next-fuzzy-entry’)。

‘F’
     前のfuzzyエントリーを検索します(‘po-previous-fuzzy-entry’)。

‘<TAB>’
     カレントエントリーのfuzzy属性を取り除きます(‘po-unfuzzy’)。

   ‘f’コマンド(‘po-next-fuzzy-entry’)と‘F’コマンド
(‘po-previous-fuzzy-entry’)は、前方もしくは後方のfuzzyエントリーに移動し
ます。fuzzyエントリーが見つからなかった場合、PO ファイルのバッファーの先
頭または終端に戻って検索します。

   ‘<TAB>’コマンド(‘po-unfuzzy’)は、エントリーに付与されているfuzzy属性
を取り除いて、通常は翻訳済みのエントリーとします。さらに、変数
‘po-auto-select-on-unfuzzy’が‘nil’でない場合には、‘<TAB>’コマンドにより
自動的に他の対象となるエントリーに移動します。
‘po-auto-select-on-unfuzzy’の初期値は‘nil’ です。

   ‘po-auto-fuzzy-on-edit’の初期値は‘nil’です。しかし変数
‘po-auto-fuzzy-on-edit’に‘t’をセットすると、‘<RET>’コマンドで編集したエ
ントリーは、後から再チェックなどができるようにfuzzyとマークされます。こ
の場合、通常の使用法では、翻訳者が変更したエントリーは、(すでにfuzzy だ
った場合をのぞき)fuzzyエントリーに変更されることになります。彼女が翻訳に
満足した場合、‘<TAB>’を使えばfuzzy属性をクリアーするとともに、他のエント
リーへと移動することができます。まだ翻訳が不十分だと思ったときは、
‘<SPC>’を使えばfuzzy属性を保持したまま他のエントリーに移動することができ
ます。

   翻訳者が作業中のエントリーを後で見直したいようなときに見つけやすいよ
うに、翻訳済みのエントリーをfuzzyとマークする場合は、‘<DEL>’コマンド
(‘po-fade-out-entry’)を使うこともできます。

   翻訳者が作業を終えてPOファイルのバッファーを‘q’コマンドで閉じるとき、
まだfuzzyエントリーが残っている場合は、終了してもよいか確認を求められま
す。

8.3.7 未翻訳エントリー
----------------------

   ‘xgettext’で元となるPOファイルを作成する場合には、‘msgid’は未翻訳の文
字列で初期化され、‘msgstr’には空文字列がセットされます。このように翻訳に
空文字列がセットされているエントリーのことを、“未翻訳(untranslated)”のエ
ントリーと呼びます。プログラマーがプログラム内の文字列に変更を加えた場合
、変更された文字列にたいする新しい未翻訳のエントリーとしてPOファイル中に
現れることになります。

   未翻訳のエントリーにたいしても、有効なエントリー間の移動に通常使用す
るコマンドと同様のレベルで考えることができます。未翻訳のエントリーは、最
後に‘msgstr ""’があるので、容易に識別できます。

   翻訳者の作業は(非常に簡単に表現するならば)、未翻訳のエントリーを探し
て編集・翻訳して、未翻訳のエントリーがなくなるまでそれを繰り返していくこ
とではないでしょうか。特に未翻訳のエントリーを処理するためのコマンドが、
いくつかあります。

‘u’
     次の未翻訳のエントリーを検索します(‘po-next-untranslated-entry’)。

‘U’
     前の未翻訳のエントリーを検索します
     (‘po-previous-untransted-entry’)。

‘k’
     カレントエントリーを未翻訳にします(‘po-kill-msgstr’)。

   ‘u’コマンド(‘po-next-untranslated-entry’)と‘U’コマンド
(‘po-previous-untransted-entry’)は、前方もしくは後方の未翻訳のエントリー
に移動します。未翻訳のエントリーが見つからなかった場合、POファイルのバッ
ファーの先頭または終端に戻って検索します。

   ‘k’コマンド(‘po-kill-msgstr’)は、単に翻訳された文字列を空文字列にする
ことによって、エントリーを未翻訳のエントリーにするコマンドです。
Modifying Translationsを参照してください。

   翻訳者が作業を終えてPOファイルのバッファーを‘q’コマンドで閉じるとき、
まだ未翻訳のエントリーが残っている場合は、終了してもよいか確認を求められ
ます。

8.3.8 陳腐化したエントリー
--------------------------

   POファイルの“陳腐化”したエントリーとは、‘msgmerge’によりローカライズ
されるパッケージ内で、その翻訳がもはや必要ないのでコメントアウトされてい
るエントリーのことです。

   陳腐化したエントリーにたいしても、有効なエントリー間の移動に通常使用
するコマンドと同様のレベルで考えることができます。行に‘msgid’や
‘msgstr’が含まれているか否かに関係なく、行が‘#’で開始されているという事
実により、陳腐化したエントリーを識別できます。

   再初期化するために翻訳を空文字列に置き換えて、元の未翻訳の空文字列に
するコマンドがあります。これらのコマンドはEmacsのkillリングと互換性があ
るので、以前にkillリングに保存された文字列を翻訳として挿入することもでき
ます。またユーザーは翻訳を対話的に編集することができます。これらすべての
コマンドは廃止されたエントリーの編集にも適用できますが、エントリーは廃止
された状態のままになります。

   陳腐化したエントリーに特化したコマンドがいくつかあります。

‘o’
     次の陳腐化エントリーを検索します(‘po-next-obsolete-entry’)。

‘O’
     前の陳腐化したエントリーを検索します
     (‘po-previous-obsolete-entry’)。

‘<DEL>’
     有効なエントリーにたいしては、それを陳腐化したエントリーにします。
     陳腐化したエントリーの場合は、エントリーを削除します
     (‘po-fade-out-entry’)。

   ‘o’コマンド(‘po-next-obsolete-entry’)と‘O’コマンド
(‘po-previous-obsolete-entry’)は、前方もしくは後方の陳腐化したエントリー
に移動します。陳腐化したエントリーが見つからなかった場合、POファイルのバ
ッファーの先頭または終端に戻って検索します。

   PO モードには、陳腐化したエントリーにたいして、そのエントリーを非コメ
ント化することにより有効なエントリーにする方法は用意されていません。用意
されていない理由は、元となる未翻訳の文字列と、プログラム中の文字列の対応
をとることができなくなるからで、これは msgid 駆動の哲学と反するからです
。

   とはいえ有効なエントリーをコメントアウトして、陳腐化したエントリーと
することは可能です。後でGNU ‘gettext’ユーティリティーが処理するとき、翻
訳が見つからなければ未翻訳の文字列が使用されます。‘<DEL>’コマンド
(‘po-fade-out-entry’)は、カレントエントリーを消滅の方向へと押しやるコマ
ンドです。有効なエントリー(翻訳されたエントリー)の場合には、そのエントリ
ーをfuzzyエントリーにします。すでにfuzzyエントリーの場合には、確認後にそ
のエントリーをコメントアウトします。すでに廃止されたエントリーの場合には
、そのエントリーをPOファイルから削除します。削除した翻訳を、他のPOファイ
ルの、(通常は)未翻訳のエントリに再使用するのは簡単です。Modifying Translations
を参照してください。

   今後POモードを開発していく上で、あなたを寝不足とさせるような、解決す
べき興味深い問題が存在します。POモードをよりよくするこのアイデアとは、新
しく出現した文字列にたいする翻訳として、すべての陳腐化したエントリーの中
から最適な候補を推測することです。これはアルゴリズム的に解決するには困難
な問題であり、文字列の相似をより効果的に計測するための開発を行う必要があ
ると私は考えています。現在ではこれらの作業は翻訳者がすべて決定しなければ
なりませんが、いつの日か陳腐化したエントリーから翻訳を検索することができ
る便利なツールを提供できるように努力しています。

8.3.9 翻訳の修正
----------------

   POモードは、通常Emacsのバッファーを変更するような方法でPOファイルを直
接編集することを防ぎます。そうすることで、直接編集してファイル全体のフォ
ーマットや文字列の引用符を誤って編集してしまう等の、容易に発生し得るエラ
ーを防ぎます。他の種類のエラーもありますが、それらのエラーは翻訳者が
‘V’コマンドを使っていつでも、バッチ検証プロセスにより発見・診断すること
ができます。その他のエラーについては、翻訳者自身の判断と、彼女が翻訳した
パッケージにたいする同じ母国語ユーザーによる、言語的な判定に頼る必要があ
ります。

   翻訳を作成し、機械的な診断およびユーザーによる報告を経た後、翻訳者は
以下のコマンドを使って翻訳を変更します。

‘<RET>’
     翻訳を対話的に編集します(‘po-edit-msgstr’)。

‘<LFD>’
‘C-j’
     翻訳を元の未翻訳の文字列で再初期化します(‘po-msgid-to-msgstr’)。

‘k’
     翻訳をkillリングに保存してから、削除します(‘po-kill-msgstr’)。

‘w’
     翻訳をkillリングに保存するだけで、削除はしません
     (‘po-kill-ring-save-msgstr’)。

‘y’
     翻訳をkillリングのもので置き換えます(‘po-yank-msgstr’)。

   ‘<RET>’コマンド(‘po-edit-msgstr’)は、新しい翻訳を編集したり既存の翻訳
を変更するための、新しいEmacsのウィンドウをオープンします。新しいウィン
ドウにはPOファイルのカレントエントリーの、翻訳のコピーが含まれています。
翻訳のコピーは、すぐに編集できるように引用符を除かれていて、Emacsによる
編集コマンドのすべてが使用できます。翻訳者が文字列の変更を終えたら、
‘C-c C-c’により、自動的に引用符を付加した形式で結果を保存し、編集用のサ
ブウィンドウを閉じることができます。変更を保存せずに取り消す場合には、
‘C-c C-k’を使用してください。詳細は、see Subeditを参照してください。

   ‘<LFD>’コマンド(‘po-msgid-to-msgstr’)は、翻訳を元の文字列で初期化しま
す。このコマンドは通常、翻訳者が以前の作業を破棄して、元の文字列にたいし
て新しく翻訳をやり直したいときに使用します。

   未翻訳のエントリーを編集するときに、常に‘<LFD>’コマンドを自動的に実行
させることもできます。‘po-auto-edit-with-msgid’に‘t’をセットすれば、翻訳
に何も文字列が設定されていない場合には、元の文字列により翻訳が初期化され
ます。デフォルトでは‘po-auto-edit-with-msgid’は‘nil’です。

   実際のところ、空の文字列から翻訳を開始するのか、それとも元の文字列の
コピーから翻訳を開始するのかは好みの問題です。元の言語と、翻訳する言語が
あまりに異なっている場合には、単に空の文字列から開始するのがよいでしょう
。その反対に元の言語と翻訳する言語が似ている場合には、元の文字列の数字や
文字を再入力する手間を省きたいときもあるでしょう。未翻訳の余分な元文字列
を取り除く手間がかかるとしても、彼女は元の文字列を見ながら未翻訳の文字列
を翻訳で上書きしていく方法を好むかもしれません。

   これにより、空文字列になる前の内容は、killリングと呼ばれる特別な場所
に置かれます。wコマンド(po-kill-ring-save-msgstr)も、翻訳をkillリングに
コピーする効果に違いはありませんが、エントリーをそのままにする点が異なり
ます。この場合、エントリーから翻訳は削除されません。どちらのコマンドも、
Emacs愛好家にはよく知られている共有バッファーである、Emacsのkillリングを
使用します。

   翻訳者は作業する過程で、‘k’や‘w’を多く使うことでしょう。それにともな
いkillリングには翻訳が保存されていきます。killリングに保存された文字列は
、後でEmacsの他のバッファーに挿入することができます。killリングは、単一
のPOファイル内の異なるエントリー間だけではなく、翻訳者がPOファイルを複数
開いている場合は、異なるPOファイル間で翻訳文字列を移動するのに使用されま
す。

   POモードではないバッファーと文字列をやりとりするのを容易にするために
、‘k’コマンドでkillリングに置かれた翻訳文字列は、引用符が取り除かれて保
存されます。すなわち、文字列を囲うための引用符は取り除かれ、複数行の文字
列は結合され、バックスラッシュでエスケープされた文字は対応する実際の文字
に変換されます。陳腐化したエントリーの場合、保存される前に翻訳は非コメン
ト化されます。

   ‘y’コマンド(‘po-yank-msgstr’)は、カレントエントリーの翻訳をkillリング
の文字列で完全に置き換えます。Emacsの用語にしたがうと、置き換えた文字列
は、PO ファイルのバッファーへ“yank(yanked)”されたといいます。
Yanking (emacs)を参照してください。最初に‘y’を使用したときは、killリン
グに最後に追加された値が翻訳として戻されます。他のキーを押さずに、もう一
度‘y’をタイプすると、killリングの最後から2番目に追加された文字列が、翻訳
として挿入されます。‘y’を何度も繰り返すことにより、望む文字列が見つかる
まで、killリングに保存された文字列を巡回することができます。

   文字列がPOファイルのエントリーにyankされるときには、自動的にPOファイ
ルの書式にしたがった形式の引用符が付与されます。さらに陳腐化したエントリ
ーの場合には、文字列は適切にコメント化されます。プログラムが使用できるよ
うに、翻訳された個々の文字列に引用符を付与するために、翻訳者が患わされる
ことはありません。

   ‘k’と‘w’だけが、文字列をkillリングに保存するコマンドではないことに注
意してください。POモードの多くのコマンドは、翻訳された文字列(または翻訳
者のコメント)を置き換えて、自動的にリングに保存します。この一般的なルー
ルに当てはまらないコマンドは、yankコマンド自身です。

   文字列のkillとyankについては、一般的な状況の実例で説明したほうがよい
でしょう。プログラマーが文字列にちょっとした変更を加えたとしましょう。そ
の後、彼が行った変更は、変更した文字列にたいする新しい未翻訳のエントリー
としてPOファイルに出現し、元の変更されていない文字列にたいする翻訳は、陳
腐化したエントリーとなります。多くの場合、翻訳者は未翻訳エントリーの
‘msgstr’に、陳腐化したエントリーの変更前の翻訳を流用することで作業を節約
できるでしょう。その後、陳腐化したエントリーが必要ないなら、安全に削除す
ることができます。

   翻訳者が未翻訳のエントリーを見つけて、それが既存の翻訳と少ししか違わ
ないのではないか、と思ったとしましょう。そのような場合は、すぐにカレント
エントリーの場所を‘m’でマークしてから、陳腐化したエントリーを検索して、
変更される前の文字列にたいする翻訳を探すために‘o’を使用します。見つかっ
たら、DELコマンドで廃止されたエントリーを削除します。なぜなら彼女はDELコ
マンドが翻訳をkillすることを知っており、それはつまり翻訳がkillリングに保
存されることを知っているからです。その後‘r’コマンドで最初の未翻訳エント
リーに戻り、保存した翻訳を‘y’コマンドで‘msgstr’に_yank_します。これで翻
訳者は、‘<RET>’を使って自由に翻訳内容を調整することができます。そしてそ
の後は再び‘u’と‘m’で次の未翻訳の文字列を探していくのかもしれません。

   翻訳者が同じキーシーケンスを何度も使用する必要があるときには、要求し
たときにそのキーシーケンスを再生させるEmacsの機能について学習するほうが
よいかもしれません。Keyboard Macros (emacs)を参照してください。

8.3.10 コメントの修正
---------------------

   翻訳とは、言語的な難しさをともなう作業です。翻訳においてどのような決
定をしたのか、その選択に関してドキュメントを残す必要があるでしょう。これ
らのドキュメントは、翻訳者のコメントとしてPOファイルに保存されます。これ
は、翻訳者が自由に作成・削除、または変更ができるコメントで、彼女が後で
POファイルを見直すときなどに便利です。

   最初の‘#’の後に空白がないコメント、たとえば‘#.’や‘#:’ではじまるコメン
トは、翻訳者のコメントではありません。これらは、‘gettext’ツールにより作
成されたコメントです。それらのシステムが追加したコメントは、翻訳者が変更
するべきではないコメントなので、以下で説明するコマンドの対象外です。
PO Filesを参照してください。

   以下のコマンドは翻訳を変更するコマンドと似ているので、一般的な原則は
同様に適用できます。Modifying Translationsを参照してください。

‘#’
     翻訳者のコメントを対話的に編集します(‘po-edit-comment’)。

‘K’
     翻訳者のコメントをkillリングに保存してから、削除します
     (‘po-kill-comment’)。

‘W’
     翻訳者のコメントをkillリングに保存するだけで、削除はしません
     (‘po-kill-ring-save-comment’)。

‘Y’
     翻訳者のコメントを、killリングのもので置き換えます
     (‘po-yank-comment’)。

   これらの、翻訳文字列を変更するためのPOモードの類似コマンドは、翻訳文
字列の代わりに翻訳者のコメントを処理する以外は、同じように動作します。詳
細はすでに説明済みなので、以下ではこれらのコマンドを簡単に説明します。
Modifying Translationsを参照してください。

   ‘#’コマンド(‘po-edit-comment’)は、POファイルのカレントエントリーにた
いする翻訳者コメントのコピーを含む、新しいEmacsウィンドウをオープンしま
す。エントリーにそのようなコメントがない場合、POモードは翻訳者がエントリ
ーにコメントを追加したいと解釈し、空のスクリーンが表示されます。編集前に
コメントマーク(‘#’)とそれに続くスペースは自動的に削除され、編集後に自動
的に再付加されます。陳腐化したエントリーにたいする翻訳者コメントは、非コ
メント化とコメント化の操作が2度行われます。編集ウィンドウで‘C-c C-c’キー
を押すと、コメントの編集を終了します。詳細については、see Subeditを
参照してください。

   ‘po-subedit-mode-hook’に関数が登録されている場合には、編集バッファー
に文字列が挿入されたときに実行されます。

   ‘K’コマンド(‘po-kill-comment’)は、翻訳者コメントをkillリングに保存し
てから削除します。‘W’コマンド(‘po-kill-ring-save-comment’)は、翻訳者コメ
ントをkillリングにコピーするだけで、カレントエントリーのコメントは変更し
ません。‘Y’コマンド(‘po-yank-comment’)は、翻訳者コメントをkillリングの文
字列で置き換えます。このコマンドを繰り返し入力すると、挿入されたコメント
はkillリングに保存された他の文字列で順に置き換えられます。

   killリングの文字列は、すべて同じ性質をもちます。_翻訳された文字列_と
_翻訳者のコメント_に違いはありません。たとえば翻訳者が翻訳を終了したとき
、以前の翻訳の何が悪かったのかをドキュメント化して覚えておこうと、コメン
トを付与したい場合を考えます。彼女は翻訳者コメントで、以前の翻訳を引用し
たいと思うのではないでしょうか。それを行うには、まず翻訳者コメントを、
killリングに残っている以前の翻訳で初期化するでしょう。すでにkillリングに
保存されている以前の翻訳を使って編集するには、‘#’の前に‘M-w’とタイプすれ
ば、以前の翻訳がkillリングに保存されるので、それに説明文などを追加すれば
よいでしょう。

   すでに何らかの翻訳者コメントがあり、そのコメント全体を置き換えるので
はなく翻訳者がコメントを追加したい場合を考えてみましょう。その場合には
‘#’でコメントを編集する必要があります。編集ウィンドウが開いたら、Emacsの
標準コマンドの‘C-y’(‘yank’)と‘M-y’(‘yank-pop’)で、以前の翻訳を取得できま
す。

8.3.11 サブエディションの詳細
-----------------------------

   PO subeditマイナーモードは、ここで詳細な説明をする価値のある特殊なモ
ードです。これによりEmacsの通常の編集コマンド以外に、以下で説明するコマ
ンドがインストールされます。

‘C-c C-c’
     編集を完了します(‘po-subedit-exit’)。

‘C-c C-k’
     編集を中止します(‘po-subedit-abort’)。

‘C-c C-a’
     追加(auxiliary)のPOファイルを参照します
     (‘po-subedit-cycle-auxiliary’)。

   ウィンドウにはメッセージにたいする翻訳、もしくは翻訳者コメントが表示
されます。翻訳者は自分の思うように、このウィンドウ内のコンテンツを変更し
ます。作業が終わったら、‘C-c C-c’コマンド(‘po-subedit-exit’)を使えば、バ
ッファーが切り替えられていたり、表示されていなくても、編集した翻訳で元の
翻訳を置き換えてPOファイルに反映することができます。

   kill翻訳者が自分の翻訳(または翻訳者コメント)に満足できなくて、
‘<RET>’コマンド(または‘#’コマンド)を押す前の状態に戻したい場合には、
‘C-c C-k’コマンド(‘po-subedit-abort’)を使えば、編集したものを破棄して、
元の翻訳(または翻訳者コメント)に戻すことができます。他にも、普通に
‘C-c C-c’で編集を終了してから、‘U’(訳注： UndoをするコマンドがUコマンド
と記述してあるが、EmacsのUndoコマンドであるCtrl+_コマンドの間違いではな
いか)で元のバージョンに戻す方法があります。

   ‘C-c C-a’コマンド(‘po-subedit-cycle-auxiliary’)は、カレントエントリー
の翻訳を編集しているとき、すでに他の言語へ翻訳されたメッセージに目を通し
たいときに使用します。このコマンドは翻訳者が複数の言語に通じているときな
どに便利でしょう(もちろん利用可能な追加のPOファイルがある場合ですが
(see Auxiliaryを参照してください)。

   ‘po-subedit-mode-hook’に関数が登録されている場合には、編集バッファー
に文字列が挿入されたときに実行されます。

   編集中には、翻訳文字列の最後で意図せず‘<RET>’(改行)キーを入力したり、
必要な改行を誤って削除していまわないよう注意を払う必要があります。そのよ
うな文字が編集バッファーで非表示になっていると、容易に間違いを犯してしま
います。そのような間違いが起きないように、‘<RET>’コマンドでは、編集して
いる文字列の最後に自動的に‘<’が付加されます。この‘<’は実際のメッセージ文
字列ではありません。‘C-c C-c’で編集ウィンドウを閉じると、POモードは自動
的にそのような‘<’文字を削除して、適切な空白文字に置き換えます。翻訳者が
末尾の‘<’の後ろに文字を追加すると、‘<’は区切り文字としての性質を失って、
翻訳文字列の一部となります。‘<’を削除した場合には、編集文字列は_そのまま
_評価され、たとえ非表示であったとしても、末尾に改行があればそれもそのま
ま評価されます。翻訳した文字列が本物の‘<’で終わる場合には、区切り文字の
‘<’も削除されずに表示されるので、編集ウィンドウの文字列の終端には2つの
‘<’が表示されます。

   翻訳(またはコメント)を編集するとき、翻訳者はカーソルをPOファイルのバ
ッファーに戻してから、エントリーを表示するために自由に他のエントリーに移
動を行えます。編集を保留して、POファイルバッファーの他の箇所に移動したり
、他のエントリーの編集をはじめることもできます。それぞれのエントリーは、
それら自身のサブエディットバッファーで編集されます。1つのエントリーにた
いする特定の翻訳やコメントを_同時_に編集したり、異なるPOファイルのエント
リーを同時に編集することも可能です。すでに編集中のエントリーにたいして
‘<RET>’をタイプすると、単にそのエントリーの編集を再開します。Emacsの複数
のウィンドウの扱いに慣れれば、翻訳者はより快適になるでしょう。

   保留したサブエディットの完了または中止は、編集を開始した順番に関わら
ず任意の順番で行うことができます。複数のサブエディットを保留している状態
で、(‘q’コマンドで)POファイルを閉じようとすると、サブエディットが1つずつ
順番に再開されるので、翻訳者それら個々について決定していくことができます
。

8.3.12 Cソースのコンテキスト
----------------------------

   POモードは、GNU ‘gettext’ユーティリティーで作成されたPOファイルの場合
、それらのユーティリティーが生成したPOファイルに特別なコメントを挿入する
ので、特に威力を発揮します。それらの特別なコメントの中には、POファイルの
エントリーの未翻訳の文字列が、プログラムのソース中で出現する位置を示すも
のがあります。

   翻訳者が未翻訳の文字列を翻訳するとき、その元文字列があまりに簡潔すぎ
たり、不可解あったり、曖昧である等、通常のように有効でない場合があります
。そのような文字列をどのように翻訳するか決める前に、その文字列が本当は何
を意味するのか、そしてそれにぴったりな翻訳は何なのかを理解する必要があり
ます。このような問題を判断するために残された唯一の方法は、プログラムのソ
ースからその文字列の場所を探し、その周辺に残されたプログラマーのコメント
や、他に助けになりそうな_何か_を探すことに時間を割くことです。

   翻訳者が有能なプログラマーである場合、プログラムのソースを見ることに
より多くの助けを得ることができるでしょう。しかしプログラミングに精通して
いなくて、Cのコードを見ると不安な気持ちになったとしても、恥ずかしがらず
にたまにはソースを見てみましょう。そうすれば彼女が必要とする何らかのヒン
トを得られるようになれるでしょう。プログラマーのコメント、そして(彼が適
切な名前をつけていれば)変数名や関数名、プログラムコード自体の全体的な構
成などに注意を払って学習することにより、すぐにプログラムのコードを見ても
違和感を感じないようになるでしょう。

   以下は、翻訳者がPOファイルのエントリーから、プログラムのソースコンテ
キストを参照するのに助けとなるコマンドです。

‘s’
     プログラムのソースコンテキストを表示、またはソースコンテキストのサ
     イクル表示を再開します(‘po-cycle-source-reference’)。

‘M-s’
     メニューで選択されたプログラムソースのコンテキストを表示します
     (‘po-select-source-reference’)。

‘S’
     ソースファイルの検索パスにディレクトリを追加します
     (‘po-consider-source-path’)。

‘M-S’
     ソースファイルの検索パスからディレクトリを削除します
     (‘po-ignore-source-path’)。

   ‘s’コマンド(‘po-cycle-source-reference’)と‘M-s’コマンド
(‘po-select-source-reference’)は、どちらも他のウィンドウを開いてプログラ
ムのソースファイルの、翻訳しようとしている文字列が使用されている場所を表
示します。このように、これらのコマンドは文字列にたいするソースプログラム
のコンテキストを与えます。しかしエントリーがコンテキストへの参照を保有し
ていなかったり、検索パスにあるプログラムソースでは参照が解決されない場合
、コマンドはその旨をエラーとして表示します。

   ‘s’(または‘M-s’)も新しいウィンドウをオープンしますが、カーソルはPOフ
ァイルのウィンドウに留まったままです。翻訳者がプログラムソースのウィンド
ウに移動したい場合には、明示的にOコマンドを使用する必要があります。

   はじめて‘s’を使用するときや、POファイルのエントリーのソースコンテキス
トが直前に取得したものと異なるときには、コマンドはこのエントリーにたいし
て利用可能な、最初のコンテキストを返します。すでにそのPOファイルのカレン
トエントリーにたいする、何かしらのコンテキストを表示していて、さらに他の
ものを探したいときには最後に表示したコンテキストのウィンドウで‘s’を入力
することにより、検索を再開できます。このコマンドにより、翻訳者がソースフ
ァイルのコンテキストからカーソルを移動していた場合には、カーソルがコンテ
キストの場所に戻されます。他のコマンドを入力しないで‘s’コマンドを連続し
て入力すると、POモードはこのエントリーにたいして利用可能なコンテキストを
順々に表示していき、最後のコンテキストを表示すると、また最初のコンテキス
トに戻って表示します。

   ‘M-s’コマンドは異なる動作をします。このコマンドは参照を循環して表示せ
ずに、いくつか存在する参照のうちから1つを翻訳者に選択させます。翻訳者が
‘M-s’で表示される質問にたいして、すぐに‘<TAB>’を押すと、翻訳者が適切なも
のを選べるように利用可能なすべての参照メニューが表示されます。このコマン
ドは翻訳する1つの文字列にたいして、多数の利用可能なコンテキストが存在す
るときに有用です。

   プログラムのソースファイルは通常、POファイルの場所から相対的に見つけ
ることができます。この検索が失敗したときには、特別なケースとしてPOファイ
ルの1つ上のディレクトリーからの相対パスのファイルも検索対象になります。
これらの2つのケースを考えておけば、大抵のPOファイルを処理することができ
ます。しかしPOファイルが移動されていたり、通常あるべき場所とは異なる場所
で編集されているときには検索が失敗します。このような場合には、翻訳者が
POモードにたいして、POファイルが本来どのディレクトリーにあるのかを、伝え
る必要があります。そのように指定したディレクトリーのことをまとめて、プロ
グラムソースの“検索パス”と呼びます。‘S’コマンド
(‘po-consider-source-path’)は、検索パスに新しいディレクトリーを対話的に
入力するために使用され、‘M-S’コマンド(‘po-ignore-source-path’)は、検索パ
スから削除したいディレクトリーを選択して削除するのに使用されます。

8.3.13 追加POファイルを調べる
-----------------------------

   POモードには、複数の言語に通じている翻訳者が、彼女の知っている言語へ
の既存の翻訳を利用するための機能があります。この機能は、他の言語への翻訳
を追加のコンテキストとして、彼女の作業に提供することができます。また一度
に複数の言語への翻訳を作成したいような場合にも、翻訳者にたいして作業を容
易にするための機能をもっています。

   “追加(auxiliary)”のPOファイルとは、翻訳者が作業するパッケージの、他の
言語用の既存のPOファイルのことです。追加のPOファイルを定義・処理したり、
作業中のエントリーのコンテキストを表示するためのコマンドが存在します。

   以下は、POモードで利用可能な、追加のPOファイルのコマンドです。

‘a’
     追加のPOファイルから、同じエントリーにたいする他の翻訳を探します
     (‘po-cycle-auxiliary’)。

‘C-c C-a’
     追加のPOファイルを指定して、それに切り替えます
     (‘po-select-auxiliary’)。

‘A’
     表示しているPOファイルを、追加のPOファイルとして定義します
     (‘po-consider-as-auxiliary’)。

‘M-A’
     表示しているPOファイルを、追加のPOファイルのリストから削除します
     (‘po-ignore-as-auxiliary’)。

   ‘A’コマンド(‘po-consider-as-auxiliary’)は、現在のPOファイルを、追加の
PO ファイルのリストに追加し、‘M-A’コマンド(‘po-ignore-as-auxiliary’は、
リストから削除します。

   ‘a’コマンド(‘po-cycle-auxiliary’)は、すべての追加POファイルを一つずつ
走査して、カレントエントリーと同じ‘msgid’にたいする、他の言語に翻訳され
たエントリーを検索するコマンドです。POファイルが見つかったら、そのPOファ
イルが現在のウィンドウに表示されます(そのウィンドウがもっとも前面に表示
されます)。追加のPOファイルに作業中のPOファイルが含まれていない場合は、
これらの処理を行う前に追加しておくとよいでしょう。このようにしておけば、
‘a’コマンドで検索された他言語のPOファイルがウィンドウに表示されても、
‘a’コマンドを繰り返し入力して、元のPOファイルに戻ることができるからです
。

   ‘C-c C-a’コマンド(‘po-select-auxiliary’)は、翻訳者にたいして追加の
POファイルを補完付き入力で選択させて、そのPOファイルに切り替えるコマンド
です。選択したPOファイルにカレントエントリーと同じ‘msgid’があった場合は
、そのエントリーをカレントエントリーとします。同じエントリー存在しない場
合には、カーソルは元の位置から変更されません。

   この機能が完全に動作するためには、‘msgid’が、同じ方法で_正確_に、正規
化されて記述されている必要があります。たとえ文字列を記述する方法は異なっ
ていても‘msgid’に同じ文字列が設定されていれば問題はありませんが、違う文
字列が記述されていると、POモードの追加POファイル関連のコマンドの動作が損
なわれてしまいます。しかしほとんどのPOファイルの‘msgid’は、同じGNU
‘gettext’ツールで書き込まれたものなので、実際には問題になることはないで
しょう。

   しかしソースファイルの文字列をマークしながら、POモードで一から作成し
たPOファイルは、異なる形式で正規化されています。そのために‘M-x
normalize’コマンドをPOファイルに適用するのです。POモードと他のGNU
‘gettext’ツール間の矛盾を解決するまでは、翻訳者は正規化の問題に留意して
ください。

8.4 翻訳compendiaの使用
=======================

   “compendium(要約)”とは、多くのパッケージで繰り返し使用される翻訳を含
んだ特別なPOファイルのことです。翻訳者はgettextツールを使って、新しい
compendiumを構築して、compendiumに含まれた翻訳から、エントリーを
compendium に追加したり、未翻訳エントリーの初期化、既存の翻訳済みエント
リーの更新できます。

8.4.1 compendiaの作成
---------------------

   基本的に、すべてのPOファイルに含まれる翻訳済みエントリーだけを、有効
なcompendiumとして定義できます。翻訳者が特別なcompendiaを所有したい場合
があります。‘連結POファイル(concatenating PO files)’と‘POファイルからメ
ッセージを抽出したサブセット(extracting a message subset from a PO
file)’という、2つのケースを考えてみましょう。

8.4.1.1 POファイルの連結
........................

   複数の有効なPOファイルを、1つのcompendiumファイルに連結するためには、
‘msgcomm’か、‘msgcat’(推奨)を使用することができます:

     msgcat -o compendium.po file1.po file2.po

   デフォルトでは‘msgcat’は、同じ文字列にたいして異なる翻訳がある場合に
は、それらの翻訳を蓄積します。これらの複数の翻訳には‘fuzzy’マークが付与
されるとともに、目立つように装飾されます。たとえば以下のような2つのファ
イルがあるとします。‘file1.po’は以下のような内容です:

     #: src/hello.c:200
     #, c-format
     msgid "Report bugs to <%s>.\n"
     msgstr "Comunicar `bugs' a <%s>.\n"

そして‘file2.po’です:

     #: src/bye.c:100
     #, c-format
     msgid "Report bugs to <%s>.\n"
     msgstr "Comunicar \"bugs\" a <%s>.\n"

これらにたいして‘msgcat’を呼び出すと、以下のような結果になります:

     #: src/hello.c:200 src/bye.c:100
     #, fuzzy, c-format
     msgid "Report bugs to <%s>.\n"
     msgstr ""
     "#-#-#-#-#  file1.po  #-#-#-#-#\n"
     "Comunicar `bugs' a <%s>.\n"
     "#-#-#-#-#  file2.po  #-#-#-#-#\n"
     "Comunicar \"bugs\" a <%s>.\n"

“競合”は翻訳者が手動で解決する必要があります。彼女は最初のバージョンが適
しているのか、それとも2番目のバージョンなのか(それとも新しい翻訳を提供す
る必要があるのか)を決定して、“マーカー行”を削除し、‘fuzzy’マークをはずす
必要があります。

   最初に検索される翻訳済みのメッセージが常に最善の翻訳であることを翻訳
者が知っている場合は、‘--use-first’スイッチを使用できます:

     msgcat --use-first -o compendium.po file1.po file2.po

   よいcompendium ファイルを作るには、‘fuzzy’や未翻訳エントリーを含めて
はいけません。入力ファイルがそのようなエントリーで“汚染”されている場合は
、‘msgattrib --translated --no-fuzzy’を使って入力ファイルを前処理するか
、結果ファイルを後処理しなければなりません。

8.4.1.2 POファイルからのメッセージサブセットの抽出
..................................................

   同じメッセージを何度も翻訳したいと思う人はいないでしょう。たとえば、
あなたが‘getopt.c’のメッセージを含んだcompendiumファイルが欲しいと思うか
もしれません。

   既存のPOファイルから1つのcompendiumにメッセージのサブセット(例:
‘getopt.c’のすべてのメッセージ)を抽出する場合は、‘msggrep’を使用できます
。

     msggrep --location src/getopt.c -o compendium.po file.po

8.4.2 compendiaの使用
---------------------

   compendiumファイルを使用して、スクラッチから翻訳を初期化したり、既存
の翻訳を更新できます。

8.4.2.1 新しい翻訳ファイルの初期化
..................................

   まだ翻訳されたPOファイルが存在しないときは、“古い”翻訳済みファイルと
して‘/dev/null’を使用できます。

     msgmerge --compendium compendium.po -o file.po /dev/null file.pot

8.4.2.2 既存の翻訳ファイルの更新
................................

   compendiumファイルと既存のPOファイルを結合した後、それをマージして
POTファイルを作成し、陳腐化したエントリーを削除します(これは任意です。こ
こでは‘msgattrib’が使用されています)。

     msgcat --use-first -o update.po compendium1.po compendium2.po file.po
     msgmerge update.po file.pot | msgattrib --no-obsolete > file.po

9 POファイルの操作
******************

   POファイルを手で扱うよりは、自動的な方法で取り扱うほうがよいときがあ
ります。GNU ‘gettext’には、この目的のための完全なツールが含まれています
。

   2つのパッケージを1つのパッケージにマージするときには、元の2つのパッケ
ージのPOTファイルが結合されたものが、マージされたパッケージのPOTファイル
になります。したがってメンテナーは、翻訳された各言語ごとに、既存の2つの
翻訳済みパッケージを1つの翻訳カタログにマージしなければなりません。これ
を行うには‘msgcat’を使うのが最善です。マージにより発生し得る競合を解決す
るのは、翻訳者の役目となります。

   ある翻訳者が他の翻訳者から作業を引き継ぐときに、彼女がそのlocaleの異
なるエンコーディングを使っている場合には、カタログの文字のエンコーディン
グを変換することになるでしょう。これを行うには‘msgconv’プログラムを使う
のが最善です。

   メンテナーが他のパッケージからタグ付けされたメッセージを取得するとき
、彼はこのソースファイルの既存の翻訳も取り込む必要があります(翻訳者が同
じ作業をしなくても済むように)。これを行うには‘msggrep’を使う方法と、その
ソースファイルからPOTファイルを作成して‘msgmerge’を使う方法があります。

   翻訳者がある翻訳カタログを特定の方言や正書法に適応させたいとき – たと
えばSwitzerlandで記述されたGermanを、Germanyで記述されたGerman に適応さ
せる場合など – 彼女はカタログの中のすべてのメッセージに適用できるテキス
トプロセッサーが必要にるでしょう。これを行うためのツールが、
‘msgfilter’です。

   ‘msgfilter’の他の使い方としては、POファイルが作成される元となった
POTファイルに近いものを生成することです。これは、‘msgfilter sed -e d |
sed -e '/^# /d'’のようなフィルターコマンドにより行うことができます。オリ
ジナルのPOTファイルには異なるコメントがあったり、plural messageの数も異
なります。この理由により、利用可能ならオリジナルのPOTファイルを使うほう
がよいことに注意してください。

   翻訳者が翻訳をチェックしたいとき、たとえば正書法のルールや非対話型の
スペルチェッカーにしたがってチェックをしたいときは、‘msgexec’を使うこと
ができます。

   サードパーティー製のツールによりPO、またはPOTファイルを作成するとき、
重複が無視されるときがあります。しかしGNU ‘gettext’ツールは、同じファイ
ル中に同じドメインで重複したmsgidがある場合にはエラーとなります。重複を
マージするためには、‘msguniq’を使うことができます。

   複数のファイル間での重複を維持(または破棄)するための、より一般的なツ
ールとしては‘msgcomm’があります。

   翻訳カタログが完全に翻訳されているかをチェックするには、‘msgcmp’を使
うことができます。

   翻訳カタログからfuzzyや未翻訳のメッセージだけを選択・抽出するためには
、‘msgattrib’を使うことができます。

   Englishの翻訳カタログを準備するための最初のステップとしては、
‘msgen’が便利です。これは、各メッセージのmsgidをmsgstrにコピーします。

   そして最後に、これらの様々なアプリケーションでも十分でない場合には、
POファイルを取り扱う特殊なプログラムを記述するために使用できる、
‘libgettextpo’ライブラリーが提供されています。

9.1 ‘msgcat’プログラムの呼び出し
================================

     msgcat [OPTION] [INPUTFILE]...

   ‘msgcat’プログラムは、指定されたPOファイルを結合・マージするプログラ
ムです。プログラムは、指定された複数のPOファイルの中から、2つ以上のファ
イルで使用されている共通のメッセージを見つけます。‘--more-than’オプショ
ンを使うと、指定したファイル数より多くのファイルで共通のメッセージを出力
するか指定できます。反対に‘--less-than’オプションでは、指定したファイル
数より少ないファイルで共通のメッセージを出力するか指定できます(例
‘--less-than=2’ と指定すると一意なメッセージだけが出力されます)。翻訳や
コメントは累積されますが、‘--use-first’を指定した場合は、指定されたPOフ
ァイルのうちで最初のものを採用します。すべてのPOファイルの位置情報も累積
されます。

9.1.1 入力ファイルの位置
------------------------

‘INPUTFILE ...’
     入力ファイルです。

‘-f FILE’
‘--files-from=FILE’
     入力ファイルの名前を、コマンドラインからではなく、FILEから読み込み
     ます。

‘-D DIRECTORY’
‘--directory=DIRECTORY’
     ディレクトリーのリストにDIRECTORYを追加します。このディレクトリーの
     リストよりソースファイルを検索します。しかし‘.po’ファイルが出力され
     るのは、カレントディレクトリーです。

   INPUTFILEに‘-’が指定された場合は、標準入力から読み込みます。

9.1.2 出力ファイルの位置
------------------------

‘-o FILE’
‘--output-file=FILE’
     指定されたファイルに出力を書き込みます。

   出力ファイルが指定されていない、または‘-’が指定された場合、結果は標準
出力に出力されます。

9.1.3 メッセージ選択
--------------------

‘-< NUMBER’
‘--less-than=NUMBER’
     NUMBERに指定した数より少ないメッセージを出力します。指定しなかった
     場合のデフォルトは無限大です。

‘-> NUMBER’
‘--more-than=NUMBER’
     NUMBERに指定した数より大きいメッセージを出力します。指定しなかった
     場合のデフォルトは0です。

‘-u’
‘--unique’
     ‘--less-than=2’の省略指定です。一意なメッセージだけを出力します。

9.1.4 入力ファイルの構文
------------------------

‘-P’
‘--properties-input’
     入力ファイルがPOファイルの構文ではなく、Javaの‘.properties’の構文に
     のっとったJava ResourceBundleファイルだとみなします。

‘--stringtable-input’
     入力ファイルがPOファイルの構文ではなく、NeXTstep/GNUstepのlocalized
     resourceの‘.strings’の構文にのっとったファイルだとみなします。

9.1.5 出力の詳細
----------------

‘-t’
‘--to-code=NAME’
     出力のエンコーディングを指定します。

‘--use-first’
     各メッセージで利用可能な最初のメッセージを使用します。複数の翻訳を
     1つにマージしません。

‘--lang=CATALOGNAME’
     ヘッダーのエントリーで使用される、‘Language’フィールドを指定します
     。このフィールドの意味については、see Header Entryを参照してく
     ださい。‘Language-Team’と‘Plural-Forms’のフィールドは変更されないこ
     とに注意してください。

‘--color’
‘--color=WHEN’
     色や色以外のテキスト属性を使うか、いつ使うかを指定します。詳細は
     The --color optionを参照してください。

‘--style=STYLE_FILE’
     ‘--color’にたいしてCSS style ruleファイルを使うかを指定します。詳細
     はThe --style optionを参照してください。

‘--force-po’
     メッセージが何も含まれていない場合でも、常に出力ファイルに書き込み
     ます。

‘-i’
‘--indent’
     インデントされた形式で.poファイルを書き込みます。

‘--no-location’
     ‘#: FILENAME:LINE’という行を書き込みません。

‘-n’
‘--add-location’
     ‘#: FILENAME:LINE’という行を生成します(デフォルト)。

‘--strict’
     Uniforumに厳密に準拠したPOファイルを出力します。このUniforum形式は
     GNUの拡張をサポートしないため避けたほうがよいでしょう。

‘-p’
‘--properties-output’
     Javaの‘.properties’の書式で、Java ResourceBundleを出力します。この
     ファイル形式はplural formをサポートせず、陳腐化したメッセージを暗黙
     で除去することに注意してください。

‘--stringtable-output’
     ‘.strings’の書式で、NeXTstep/GNUstepのローカライズされたリソースフ
     ァイルを出力します。このファイル形式はplural formをサポートしないこ
     とに注意してください。

‘-w NUMBER’
‘--width=NUMBER’
     出力ページの幅をセットします。これにより出力ファイル中の長い文字列
     が指定した幅(例:スクリーンの列数)に収まるように、各行の長さが
     NUMBER以下のような複数の行に分割されます。

‘--no-wrap’
     長いメッセージ行を分割しません。出力ページの幅を超えるようなメッセ
     ージ行も、複数行に分割されません。出力ページの幅を超えるファイル参
     照行だけが分割されます。

‘-s’
‘--sort-output’
     ソートされた出力を生成します。このオプションを使用することにより翻
     訳者が、メッセージがどのようなコンテキストで使用されるかを理解する
     のが、困難になることに注意してください。

‘-F’
‘--sort-by-file’
     ファイルの場所により出力をソートします。

9.1.6 情報的な出力
------------------

‘-h’
‘--help’
     このヘルプを表示して終了します。

‘-V’
‘--version’
     バージョン情報を表示して終了します。

9.2 ‘msgconv’プログラムの呼び出し
=================================

     msgconv [OPTION] [INPUTFILE]

   ‘msgconv’は、ある翻訳カタログを別の文字エンコーディングに変換するプロ
グラムです。

9.2.1 入力ファイルの位置
------------------------

‘INPUTFILE’
     入力となるPOファイルです。

‘-D DIRECTORY’
‘--directory=DIRECTORY’
     ディレクトリーのリストにDIRECTORYを追加します。このディレクトリーの
     リストよりソースファイルを検索します。しかし‘.po’ファイルが出力され
     るのは、カレントディレクトリーです。

   INPUTFILEが指定されていないか、‘-’が指定された場合は、標準入力から読
み込みます。

9.2.2 出力ファイルの位置
------------------------

‘-o FILE’
‘--output-file=FILE’
     指定されたファイルに出力を書き込みます。

   出力ファイルが指定されていない、または‘-’が指定された場合、結果は標準
出力に出力されます。

9.2.3 変換する対象
------------------

‘-t’
‘--to-code=NAME’
     出力のエンコーディングを指定します。

   デフォルトのエンコーディングは、現在のロケールのエンコーディングです
。

9.2.4 入力ファイルの構文
------------------------

‘-P’
‘--properties-input’
     入力ファイルがPOファイルの構文ではなく、Javaの‘.properties’の構文に
     のっとったJava ResourceBundleファイルだとみなします。

‘--stringtable-input’
     入力ファイルがPOファイルの構文ではなく、NeXTstep/GNUstepのlocalized
     resourceの‘.strings’の構文にのっとったファイルだとみなします。

9.2.5 出力の詳細
----------------

‘--color’
‘--color=WHEN’
     色や色以外のテキスト属性を使うか、いつ使うかを指定します。詳細は
     The --color optionを参照してください。

‘--style=STYLE_FILE’
     ‘--color’にたいしてCSS style ruleファイルを使うかを指定します。詳細
     はThe --style optionを参照してください。

‘--force-po’
     メッセージが何も含まれていない場合でも、常に出力ファイルに書き込み
     ます。

‘-i’
‘--indent’
     インデントされた形式で.poファイルを書き込みます。

‘--no-location’
     ‘#: FILENAME:LINE’という行を書き込みません。

‘--add-location’
     ‘#: FILENAME:LINE’という行を生成します(デフォルト)。

‘--strict’
     Uniforumに厳密に準拠したPOファイルを出力します。このUniforum形式は
     GNUの拡張をサポートしないため避けたほうがよいでしょう。

‘-p’
‘--properties-output’
     Javaの‘.properties’の書式で、Java ResourceBundleを出力します。この
     ファイル形式はplural formをサポートせず、陳腐化したメッセージを暗黙
     で除去することに注意してください。

‘--stringtable-output’
     ‘.strings’の書式で、NeXTstep/GNUstepのローカライズされたリソースフ
     ァイルを出力します。このファイル形式はplural formをサポートしないこ
     とに注意してください。

‘-w NUMBER’
‘--width=NUMBER’
     出力ページの幅をセットします。これにより出力ファイル中の長い文字列
     が指定した幅(例:スクリーンの列数)に収まるように、各行の長さが
     NUMBER以下のような複数の行に分割されます。

‘--no-wrap’
     長いメッセージ行を分割しません。出力ページの幅を超えるようなメッセ
     ージ行も、複数行に分割されません。出力ページの幅を超えるファイル参
     照行だけが分割されます。

‘-s’
‘--sort-output’
     ソートされた出力を生成します。このオプションを使用することにより翻
     訳者が、メッセージがどのようなコンテキストで使用されるかを理解する
     のが、困難になることに注意してください。

‘-F’
‘--sort-by-file’
     ファイルの場所により出力をソートします。

9.2.6 情報的な出力
------------------

‘-h’
‘--help’
     このヘルプを表示して終了します。

‘-V’
‘--version’
     バージョン情報を表示して終了します。

9.3 ‘msggrep’プログラムの呼び出し
=================================

     msggrep [OPTION] [INPUTFILE]

   ‘msggrep’は翻訳カタログから、指定したパターン、指定したソースファイル
に属するすべてのメッセージを抽出するプログラムです。

9.3.1 入力ファイルの位置
------------------------

‘INPUTFILE’
     入力となるPOファイルです。

‘-D DIRECTORY’
‘--directory=DIRECTORY’
     ディレクトリーのリストにDIRECTORYを追加します。このディレクトリーの
     リストよりソースファイルを検索します。しかし‘.po’ファイルが出力され
     るのは、カレントディレクトリーです。

   INPUTFILEが指定されていないか、‘-’が指定された場合は、標準入力から読
み込みます。

9.3.2 出力ファイルの位置
------------------------

‘-o FILE’
‘--output-file=FILE’
     指定されたファイルに出力を書き込みます。

   出力ファイルが指定されていない、または‘-’が指定された場合、結果は標準
出力に出力されます。

9.3.3 メッセージ選択
--------------------

       [-N SOURCEFILE]... [-M DOMAINNAME]...
       [-J MSGCTXT-PATTERN] [-K MSGID-PATTERN] [-T MSGSTR-PATTERN]
       [-C COMMENT-PATTERN]

   以下のような場合、メッセージが選択されます
   • 指定したソースファイルのいずれかに属するメッセージの場合
   • 指定したdomainのいずれかに属するメッセージの場合
   • ‘-J’が指定されていて、メッセージのコンテキスト(msgctxt)が
     MSGCTXT-PATTERNにマッチする場合
   • ‘-K’が指定されていて、メッセージのキー(msgid または msgid_plural)が
     MSGID-PATTERNにマッチする場合
   • ‘-T’が指定されていて、翻訳(msgstr)が MSGSTR-PATTERNにマッチする場合
   • ‘-C’が指定されていて、翻訳者のコメントが COMMENT-PATTERNにマッチす
     る場合

   1つ以上の条件を指定した場合には、それぞれの条件に適合するメッセージの
がすべて選択されます。

   MSGCTXT-PATTERN、MSGID-PATTERN、MSGSTR-PATTERNの書式です:
       [-E | -F] [-e PATTERN | -f FILE]...
   PATTERNにはデフォルトでは標準の正規表現(POSIX Basic Regular
Expressions: grep -eと同等)を指定します。拡張された正規表現(POSIX
Extended Regular Expressions: egrep, grep -Eと同等)の場合は-Eを、固定文
字列の場合(Fixed String search: fgrep, grep -Fと同等)には-Fを指定してく
ださい。

‘-N SOURCEFILE’
‘--location=SOURCEFILE’
     SOURCEFILEから抽出されたメッセージを選択します。SOURCEFILEにはファ
     イル名の文字列、またはワイルドカード文字列を指定できます。

‘-M DOMAINNAME’
‘--domain=DOMAINNAME’
     ドメインDOMAINNAMEに属するメッセージを選択します。

‘-J’
‘--msgctxt’
     msgctxtを選択するためのパターンの開始を宣言します。

‘-K’
‘--msgid’
     msgidを選択するためのパターンの開始を宣言します。

‘-T’
‘--msgstr’
     msgstrを選択するためのパターンの開始を宣言します。

‘-C’
‘--comment’
     翻訳者コメントを選択するためのパターンの開始を宣言します。

‘-X’
‘--extracted-comment’
     抽出コメントを選択するためのパターンの開始を宣言します。

‘-E’
‘--extended-regexp’
     PATTERNが、拡張された正規表現であることを指定します。

‘-F’
‘--fixed-strings’
     PATTERNが、改行で区切られた一連の文字列であることを指定します。

‘-e PATTERN’
‘--regexp=PATTERN’
     PATTERNを、正規表現として使用します。

‘-f FILE’
‘--file=FILE’
     PATTERNを、FILEから取得します。

‘-i’
‘--ignore-case’
     大文字と小文字を区別しません。

‘-v’
‘--invert-match’
     条件に一致するメッセージではなく、一致しないメッセージだけを出力し
     ます。

9.3.4 入力ファイルの構文
------------------------

‘-P’
‘--properties-input’
     入力ファイルがPOファイルの構文ではなく、Javaの‘.properties’の構文に
     のっとったJava ResourceBundleファイルだとみなします。

‘--stringtable-input’
     入力ファイルがPOファイルの構文ではなく、NeXTstep/GNUstepのlocalized
     resourceの‘.strings’の構文にのっとったファイルだとみなします。

9.3.5 出力の詳細
----------------

‘--color’
‘--color=WHEN’
     色や色以外のテキスト属性を使うか、いつ使うかを指定します。詳細は
     The --color optionを参照してください。

‘--style=STYLE_FILE’
     ‘--color’にたいしてCSS style ruleファイルを使うかを指定します。詳細
     はThe --style optionを参照してください。

‘--force-po’
     メッセージが何も含まれていない場合でも、常に出力ファイルに書き込み
     ます。

‘--indent’
     インデントされた形式で.poファイルを書き込みます。

‘--no-location’
     ‘#: FILENAME:LINE’という行を書き込みません。

‘--add-location’
     ‘#: FILENAME:LINE’という行を生成します(デフォルト)。

‘--strict’
     Uniforumに厳密に準拠したPOファイルを出力します。このUniforum形式は
     GNUの拡張をサポートしないため避けたほうがよいでしょう。

‘-p’
‘--properties-output’
     Javaの‘.properties’の書式で、Java ResourceBundleを出力します。この
     ファイル形式はplural formをサポートせず、陳腐化したメッセージを暗黙
     で除去することに注意してください。

‘--stringtable-output’
     ‘.strings’の書式で、NeXTstep/GNUstepのローカライズされたリソースフ
     ァイルを出力します。このファイル形式はplural formをサポートしないこ
     とに注意してください。

‘-w NUMBER’
‘--width=NUMBER’
     出力ページの幅をセットします。これにより出力ファイル中の長い文字列
     が指定した幅(例:スクリーンの列数)に収まるように、各行の長さが
     NUMBER以下のような複数の行に分割されます。

‘--no-wrap’
     長いメッセージ行を分割しません。出力ページの幅を超えるようなメッセ
     ージ行も、複数行に分割されません。出力ページの幅を超えるファイル参
     照行だけが分割されます。

‘--sort-output’
     ソートされた出力を生成します。このオプションを使用することにより翻
     訳者が、メッセージがどのようなコンテキストで使用されるかを理解する
     のが、困難になることに注意してください。

‘--sort-by-file’
     ファイルの場所により出力をソートします。

9.3.6 情報的な出力
------------------

‘-h’
‘--help’
     このヘルプを表示して終了します。

‘-V’
‘--version’
     バージョン情報を表示して終了します。

9.3.7 例
--------

   ‘gnulib-lib/error.c’と‘gnulib-lib/getopt.c’というソースファイルからメ
ッセージを抽出する場合:

     msggrep -N gnulib-lib/error.c -N gnulib-lib/getopt.c input.po

   “Please specify”という文字列が含まれるメッセージを抽出する場合:

     msggrep --msgid -F -e 'Please specify' input.po

   “Menu>File”、“Menu>Edit”またはそれらのサブメニューであることを指定す
るコンテキストをもつメッセージを抽出する場合:

     msggrep --msgctxt -E -e '^Menu>(File|Edit)' input.po

   翻訳文字列に‘wordlist.txt’というファイル中の文字列を含むメッセージを
抽出する場合:

     msggrep --msgstr -F -f wordlist.txt input.po

9.4 ‘msgfilter’プログラムの呼び出し
===================================

     msgfilter [OPTION] FILTER [FILTER-OPTION]

   ‘msgfilter’は、翻訳カタログ内の翻訳にフィルターを適用するためのプログ
ラムです。

   それぞれのFILTER呼び出しにおいて、環境変数の‘MSGFILTER_MSGID’と
‘MSGFILTER_LOCATION’に、メッセージのmsgidとメッセージを含むPOファイルの
場所がバインドされます。メッセージがコンテキストを保有する場合は、環境変
数‘MSGFILTER_MSGCTXT’がメッセージのコンテキストにバインドされます(コンテ
キストを保有していない場合にはバインドされません)。

9.4.1 入力ファイルの位置
------------------------

‘-i INPUTFILE’
‘--input=INPUTFILE’
     入力となるPOファイルです。

‘-D DIRECTORY’
‘--directory=DIRECTORY’
     ディレクトリーのリストにDIRECTORYを追加します。このディレクトリーの
     リストよりソースファイルを検索します。しかし‘.po’ファイルが出力され
     るのは、カレントディレクトリーです。

   INPUTFILEが指定されていないか、‘-’が指定された場合は、標準入力から読
み込みます。

9.4.2 出力ファイルの位置
------------------------

‘-o FILE’
‘--output-file=FILE’
     指定されたファイルに出力を書き込みます。

   出力ファイルが指定されていない、または‘-’が指定された場合、結果は標準
出力に出力されます。

9.4.3 フィルター
----------------

   FILTERは、標準入力から翻訳を読み込み、それに変更を加えて標準出力に書
き込むプログラムです。フィルターとして頻繁に使用されるプログラムとしては
‘sed’があります。その他にも認識できるビルトインフィルターがいくつか存在
します。

   注意: ビルトインではないフィルターの場合には、エンコーディングに注意
する必要があります。FILTERが、入力となる翻訳カタログのエンコードに対処で
きるようにするのは、あなたの責任となります。FILTERが入力として特定のエン
コーディングを期待する場合には、‘msgfilter’を呼び出す前に、最初のステッ
プとして‘msgconv’で翻訳カタログをそのエンコーディングに変換できます。
FILTERが入力としてlocaleのエンコーディングを期待しているけれど、あなたは
localeのエンコーディングを無視したいときには、最初に‘msgconv’で翻訳カタ
ログをUTF-8に変換してから、環境変数‘LC_ALL’にUTF-8 localeを指定して、
‘msgfilter’を使うことができます。

   注意: 翻訳カタログ内のほとんどの翻訳は改行で終端されていません。その
ため、入力の最終行が改行で終端されていなくても、FILTERがそれを認識するこ
と、そして最終行に余分な改行を付加しないことが重要になります。いくつかの
プラットフォームにおいて‘sed’が、改行で終端されていない最終行を無視する
ことが知られています。代用として、このような制限を持たないGNU ‘sed’を使
うことができます。

9.4.4 FILTERが‘sed’のときの便利なFILTER-OPTION
----------------------------------------------

‘-e SCRIPT’
‘--expression=SCRIPT’
     実行するコマンドにSCRIPTを追加します。

‘-f SCRIPTFILE’
‘--file=SCRIPTFILE’
     実行するコマンドに、SCRIPTFILEの内容を追加します。

‘-n’
‘--quiet’
‘--silent’
     パターンの空白の出力を自動的に抑制します。

9.4.5 ビルトインのFILTER
------------------------

   ‘recode-sr-latin’はビルトインのフィルターとして認識されます。
‘recode-sr-latin’は、Cyrillic文字で記述されたSerbianのテキストを、
Latin文字に変換するコマンドです。‘msgfilter recode-sr-latin’コマンドによ
り、POファイルの翻訳にたいしてこの変換を適用できます。これを使えば
‘sr.po’ファイルを、‘sr@latin.po’ファイルに変換できます。

   ビルトインのフィルターは、現在のロケールのエンコーディングとは無関係
です。またビルトインのフィルターを使う場合、‘msgfilter’はメッセージカタ
ログのエンコーディングを自動的にUTF-8に変換することができます。

9.4.6 入力ファイルの構文
------------------------

‘-P’
‘--properties-input’
     入力ファイルがPOファイルの構文ではなく、Javaの‘.properties’の構文に
     のっとったJava ResourceBundleファイルだとみなします。

‘--stringtable-input’
     入力ファイルがPOファイルの構文ではなく、NeXTstep/GNUstepのlocalized
     resourceの‘.strings’の構文にのっとったファイルだとみなします。

9.4.7 出力の詳細
----------------

‘--color’
‘--color=WHEN’
     色や色以外のテキスト属性を使うか、いつ使うかを指定します。詳細は
     The --color optionを参照してください。

‘--style=STYLE_FILE’
     ‘--color’にたいしてCSS style ruleファイルを使うかを指定します。詳細
     はThe --style optionを参照してください。

‘--force-po’
     メッセージが何も含まれていない場合でも、常に出力ファイルに書き込み
     ます。

‘--indent’
     インデントされた形式で.poファイルを書き込みます。

‘--keep-header’
     ヘッダーのエントリーを保持します(例: ‘msgid ""’にフィルターを適用し
     ないで未変更にします)。デフォルトでは、ヘッダーのエントリーにたいし
     ても、他のメッセージと同様にフィルタリングの対象になります。

‘--no-location’
     ‘#: FILENAME:LINE’という行を書き込みません。

‘--add-location’
     ‘#: FILENAME:LINE’という行を生成します(デフォルト)。

‘--strict’
     Uniforumに厳密に準拠したPOファイルを出力します。このUniforum形式は
     GNUの拡張をサポートしないため避けたほうがよいでしょう。

‘-p’
‘--properties-output’
     Javaの‘.properties’の書式で、Java ResourceBundleを出力します。この
     ファイル形式はplural formをサポートせず、陳腐化したメッセージを暗黙
     で除去することに注意してください。

‘--stringtable-output’
     ‘.strings’の書式で、NeXTstep/GNUstepのローカライズされたリソースフ
     ァイルを出力します。このファイル形式はplural formをサポートしないこ
     とに注意してください。

‘-w NUMBER’
‘--width=NUMBER’
     出力ページの幅をセットします。これにより出力ファイル中の長い文字列
     が指定した幅(例:スクリーンの列数)に収まるように、各行の長さが
     NUMBER以下のような複数の行に分割されます。

‘--no-wrap’
     長いメッセージ行を分割しません。出力ページの幅を超えるようなメッセ
     ージ行も、複数行に分割されません。出力ページの幅を超えるファイル参
     照行だけが分割されます。

‘-s’
‘--sort-output’
     ソートされた出力を生成します。このオプションを使用することにより翻
     訳者が、メッセージがどのようなコンテキストで使用されるかを理解する
     のが、困難になることに注意してください。

‘-F’
‘--sort-by-file’
     ファイルの場所により出力をソートします。

9.4.8 情報的な出力
------------------

‘-h’
‘--help’
     このヘルプを表示して終了します。

‘-V’
‘--version’
     バージョン情報を表示して終了します。

9.4.9 例
--------

   Germanの翻訳を、Swissの正書法に変換する場合(UTF-8 locale):

     msgconv -t UTF-8 de.po | msgfilter sed -e 's/ß/ss/g'

   Cyrillic文字の Serbianの翻訳を、Latin文字に変換する場合:

     msgfilter recode-sr-latin < sr.po

9.5 ‘msguniq’プログラムの呼び出し
=================================

     msguniq [OPTION] [INPUTFILE]

   ‘msguniq’は、翻訳カタログ内の重複した翻訳を統一するためのプログラムで
す。このプログラムは、同じメッセージIDにたいする、重複した翻訳を探します
。このような重複したメッセージは、‘msgfmt’、‘msgmerge’、‘msgcat’の入力と
しては無効です。デフォルトでは重複はマージされます。‘--repeated’オプショ
ンを指定すると、重複したメッセージだけが出力され、他のすべてのメッセージ
は破棄されます。コメント、および抽出されたコメントは累積されます。ただし
‘--use-first’が指定された場合には、最初の翻訳のものが使用されます。
‘--unique’オプションを使用すると、重複は破棄されます。

9.5.1 入力ファイルの位置
------------------------

‘INPUTFILE’
     入力となるPOファイルです。

‘-D DIRECTORY’
‘--directory=DIRECTORY’
     ディレクトリーのリストにDIRECTORYを追加します。このディレクトリーの
     リストよりソースファイルを検索します。しかし‘.po’ファイルが出力され
     るのは、カレントディレクトリーです。

   INPUTFILEが指定されていないか、‘-’が指定された場合は、標準入力から読
み込みます。

9.5.2 出力ファイルの位置
------------------------

‘-o FILE’
‘--output-file=FILE’
     指定されたファイルに出力を書き込みます。

   出力ファイルが指定されていない、または‘-’が指定された場合、結果は標準
出力に出力されます。

9.5.3 メッセージ選択
--------------------

‘-d’
‘--repeated’
     重複したメッセージだけを出力します。

‘-u’
‘--unique’
     一意なメッセージだけを出力します(重複したメッセージは破棄されます
     )。

9.5.4 入力ファイルの構文
------------------------

‘-P’
‘--properties-input’
     入力ファイルがPOファイルの構文ではなく、Javaの‘.properties’の構文に
     のっとったJava ResourceBundleファイルだとみなします。

‘--stringtable-input’
     入力ファイルがPOファイルの構文ではなく、NeXTstep/GNUstepのlocalized
     resourceの‘.strings’の構文にのっとったファイルだとみなします。

9.5.5 出力の詳細
----------------

‘-t’
‘--to-code=NAME’
     出力のエンコーディングを指定します。

‘--use-first’
     各メッセージで利用可能な最初のメッセージを使用します。複数の翻訳を
     1つにマージしません。

‘--color’
‘--color=WHEN’
     色や色以外のテキスト属性を使うか、いつ使うかを指定します。詳細は
     The --color optionを参照してください。

‘--style=STYLE_FILE’
     ‘--color’にたいしてCSS style ruleファイルを使うかを指定します。詳細
     はThe --style optionを参照してください。

‘--force-po’
     メッセージが何も含まれていない場合でも、常に出力ファイルに書き込み
     ます。

‘-i’
‘--indent’
     インデントされた形式で.poファイルを書き込みます。

‘--no-location’
     ‘#: FILENAME:LINE’という行を書き込みません。

‘-n’
‘--add-location’
     ‘#: FILENAME:LINE’という行を生成します(デフォルト)。

‘--strict’
     Uniforumに厳密に準拠したPOファイルを出力します。このUniforum形式は
     GNUの拡張をサポートしないため避けたほうがよいでしょう。

‘-p’
‘--properties-output’
     Javaの‘.properties’の書式で、Java ResourceBundleを出力します。この
     ファイル形式はplural formをサポートせず、知能化したメッセージを暗黙
     で除去することに注意してください。

‘--stringtable-output’
     ‘.strings’の書式で、NeXTstep/GNUstepのローカライズされたリソースフ
     ァイルを出力します。このファイル形式はplural formをサポートしないこ
     とに注意してください。

‘-w NUMBER’
‘--width=NUMBER’
     出力ページの幅をセットします。これにより出力ファイル中の長い文字列
     が指定した幅(例:スクリーンの列数)に収まるように、各行の長さが
     NUMBER以下のような複数の行に分割されます。

‘--no-wrap’
     長いメッセージ行を分割しません。出力ページの幅を超えるようなメッセ
     ージ行も、複数行に分割されません。出力ページの幅を超えるファイル参
     照行だけが分割されます。

‘-s’
‘--sort-output’
     ソートされた出力を生成します。このオプションを使用することにより翻
     訳者が、メッセージがどのようなコンテキストで使用されるかを理解する
     のが、困難になることに注意してください。

‘-F’
‘--sort-by-file’
     ファイルの場所により出力をソートします。

9.5.6 情報的な出力
------------------

‘-h’
‘--help’
     このヘルプを表示して終了します。

‘-V’
‘--version’
     バージョン情報を表示して終了します。

9.6 ‘msgcomm’プログラムの呼び出し
=================================

     msgcomm [OPTION] [INPUTFILE]...

   ‘msgcomm’は、指定された2つ以上のファイルから、共通のメッセージを探す
プログラムです。‘--more-than’オプションを使用すると、指定された数より多
くのファイルで共通のメッセージを出力します。反対に‘--less-than’オプショ
ンを使用すると、指定された数より少ないファイルで共通のメッセージを出力し
ます(例: ‘--less-than=2’は一意なメッセージだけを出力します)。翻訳、コメ
ント、および抽出されたコメントは蓄積されます(最初のPOファイルのものを使
用するように指定した場合を除く)。POファイルのファイル位置の情報も蓄積さ
れます。

9.6.1 入力ファイルの位置
------------------------

‘INPUTFILE ...’
     入力ファイルです。

‘-f FILE’
‘--files-from=FILE’
     入力ファイルの名前を、コマンドラインからではなく、FILEから読み込み
     ます。

‘-D DIRECTORY’
‘--directory=DIRECTORY’
     ディレクトリーのリストにDIRECTORYを追加します。このディレクトリーの
     リストよりソースファイルを検索します。しかし‘.po’ファイルが出力され
     るのは、カレントディレクトリーです。

   INPUTFILEに‘-’が指定された場合は、標準入力から読み込みます。

9.6.2 出力ファイルの位置
------------------------

‘-o FILE’
‘--output-file=FILE’
     指定されたファイルに出力を書き込みます。

   出力ファイルが指定されていない、または‘-’が指定された場合、結果は標準
出力に出力されます。

9.6.3 メッセージ選択
--------------------

‘-< NUMBER’
‘--less-than=NUMBER’
     NUMBERに指定した数より少ないメッセージを出力します。指定しなかった
     場合のデフォルトは無限大です。

‘-> NUMBER’
‘--more-than=NUMBER’
     NUMBERに指定した数より大きいメッセージを出力します。指定しなかった
     場合のデフォルトは1です。

‘-u’
‘--unique’
     ‘--less-than=2’の省略指定です。一意なメッセージだけを出力します。

9.6.4 入力ファイルの構文
------------------------

‘-P’
‘--properties-input’
     入力ファイルがPOファイルの構文ではなく、Javaの‘.properties’の構文に
     のっとったJava ResourceBundleファイルだとみなします。

‘--stringtable-input’
     入力ファイルがPOファイルの構文ではなく、NeXTstep/GNUstepのlocalized
     resourceの‘.strings’の構文にのっとったファイルだとみなします。

9.6.5 出力の詳細
----------------

‘--color’
‘--color=WHEN’
     色や色以外のテキスト属性を使うか、いつ使うかを指定します。詳細は
     The --color optionを参照してください。

‘--style=STYLE_FILE’
     ‘--color’にたいしてCSS style ruleファイルを使うかを指定します。詳細
     はThe --style optionを参照してください。

‘--force-po’
     メッセージが何も含まれていない場合でも、常に出力ファイルに書き込み
     ます。

‘-i’
‘--indent’
     インデントされた形式で.poファイルを書き込みます。

‘--no-location’
     ‘#: FILENAME:LINE’という行を書き込みません。

‘-n’
‘--add-location’
     ‘#: FILENAME:LINE’という行を生成します(デフォルト)。

‘--strict’
     Uniforumに厳密に準拠したPOファイルを出力します。このUniforum形式は
     GNUの拡張をサポートしないため避けたほうがよいでしょう。

‘-p’
‘--properties-output’
     Javaの‘.properties’の書式で、Java ResourceBundleを出力します。この
     ファイル形式はplural formをサポートせず、陳腐化したメッセージを暗黙
     で除去することに注意してください。

‘--stringtable-output’
     ‘.strings’の書式で、NeXTstep/GNUstepのローカライズされたリソースフ
     ァイルを出力します。このファイル形式はplural formをサポートしないこ
     とに注意してください。

‘-w NUMBER’
‘--width=NUMBER’
     出力ページの幅をセットします。これにより出力ファイル中の長い文字列
     が指定した幅(例:スクリーンの列数)に収まるように、各行の長さが
     NUMBER以下のような複数の行に分割されます。

‘--no-wrap’
     長いメッセージ行を分割しません。出力ページの幅を超えるようなメッセ
     ージ行も、複数行に分割されません。出力ページの幅を超えるファイル参
     照行だけが分割されます。

‘-s’
‘--sort-output’
     ソートされた出力を生成します。このオプションを使用することにより翻
     訳者が、メッセージがどのようなコンテキストで使用されるかを理解する
     のが、困難になることに注意してください。

‘-F’
‘--sort-by-file’
     ファイルの場所により出力をソートします。

‘--omit-header’
     Don’t write header with ‘msgid ""’ entry.

9.6.6 情報的な出力
------------------

‘-h’
‘--help’
     このヘルプを表示して終了します。

‘-V’
‘--version’
     バージョン情報を表示して終了します。

9.7 ‘msgcmp’プログラムの呼び出し
================================

     msgcmp [OPTION] DEF.po REF.pot

   ‘msgcmp’プログラムは、Uniforum形式の2つの.poファイルを比較して、同じ
msgid文字列を含んでいるかチェックするプログラムです。DEF.poファイルは、
翻訳を含んだ既存のPOファイルです。REF.potは、最後に作成したPOファイル、
またはPO Templateファイル(通常‘xgettext’により作成される)です。このプロ
グラムは、プログラム内のメッセージが翻訳されているかチェックするときに便
利です。完全に一致するエントリーが見つからない場合は、より良い診断メッセ
ージを生成するためにfuzzyマッチングが行われます。

9.7.1 入力ファイルの位置
------------------------

‘DEF.po’
     翻訳です。

‘REF.pot’
     ソースへの参照です。

‘-D DIRECTORY’
‘--directory=DIRECTORY’
     ディレクトリーのリストにDIRECTORYを追加します。このディレクトリーの
     リストよりソースファイルを検索します。

9.7.2 オペレーションの修飾
--------------------------

‘-m’
‘--multi-domain’
     DEF.po 内の各ドメインにたいしてREF.potを適用します。

‘-N’
‘--no-fuzzy-matching’
     完全に一致するものが見つからない場合、fuzzyマッチングを行いません。
     これにより処理のスピードが大幅に改善されます。

‘--use-fuzzy’
     DEF.po内のfuzzyメッセージを、翻訳されたメッセージとみなします。
     fuzzyメッセージは翻訳者により検証されていないので、普通はこのオプシ
     ョンを使うのは正しくないことに注意してください。

‘--use-untranslated’
     DEF.po内の未翻訳のメッセージを、翻訳されたメッセージとみなします。
     普通はこのオプションを使うのは正しくないことに注意してください。

9.7.3 入力ファイルの構文
------------------------

‘-P’
‘--properties-input’
     入力ファイルがPOファイルの構文ではなく、Javaの‘.properties’の構文に
     のっとったJava ResourceBundleファイルだとみなします。

‘--stringtable-input’
     入力ファイルがPOファイルの構文ではなく、NeXTstep/GNUstepのlocalized
     resourceの‘.strings’の構文にのっとったファイルだとみなします。

9.7.4 情報的な出力
------------------

‘-h’
‘--help’
     このヘルプを表示して終了します。

‘-V’
‘--version’
     バージョン情報を表示して終了します。

9.8 ‘msgattrib’プログラムの呼び出し
===================================

     msgattrib [OPTION] [INPUTFILE]

   ‘msgattrib’プログラムは、翻訳カタログのメッセージの属性にしたがってフ
ィルターを適用したり、属性を操作するためのプログラムです。

9.8.1 入力ファイルの位置
------------------------

‘INPUTFILE’
     入力となるPOファイルです。

‘-D DIRECTORY’
‘--directory=DIRECTORY’
     ディレクトリーのリストにDIRECTORYを追加します。このディレクトリーの
     リストよりソースファイルを検索します。しかし‘.po’ファイルが出力され
     るのは、カレントディレクトリーです。

   INPUTFILEが指定されていないか、‘-’が指定された場合は、標準入力から読
み込みます。

9.8.2 出力ファイルの位置
------------------------

‘-o FILE’
‘--output-file=FILE’
     指定されたファイルに出力を書き込みます。

   出力ファイルが指定されていない、または‘-’が指定された場合、結果は標準
出力に出力されます。

9.8.3 メッセージ選択
--------------------

‘--translated’
     翻訳されたメッセージを残して、未翻訳のメッセージは削除します。

‘--untranslated’
     未翻訳のメッセージを残して、翻訳済みのメッセージは削除します。

‘--no-fuzzy’
     削除: ‘fuzzy’ とマークされたメッセージを削除します。

‘--only-fuzzy’
     保持: ‘fuzzy’ とマークされたメッセージを残して、他のすべてのメッセ
     ージは削除します。

‘--no-obsolete’
     #~のついた廃止されたメッセージを削除します。

‘--only-obsolete’
     #~のついた廃止されたメッセージを残して、他のすべてのメッセージは削
     除します。

9.8.4 属性の操作
----------------

   メッセージの選択・削除が実行された後に、属性は変更されます。
‘--only-file’か‘--ignore-file’オプションを指定すると、ONLY-FILEに記載さ
れたメッセージ、もしくはIGNORE-FILEに記載されていないメッセージにだけ、
変更が適用されます。

‘--set-fuzzy’
     すべてのメッセージに、 ‘fuzzy’をセットします。

‘--clear-fuzzy’
     すべてのメッセージに、 非‘fuzzy’をセットします。

‘--set-obsolete’
     すべてのメッセージを、陳腐化したメッセージにします。

‘--clear-obsolete’
     陳腐化したメッセージを、陳腐化していないメッセージにセットします。

‘--previous’
     もし ‘fuzzy’ とマークされているとき、翻訳されたメッセージの“以前の
     msgid”を残します。

‘--clear-previous’
     すべてのメッセージから、“以前のmsgid”であることを示すコメントマーク
     (‘#|’)がついたものを削除します。

‘--only-file=FILE’
     FILEに記載されたエントリーの属性だけを変更します。FILEにはPO、また
     はPOTファイルを指定します。

‘--ignore-file=FILE’
     FILEに記載されていないエントリーの属性だけを変更します。FILEには
     PO、またはPOTファイルを指定します。

‘--fuzzy’
     ‘--only-fuzzy --clear-fuzzy’の省略指定です。fuzzyメッセージだけを残
     すとともに、それらのメッセージの ‘fuzzy’ マークを外します。

‘--obsolete’
     ‘--only-obsolete --clear-obsolete’の省略指定です。廃止されたメッセ
     ージだけを残すとともに、それらのメッセージが陳腐化していることを示
     すマークを外します。

9.8.5 入力ファイルの構文
------------------------

‘-P’
‘--properties-input’
     入力ファイルがPOファイルの構文ではなく、Javaの‘.properties’の構文に
     のっとったJava ResourceBundleファイルだとみなします。

‘--stringtable-input’
     入力ファイルがPOファイルの構文ではなく、NeXTstep/GNUstepのlocalized
     resourceの‘.strings’の構文にのっとったファイルだとみなします。

9.8.6 出力の詳細
----------------

‘--color’
‘--color=WHEN’
     色や色以外のテキスト属性を使うか、いつ使うかを指定します。詳細は
     The --color optionを参照してください。

‘--style=STYLE_FILE’
     ‘--color’にたいしてCSS style ruleファイルを使うかを指定します。詳細
     はThe --style optionを参照してください。

‘--force-po’
     メッセージが何も含まれていない場合でも、常に出力ファイルに書き込み
     ます。

‘-i’
‘--indent’
     インデントされた形式で.poファイルを書き込みます。

‘--no-location’
     ‘#: FILENAME:LINE’という行を書き込みません。

‘-n’
‘--add-location’
     ‘#: FILENAME:LINE’という行を生成します(デフォルト)。

‘--strict’
     Uniforumに厳密に準拠したPOファイルを出力します。このUniforum形式は
     GNUの拡張をサポートしないため避けたほうがよいでしょう。

‘-p’
‘--properties-output’
     Javaの‘.properties’の書式で、Java ResourceBundleを出力します。この
     ファイル形式はplural formをサポートせず、陳腐化したメッセージを暗黙
     で除去することに注意してください。

‘--stringtable-output’
     ‘.strings’の書式で、NeXTstep/GNUstepのローカライズされたリソースフ
     ァイルを出力します。このファイル形式はplural formをサポートしないこ
     とに注意してください。

‘-w NUMBER’
‘--width=NUMBER’
     出力ページの幅をセットします。これにより出力ファイル中の長い文字列
     が指定した幅(例:スクリーンの列数)に収まるように、各行の長さが
     NUMBER以下のような複数の行に分割されます。

‘--no-wrap’
     長いメッセージ行を分割しません。出力ページの幅を超えるようなメッセ
     ージ行も、複数行に分割されません。出力ページの幅を超えるファイル参
     照行だけが分割されます。

‘-s’
‘--sort-output’
     ソートされた出力を生成します。このオプションを使用することにより翻
     訳者が、メッセージがどのようなコンテキストで使用されるかを理解する
     のが、困難になることに注意してください。

‘-F’
‘--sort-by-file’
     ファイルの場所により出力をソートします。

9.8.7 情報的な出力
------------------

‘-h’
‘--help’
     このヘルプを表示して終了します。

‘-V’
‘--version’
     バージョン情報を表示して終了します。

9.9 ‘msgen’プログラムの呼び出し
===============================

     msgen [OPTION] INPUTFILE

   ‘msgen’は、Englishの翻訳カタログを作成するプログラムです。最後に作成
されたEnglishのPOファイル、またはPO Template(xgettext により生成されます
)を入力とし、未翻訳エントリーの翻訳に、msgidと同じ文字列を割り当てます。

   注意: ‘msginit --no-translator --locale=en’でも、同じような処理を行う
ことができます。異なるのは、‘msginit’はヘッダーエントリーにたいして特別
な配慮を払いますが、‘msgen’は異なるという点です。

9.9.1 入力ファイルの位置
------------------------

‘INPUTFILE’
     入力となるPOまたはPOTファイルです。

‘-D DIRECTORY’
‘--directory=DIRECTORY’
     ディレクトリーのリストにDIRECTORYを追加します。このディレクトリーの
     リストよりソースファイルを検索します。しかし‘.po’ファイルが出力され
     るのは、カレントディレクトリーです。

   INPUTFILEに‘-’が指定された場合は、標準入力から読み込みます。

9.9.2 出力ファイルの位置
------------------------

‘-o FILE’
‘--output-file=FILE’
     指定されたファイルに出力を書き込みます。

   出力ファイルが指定されていない、または‘-’が指定された場合、結果は標準
出力に出力されます。

9.9.3 入力ファイルの構文
------------------------

‘-P’
‘--properties-input’
     入力ファイルがPOファイルの構文ではなく、Javaの‘.properties’の構文に
     のっとったJava ResourceBundleファイルだとみなします。

‘--stringtable-input’
     入力ファイルがPOファイルの構文ではなく、NeXTstep/GNUstepのlocalized
     resourceの‘.strings’の構文にのっとったファイルだとみなします。

9.9.4 出力の詳細
----------------

‘--lang=CATALOGNAME’
     ヘッダーエントリーで使用される、‘Language’フィールドを指定します。
     このフィールドの意味については、see Header Entryを参照してくだ
     さい。注意: このオプションでは、‘Language-Team’と‘Plural-Forms’はセ
     ットされません。

‘--color’
‘--color=WHEN’
     色や色以外のテキスト属性を使うか、いつ使うかを指定します。詳細は
     The --color optionを参照してください。

‘--style=STYLE_FILE’
     ‘--color’にたいしてCSS style ruleファイルを使うかを指定します。詳細
     はThe --style optionを参照してください。

‘--force-po’
     メッセージが何も含まれていない場合でも、常に出力ファイルに書き込み
     ます。

‘-i’
‘--indent’
     インデントされた形式で.poファイルを書き込みます。

‘--no-location’
     ‘#: FILENAME:LINE’という行を書き込みません。

‘--add-location’
     ‘#: FILENAME:LINE’という行を生成します(デフォルト)。

‘--strict’
     Uniforumに厳密に準拠したPOファイルを出力します。このUniforum形式は
     GNUの拡張をサポートしないため避けたほうがよいでしょう。

‘-p’
‘--properties-output’
     Javaの‘.properties’の書式で、Java ResourceBundleを出力します。この
     ファイル形式はplural formをサポートせず、陳腐化したメッセージを暗黙
     で除去することに注意してください。

‘--stringtable-output’
     ‘.strings’の書式で、NeXTstep/GNUstepのローカライズされたリソースフ
     ァイルを出力します。このファイル形式はplural formをサポートしないこ
     とに注意してください。

‘-w NUMBER’
‘--width=NUMBER’
     出力ページの幅をセットします。これにより出力ファイル中の長い文字列
     が指定した幅(例:スクリーンの列数)に収まるように、各行の長さが
     NUMBER以下のような複数の行に分割されます。

‘--no-wrap’
     長いメッセージ行を分割しません。出力ページの幅を超えるようなメッセ
     ージ行も、複数行に分割されません。出力ページの幅を超えるファイル参
     照行だけが分割されます。

‘-s’
‘--sort-output’
     ソートされた出力を生成します。このオプションを使用することにより翻
     訳者が、メッセージがどのようなコンテキストで使用されるかを理解する
     のが、困難になることに注意してください。

‘-F’
‘--sort-by-file’
     ファイルの場所により出力をソートします。

9.9.5 情報的な出力
------------------

‘-h’
‘--help’
     このヘルプを表示して終了します。

‘-V’
‘--version’
     バージョン情報を表示して終了します。

9.10 ‘msgexec’プログラムの呼び出し
==================================

     msgexec [OPTION] COMMAND [COMMAND-OPTION]

   ‘msgexec’は、翻訳カタログ内のすべての翻訳に、コマンドを適用するための
プログラムです。COMMANDには、標準入力から翻訳を読み込む任意のプログラム
を指定できます。呼び出しは、それぞれの翻訳について1回行われます。コマン
ドの出力は、msgexecの出力となります。‘msgexec’自体の戻り値は、すべての呼
び出しにおける最大の戻り値となります。

   ‘0’という、特別なビルトインコマンドを呼び出すと、NULL終端された翻訳が
出力されます。‘msgexec 0’の出力は、‘xargs -0’の入力として適しています。

   それぞれのCOMMAND呼び出しにおいて、環境変数の‘MSGEXEC_MSGID’と
‘MSGEXEC_LOCATION’に、メッセージのmsgidとメッセージを含むPOファイルの場
所がバインドされます。メッセージがコンテキストを保有する場合は、環境変数
‘MSGEXEC_MSGCTXT’がメッセージのコンテキストにバインドされます(コンテキス
トを保有していない場合にはバインドされません)。

   注意: COMMANDが翻訳カタログ内の翻訳のエンコーディングに対処できるよう
にするのは、あなたの責任です。COMMANDが特定のエンコーディングを期待する
場合、‘msgexec’を呼び出す前に、‘msgconv’プログラムで、翻訳カタログをその
エンコーディングに変換するのが最初のステップとなります。COMMANDが
localeのエンコーディングを期待しているが、あなたはlocaleのエンコーディン
グを無視したいときには、最初に‘msgconv’で翻訳カタログをUTF-8に変換してか
ら、環境変数‘LC_ALL’を指定して、‘msgexec’がUTF-8を処理するようにできます
。

9.10.1 入力ファイルの位置
-------------------------

‘-i INPUTFILE’
‘--input=INPUTFILE’
     入力となるPOファイルです。

‘-D DIRECTORY’
‘--directory=DIRECTORY’
     ディレクトリーのリストにDIRECTORYを追加します。このディレクトリーの
     リストよりソースファイルを検索します。しかし‘.po’ファイルが出力され
     るのは、カレントディレクトリーです。

   INPUTFILEが指定されていないか、‘-’が指定された場合は、標準入力から読
み込みます。

9.10.2 入力ファイルの構文
-------------------------

‘-P’
‘--properties-input’
     入力ファイルがPOファイルの構文ではなく、Javaの‘.properties’の構文に
     のっとったJava ResourceBundleファイルだとみなします。

‘--stringtable-input’
     入力ファイルがPOファイルの構文ではなく、NeXTstep/GNUstepのlocalized
     resourceの‘.strings’の構文にのっとったファイルだとみなします。

9.10.3 情報的な出力
-------------------

‘-h’
‘--help’
     このヘルプを表示して終了します。

‘-V’
‘--version’
     バージョン情報を表示して終了します。

9.11 POファイルの一部をハイライトする
=====================================

   翻訳者は通常、POファイル中の未翻訳、およびfuzzyメッセージを見ることだ
けに関心を持っています。また、msgidが変更されたことによりメッセージに
fuzzyがセットされたときに、以前のメッセージと現在のメッセージの差分を見
たいと望みます(長いmsgidの中の数語が変更されたときは特に)。そして最後に
、POファイル内のセクションのメッセージ(コメント、msgid、msgstrなど)の違
いを強調するのは、いつでも歓迎します。

   このような強調表示は、‘msgcat’の‘--color’と‘--style’オプションで可能
になります。

9.11.1 ‘--color’オプション
--------------------------

   ‘--color=WHEN’オプションは、どのような状況で着色された出力を生成する
か指定します。WHENには、以下のうち1つを指定できます:

‘always’
‘yes’
     着色された出力が生成されます。

‘never’
‘no’
     出力は着色されません。

‘auto’
‘tty’
     出力デバイスがttyのとき(例 テキスト画面やterminal emulatorウィンド
     ウに直接出力する場合)は、出力に着色します。

‘html’
     着色されたHTML出力が生成されます。

‘--color’と‘--color=yes’は同じです。デフォルトは‘--color=auto’です。

   そのため、コマンドウィンドウで‘msgcat vi.po’のようなコマンドを実行す
ると、着色された出力が生成されます。‘msgcat vi.po | less -R’のように、パ
イプにたいして出力するときは、出力への着色は行われません。このような状況
でも常に着色された出力を得るには、‘msgcat --color vi.po | less -R’のよう
に指定します。

   ‘--color=html’オプションでは、ブラウザーで閲覧可能な出力が生成されま
す。このオプションは、例えばIndic言語を表示したいときに有用です。なぜな
ら、通常はIndic文字の表示にはterminal emulatorよりもブラウザーのほうが適
しているからです。

   ‘--color’オプションにより生成される出力は、有効なPOファイルでは_ない
_ことに注意してください。出力にはterminal特有のエスケープシーケンスや
HTMLタグが含まれます。このようなPOファイルをプログラムが読み込むと、文法
エラーとなります。‘--color=html’オプションでHTMLファイルを生成する場合を
のぞき、通常は‘--color’オプションで生成した結果をファイルに保存する必要
はありません。

9.11.2 環境変数‘TERM’
---------------------

   環境変数‘TERM’には、テキストウィンドウの能力に関する識別情報が含まれ
ています。これらの能力について詳細なリストを得るには、‘infocmp’コマンド
を使用します(リファレンスは‘man 5 terminfo’コマンドで参照することができ
ます)。

   埋め込みの色指定をもつテキストを生成するとき、‘msgcat’はTERM変数を参
照します。現在のテキストウィンドウは、普通は少なくとも8色の表示をサポー
トします。しかしテキストウィンドウが16色、またはそれ以上の色数をサポート
するのに、‘TERM’変数には8色しかサポートしないように記述されている場合も
あります。そのようなときは、‘TERM’に異なる値を設定する価値があります。

‘xterm’
     多くのケースでは、‘xterm’は16色をサポートするように構築されています
     。88色、または256色をサポートするように構築することもできます(両方
     はできませんが)。このような場合は、‘TERM’に‘xterm-16color’、
     ‘xterm-88color’、または‘xterm-256color’をセットすることを試みてもよ
     いでしょう。

‘rxvt’
     ‘rxvt’が、16色をサポートするよう構築されている場合があります。この
     ような場合は、‘TERM’に‘rxvt-16color’をセットすることができます。

‘konsole’
     ‘konsole’も、16色をサポートするよう構築されている場合があります。こ
     のような場合には、‘TERM’に‘konsole-16color’、または
     ‘xterm-16color’をセットすることができます。

   ‘TERM’を設定した後は、‘msgcat --color=test’により設定を検証するととも
に、適切なカラーマップに見えるか出力を視認できます。

9.11.3 ‘--style’オプション
--------------------------

   ‘--style=STYLE_FILE’オプションで、着色時に使用するスタイルファイルを
指定できます。この指定は‘--color’が有効なときだけ効果があります。

   ‘--style’オプションが指定されていないときは、環境変数‘PO_STYLE’が使用
されます。この環境変数にはユーザーが好むPOファイル用のスタイルファイルを
指定します。

   デフォルトのスタイルファイルは、
‘$prefix/share/gettext/styles/po-default.css’です。‘$prefix’はインストー
ルした場所です。

   いくつかのスタイルファイルが事前に定義されています:
‘po-vim.css’
     このスタイルはvim 7の表示を模倣します。

‘po-emacs-x.css’
     このスタイルは、X11ウィンドウでのGNU Emacs 21、22の表示を模倣します
     。

‘po-emacs-xterm.css’
‘po-emacs-xterm16.css’
‘po-emacs-xterm256.css’
     このスタイルは、‘xterm’(8色)、‘xterm-16color’(16色)、
     ‘xterm-256color’(256色)の端末でGNU Emacs 22を実行したときの表示を模
     倣します。

これらのスタイルについてはディレクトリーを指定しなくても使うことができま
す。これらのスタイルファイルは‘$prefix/share/gettext/styles/’にあります
。‘$prefix’はインストールした場所です。

   あなた自身でスタイルをデザインできます。これは次のセクションで説明し
ます。

9.11.4 POファイルのスタイルルール
---------------------------------

   端末出力とHTML出力で、同じPOファイル用スタイルを使用できます。POファ
イル用のスタイルはCSS(Cascading Style Sheet)の書式で記述します。CSSの正
式な定義については、<http://www.w3.org/TR/css2/cover.html>を参照してくだ
さい。CSSについての説明を含んだ、HTML記述のチュートリアルも数多く存在し
ます。

   HTML出力の場合、スタイルファイルはHTML出力中に埋め込まれます。テキス
ト出力の場合、スタイルファイルは‘msgcat’プログラムにより逐次解釈されます
。これは‘@import’に関連するファイル名が指定されていて、そのファイル名が
以下のような場合、特に意味をもちます:

   − HTML出力のときは関係のある結果HTMLファイル、

   − テキスト出力のときは‘@import’を含む、関係のあるスタイルシート(実際
     にこのようなケースでは、libcrocoの制限により@importはまだサポートさ
     れていません)。

   CSSルールはselectorとdeclarationにより構築されます。declarationにはグ
ラフィカルなプロパティーを指定し、selectorにはそれをいつ適用するかを指定
します。

   POファイル用に、以下の簡単なselectorがサポートされています("CSS
classes"を基本とします。詳細はCSS2 specのsection 5.8.3を参照してください
)。

   • 以下はメッセージ全体に適用されるSelectorです:

     ‘.header’
          POファイルのヘッダーエントリーにマッチします。

     ‘.translated’
          翻訳されたメッセージにマッチします。

     ‘.untranslated’
          未翻訳のメッセージにマッチします(例: 翻訳が空のメッセージ)。

     ‘.fuzzy’
          fuzzyメッセージにマッチします(例: 翻訳者のレビューが必要な翻訳
          をともなうメッセージ)。

     ‘.obsolete’
          陳腐化したメッセージにマッチします(例: 現在のPOTファイルでは必
          要とされない翻訳済みのメッセージ)。

   • 以下は、メッセージのPO文法の一部に適用されるSelectorです。PO文法の
     一般的なメッセージ構造ごとに呼び出されます:

          WHITE-SPACE
          #  TRANSLATOR-COMMENTS
          #. EXTRACTED-COMMENTS
          #: REFERENCE...
          #, FLAG...
          #| msgid PREVIOUS-UNTRANSLATED-STRING
          msgid UNTRANSLATED-STRING
          msgstr TRANSLATED-STRING

     ‘.comment’
          すべてのコメントにマッチします(翻訳者コメント、抽出されたコメ
          ント、ソースファイルへの参照コメント、フラグコメント、以前のメ
          ッセージであることを示すコメント、同様にすべての廃止されたコメ
          ント)。

     ‘.translator-comment’
          翻訳者のコメントにマッチします。

     ‘.extracted-comment’
          抽出されたコメントにマッチします(例: 翻訳者への注意を換気する
          ためにプログラマーにより記述されたコメント)。

     ‘.reference-comment’
          ソースファイルへの参照コメントにマッチします(行全体)。

     ‘.reference’
          ソースファイルへの参照コメント行中の、特定のソースファイルへの
          参照にマッチします。

     ‘.flag-comment’
          フラグコメントにマッチします(行全体)。

     ‘.flag’
          フラグコメント行の中の、特定のフラグにマッチします。

     ‘.fuzzy-flag’
          コメント行中の‘fuzzy’フラグにマッチします。

     ‘.previous-comment’
          以前の未翻訳文字列に含まれるコメントにマッチします(行全体)。

     ‘.previous’
          区切り文字、結びつけられたキーワード(‘msgid’など)、それらの文
          字列間の空白を含んだ、以前の未翻訳文字列にマッチします。

     ‘.msgid’
          区切り文字、結びつけられたキーワード(‘msgid’など)、それらの文
          字列間の空白を含んだ、未翻訳文字列にマッチします。

     ‘.msgstr’
          区切り文字、結びつけられたキーワード(‘msgstr’など)、それらの文
          字列間の空白を含んだ、翻訳済みの文字列にマッチします。

     ‘.keyword’
          キーワード(‘msgid’、‘msgstr’など)にマッチします。

     ‘.string’
          区切り文字(2重引用符)を含む文字列にマッチします。

   • 以下はメッセージ文字列の一部に適用されるSelectorです:

     ‘.text’
          文字列の内容全体にマッチします(区切り文字は除く例: 2重引用符
          )。

     ‘.escape-sequence’
          (バックスラッシュで始まる)エスケープシーケンスにマッチします。

     ‘.format-directive’
          書式指定文字列にマッチします(多くの言語では‘%’、
          ‘java-format’と‘csharp-format’では‘{’、‘lisp-format’と
          ‘scheme-format’では‘~’、‘sh-format’では‘$’で開始されます)。

     ‘.invalid-format-directive’
          無効な書式指定文字列にマッチします。

     ‘.added’
          未翻訳文字列中で、以前の未翻訳文字列には無かった文字列にマッチ
          します(このリリースではまだ実装されていません)。

     ‘.changed’
          未翻訳文字列、または以前の未翻訳文字列中で、変更または置き換え
          られた文字列にマッチします(このリリースではまだ実装されていま
          せん)。

     ‘.removed’
          以前の未翻訳文字列中で、現在の未翻訳文字列には無い文字列にマッ
          チします(このリリースではまだ実装されていません)。

   これらのselectorは、以下の例のように階層的なselectorとして組み合わせ
ることができます。

     .msgstr .invalid-format-directive { color: red; }

上記の例では、翻訳文字列中の無効な書式指定を強調表示しています。

   テキストモードでは、pseudo-classes(CSS2 spec, section 5.11)と
pseudo-elements(CSS2 spec, section 5.12)はサポートされません。

   HTMLモードでの宣言には制限はありません。ブラウザーがサポートする任意
のgraphical attributeがサポートされます。

   テキストモードでの宣言は以下のプロパティーに制限され、他のプロパティ
ーは暗黙に無視されます。

‘color’ (CSS2 spec, section 14.1)
‘background-color’ (CSS2 spec, section 14.2.1)
     これらのプロパティーはサポートされます。色数はterminalの能力に適合
     されます。ほとんどのterminalのサポートは8色であることに注意してくだ
     さい。

‘font-weight’ (CSS2 spec, section 15.2.3)
     このプロパティーはサポートされますが、ほとんどのterminalは
     ‘normal’と‘bold’の2種類のweightしか描画できません。600以上の値を指
     定したときは‘bold’として描画されます。

‘font-style’ (CSS2 spec, section 15.2.3)
     このプロパティーはサポートされます。‘italic’と‘oblique’は、同じ方法
     で描画されます。

‘text-decoration’ (CSS2 spec, section 16.3.1)
     このプロパティーはサポートされます。値は‘none’と‘underline’に制限さ
     れます。

9.11.5 POファイルを閲覧するために‘less’をカスタマイズする
---------------------------------------------------------

   ‘less’は、テキストスクリーンやterminal emulatorでテキストファイルを閲
覧するための一般的なプログラムです。このプログラムは、色表示や文字飾りの
ための埋め込みエスケープシーケンスもサポートします。

   以下のようにして、POファイルの閲覧に‘less’を使用できます(UTF-8 環境の
場合):

     msgcat --to-code=UTF-8 --color xyz.po | less -R

   これと同じことを、次ような簡単なコマンドで行うための方法を説明します:

     less xyz.po

以下の3つの準備が必要です:

  1. 環境変数‘LESS’に‘-R’と‘-f’のオプションを追加します:
          $ LESS="$LESS -R -f"
          $ export LESS

  2. あなたのシステムに‘lessopen.sh’と‘lessclose.sh’スクリプトがない場合
     は、マニュアル(‘man less’)に記載されているように、それらのスクリプ
     トを作成して、環境変数‘LESSOPEN’、‘LESSCLOSE’にセットします。

  3. 以下のような、ファイルの拡張子からPOファイルを認識することにより
     ‘msgcat’を呼び出し、一時ファイルを生成する断片的なスクリプトを
     ‘lessopen.sh’に追加します:

          case "$1" in
            *.po)
              tmpfile=`mktemp "${TMPDIR-/tmp}/less.XXXXXX"`
              msgcat --to-code=UTF-8 --color "$1" > "$tmpfile"
              echo "$tmpfile"
              exit 0
              ;;
          esac

9.12 POファイルを処理するプログラムを独自に記述する
===================================================

   ‘msgattrib’や‘msgcat’などの組み合わせによる処理では十分でない場合のた
めに、一連のC関数がライブラリにより提供されています。これを使うことによ
り、あなたのプログラムからPOファイルを処理できるようになります。ライブラ
リーを使う場合は、POファイルをパースするルーチンを自分で記述する必要はあ
りません。かわりにPOファイル内の各メッセージに対応するメモリーへのポイン
ターを取得することができます。現時点では、POファイルへ書き込むための関数
は提供されていません。

   関数はヘッダーファイル‘<gettext-po.h>’で宣言されており、
‘libgettextpo’というライブラリーで定義されています。

 -- Data Type: po_file_t
     POファイルのコンテンツをメモリーに読み込んだ後に、それらを参照する
     ためのポインター型です。

 -- Data Type: po_message_iterator_t
     一連のメッセージを生成するiteratorを参照するためのポインター型です
     。

 -- Data Type: po_message_t
     POファイルのメッセージ(翻訳を含む)を参照するためのポインター型です
     。

 -- Function: po_file_t po_file_read (const char *FILENAME)
     関数‘po_file_read’は、引数としてファイル名を受け取り、そのPOファイ
     ルをメモリー内に読み込みます。戻り値はPOファイル内のコンテンツへの
     ハンドルで、そのハンドルは‘po_file_free’が呼び出されるまで有効です
     。エラーが発生したときの戻り値は‘NULL’で、‘errno’がセットされます。

 -- Function: void po_file_free (po_file_t FILE)
     関数‘po_file_free’は、メモリー内のPOファイルのコンテンツを解放しま
     す。iteratorを通じて暗黙にアクセス可能なすべてのメッセージも解放さ
     れます。

 -- Function: const char * const * po_file_domains (po_file_t FILE)
     関数‘po_file_domains’は、メッセージを所有するPOファイルのdomainを戻
     します。戻り値は‘NULL’で終端された配列で、この配列はFILEのハンドル
     が有効な間は有効です。‘domain’指定を持たないPOファイルの場合は、デ
     フォルトのドメインである‘"messages"’という名前のドメインだけが戻さ
     れます。

 -- Function: po_message_iterator_t po_message_iterator (po_file_t FILE,
          const char *DOMAIN)
     ‘po_message_iterator’は、与えられたDOMAINに属するFILEのメッセージを
     生成するiteratorを戻します。DOMAINが‘NULL’のときは、かわりにデフォ
     ルトのdomainが使用されます。関数‘po_next_message’を繰り返し呼び出す
     と、メッセージをリストすることができます。

 -- Function: void po_message_iterator_free (po_message_iterator_t
          ITERATOR)
     関数‘po_message_iterator_free’は、関数‘po_message_iterator’により割
     り当てられたiteratorを開放します。

 -- Function: po_message_t po_next_message (po_message_iterator_t
          ITERATOR)
     関数‘po_next_message’は、ITERATORから次のメッセージを戻すとともに
     iteratorを1つ進めます。メッセージリストの終端に達すると、‘NULL’が戻
     されます。

   以下は‘po_message_t’のメンバーを戻す関数です。FILEハンドルが有効な間
は、呼び出しによる結果も有効です。

 -- Function: const char * po_message_msgid (po_message_t MESSAGE)
     関数‘po_message_msgid’は、メッセージの‘msgid’(未翻訳のEnglish文字列
     )を戻します。この結果は、非‘NULL’であることが保証されています。

 -- Function: const char * po_message_msgid_plural (po_message_t
          MESSAGE)
     関数‘po_message_msgid_plural’は、pluralをもつメッセージの
     ‘msgid_plural’(未翻訳のEnglish plural文字列)を戻します。メッセージ
     がpluralをもたない場合には、‘NULL’が戻されます。

 -- Function: const char * po_message_msgstr (po_message_t MESSAGE)
     関数‘po_message_msgstr’は、メッセージの‘msgstr’(翻訳済み)を戻します
     。未翻訳のメッセージの場合は、空文字列が戻されます。

 -- Function: const char * po_message_msgstr_plural (po_message_t
          MESSAGE, int INDEX)
     関数‘po_message_msgstr_plural’は、pluralをもつメッセージの
     ‘msgstr[INDEX]’を戻します。INDEXが範囲外のとき、またはメッセージが
     pluralをもたない場合は‘NULL’が戻されます。

   以下は、これらの関数がどのように使用されるかを示す例です。

     const char *filename = ...;
     po_file_t file = po_file_read (filename);

     if (file == NULL)
       error (EXIT_FAILURE, errno, "couldn't open the PO file %s", filename);
     {
       const char * const *domains = po_file_domains (file);
       const char * const *domainp;

       for (domainp = domains; *domainp; domainp++)
         {
           const char *domain = *domainp;
           po_message_iterator_t iterator = po_message_iterator (file, domain);

           for (;;)
             {
               po_message_t *message = po_next_message (iterator);

               if (message == NULL)
                 break;
               {
                 const char *msgid = po_message_msgid (message);
                 const char *msgstr = po_message_msgstr (message);

                 ...
               }
             }
           po_message_iterator_free (iterator);
         }
     }
     po_file_free (file);

10 バイナリーのMOファイルの生成
*******************************

10.1 ‘msgfmt’プログラムの呼び出し
=================================

     msgfmt [OPTION] FILENAME.po ...

   ‘msgfmt’は、翻訳済みのテキストのメッセージから、バイナリーのメッセー
ジカタログを生成するプログラムです。

10.1.1 入力ファイルの位置
-------------------------

‘FILENAME.po ...’

‘-D DIRECTORY’
‘--directory=DIRECTORY’
     ディレクトリーのリストにDIRECTORYを追加します。このディレクトリーの
     リストよりソースファイルを検索します。しかし、結果となるバイナリー
     ファイルが出力されるのは、カレントディレクトリーです。

   入力ファイルに‘-’が指定された場合は、標準入力から読み込みます。

10.1.2 オペレーションモード
---------------------------

‘-j’
‘--java’
     Javaモード: Javaの‘ResourceBundle’クラスを生成します。

‘--java2’
     –javaと同様ですがJava2(JDK 1.2以上)とみなします。

‘--csharp’
     C#モード: ‘GettextResourceSet’のサブクラスを含んだ、.NETの.dllファ
     イルを生成します。

‘--csharp-resources’
     C# resourcesモード: .NETの‘.resources’ファイルを生成します。

‘--tcl’
     Tclモード: tcl/msgcatの‘.msg’ファイルを生成します。

‘--qt’
     Qtモード: Qtの‘.qm’ファイルを生成します。

10.1.3 出力ファイルの位置
-------------------------

‘-o FILE’
‘--output-file=FILE’
     指定されたファイルに出力を書き込みます。

‘--strict’
     プログラムがUniforum/Sun実装にしたがうように指定します。これは現時
     点では、出力ファイルの名前に影響を与えるだけです。オプションにファ
     イル名を指定しなかった場合、出力ファイルは同じdomain 名になります。
     厳密なUniforumモードが有効でファイル名が与えられなかった場合には、
     ファイル名に‘.mo’が付加されます。

     わたしたちはこのSun実装は意味がないと考え、デフォルトではこのモード
     は選択_されません_。

   出力となるFILEに‘-’が指定されたときは、出力は標準出力に書き込まれます
。

10.1.4 Javaモードでの出力ファイルの位置
---------------------------------------

‘-r RESOURCE’
‘--resource=RESOURCE’
     リソース名を指定します。

‘-l LOCALE’
‘--locale=LOCALE’
     locale名を指定します。LL形式による言語指定と、国と言語指定を組み合
     わせたLL_CCのどちらでも指定できます。

‘-d DIRECTORY’
     classのディレクトリー階層のベースとなるディレクトリーを指定します。

   クラス名はリソース名の後ろに区切り文字のアンダースコアーとlocale名を
付加して決定されます。‘-d’オプションは必須です。クラスは指定されたディレ
クトリーに出力されます。

10.1.5 C#モードでの出力ファイルの位置
-------------------------------------

‘-r RESOURCE’
‘--resource=RESOURCE’
     リソース名を指定します。

‘-l LOCALE’
‘--locale=LOCALE’
     locale名を指定します。LL形式による言語指定と、国と言語指定を組み合
     わせたLL_CCのどちらでも指定できます。

‘-d DIRECTORY’
     localeに依存する‘.dll’ファイルを出力するベースディレクトリーを指定
     します。

   \‘-l’と‘-d’が必須オプションです。‘.dll’ファイルは、localeに依存した名
前の指定ディレクトリーのサブディレクトリーに出力されます。

10.1.6 Tclモードでの出力ファイルの位置
--------------------------------------

‘-l LOCALE’
‘--locale=LOCALE’
     locale名を指定します。LL形式による言語指定と、国と言語指定を組み合
     わせたLL_CCのどちらでも指定できます。

‘-d DIRECTORY’
     メッセージカタログ‘.msg’のベースディレクトリーを指定します。

   ‘-l’と‘-d’は必須オプションです。‘.msg’は指定されたディレクトリーに出
力されます。

10.1.7 入力ファイルの構文
-------------------------

‘-P’
‘--properties-input’
     入力ファイルがPOファイルの構文ではなく、Javaの‘.properties’の構文に
     のっとったJava ResourceBundleファイルだとみなします。

‘--stringtable-input’
     入力ファイルがPOファイルの構文ではなく、NeXTstep/GNUstepのlocalized
     resourceの‘.strings’の構文にのっとったファイルだとみなします。

10.1.8 入力ファイルの解釈
-------------------------

‘-c’
‘--check’
     ‘--check-format’、‘--check-header’、‘--check-domain’がすべて指定さ
     れたとみなしてチェックを行います。

‘--check-format’
     languageに依存した書式文字列をチェックします。

     文字列が‘printf’のような関数で使用される書式文字列の場合、書式指定
     子‘%’と、それらに対応する型の変数の個数は一致するはずです。エントリ
     ーにたいして<#,>コメントで‘c-format’や‘possible-c-format’フラグが指
     定されている場合は、チェックが行われます。たとえば、‘%s’が期待され
     る箇所に‘%.*s’や‘%d’が使われていたり、‘%x’が期待される箇所に‘%d’が
     使われている場合、チェックは診断メッセージを出力します。このチェッ
     クは位置パラメーターを処理することさえできるのです。

     ‘xgettext’プログラムは通常、ある文字列が書式文字列かどうかを、自動
     的に判定します。しかしこのアルゴリズムも完全ではありません。そのた
     め、‘printf’のような関数で使用されていない文字列を書式文字列とみな
     してしまい、エラーが存在しないにもかかわらず‘msgfmt’がエラーを報告
     する場合があります。

     プログラマーが‘xgettext’に判定結果を指示することにより、この問題を
     解決することができます(see c-formatを参照してください)。翻訳者
     は<#,>行からフラグを削除しようと考える必要はありません。なぜならこ
     の"fix"は、次に‘msgmerge’を呼び出したときに元に戻されてしまうからで
     す。

‘--check-header’
     ヘッダーエントリーの存在および内容をチェックします。ヘッダーエント
     リーのさまざまなフィールドの説明は、see Header Entryを参照して
     ください。

‘--check-domain’
     domain指定と‘--output-file’オプションの競合をチェックします。

‘-C’
‘--check-compatibility’
     GNU msgfmtがX/Open msgfmtのように振る舞うかをチェックします。GNU拡
     張を使用しているとエラーになります。

‘--check-accelerators[=CHAR]’
     メニューアイテムにたいしてキーボードアクセラレーターの存在をチェッ
     クします。このチェックは、いくつかのGUIにおいてメニューアイテム文字
     列内のキーボードアクセラレーターが、‘&’のすぐ後ろに続く文字としてデ
     ザインされていることにもとづきます。キーボードアクセラレーターが
     "keyboard mnemonic"と呼ばれることもあります。このチェックは、未翻訳
     文字列に‘&’が1つあるとき、翻訳文字列にも1つの‘&’があるかをチェック
     します。このオプションの引数にCHARが与えらる場合、CHARには非英数文
     字を指定します。指定した文字は‘&’のかわりに、キーボードアクセラレー
     ターのマークとして使用されます。

‘-f’
‘--use-fuzzy’
     出力にfuzzyエントリーを使用します。これらのfuzzyメッセージは人間の
     翻訳者により検証されたものではないため、このオプションの使用は通常
     は正しくないことに注意してください。

10.1.9 出力の詳細
-----------------

‘-a NUMBER’
‘--alignment=NUMBER’
     文字列をNUMBERバイトに揃えます(デフォルトは1)。

‘--endianness=BYTEORDER’
     32ビットの数字を与えられたバイト順で書き出します。‘big’と‘little’を
     指定できます。デフォルトはプラットフォーム、正確に言うとCPUのインデ
     ィアンに依存します。

     任意のインディアンをもつMOファイルは、任意のプラットフォームで使用
     できます。MOファイルのインディアンがプラットフォームのものでない場
     合、32ビットの数値は実行時に交換されます。パフォーマンスに与える影
     響は無視できるものです。

     このオプションは、プラットフォームに束縛されずMOを作成するために便
     利です。

‘--no-hash’
     バイナリーファイルにハッシュテーブルを含めないようにします。(ハッシ
     ュテーブルを参照するかわりに、バイナリーサーチが行われるため)実行時
     の検索が、より高価な処理となります。

10.1.10 情報的な出力
--------------------

‘-h’
‘--help’
     このヘルプを表示して終了します。

‘-V’
‘--version’
     バージョン情報を表示して終了します。

‘--statistics’
     翻訳の統計情報を表示します。‘--statistics’とともに‘--verbose’オプシ
     ョンが指定された場合は、統計行の前に入力ファイルの名前が出力されま
     す。

‘-v’
‘--verbose’
     診断レベルを上げます。

10.2 ‘msgunfmt’プログラムの呼び出し
===================================

     msgunfmt [OPTION] [FILE]...

   ‘msgunfmt’は、バイナリーのメッセージカタログを、Uniforum形式の.poファ
イルに変換するプログラムです。

10.2.1 オペレーションモード
---------------------------

‘-j’
‘--java’
     Javaモード: Javaの‘ResourceBundle’ class が入力となります。

‘--csharp’
     C#モード: ‘GettextResourceSet’のサブクラスを含む.NETの.dllファイル
     が入力となります。

‘--csharp-resources’
     C# resourcesモード: .NETの‘.resources’ファイルが入力となります。

‘--tcl’
     Tclモード: tcl/msgcatの‘.msg’ファイルが入力となります。

10.2.2 入力ファイルの位置
-------------------------

‘FILE ...’
     入力となる.moファイルです。

   FILEが指定されていないか、‘-’が指定された場合は、標準入力から読み込み
ます。

10.2.3 Javaモードでの入力ファイルの位置
---------------------------------------

‘-r RESOURCE’
‘--resource=RESOURCE’
     リソース名を指定します。

‘-l LOCALE’
‘--locale=LOCALE’
     locale名を指定します。LL形式による言語指定と、国と言語指定を組み合
     わせたLL_CCのどちらでも指定できます。

   class名は、resource名の後ろにアンダースコアーをつけて、その後ろに
locale 名を付加することにより決定されます。classは、‘CLASSPATH’によって
配置されます。

10.2.4 C#モードでの入力ファイルの位置
-------------------------------------

‘-r RESOURCE’
‘--resource=RESOURCE’
     リソース名を指定します。

‘-l LOCALE’
‘--locale=LOCALE’
     locale名を指定します。LL形式による言語指定と、国と言語指定を組み合
     わせたLL_CCのどちらでも指定できます。

‘-d DIRECTORY’
     localeに依存する‘.dll’ファイルを出力するベースディレクトリーを指定
     します。

   ‘-l’と‘-d’が必須オプションです。‘.msg’ファイルは、locale に依存した名
前の指定ディレクトリーのサブディレクトリーに配置されています。

10.2.5 Tclモードでの入力ファイルの位置
--------------------------------------

‘-l LOCALE’
‘--locale=LOCALE’
     locale名を指定します。LL形式による言語指定と、国と言語指定を組み合
     わせたLL_CCのどちらでも指定できます。

‘-d DIRECTORY’
     メッセージカタログ‘.msg’のベースディレクトリーを指定します。

   ‘-l’と‘-d’は必須オプションです。‘.msg’は指定されたディレクトリーに配
置されています。

10.2.6 出力ファイルの位置
-------------------------

‘-o FILE’
‘--output-file=FILE’
     指定されたファイルに出力を書き込みます。

   出力ファイルが指定されていない、または‘-’が指定された場合、結果は標準
出力に出力されます。

10.2.7 出力の詳細
-----------------

‘--color’
‘--color=WHEN’
     色や色以外のテキスト属性を使うか、いつ使うかを指定します。詳細は
     The --color optionを参照してください。

‘--style=STYLE_FILE’
     ‘--color’にたいしてCSS style ruleファイルを使うかを指定します。詳細
     はThe --style optionを参照してください。

‘--force-po’
     メッセージが何も含まれていない場合でも、常に出力ファイルに書き込み
     ます。

‘-i’
‘--indent’
     インデントされた形式で.poファイルを書き込みます。

‘--strict’
     Uniforumに厳密に準拠したPOファイルを出力します。このUniforum形式は
     GNUの拡張をサポートしないため避けたほうがよいでしょう。

‘-p’
‘--properties-output’
     Javaの‘.properties’の書式で、Java ResourceBundleを出力します。この
     ファイル形式はplural formをサポートせず、陳腐化したメッセージを暗黙
     で除去することに注意してください。

‘--stringtable-output’
     ‘.strings’の書式で、NeXTstep/GNUstepのローカライズされたリソースフ
     ァイルを出力します。このファイル形式はplural formをサポートしないこ
     とに注意してください。

‘-w NUMBER’
‘--width=NUMBER’
     出力ページの幅をセットします。これにより出力ファイル中の長い文字列
     が指定した幅(例:スクリーンの列数)に収まるように、各行の長さが
     NUMBER以下のような複数の行に分割されます。

‘--no-wrap’
     長いメッセージ行を分割しません。出力ページの幅を超えるようなメッセ
     ージ行も、複数行に分割されません。出力ページの幅を超えるファイル参
     照行だけが分割されます。

‘-s’
‘--sort-output’
     ソートされた出力を生成します。このオプションを使用することにより翻
     訳者が、メッセージがどのようなコンテキストで使用されるかを理解する
     のが、困難になることに注意してください。

10.2.8 情報的な出力
-------------------

‘-h’
‘--help’
     このヘルプを表示して終了します。

‘-V’
‘--version’
     バージョン情報を表示して終了します。

‘-v’
‘--verbose’
     診断レベルを上げます。

10.3 GNU MOファイルのフォーマット
=================================

   生成されたMOファイルの書式については、以下のような図を用いて説明する
のがよいでしょう。

   最初の2wordには、ファイルの識別が含まれます。magic numberは常にGNU
MOファイルを意味するnumberになります。numberは生成されたマシンのバイトオ
ーダーにしたがって格納されます。つまり実際のmagic numberは、
‘0x950412de’と‘0xde120495’のいずれかです。

   2番目のwordは、ファイル書式の現在のrevisionを説明し、major revision
number、およびminor revision numberから成り立ちます。revision numberによ
り、MOファイルの読み手は、古い書式と新しい書式を識別して、(可能なかぎり
)内容を処理できます。いまのところmajor revisionは0か1で、minor revisionも
0と1ですが、将来は追加されるかもしれません。想定外のmajor revision
numberの場合、プログラムはMOファイル全体を読み込むのを中止する必要があり
ます。想定外のminor revision numberは、ファイルは読み込めても、すべての
内容は読み込めないことを意味します。プログラムが解析できるのは、より小さ
なminor revision numberのときだけです。

   異なるmagic numberによって書式の違いを表すのではなく、magic numberと
は別にversionが保持されます。これは‘/etc/magic’が滅多に更新されないこと
が主な理由です。

   MOファイルの冒頭部の情報が拡張されたときに、それらを読み込むプログラ
ムをリコンパイルしなくても良いように、以降のテーブルのポインターを使って
ください。そのようにしておけば、後で新しいフラグのビットを追加したり、使
用されている文字コードの表示や、新しいテーブルなどを挿入されたときに便利
です。

   図中のoffset Oとoffset Tには、2つのstring descriptorを見出すことがで
きます。この2つのテーブルでは、どちらもstring descriptorとして 32ビット
の整数が使用されており、1つは文字列の長さを示し、もう1つは文字列がMOファ
イルの先頭から何バイト目かというoffsetを示します。最初のテーブルには元の
文字列のdescriptorが含まれていて、これらの元文字列は辞書順にソートされて
格納されています。2番目のテーブルには翻訳された文字列のdescriptorが含ま
れており、これらは1番目のテーブルに対応しています。つまり1番目のテーブル
と同じ添字で2番目のテーブルにアクセスすれば、対応する翻訳を取得できます
。

   元の文字列をソートして格納することにより、MOファイルにハッシュテーブ
ルを含まれていなかったり、含まれていたとしても実際に使うことができないと
きにも、単純な二分探索が可能になります。これには他にも利点があります。
GNU ‘gettext’は、POファイルの空の文字列にたいする翻訳文字列として、MOフ
ァイルに付加するシステム情報を割り当てます。この空文字列と翻訳のペアが、
元の文字列のテーブルと、翻訳文字列のテーブルの最初に配置されることにより
、システム情報を簡単に見つけることができるのです。

   ハッシュテーブルのサイズSが0のときもあります。これは、ハッシュテーブ
ル自体がMOファイルに含まれていない場合です。事前に算出されたハッシュテー
ブルはディスク容量を消費し、速度も早くないという理由で、この方式を好む人
もいます。ハッシュテーブルは、MOファイル中の文字列のソートされた配列の添
字を含んでいます。競合はdouble hashingにより解決しています。使用されてい
る正確なhashing algorithmは、GNU ‘gettext’のコード実装の説明になってしま
うので、ここでは説明しません。

   ハッシュテーブルを参照して取得する文字列自体は<NUL>終端されており、
string descriptorの文字列長にその<NUL>の分は含まれません。‘msgfmt’プログ
ラムには、MOファイル中の文字列のインデントを選択するオプションがあります
。このオプションを指定すると、個々の文字列の開始位置のオフセットは指定さ
れたインデント値の倍数分ずれます。RISCマシンには、適したインデント指定に
よって速度が改善するものがあります。

   contextについては、元の文字列の代わりに、context文字列と元の文字列を
<EOT>で連結したものが、ソートされて格納されます。

   plural formについては、元の文字列のsingularとpluralが<NUL>で区切られ
て格納されます。string descriptorには、両方の長さが記述されます。しかし
、ハッシュテーブルを参照するときは、元の文字列のsingularだけが使用されま
す。さまざまなpluralにたいする翻訳は、すべて<NUL>区切りで格納されます。
この場合もstring descriptorには、それらすべての長さが格納されます。

   MOファイル内の文字列に<NUL>が埋め込まれることを防ぐ方法はありません。
しかし現在のプログラムのインターフェースは、文字列が<NUL>で終端されると
仮定しているため、文字列の途中に<NUL>が埋め込まれている場合、何らかの不
都合が起こり得ます。MOファイルの書式は、後から他のインターフェースを適用
できるほどには一般的です。一例としては、意図しない<NUL>が出現するような
箇所にwide characterを使用する方法などがあります(実際にはMOファイル中に
wide characterを保持することはしません。wide characterを使用するとファイ
ルの容量が不必要に大きくなります。また‘wchar_t’はプラットフォームに依存
するため、MOファイルもプラットフォームに依存することになるからです)。

   この技術的な問題は、GNU ‘gettext’のdevelopment forumで盛んに議論され
ており、MOファイルの書式が将来、進化・変更されることが予想されます。その
可能性としては、同時に複数の書式にたいするサポートさえもが含まれます。し
かし、わたしたちに何らかの出発点が必要なことは確かで、ここで説明している
MOファイルの書式はよい出発点でした。今の書式には厳密な制約もなく、後から
書式を拡張するのは簡単なので、わたしたちは現在のアプローチに満足していま
す。

             byte
                  +------------------------------------------+
               0  | magic number = 0x950412de                |
                  |                                          |
               4  | file format revision = 0                 |
                  |                                          |
               8  | number of strings                        |  == N
                  |                                          |
              12  | offset of table with original strings    |  == O
                  |                                          |
              16  | offset of table with translation strings |  == T
                  |                                          |
              20  | size of hashing table                    |  == S
                  |                                          |
              24  | offset of hashing table                  |  == H
                  |                                          |
                  .                                          .
                  .    (possibly more entries later)         .
                  .                                          .
                  |                                          |
               O  | length & offset 0th string  ----------------.
           O + 8  | length & offset 1st string  ------------------.
                   ...                                    ...   | |
     O + ((N-1)*8)| length & offset (N-1)th string           |  | |
                  |                                          |  | |
               T  | length & offset 0th translation  ---------------.
           T + 8  | length & offset 1st translation  -----------------.
                   ...                                    ...   | | | |
     T + ((N-1)*8)| length & offset (N-1)th translation      |  | | | |
                  |                                          |  | | | |
               H  | start hash table                         |  | | | |
                   ...                                    ...   | | | |
       H + S * 4  | end hash table                           |  | | | |
                  |                                          |  | | | |
                  | NUL terminated 0th string  <----------------' | | |
                  |                                          |    | | |
                  | NUL terminated 1st string  <------------------' | |
                  |                                          |      | |
                   ...                                    ...       | |
                  |                                          |      | |
                  | NUL terminated 0th translation  <---------------' |
                  |                                          |        |
                  | NUL terminated 1st translation  <-----------------'
                  |                                          |
                   ...                                    ...
                  |                                          |
                  +------------------------------------------+

11 プログラマーの視点
*********************

   GNU ‘gettext’により提供される現在のメッセージカタログの実装は、インス
トーラーにより選択された場合にはシステムによるメッセージカタログ処理を使
用することを目標にしています。そのため、まず最初に既知の解決策を概観して
おく必要があるかもしれません。POSIXコミティーの人たちは、以下で説明する
準公式な標準候補のうちから1つを採択して管理しませんでした。実際、彼らは
何も採択せず、インターフェースの例を含めるだけに決めました。Unixのメジャ
ーなベンダーによるのインターフェースの採用は、X/Openのcatgetsと、
Uniforumのgettextに二分されました。以下ではそれらのインターフェースにつ
いて説明するとともに、このジレンマにたいするわたしたちの解決策を説明しま
す。

11.1 ‘catgets’について
======================

   ‘catgets’の実装は、X/Open Portability Guide, Volume 3, XSI
Supplementary Definitions, Chapter 5に定義されています。しかし、この標準
を作成する過程は、いくつかのUnixベンダーからは遅すぎると見なされ、それゆ
え彼らは標準を先取りしたバージョンを実装しました。プラットフォームに依存
したプログラムを記述したことから、これは問題を引き起こしました
(‘catgets’が一意なインターフェースを保証しないことさえありました)。

   インターフェースの決定にコメントするのがコミティー仲間だけに制限され
ていて、彼らだけがインターフェースを作成できました。彼らは、このインター
フェースを本当にプログラムに使わせようと考えてはいませんでした。メモリー
保存の実装手法により処理は高速だったので、ユーザーはハッピーでしたが、プ
ログラマーはそれを嫌っていました(少なくともわたしと、他の何人かも...)。

   Unix(tm)への正しい移植にともなうすべてのトラブルの原因は、結局のとこ
ろ彼らがこの仕様を発行した人たちと同じ、X/Openの人たちだったことです。こ
れはわたしに、すべてのUnix(という名前を名乗ることを許された)実装にたいし
て、このインターフェースがUnix標準となる未来を予想させるのです(例:
Spec1170)。

11.1.1 インターフェース
-----------------------

   ‘catgets’の実装にたいするインターフェースには、ファイルのアクセスのた
めの3つの関数: ファイルを開く‘catopen’、メッセージテーブルにアクセスする
‘catgets’、そして処理が終わった後にファイルを閉じるための‘catclose’が含
まれます。関数のプロトタイプと、必要となる定義は、‘<nl_types.h>’というヘ
ッダーファイルにあります。

   ‘catopen’は、以下のように呼び出されます:

     nl_catd catd = catopen ("catalog_name", 0);

   関数の引数としてカタログ名を指定します。これは通常、プログラムかパッ
ケージを参照する名前を指定します。2番目のパラメーターは、標準仕様では規
定されていません。わたしには、それがさまざまなシステムで一貫した形で実装
されているかすら、わからりません。あたりさわりのないアドバイスとしては、
値として‘0’を指定するのがよいでしょう。戻り値はメッセージカタログのハン
ドルで、このハンドルは‘open’で戻されるファイルのハンドルと同じです。

   このハンドルは、以下のようにして‘catgets’関数で使うことができます:

     char *translation = catgets (catd, set_no, msg_id, "original string");

   最初のパラメーターはcatalog descriptorです。2番目のパラメーターには
‘msg_id’に保持されるメッセージの、セット番号を指定します。つまり
‘catgets’は、以下のような3段階のアドレッシングを行います:

     catalog name ⇒ set number ⇒ message ID ⇒ translation

   4番目の引数は、翻訳された文字列のアドレスを指すためには使用しません。
これはアドレッシングステージが失敗したとき、デフォルト値を与えるためのも
のです。ここで重要なのは、catgetsの戻り値の型が‘char *’だとしても、結果
の文字列を変更しては_ならない_ということです。本来、この戻り値の型は
‘const char *’のほうがよいのですが、この標準はANSI C標準が発行される1年
前の、1988年に発行されたものなのです。

最後の関数は期待されたとおりに使用され、そのとおりに振る舞います:

     catclose (catd);

   この関数を呼び出すと、そのdescriptorを‘catgets’の呼び出しには使用でき
ません。

11.1.2 ‘catgets’インターフェースに関する問題点?!
------------------------------------------------

   これを説明するのはとても簡単に見えます — わたしたちが話してきたインタ
ーフェースのどこに問題があったのでしょうか? 実際のところ、分別のある使い
方をするかぎり、そのインターフェースを使うことはできます。しかしメッセー
ジカタログを構築するのは苦痛をともないます。その理由は‘catgets’の3番目の
引数となる、一意なmessage IDです。これには、すべてのメッセージのペアごと
に、数字を割り当てなければなりません。ソースコードの変更、たとえばメッセ
ージを追加したり削除するときに、このリストを保守する際に発生する問題を想
像してみてください。もちろん、この混沌を組織化するためのツールもたくさん
開発されました。しかし、あるツールで処理できるのに、他のツールでは読み込
めないといった様相でした。より簡単に管理できて問題もない、他のやり方はあ
るのですが、述べないでおきましょう。

11.2 ‘gettext’について
======================

   ‘gettext’のインターフェースの定義は、Uniforumの提案によるものです。こ
れはSunから提出されたもので、Sunは1990頃に、SunOS4で‘gettext’を実装済み
でした。現在では、‘gettext’のインターフェースは、OpenI18N標準により規定
されています。

   この解決策の主要な点は、通常のファイル処理の手順(open-use-close)を踏
襲しないことと、プログラマーに負担(特に一意なキーの取扱いにたいして)をか
けないことにあります。もちろん一意なキーは必要なので、(メッセージの長短
に関わらず)メッセージ自身をキーとします。比較に関する2つの方法の詳細につ
いては、see Comparisonを参照してください。

   以下のセクションでは、より詳細にインターフェースを説明します。インタ
ーフェースについて詳細を掘り下げて説明するのは、それが GNU ‘gettext’ライ
ブラリーに密接に関係しているからです。ライブラリーの使い方に興味をもつプ
ログラマーは、この説明にも興味をもつことでしょう。

11.2.1 インターフェース
-----------------------

   インターフェースは最小限、a)文字列が由来するドメインの選択(すべてのプ
ログラムが1つのドメインを使用するのは、構築と保守が難しいので、たとえ可
能であったとしても合理的ではありません)、b)選択されたドメインの文字列へ
のアクセス、の機能をもたなければなりません。

   これは主に‘gettext’のインターフェースについての説明です。このインター
フェースは、使用するドメインを与えなかった場合に、無条件に参照されるグロ
ーバルドメインをもっています。もちろん、このドメインはユーザーが選択する
ことができます。

     char *textdomain (const char *domain_name);

   これにより、‘LC_MESSAGE’カテゴリーにおける現在のグローバルドメインの
状態を問い合わせたり変更することができます。引数はヌル終端された文字列で
、ファイル名として使用できる文字でなければなりません。引数DOMAIN_NAMEが
‘NULL’の場合、この関数は現在の値を戻します。値がセットされていなければ、
デフォルトのドメイン名_messages_が戻されます。‘textdomain’の戻り値型は
‘char *’となっていますが、それを変更することはできないことに注意してくだ
さい。それと、ドメイン名が利用可能かのチェックは行われないことを知ること
も重要です。ドメイン名が利用可能でない場合、それは翻訳が提供されていない
という事実をあらわします。

‘textdomain’でセットしたドメインは、以下の関数で使用されます

     char *gettext (const char *msgid);

この関数は想像されるとおりの簡単な方法で使用されます。これにより、現在の
ドメインが利用可能な場合には、MSGIDにたいする翻訳文字列が戻されます。ド
メインが利用可能でない場合には、引数自身が戻されます。引数に‘NULL’が指定
された場合の戻り値は未定義です。

   1つ念頭においてもらいたいのは、使用するドメインを明示的に与えられなか
った場合のことです。この場合には現在のドメインが使用されます。プログラム
中で同じ‘gettext’を呼び出したとしても、実行の間にドメインが変更された場
合には、異なるメッセージカタログが参照されることになります。

   もっとも簡単なのは、国際化されたパッケージで普通に使うケースで、この
場合は実行開始時に呼び出される‘textdomain’により、一意なドメイン名(通常
はパッケージ名)がセットされます。以降のコードでは、翻訳が必要な文字列は
すべてgettext関数により処理されます。これだけでパッケージがあなたの言語
で話し出すのです。

11.2.2 あいまいざの解決
-----------------------

   ほとんどのアプリケーションでは、単一のドメイン名でうまく動作するかも
しれませんが、複数のドメインから翻訳を取得する必要があるアプリケーション
も存在します。‘textdomain’を呼び出すことにより異なるドメインに切り替える
こともできますが、これは不便だし低速です。起こり得る状況としては、この文
書を記述しているときに提出された議論(一般的に使われる関数のすべてのエラ
ーメッセージは、errorというドメインに分離するべきである)のケースがありま
す。これには翻訳が1度で済むという意味があります。他のケースとしてはライ
ブラリーのメッセージの場合で、これらがアプリケーションの現在のドメインか
らは独立している_必要_があります。

これらの理由により、文字列を取得するために、さらに2つの関数が用意されて
います:

     char *dgettext (const char *domain_name, const char *msgid);
     char *dcgettext (const char *domain_name, const char *msgid,
                      int category);

   これらの関数は、どちらも1番目に追加の引数があります。これには
‘textdomain’と同じ引数を与えます。‘dcgettext’の3番目の引数により、
‘LC_MESSAGES’以外の、他のlocale categoryを使うことができます(実際のとこ
ろ、わたしにはこれがどんなときに便利なのか、わかりませんが)。
DOMAIN_NAMEが‘NULL’のとき、またはCATEGORYに未知のものが指定された場合、
結果は未定義となります。Solarisの関数ファミリーの2番目の実装にはでは、
1つは含まれているのに、この関数は含まれていないことも触れておくべきでし
ょう

   多重定義が発生する2番目の理由は、複数のドメインが同じ名前を共有するか
もしれないという事実に起因します。これは必要なメッセージカタログがどこに
あるか指定することで解決します。

     char *bindtextdomain (const char *domain_name,
                           const char *dir_name);

   この関数を呼び出すことにより、指定されたドメインとディレクトリーのフ
ァイルがバインドされます(ファイルがどのように決定されるかは以下で説明し
ます)。特に、システムの既定の位置にあるファイルのかわりに、指定された位
置のファイルを使って‘textdomain’を呼び出したいときに使用します。
DIR_NAMEパラメーターに‘NULL’ポインターを与えると、DOMAIN_NAMEにバインド
されている値が戻されます。DOMAIN_NAME自身が‘NULL’の場合は何も行われず、
‘NULL’ポインターが戻されます。他の関数と同様に、戻された値を変更すること
はできません!

   DIR_NAMEに相対パスを指定することは、トラブルの原因になることを覚えて
おくことは重要です。プログラムが‘chdir’コマンドを呼び出すことにより、カ
レントディレクトリーに関連づいた相対パスは、再計算されます。相対パスの使
用により、常に非依存性と信頼性が無効にされます。

11.2.3 メッセージカタログファイルの配置
---------------------------------------

   さまざまなパッケージごとに、多くの異なる言語を保存する必要があるとい
う理由により、わたしたちにはこれらの情報をメッセージカタログファイルに記
録するための、何らかの方法が必要です。Unix環境でよく使われるのは、ファイ
ル名にエンコード名をもたせる方法で、ここでも同じ方法を用います。ディレク
トリーは、‘bindtextdomain’の2番目の引数に指定するディレクトリー(または既
定のディレクトリー)の後ろに、locale名とlocale category、それとdomain名を
連結したものになります:

     DIR_NAME/LOCALE/LC_CATEGORY/DOMAIN_NAME.mo

   DIR_NAMEの既定値はシステムにより定義されます。この習慣を順守するGNUの
ライブラリーやパッケージのために、以下のように定義されています:
     /usr/local/share/locale

LOCALEは、‘LC_CATEGORY’で指定されたlocale categoryの名前です。
‘gettext’と‘dgettext’の場合、‘LC_CATEGORY’は常に‘LC_MESSAGES’になります
(1)。locale category の名前は、‘setlocale (LC_CATEGORY, NULL)’を通じて決
定されます(2)。‘dcgettext’関数では、3番目の引数にlocale categoryを指定で
きます。

   ---------- Footnotes ----------

   (1) ‘LC_MESSAGES’のないシステムも存在します(例: mingw)。そのような場
合には、任意の値として1729(2つの立方数の和として、2通りの方法で表すこと
のできる最小の正の整数。訳注:ハーディ＝ラマヌジャン数と呼ぶそうです)を使
用します。

   (2) ‘setlocale’がサポートされないシステムでのlocaleの値のセットは、環
境変数を参照するのと同じ方法によりシミュレートされます。

11.2.4 ‘gettext’が使用する出力文字セットの指定方法
--------------------------------------------------

   ‘gettext’は、メッセージカタログ内の翻訳を取得するだけでなく、オンザフ
ライで翻訳出力の文字セットを変換することもできます。これは、翻訳者がメッ
セージカタログを作ったときとは異なる文字セットを使っているユーザーにとっ
て便利です。これにより、文字セットだけが異なるメッセージカタログをいくつ
も作らなくてよくなるからです。

   出力される文字セットのデフォルトは‘nl_langinfo (CODESET)’です。これは
現在のlocaleの‘LC_CTYPE’の部分に依存します。文字列をlocaleとは関係のない
文字セット(例: UTF-8)で保存するプログラムは、‘gettext’や、それに関連する
プログラムにたいして、そのエンコードで翻訳を戻すように要求することができ
ます。これは、‘bind_textdomain_codeset’関数により行います。

   ‘gettext’の引数であるMSGIDは、文字セットの変換の対象外であることに注
意してください。‘gettext’が、MSGIDに対応する翻訳を見つけられなかったとき
は、現在の出力の文字セットとは関係なく、元のMSGIDが変更されずに出力され
ます。すべてのMSGIDに US-ASCII 文字列が推奨されているのは、これが理由で
す。

 -- Function: char * bind_textdomain_codeset (const char *DOMAINNAME,
          const char *CODESET)
     関数‘bind_textdomain_codeset’は、ドメインDOMAINNAME用のメッセージカ
     タログの出力文字セットを指定するのに使用します。引数CODESETには、関
     数‘iconv_open’で使用できる有効なコードセット名、またはNULLポインタ
     ーでなければなりません。

     パラメーターCODESETがNULLポインターの場合、
     ‘bind_textdomain_codeset’は、ドメインDOMAINNAMEで現在選択されている
     コードセットを戻します。コードセットが選択されていないときは、
     ‘NULL’が戻されます。

     ‘bind_textdomain_codeset’関数を複数回呼び出すこともあるでしょう。引
     数DOMAINNAMEを変更せずに複数回呼び出したときは、それ以前に呼び出し
     たときのセッティングによりオーバーライドされます。

     ‘bind_textdomain_codeset’関数は、選択されたコードセットを結合した文
     字列へのポインターを戻します。その文字列は関数内部で割り当てられ、
     ユーザーは変更できません。‘bind_textdomain_codeset’の実行中にシステ
     ムが割り当てに失敗すると、戻り値は‘NULL’となり、グローバル変数
     ERRNOに対応するエラーがセットされます。

11.2.5 あいまいさの解決のためにコンテキストを使用する
-----------------------------------------------------

   グラフィカルユーザーインターフェース(GUI)をもつプログラムで、
‘gettext’関数を普通に使うと、大きな問題がおきるかもしれない箇所がありま
す。その問題とは、翻訳する必要がある文字列のほとんどが、短い文字列である
ような場所で発生します。そらの文字列とは、プルダウンメニューの文字列のよ
うに、長さを制限する必要のある文字列です。それらの文字列は、センテンス全
体を含んでいなかったり、センテンスの断片がプログラムの異なるシチュエーシ
ョンで出現し、シチュエーションごとに異なる翻訳を割り当てる必要のあるもの
です。特にGUIプログラムで頻繁に使用される、1単語の文字列が問題になります
。

   ‘gettext’のアプローチには問題があるので、このような問題が存在しない
‘catgets’を使う必要があるという人もたくさんいます。しかし、この種の問題
を処理するための簡単で強力な方法が、‘gettext’関数には備わっているのです
。

   それは翻訳するべき文字列に、contextを追加する方法です。contextにもと
づく翻訳参照とは、与えられた文字列にたいする翻訳を検索するときに与えられ
たcontextに検索範囲を限定することです。同じ文字列でも、異なるcontextに属
する場合、異なる翻訳を割り当てることができます。ある文字列にたいする
contextごとの翻訳は、1つのMOファイルに一緒に保存でき、翻訳者も1つのPOフ
ァイルを編集するだけです。

   ‘gettext.h’には、context付きの文字列を参照するためのマクロが含まれま
す。これらは‘<libintl.h>’由来の軽量マクロ、またはインライン関数により実
装されています。

     const char *pgettext (const char *msgctxt, const char *msgid);

   このマクロの呼び出しでは、MSGCTXTとMSGIDを文字列リテラルにしなければ
なりません。マクロは、MSGCTXTに与えられたcontextの、MSGIDに対応する翻訳
を戻します。

   MSGCTXTは、POファイル中で翻訳者が目にすることのできる文字列です。あな
たは何らかの方法により標準的なものを定めることと、それを決して変更しない
ことが必要です。なぜならMSGCTXTを変更する度に、翻訳者はMSGIDにたいする翻
訳をレビューする必要があるからです。

   時間を経過しても変更されないような、標準的なMSGCTXT文字列を見つけるの
は困難です。しかし‘pgettext’の呼び出しに、ファイル名やクラス名を使うべき
ではありません – なぜならファイルやクラスの名前を変更するのは開発タスク
では一般的なので、それが翻訳者の作業に影響を及ぼすべきでないからです。ま
た、MSGCTXTに完全な英語センテンスのコメント形式を使うべきでもありません
– なぜなら、そのようなセンテンスに適用される正書法や文法はしばしば変更さ
れるので、繰り返しになりますが、その変更により翻訳者がレビューを強いられ
るべきではありません。

   ‘pgettext’の‘p’は、“particular(特定の)”から由来しています:
‘pgettext’は、特定のMSGIDから翻訳を取得します。

     const char *dpgettext (const char *domain_name,
                            const char *msgctxt, const char *msgid);
     const char *dcpgettext (const char *domain_name,
                             const char *msgctxt, const char *msgid,
                             int category);

   これらの関数は‘pgettext’を、より一般化したものです。それぞれの関数は
、‘dgettext’や‘dcgettext’と同様に振る舞います。引数DOMAIN_NAMEには、翻訳
のドメインを定義します。引数CATEGORYを指定することにより、
‘LC_MESSAGES’とは異なるlocale categoryを指定できます。

   次のような例で考えてみましょう。メニューバーをもつGUIプログラムがあり
、メニューには以下のようなエントリーがあるとします:

     +------------+------------+--------------------------------------+
     | File       | Printer    |                                      |
     +------------+------------+--------------------------------------+
     | Open     | | Select   |
     | New      | | Open     |
     +----------+ | Connect  |
                  +----------+

   コード中の‘File’、‘Printer’、‘Open’、‘New’、‘Select’、‘Connect’の文字
列は、‘gettext’ファミリーの関数によって翻訳される必要があります。しかし
‘Open’という文字列は、2ヶ所で使われており、それにたいして異なる翻訳を割
り当てなければならないかもしれず、それゆえ上述したようなジレンマが発生し
ます。

   メニュー中の同じ2つの文字列を区別するのは、メニューのルートからそれら
のエントリーへのパスです:

     Menu|File
     Menu|Printer
     Menu|File|Open
     Menu|File|New
     Menu|Printer|Select
     Menu|Printer|Open
     Menu|Printer|Connect

   したがってcontextは、メニューのパスから最後の部分を除いたものになりま
す。そうすると呼び出しは以下のようになるでしょう:

     pgettext ("Menu|", "File")
     pgettext ("Menu|", "Printer")
     pgettext ("Menu|File|", "Open")
     pgettext ("Menu|File|", "New")
     pgettext ("Menu|Printer|", "Select")
     pgettext ("Menu|Printer|", "Open")
     pgettext ("Menu|Printer|", "Connect")

   contextの最後に、区切り文字の‘|’をつけるかどうかは、スタイルの問題に
なります。

   より複雑なケースとしては、MSGCTXTやMSGIDが文字列リテラルでない場合が
あります。そのようなケースにたいしては、より一般的なマクロが利用できます
:

     const char *pgettext_expr (const char *msgctxt, const char *msgid);
     const char *dpgettext_expr (const char *domain_name,
                                 const char *msgctxt, const char *msgid);
     const char *dcpgettext_expr (const char *domain_name,
                                  const char *msgctxt, const char *msgid,
                                  int category);

   これらのマクロは、MSGCTXTとMSGIDに、任意の文字列変数を指定できるので
、より一般的です。どちらの引数も文字列リテラルのときは、‘_expr’が付加さ
れていないマクロのほうが効率的です。

11.2.6 複数形(plural forms)にたいする追加の関数
-----------------------------------------------

   いままで説明してきた既存のアプローチでは完全に無視してきましたが、
‘gettext’ファミリーの関数(すべての‘catgets’関数も同様)を実世界で使用する
場合は、1つの問題があります。それはplural form(複数形書式)の取り扱いです
。

   インターナショナリゼーション以前のUnixのソースコード(そして悲しいこと
にインターナショナリゼーション以降のソースコードさえも)を見てみると、以
下のようなコードを目にすることがあります:

        printf ("%d file%s deleted", n, n == 1 ? "" : "s");

最初にコードをインターナショナライズする人々から不具合が報告された後は、
このような複数形についての場合分けを無視するか、‘"file(s)"’という文字列
を使うようになりました。これはどちらも不自然で解決法とはなりませんでした
。最初の試みとして、以下のようにすることで解決が図られました:

        if (n == 1)
          printf ("%d file deleted", n);
        else
          printf ("%d files deleted", n);

   しかし、これは問題の解決になっていません。この方法は、単純に名詞に
‘s’ を追加することによりplural formを表現するだけではない言語をも対象と
していましたが、結局それだけのことでした。人々は自分が使っている言語のル
ールが、他の言語にも適用できる普遍的なものだと信じるという罠に陥っていた
のです。実際には言語ファミリー間でplural formの取り扱いかたは大きく異な
っていたのです。たとえば、Rafal Maszkowski ‘<rzm@mat.uni.torun.pl>’によ
る以下のレポートを見てください:

     わたしたちはPolishでplik(fileのこと)を以下ように表現します:
          1 plik
          2,3,4 pliki
          5-21 pliko'w
          22-24 pliki
          25-31 pliko'w
     以下同様にカウントしていきます(o’は8859-2 oacuteを意味しており、
     okreskaより、むしろaogonekと似ています。

   言語間(そして言語ファミリー内部においてさえも)には、2つの異なる事象が
存在しました:

   • plural formを構築する方式が異なること。これは規則的ではないルールを
     多くもつ言語で問題になります。極端なケースとしてはGermanがあげられ
     ます。EnglishからGermanへは、同じ言語ファミリー(Germanic)ですが、名
     詞に( ‘s’) を付加して複数形を表す標準的な方式を、Germanではほとんど
     見出せません。

   • plural formを適用するべき数値が異なること。これは、複数形にすべき数
     値が単に2からであるような、RomanicやGermanicしか経験したことのない
     人を驚かせます。

     単一の形式しかもたない言語ファミリーや、多数の形式をもつ言語ファミ
     リーがあります。これに関する更なる情報は、このセクションの範囲を超
     えています。

   これらの理由により、アプリケーションを記述する人は、これらの問題をコ
ードで解決するべきではないという結論になります。これは言語環境にたいして
ハードコードされた状態においてのみ有用なローカリゼーションでしょう。かわ
りに拡張された‘gettext’のインターフェースを使うべきです。

   これらの追加の関数は、単一のキー文字列ではなく、2つの文字列と、数値の
引数をとります。この考え方の背景には、数値の引数と最初の文字列をキー文字
列として使用することにより、翻訳者が指定した正しいplural formを実装が選
択できるようにするというアイデアがあります。それから、2つの文字列引数は
、メッセージカタログが見つからなかったときの戻り値を提供するために使用さ
れます(これは通常の‘gettext’の振る舞いと同じです)。このケースでは
Germanic言語のルールが適用され、最初の文字列引数はsingular form、2番目の
文字列引数はplural formとみなされます。

   この結果、言語カタログをもたないプログラムは、それがGermanic言語のル
ールにしたがって記述された場合のみ正しい文字列を表示できるということにな
ります。これは確かに制限なのですが、GNU C library(とGNU ‘gettext’パッケ
ージ)がGNUパッケージの一部として記述されていること、そしてGNUプロジェク
トのコーディング規約がEnglishによるプログラム記述を要請しているので、制
限があるにもかかわらずこの解決策により要件を満足することができるのです。

 -- Function: char * ngettext (const char *MSGID1, const char *MSGID2,
          unsigned long int N)
     ‘ngettext’関数は、‘gettext’関数と似ており、メッセージカタログを検索
     する方法は同じですが、2つの追加の引数をとります。パラメーター
     MSGID1には、変換する必要のある文字列のsingular formを指定します。こ
     のパラメーターはカタログを検索するキーとしても使用されます。パラメ
     ーターMSGID2にはplural formを指定します。パラメーターNは、plural
     formの適用を決定するのに使用されます。メッセージカタログが見つから
     なかったとき、‘n == 1’なら‘msgid1’が戻され、それ以外のときは
     ‘msgid2’が戻されます。

     以下はこの関数の使用例です:

          printf (ngettext ("%d file removed", "%d files removed", n), n);

     Nの数値は、‘printf’関数にも引き渡されることに注意してください。
     ‘ngettext’だけに渡したい場合、この例は不適切です。

     Englishのsingular caseの場合、常に1であるような数値は、"one"に置き
     換えることができます:

          printf (ngettext ("One file removed", "%d files removed", n), n);

     ‘printf’関数は、format stringが与えられていない余分な引数を無視する
     ので、この例は問題なく動作します。

     ここで2つ以上の引数を要求するようなformat stringを関数で使う場合、
     以下の例のような使い方はできません:

          printf (ngettext ("%d file removed from directory %s",
                            "%d files removed from directory %s",
                            n),
                  n, dir);

     Englishでsingular caseのときに‘%d’を“one”に置き換えたように、他の言
     語の翻訳者も特定の単語に置き換えたいと望むかもしれません。しかしCの
     format stringでは、1番目の引数をスキップして2番目の引数を使用するよ
     うなことはできません。このような場合は引数の順番を変えて、‘n’が最後
     にくるようにする必要があります:

          printf (ngettext ("%$2d file removed from directory %$1s",
                            "%$2d files removed from directory %$1s",
                            n),
                  dir, n);

     このように引数の配置を指定する文法についての詳細は、see
     c-formatを参照してください。

     ‘n’の値がとる範囲がわかっている場合には、‘xgettext’ツールのためのコ
     メントを指定することができます。以下の例のような情報は、翻訳者が適
     切な翻訳を行う助けとなるでしょう:

          if (days > 7 && days < 14)
            /* xgettext: range: 1..6 */
            printf (ngettext ("one week and one day", "one week and %d days",
                              days - 7),
                    days - 7);

     以下の例のように、文字列に数値が含まれないようなときに、この関数を
     使うこともできます:

          puts (ngettext ("Delete the selected file?",
                          "Delete the selected files?",
                          n));

     この例で、Nはplural formであるかを判定するためだけに使用されていま
     す。

 -- Function: char * dngettext (const char *DOMAIN, const char *MSGID1,
          const char *MSGID2, unsigned long int N)
     ‘dngettext’は、選択されたメッセージカタログにたいして、‘dgettext’と
     同様な方法で使用します。異なるのは、正しいplural formのために、2つ
     の余分なパラメーターを指定できる点です。この2つのパラメーターは、
     ‘ngettext’のときと同様に処理されます。

 -- Function: char * dcngettext (const char *DOMAIN, const char *MSGID1,
          const char *MSGID2, unsigned long int N, int CATEGORY)
     ‘dcngettext’は、選択されたメッセージカタログにたいして、
     ‘dcgettext’と同様な方法で使用します。異なるのは、正しいplural formの
     ために、2つの余分なパラメーターを指定できる点です。この2つのパラメ
     ーターは、‘ngettext’のときと同様に処理されます。

   では、これらの関数はどのようにしてplural formsの問題を解決しているの
でしょうか? 言語学の情報(そして、それは利用可能ではありません)がないかぎ
り、少しの差異しかないplural formのうちからどれを使用すればよいのか、そ
して新たにサポートされる言語ごとに数を増やせるかを決定することはできませ
ん。

   したがって、plural formを選択するルールを翻訳者が指定するという解決策
が実装されました。各言語ごとに方式が異なる以上、これはコード内に情報をハ
ードコーディングする以外の、唯一可能な解決策なのです(それでもまだ新しい
言語の使用を妨げない拡張可能性を満たすという要件は残されています)。

   plural form選択のための情報は、以下のようにPOファイルのヘッダーエント
リー(‘msgid’が空文字列のエントリーのうちの1つ)に保存されています:

     Plural-Forms: nplurals=2; plural=n == 1 ? 0 : 1;

   ‘nplurals’には、その言語では何種類のplural formがあるのかを数字で指定
します。‘plural’に続く文字列には、C言語で使用できる評価式です。負の数値
は使用できません。数値には正の整数を指定します。また、変数として使用でき
るのは‘n’だけです。式で空白を使うことはできますが、バックスラッシュは使
用できません。以下の例のうち、バックスラッシュと改行が使用されている例が
ありますが、これは表示を見やすくする目的のためだけに使用しています。この
式は‘ngettext’、‘dngettext’、‘dcngettext’が呼び出されたときに評価されま
す。これらの関数に数値が渡されると、式中の変数‘n’の値として、その数値が
評価されます。結果は0以上、かつ‘nplurals’に指定した値より小さくなければ
なりません。

複数形の使い分けについては、以下のルールが知られています。言語と言語のフ
ァミリーが記載されていますが、この情報を言語ファミリー全体に適用する必要
があるという訳ではありません(見やすくするために併記しています)。(1)

１つの形式だけを使うもの:
     1つの形式しか必要としない言語があります。これらの言語ではsingular
     formとplural formの区別はありません。この場合の適切なヘッダーエント
     リーは以下のようになるでしょう:

          Plural-Forms: nplurals=1; plural=0;

     このような特性をもつのは以下の言語です:

     Asian family
          Japanese, Vietnamese, Korean

2つの形式がありsingularは１にしか適用しないもの
     この形式はEnglishで使われているもので、既存のプログラムでも一番多く
     使用されています。この場合のヘッダーエントリーは以下のようになるで
     しょう:

          Plural-Forms: nplurals=2; plural=n != 1;

     (注意: これはCの真偽値が0か1の2値をとる機能を使用しています。)

     このような特性をもつのは以下の言語です:

     Germanic family
          English, German, Dutch, Swedish, Danish, Norwegian, Faroese
     Romanic family
          Spanish, Portuguese, Italian, Bulgarian
     Latin/Greek family
          Greek
     Finno-Ugric family
          Finnish, Estonian
     Semitic family
          Hebrew
     Artificial
          Esperanto

     同じヘッダーエントリーを使う他の言語:

     Finno-Ugric family
          Hungarian
     Turkic/Altaic family
          Turkish

     Hungarianは、数字を含んだセンテンスでは複数形を使いません。たとえば
     “1 apple”は “1 alma” で、“123 apples”も“123 alma”です。しかし数が明
     確でない場合には“the apple”は“az alma”、“the apples”は“az almák”の
     ようにsingularとpluralを区別します。このようなセンテンスを
     ‘ngettext’がサポートするようになってから、Hungarianも2つの形式をも
     つクラスに分類されるようになりました。

     Turkish も同様です: “1 apple”は“1 elma”で、“123 apples”も“123
     elma”です。しかし数字が省略された場合には、“the apple”は“elma”、
     “the apples”は“elmalar”のようにsingularとpluralを区別します。

2つの形式がありsingularを0と1に適用するもの
     言語ファミリーの例外的なケースです。ヘッダーエントリーは以下のよう
     になります:

          Plural-Forms: nplurals=2; plural=n>1;

     このような特性をもつのは以下の言語です:

     Romanic family
          Brazilian Portuguese, French

3つの形式があり、0を特別なケースとして扱うもの
     ヘッダーエントリーは以下のようになります:

          Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2;

     このような特性をもつのは以下の言語です:

     Baltic family
          Latvian

3つの形式があり、1と2を特別なケースとして扱うもの
     ヘッダーエントリーは以下のようになります:

          Plural-Forms: nplurals=3; plural=n==1 ? 0 : n==2 ? 1 : 2;

     このような特性をもつのは以下の言語です:

     Celtic
          Gaeilge (Irish)

3つの形式があり、00または[2-9][0-9]で終わる数字を特別なケースとして扱うもの
     ヘッダーエントリーは以下のようになります:

          Plural-Forms: nplurals=3; \
              plural=n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < 20)) ? 1 : 2;

     このような特性をもつのは以下の言語です:

     Romanic family
          Romanian

3つの形式があり、1[2-9]で終わる数字を特別なケースとして扱うもの
     ヘッダーエントリーは以下のようになります:

          Plural-Forms: nplurals=3; \
              plural=n%10==1 && n%100!=11 ? 0 : \
                     n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2;

     このような特性をもつのは以下の言語です:

     Baltic family
          Lithuanian

3つの形式があり、1、または2、3、4で終わる数字を特別なケースとして扱うもの、ただし1[1-4]で終わる数字を除く
     ヘッダーエントリーは以下のようになります:

          Plural-Forms: nplurals=3; \
              plural=n%10==1 && n%100!=11 ? 0 : \
                     n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;

     このような特性をもつのは以下の言語です:

     Slavic family
          Russian, Ukrainian, Belarusian, Serbian, Croatian

3つの形式があり、1と、2、3、4を特別なケースとして扱うもの
     ヘッダーエントリーは以下のようになります:

          Plural-Forms: nplurals=3; \
              plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;

     このような特性をもつのは以下の言語です:

     Slavic family
          Czech, Slovak

3つの形式があり1と、2、3、4で終わる数字を特別なケースとして扱うもの
     ヘッダーエントリーは以下のようになります:

          Plural-Forms: nplurals=3; \
              plural=n==1 ? 0 : \
                     n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;

     このような特性をもつのは以下の言語です:

     Slavic family
          Polish

4つの形式があり1と、02、03、04で終わるすべての数字を特別なケースとして扱うもの
     ヘッダーエントリーは以下のようになります:

          Plural-Forms: nplurals=4; \
              plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3;

     このような特性をもつのは以下の言語です:

     Slavic family
          Slovenian

   ここまで読んで、あなたは思うかもしれません。‘ngettext’が扱うNの型は
‘unsigned long’だ。では、もっと大きな整数型の場合はどうだろうか? 負の数
値については? 浮動小数値の場合は?

   ‘uintmax_t’や‘unsigned long long’のようなより大きな数値のための整数型
の場合、これらの数値は‘unsigned long’の範囲に適合するように値を小さくし
て処理できます。この場合、単に値を‘unsigned long’にキャストするのは正し
くありません(キャストでは‘ULONG_MAX + 1’は0、‘ULONG_MAX + 2’は1、...のよ
うにキャストされます)。あなたは、いままで紹介してきたすべてのplural
formで、100(または1000や1000000)で除する方法によって数式を間接的に評価で
きるという事実を見てきたでしょう。もし大きな数値を、下6桁を保持して
[1000000, 1999999]という範囲の他の数値に置き換えられれば、同じplural
formの選択方法で取り扱えます。この場合のコードは以下のようになるでしょう
:

     #include <inttypes.h>
     uintmax_t nbytes = ...;
     printf (ngettext ("The file has %"PRIuMAX" byte.",
                       "The file has %"PRIuMAX" bytes.",
                       (nbytes > ULONG_MAX
                        ? (nbytes % 1000000) + 1000000
                        : nbytes)),
             nbytes);

   負の数や小数については、通常はsingularかpluralが明解でない物質量に適
用されます。このようなケースでは、‘ngettext’を使う必要はなく、単にすべて
の値に適切な形式を指定して‘gettext’を呼び出します:

     printf (gettext ("Time elapsed: %.3f seconds"),
             num_milliseconds * 0.001);

NUM_MILLISECONDSが1000の倍数のようなときでも、出力は以下のようになります
     Time elapsed: 1.000 seconds
これは、Englishや他の言語でも許容できる出力です。

   plural formにたいする翻訳者の考え方については、see Translating plural forms
で説明しています。

   ---------- Footnotes ----------

   (1) 追加の情報を歓迎します。<bug-gnu-gettext@gnu.org>か
<bug-glibc-manual@gnu.org>までメールしてください。

11.2.7 *gettext関数の最適化
---------------------------

   この点を議論するには、GNU ‘gettext’の実装の優位性について話す必要があ
ります。インターナショナライズされたプログラムは、翻訳する必要のある文字
列がループ内にあるような場合に性能が劣化すると思う読者がいるかもしれませ
ん。たしかにループを実行するごとに文字列が評価されることによる劣化は無視
できません。ループの実行中に文字列が変化しない場合に毎回文字列を翻訳する
場合は、時間の無駄になります。以下の例で考えてみましょう:

     {
       while (...)
         {
           puts (gettext ("Hello world"));
         }
     }

選択したlocaleが実行中に変更されないような場合、翻訳結果の文字列は常に同
じです。以下のようなやり方も1つの方法です:

     {
       str = gettext ("Hello world");
       while (...)
         {
           puts (str);
         }
     }

しかしこの解決策は、すべての状況で使える訳ではありません(例: 実行中に
localeが変更される場合)。また、コードも読みにくくなってしまいます。

   この理由により、GNU ‘gettext’は以前の結果をキャッシュしています。同じ
翻訳が2度要求された場合、要求の間に新たなメッセージカタログがロードされ
ていなければ、2度目の呼び出しでは‘gettext’は結果をキャッシュから取得しま
す。

11.3 2つのインターフェースの比較
================================

   以下の議論は幾分誇張されたものかもしれません。これまで述べてきたよう
に、わたしたちはUniforumの勧告にしたがう理由があって、GNU ‘gettext’を実
装しました。しかし、どのようにしてこの決定に至ったかをお見せするべきでし
ょう。

   最初に開発プロセスを概観してみましょう。わたしたちが‘gettext’により提
供されるNLSを使ってアプリケーションを記述するときは、いつものとおり処理
のことです。ユーザーの目に触れるので文字列を翻訳する必要があるときだけ、
わたしたちは‘"..."’のかわりに‘gettext("...")’を使って翻訳を行います。各
ソースファイル(または中核となるヘッダーファイル)で、以下を定義します

     #define gettext(String) (String)

   この定義により、システムのCライブラリー自体で‘gettext’がサポートされ
ていても、それを無効化できます。このコードをコンパイルすると、NLSコード
を使わない場合と同じ結果が得られます。GNU ‘gettext’のコードを見ると、
‘gettext("...")’のかわりに‘_("...")’を使っているのがわかるでしょう。これ
により翻訳可能な文字列のために余分にタイプしなければならない文字数を3文
字まで減らせます。

   これを出荷するバージョンのプログラムにする場合は、単に以下の定義

     #define _(String) (String)

を、以下の定義に置き換えるだけで済みます。

     #include <libintl.h>
     #define _(String) gettext (String)

そして、翻訳可能な文字列を含むすべてのソースファイルにたいして
‘xgettext’プログラムを実行します。わたしたちは翻訳が利用できないものにた
いしても、利用可能になったら使えるように、プログラムを実行します。

   同様のことは‘gettext_noop’呼び出しでも行うことができます(see
Special casesを参照してください)。‘gettext_noop’は通常、no-op(訳注:
no-operation = 何もしない) マクロとして定義します。プロジェクトでは以下
のようなコードを考慮する必要があります:

     #define gettext_noop(String) String
     #define N_(String) gettext_noop (String)

   ‘N_’は、‘_’と同様、省略形です。GNU ‘gettext’の‘po/’ディレクトリーにあ
る‘Makefile’は、これらの省略形を認識するので、必要に応じて使うことができ
ます。

   今度は‘catgets’を見てみましょう。主な問題点はプログラマー向けの機能に
あります。彼は、翻訳可能な文字列ごとに、毎回異なる数字(または記号定数)を
割り当てる必要があります。彼は重複したエントリー、重複したメッセージID、
etc...にも注意を払わなければなりません。もしGNU ‘gettext’プログラムが提
供するのと同じ品質をメッセージカタログにもたせたい場合、文字列にたいする
説明コメントやソースコード中での場所をメッセージカタログに記述しなければ
なりません。これはほとんどMission: Impossibleでしょう。

   しかし‘catgets’の優位性を語る人たちが触れる点もいくつかあります。文字
列内にある単語があり、その文字列が異なるコンテキストや他の言語で使われて
いる場合に、その単語は異なる翻訳をもつことができます。以下に例を示しまし
ょう:

     printf ("%s: %d", gettext ("number"), number_of_errors)

     printf ("you should see %d %s", number_count,
             number_count == 1 ? gettext ("number") : gettext ("numbers"))

   この例では、‘"number"’という文字列を2回翻訳する必要があります。たとえ
あなたがEnglishに類する言語を話さなくても、この単語が2つの文で異なる意味
をもつかもしれないことに気づくでしょう。Germanでは、1番目にたいして
‘"Anzahl"’、2番目には‘"Zahl"’と翻訳する必要があります。

   これであなたはこのが難解な例だということに同意するでしょう。そしてあ
なたは間違っていません! では問題を正確に把握して、その問題がそれほど深刻
ではないことにも気づくはずです。この問題は以下のようにして簡単に解決する
ことができます:

     printf ("%s %d", gettext ("number:"), number_of_errors)

     printf (number_count == 1 ? gettext ("you should see %d number")
                               : gettext ("you should see %d numbers"),
             number_count)

   わたしたちは、この方法で文字列の競合はすべて解決できると信じます。も
し競合する文字列の一方を変更するのが困難なら、もう一方の文字列を少しだけ
変更することも考慮できます。これを克服するのは不可能ではありません。

   ‘catgets’は、同じ元文字列にたいして異なる翻訳をもたせることができます
。‘gettext’では同じ元文字列にたいして異なる翻訳をもたせることはできませ
んが、この種のあいまいさによる問題を解決する、よりスケーラブルな解決策が
あります。Ambiguitiesを参照してください。

11.4 独自のプログラム内でlibintl.aを使用する
============================================

   ライブラリーのバージョン0.9.4から始める場合、‘libintl.h’は自己充足的
になっています(例: 追加の関数なしでプログラムで使用できます)。ヘッダーと
ライブラリーは‘Makefile’により、‘$(prefix)’で選択されたディレクトリーに
配置されます。

11.5 ‘gettext’を根底から理解する
================================

   *注意: *このセクションの文書は時代遅れになっているので、改訂する必要
があります。

   ソースコードを読むことは、GNU ‘gettext’の機能を完全に活用するための助
けになるでしょう。しかし、(時として込み入った内容の)コードを読むために時
間 費やすことを望まない人々のために、幾つかのコメントを挙げておきます:

   • 実行時に言語を変更する

     対話的なプログラムにおいては、使用する言語を実行時に尋ねたほうが有
     用であることがあります。これを理解するためには、‘gettext’関数が使用
     する言語をどのように決定しているのかを知る必要があります。ここに示
     す方法はGNUによる‘gettext’関数の実装においてのみ正しいものです。

     dcgettext関数は呼出しごとに、環境変数の中で最高のプライオリティを持
     つものを探し出して使用します。プライオリティは以下のリストで示され
     ます。プライオリティは下にいくにつれて低くなります。

       1. ‘LANGUAGE’
       2. ‘LC_ALL’
       3. ‘LC_xxx’、選択されたロカールによる
       4. ‘LANG’

     その後、検索された値を用いてパスが設定され、可能であれば翻訳ファイ
     ルがロー ドされます。

     「今」とは、‘LANGUAGE’が変更されたときです。上で説明した過程に従い
     、この変数の新しい値は‘dcgettext’関数が呼び出された時点で決定されま
     す。これは(おそらく)異なったメッセージカタログがロードされることを
     意味します。即ち、使用する言語が変更されるのです。

     しかし、これは一つの小さなフックに過ぎません。 gcc 2.7.0以上のコー
     ドでは幾分の最適化が図られています。この最適化は通常、‘dcgettext’関
     数の呼び出しによって新しいカタログがロードされる前に行われます。し
     かし、もしdcgettextが呼び出されなければ、プログラムもまた
     ‘LANGUAGE’変数の値が変更されたことを知ることができないでしょう
     (see Optimized gettextを参照してください)。この解決方法は非常に
     簡単です。以下のコードを言語変更関数の前に 置けばよいのです。

            /* Change language.  */
            setenv ("LANGUAGE", "fr", 1);

            /* Make change known.  */
            {
              extern int  _nl_msg_cat_cntr;
              ++_nl_msg_cat_cntr;
            }

     変数‘_nl_msg_cat_cntr’は‘loadmsgcat.c’中で定義されています。あなた
     はこれが何のためのものなのか知る必要はありません。しかし、これは、
     ある‘gettext’実装がGNU gettextなのか、それとも非GNUシステムのネイテ
     ィブのgettext実装なのかを決定するために使用できます。

11.6 プログラマの章についての一時的なメモ
=========================================

   *注意: *このセクションの文書は時代遅れになっているので、改訂する必要
があります。

11.6.1 一時的な情報 - 二つの実装
--------------------------------

   言語に依存せずにメッセージを扱う二つの手法があります。一つはX/Openの
catgetsによるものであり、もう一つはUniforumのgettextによるものです。
catgetsによる方法では、整数によってメッセージを指定します。gettextによる
方法では、英語のメッセージによって指定します。catgetsによる方法は長く使
われ、多くのベンダでサポートされています。gettextによる方法ははSunでサポ
ートされていて、COSEマルチベンダイニシアティブ(COSE multivendor
initiative)がサポートするようです。どちらもPOSIX標準とはなりませんでした
。POSIX.1 委員会では、この件に関して様々な見解の相違がありました。

   二つの手法のいずれもPOSIX標準ではありません。‘gettext’と
‘catgets’(XPG)ルーチンのいずれを標準として採用するかについて、POSIX.1 委
員会ではは様々な議論がなされました。委員会の終盤に至っても何らの合意は得
られず、結局メッセージングシステムは標準規格には含まれませんでした。私は
XPG3メッセージングインターフェースに関する追記を標準に付与するのは有益で
あると信じていますし、“...メッセージングシステムの実例は既に実装されてい
るのです...”

   委員会は、ある一つのインターフェースの実装を使うのが良いということを
どの場所でも言わないように非常に注意していました。この話題に関するこれ以
上の情報 については、国際化プログラミングFAQ(Programming for
Internationalization FAQ)を参照して下さい。

11.6.2 一時的な情報 - ‘catgets’について
---------------------------------------

   ‘catgets’を基盤として使用することに関する討議の末期には、幾つかの議論
がありました。その議論の両側を提示することは大切だと思いますし、これから
、私はちょっとしたことに対して「悪魔の弁護士」となってみることにします。

   ‘catgets’はもっと良くデザイン出来たでだろうということは否定しません。
その実装には既に指摘したような制限が少なからずあります。

   しかしながら、その一貫性と標準化の度合いについては申し分ありません。
UNIXソフトウェアを書くときに繰り返し発生する問題とは、UNIXプラットフォー
ム間での移植性に関する問題です。それは全ての UNIXベンダがオペレーティン
グシステム上を調べて改良する部分を見つけたようなものです。疑いもなく、こ
れらの修正は革新的なものであり、現実の問題を解決するものです。しかしなが
ら、ソフトウェアベンダがこれらの変更を多くのプラットフォームで行いつづけ
るには、多くの労力が必要です。

   そしてこれは各UNIXベンダが自社のシステムを標準化することを促進します
。Spec1170に準拠するためにです。各主要UNIXベンダはこの標準化のために委員
会を設けました。そして全てのUNIXソフトウェア開発者はこの標準に従ってソフ
トウェアを作成し、異なるプラットフォームへソフトウェアを導入する際には
(autoconfを使うことなく)リコンパイルするだけで済むようになる日を心待ちに
し ているのです。

   私の理解しているところでは、Spec1170はX/Open Portability Guidelinesの
バージョン4(XPG4)に基づいたものです。‘catgets’とその眷属がXPG4で定義され
ているので、私は‘catgets’がSpec1170の一部であり、それがすべてのUNIXシス
テムの標準的なコンポーネントになることを信じています。

11.6.3 一時的な情報 - なぜ一つの実装なのか
------------------------------------------

   メッセージカタログにアクセスするために二つの異なるシステムをインスト
ールすることは不経済なことのように思えます。我々が‘catgets’の不足してい
るものを改善したいと思ったのなら、なぜ新しいシステムを実装するのではなく
、‘catgets’を(互換性を保ちながら)拡張しようとしないのでしょうか? いずれ
にせよ我々は、メッセージカタログにアクセスするためのシステムをオペレーテ
ィ ングシステムに対して二つインストールすることになるでしょう。一つは
GNUソフ トウェアのためルーチン群であり、もう一つはその他全てのソフトウェ
アのためのルーチン群(catgets)です。傲慢でしょうか?

   カタログにアクセスする別のシステムが実装されたと仮定してみましょう。
我々がお奨めするのはどちらでしょうか? 少なくともLinuxシステムに対しては
、我々は可能な限り多くのソフトウェア開発者を呼び込む必要があります。その
ため、我々はソフトウェア開発者が彼らのソフトウェアを移植しやすいようにす
る必要があります。そしてそれは‘catgets’をサポートすることを意味します。
我々は ‘libintl’コードを‘libc’中に実装するでしょうが、‘libc’には別のメッ
セージカタログに対するアクセス方法を同じように取り込まなければいけないと
いうことなのでしょうか? そして、‘libintl’と非‘catgets’ルーチンを組み合わ
せて使おうとする人達に関してはどうでしょうか?ソフトウェア開発者が彼らの
ソフトウェアを他のプラットフォームに移植する際、彼らはそのソフトウェアに
単に‘libintl’を含めるだけでなく、フロントエンド(‘libintl’)コードと、バッ
クエンド(非‘catgets’アクセスルーチン)コードを付け加えようとするでしょう
。

   しかしメッセージカタログのサポートは氷山の一角に過ぎません。他のロカ
ールカテゴリのデータはどうでしょうか。それらもまた、多くの相違点を持って
います。我々はそれに対処することを諦めて、重複したルーチン群を別々に開発
せねばならないのでしょうか(‘libintl’をメッセージカタログサポート以上のも
のにすべきなのでしょうか)?

   UNIX上の改良可能な多くの部分と同じように、我々は将来に向けて改良を加
えつつも、過去のものに対する互換性を落とさないようにしていました。

11.6.4 一時的な情報 - ノート
----------------------------

   多くの実装が最終形式からかけ離れたものであったため、X/Openが標準形式
を承認するのは非常に遅くなりました。私の使っている両方のシステム(古い
Linux catgetsとUltrix-4)には奇妙なバリエーションがあります。

   最後の変更を加えた後、私はGNU/Linux ‘libc’の‘gettext’関数群を作成する
ために時間を割かねばなりませんでした。従って、将来的にはSolarisが
‘gettext’を備えた唯一のシステムであるということはなくなります。

12 翻訳者の視点
***************

12.1 イントロダクション0
========================

   *注意: *このセクションの文書は時代遅れになっているので、改訂する必要
があります。

   GNUは国際化しつつあります! 翻訳プロジェクトは保守担当者、翻訳者、そし
てユーザーを全てまとめるもので、そのためGNUソフトウェアは徐々に多くの言
語を喋ることが出来るようになります。

   GNU ‘gettext’ツールセットには、保守担当者がパッケージのメッセージを国
際化するために必要となる_全て_があります。また、パッケージが国際化された
後で、翻訳者がメッセージの地域化を行う際の助けになるような便利なツールも
あります。

   翻訳プロジェクトを完遂するために、我々は自分の国の言葉を愛し、良く書
くことが出来、そして他の翻訳者が話しているのと同じ言語で助けることの出来
る(synergize)能力を持った人間を数多く必要としています。もしあなたが翻訳
チームでボランティアとして働くことを望むなら、該当する翻訳チームにメー ル
を出して下さい。

   各チームはLinux Internationalの好意による自身のメーリングリストを持っ
ています。‘LL@li.org’というアドレスのLLをあなたの注目する言語のISO 639の
二文字コードに置き換えることによって、その言語の翻訳チームに連絡できます
。言語コードはISO 3166に定められている国コードと同じではありません。現時
点では以下の翻訳チームが存在します。

     Chinese ‘zh’、Czech ‘cs’、Danish ‘da’、Dutch ‘nl’、Esperanto ‘eo’、
     Finnish ‘fi’、French ‘fr’、Irish ‘ga’、German ‘de’、Greek ‘el’、
     Italian ‘it’、Japanese ‘ja’、Indonesian ‘in’、Norwegian ‘no’、
     Polish ‘pl’、Portuguese ‘pt’、Russian ‘ru’、Spanish ‘es’、Swedish
     ‘sv’、Turkish ‘tr’。

仮に中国語翻訳チームにメールを出すとすれば、‘zh@li.org’となります。翻訳
チームのメンバーになるには、その言語チームのメーリングリストに登録する必
要があります。例えば、スウェーデン人は本文に以下の内容を記述して
‘sv-request@li.org’にメールを出します。

     subscribe

   チームのメンバーは翻訳_作業_に興味を持つべきだということを心に留めて
置いて下さい。そうでなければ翻訳を果たすことは難しいのです。もしが希望す
る言語のチームがまだ存在せず、その言語のチームを作りたいという場合には
‘coordinator@translationproject.org’まで連絡して下さい。それによって全て
の翻訳チームの調整者に連絡が取れます。

   一握りのGNUパッケージには幾つかの言語に対するメッセージの翻訳が適用・
提供 されています。翻訳チームは組織化され始めており、これらのパッケージ
を起点として使っています。しかしまだまだ多くのパッケージがあり、多くの言
語についてはボランティアの翻訳者がいません。もし翻訳チームでボランティア
として作業したいと思うのでしたら、‘coordinator@translationproject.org’に
作業することの出来る言語を明記してメールを送って下さい。

12.2 イントロダクション1
========================

   *注意: *このセクションの文書は時代遅れになっているので、改訂する必要
があります。

   現在公式に、GNUは国際化しつつあります! 以下は1995年1月のGNU Bulletinで
述べられた声明です。

     一握りのGNUパッケージには幾つかの言語に対するメッセージの翻訳が適用
     ・提供されています。翻訳チームは組織化され始めており、これらのパッ
     ケージを起点として使っています。しかしまだまだ多くのパッケージがあ
     り、多くの言語についてはボランティアの翻訳者がいません。もし翻訳チ
     ームでボランティアとして作業したいと思うのでしたら、
     ‘coordinator@translationproject.org’に作業することの出来る言語を明
     記してメールを送って下さい。

   本ドキュメントはその過程に興味を持ったり、貢献したいと考えている人々
が持つ多くの疑問に答えます。願わくばざっと目を通し、GNUの国際化に対する
この集合的努力から産み出される大量のメールの幾ばくかでもを担当して下さい
。

   広く共用される多くのフリーソフトウェアのプログラミングは英語で行われ
ています。そして現在のところ、英語はGNUプロジェクトに協力する国家的コミ
ュニ ティ間での主要なコミュニケーション言語として使われています。このド
キュメントでさえも英語で書かれています。これは当面変わらないでしょう。

   しかしながら、多くのソフトウェアで自国語や自国の習慣を用いたいという
、国家的コミュニティからの強い欲求があります。また、GNUソフトウェアをそ
のようにするための努力が現在も行われています。この試みは今までのところプ
リテスタからの熱心な反応の向上によって動かされており、我々はGNUの国際化
は成功すると信じています。

   このドキュメントに対する内容の明確化、追加、訂正に関する提案について
は、‘coordinator@translationproject.org’までメールを送って下さい。

12.3 議論
=========

   *注意: *このセクションの文書は時代遅れになっているので、改訂する必要
があります。

   この国際化の効果を目の当たりにして、幾人かのユーザが彼らの考えを表明
しています。紹介され議論されたこれらの疑問の幾つかをここに挙げてみましょ
う。

   • より小さいグループ

     幾つかの言語は多くの人々によって話されていないため、その言語を話す
     人々はフリーソフトウェアパッケージの当該言語版に対する必要性はあま
     りないと考えています。更に、幾つかの国にいるコンピュータの_中にいる
     _多くの人々は一般的に英語版ソフトウェアのほうを好むようです。

     一方で、人々は自分達の言語を非常に好きですし、彼らのお気に入りのフ
     リーソフトウェアが彼らの母国語を喋ることが出来るように努力します。
     彼らは個人的な楽しみのためにそれを行います。そしてどのくらいの人間
     がその作業によって便益を得るかなどといったことは考えません。

   • 解釈の誤り

     ある種の誤ったプロパガンダのせいか、一部のユーザは自身の言語を押し
     出すことについて臆病になっています。ある人は、ネットワークの向こう
     側にはその言語をうるさくせがむユーザがいるに違いないと考えています
     。

     しかしあらゆる言語には地域化される価値があります。なぜなら、その言
     語が大切で敬愛されるものであると考える人々がその言語の向こうにいる
     からです。

   • 変な翻訳

     誰もがメッセージを理解出来るためには、正しい翻訳を見つけ出すことが
     もっとも大きな問題となります。翻訳は通常、少し変なものなのです。一
     部の人々は、「どちらかといえば押しが強く、嫌でときどき滑稽な」彼ら
     の言語に対する翻訳を行うことが出来る程度には英語を扱うことが出来ま
     す。フランス語を話す人間として、私は韓国または台湾において商品の取
     扱説明書を貧弱なフランス語へと翻訳した経験があります。...

     我々はときどきある種の国家的計算機文化を作り上げる必要があるという
     のは事実です。そして、その作業は彼らの母国語によって繋がっている多
     くの人間の協調作業なしに簡単に出来ることではありません。翻訳は彼ら
     自身の言語を知りそして愛する人々によってより良く行われ、より良い結
     果を得るという点において一緒に作業されるものなのです。

   • GPL(またはLGPL)への依存

     何人かの人々は、彼らが彼らのプログラムをフリーにしたくない場合、又
     は別の種類の自由を与えたい場合に、GNU ‘gettext’を使うことによって彼
     らのパッケージをGNU一般公有許諾書(GNU General Public License)の保護
     の元で配布する必要があるのではないかと思案します。これに対する単純
     な答えは“通常はいいえ”です。

     GNU ‘gettext’の‘gettext-runtime’の部分(たとえば‘libintl’のコンテン
     ツ)は、GNU Lesser General Public Licenseにより保護されています。GNU
     ‘gettext’の‘gettext-tools’の部分(たとえば、GNU ‘gettext’パッケージ
     の残りの部分)は、GNU General Public Licenseにより保護されています。

     パッケージ中の僅かな地域化された文字列のマーキング、又は国際化のた
     めの条件つきの数行の包含はGPLまたはLGPLのコードを含んでいません。し
     かしながら、‘libintl’内の地域化ルーチンそれ自身はLGPLの元にあり、
     LGPLとして考慮される必要があります。これは、たとえ非フリーなプログ
     ラムでさえ、変更されていない‘libintl’の完全なソースコードを配布する
     権利を与えます。これはまた、非フリーなプログラムでさえ、共有ライブ
     ラリーとして‘libintl’を使用する権利を与えます。しかしこれは、フリー
     なソフトウェアーだけにたいして、静的ライブラリーとして‘libintl’を使
     用、または他のライブラリー内に‘libintl’を含める権利を与えます。

12.4 組織
=========

   *注意: *このセクションの文書は時代遅れになっているので、改訂する必要
があります。

   大きな尺度で見れば、真の解決方法は有志が参加できるようなある種の正し
く厳密な集合を組織化することでしょう。私は、最近このアイディアについて幾
つかの考察を行い、幾つかの微妙なポイントがあるであろうことを認識していま
す。私は、そのようなプロジェクトを開始するために、Richard Stallmanに連絡
することを考えましたが、まず最初に我々の間でアイディアを揺り落とすことが
良いだろうと感じました。おそらく、Linux Internationalは既にこの分野にお
ける幾らかの経験、または、有志の作業のオーケストラのようなものを持ってい
ます。あらゆる場合に、思考のための食物を!

   我々は早々に何らかの方法で何かをセットアップせねばならないと考えます
。同じ言語に対する作業のインターロックと重複を避けるという点で、それは多
くの言語のコントリビュータを助けるでしょう。そして、更にそれらの言語(大
部分の言語では技術的な英語の翻訳について独特な多くの問題点があります)に
ついての独特な問題を共に解決するように連絡が取れるようにします。スウェー
デンのコントリビュータはこれらの問題点を認め、そして私はフランス語におい
てのそれらの問題点に相当に気が付いています。

   確かにこれは技術的問題ではありません、しかし我々は、コントリビュータ
、及び管理者間の国家チーム層のインターフェースに関わらず、ロカールコント
リビュータの努力が最大限に有益になるように管理するべきです。

   翻訳プロジェクトは言語コーディネータを統合するためにある準備を必要と
します。一度この作業が始められたなら、発展中のプログラムのローカライズは
、確かにフリーソフトウェアコミュニティにおいて永久の、そして、連続的な動
きになるでしょう。GNU ‘gettext’が公式の現実になる前に、最小限の準備が完
了し、そしてテストされているべきです。電子メールアドレス
‘coordinator@translationproject.org’は、これらの話題に基づくボランティア
、及び、一般的な電子メールから申し出を受けるための準備でした。このアドレ
スは、翻訳プロジェクトのコーディネータに届きます。

12.4.1 中央による調整
---------------------

   そのことについて考えるよりも更に早く、GNUは誰かがそれらのグループを組
織化し調整する方法を準備する必要があると私もまた考えます。ある種のグルー
プのグループです。GNUは直ちに共同で働いているボランティアの小さなグルー
プにこのタスクを委託することが良いだろうと、私は考えています。 おそらく
、この国家委員会的なグループのリストは‘gnu.announce’において公表され得ま
す。

   コーディネータとしての私の役割は単に、Ulrichをフリーソフトウェアの地
域化に興味を持っているドイツ語を話すボランティアに紹介すること、そして国
家的グループの準備が出来るまでの国家的登録機関のメンテナンス中に、国家的
グループの最初の組織化を助けることです。実際、コーディネータは、ボランテ
ィアが国家チーム(言語または国(局地的言語)について1人のコーディネータを選
択するべきです)を作成するために相互と連絡を取りやすくせねばなりません。
これが正しく行われたならば、コーディネーションは不可抗力的作業を除いて便
利なものとなり、代理人に時間を任せることが出来るようになります。

12.4.2 国家チーム
-----------------

   私は、我々が個々の言語のための有志のコーディネータ/エディタを捜すこと
を提案します。これらの人々は彼ら自身の言語のために、様々なプログラムの翻
訳ファイルを探し出し、そして、語法に対する高度で一定の標準を保証すること
になるで しょう。

   今までの他の人々との間の私の現在の経験によれば、地域化を実現する人々
はこのプロセスに対して非常に熱心であり、彼らは自分自身が地域化するプログ
ラムよりも地域化のプロセスにほうに興味を持ち、それだけでなく多くのプログ
ラムを地域化したいと思うものです。この事実は、各言語のためのコーディネー
タ/エディタを持つことは良いアイディアであることを確信させます。

   我々は、問題となる言語において明瞭かつ簡潔な文章を書く際、適任となる
人物を選択する必要があります。これは難しい作業です — 我々は、自分自身で
それをチェックすることができません。従って、我々は数人の人間対してに互い
の記述を判断するように要請し、そして最適任者を選択する必要があります。

   私は私のプレリリースを20人から30人の人々に発表ましたが、そのプレリリ
ースが既に生み出した全ての議論をあなたは信じないでしょう。私は、真に、公
式に、世界中でこの作業が開始されるときに起こるであろうことを想像すると身
震いがします。例えば、相互に反論しあう二人のチェコスロヴァキアのユーザー
の間を仲裁するのは私なのでしょうか?

   私がこれらの公式化について判断することが出来ないように、あなたのドイ
ツ語が私のフランス語よりはるかに良いとは限らないと推測します。私が提案す
るものは、各言語に対してPOファイルをメンテナンスしその変更を判定する人々
のグループを置くということです。そのような人々のグループがどのように行動
するかについて、グループ間には文化的な相違点があると考えます。幾つかのグ
ループはは緩い方法を採用し、簡単にコンセンサスの一致に達し、グループ中の
誰もが保守者に関わることができます。一方は死ぬまで戦い、重い管理を国家の
標準にまで組織化し、厳密なチャネルを使用するでしょう。

   ドイツのチームは良い例を出しています。直ちに、彼らはおそらくお互いの
翻訳を訂正する半数の人々と言語上の論点について議論する半ダースの人々です
。私は全ての名前を知っているわけではありません。Ulrich Drepperはドイツの
チームのコーディネートを担当しています。彼は私のプレテストのリストの購読
を申し込みました。従って、私は彼に対して、連絡されるリリースの詳細につい
て警告する必要は特にありません。

   各言語を担当する翻訳チームを得るためには、それはよいアイディアだと思
います。 翻訳を更に良く首尾一貫した状態にするでしょう。

12.4.2.1 サブカルチャー
.......................

   フランス語を例に取ってみましょう。コンピュータの世界では、意味が異な
る語彙を持つ幾つかのサブカルチャーがあります。組織化された方法でこの問題
を提起することなしにあちこちでボランティアを選んでいると、プロジェクトに
はすぐに国際化されたプログラムのごちゃ混ぜ状態が発生します。そしてことに
よると、実際にこの問題を気にする人々の間で終りなき口論が始まるでしょう。

   国際化されたプログラムをフランス語へ地域化する過程において、ある種の
統一を保つことは難しい(そしてデリケートな)仕事です。フランス人のラテンな
人柄 (:-) を知っていても、もし我々がこのことを間違った方法で捉えれば、我
々はどことも知れぬ場所で終わってしまうか、多くのエネルギーを無駄にしてし
まうことでしょう。おそらく我々は、GNU ‘gettext’が公式に発表される前に真
剣にこの問題に取り組まなければならないでしょう。そして、それはすぐではな
いかと私は推測します!

12.4.2.2 組織化へのアイディア
.............................

   私は、公式リリース後に次の大きな変更があると考えています。どうか、私
が短いGPLメッセージのドイツ語翻訳を用いることに注目してください。我々は
、フリーソフトウェアコミュニティにおける真の地域化が消え去ってしまう前に
2、3の良い例を示す必要があります、ここでは、議論が必要ないくつかのポイン
トを示します。

   • 各グループは、一つのFTPサーバ(少なくとも一つのマスタサーバ)を持つべ
     きです。

   • サーバ上のファイルは、最新版(もちろん!)を反映すべきであり、そしてサ
     ーバは、対応するするアーカイブと共にRCSディレクトリ(私は今、これを
     持っていません)をもまた含んでいるべきです。

   • 同じくChangeLogファイル(これはRCSアーカイブより有益ですが、しかし
     Emacsによって後から自動的に生成することが出来ます)を含んでいるべき
     です。

   • “コアグループ”は、疑わしい変更について判定するべきです(現在、このグ
     ループは私だけで構成されていますが、私は時折他の人間に「これもまた
     仕事に見える」と尋ねます)。

12.4.3 メーリングリスト
-----------------------

   GNU ‘gettext’に関するあらゆる問合せについては、以下に送ってください。

     coordinator@translationproject.org

   ‘*-pretest’リストは、私にとって本当に有益です、アイディアはおそらく、
多くのGNU、及び、非GNUパッケージへと一般化されるでしょう。しかし、保守者
以外の、彼/彼女の方法!

   François、我々は、チーム、チームをサポートするメーリングリストそして
ログメンバを追跡するために、‘gnu.ai.mit.edu’に適当なメカニズムを持って い
ます。我々は、あなたが使うわずかな優先権を持っています。これがあなたにと
って問題ないならば、私はあなたに情報を与えることができます。

   事物は変化しています!  2、3年前、Daniel Feketeと私がGNU地域化のメーリ
ングリスト(FSFの中にあった)に尋ねたとき、我々は作業をどこででも組織化す
るように礼儀正しく勧められ、そして我々はそれを実行しました。私のプリテス
タと連絡を取るために、私は‘majordomo’で管理される少数のメーリングリスト
をiro.umontreal.caに作成しました。これらのリストは今までのところ非常に信
頼できました...

   私は、ドイツ語のチームがドイツにあるメーリングリストを組織化し、他の
国にも組織化をさせると思います。しかし組織化が行われる前に、FSFにおいて
各国のチームのためのメーリングリストを提供することは確かに有益でしょう。
そうです、私にどのようにメーリングリストを作成し扱えばよいかを説明して下
さい。

   我々は一時的なメーリングリストを、人々を組織化しやすいように国ごとに
一つずつ作らねばなりません。なぜ一時的か、なぜなら一度再構成されたなら、
各国のボ ランティアは彼らのリストへと戻ってきて、そして自分達が望むよう
に管理するだろうからです。このことについては、個々のチームは自分達の国の
中から 自分達のリストを動かすだろうと思います。全てのチームが購読するこ
との出来る、 中央のメーリングリストも作る必要があるでしょう。

12.5 情報の流れ
===============

   *注意: *このセクションの文書は時代遅れになっているので、改訂する必要
があります。

   パッケージが最終的にリリースされた後、このメッセージについての幾つか
の議論があることでしょう。今、人々が更に良い幾つかのメッセージを提案した
としたら、あなたはどうしますか?  Jim、私が提供する1ダース近い地域化され
たプログラムと同様、どうか直ちにそれらのメッセージに注目して下さい。私は
翻訳とそれらに関する調整の両方を受け取るのです。

   私が事前にテストするものを一つ置いたならば、Ulrichはその告知を受け取
り、そしてそれを最後に修正するドイツ語のチームに渡します。そして彼は_保
守者_として私に翻訳ファイルを引き渡します。私が保守していないフリーのパ
ッケー ジについては何も聞きません。私が思うに、全ての翻訳プロジェクトに
おいてこのスキームが作られるでしょう。セキュリティに関わる理由のために、
おそらく Ulrich(実際の国家的コーディネータ)は時折翻訳プロジェクト(Jim、
私、又はLenの新人)によって保持される中央のレジストリをアップデートすべき
です。

   私は小さなGNUパッケージは一週間に一つずつ、より大きなパッケージは数週
間か数ヵ月をかけるという責務を私自身に課し、12月か1月には私はにGNUの全パ
ッケー ジを国際化する準備を積極的に整えていました。しかし、それはそのよ
うには動きません。私は最初に、私が責任を持つ全てのことを行いました。私は
他の保守者の幾らかの伝道作業に対して何も持っていませんでした。しかし私も
また多くのエネルギーを失いました — 同じ議論を繰り返します。

   そして、最初に地域化されたパッケージがリリースされるとき、我々は、醜
悪な翻訳 :-) についての多くの反応を得るでことしょう。確かに、そして我々
は事前に、パッケージ保守者と国家チームの間の情報の流れを制御することに関
する良いアイディアを持つ必要があります。

   どうかどこかに各POファイルの迅速なヒストリを保存し始めて下さい。コメ
ントを認めることによってファイルフォーマットがいずれ変更されるであろうこ
とを私は知っています。各ファイルがログのようなもの、そしてコメントや不平
の申し立て、又はその他の貢献をしたいと思う人々へのリファレンスを持つほう
がよいでしょう。私は高速でフレキシブルなフォーマットに関する申し立てをし
ましたが、しかしそれはまだGNUの意思決定者によって受け入れられていません
。私がこれについてより多くの情報を得たなら、このことについてお話しするこ
とになるでしょう。

12.6 複数形の翻訳
=================

   あなたがPOファイルを翻訳しようとしていて、それには以下のようなエント
リーが含まれているとしましょう:

     #, c-format
     msgid "One file removed"
     msgid_plural "%d files removed"
     msgstr[0] ""
     msgstr[1] ""

これはどういう意味なのでしょうか? どうやって記入すればよいのでしょうか?

   このようなエントリーは、メッセージにplural formがあることを示していま
す。plural formとは、メッセージ中の数字の値が複数形として出力しなければ
ならない値の時に出力すべき文字列です。‘msgid_plural’行に記述されているの
は、Englishにおけるそのようなメッセージの一般的な形式です。‘msgid’行には
、Englishにおけるsingular formで、数字の値が1のときに出力するテキストが
記述されています。plural formについての詳細は、see Plural formsで説
明しています。

   最初に見る必要があるのは、POファイルのヘッダーエントリーの
‘Plural-Forms’という行です。この行にはplural formを判定するための数字と
式が記述されています。まだPOファイルにそのような行がない場合は、追加する
必要があります。これは、あなたが翻訳しようとしている言語に依存します。こ
の情報は‘msginit’コマンド(see Creatingを参照してください) – これには
既知のplural formulaのデータベースが含まれています – を使うか、翻訳チー
ムの他のメンバーに尋ねてみてください。

   以下のような行について考えてみましょう:

     "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
     "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"

   これは論理的には1行になります。POファイルの書式では、各行を80文字まで
におさまるように長い行を分割できることを思い出してください。

   ‘nplurals’の値は、3つのplural formがあることを示しています。最初に行
わなければならないのは、各形式ごとに‘msgstr’を含むエントリーを作ることで
す:

     #, c-format
     msgid "One file removed"
     msgid_plural "%d files removed"
     msgstr[0] ""
     msgstr[1] ""
     msgstr[2] ""

   それから‘msgid_plural’を翻訳して、各‘msgstr’行にそれを記述します:

     #, c-format
     msgid "One file removed"
     msgid_plural "%d files removed"
     msgstr[0] "%d slika uklonjenih"
     msgstr[1] "%d slika uklonjenih"
     msgstr[2] "%d slika uklonjenih"

   ではplural formに適合するように翻訳を改善しましょう。上述の式にしたが
って、‘msgstr[0]’には1で終わるが11では終わらない数字のときの翻訳を、
‘msgstr[1]’には2、3、4で終わるが12、13、14では終わらない数字のときの翻訳
、そして‘msgstr[2]’にはそれ以外のときに使用する翻訳を記述します。これに
したがって改善したものが以下の翻訳です:

     #, c-format
     msgid "One file removed"
     msgid_plural "%d files removed"
     msgstr[0] "%d slika je uklonjena"
     msgstr[1] "%d datoteke uklonjenih"
     msgstr[2] "%d slika uklonjenih"

   Englishのsingular form(‘msgid’)では、数字用の書式指定が省かれて、数字
の1をあらわす“one”という単語に置き換えられていることに気づくでしょう。あ
なたが翻訳するときも同じようできるでしょうか?

     msgstr[0] "jednom datotekom je uklonjen"

これは‘msgstr[0]’を1のときだけ使うのか、他の数字のときも使うかによります
。plural formulaに当てはめて考えると、‘msgstr[0]’が‘n == 1’のときだけ、
数字用の書式指定子を使わない特定の翻訳文を使うことができます。しかしこの
例の場合、‘msgstr[0]’は21、31、41...などのときにも使用するので、書式指定
子を省くことはできません。

12.7 メッセージの優先度: 最初に翻訳すべきメッセージを決める方法
===============================================================

   翻訳者が週のうちパッケージに避ける時間が限られているにもかかわらず、
パッケージにはとても多くのメッセージ(1000超)があるとしましょう。そのよう
なときは彼女は一番ユーザーの目に触れるメッセージ、または一番頻繁に発生す
るメッセージを訳したいと望むでしょう。このセクションでは、このような"も
っとも緊急"なメッセージをどのように決定するか説明します。これは、すでに
部分的に翻訳されたメッセージカタログの中から、"次に緊急"なメッセージを決
定するのにも適用できます。

   最初のステップとして、彼女は、ユーザーがプログラムを使うのと同様にし
てプログラムを使ってみます。彼女がこれを行っているとき、プログラムがまだ
翻訳されていないメッセージの翻訳にたいする要求があると、GNU ‘gettext’ラ
イブラリーはそれをログファイルに記録します。

   次のステップで、彼女はPOモードを使って、それらのメッセージを翻訳する
のです。

   より詳細に見てみましょう。GNU ‘libintl’(GNU ‘libc’の対応する関数とは
異なる)は、環境変数‘GETTEXT_LOG_UNTRANSLATED’をサポートします。GNU
‘libintl’ライブラリーは‘gettext()’、および関連する関数が翻訳を見つけられ
なかったとき、そのメッセージをログに記録します。ログファイルがない場合に
は、必要に応じて作成します。GNU ‘libc’によるシステムでは、ELFの
‘LD_PRELOAD’メカニズムで使用できる、共有ライブラリー
‘preloadable_libintl.so’が提供されます。

   GNU ‘libc’のシステムでは、翻訳者は最初のステップとして以下のコマンド
を実行します:

     $ LD_PRELOAD=/usr/local/lib/preloadable_libintl.so
     $ export LD_PRELOAD
     $ GETTEXT_LOG_UNTRANSLATED=$HOME/gettextlogused
     $ export GETTEXT_LOG_UNTRANSLATED

他のシステムでは以下のコマンドを使います:

     $ GETTEXT_LOG_UNTRANSLATED=$HOME/gettextlogused
     $ export GETTEXT_LOG_UNTRANSLATED

   それから彼女はプログラムを使ってみます(あなたが翻訳を提供するプログラ
ムを使うのはよいことですし、お勧めの練習方法です。これは必要なコンテキス
トを与えてくれます)。これが終わったら、彼女は環境変数を削除します:

     $ unset LD_PRELOAD
     $ unset GETTEXT_LOG_UNTRANSLATED

   次のステップは、重複を取り除くことです:

     $ msguniq $HOME/gettextlogused > missing.po

   この結果はPOファイルですが、POファイルエディターで処理するためには、
少し前処理が必要です。最初に、このファイルは多くの翻訳ドメインのメッセー
ジを含んだマルチドメインのPOファイルです。次に、翻訳者のコメントとソース
ファイルへの参照が含まれていません。以下は、影響を受ける翻訳ドメインの一
覧を得る方法です:

     $ sed -n -e 's,^domain "\(.*\)"$,\1,p' < missing.po | sort | uniq

   それから翻訳者はドメインを1つずつ処理していきます。単純にするために、
language、domain、source package を環境変数に設定しましょう。

     $ lang=nl             # your language
     $ domain=coreutils    # the name of the domain to be handled
     $ package=/usr/src/gnu/coreutils-4.5.4   # the package where it comes from

   彼女は、‘$lang.po’の最新コピーを、翻訳プロジェクト、またはそのパッケ
ージ(大抵は‘$package/po/$lang.po’)から入手します。もし彼女が、そのパッケ
ージの最初の翻訳者の場合は、新規作成することになります(see Creatingを
参照してください)。それから彼女は、以下のコマンドを使って、緊急ではない
メッセージにたいして "obsolete" のマークを付与します（それらの翻訳済み、
および未翻訳のメッセージが本当に "obsolete" としてしまう訳ではありません
。これは以下の編集で、POファイルエディターに、それらのメッセージを無視さ
せるためです）。

     $ msggrep --domain=$domain missing.po | grep -v '^domain' \
       > $domain-missing.po
     $ msgattrib --set-obsolete --ignore-file $domain-missing.po $domain.$lang.po \
       > $domain.$lang-urgent.po

   それから彼女はPOファイルエディターを使って‘$domain.$lang-urgent.po’を
翻訳します(see Editingを参照してください)。(FIXME: KBabelと
gtranslatorが期待通りobsolete messageを保持してくれるかどうかについては
、わたしにはわかりません) そして彼女は最後に、以下のコマンドで緊急ではな
いメッセージ(およびすでに翻訳済みのメッセージの初期の"翻訳")を復元します
:

     $ msgmerge --no-fuzzy-matching $domain.$lang-urgent.po $package/po/$domain.pot \
       > $domain.$lang.po

   ‘$domain.$lang.po’を投稿したら、彼女は次のドメインを処理できます。

13 メンテナーの視点
*******************

   パッケージのメンテナーには多くの責任があります。そのうちの1つは、たく
さんのプラットフォームでパッケージを簡単にインストールできるようにするこ
とで、わたしたちが前に説明したマジック(see Usersを参照してください
)を、インストーラーとエンドユーザーにたいして働くようにすることです。

   GNU ‘gettext’をディストリビューションに統合できるようにする方法はたく
さんありますが、このチャプターではそれらを総括的にカバーすることはしませ
ん。かわりにGNU標準、さらにはGnits標準にしたがった、多くのフリーソフトウ
ェアディストリビューションで利用可能なアプローチの詳細について議論します
。なぜならGNU ‘gettext’は、GNUプロジェクト全体のインターナショナリゼーシ
ョンを助けるのを目的としているので、多くの有用でフリーなパッケージが対象
となるからです。そのためこのチャプターでは、すでに‘configure.ac’があり、
GNU Autoconfを使うパッケージを対象とします。

   それにもかかわらずGNU ‘gettext’は、GNU標準やその類にしたがっていない
フリーパッケージにたいしても有用です。そのようなパッケージのメンテナーは
自分の想像力と独創力によりディストリビューションを組織化する必要がありま
すが、‘gettext’はすべての状況で動作するでしょう(そしてそのようなパッケー
ジはたくさん存在します)。

   ‘gettext’のメソッドは現在安定しているとはいえ、‘gettext’の各バージョ
ン間でちょっとした調整は必要になるでしょう。そのため、このチャプターの内
容は、新たなリリースによる変更にしたがって読み替える必要があります。

13.1 非フラットなディレクトリー階層
===================================

   フリーなソフトウェアパッケージの中には、‘tar’により配布され、解凍する
と単層のディレクトリーに展開されるものがあります。このようなパッケージを
“flat”なディストリビューションと呼びます。それとは別に、Texinfoマニュア
ルやman pageのためのサブディレクトリー‘doc/’、Cライブラリーを置き換えた
り保管する関数を保持する‘lib/’、パッケージのソースの入った‘src/’などの階
層をもつ、フリーなソフトウェアパッケージも存在します。このようなディスト
リビューションのことを、“non-flat”であると呼びます。

   flatなディストリビューションにたいして、わたしたちはあまり多くを語る
ことはできません。GNU ‘gettext’を新しいバージョンにすることにより、
flatなディレクトリー構造は難しさが増大するという欠点があります。たくさん
のPOファイルがある場合、この単層のディレクトリーの内容は汚くなってしまう
でしょう。またCソースに含まれる GNU ‘gettext’のlibintlのソース、シェルや
‘sed’のスクリプト、そして複雑なMakefileのルールは、flatな構造には適しま
せん。これらの理由により、non-flatを使う方法を推奨します。

   GNU ‘gettext’自身もnon-flatな構造をもち、わたしたちはこの方法に精通し
ていることも、わたしたちがこのチャプターでそれを説明しようとしている理由
なのかもしれません。これを機会に、パッケージの構造をnon-flatにするメンテ
ナーもいるかもしれません。

13.2 前提となる作業
===================

   パッケージにたいしてGNU ‘gettext’を使用するためには、準備が少し必要で
す。これらの作業は、要点の説明だけだと肝心な部分がわからなくなってしまう
ある種の一般性をもっているので、このチャプターを読んで後から見返せるよう
に、ここで大まかに説明しておきましょう。

   • ‘gettextize’を使う前に、最初に他のパッケージをインストールする必要
     があります。最新のバージョンのGNU ‘m4’、GNU Autoconf、GNU
     ‘gettext’がインストールされていることを確認してください。もしインス
     トールされていない場合、それらを最初にインストールします。GNU
     Autoconfをインストールする前に(たとえ_configured_済みだとしても)、
     GNU ‘m4’が完全にインストールされていなければならないことに注意して
     ください。

     パッケージ‘automake’は、メンテナーのタスクを楽にするためにデザイン
     ・実装されています。現在のGNU ‘gettext’もこれらのツールを使用してい
     るので、‘intl/’や‘po/’にある‘Makefile’は、1つのプロジェクトで
     ‘automake’と‘libintl’を使う場合に必要なものです。

     これら4つのパッケージはメンテナーにとって必要なだけです。パッケージ
     を正常にインストールして翻訳されたメッセージを正しく表示するだけな
     ら、インストールする人やパッケージのエンドユーザーには、GNU ‘m4’、
     GNU Autoconf、GNU ‘gettext’、GNU ‘automake’は必要ありません。しかし
     パッケージにインターナショナライズされたシェルを含めて配布する場合
     、これは完全に真実とはいえなくなります: ユーザーがシェルスクリプト
     の翻訳されたメッセージを見たいときは、GNU ‘gettext’のインストールが
     必要になります。

   • パッケージは‘configure.ac’か‘configure.in’をもち、Autoconfを使用す
     る必要があります。もしそうなっていない場合は、どのようにするか学ぶ
     必要があります。Autoconfのドキュメントはとてもよく書けているので、
     印刷して読んでみるのもよい考えでしょう。

   • このマニュアルで前述したようにCソースを変更する必要があります。詳細
     はSourcesを参照してください。

   • ‘po/’ディレクトリーには、翻訳チームから提出された‘LL.po’という名前
     のPOファイルが、すべて保存されている必要があります。パッケージがイ
     ンターナショナライズされて、それが利用可能になる前に翻訳作業を完了
     するのは、普通は簡単ではありません! メンテナーにとって翻訳作業のサ
     イクルを開始するのに簡単なのは、最初はPOファイルを何も用意せず、パ
     ッケージに興味をもつ翻訳チームが現れてPOファイルが投稿されるのを待
     つことです。

   POファイルが投稿されたとき、メンテナーとしてどのように振る舞うのが理
想的なのか、少し説明をしておきましょう。メンテナーとしてのあなたの役割は
、その投稿が翻訳プロジェクト内の対応する翻訳チーム(わからないときは
‘coordinator@translationproject.org’に転送してください)によるものである
ことを証明し、POファイルのフォーマットが壊れていてインストールできないく
なっていないか確認し、それらのPOファイルを配布物の‘po/’ディレクトリーに
配置することです。

   メンテナーとしては、翻訳が十分なのか、または完璧なのかをチェックする
責任を負う必要はないので、語学に関する事柄については無視するべきです。翻
訳チームは、チーム自身の運営と翻訳プロジェクトでの言語学的な選択について
完全な責任を負います。翻訳チームがメンテナーにより運営されるのでは_ない
_ことを覚えておいてください。ユーザーからの言語上の指摘や報告などを、適
切な翻訳チームに転送したり、ユーザーが翻訳チームに参加する方法を説明する
ような手助けをすることはできます。もっとも簡単なのは‘ABOUT-NLS’ファイル
を送ることでしょう。

   メンテナーが翻訳チームを介さずに、自分でPOファイルに関するバグ報告を
受けるのは_決して行うべきではない_ことです。ある問題について翻訳者が彼女
のチームと一致した見解をもつのが困難なとき、彼女が直接メンテナーと交渉す
るようなオプションが存在するべきではありません。どんな問題にせよ、彼らは
問題をチーム自身で解決するべきです。メンテナーとしては、もしチームに本当
に問題があると思えるときでも、あなた自身がチームの問題を解決しようとはし
ないでください。

13.3 ‘gettextize’プログラムの呼び出し
=====================================

   ‘gettextize’プログラムは、GNU ‘gettext’によりインターナショナライズさ
れたパッケージのメンテナーを助けるための対話的なツールで、2つの目的のた
めに使用されます:

   • 最初に、GNU ‘gettext’を使ってパッケージをするときは、ウィザードとし
     て使用されます。

   • パッケージ内でのGNU ‘gettext’サポートを、以前のGNU ‘gettext’から新
     しいバージョンにアップグレードするための、移行ツールとして使用しま
     す。

   このプログラムは以下のタスクを処理します:

   • GNU ‘gettext’によりインターナショナライズされた、すべてのパッケージ
     で必要なファイルをパッケージにコピーします。

   • 次のセクション Adjusting Filesで説明する多くのタスクを、で
     きるだけ自動的に処理します。

   • 以前のバージョンのGNU ‘gettext’で使われていた陳腐化したファイルやイ
     ディオムを削除して、現在のバージョンのGNU ‘gettext’で推奨される形式
     にします。

   • 手動で行うべきタスクや、 ‘gettextize’で自動的に処理できないタスクの
     要約をプリントします。

   呼び出し方は以下のようになります:

     gettextize [ OPTION... ] [ DIRECTORY ]

以下のオプションを指定できます:

‘-f’
‘--force’
     すでに存在するファイルを強制的に置き換えます。

‘--intl’
     libintlのソースを、‘intl/’というサブディレクトリーにインストールし
     ます。このlibintlは、GNU libintlがインストールされていないシステム
     でインターナショナリゼーションを提供するのに使用されます。このオプ
     ションが省略された場合は、‘configure.ac’の‘AM_GNU_GETTEXT’呼び出し
     が読み込まれます。しかし‘AM_GNU_GETTEXT([external])’とインターナシ
     ョナリゼーションは、GNU gettextのないシステムでは利用できないでしょ
     う。

‘--po-dir=DIR’
     POファイルを含むディレクトリを指定します。このようなディレクトリー
     には、特定のPOTファイルをさまざまな言語に翻訳したファイルが含まれて
     います。このオプションは、翻訳ドメインどとに複数回指定することがで
     きます。指定されなかったときは、‘po/’というディレクトリーが更新され
     ます。

‘--no-changelog’
     ChangeLogの作成・更新をしません。デフォルトでは‘gettextize’は、影響
     を受けるディレクトリーごとの‘ChangeLog’というファイルに、すべての変
     更(ファイルの追加・変更・削除)を記録します。

‘--symlink’
     必要なファイルをコピーするかわりに、シンボリックリンクを作成します
     。これはディスク容量を数キロバイト節約するのには便利ですが、自分自
     身を含む形式のtarballの作成には特別な配慮が必要になり、メンテナーが
     ソースに適用できるいくつかの機能が使えなくなり、システムに新しいバ
     ージョンの‘gettext’がインストールされたときにバグ(のような状態)を招
     きます。

‘-n’
‘--dry-run’
     変更を出力しますが、処理は行いません。普通に‘gettextize’を実行した
     ときのアクションはすべて抑止され、かわりにリストが標準出力に出力さ
     れるだけになります。

‘--help’
     このヘルプを表示して終了します。

‘--version’
     バージョン情報を表示して終了します。

   DIRECTORYを指定した場合、そのディレクトリーはGNU ‘gettext’を使う準備
をしたいパッケージの、トップレベルのディレクトリーになります。

   プログラム‘gettextize’は、以下のファイルを提供します。しかし‘--force’
(‘-f’)オプションを指定しなければ、既存のファイルは置き換えられません。

  1. ‘ABOUT-NLS’ファイルは、パッケージのメインディレクトリー(トップレベ
     ル)にコピーされます。このファイルは、プログラムでNative Language
     Support機能をインストールして使う方法を示す主要なファイルです。もし
     手軽に入手できるなら、‘gettextize’により提供される‘ABOUT-NLS’よりも
     、新しいコピーを使いたいと思うかもしれません。より新しい
     ‘ABOUT-NLS’ファイルのコピーを、翻訳プロジェクト、またはGNU archive
     siteから入手することもできます。

  2. 作成された‘po/’ディレクトリーには、最終的にはすべての翻訳用ファイル
     が保持されますが、初期状態ではGNU ‘gettext’による
     ‘po/Makefile.in.in’(ファイル名に‘.in’が2つあることに注意してくださ
     い)と、いくつかの予備ファイルしか含まれていません。すでに‘po/’とい
     うディレクトリーがあるときは、そのディレクトリーのファイルは保持さ
     れ、‘Makefile.in.in’と予備ファイルだけが上書きされます。

     ‘--po-dir’が指定されたときは、‘po/’のかわりに‘--po-dir’で指定された
     それぞれのディレクトリーに配置されます。

  3. ‘--intl’だけが指定されたときは、‘intl/’ディレクトリーが作成され、
     GNU ‘gettext’の‘intl/’ディレクトリーから、ほとんどのファイルがコピ
     ーされます。‘--force’ (‘-f’)も指定されたときは、まず最初に‘intl/’が
     空にされます。

  4. ファイル‘config.rpath’は、設定サポートファイルを含むディレクトリー
     にコピーされます。このファイルは、autoconfマクロ‘AM_GNU_GETTEXT’で
     必要です。

  5. プロジェクトがGNU ‘automake’しか使っていないときは、‘autoconf’の一
     連のマクロファイルが、パッケージの‘autoconf’マクロのレポジトリー(通
     常は‘m4/’というディレクトリー)にコピーされます。

   シンボリックリンクがサポートされている場合、‘gettextize’はパッケージ
のディレクトリーへは実際にコピーはされず、かわりにシンボリックリンクが作
成されます。これによりすべてのパッケージで必要なファイルによる重複を避け
ることができます。単に‘-h’オプションを指定すると、配布物の‘tar’アーカイ
ブを作成するときには、それらのリンクが解決されて実際のファイルが配布物の
アーカイブにコピーされます。そのため、メインの‘Makefile.in’のゴール
‘dist’にたいする‘tar’のオプションには、‘-h’を使う必要があることを強調し
ておきましょう

   それだけではなく、‘gettextize’は、影響を受ける各ディレクトリーの
‘Makefile.am’をすべて更新し、同様にトップレベルの‘configure.ac’(または
‘configure.in’)も更新します。

   パッケージのサブディレクトリー‘intl/’、‘po/’、‘m4/’にコピーされる、
GNU ‘gettext’をサポートするための最新のファイルを理解するのも、興味深い
でしょう。‘intl/’と他の2つのディレクトリーの違いは、‘intl/’はGNU
‘gettext’を使うすべてのパッケージで同じですが、他の2つのディレクトリーの
ものの大部分はパッケージに依存したものだという点です。

   ‘gettextize’プログラムは、置換または変更するファイルのバックアップを
作成して、それらの変更をChangeLogに書き込みます。この方法により、注意深
いメンテナーは‘gettextize’を実行した後に、それによる変更が許容できるか確
認して、可能なら調整することができます。このルールの例外は‘intl/’ディレ
クトリーで、このディレクトリーは完全に追加・置換、または削除されます。

   ‘gettextize’が、GNU ‘gettext’を使うパッケージのための調整すべてを処理
できる訳ではないことを理解するのことも重要です。残っている作業の量は、パ
ッケージがGNU ‘automake’を使うか否かによります。それでも大抵の場合、メン
テナーは‘gettextize’を呼び出した後、see Adjusting Filesを読む必要が
あるでしょう。

   特に‘gettexize’を使った後は、‘AC_COMPILE_IFELSE was called before
AC_GNU_SOURCE’、または‘AC_RUN_IFELSE was called before AC_GNU_SOURCE’と
いうエラーが発生するかもしれません。このエラーはconfigure.acで説
明している方法で‘configure.ac’を変更することにより修正できます。

   ‘gettextize’は、GNU build systemの一部ではないので、自動的には呼び出
されず、パッケージメンテナーとしての責任を持たない人も呼び出さないことを
理解しておくのも重要です。後者の目的のためには個別にツールが準備されてい
ます。詳細はautopoint Invocationを参照してください。

13.4 作成または変更しなければならないファイル
=============================================

   ‘gettextize’により自動的に追加されたファイルをのぞいて、GNU
‘gettext’と正常に対話するために修正が必要なファイルがたくさんあります。
あなたがMakefileの設計とauto-configuration自動設定のためのGNU標準に忠実
にしたがっているなら、調整は容易でしょう。ここではそれぞれについて必要な
変更を順に説明します。

   以下では変更が必要なファイルと、必要な変更を説明していきます。多くの
例はGNU ‘gettext’ 0.18.3 のディストリビューション自体か、GNU ‘hello’ディ
ストリビューション(<http://www.franken.de/users/gnu/ke/hello>または
<http://www.gnu.franken.de/ke/hello/>)から引用しました。GNU ‘gettext’の
ソースコードとGNU ‘hello’を参照してみれば、これらのパッケージがGNU
‘gettext’の機能を使うよい例だということが納得できるでしょう。

13.4.1 ‘po/’内の‘POTFILES.in’
-----------------------------

   ディレクトリー‘po/’には、‘POTFILES.in’というファイルが必要です。この
ファイルは、すべてのプログラムソースの中で、翻訳が必要だとマークされた文
字列をもつファイルがどれかを告げるもので、以下のような内容です:

     # List of source files containing translatable strings.
     # Copyright (C) 1995 Free Software Foundation, Inc.

     # Common library files
     lib/error.c
     lib/getopt.c
     lib/xmalloc.c

     # Package source files
     src/gettext.c
     src/msgfmt.c
     src/xgettext.c

#マークのコメントと空行は無視されます。それ以外の行は翻訳用にマークされ
た文字列を含むソースファイルをリストした行(see Mark Keywordsを参照し
てください)で、相対パスは‘POTFILES.in’のあるディレクトリーではなく、ディ
ストリビューション全体のトップレベルからの相対パスです。

   ‘flex’や‘bison’のような、それ自身では翻訳可能な文字列を提供しないよう
なツールによりCファイルが自動生成されるときは、‘po/POTFILES.in’には自動
生成されたCファイルではなく、本当のソースファイル(‘flex’のときは‘.l’で終
わるファイル、‘bison’のときは‘.y’というファイル)を記述することをお勧めし
ます。

13.4.2 ‘po/’内の‘LINGUAS’
-------------------------

   ディレクトリー‘po/’には、‘LINGUAS’というファイルも必要です。このファ
イルは利用可能な翻訳がリストされています。これは空白区切りのリストで、
#マークのコメントと空行は無視されます。以下は例です:

     # Set of available languages.
     de fr

この例はGermanとFrenchのPOファイルが利用可能で、パッケージでは現在それら
の言語がサポートされていることを意味しています。インストール時に、インス
トールされる言語にさらに制限をかけたいときは、ファイル‘LINGUAS’を変更す
るのではなく、環境変数‘LINGUAS’を使用します(see Installersを参照して
ください)。

   ‘LINGUAS’ファイルには、‘en@quot’と‘en@boldquot’という"言語"を追加する
ことをお勧めします。‘en@quot’はEnglishのメッセージカタログ(‘en’)の亜種で
、非対称な体裁の‘`’と‘'’によるASCIIの置き換えではなく、本当のクォーテー
ションマークを使います。‘en@boldquot’は‘en@quot’の亜種で、クォーテーショ
ン文字を太字のフォントで出力します。これはVT100のエスケープシーケンスを
サポートする端末エミュレーター(‘xterm’やLinuxのconsole。Emacsの‘M-x
shell’モードは該当しません)で使用されます。

   これらの追加のメッセージカタログ‘en@quot’および‘en@boldquot’は、翻訳
者が作成したのではなく、自動的に作成されたものです。これらのファイルをサ
ポートするためには‘po/’ディレクトリーに、‘Rules-quot’、‘quot.sed’、
‘boldquot.sed’、‘en@quot.header’、‘en@boldquot.header’、
‘insert-header.sin’というファイルが必要です。これらのファイルは、
‘gettextize’を実行することによりインストールされます。

13.4.3 ‘po/’内の‘Makevars’
--------------------------

   ディレクトリー‘po/’には、‘Makevars’というファイルもあります。このファ
イルには、プロジェクトで固有の変数が含まれています。‘po/Makevars’が作成
されるときに、‘po/Makefile’が挿入されます。そのため、変数はPOTファイルが
作成・更新されたときや、メッセージカタログがインストールされたときに効果
を及ぼします。

   あなたのパッケージが単一のメッセージドメイン(1つの‘po/’ディレクトリー
しかない)のときは、最初の3つの変数は変更する必要はありません。別々の場所
に複数の‘po/’ディレクトリーをもつパッケージの場合だけ、‘Makevars’の最初
に定義された3つの変数を調整する必要があります。

   ‘XGETTEXT_OPTIONS’変数のかわりに、autoconfマクロの
‘AM_XGETTEXT_OPTION’により、‘xgettext’のオプションを指定することもできま
す。詳細はAM_XGETTEXT_OPTIONを参照してください。

13.4.4 ‘po/’内の‘Makefile’の拡張
--------------------------------

   ‘po/’ディレクトリーの、‘Rules-*’と呼ばれるファイルは、‘po/Makefile’が
作成されたときに追加されたファイルです。これらのファイルは、
‘po/Makefile.in.in’に干渉することなく、特定のPOファイルのMakefileにルー
ルを追加する機会を与えてくれます。

   GNU gettextには、カタログ‘en@quot.po’および‘en@boldquot.po’をビルドす
るルールを含む、‘Rules-quot’ファイルが含まれます。‘en@quot.po’の効果は、
環境変数‘LANGUAGE’に‘en@quot’をセットすると、クォーテーションを示す代替
のASCII grave accentとASCII apostropheのかわりに、対称性をもつUnicodeの
正しいクォーテーションマークが表示されることです。このカタログを有効にす
るには、単に‘en@quot’を‘po/LINGUAS’に追加します。‘en@boldquot.po’の効果
は、‘LANGUAGE’に‘en@boldquot’をセットすると、正しいクォーテーションマー
クが得られるだけでなく、ターミナルやコンソールで表示されるクォーテーショ
ンマークの文字に、太字フォントが使用されることです。これはGUIプログラム
ではなく、コマンドラインのプログラムにとってだけ便利なカタログです。
‘po/LINGUAS’ファイルに‘en@boldquot’を追加するだけで、このカタログを利用
できます。

   同様にして、‘sr’ locale – Cyrillic文字で記述されたSerbian – から、
‘sr@latin’ locale – Latinアルファベットで記述されたSerbian – のためのメ
ッセージカタログを構築するルールを作成することができます。
msgfilter Invocationを参照してください。

13.4.5 トップレベルの‘configure.ac’
-----------------------------------

   ‘configure.ac’または‘configure.in’ – これは‘autoconf’が‘configure’ス
クリプトを生成するときのソースになるファイルです。

  1. パッケージとバージョンを宣言します。

     これは以下のように宣言します:

          PACKAGE=gettext
          VERSION=0.18.3
          AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE")
          AC_DEFINE_UNQUOTED(VERSION, "$VERSION")
          AC_SUBST(PACKAGE)
          AC_SUBST(VERSION)

     GNU ‘automake’を使っている場合は、以下のようになるでしょう:

          AM_INIT_AUTOMAKE(gettext, 0.18.3)

     もちろん、パッケージ名の‘gettext’と、バージョン番号の‘0.18.3’は、あ
     なたのパッケージの名前とバージョン番号で置き換えます。これらは配布
     物のパッケージされた‘tar’のファイル名(この例では
     ‘gettext-0.18.3.tar.gz’)にそのまま使用されます。

  2. インターナショナリゼーションにたいするサポートのチェック。

     以下のマクロは、インターナショナリゼーションにたいするサポートを発
     動するためにメインとなる、‘m4’のマクロです。この行を
     ‘configure.ac’に追加します:

          AM_GNU_GETTEXT

     マクロはconfigure時に多くのチェックと処理を行いますが、呼び出しは故
     意に単純にしています。

     ‘gettextize’を呼び出すとき、‘--intl’オプションを指定せず、‘intl/’を
     作成しない場合は、以下の呼び出しが読み込まれます:

          AM_GNU_GETTEXT([external])

  3. 出力ファイルの作成。

     AC_OUTPUT命令は‘configure.ac’ファイルの最後にあり、以下の2つの方法
     で変更する必要があります:

          AC_OUTPUT([EXISTING CONFIGURATION FILES intl/Makefile po/Makefile.in],
          [EXISTING ADDITIONAL ACTIONS])

     ‘AC_OUTPUT’の最初の引数の変更は、‘intl/’および‘po/’ディレクトリーを
     置き換えるための変更です。接尾辞‘.in’は、‘po/’だけに使用されること
     に注意してください。これにより配布される本当のファイルは
     ‘po/Makefile.in.in’であることがわかります。

     ‘gettextize’を呼び出すとき、‘--intl’オプションを指定せず、‘intl/’を
     作成しない場合は、‘AC_OUTPUT’の行に‘intl/Makefile’を追加する必要は
     ありません。

   必要な変更をした後は、‘aclocal -I m4’や‘autoconf’(または
‘autoreconf’)などのコマンドは、以下のようなトレース情報を出力して失敗す
るようになります:

     configure.ac:44: warning: AC_COMPILE_IFELSE was called before AC_GNU_SOURCE
     ../../lib/autoconf/specific.m4:335: AC_GNU_SOURCE is expanded from...
     m4/lock.m4:224: gl_LOCK is expanded from...
     m4/gettext.m4:571: gt_INTL_SUBDIR_CORE is expanded from...
     m4/gettext.m4:472: AM_INTL_SUBDIR is expanded from...
     m4/gettext.m4:347: AM_GNU_GETTEXT is expanded from...
     configure.ac:44: the top level
     configure.ac:44: warning: AC_RUN_IFELSE was called before AC_GNU_SOURCE

‘configure.ac’ファイルの‘AC_PROG_CC’より後、かつ‘AM_GNU_GETTEXT’より前の
箇所(おそらく‘AC_PROG_CC’呼び出しのすぐ近く)に、‘AC_GNU_SOURCE’の明示的
な呼び出しを追加する必要があります。この順番は、GNU autoconfによる制限に
より必要です。

13.4.6 トップレベルの‘config.guess’、‘config.sub’
-------------------------------------------------

   サブディレクトリー‘intl/’の作成を省略しない場合、配布物に
‘config.guess’および‘config.sub’という、GNUのファイルを追加する必要があ
ります。これらのファイルが必要なのは、‘intl/’ディレクトリーがlocaleの文
字エンコーディングを決定するという、プラットフォームに依存したサポートを
行うため、プラットフォームを識別しなければならないからです。

   最新バージョンの‘config.guess’および‘config.sub’を、
‘http://savannah.gnu.org/’の‘config’プロジェクトから入手できます。以下は
入手するためのコマンドです
     $ wget -O config.guess 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD'
     $ wget -O config.sub 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD'
バージョンは最新ではありませんが、GNU ‘automake’とGNU ‘libtool’パッケー
ジにも含まれています。

   ‘config.guess’および‘config.sub’は通常、配布物のトップレベルに配置さ
れます。しかし、他の設定ファイル(‘install-sh’、‘ltconfig’、‘ltmain.sh’、
‘missing’など)と同様に、サブディレクトリーに配置することもできます。ファ
イルを移動すること以外に必要なのは、‘configure.ac’に以下の行を追加するこ
とです。

     AC_CONFIG_AUX_DIR([SUBDIR])

13.4.7 トップレベルの‘mkinstalldirs’
------------------------------------

   初期のバージョンのGNU gettextでは、配布物にGNU ‘mkinstalldirs’スクリ
プトを追加する必要がありました。これは今では必要ありません。使用している
automakeが、automake 1.9以降であれば削除することができます。

13.4.8 トップレベルの‘aclocal.m4’
---------------------------------

   配布物に‘aclocal.m4’ファイルがない場合、1番単純なのは、GNU ‘gettext’の
サブディレクトリー‘m4/’の‘codeset.m4’、‘fcntl-o.m4’、‘gettext.m4’、
‘glibc2.m4’、‘glibc21.m4’、‘iconv.m4’、‘intdiv0.m4’、‘intl.m4’、
‘intldir.m4’、‘intlmacosx.m4’、‘intmax.m4’、‘inttypes_h.m4’、
‘inttypes-pri.m4’、‘lcmessage.m4’、‘lib-ld.m4’、‘lib-link.m4’、
‘lib-prefix.m4’、‘lock.m4’、‘longlong.m4’、‘nls.m4’、‘po.m4’、
‘printf-posix.m4’、‘progtest.m4’、‘size_max.m4’、‘stdint_h.m4’、
‘threadlib.m4’、‘uintmax_t.m4’、‘visibility.m4’、‘wchar_t.m4’、
‘wint_t.m4’、‘xsize.m4’を1つのファイルに結合する方法です。‘intl/’ディレ
クトリーを作成しなかった場合、結合する必要があるのは‘gettext.m4’、
‘iconv.m4’、‘lib-ld.m4’、‘lib-link.m4’、‘lib-prefix.m4’、‘nls.m4’、
‘po.m4’、‘progtest.m4’だけです。

   GNU ‘automake’ 1.8以降を使っていない場合は、もっと新しいautomakeの配
布物から、上記のファイルに‘mkdirp.m4’ファイルを追加する必要があります。

   すでに‘aclocal.m4’ファイルがある場合は、前述のマクロファイルを既存の
‘aclocal.m4’にマージする必要があります。以前にリリースされたGNU
‘gettext’からアップグレードしたようなときは、ほとんどの場合マクロ
(‘AM_GNU_GETTEXT’、...  )を_置き換える_必要があることに注意してください
。なぜならそれらのマクロは、GNU ‘gettext’がリリースされるときは通常、少
し変更されるからです。これらの内容は、わたしたちが "奇妙" なシステムに出
会う度に増えていくかもしれません。

   GNU ‘automake’ 1.5以降を使用している場合には、マクロファイルを‘m4/’と
いうサブディレクトリーに配置して、以下の行を追加すれば充分です。

     ACLOCAL_AMFLAGS = -I m4

上記のような行を、トップレベルの‘Makefile.am’に追加してください。

   GNU ‘automake’ 1.10以降を使用している場合は、さらに簡単になります。以
下の行を追加してください

     ACLOCAL_AMFLAGS = --install -I m4

上記のような行を、トップレベルの‘Makefile.am’に追加して、‘aclocal
--install -I m4’を実行します。これは‘aclocal.m4’を更新する前に、必要なフ
ァイルを自動的に‘m4/’サブディレクトリーに追加します。

   これらのマクロはインターナショナリゼーションのサポート機能と関連情報
をチェックします。1度うまく安定させられれば、多分これらのマクロを、標準
のAutoconfに統合できるでしょう。なぜなら、これらの断片的な‘m4’コードは、
GNU ‘gettext’を使うプロジェクトでは同一だからです。

13.4.9 トップレベルの‘acconfig.h’
---------------------------------

   初期のバージョンのGNU ‘gettext’では、‘acconfig.h’ファイル内で
‘ENABLE_NLS’、‘HAVE_GETTEXT’ and ‘HAVE_LC_MESSAGES’、‘HAVE_STPCPY’、
‘PACKAGE’ and ‘VERSION’を定義することが要求されました。これは今では必要
ないので、パッケージが‘intl/’ディレクトリーから独自に使用していなければ
、削除することができます。

13.4.10 トップレベルの‘config.h.in’
-----------------------------------

   ‘configure’により定義されるCマクロを保持するインクルードファイルのテ
ンプレートを、通常は‘config.h.in’と呼び、手動または自動で保守されるかも
しれません。

   ‘gettextize’が‘intl/’ディレクトリーを作成している場合、ファイル名は
‘config.h.in’で、トップレベルになければなりません。‘gettextize’の
‘--intl’オプションを指定しないで、‘intl/’ディレクトリーを作成しなかった
ときは、ファイル名と場所は自由に選ぶことができます。

   プログラム‘autoheader’を使って自動的に保守されている場合、なにも行う
必要はありません。これは特にGNU ‘automake’を使っているケースです。

   手動で保守していて‘gettextize’が‘intl/’ディレクトリーを作成している場
合は、‘autoheader’を使うように変更するべきです。‘intl/’ディレクトリーの
ために追加するCマクロのリストは、手動で保守するには長すぎます。そして、
このリストはGNU ‘gettext’のバージョンが異なることにより変化するのです。

   手動で保守している場合で、‘gettextize’を‘--intl’オプションなしで呼び
出したために、‘intl/’ディレクトリーが作成されていないなら、
‘config.h.in’に以下の行を追加して"逃げる"ことができます:

     /* Define to 1 if translation of program messages to the user's
        native language is requested. */
     #undef ENABLE_NLS

13.4.11 トップレベルの‘Makefile.in’
-----------------------------------

   以下は、トップレベルにあるメインの‘Makefile.in’ファイルにたいして必要
な変更です。

  1. ゴール‘dist:’が正常に動作(以降で説明します)するように、
     ‘Makefile.in’の最初の部分に、以下の行を追加します:

          PACKAGE = @PACKAGE@
          VERSION = @VERSION@

  2. 定義‘DISTFILES’に、ファイル‘ABOUT-NLS’を追加して、このファイルが配
     布されるように変更します。

  3. どのサブディレクトリーの‘Makefile.in’を処理する場合でも、サブディレ
     クトリー‘intl’および‘po’も処理するようにしてください。‘Makefiles’内
     の特別なルールは、インターナショナリゼーションが必要ない場合を処理
     するためのものです。

     Makefilesを使用している場合、それがautomakeにより作成されたものか、
     手入力されたものかにかかわらず、GNUのコーディング規約にしたがうよう
     に注意してください。新しいサブディレクトリーを処理しなければならな
     いために影響を受けるゴールには、‘installdirs’、‘install’、
     ‘uninstall’、‘clean’、‘distclean’が含まれます。

     以下は標準的な処理順の例です。この例ではゴール‘dist:’のために使用さ
     れる‘SUBDIRS’を、‘Makefile.in’の中で定義しています。

          SUBDIRS = doc intl lib src po

     ‘make’の調整では、ヘッダーファイル‘libintl.h’を使うコードが含まれる
     ディレクトリーより、‘intl’ディレクトリーが前にくるように注意してく
     ださい。intl の前に ‘lib’と‘src’の前に‘intl’があるのは、これが理由
     です。

  4. デリケートなポイントは、‘intl/Makefile’と‘po/Makefile’の両方のゴー
     ル‘dist:’が、メインの‘Makefile’によって、後から正しいディレクトリー
     にセットアップされる点です。以下はゴール‘dist:’がどのようなものかと
     いう例です:

          distdir = $(PACKAGE)-$(VERSION)
          dist: Makefile
          	rm -fr $(distdir)
          	mkdir $(distdir)
          	chmod 777 $(distdir)
          	for file in $(DISTFILES); do \
          	  ln $$file $(distdir) 2>/dev/null || cp -p $$file $(distdir); \
          	done
          	for subdir in $(SUBDIRS); do \
          	  mkdir $(distdir)/$$subdir || exit 1; \
          	  chmod 777 $(distdir)/$$subdir; \
          	  (cd $$subdir && $(MAKE) $@) || exit 1; \
          	done
          	tar chozf $(distdir).tar.gz $(distdir)
          	rm -fr $(distdir)

   GNU ‘automake’を使っているときは、‘Makefile.am’から‘Makefile.in’が自
動的に生成されますが、‘Makefile.am’に必要な修正は、‘gettextize’の実行よ
って修正済みであることに注意してください。

13.4.12 ‘src/’内の‘Makefile.in’
-------------------------------

   メインの‘Makefile.in’で行ったいくつかの修正は、あなたのパッケージソー
スの‘Makefile.in’(ここでは‘src/’サブディレクトリーにあると仮定します)で
も必要です。以下は、‘src/Makefile.in’内で必要な修正のすべてです:

  1. ゴール‘dist:’を考慮して、‘src/Makefile.in’の先頭の部分に以下の行が
     必要になります:

          PACKAGE = @PACKAGE@
          VERSION = @VERSION@

  2. まだ定義されていなければ、‘top_srcdir’を定義する必要があります。こ
     れは‘cpp’のインクルードファイルのための定義で、以下の行を追加するだ
     けです:

          top_srcdir = @top_srcdir@

  3. 後ですべての‘Makefile.in’で、一様なのゴール‘dist:’とするために、
     ‘subdir’を‘src’と定義したいと思うかもしれません。以下は、このゴール
     ‘dist:’のために必要な定義です:

          subdir = src

  4. 以下のようにプログラムの‘main’関数は通常、‘bindtextdomain’(see
     Triggeringを参照してください)を呼び出します:

          bindtextdomain (PACKAGE, LOCALEDIR);
          textdomain (PACKAGE);

     プログラムにLOCALEDIRを知らせるために、以下の行を‘Makefile.in’に追
     加します(Autoconfのバージョン2.60以降の場合):

          datadir = @datadir@
          datarootdir= @datarootdir@
          localedir = @localedir@
          DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@

     Autoconfのバージョンが2.60より古い場合は、以下の行を追加します:

          datadir = @datadir@
          localedir = $(datadir)/locale
          DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@

     ‘@datadir@’のデフォルトは‘$(prefix)/share’なので、‘$(localedir)’の
     デフォルトは、‘$(prefix)/share/locale’になることに注意してください
     。

  5. あなたは最後のリンクで、ライブラリーとして‘@LIBINTL@’または
     ‘@LTLIBINTL@’が使われることを保証する必要があります。‘@LIBINTL@’は
     ‘libtool’なしで使用され、‘@LTLIBINTL@’は‘libtool’とともに使用されま
     す。これを達成するには、以下のようにこれらを‘LIBS’で管理します:

          LIBS = @LIBINTL@ @LIBS@

     GNU ‘gettext’でインターナショナライズされたパッケージには、ヘルパー
     関数を含むライブラリーを、ディレクトリー‘lib/’にビルドするものがた
     くさんあります(少なくともGNU ‘gettext’ライブラリー自身が必要とする
     いくつかの関数が必要です)。しかし‘lib/’の中の関数のいくつかは、ユー
     ザーに翻訳が必要なメッセージをあたえる関数です。これに注意してサポ
     ートのためのライブラリー (‘libsupport.a’としましょう)を、上記の例の
     ‘@LIBINTL@’と‘@LIBS@’の前に配置します:

          LIBS = ../lib/libsupport.a @LIBINTL@ @LIBS@

  6. あなたは、あらゆる状況において、ディレクトリー‘intl/’が、Cプリプロ
     セッサーに検索されることも保証する必要があります。そのためには、
     ‘-I../intl’と‘-I$(top_srcdir)/intl’の両方がCコンパイラーに与えられ
     るように管理する必要があります。

  7. ゴール‘dist:’は、他のものと一致している必要があります。以下はそのた
     めの合理的な定義です:

          distdir = ../$(PACKAGE)-$(VERSION)/$(subdir)
          dist: Makefile $(DISTFILES)
          	for file in $(DISTFILES); do \
          	  ln $$file $(distdir) 2>/dev/null || cp -p $$file $(distdir) || exit 1; \
          	done

   GNU ‘automake’を使用している場合、‘Makefile.in’は‘Makefile.am’から自
動的に生成されるので、最初の3つと最後の変更は必要ないことに注意してくだ
さい。‘Makefile.am’に必要な変更は以下になります:

  1. プログラムにLOCALEDIRを知らせるために、特定のモジュールにたいしては
     以下の行を:

          <module>_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\"

     またはコンパイル単位については以下のように‘Makefile.am’に記述します
     。

          AM_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\"

     これはすべてのモジュール、またはコンパイル単位のためのものです。さ
     らにAutoconfのバージョンが2.60より古いものを使用している場合、以下
     の行を追加して‘localedir’を定義します:

          localedir = $(datadir)/locale

  2. 最後のリンクが‘@LIBINTL@’または‘@LTLIBINTL@’を使うことを保証するた
     めに、以下を‘Makefile.am’に追加します:

          <program>_LDADD = @LIBINTL@

     特定のプログラムごとには上記のように記述します。

          LDADD = @LIBINTL@

     これはすべてのプログラムの場合です。プログラムのリンクに‘libtool’を
     使うときは、プログラム用に@LIBINTL@ではなく、@LTLIBINTL@を使う必要
     があることを忘れないでください。

  3. ‘intl/’ディレクトリーがあり、その内容が‘gettextize’により作成された
     ものである場合は、以下のような行を‘Makefile.am’に追加して、すべての
     状況において、Cプリプロセッサーがインクルード ファイルをそこから検
     索することを保証するようにしてください:

          AM_CPPFLAGS = -I../intl -I$(top_srcdir)/intl

13.4.13 ‘lib/’内の‘gettext.h’
-----------------------------

   GNU ‘gettext’により提供される、パッケージのインターナショナリゼーショ
ンはオプションであり、2つの状況でオフに切り替えることが考えられます:

   • インストーラーで、‘./configure --disable-nls’が指定されたとき。ブー
     トディスク用のユーティリティーをビルドするときのように、これは機能
     よりも小さいバイナリーを生成する方が重要な場合に有用かもしれません
     。これは、3.0より古いバージョンのGCCで、コード品質にたいするCコンパ
     イラーの特定の警告を取得するためにも有用でしょう。

   • パッケージにサブディレクトリー‘intl/’が含まれておらず、libintl.hヘ
     ッダー(および、それに関連付けられたlibintlライブラリー)がまだシステ
     ムにインストールされていない場合は、コンパイルエラーよりもインター
     ナショナリゼーションのサポートなしでパッケージをビルドする方が望ま
     しいでしょう。

   Cプリプロセッサーのマクロは、これら2つのケースを検知するのに使用でき
ます。通常、‘libintl.h’が見つかって、明示的に利用不可されていなければ、
autoconfが設定ファイルを生成するときに、‘ENABLE_NLS’マクロが1に定義され
ます。しかし上記以外の状況では、このマクロは定義されず、それゆえCでは0に
評価されます。

   ‘gettext.h’は、‘ENABLE_NLS’マクロにもとづいて‘<libintl.h>’を使用する
、便利なヘッダーファイルです。‘ENABLE_NLS’がセットされていると、
‘<libintl.h>’がインクルードされ、セットされていない場合はlibintl.h関数の
ために代用のno-op(訳注: no-op = no operation = 何もしない)が定義されます
。わたしたちは直接‘<libintl.h>’を使うのではなく、‘"gettext.h"’を使うこと
を推奨します。そうすれば古いシステムへの可搬性が保証され、もし望むならイ
ンストーラーでインターナショナリゼーションをオフにできます。

     #include "gettext.h"

Cのソースコードは下記の行を、上記のように書き換えます(訳注: 下が修正前で
、上が修正後です。通常とは逆の順序で説明しているので間違えないでください
)。

     #include <libintl.h>

   ‘gettext.h’の場所は通常、補助のインクルードファイルを含んだディレクト
リーです。多くのGNUパッケージには、ヘルパー関数を含む‘lib/’ディレクトリ
ーがあるので、‘gettext.h’はそこに配置すればよいでしょう。他のパッケージ
では、‘src’ディレクトリーに配置することができます。

   ‘gettext.h’をパブリックな場所にインストールしないでください。このファ
イルを必要とするすべてのパッケージは、パッケージ自身にそのファイルのコピ
ーが含まれているからです。

13.5 ‘configure.ac’内でのautoconfマクロの使用
=============================================

   GNU ‘gettext’は、パッケージの‘configure.ac’(または‘configure.in’)で使
用されるマクロをインストールします。詳細については、see Introduction (autoconf).
を参照してください。その中でも主要なマクロは、もちろん
‘AM_GNU_GETTEXT’です。

13.5.1 ‘gettext.m4’内のAM_GNU_GETTEXT
-------------------------------------

   ‘AM_GNU_GETTEXT’マクロは、Cライブラリーおよび‘libintl’ライブラリー(ど
ちらも共有または静的なライブラリーをサポートしています)に分割されたGNU
gettextの関数ファミリー、またはパッケージの‘intl/’ディレクトリーをテスト
します。このマクロは、ビルド用にパッケージの‘po/’ディレクトリーを準備す
るのに、‘AM_PO_SUBDIRS’も呼び出します。

   ‘AM_GNU_GETTEXT’は、オプションの引数を3つ指定でき、一般的な書式は以下
のようになります

     AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR])

   INTLSYMBOLには、‘external’または‘no-libtool’が指定できます。デフォル
ト(指定されなかったとき、または空のとき)は、‘no-libtool’です。‘intl/’デ
ィレクトリーのないパッケージでは、intlsymbol に ‘external’ を指定する必
要があります。intl/ ディレクトリーのあるパッケージでは、INTLSYMBOLに
‘no-libtool’を指定することもできるし、‘external’を指定して、他の場所でマ
クロ‘AM_GNU_GETTEXT_INTL_SUBDIR’を使用することにより、それをオーバーライ
ドすることもできます。この‘intl/’の実体を指定する2つの方法は、同じことを
行います。どちらもビルド時には、静的なライブラリー
‘$(top_builddir)/intl/libintl.a’を作成します。

   NEEDSYMBOLに‘need-ngettext’が指定されると、‘ngettext()’をもたない
(libcまたはlibintlの)GNU gettext実装は無視されます。NEEDSYMBOLに
‘need-formatstring-macros’が指定されると、ISO C 99 ‘<inttypes.h>’書式文
字列マクロをサポートしないGNU gettext実装は無視されます。NEEDSYMBOLだけ
を指定することもできます。他の場所で‘AM_GNU_GETTEXT_NEED’を指定すること
でも、これらの指定を満たすことはできます。1つ以上指定したときは、もっと
も強い指定が使用されるか、‘AM_GNU_GETTEXT_NEED’マクロを複数回呼び出しま
す。これらの指定は、‘need-formatstring-macros’が‘need-ngettext’を含むよ
うな階層になっています。

   INTLDIRは、intlを探すのに使用されます。空の場合は、
‘$(top_builddir)/intl/’という値が使用されます。

   ‘AM_GNU_GETTEXT’マクロは、GNU gettextが利用可能で、使用できるかどうか
を決定するマクロです。利用できる場合は、変数‘USE_NLS’に‘yes’をセットし、
これはautoconfが生成する設定ファイル(通常は‘config.h’というファイル)の
‘ENABLE_NLS’に1を定義し、Makefileで使用される変数‘LIBINTL’と
‘LTLIBINTL’にリンカーオプションをセットし(‘LIBINTL’はlibtoolなしのときで
、‘LTLIBINTL’はlibtoolを使用するとき)、必要なときは‘CPPFLAGS’のオプショ
ンに‘-I’を追加し、利用できない場合は‘USE_NLS’に‘no’をセットし、
‘LIBINTL’と‘LTLIBINTL’を空にセットして、‘CPPFLAGS’を変更しません。

   ‘AM_GNU_GETTEXT’が対処する複雑さは、以下のようなものです:

   • いくつかのオペレーティングシステムは、Cライブラリー(例: glibc)に
     ‘gettext’をもちます。GNU ‘libintl’は、GNU ‘gettext’の一部としてイン
     ストールされたのかもしれません。

   • GNU ‘libintl’がインストールされていて、検索パス(インクルードファイ
     ルの検索パスは‘CPPFLAGS’、ライブラリーの検索パスは‘LDFLAGS’)にある
     が、必要ない場合。

   • glibcをのぞく、GNUのmoファイルを取り扱えないオペレーティングシステ
     ムのネイティブの‘gettext’は、必要なlocale依存の機能をもたず、カタロ
     グのテキストのエンコーディングから、ユーザーのlocaleのエンコーディ
     ングにメッセージを変換できません。

   • GNU ‘libintl’がインストールされていて、実行時ライブラリーの検索パス
     にあるが、必要ない場合。‘LD_LIBRARY_PATH’のような環境変数による設定
     を無視するために、このマクロは適切な実行時の検索パスオプションを、
     変数‘LIBINTL’および‘LTLIBINTL’に追加します。これはほとんどシステム
     で動作しますが、SCOのように共有ライブラリーに制限のあるいくつかのオ
     ペレーティングシステムではうまく動作しません。

   • GNU ‘libintl’は、POSIX/XSIの‘iconv’に依存します。このマクロは
     iconvを使うために必要なリンカーオプションをチェックして、変数
     ‘LIBINTL’および‘LTLIBINTL’に追加します。

13.5.2 ‘gettext.m4’内のAM_GNU_GETTEXT_VERSION
---------------------------------------------

   ‘AM_GNU_GETTEXT_VERSION’マクロは、パッケージで使用するGNU gettextイン
フラストラクチャーのバージョン番号を宣言します。

   このマクロの使用はオプションで、これを使用するプログラムは
‘autopoint’だけです(see CVS Issuesを参照してください)。

13.5.3 ‘gettext.m4’内のAM_GNU_GETTEXT_NEED
------------------------------------------

   ‘AM_GNU_GETTEXT_NEED’マクロは、GNU gettextの実装に関する制約を宣言す
るもので、構文は以下のようになります

     AM_GNU_GETTEXT_NEED([NEEDSYMBOL])

   NEEDSYMBOLに‘need-ngettext’を指定した場合、‘ngettext()’関数をもたない
、(libcまたはlibintlの)GNU gettext実装は無視されます。NEEDSYMBOLに
‘need-formatstring-macros’を指定した場合、ISO C 99 ‘<inttypes.h>’の書式
文字列マクロをサポートしないGNU gettext実装は無視されます。

   ‘AM_GNU_GETTEXT’の2番目のオプション引数も考慮されます。

   ‘AM_GNU_GETTEXT_NEED’呼び出しは、‘AM_GNU_GETTEXT’呼び出しの前後どちら
でもよく、順番は関係ありません。

13.5.4 ‘intldir.m4’内のAM_GNU_GETTEXT_INTL_SUBDIR
-------------------------------------------------

   ‘AM_GNU_GETTEXT_INTL_SUBDIR’マクロは、‘AM_GNU_GETTEXT’の最初の引数に
‘external’を指定して呼び出した場合でも、ビルドのために‘intl/’サブディレ
クトリーも参照します。

   ‘AM_GNU_GETTEXT_INTL_SUBDIR’呼び出しは、‘AM_GNU_GETTEXT’呼び出しの前
後どちらでもよく、順番は関係ありません。

   このマクロはGNU automake 1.10以降、またはGNU autoconf 2.61以降で使用
できます。

13.5.5 ‘po.m4’内のAM_PO_SUBDIRS
-------------------------------

   このマクロはC、C++、Objective C以外のプログラム言語(例: ‘sh’、
‘Python’、‘Lisp’)による、インターナショナライズされたプログラムで使う必
要があります。PO ファイルによるローカリゼーションをサポートするプログラ
ム言語のリストは、see Programming Languagesを参照してください。

   ‘AM_PO_SUBDIRS’マクロは、インターナショナリゼーションを使う必要がある
かを決定します。使う必要がある場合には‘USE_NLS’変数に‘yes’をセットし、必
要ない場合には‘no’をセットします。このマクロは、各‘po/’ディレクトリーの
Makefileの変数にたいする適切な値も決定します。

13.5.6 ‘po.m4’内のAM_XGETTEXT_OPTION
------------------------------------

   ‘AM_XGETTEXT_OPTION’マクロは、パッケージの‘po/’ディレクトリーでの
‘xgettext’呼び出しで使用する、コマンドラインオプションを登録するマクロで
す。

   たとえば、‘error_at_line’という関数を定義しているソースファイルがあり
、その関数の5番目の引数には、書式文字列を指定する場合には、以下のように
使うことができます
     AM_XGETTEXT_OPTION([--flag=error_at_line:5:c-format])
これは、この関数の5番目の引数にたいする‘gettext’呼び出しにたいして、これ
を翻訳可能な‘c-format’の文字列だとマークするよう、‘xgettext’に指示します
。

   ‘xgettext’に指定できるオプションのリストは、see xgettext Invocation
を参照してください。

   このマクロの使用は、‘po/Makevars’の中の‘XGETTEXT_OPTIONS’変数の代用と
なります。

13.5.7 ‘iconv.m4’内のAM_ICONV
-----------------------------

   ‘AM_ICONV’マクロは、Cライブラリー(または‘iconv’ライブラリーに分離され
た)POSIX/XSI ‘iconv’関数が提供されているかテストするマクロです。もし見つ
かったときは‘am_cv_func_iconv’変数に‘yes’をセットし、autoconfが生成する
設定ファイル(通常は‘config.h’というファイル)の‘HAVE_ICONV’に1を定義し、
‘iconv()’の2番目の引数の型が‘const char **’または‘char **’で定義さされて
いるかにより、‘ICONV_CONST’に‘const’または空を定義し、Makefileの中で使用
されるリンカーオプションの変数‘LIBICONV’および‘LTLIBICONV’をセット
(‘LIBICONV’はlibtoolなしのとき、‘LTLIBICONV’はlibtoolありのとき)、必要な
ら‘CPPFLAGS’のオプションに‘-I’を追加します。見つからなかったときは、
‘LIBICONV’および‘LTLIBICONV’に空をセットして、‘CPPFLAGS’を変更しません。

   ‘AM_ICONV’が対処する複雑さは、以下のようなものです:

   • Cライブラリーに‘iconv’のあるオペレーティングシステムとしては、たと
     えばglibcがあり、ライブラリー‘libiconv’に分割されているシステムには
     、たとえばOSF/1、FreeBSDがあります。種類の如何にかかわらず、GNU
     ‘libiconv’がインストールされたオペレーティングシステムの場合、オペ
     レーティングシステムのネイティブの‘iconv’のかわりに使用されます。

   • GNU ‘libiconv’がインストールされていて、検索パス(インクルードファイ
     ルの検索パス ‘CPPFLAGS’、ライブラリーの検索パス‘LDFLAGS’)にあるが、
     必要ない場合。

   • GNU ‘libiconv’は、いくつかのオペレーティングシステムのネイティブの
     ‘iconv’にたいしてバイナリーの非互換があります(例: FreeBSD)。適合し
     ていない‘iconv.h’および‘libiconv.so’の使用は、プログラムのクラッシ
     ュを招きます。

   • GNU ‘libiconv’がインストールされていて、実行時ライブラリーの検索パ
     スにあるが、必要ない場合。‘LD_LIBRARY_PATH’のような環境変数による設
     定を無視するために、このマクロは適切なランタイムのサーチパスオプシ
     ョンを、変数‘LIBICONV’に追加します。これはほとんどシステムで動作し
     ますが、SCOのように共有ライブラリーに制限のあるいくつかのオペレーテ
     ィングシステムではうまく動作しません。

   ‘gettext.m4’が依存しているので、‘iconv.m4’はGNU gettextの一部として配
布されます。

13.6 CVSによる統合
==================

   多くのプロジェクトでは分散開発におけるバージョンコントロールとソース
のバックアップにCVSを使用しています。このセクションでは‘cvs’、
‘gettextize’、‘autopoint’、‘autoconf’の使用をどのように管理するかについ
てのアドバイスを与えます

13.6.1 分散開発におけるバージョンミスマッチを避ける
---------------------------------------------------

   複数の開発者によるCVSを使ったプロジェクト開発では、‘gettext’の新しい
バージョンにアップグレードしたいと望む一人の開発者が、‘gettextize’を実行
してAdjusting Filesにリストした変更をほどこした後に、その変更を
CVSにコミットするようなことが時折あります。

   プロジェクトのすべての開発者が、パッケージのGNU ‘gettext’に、同じバー
ジョンのものを使用することを強く推奨します。別の言い方をすると、
‘gettextize’を実行したら、開発者はプロジェクト全体と同じ方法で必要な変更
をほどこしてCVSにコミットする必要があります。さもないと以下のような損傷
が発生します:

   • 開発者の間での、明らかなバージョンの不一致。‘configure.ac’および
     ‘configure.in’、‘Makefile.am’および‘Makefile.in’内の‘gettext’に関係
     する特定の箇所は、‘gettext’のバージョンに依存しており、異なるバージ
     ョンの‘gettext’による基礎的なファイルの使用により、容易にビルドエラ
     ーが発生します。

   • 明らかでないバージョンの不一致。このようなバージョン不一致は、開発
     者が発見できないようなパッケージの動作不良も招きます。明らかでない
     バージョンの不一致による最悪のケースは、パッケージのインターナショ
     ナリゼーションが動作しないケースです。

   • リリースのリスク。すべての開発者は、パッケージにたいして一定のテス
     トを暗黙に行います。このテストはリリースの数週間から数日前にかけて
     重要です。もしも誰かが他の開発者とは異なるバージョンのGNU
     ‘gettext’を使ってリリース用のtarファイルを作ったら、その配布物は同
     じバージョンの‘gettext’を使ってテストされたものに比べてテストされて
     いないことになり、たとえばそれがプラットフォームに固有の未知のバグ
     にもなり得るのです。

13.6.2 CVSバージョンコントロールの配下に置くファイル
----------------------------------------------------

   CVSレポジトリーのコンテキストで作成されるファイル、たとえば
‘configure.ac’により生成される‘configure’、‘PARSER.y’から生成される
‘PARSER.c’、‘gettextize’や‘autopoint’により自動インストールされる
‘po/Makefile.in.in’のようなファイルを取り扱うには、基本的に3つの方法があ
ります。

  1. 生成されるすべてのファイルを、常にレポジトリーにコミットする。

  2. 生成されるすべてのファイルを、時々(たとえば毎リリースごとに)レポジ
     トリーにコミットする。

  3. 生成されるファイルを、レポジトリーにコミットされない。

   これら3つの方法には、それぞれ異なる利点と欠点があります。

  1. 1番目の方法の利点は、誰でもCVSからその時点で動作するビルドをチェッ
     クアウトできる点です。欠点は以下のとおりです:
     1a メンテナーによる頻繁な"cvs commit"操作が必要です。
     1b レポジトリーサイズの増加が早くなります。

  2. 2番目の方法の利点は、誰もがチェックアウトでき、通常は"./configure;
     make"は動作します。欠点は以下のとおりです:
     2a レポジトリーからチェックアウトした人のPATHにGNU ‘automake’、GNU
     ‘autoconf’、GNU ‘m4’のようなツールがインストールされている必要があ
     り、ときには特定のバージョンが必要になる。
     2b リリース版が作成されて生成されるファイルもコミットされた後に他の
     開発者が"cvs update"を行うと、生成されるファイルで競合が発生する点
     。この競合は簡単に解決できますが、煩わしいものです。

  3. 3番目の方法の利点はメンテナーの作業負荷が軽減されることです。欠点は
     レポジトリーからチェックアウトした人のPATHにGNU ‘automake’, GNU
     ‘autoconf’, GNU ‘m4’のようなツールがインストールされている必要があ
     るだけではなく、"./configure; make"をできるようになる前に、パッケー
     ジ固有のpre-build(ビルド前)ステップが必要になることです。

   1番目と2番目の方法では、変更されたファイルや、‘gettextize’呼び出しに
より生成・更新されたファイルは、CVSにコミットする必要があります。

   3番目の方法では、‘gettextize’が"コピー"するすべてのファイルを、CVSレ
ポジトリーから除外できます。そのかわりに‘configure.ac’(または
‘configure.in’)を、以下のような形式で記述します

     AM_GNU_GETTEXT_VERSION(0.18.3)

さらにパッケージのpre-buildスクリプトに‘autopoint’呼び出しを追加します。
CVSからチェックアウトする人は誰でも、この‘autopoint’呼び出しによりCVSか
ら除外された‘gettext’の基礎的なファイルが適切な場所にコピーされます。

   ‘AM_GNU_GETTEXT_VERSION’の引数に使用されているバージョン番号は、パッ
ケージが使いたい‘gettext’インフラストラクチャーのバージョン番号です。こ
れは‘autopoint’プログラムの最小のバージョン番号でもあります。もし
‘AM_GNU_GETTEXT_VERSION(0.11.5)’と記述した場合、開発者は0.11.5以上のバー
ジョンを使用でき、すべての開発者のビルドがバージョン0.11.5のインフラスト
ラクチャーで動作します。メンテナーがパッケージにたいしてバージョン
0.12.1を指定してgettextizeを実行したとき、
‘AM_GNU_GETTEXT_VERSION(0.11.5)’は‘AM_GNU_GETTEXT_VERSION(0.12.1)’に変更
され、今後CVSを使う開発者はGNU ‘gettext’ 0.12.1以降をインストールする必
要があります。

13.6.3 ‘autopoint’プログラムの呼び出し
--------------------------------------

     autopoint [OPTION]...

   ‘autopoint’は、gettextの基礎となるファイルを、ソースパッケージにコピ
ーするプログラムです。このプログラムは
‘AM_GNU_GETTEXT_VERSION(VERSION)’の形式で呼び出されるマクロにより、パッ
ケージの‘configure.in’(または‘configure.ac’)ファイルからパッケージで使用
されるgettextのバージョンを抽出して、そのバージョンに該当する基礎となる
ファイルをパッケージにコピーします。

13.6.3.1 Options
................

‘-f’
‘--force’
     既存のファイルを強制的に上書きします。

‘-n’
‘--dry-run’
     変更を出力しますが、処理は行いません。普通に‘autopoint’を実行したこ
     とによるファイルのコピーはすべて抑止され、かわりに標準出力にリスト
     が出力されます。

13.6.3.2 Informative output
...........................

‘--help’
     このヘルプを表示して終了します。

‘--version’
     バージョン情報を表示して終了します。

   ‘autopoint’は、GNU ‘gettext’のバージョン0.10.35から、現在の0.18.3まで
をサポートします。0.18.3より新しいバージョンの‘gettext’を使用してパッケ
ージに‘autopoint’を適用するためには、少なくとも同じバージョンのGNU
‘gettext’をインストールする必要があります。

   GNU ‘automake’を使用するパッケージでの‘autopoint’の呼び出しは、
‘aclocal’呼び出しの後に行い、その後で‘autoconf’および‘autoheader’を呼び
出します。これは、‘autopoint’が‘aclocal.m4’を作成するために、
‘autopoint’がいくつかのautoconfマクロをインストールするのが理由です。こ
の aclocal.m4 は、autoconf によるパッケージの configure スクリプトを作成
と、autoheader によるパッケージのインクルードファイルのテンプレート
config.h.in を作成するために使用されます。このマクロファイルは
‘aclocal.m4’を作成するために‘aclocal’により使用され、‘aclocal.m4’はパッ
ケージの‘configure’を作成するために‘aclocal’により使用され、インクルード
ファイルテンプレートであるパッケージの‘config.h.in’を作成するために
‘autoheader’により使用されます。

   ‘autopoint’という名前は‘auto-po-intl-m4’を省略したものです。このツー
ルは主に‘po’、‘intl’、‘m4’ディレクトリーのファイルをコピーします。

13.7 配布用tarballの作成
========================

   GNU ‘automake’を使うプロジェクトでは、配布用のtarballを作成する通常の
コマンドは、‘make dist’または‘make distcheck’で、これにより必要に応じて
自動的にPOファイルが更新されます。

   GNU ‘automake’を使用していない場合、メンテナーはこのような更新をリリ
ースの前に行う必要があります:

     $ ./configure
     $ (cd po; make update-po)
     $ make distclean

14 インストーラーと配布者の視点
*******************************

   デフォルトでは、内部的にGNU ‘gettext’をフルに使っているパッケージは、
翻訳されたメッセージを使えるような方法でインストールされます。
_configuration_実行時には、これらのパッケージはホストシステムですでにGNU
‘gettext’の機能が提供されているかを、自動的に検出する必要があります。も
し提供されていない場合、GNU ‘gettext’ライブラリーが自動的に準備・使用さ
れます。インストーラーは、configure時のこの動作を変更するための特別なオ
プションを使うことができます。コマンド‘./configure
--with-included-gettext’により、そのシステムの‘gettext’をバイパスしてか
わりに同梱された GNU ‘gettext’を使用します。また‘./configure
--disable-nls’では、翻訳されたメッセージを利用しないプログラムを生成しま
す。

   インターナショナライズされたパッケージには通常、多くの‘LL.po’ファイル
があります。翻訳が利用不可になっていなければ、パッケージのインストールに
よりそれらが利用可能になります。しかしconfigureに先立ち環境変数の
‘LINGUAS’がセットされていると、インストールされる対象が制限されます。
‘LINGUAS’はスペースで区切られた2文字のコードのリストで、利用できる言語を
指定します。

15 その他のプログラミング言語
*****************************

   ‘gettext’が提供するものの大部分はC(これは暗黙でC++にも同様に適用でき
ます)に焦点をあてていますが、それ以外にも他の多くのプログラム言語やスク
リプト言語、その他のテキストデータ、たとえばGUIリソースやパッケージの説
明にも‘gettext’の手法を用いることができます。

15.1 言語実装者の視点
=====================

   すべてのプログラム言語およびスクリプト言語は、‘gettext’をサポートする
のに適した文字列の表記をもっています。‘gettext’をサポートするとは、以下
のことを意味します:

  1. 翻訳可能な文字列にたいする書式を言語に追加する必要があります。原則
     としては‘gettext’の関数呼び出しですが、省略した書式はインターナショ
     ナライズされたプログラムの可読性を向上する助けとなります。たとえば
     Cでは‘_("string")’、GNU awkでは‘_"string"’という書式が使用されます
     。

  2. 実行時の‘gettext’呼び出し(または等価な処理)により、このような翻訳可
     能な文字列を評価するための用意をする必要があります。

  3. 同様に、その言語で‘ngettext’、‘dcgettext’、‘dcngettext’の関数を利用
     可能にする必要があります。これらの関数が使用されることは少ないかも
     しれません。しかし‘ngettext’は正しくpluralを処理するために、そして
     ‘dcgettext’と‘dcngettext’は‘LC_TIME’や‘LC_MONETARY’などの、
     ‘LC_MESSAGES’以外のlocale関連の環境変数を処理する等の、特別の目的の
     ために必要です。後者の関数についてはCのヘッダーファイル
     ‘<locale.h>’の定数‘LC_*’が通常、環境変数や文字列で参照するため、そ
     の言語からも参照できるようにする必要があります。

  4. その言語から‘textdomain’関数を利用可能にするか、‘TEXTDOMAIN’のよう
     な"魔法"の変数を用意するなどして、プログラマーがメッセージドメイン
     を明示できるようにする必要があります。同様に、‘bindtextdomain’関数
     のように、プログラマーがメッセージカタログをどこから検索するかを、
     明示できるようにする機能を提供する必要があります。

  5. ‘setlocale (LC_ALL, "")’を、言語が実行されたスタートアップ時に呼び
     出すか、プログラマーが呼び出して処理できるようにするべきです。
     localeカテゴリーの‘LC_MESSAGES’と‘LC_CTYPE’がどちらもセットされてい
     ないときは、gettextはno-opとして振る舞うことを思い出してください。

  6. プログラマーには、プログラムから翻訳可能な文字列をPOファイルに抽出
     する方法が必要です。GNU ‘xgettext’は、非常に多くの異なるプログラム
     言語をサポートするように拡張されています。どうすればサポートされる
     かについては、GNU ‘gettext’のメンテナーに連絡してください。文字列の
     抽出機能が、あなたの言語のパーサーに統合されれば、GNU ‘xgettext’を
     あなたの言語の文字列抽出機能のフロントエンドとすることができます。

  7. 言語のライブラリーに、書式文字列と書式文字列の引数を位置番号や名前
     で示せるような機能をもたせる必要があります。これはいくつかの言語や
     メッセージでは、2つ以上の代替の引数にたいして、翻訳者はそれらの代替
     の引数を異なった順序で出力する必要があるからです。詳細は、see
     c-format Flagを参照してください。

  8. 言語に2つ以上の実装があって、それらのすべてが‘gettext’を実装してい
     る訳ではないにもかかわらず、それらの異なる実装間でプログラムに可搬
     性をもたせなければならないような場合には、no-i18nエミュレーションを
     提供する必要があります。これにより、実際に翻訳された文字列がなくて
     も、あなたの実装向けに記述されたプログラムを他の実装で利用すること
     ができます。

  9. プログラマーが翻訳文字列にマークを付与するタスクを助けるために、
     EmacsのPOモードが使用される場合があります(see Markingを参照して
     ください)。遠慮なくGNU ‘gettext’のメンテナーに連絡してください。そ
     うすれば彼らが‘po-mode.el’にあなたの言語にたいするサポートを追加す
     ることができます。

   実装から考えると、可搬性と著作権の面において異なる効果をもつ、3つのア
プローチが利用できます。

   • Maintainersで説明している方法で、あなたのパッケージのGNU
     ‘gettext’用の‘intl/’ディレクトリーを使って統合する方法があります。
     これにより、すべてのプラットフォームでインターナショナリゼーション
     が可能になります。この場合、パッケージは法的にはGNU General Public
     Licenseの下に配布されることに注意してください。そしてGNU projectは
     フリーソフトウェアの蓄積にたいするあなたの貢献を歓迎するでしょう。

   • CライブラリーのGNU ‘gettext’関数にたいしてリンクする方法があります
     。たとえば、autoconfが‘gettext()’を‘ngettext()’をテストしてこの状況
     を検知します。当面のところ、このテストはGNUシステムでは成功しますが
     、他のシステムでは成功しません。また、厳密な著作権の制限はありませ
     ん。

   • GNU ‘gettext’の機能をエミュレート、もしくは再実装する方法があります
     。この方法には、完全な可搬性と著作権の制限がないという利点がありま
     す。しかしGNU ‘gettext’の機能(環境変数‘LANGUAGE’、locale aliaseのデ
     ータベース、自動的な文字コード変換、pluralの処理のような機能)を再実
     装する必要があるという欠点もあります。

15.2 プログラマーの視点
=======================

   プログラマーにとって、一般的な手続きはC言語の場合と同じです。Emacsの
PO モードによるマークづけは他の言語もサポートしており、GNU ‘xgettext’の
文字列抽出も、ファイルの拡張子やコマンドラインのオプションで他の言語を識
別できます。実行時の言語にしたがって実行されるために、‘setlocale’を必要
としない言語もいくつかあります。

15.3 翻訳者の視点
=================

   翻訳者の作業はC言語の場合と同じです。唯一の違いは書式文字列の翻訳で、
彼女は書式文字列にたいする、その言語特有の位置引数を理解する必要がありま
す。

15.3.1 Cフォーマット文字列
--------------------------

   Cの書式文字列はPOSIX(IEEE P1003.1 2001)のセクションXSH 3 fprintf()
<http://www.opengroup.org/onlinepubs/007904975/functions/fprintf.html>で
説明されています。また fprintf()のman
<http://www.linuxvalley.it/encyclopedia/ldp/manpage/man3/printf.3.php>,
<http://informatik.fh-wuerzburg.de/student/i510/man/printf.html>も参照し
てください。

   以下のような、引数の位置を再指定する書式文字列があったとします

     "Only %2$d bytes free on '%1$s'."

これは以下の文と同じ意味をあらわします

     "'%s' has only %d bytes free."

これはPOSIX/XSIの機能であり、ISO C 99には明記されていませんが、翻訳者は
この再配置の機能を信頼することができます: ネイティブでは‘printf()’や
‘fprintf()’などがこの機能をサポートしていないプラットフォームも存在しま
すが、‘libintl.a’(または‘libintl.so’)が再配置の関数を提供していて、
‘<libintl.h>’がこれらの再配置のための関数を自動的に有効化するからです。

   Farsi(Persian)そして多分Arabicのための特別な機能として、翻訳者は数値
の書式指定子に‘I’フラグを挿入できます。この場合、たとえば‘"%d"’は‘"%Id"’
に翻訳されます。このフラグを指定すると、GNU ‘libc’のあるシステムでは、
ASCIIでの数字の出力が、localeカテゴリーの‘LC_CTYPE’で定義された
‘outdigits’により置き換えられます。他のシステムでは、‘gettext’関数がフラ
グを取り除くため、何の影響もありません。

   プログラマーはこのフラグを未翻訳の文字列に 挿入するべきでは_ない_こと
に注意してください(文字列MSGIDの書式指定のフラグに‘I’を挿入すると、
glibcがないシステムでNLSが無効になっているときに、未定義の動作を招きます
)。

15.3.2 Objective Cフォーマット文字列
------------------------------------

   Objective Cの書式文字列は、Cの書式文字列と似ています。Objective Cの場
合は、追加の書式指定子として、実行時に引数を‘Object *’タイプとして評価す
るための"%@"をサポートします。

15.3.3 Shellフォーマット文字列
------------------------------

   Shellの書式文字列はGNU gettextと‘envsubst’プログラムにより、
‘$VARIABLE’または‘${VARIABLE}’という形式で参照されるシェル変数がサポート
されています。‘${VARIABLE-DEFAULT}’、‘${VARIABLE:-DEFAULT}’、
‘${VARIABLE=DEFAULT}’、‘${VARIABLE:=DEFAULT}’、
‘${VARIABLE+REPLACEMENT}’、‘${VARIABLE:+REPLACEMENT}’、
‘${VARIABLE?IGNORED}’、‘${VARIABLE:?IGNORED}’で参照される、シェルスクリ
プト内だけで有効な形式はサポートされません。VARIABLEの名前には、半角の英
数字かASCII文字のアンダースコアーしか含められません。また数字で開始する
ことはできず、空も指定できません。そのような変数にたいする参照は無視され
ます。

15.3.4 Pythonフォーマット文字列
-------------------------------

   Pythonには2つの書式文字列があります。‘python-format’としてラベルづけ
されたPythonのビルトイン書式オペレーター‘%’と、‘str’オブジェクトの
‘format’に適用できます。

   Pythonの‘%’書式文字列については Python Library reference /
2. Built-in Types, Exceptions and Functions / 2.2. Built-in Types /
2.2.6. Sequence Types / 2.2.6.2. String Formatting Operationsで説明され
ています。<http://www.python.org/doc/2.2.1/lib/typesseq-strings.html>を
参照してください。

   Pythonカッコつき書式文字列(Python brace format strings)は、
PEP 3101 – Advanced String Formatting、
<http://www.python.org/dev/peps/pep-3101/>で説明されています。

15.3.5 Lispフォーマット文字列
-----------------------------

   Lispの書式文字列はCommon Lisp HyperSpecのchapter 22.3
Formatted Output、<http://www.lisp.org/HyperSpec/Body/sec_22-3.html>で説
明されています。

15.3.6 Emacs Lispフォーマット文字列
-----------------------------------

   Emacs Lispの書式文字列はEmacs Lisp referenceのsection
Formatting Strings、
<http://www.gnu.org/manual/elisp-manual-21-2.8/html_chapter/elisp_4.html#SEC75>に
記述されています。バージョン21のXEmacsでは、FSF Emacsがサポートしていな
い書式文字列内に番号付けられた引数指定をサポートすることに注意してくださ
い。

15.3.7 librepフォーマット文字列
-------------------------------

   librepの書式文字列はlibrep manualのsectionFormatted Output、
<http://librep.sourceforge.net/librep-manual.html#Formatted%20Output>、
<http://www.gwinnup.org/research/docs/librep.html#SEC122>に記述されてい
ます。

15.3.8 Schemeフォーマット文字列
-------------------------------

   Schemeの書式文字列はSLIB manualのsection Format Specification に記述
されています。

15.3.9 Smalltalkフォーマット文字列
----------------------------------

   Smalltalkの書式文字列は、GNU Smalltalk documentationのclass
‘CharArray’、methods ‘bindWith:’と‘bindWithArguments:’で説明されています
。
<http://www.gnu.org/software/smalltalk/gst-manual/gst_68.html#SEC238>を
参照してください。要約すると、指定子は‘%’で開始され、‘%’か非0の数字(‘1’
to ‘9’)が後に続きます。

15.3.10 Javaフォーマット文字列
------------------------------

   Javaの書式文字列はJDK documentationの class
‘java.text.MessageFormat’、
<http://java.sun.com/j2se/1.4/docs/api/java/text/MessageFormat.html>で説
明されています。ICU documentation、
<http://oss.software.ibm.com/icu/apiref/classMessageFormat.html>も参照し
てください。

15.3.11 C#フォーマット文字列
----------------------------

   C#の書式文字列は.NET documentationのclass ‘System.String’と
<http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpConFormattingOverview.asp>で
説明されています。

15.3.12 awkフォーマット文字列
-----------------------------

   awkの書式文字列はgawk documentationのsection Printf、
<http://www.gnu.org/manual/gawk/html_node/Printf.html#Printf>で説明され
ています。

15.3.13 Object Pascalフォーマット文字列
---------------------------------------

   Object Pascalの書式文字列はdocumentation of the Free Pascal runtime
libraryのsection Format、
<http://www.freepascal.org/docs-html/rtl/sysutils/format.html>で説明され
ています。

15.3.14 YCPフォーマット文字列
-----------------------------

   YCPの書式文字列はlibycp documentation
<file:/usr/share/doc/packages/libycp/YCP-builtins.html>で説明されていま
す。要約すると、指定子は‘%’で開始され、‘%’か非0の数字(‘1’から‘9’)が続き
ます。

15.3.15 Tclフォーマット文字列
-----------------------------

   Tclの書式文字列は‘format.n’のman、
<http://www.scriptics.com/man/tcl8.3/TclCmd/format.htm>で説明されていま
す。

15.3.16 Perlフォーマット文字列
------------------------------

   Perlには2種類の書式文字列があります。‘perl-format’とラベルつけされた
Perlのビルトイン関数‘printf’と、‘perl-brace-format’とラベルつけされた
‘libintl-perl’関数‘__x’で利用することができます。

   Perlの‘printf’の書式文字列は、‘man perlfunc’の‘sprintf’のsectionで説
明されています。

   perl braceの書式文字列はCPANのパッケージlibintl-perlの
‘Locale::TextDomain(3pm)’ manpageで説明されています。要約すると、Perl
format はカッコ(‘{’と‘}’)の間に記述されたプレースホルダーを使用します。
このプレースホルダーは簡単に識別できる構文でなければなりません。

15.3.17 PHPフォーマット文字列
-----------------------------

   PHPの書式文字列は、‘phpdoc/manual/function.sprintf.html’、または
<http://www.php.net/manual/en/function.sprintf.php>で説明されています。

15.3.18 GCC internalフォーマット文字列
--------------------------------------

   これらの書式文字列は、GCCのソース内で使用されるものです。このような書
式文字列では、指定子は‘%’で開始され、オプションのサイズ指定子‘l’、オプシ
ョンフラグの‘+’、他のオプションフラグとして‘#’が続きます。終端させるため
の指定子は、‘%’の場合はリテラルのパーセント記号、‘c’の場合は文字、‘s’は
文字列、‘i’および‘d’は整数、‘o’, ‘u’, ‘x’は符号なし整数、‘.*s’は前に幅指
定をともなう文字列、‘H’‘location_t *’型のポインター、‘D’は一般的な宣言、
‘F’は関数宣言、‘T’は型、‘A’は関数の引数、‘C’はtree code、‘E’は式、‘L’は
プログラム言語、‘O’はバイナリー演算子、‘P’は関数パラメーター、‘Q’は
assignment operator、‘V’はconst/volatile qualifierを表します。

15.3.19 GFC internalフォーマット文字列
--------------------------------------

   これらの書式文字列はGNU Fortran Compilerのソース内で使用されます。こ
れはGCC ソースのFortran用フロントエンドです。このような書式文字列では、
指定子は‘%’で開始され、終端させるための指定子は、‘%’はリテラルのパーセン
ト記号、‘C’は現在のソース位置、‘L’はソースの位置、‘c’は文字、‘s’は文字列
、‘i’ and ‘d’は整数、‘u’は符号なし整数で、‘i’、‘d’、‘u’の場合は前には、
サイズ指定子‘l’が指定されている場合があります。

15.3.20 Qtフォーマット文字列
----------------------------

   Qtの書式文字列はdocumentation of the QString class
<file:/usr/lib/qt-4.3.0/doc/html/qstring.html>で説明されています。要約す
ると、指定子は‘%’とその後ろの数字から成り立ちます。1つの書式文字列内に同
じ指定子を2回以上使うことはできません。

15.3.21 Qtフォーマット文字列
----------------------------

   Qtの書式文字列は documentation of the QObject::tr method
<file:/usr/lib/qt-4.3.0/doc/html/qobject.html>で説明されています。要約す
ると、使用できる指定子は‘%n’だけです。

15.3.22 KDEフォーマット文字列
-----------------------------

   KDE 4の書式文字列は次のように定義されています: 指定子は‘%’とその後ろ
の非0の10進数からなります。書式文字列内に‘%n’がある場合、それ以外の
‘%1’、...、‘%(n-1)’も存在しなければなりません。

15.3.23 Boostフォーマット文字列
-------------------------------

   Boostの書式文字列は、
<http://www.boost.org/libs/format/doc/format.html>のdocumentation of the
boost::format class で説明されています。要約すると、指定子は‘%1$+5d’のよ
うなCの書式文字列と同じ文法、または‘%|1$+5d|’や‘%|1$+5|’のように垂直バー
囲まれたものか、‘%1%’のように単にパーセント記号で囲まれたものです。

15.3.24 Luaフォーマット文字列
-----------------------------

   Luaの書式文字列は、Lua reference manualのsection String Manipulationで
説明されています。
<http://www.lua.org/manual/5.1/manual.html#pdf-string.format>を参照して
ください。

15.3.25 Java Scriptフォーマット文字列
-------------------------------------

   JavaScript仕様には書式文字列が定義されていないとはいえ、多くの
JavaScript実装はprintf-likeな関数を提供します。‘xgettext’は、Gjs、Seed、
Node.JSを含む著名なJavaScript実装で使用される、一般的な書式文字列のセッ
トを理解します。そのような書式文字列では、書式指定は‘%’で開始され、以下
の指定子で終端されます: ‘%’はリテラルのパーセント、‘c’は文字、‘s’は文字
列、‘b’、‘d’、‘o’、‘x’、‘X’は整数、‘f’は浮動小数点数、‘j’はJSONオブジェ
クトを表します。

15.4 メンテナーの視点
=====================

   メンテナーにとっては、一般的な手続きでC言語の場合での方法と異なるのは
、以下の2つです。

   • GNU gettextを使用しない言語では、‘intl/’ディレクトリーは必要ないの
     で省略できます。これはメンテナーが‘gettextize’プログラムを
     ‘--intl’オプションなしで呼び出すこと、そしてautoconfマクロ
     ‘AM_GNU_GETTEXT’を‘AM_GNU_GETTEXT([external])’と呼び出すことを意味
     します。

   • もし使用されているプログラム言語が1つだけの場合には、
     ‘po/Makevars’(see po/Makevarsを参照してください)の変数
     ‘XGETTEXT_OPTIONS’は、‘xgettext’のその言語向け特有のオプションにす
     る必要があります。パッケージが‘gettext’のサポートを複数のプログラム
     言語を使用している場合、‘po/Makefile.in.in’内のPOTファイルの構築ル
     ールを変更する必要があります。この場合は、1つのプログラム言語ごとに
     、言語に適したオプションで‘xgettext’呼び出しを行い、‘msgcat’により
     結果ファイルを結合する方法をお勧めします。

15.5 個別のプログラミング言語
=============================

15.5.1 C、C++、Objective
------------------------

RPM
     gcc、gpp、gobjc、glibc、gettext

ファイル拡張子
     C: ‘c’、‘h’
     C++: ‘C’、‘c++’、‘cc’、‘cxx’、‘cpp’、‘hpp’
     Objective C: ‘m’

文字列構文
     ‘"abc"’

gettextの略記
     ‘_("abc")’

gettext/ngettext関数
     ‘gettext’、‘dgettext’、‘dcgettext’、‘ngettext’、‘dngettext’、
     ‘dcngettext’

textdomain
     ‘textdomain’関数

bindtextdomain
     ‘bindtextdomain’関数

setlocale
     プログラマーは、‘setlocale (LC_ALL, "")’を呼び出さなければなりませ
     ん。

必要条件
     ‘#include <libintl.h>’
     ‘#include <locale.h>’
     ‘#define _(string) gettext (string)’

GNU gettextの使用またはエミュレート
     使用

抽出プログラム
     ‘xgettext -k_’

位置の書式
     ‘fprintf "%2$d %1$d"’
     C++は‘autosprintf "%2$d %1$d"’ (see Introduction (autosprintf).
     を参照してください)

可搬性
     autoconf(gettext.m4)、および#if ENABLE_NLS

po-modeでのマーキング
     yes

   ‘examples’ディレクトリーの以下の例が利用できます: ‘hello-c’、
‘hello-c-gnome’、‘hello-c++’、‘hello-c++-qt’、‘hello-c++-kde’、
‘hello-c++-gnome’、‘hello-c++-wxwidgets’、‘hello-objc’、
‘hello-objc-gnustep’、‘hello-objc-gnome’

15.5.2 sh - シェルスクリプト
----------------------------

RPM
     bash、gettext

ファイル拡張子
     ‘sh’

文字列構文
     ‘"abc"’、‘'abc'’、‘abc’

gettextの略記
     ‘"`gettext \"abc\"`"’

gettext/ngettext関数
     プログラム: ‘gettext’、‘ngettext’
     シェル関数: ‘eval_gettext’、‘eval_ngettext’

textdomain
     環境変数‘TEXTDOMAIN’

bindtextdomain
     環境変数‘TEXTDOMAINDIR’

setlocale
     自動

必要条件
     ‘. gettext.sh’

GNU gettextの使用またはエミュレート
     使用

抽出プログラム
     ‘xgettext’

位置の書式
     —

可搬性
     完全な可搬性がある

po-modeでのマーキング
     —

   ‘examples’ディレクトリーの例‘hello-sh’が利用できます

15.5.2.1 インターナショナリゼーションのためにシェルスクリプトを準備する
.......................................................................

   インターナショナリゼーションにむけたシェルの準備は、概念的には
Sourcesで説明したステップと似ています。以下はシェルスクリプトのための
具体的なステップです。

  1. スクリプトの冒頭付近に、以下の行を挿入します。

          . gettext.sh

     ‘gettext.sh’は、関数‘eval_gettext’(see eval_gettext Invocationを
     参照してください)と、‘eval_ngettext’(see eval_ngettext Invocation
     を参照してください)を提供するシェルの関数ライブラリーで
     す。‘gettext.sh’は、‘PATH’に記述された検索パスに配置されている必要
     があります。

  2. 環境変数‘TEXTDOMAIN’および‘TEXTDOMAINDIR’を、setしてexportします。
     ‘TEXTDOMAIN’は通常はパッケージ名かプログラム名、‘TEXTDOMAINDIR’は
     ‘$prefix/share/locale’に対応する絶対パスです。ここで‘$prefix’はイン
     ストールした場所です。

          TEXTDOMAIN=@PACKAGE@
          export TEXTDOMAIN
          TEXTDOMAINDIR=@LOCALEDIR@
          export TEXTDOMAINDIR

  3. Preparing Stringsで説明しているように、翻訳する文字列を準備
     します。

  4. 翻訳可能な文字列を単純にするため、コマンドによる文字列の置き換え
     ((‘"`...`"’または‘"$(...)"’))や、デフォルト値が含まれる変数(例：
     ‘${VARIABLE-DEFAULT}’)、‘$0’, ‘$1’, ...のような引数参照、一時的なシ
     ェル変数(例: ‘$?’)を含めないようにします。こうすることにより、常に
     単純なlocalコードを再構築することができます。たとえば、

          echo "Usage: $0 [OPTION] FILE..."

     は以下のように書き換えます

          program_name=$0
          echo "Usage: $program_name [OPTION] FILE..."

     同様に、

          echo "Remaining files: `ls | wc -l`"

     は以下のように書き換えます

          filecount="`ls | wc -l`"
          echo "Remaining files: $filecount"

  5. 個々の翻訳可能な文字列にたいして、出力コマンド‘echo’や‘$echo’を、
     ‘gettext’(文字列にシェル変数の参照が含まれない場合)や
     ‘eval_gettext’(シェル変数を参照する場合)に変更して、その後ろに引数
     を指定しない‘echo’コマンドを記述します(これは行末の改行のためです
     )。pluralを扱う場合は同様に、‘echo’コマンドを‘ngettext’または
     ‘eval_ngettext’の呼び出しに置き換えて、後に引数なしの‘echo’コマンド
     を記述します。

     この変更を行う際には、シェル変数への参照の前にある$記号をエスケープ
     するためのバックスラッシュを追加する必要もあります。そうすれば
     ‘eval_gettext’関数が変数が置き換える前の、翻訳可能な文字列を受けと
     ることができます。例えば以下のような文字列で考えてみましょう

          echo "Remaining files: $filecount"

     は以下のように書き換えます

          eval_gettext "Remaining files: \$filecount"; echo

     出力コマンドが‘echo’ではないときも、バッククォートにより‘echo’を使
     うことができます。バッククォートの内側では、バックスラッシュを2重に
     指定しなければ効果がないことに注意しなければなりません(これはバック
     クォートすることにより、バックスラッシュが1階層分消費されるからです
     )。例として、‘echo’がエラーをシグナルするシェル関数だとすると、

          error "file not found: $filename"

     は最初に以下へ変換され

          error "`echo \"file not found: \$filename\"`"

     となり、その後以下のようになります

          error "`eval_gettext \"file not found: \\\$filename\"`"

15.5.2.2 ‘gettext.sh’の内容
...........................

   ‘gettext.sh’にはGNU gettextのランタイム パッケージが含まれており、以
下が提供されます:

   • $echo 変数‘echo’には、最初の引数(引数文字列内のバックスラッシュの解
     釈されません)と、改行を出力するコマンドがセットされます。

   • eval_gettext eval_gettext Invocationを参照してください。

   • eval_ngettext eval_ngettext Invocationを参照してください。

15.5.2.3 ‘gettext’プログラムの呼び出し
......................................

     gettext [OPTION] [[TEXTDOMAIN] MSGID]
     gettext [OPTION] -s [MSGID]...

   ‘gettext’は、母国語に翻訳されたテキストメッセージを表示するプログラム
です。

*Arguments*

‘-d TEXTDOMAIN’
‘--domain=TEXTDOMAIN’
     TEXTDOMAINから、翻訳されたメッセージを取得します。TEXTDOMAINは通常
     、パッケージか、プログラムやプログラムのモジュールと一致します。

‘-e’
     いくつかのエスケープシーケンスの展開を可能にします。これはechoプロ
     グラムややシェルのビルトインコマンドにたいする互換のためのオプショ
     ンです。対象となるエスケープシーケンスは‘\a’、‘\b’、‘\c’、‘\f’、
     ‘\n’、‘\r’、‘\t’、‘\v’、‘\\’、および‘\’と、その後の3桁以内の8進数で
     す(これらはSystem Vの‘echo’と同様に処理されます)。

‘-E’
     このオプションは‘echo’プログラムとシェルのビルトインコマンドとの互
     換性のためだけのもので、何の効果も及ぼしません。

‘-h’
‘--help’
     このヘルプを表示して終了します。

‘-n’
     行末の改行を抑止します。デフォルトでは、‘gettext’は出力に改行を付与
     します。

‘-V’
‘--version’
     バージョン情報を表示して終了します。

‘[TEXTDOMAIN] MSGID’
     TEXTDOMAINから、MSGIDに対応する翻訳されたメッセージを取得します。

   パラメーターTEXTDOMAINを指定しなかった場合、環境変数‘TEXTDOMAIN’によ
りdomainが決定されます。メッセージカタログが標準のディレクトリーで見つか
らなかった場合には、環境変数‘TEXTDOMAINDIR’で他の場所を指定できます。

   ‘-s’オプションを使うと、プログラムは‘echo’コマンドのように振る舞いま
す。しかし、このプログラムは引数を単に標準出力にコピーするのではなく、選
択されたカタログにメッセージが見つかった場合は翻訳されたメッセージを出力
します。

   注意: ‘xgettext’は‘gettext’呼び出しで1つだけ引数を指定した形式(オプシ
ョンを指定せず、環境変数から暗黙にTEXTDOMAINを取得する形式)だけをサポー
トします。

15.5.2.4 ‘ngettext’プログラムの呼び出し
.......................................

     ngettext [OPTION] [TEXTDOMAIN] MSGID MSGID-PLURAL COUNT

   ‘ngettext’は数に依存した文法をもつテキストメッセージを母国語に翻訳し
て表示するプログラムです。

*Arguments*

‘-d TEXTDOMAIN’
‘--domain=TEXTDOMAIN’
     TEXTDOMAINから翻訳されたメッセージを取得します。TEXTDOMAINは通常、
     パッケージか、プログラムやプログラムのモジュールと一致します。

‘-e’
     いくつかのエスケープシーケンスの展開を可能にします。これは
     ‘gettext’プログラムにたいする互換のためのオプションです。対象となる
     エスケープシーケンスは、‘\a’、‘\b’、‘\c’、‘\f’、‘\n’、‘\r’、‘\t’、
     ‘\v’、‘\\’、および‘\’と3桁以内の8進数です(System Vの‘echo’と同様に
     処理されます)。

‘-E’
     このオプションは‘gettext’プログラムとの互換性のためだけのもので、何
     の効果も及ぼしません。

‘-h’
‘--help’
     このヘルプを表示して終了します。

‘-V’
‘--version’
     バージョン情報を表示して終了します。

‘TEXTDOMAIN’
     TEXTDOMAINから、翻訳されたメッセージを取得します。

‘MSGID MSGID-PLURAL’
     msgid( Englishのsingular )、およびmsgid-plural(Englishのplural)を翻
     訳します。

‘COUNT’
     この値にもとづいて、singularとpluralのどちらを使うか選択します。

   パラメーターTEXTDOMAINを指定しなかった場合、環境変数‘TEXTDOMAIN’によ
りdomainが決定されます。メッセージカタログが標準のディレクトリーで見つか
らなかった場合には、環境変数‘TEXTDOMAINDIR’で他の場所を指定できます。

   注意: ‘xgettext’は‘ngettext’呼び出しで3つの引数を指定した形式(オプシ
ョンを指定せず、環境変数から暗黙にTEXTDOMAINを取得する形式)だけをサポー
トします。

15.5.2.5 ‘envsubst’プログラムの呼び出し
.......................................

     envsubst [OPTION] [SHELL-FORMAT]

   ‘envsubst’は環境変数をその値に置き換えるプログラムです。

*Operation mode*

‘-v’
‘--variables’
     SHELL-FORMATの中に出現する変数を出力します。

*Informative output*

‘-h’
‘--help’
     このヘルプを表示して終了します。

‘-V’
‘--version’
     バージョン情報を表示して終了します。

   通常では、標準入力から‘$VARIABLE’または‘${VARIABLE}’という形式で参照
される環境変数を読み込んで、対応する値に置き換えてから標準出力にコピーし
ます。SHELL-FORMATが与えられたときは、SHELL-FORMATで指定された環境変数だ
けが置き換えられます。指定しなかった場合は、標準入力の中に出現するすべて
の環境変数が置き換えられます。

   この置き換えは、ダブルクォートされた文字列をシェルがアンクォートする
ときに行われる置き換え処理のサブセットです。他の‘${VARIABLE-DEFAULT}’、
‘$(COMMAND-LIST)’、‘`COMMAND-LIST`’などにたいする置き換えは、セキュリテ
ィー上の理由から‘envsubst’ではなくシェルによって処理されます。

   ‘--variables’を指定したときは、SHELL-FORMATに含まれる環境変数名を1行
に1つずつ出力します(標準入力は無視されます)。

15.5.2.6 ‘eval_gettext’プログラムの呼び出し
...........................................

     eval_gettext MSGID

   この関数は、テキストメッセージを母国語に翻訳して、翻訳した結果文字列
に含まれる$記号のついた変数にたいして置き換え処理を行ってから出力します
。$変数にたいする置き換えは、MSGIDに含まれるシェル変数にたいしてだけ行わ
れることに注意してください。

15.5.2.7 ‘eval_ngettext’プログラムの呼び出し
............................................

     eval_ngettext MSGID MSGID-PLURAL COUNT

   この関数は、数に依存した文法をもつテキストメッセージを母国語に翻訳し
て、翻訳した結果文字列に含まれる$記号のついた変数にたいして置き換え処理
を行ってから出力します。$変数にたいする置き換えは、MSGIDまたは
MSGID-PLURALに含まれるシェル変数にたいしてだけ行われることに注意してくだ
さい。

15.5.3 bash - Bourne-Againシェルスクリプト
------------------------------------------

   GNU ‘bash’ 2.0以降には、変数の中の文字列を翻訳して置き換えるための特
別な略記法‘$"msgid"’があります。しかし、これによりもたらされるセキュリテ
ィーホールと可搬性の問題により、この機能の使用には 賛成できません。

   ‘$"..."’によるセキュリティーホールとは、その文字列にたいする翻訳を検
索した後、‘eval’が2重引用符に囲まれた文字列や$ 記号、バッククォートされ
た文字列にたいして行うのと同様なことを‘bash’が行う点にあります。

  1. エンコーディングがBIG5、BIG5-HKSCS、GBK、GB18030、SHIFT_JIS、
     JOHABのいずれかを使うlocaleでは、2byte文字の2byte目が‘0x60’の文字が
     存在します。たとえば、これらのlocaleでは‘\xe0\x60’というバイト並び
     は1つの文字です。‘bash’の多くのバージョン(bash-2.05以降、および
     mbsrtowcs()関数を持たないプラットフォーム向けの新しいバージョン)は
     、文字境界を認識しないので、特定のChinese文字をバッククォートと認識
     します。このため翻訳の一部がコマンドリストとして実行されてしまうこ
     とが起こり得るのです。この状況は翻訳者が気をつけていても起こり得ま
     す。翻訳者が翻訳をUTF-8エンコーディングで提供したとしても、その翻訳
     は‘gettext()’関数によって翻訳者のエンコーディングからユーザーの
     localeのエンコーディングに変換され、その変換によって"危険な
     "‘\x60’というバイトが生成される可能性があるからです。

  2. 故意にせよ不注意にせよ、翻訳者は翻訳の中にバッククォート‘"`...`"’や
     、$カッコ‘"$(...)"’を使用することもあり得るので、それらに囲まれた文
     字列はコマンドリストとしてシェルにより実行されてしまいます。

   可搬性の問題とは、‘bash’をインターナショナリゼーションのサポート付き
でビルドしなければならないことです。これはlibcに‘gettext()’関数がないシ
ステムでは、通常できません。

15.5.4 Python
-------------

RPM
     python

ファイル拡張子
     ‘py’

文字列構文
     ‘'abc'’、‘u'abc'’、‘r'abc'’、‘ur'abc'’、
     ‘"abc"’、‘u"abc"’、‘r"abc"’、‘ur"abc"’、
     ‘'''abc'''’、‘u'''abc'''’、‘r'''abc'''’、‘ur'''abc'''’、
     ‘"""abc"""’、‘u"""abc"""’、‘r"""abc"""’、‘ur"""abc"""’

gettextの略記
     ‘_('abc')’など

gettext/ngettext関数
     ‘gettext.gettext’、‘gettext.dgettext’、‘gettext.ngettext’、
     ‘gettext.dngettext’、‘ugettext’、‘ungettext’

textdomain
     ‘gettext.textdomain’関数、または‘gettext.install(DOMAIN)’関数

bindtextdomain
     ‘gettext.bindtextdomain’関数、または
     ‘gettext.install(DOMAIN,LOCALEDIR)’関数

setlocale
     gettextエミュレーションでは使用されません

必要条件
     ‘import gettext’

GNU gettextの使用またはエミュレート
     エミュレート

抽出プログラム
     ‘xgettext’

位置の書式
     ‘'...%(ident)d...' % { 'ident': value }’

可搬性
     完全な可搬性がある

po-modeでのマーキング
     —

   ‘examples’ディレクトリーの例‘hello-python’を利用できます。

   書式文字列についての注意: Pythonは‘'...%d...'’のような名前なし引数の
書式文字列をサポートと、‘'...%(ident)d...'’のような名前つき引数の書式文
字列をサポートする。以下の2つの理由により、インターナショナライズされた
プログラムでは後者の方が好ましい

   • 書式文字列が2つ以上の引数をとるときに、書式文字列に名前付きの引数を
     使っていれば、翻訳者は引数を異なる順序で使用するような翻訳を提供で
     きます。例えば以下のような書式文字列
          "'%(volume)s' has only %(freespace)d bytes free."
     から
          "Only %(freespace)d bytes free on '%(volume)s'."
     に書き換えることができます。さらに識別名により翻訳者にコンテキスト
     を提供できます。

   • 多くの言語のplural formのコンテキストでは、singular formのための書
     式文字列で、数値引数は使用されません。Englishでも、‘"1 hour"’より
     ‘"one hour"’と書くのが好まれたりします。このように、書式文字列から
     特定の引数を除外するのは、名前付き引数の構文でのみ可能なことです(名
     前なし引数の場合、Python は – C とは異なり – 与えられたすべての引数
     が書式文字列で使用されているかチェックするからです)。

15.5.5 GNU clisp - Common Lisp
------------------------------

RPM
     clisp 2.28以降

ファイル拡張子
     ‘lisp’

文字列構文
     ‘"abc"’

gettextの略記
     ‘(_ "abc")’、‘(ENGLISH "abc")’

gettext/ngettext関数
     ‘i18n:gettext’、‘i18n:ngettext’

textdomain
     ‘i18n:textdomain’

bindtextdomain
     ‘i18n:textdomaindir’

setlocale
     自動

必要条件
     —

GNU gettextの使用またはエミュレート
     使用

抽出プログラム
     ‘xgettext -k_ -kENGLISH’

位置の書式
     ‘format "~1@*~D ~0@*~D"’

可搬性
     gettextのないプラットフォームでは、翻訳しません

po-modeでのマーキング
     —

   ‘examples’ディレクトリーの例‘hello-clisp’が利用できます

15.5.6 GNU clisp ソース
-----------------------

RPM
     clisp

ファイル拡張子
     ‘d’

文字列構文
     ‘"abc"’

gettextの略記
     ‘ENGLISH ? "abc" : ""’
     ‘GETTEXT("abc")’
     ‘GETTEXTL("abc")’

gettext/ngettext関数
     ‘clgettext’、‘clgettextl’

textdomain
     —

bindtextdomain
     —

setlocale
     自動

必要条件
     ‘#include "lispbibl.c"’

GNU gettextの使用またはエミュレート
     使用

抽出プログラム
     ‘clisp-xgettext’

位置の書式
     ‘fprintf "%2$d %1$d"’

可搬性
     gettextのないプラットフォームでは、翻訳しません

po-modeでのマーキング
     —

15.5.7 Emacs Lisp
-----------------

RPM
     emacs、xemacs

ファイル拡張子
     ‘el’

文字列構文
     ‘"abc"’

gettextの略記
     ‘(_"abc")’

gettext/ngettext関数
     ‘gettext’、‘dgettext’(xemacsのみ)

textdomain
     スペシャルフォーム‘domain’(xemacsのみ)

bindtextdomain
     関数‘bind-text-domain’(xemacsのみ)

setlocale
     自動

必要条件
     —

GNU gettextの使用またはエミュレート
     使用

抽出プログラム
     ‘xgettext’

位置の書式
     ‘format "%2$d %1$d"’

可搬性
     XEmacsのみ。ビルド時に‘I18N3’を定義しない場合は、翻訳しません

po-modeでのマーキング
     —

15.5.8 librep
-------------

RPM
     librep 0.15.3以降

ファイル拡張子
     ‘jl’

文字列構文
     ‘"abc"’

gettextの略記
     ‘(_"abc")’

gettext/ngettext関数
     ‘gettext’

textdomain
     ‘textdomain’関数

bindtextdomain
     ‘bindtextdomain’関数

setlocale
     —

必要条件
     ‘(require 'rep.i18n.gettext)’

GNU gettextの使用またはエミュレート
     使用

抽出プログラム
     ‘xgettext’

位置の書式
     ‘format "%2$d %1$d"’

可搬性
     gettextのないプラットフォームでは、翻訳しません

po-modeでのマーキング
     —

   ‘examples’ディレクトリーの例‘hello-librep’が利用できます

15.5.9 GNU guile - Scheme
-------------------------

RPM
     guile

ファイル拡張子
     ‘scm’

文字列構文
     ‘"abc"’

gettextの略記
     ‘(_ "abc")’

gettext/ngettext関数
     ‘gettext’、‘ngettext’

textdomain
     ‘textdomain’

bindtextdomain
     ‘bindtextdomain’

setlocale
     ‘(catch #t (lambda () (setlocale LC_ALL "")) (lambda args #f))’

必要条件
     ‘(use-modules (ice-9 format))’

GNU gettextの使用またはエミュレート
     使用

抽出プログラム
     ‘xgettext -k_’

位置の書式
     —

可搬性
     gettextのないプラットフォームでは、翻訳しません

po-modeでのマーキング
     —

   ‘examples’ディレクトリーの例‘hello-guile’が利用できます

15.5.10 GNU Smalltalk
---------------------

RPM
     smalltalk

ファイル拡張子
     ‘st’

文字列構文
     ‘'abc'’

gettextの略記
     ‘NLS ? 'abc'’

gettext/ngettext関数
     ‘LcMessagesDomain>>#at:’、‘LcMessagesDomain>>#at:plural:with:’

textdomain
     ‘LcMessages>>#domain:localeDirectory:’(オブジェクト
     ‘LcMessagesDomain’を返します)
     例: ‘I18N Locale default messages domain: 'gettext'
     localeDirectory: /usr/local/share/locale'’

bindtextdomain
     ‘LcMessages>>#domain:localeDirectory:’、上記参照

setlocale
     ‘I18N Locale default’をuseする場合は自動

必要条件
     ‘PackageLoader fileInPackage: 'I18N'!’

GNU gettextの使用またはエミュレート
     エミュレート

抽出プログラム
     ‘xgettext’

位置の書式
     ‘'%1 %2' bindWith: 'Hello' with: 'world'’

可搬性
     完全な可搬性がある

po-modeでのマーキング
     —

   ‘examples’ディレクトリーの例‘hello-smalltalk’が利用できます

15.5.11 Java
------------

RPM
     java、java2

ファイル拡張子
     ‘java’

文字列構文
     "abc"

gettextの略記
     _("abc")

gettext/ngettext関数
     ‘GettextResource.gettext’、‘GettextResource.ngettext’、
     ‘GettextResource.pgettext’、‘GettextResource.npgettext’

textdomain
     —
     かわりに‘ResourceBundle.getResource’を使用してください

bindtextdomain
     —
     かわりにCLASSPATHを使用してください

setlocale
     自動

必要条件
     —

GNU gettextの使用またはエミュレート
     —
     Java specific message catalog formatを使用してください

抽出プログラム
     ‘xgettext -k_’

位置の書式
     ‘MessageFormat.format "{1,number} {0,number}"’

可搬性
     完全な可搬性がある

po-modeでのマーキング
     —

   文字列をインターナショナライズ可能とマークする前に、文字列結合演算子
を使って、‘MessageFormat’アプリケーションで変換が必要な文字列を結合して
ください。たとえば‘"file "+filename+" not found"’は、
‘MessageFormat.format("file {0} not found", new Object[] { filename })’と
なります。これを行った後のみ、文字列をマークして抽出することが可能になり
ます。

   GNU gettextはJava 本来がもつ、‘ResourceBundle’という名前のインターナ
ショナリゼーションのメカニズムを使います。‘ResourceBundle’には、
‘.properties’と‘.class’という、2つのファイル フォーマットがあります。
‘.properties’ファイルは、POファイルのように翻訳者が直接編集できるテキス
ト形式ですが、plural formをサポートしません。‘.class’は、‘.java’のソース
コードからコンパイルされた形式で、plural formをサポートします(適切な
APIを通じてのアクセスが提供されています。以下を参照してください)。

   POファイルを‘.properties’ファイルに変換するためには、‘msgcat’プログラ
ムの ‘--properties-output’オプションを使うことができます。逆に
‘.properties’ファイルをPOファイルに変換するには、‘msgcat’プログラムの
‘--properties-input’オプションを使うことができます。POファイルを扱うすべ
てのツールは、‘--properties-input’および/または‘--properties-output’オプ
ションにより、‘.properties’も同様に取り扱うことができます。

   POファイルをResourceBundle classに変換するためには、‘msgfmt’プログラ
ムの、‘--java’(または‘--java2’)オプションを使うことができます。逆に
ResourceBundleをPOファイルに変換するためには、‘msgunfmt’の‘--java’オプシ
ョンを使うことができます。

   プログラムからResourceBundleにアクセスするために、異なる2つのAPIを使
うことができます。これら2つのAPIは、ResourceBundleがGNU gettextにより生
成されたものであるか、それともこれ以外の‘.class’や‘.properties’ファイル
であるかによらず、すべての種類のResourceBundleを扱えることに注意してくだ
さい。

  1. ‘java.util.ResourceBundle’ API

     特徴は、これの‘getString’関数が、翻訳された文字列を戻すことです。翻
     訳がない場合には、‘MissingResourceException’が発生することに注意し
     てください。

     これは、標準のAPIに採用されるためには有利な特徴といえます。さらに、
     このAPIは追加のライブラリーを必要とせず、‘msgcat’によって生成された
     ‘.properties’ファイルか、‘msgfmt’によって生成された‘.class’ファイル
     だけが必要です。しかし、このAPIはpluralを処理できず、それはpluralを
     処理するPOファイルから‘msgfmt’で生成されたリソースの場合も同様です
     。

  2. ‘gnu.gettext.GettextResource’ API

     javadoc2 directory (javadoc2/index.html)に、Javadoc 1.1 style
     formatのReference documentation があります。

     このAPIの‘gettext’関数は、翻訳された文字列を戻します。翻訳がない場
     合には、MSGIDが変更されずに戻されることに注意してください。

     このAPIの有利な点は、pluralを処理する‘ngettext’関数があること、そし
     て特定のcontextにたいする制約をもつ文字列を処理する‘pgettext’と
     ‘npgettext’のある点です。

     このAPIを使うために必要なのは、GNU gettextパッケージの一部である
     ‘libintl.jar’だけで、これはLGPLのもとで配布されています。

   2番目のAPIを使うための例としては、‘examples’ディレクトリーの、
‘hello-java’、‘hello-java-awt’、‘hello-java-swing’、
‘hello-java-qtjambi’が利用できます。

   ではAPIの使い方と、‘getString’の略記をしてみましょう。以下の3つの用法
から選択することができましょう:

   • (Java 1.5以降の場合)あなたのプロジェクトに‘Util’という一意なクラス
     があるとき、‘ResourceBundle’のインスタンスを保持するstaticな変数を
     定義する場合、以下のような略記を定義します:

          private static ResourceBundle myResources =
            ResourceBundle.getBundle("domain-name");
          public static String _(String s) {
            return myResources.getString(s);
          }

     そして、インターナショナライズする文字列を含むすべてのクラスに、以
     下の宣言を含めます

          import static Util._;

     これで以下のようにして略記を使うことができます:

          System.out.println(_("Operation completed."));

   • あなたのプロジェクトに‘Util’という一意なクラスがあるとき、
     ‘ResourceBundle’のインスタンスを保持するstaticな変数を定義する場合
     、以下のような略記を定義します:

          public static ResourceBundle myResources =
            ResourceBundle.getBundle("domain-name");

     そして、インターナショナライズする文字列を含むすべてのクラスに、以
     下の宣言を含めます

          private static ResourceBundle res = Util.myResources;
          private static String _(String s) { return res.getString(s); }

     これで以下のようにして略記を使うことができます:

          System.out.println(_("Operation completed."));

   • resource bundleの定義だけを含む、とても短い名前の‘S’というクラスを
     追加して、以下のような略記を定義します:

          public class S {
            public static ResourceBundle myResources =
              ResourceBundle.getBundle("domain-name");
            public static String _(String s) {
              return myResources.getString(s);
            }
          }

     これで以下のようにして略記を使うことができます:

          System.out.println(S._("Operation completed."));

   3つの用法のどれを選ぶかは、あなたのプロジェクトがJava 1.5より前のバー
ジョンにたいする互換性を必要とするかに依存します。もしその必要がある場合
には、プロジェクトのすべてのクラスに1文字のクラスを追加するより、すべて
のクラスに2行追加するほうがよいでしょう。

15.5.12 C#
----------

RPM
     pnet、pnetlib 0.6.2以降、またはmono 0.29以降

ファイル拡張子
     ‘cs’

文字列構文
     ‘"abc"’, ‘@"abc"’

gettextの略記
     _("abc")

gettext/ngettext関数
     ‘GettextResourceManager.GetString’,
     ‘GettextResourceManager.GetPluralString’
     ‘GettextResourceManager.GetParticularString’
     ‘GettextResourceManager.GetParticularPluralString’

textdomain
     ‘new GettextResourceManager(domain)’

bindtextdomain
     —
     実行可能ファイルを含むディレクトリーのサブディレクトリーにコンパイ
     ルされたmessage catalogが配置されます

setlocale
     自動

必要条件
     —

GNU gettextの使用またはエミュレート
     —
     C# specific message catalog formatを使用してください

抽出プログラム
     ‘xgettext -k_’

位置の書式
     ‘String.Format "{1} {0}"’

可搬性
     完全な可搬性がある

po-modeでのマーキング
     —

   文字列をインターナショナライズ可能とマークする前に、文字列結合演算子
を使って、‘String.Format’呼び出しで変換が必要な文字列を結合してください
。たとえば‘"file "+filename+" not found"’は、‘String.Format("file {0}
not found", filename)’となります。これを行った後のみ、文字列をマークして
抽出することが可能になります。

   GNU gettextは、‘ResourceManager’および‘ResourceSet’という名前の、
C#/.NET本来のインターナショナリゼーション メカニズムを使います。アプリケ
ーションは‘ResourceManager’のメソッドを使って、母国語に翻訳された文字列
を取得します。メッセージカタログファイルをインメモリーに展開したものが、
‘ResourceSet’のインスタンスです。‘ResourceManager’は、翻訳を検索する必要
が生じると、‘ResourceSet’のインスタンスをロード・アクセスします。

   C#のランタイムが直接ロードできる‘ResourceSet’には、‘.resources’ファイ
ル、および‘.dll’ファイルという、2つの形式があります:

   • ‘.resources’の形式はバイナリーのファイルで、通常は‘resgen’または
     ‘monoresgen’ユーティリティーにより生成され、この形式はplural formを
     サポートしません。‘.resources’は、.NETの‘.exe’ファイルに埋め込むこ
     ともできます。これは、メッセージカタログをロードするためにファイル
     システムにアクセスするかどうかに影響を及ぼすだけで、メッセージカタ
     ログの内容には影響しません。

   • 一方‘.dll’の形式は、ソースコードの‘.cs’からコンパイルされたバイナリ
     ーファイルで、plural formをサポートします(これは以下で記述するよう
     に、GNU gettext APIを通じてアクセスすることにより提供されます)。

   これら .NETの‘.dll’や‘.exe’ファイルは、特定のプラットフォームに限定さ
れたものではないことに注意してください。これらのファイル形式、およびC#の
ためのGNU gettextは、任意のプラットフォームで使用できます。

   ‘msgfmt’プログラムに‘--csharp-resources’オプションを指定することによ
り、POファイルを‘.resources’ファイルに変換できます。また、‘msgunfmt’プロ
グラムに‘--csharp-resources’オプションを指定することにより、
‘.resources’ファイルからPOファイルに逆変換できます。これらの処理は、
‘resgen’プログラム(‘pnet’パッケージ)や、‘monoresgen’プログラム
(‘mono’/‘mcs’パッケージ)でできる場合もあります。これらのプログラムは、
‘.resources’ファイルからPOファイルへの逆変換もできます。しかし、この文書
を記述している時点(2004年1月)では、‘monoresgen’コンバーターにはバグが多
く、‘resgen’コンバーターはPOファイルのエンコーディングを無視することに注
意してください。

   ‘msgfmt’プログラムに‘--csharp’オプションを指定することにより、POファ
イルを‘.dll’ファイルに変換できます。‘GettextResourceSet’(このクラスも
‘ResourceSet’のサブクラスです)のサブクラスを含んだ、‘.dll’ファイルを得る
ことができます。また、‘msgunfmt’プログラムに‘--csharp’オプションを指定す
ることにより、サブクラス‘GettextResourceSet’を含む‘.dll’ファイルをPOファ
イルに逆変換できます。

   ‘.resources’形式に比べて、‘.dll’形式には、以下のような利点があります:

  1. 自由なローカライズ: アプリケーションをビルド・配布した後でも、ユー
     ザーは自分の翻訳を自由に追加できます。一方、システムにより提供され
     る‘ResourceManager’のコンストラクターをプログラマーが使った場合、ア
     プリケーション用の一連の‘.resources’ファイルは、アプリケーションの
     ビルド時に指定しなければならず、後から拡張はできません。

  2. Plural の処理: ‘.dll’形式のメッセージカタログは、pluralを処理するた
     めの関数‘GetPluralString’をサポートします。一方、‘.resources’ファイ
     ルは、含まれているデータと、単一の文字列にもとづく検索だけをサポー
     トします。

  3. Context の処理: ‘.dll’形式のメッセージカタログは、contextにもとづく
     問い合わせをおこなうための関数‘GetParticularString’および
     ‘GetParticularPluralString’をサポートします。一方、‘.resources’ファ
     イルは、含まれているデータと、単一の文字列にもとづく検索だけをサポ
     ートします。

  4. ‘GettextResourceManager’は、‘.dll’形式の中のメッセージカタログのロ
     ードと、メッセージ単位でのロードも提供します。たとえば
     Austrian(‘de_AT’)のlocaleでは、メッセージがAustrianのメッセージカタ
     ログにないときに、German(‘de’)のメッセージカタログが使用されます。
     つまり、Austrianの翻訳者は、Germanの翻訳とは異なるいくつかのメッセ
     ージだけを、Austrianに翻訳する必要があるということです。一方、
     ‘.resources’ファイルでは、各メッセージカタログは、それ自身に含まれ
     るすべてのメッセージの翻訳を提供しなければなりません。

  5. ‘GettextResourceManager’は、翻訳が見つからないときはEnglishの
     MSGIDを戻すというフォールバック付きで、‘.dll’形式のメッセージカタロ
     グをロードします。一方、‘.resources’ファイルでは、その
     ‘.resources’が言語中立な場合、フォールバックを明示的に提供しなけれ
     ばなりません。

   プログラム用のAPIという面では、プログラマーは標準の‘ResourceManager’
APIと、GNU ‘GettextResourceManager’ API のどちらを使うこともできます。前
者の‘ResourceManager’のサブクラスが、後者の‘GettextResourceManager’なの
で、後者の方が拡張されています。

  1. ‘System.Resources.ResourceManager’ API

     このAPIは、‘.resources’形式のリソースにたいして動作します。

     ‘ResourceManager’を生成するには、以下のようにします
            new ResourceManager(domainname, Assembly.GetExecutingAssembly())

     ‘GetString’関数は、文字列にたいする翻訳を戻します。翻訳がない場合は
     nullが戻されることに注意してください(例: これはフォールバックのリソ
     ースファイルの場合にも適用されます)。

  2. ‘GNU.Gettext.GettextResourceManager’ API

     このAPIは、‘.dll’形式のリソースにたいして動作します。

     Reference documentationは、csharpdoc directory
     (csharpdoc/index.html)にあります。

     ‘ResourceManager’を生成するには、以下のようにします
            new GettextResourceManager(domainname)

     このAPIの‘GetString’関数は、翻訳された文字列を戻します。翻訳がない
     場合には、MSGIDが変更されずに戻されることに注意してください。

     ‘GetPluralString’関数は、Cの‘ngettext’関数のように、文字列にたいし
     てplural処理をした翻訳を戻します。

     ‘GetParticularString’関数は、Cの‘pgettext’関数のように、特定の
     contextが指定された文字列の翻訳を戻します。翻訳がない場合には、
     MSGIDが変更されずに戻されることに注意してください。

     ‘GetParticularPluralString’関数は、Cの‘npgettext’関数のように、特定
     のcontextが指定された文字列にたいして、plural処理をした翻訳を戻しま
     す。

     このAPIを使うために必要なのは、GNU gettextパッケージの一部である
     ‘GNU.Gettext.dll’だけで、これはLGPLのもとで配布されています。

   2つのアプローチをミックスすることもできます: たとえば
‘GNU.Gettext.GettextResourceManager’コンストラクターは使うが、
‘ResourceManager’型と‘GetString’メソッドだけを使うような場合です。これは
POファイル用のツールに適合させたいが、‘ResourceManager’を使う既存のソー
スコードを変更したくなくて、(まだ)‘GetPluralString’メソッドが必要ないと
きには適しているでしょう。

   2番目のAPIを使うためには、‘examples’ディレクトリーの‘hello-csharp’、
‘hello-csharp-forms’の2つの例が利用できます。

   ではAPIの使い方と、‘GetString’の略記をしてみましょう。以下の3つの用法
から選択することができましょう:

   • あなたのプロジェクトに‘Util’という一意なクラスがあるとき、
     ‘ResourceManager’のインスタンスを保持するstaticな変数を定義する場合
     は、以下のような略記を定義します:

          public static GettextResourceManager MyResourceManager =
            new GettextResourceManager("domain-name");

     そして、インターナショナライズする文字列を含むすべてのクラスに、以
     下の宣言を含めます

          private static GettextResourceManager Res = Util.MyResourceManager;
          private static String _(String s) { return Res.GetString(s); }

     これで以下のようにして略記を使うことができます:

          Console.WriteLine(_("Operation completed."));

   • resource managerの定義だけを含む、とても短い名前の‘S’というクラスを
     追加して、以下のような略記を定義します:

          public class S {
            public static GettextResourceManager MyResourceManager =
              new GettextResourceManager("domain-name");
            public static String _(String s) {
               return MyResourceManager.GetString(s);
            }
          }

     これで以下のようにして略記を使うことができます:

          Console.WriteLine(S._("Operation completed."));

   2つの用法のどちらを選ぶかは、すべてのクラスに上記の2行をコピーするの
がよいか、それともすべてのクラスに1文字のクラスを追加するのがよいかによ
ります。

15.5.13 GNU awk
---------------

RPM
     gawk 3.1以降

ファイル拡張子
     ‘awk’

文字列構文
     ‘"abc"’

gettextの略記
     ‘_"abc"’

gettext/ngettext関数
     ‘dcgettext’、gawk-3.1.0に‘dcngettext’はありません

textdomain
     ‘TEXTDOMAIN’変数

bindtextdomain
     ‘bindtextdomain’関数

setlocale
     自動、ただしgawk-3.1.0には‘setlocale (LC_MESSAGES, "")’はありません

必要条件
     —

GNU gettextの使用またはエミュレート
     使用

抽出プログラム
     ‘xgettext’

位置の書式
     ‘printf "%2$d %1$d"’(GNU awkのみ)

可搬性
     gettextのないプラットフォームでは翻訳されません。非GNUのawkでは、
     ‘dcgettext’、‘dcngettext’、‘bindtextdomain’を自分で定義しなければな
     りません。

po-modeでのマーキング
     —

   ‘examples’ディレクトリーの、例‘hello-gawk’が利用できます

15.5.14 Pascal - フリーPascalコンパイラー
-----------------------------------------

RPM
     fpk

ファイル拡張子
     ‘pp’、‘pas’

文字列構文
     ‘'abc'’

gettextの略記
     自動

gettext/ngettext関数
     —
     かわりにデータ型‘ResourceString’を使用してください

textdomain
     —
     , かわりに関数‘TranslateResourceStrings’を使用してください

bindtextdomain
     —
     , かわりに関数‘TranslateResourceStrings’を使用してください

setlocale
     自動、ただし使うのはLANGだけで、LC_MESSAGESやLC_ALL は使いません

必要条件
     ‘{$mode delphi}’、または‘{$mode objfpc}’
     ‘uses gettext;’

GNU gettextの使用またはエミュレート
     エミュレート(部分的)

抽出プログラム
     ‘xgettext’(または‘rstconv’)サポートのある‘ppc386’

位置の書式
     ‘uses sysutils;’
     ‘format "%1:d %0:d"’

可搬性
     ?

po-modeでのマーキング
     —

   Pascalコンパイラーには、‘ResourceString’データ型にたいする特別なサポ
ートがあります。これは‘.rst’ファイルを生成します。このファイルは、
‘xgettext’または‘rstconv’を使用することにより、‘.pot’ファイルに変換され
ます。実行時には、‘gettext’ユニット内の‘TranslateResourceStrings’関数を
使用して、この‘.pot’ファイルの翻訳に対応する‘.mo’ファイルをロードできま
す。

   ‘examples’ディレクトリーの、例‘hello-pascal’が利用できます。

15.5.15 wxWidgetsライブラリー
-----------------------------

RPM
     wxGTK、gettext

ファイル拡張子
     ‘cpp’

文字列構文
     ‘"abc"’

gettextの略記
     ‘_("abc")’

gettext/ngettext関数
     ‘wxLocale::GetString’、‘wxGetTranslation’

textdomain
     ‘wxLocale::AddCatalog’

bindtextdomain
     ‘wxLocale::AddCatalogLookupPathPrefix’

setlocale
     ‘wxLocale::Init’、‘wxSetLocale’

必要条件
     ‘#include <wx/intl.h>’

GNU gettextの使用またはエミュレート
     エミュレート、‘include/wx/intl.h’と‘src/common/intl.cpp’を参照して
     ください。

抽出プログラム
     ‘xgettext’

位置の書式
     wxString::Formatはシステムに‘wprintf()’と‘vswprintf()’関数があり、
     それらがPOSIX準拠の位置指定をサポートする場合のみ、位置指定をサポー
     トします。

可搬性
     完全な可搬性がある

po-modeでのマーキング
     yes

15.5.16 YCP - YaST2スクリプト言語
---------------------------------

RPM
     libycp、libycp-devel、yast2-core、yast2-core-devel

ファイル拡張子
     ‘ycp’

文字列構文
     ‘"abc"’

gettextの略記
     ‘_("abc")’

gettext/ngettext関数
     引数を１つ、または3つの‘_()’

textdomain
     ‘textdomain’命令

bindtextdomain
     —

setlocale
     —

必要条件
     —

GNU gettextの使用またはエミュレート
     使用

抽出プログラム
     ‘xgettext’

位置の書式
     ‘sformat "%2 %1"’

可搬性
     完全な可搬性がある

po-modeでのマーキング
     —

   ‘examples’ディレクトリーの、例‘hello-ycp’が利用できます

15.5.17 Tcl - Tkのスクリプト言語
--------------------------------

RPM
     tcl

ファイル拡張子
     ‘tcl’

文字列構文
     ‘"abc"’

gettextの略記
     ‘[_ "abc"]’

gettext/ngettext関数
     ‘::msgcat::mc’

textdomain
     —

bindtextdomain
     —
     かわりに‘::msgcat::mcload’を使用してください

setlocale
     自動、LANGは使いますが、LC_MESSAGESとLC_ALL は無視されます

必要条件
     ‘package require msgcat’
     ‘proc _ {s} {return [::msgcat::mc $s]}’

GNU gettextの使用またはエミュレート
     — Tcl specific message catalog formatを使用してください

抽出プログラム
     ‘xgettext -k_’

位置の書式
     ‘format "%2\$d %1\$d"’

可搬性
     完全な可搬性がある

po-modeでのマーキング
     —

   ‘examples’ディレクトリーの2つの例‘hello-tcl’と‘hello-tcl-tk’が利用で
きます

   文字列をインターナショナライズ可能とマークする前に、代用の変数を
‘format’アプリケーションで変換する必要がある文字列にします(例: ‘"file
$filename not found"’は‘[format "file %s not found" $filename]’)。これを
行った後のみ、文字列をマークして抽出できます。上記の例では、マークした後
は‘[format [_ "file %s not found"] $filename]’(または‘[msgcat::mc "file
%s not found" $filename]’)となります。msgcat::mc 関数は、2つ以上の引数が
与えられたときは、暗黙的に‘format’を呼び出すことに注意してください。

15.5.18 Perl
------------

RPM
     perl

ファイル拡張子
     ‘pl’、‘PL’、‘pm’、‘perl’、‘cgi’

文字列構文

        • ‘"abc"’

        • ‘'abc'’

        • ‘qq (abc)’

        • ‘q (abc)’

        • ‘qr /abc/’

        • ‘qx (/bin/date)’

        • ‘/pattern match/’

        • ‘?pattern match?’

        • ‘s/substitution/operators/’

        • ‘$tied_hash{"message"}’

        • ‘$tied_hash_reference->{"message"}’

        • その他(この問題は‘man perlsyn’コマンドで詳細に論じられています
          )

gettextの略記
     ‘__’(2連のアンダースコアー)

gettext/ngettext関数
     ‘gettext’、‘dgettext’、‘dcgettext’、‘ngettext’、‘dngettext’、
     ‘dcngettext’

textdomain
     ‘textdomain’関数

bindtextdomain
     ‘bindtextdomain’関数

bind_textdomain_codeset
     ‘bind_textdomain_codeset’関数

setlocale
     Use ‘setlocale (LC_ALL, "");’

必要条件
     ‘use POSIX;’
     ‘use Locale::TextDomain;’(libintl-perlパッケージに含まれています。
     これはCPAN(Comprehensive Perl Archive Network)
     http://www.cpan.org/)で入手できます。

GNU gettextの使用またはエミュレート
     プラットフォームに依存: gettext_ppはエミュレート、gettext_xsはGNU
     gettextを使っています

抽出プログラム
     ‘xgettext -k__ -k\$__ -k%__ -k__x -k__n:1,2 -k__nx:1,2 -k__xn:1,2
     -kN__ -k’

位置の書式
     どちらの種類の位置指定付き書式もサポートしています
     ‘printf "%2\$d %1\$d", ...’(Perl 5.8.0以降)
     ‘__expand("[new] replaces [old]", old => $oldvalue, new =>
     $newvalue)’

可搬性
     ‘libintl-perl’パッケージはプラットフォームに依存しませんが、Perlの
     中核となるものの一部です。ターゲットとなるシステムにパッケージがイ
     ンストールされていない場合、必要な関数のダミーの実装を提供するのは
     、プログラマーの責任です。

po-modeでのマーキング
     —

ドキュメント
     ‘libintl-perl’に含まれています。これはCPAN(http://www.cpan.org/)で
     利用できます

   ‘examples’ディレクトリーの、例‘hello-perl’が利用できます

   Perl用の‘xgettext’パーサーのバックエンドと、他のプログラム言語用のパ
ーサーのバックエンドには、重大な違いがあります。これはPerl自体に、他の言
語との間に重大な違いがあるからです。Perl用のパーサーのバックエンドは、文
字列をマークするための機能を、他のバックエンドより多く提供しますが、これ
にはPerl固有の制限がいくつかあり、その中でもっとも問題となるのは言語の不
完全性によるものでしょう。

15.5.18.1 Perlコードをパースするときの一般的な問題
..................................................

   PerlだけがPerlをパースできるということを、しばしば耳にしますが、これ
は真実ではありません。結局Perlを_パース_することはできず、_実行_すること
ができるだけなのです。Perlにはビルトインでさまざまなあいまいさがあり、そ
れを解決できるのは実行時だけなのです。

   以下は一般的な例を示した例です:

     print gettext "Hello World!";

   これは関数呼び出しの"堅実"な例に見えるかもしれませんが、そうでもあり
ません:

     open gettext, ">testfile" or die;
     print gettext "Hello world!"

   上記のコンテキストでは、文字列‘gettext’はファイルハンドルのように見え
ます。しかし必ずしもそうではありません:

     use Locale::Messages qw (:libintl_h);
     open gettext ">testfile" or die;
     print gettext "Hello world!";

   この例では、Perlのインクルードパスで最初に見つかる
‘Locale::Messages’モジュールがエクスポートする‘gettext’関数により提供さ
れるファイル名は、多分文法エラーになるでしょう。しかし実際の
‘Locale::Messages’モジュールが以下のようなものだったらどうなるでしょうか
?

     use vars qw (*gettext);

     1;

   このケースでは、文字列‘gettext’は再びファイルハンドルとして解釈される
ので、‘testfile’というファイルを作成して、そのファイルに“Hello world!”と
いう文字列を書き込む例になります。より高度なフロー分析による制御も、助け
にはなりません:

     if (0.5 < rand) {
        eval "use Sane";
     } else {
        eval "use InSane";
     }
     print gettext "Hello world!";

   わたしたちが期待するような‘gettext’関数をエクスポートするモジュールが
‘Sane’で、‘gettext’という_ハンドル_の出力ストリームを書き込み用にオープ
ンするのが‘InSane’というモジュールの場合、わたしたちには実行時に何が起こ
るのか知る糸口がなく、完全に予測不能です。本当のところPerlには、実行時に
それ自身のシンボルテーブルにシンボルを追加するために非常に多くの方法があ
り、実行することなく特定のコードの断片を解釈するのは不可能なのです。

   もちろん‘xgettext’は翻訳可能な文字列を走査するときに、走査するPerlの
ソースを実行するわけではなく、コードを記述した人が何を意図したのかを推測
するために発見的な手法を用います。

   他にもスラッシュとクエスチョンマークの曖昧さという問題があります。こ
れらの解釈はコンテキストに依存します:

     # A pattern match.
     print "OK\n" if /foobar/;

     # A division.
     print 1 / 2;

     # Another pattern match.
     print "OK\n" if ?foobar?;

     # Conditional.
     print $x ? "foo" : "bar";

   スラッシュは除算のための演算子と、パターンマッチをあらわすための両方
の用途で使用されます。一方、クエスチョン マークは3項演算の条件判定と、パ
ターンマッチでも使用されます。他の‘awk’のようなプログラム言語にも同様な
問題はありますが、このようにソースを誤って解釈してしまう問題はPerlのソー
スの場合が特に顕著なのです。たとえば‘awk’では、命令文は決して1行を超えな
いので、パーサーはパースエラーから復帰して、次の行から残りの入力ストリー
ムを正しく処理できます。これと異なりPerlは、コンテキストの意味とは無関係
に、入力ストリームに次の区切り文字(スラッシュまたはクエスチョンマーク)が
出現することでパターンマッチが終端されます。本来は除算演算子として使用さ
れているスラッシュがパターンマッチと誤って解釈された場合、おそらく残りの
入力ファイルは正常にパースされないでしょう。

   以下に、あいまいさの解決が不可能なケースを示します:

     $x = wantarray ? 1 : 0;

   Perlのビルトイン関数である‘wantarray’は引数をとらないので、Perlのパー
サーはクエスチョンマークが正規表現の開始ではなく、3項演算子だと知ること
ができます。

     sub wantarrays {}
     $x = wantarrays ? 1 : 0;

   今度は状況が異なります。関数‘wantarrays’は、可変個の引数をとります(他
のプロトタイプがない任意のPerl関数と同様です)。この場合、クエスチョンマ
ークはパターンマッチの区切り文字として解釈されるので、このコードの断片は
コンパイルされません。

     sub wantarrays() {}
     $x = wantarrays ? 1 : 0;

   さて今度は関数がプロトタイプされているので、Perlは関数が引数をとらな
いことを知っているので、クエスチョンマークは再び3項演算子として解釈され
ます。しかし残念ながら‘xgettext’はそうではありません。

   ‘xgettext’のPerl用パーサーは、関数にプロトタイプがあるのか、そしてそ
のプロトタイプがどのように見えるのか知ることができないので、経験的に推測
することになります。ある関数がPerlのビルトイン関数で、この関数が引数を受
け付けない場合は、それに続くクエスチョンマーク(またはスラッシュ)は演算子
として扱われ、それ以外の場合は以降に続く正規表現のための区切り文字として
扱われます。Perlのビルトイン関数で引数をとらないのは‘wantarray’、
‘fork’、‘time’、‘times’、‘getlogin’、‘getppid’、‘getpwent’、‘getgrent’、
‘gethostent’、‘getnetent’、‘getprotoent’、‘getservent’、‘setpwent’、
‘setgrent’、‘endpwent’、‘endgrent’、‘endhostent’、‘endnetent’、
‘endprotoent’、‘endservent’です。

   もし‘xgettext’が、あなたのソースから文字列を抽出するのに失敗する場合
には、このセクションで説明したようなスラッシュ(またはクエスチョンマーク
)を探してみる必要があります。もしかしたら‘xgettext’のPerlパーサーの、他
のバグである可能性もあります(もちろんそのようなバグは報告する必要がある
でしょう)。そのうちに、あなたは‘xgettext’に "挑戦"するより、マナーにのっ
とってコードを整形する必要があると思うでしょう。

   特に、引数をとらない関数をパーサーが認識できないときは、カッコを使っ
てください:

     $x = somefunc() ? 1 : 0;
     $y = (somefunc) ? 1 : 0;

   実際のところはPerlのパーサーも、このような状況にたいする問題をもって
いて、警告を発します。

15.5.18.2 xgettextが探すキーワードはどれ?
.........................................

   ‘xgettext’に‘--keyword’(または‘-k’)オプションを指定しない場合は、
Perlソース中の以下のキーワードを認識します:

   • ‘gettext’

   • ‘dgettext’

   • ‘dcgettext’

   • ‘ngettext:1,2’

     1番目(singular)と2番目(plural)の引数が抽出されます。

   • ‘dngettext:1,2’

     1番目(singular)と2番目(plural)の引数が抽出されます。

   • ‘dcngettext:1,2’

     1番目(singular)と2番目(plural)の引数が抽出されます。

   • ‘gettext_noop’

   • ‘%gettext’

     ハッシュ‘%gettext’の中のハッシュ キーが抽出されます。

   • ‘$gettext’

     ハッシュ リファレンス‘$gettext’の指すハッシュの中のハッシュ キーが
     抽出されます。

15.5.18.3 ハッシュキーを抽出する方法
....................................

   通常の実行時のメッセージ翻訳は、翻訳が格納されたデータベースから元の
文字列を検索して、、翻訳された文字列を戻します。これをPerlで実装する“自
然な”方法は、ハッシュのルックアップで、もちろん‘xgettext’もこのような実
装をサポートしています。

     print __"Hello world!";
     print $__{"Hello world!"};
     print $__->{"Hello world!"};
     print $$__{"Hello world!"};

   上の4つの行は、すべて同じことを行います。Perlの‘Locale::TextDomain’モ
ジュールは、関数‘__()’にtiedされたハッシュ‘%__’をデフォルトでエクスポー
トします。また、このモジュールは‘%__’にたいするリファレンス‘$__’もエクス
ポートします。

   ‘xgettext’に‘--keyword’(または‘-k’)オプションを指定したときに、その引
数の1文字目がパーセント記号(%)の場合、残りの部分のキーワードはハッシュの
名前として解釈されます。引数の1文字目がダラー記号($)の場合、残りの部分の
キーワードはハッシュにたいするリファレンスとして解釈されます。

   Perlのコードとして許容できるなら(大抵の場合は問題ないはずです)、ハッ
シュキーを囲むシングルクォーテーション(またはダブルクォーテーション)は省
略できることに注意してください:

     print $gettext{Error};

   ルールを正確にいうと: ハッシュキーが有効なCの識別子(!)の場合(例: 識別
子の1文字目がアンダースコアーまたはASCII文字で、その後ろに任意の個数のア
ンダースコアー、または半角英数が続くような識別子)、その識別子を囲むクォ
ート記号を省略できます。その他のUnicode文字は、‘use utf8’ pragmaを使って
いない限り、認められません。

15.5.18.4 何が文字列で、何がクォート風の式なのか?
.................................................

   Perlは文字列の構成方法として、過剰ともいえるほどの異なる方法を提供し
ています。関数の引数や、ハッシュをルックアップするカッコのなかで使用でき
るこれらの文字列は、‘xgettext’でも概ねサポートされています。

   • *double-quoted strings*
          print gettext "Hello World!";

   • *single-quoted strings*
          print gettext 'Hello World!';

   • *演算子qq*
          print gettext qq |Hello World!|;
          print gettext qq <E-mail: <guido\@imperia.net>>;

     ‘qq’演算子は完全にサポートされています。演算子のための区切り文字に
     は、4種類のカッコ(round、angle、square、curly)を入れ子にして使うこ
     とも含めて、任意の区切り文字を使用できます。

   • *演算子q*
          print gettext q |Hello World!|;
          print gettext q <E-mail: <guido@imperia.net>>;

     ‘q’演算子は完全にサポートされています。演算子のための区切り文字には
     、4種類のカッコ(round、angle、square、curly)を入れ子にして使うこと
     も含めて、任意の区切り文字を使用できます。

   • *演算子qx*
          print gettext qx ;LANGUAGE=C /bin/date;
          print gettext qx [/usr/bin/ls | grep '^[A-Z]*'];

     ‘qx’演算子は完全にサポートされています。演算子のための区切り文字に
     は、4種類の括弧(round、angle、square、curly) を入れ子にして使うこと
     も含めて、任意の区切り文字を使用できます。

     この例の場合、演算子内部の文字列にたいして‘gettext’は使われません。
     これは‘qx’演算子の中に指定したコマンドの出力を使って、‘gettext’を呼
     び出します。これはインターフェースを統一するために提供されている機
     能です(パーサーはすべての文字列と引用符類を抽出します)。

   • *ヒアドキュメント*
          print gettext <<'EOF';
          program not found in $PATH
          EOF

          print ngettext <<EOF, <<"EOF";
          one file deleted
          EOF
          several files deleted
          EOF

     ヒアドキュメントは認識されます。ヒアドキュメントを終端する区切り文
     字列がシングルクォーテーションでくくられていた場合、文字列中の変数
     は展開されません。区切り文字列がダブルクォーテーションでくくられて
     いる場合、または区切り文字でくくられていない場合には、文字列中の変
     数は展開されます。

     数字ではじめまる区切り文字列はサポートされていません!

15.5.18.5 文字列内挿の無効な使い方
..................................

   Perlでは、変数による文字列の補間ができます。これはローカライズされる
プログラムに恩恵をもたらしますが、問題を引き起こすこともあります。

   以下のような文字列の生成はエラーを発生させます:

     print gettext "This is the program $0!\n";

   このような場合Perlは実行時に、関数‘gettext()’の引数内の、変数‘$0’を補
間するでしょう。これにより、この引数は文字列定数ではなく文字列変数となり
ます(‘$0’はグローバル変数で、実行されているperlのスクリプト名が保持され
ています)。補間はPerlが文字列引数を‘gettext()’に渡す前に行われるので、文
字列は実行時にのみ決定可能なスクリプト名に依存することになります。その結
果、実行時に翻訳を見つけるのはほとんど不可能になります(メッセージカタロ
グで補間された文字列が偶然見つかってしまった場合を除きます)。

   そのため‘xgettext’プログラムは、抽出された文字列の中に変数を見つける
と、致命的なエラーとして解析を打ちきります。これは一般的に、このような補
間文字列すべてをコンパイル時に安全に処理することができないからです。あな
たが自分が何をしているか完全に知っている場合には、以下のようにしてこの挙
動を回避できます:

     my $know_what_i_am_doing = "This is program $0!\n";
     print gettext $know_what_i_am_doing;

   パーサーは、変数やその他の単語は認識しませんが、文字列と引用符の類だ
けなら認識するので、上記の文は許されます。しかし、多分あなたは元文字列を
メッセージカタログに抽出するための、別の方法を見つける必要があるでしょう
。

   ‘--extract-all’(または‘-a’)オプションを指定して呼び出すと、変数の補間
ができるようになります。理論的な根拠: 一般的にはソースをインターナショナ
ライズ用に準備するために、このオプションを使うでしょう。

   補間される文字列・補間されない文字列と、引用符類の表現についての詳細
は、‘man perlop’のmanpageを参照してください。以下は、(致命的なエラーとな
らない)安全な補間です:

   • エスケープシーケンス‘\t’(tab, HT, TAB)、 ‘\\n’(newline、NL)、
     ‘\r’(return、CR)、‘\f’(form feed、FF)、‘\b’(backspace、BS)、
     ‘\a’(alarm、bell、BEL)、‘\e’ (escape、ESC)

   • ‘\033’のような8進文字
     400から777の範囲の8進シーケンスは、‘use utf8’ pragmaが記述されてい
     るか否かにかかわらず、UTF-8表現に翻訳されることに注意してください。

   • hex chars, like ‘\x1b’

   • ‘\x{263a}’のような16進文字
     このエスケープは、‘use utf8’ pragmaが記述されているか否かにかかわら
     ず、UTF-8表現に翻訳されることに注意してください。

   • ‘\c[’(CTRL-[)のような制御文字

   • ‘\N{LATIN CAPITAL LETTER C WITH CEDILLA}’のような名前つきUnicode文
     字
     このエスケープは、‘use utf8’ pragmaが記述されているか否かにかかわら
     ず、UTF-8表現に翻訳されることに注意してください。

   以下のエスケープは、部分的には安全だとみなされます:

   • ‘\l’ 次の文字を小文字にします

   • ‘\u’ 次の文字を大文字にします

   • ‘\L’ \E までを小文字にします

   • ‘\U’ \Eまでを大文字にします

   • ‘\E’ 大文字小文字変換を終端します

   • ‘\Q’ \Eまでの非単語文字をクォートします

   これらのエスケープは、文字列にASCII文字しか含まれていないときだけ、安
全とみなされます。ASCIIで定義された範囲外の翻訳文字はlocale依存であり、
実際には実行時しか処理できません。‘xgettext’は、これらのlocale依存の翻訳
を抽出時に処理しません。

   修飾子‘\Q’を除き、たとえこれらの翻訳が有効だとしても、一般的には無用
であり、ソースがわかりにくくなるだけです。コンパイル時に翻訳が安全に処理
できるなら、あなたも、意図することを同じように記述できるはずです。

15.5.18.6 文字列内挿の有効な使い方
..................................

   Perlは他のプログラム言語のソースや、任意のファイルフォーマットを生成
するために使用されることもあります。このような使用方法の例として有名なも
のには、HTMLコードを出力するWebアプリケーションがあります。

   以下のHTMLの例のように、翻訳可能なメッセージを含む言語(またはプログラ
ム言語)を、散在させて記述したい状況に出会うこともあるでしょう:

     print gettext <<EOF;
     <h1>My Homepage</h1>
     <script language="JavaScript"><!--
     for (i = 0; i < 100; ++i) {
         alert ("Thank you so much for visiting my homepage!");
     }
     //--></script>
     EOF

   parserによりヒアドキュメント全体が抽出されて、埋め込みJavaScriptの断
片が含まれたHTMLコードが、抽出結果であるPOファイルに出現します。上記のよ
うな構築法の多用には、そのパッケージの翻訳者がもっと難易度の低いパッケー
ジを探すというリスクがあります。このような場合には以下のような代替の表現
を考慮する必要があるでしょう:

     print <<EOF;
     <h1>$gettext{"My Homepage"}</h1>
     <script language="JavaScript"><!--
     for (i = 0; i < 100; ++i) {
         alert ("$gettext{'Thank you so much for visiting my homepage!'}");
     }
     //--></script>
     EOF

   この例ではコードの翻訳可能な部分だけが抽出されるので、結果となるPOフ
ァイルは、不本意ながら可読性の点においては改善されるでしょう。

   すべての文字列の中のhashのルックアップ、およびquote風な表現は補間する
ことができます(quote風というな表現は、補完という処理が抱えているテーマで
もあります。詳細についてはmanpage ‘man perlop’を参照してください)。しか
し2重の補間は無効になります:

     # TRANSLATORS: Replace "the earth" with the name of your planet.
     print gettext qq{Welcome to $gettext->{"the earth"}};

   最初の位置の‘qq’によりクォートされた文字列が、‘xgettext’の引数として
認識されて、無効な可変補間かどうかをチェックされますそのため、
hash-dereferencingの$記号は、parserによって“invalid interpolation”エラー
となります。

   以下の、正規表現の中のhash lookupの補間は有効です:

     if ($var =~ /$gettext{"the earth"}/) {
        print gettext "Match!\n";
     }
     s/$gettext{"U. S. A."}/$gettext{"U. S. A."} $gettext{"(dial +0)"}/g;

15.5.18.7 カッコを使用すべきとき
................................

   Perlでは、関数の引数を囲うカッコは、ほとんどの場合は任意です。常に
‘xgettext’は、すべての認識されたキーワード(hashおよびhash referencesにた
いするものは除く)を、適切にプロトタイプされた関数の名前とみなし、(願わく
ば)Perl自体がカッコを必要とする場所だけにカッコが必要です。それゆえ、以
下の例の構築例はすべて使用できます:

     print gettext ("Hello World!\n");
     print gettext "Hello World!\n";
     print dgettext ($package => "Hello World!\n");
     print dgettext $package, "Hello World!\n";

     # The "fat comma" => turns the left-hand side argument into a
     # single-quoted string!
     print dgettext smellovision => "Hello World!\n";

     # The following assignment only works with prototyped functions.
     # Otherwise, the functions will act as "greedy" list operators and
     # eat up all following arguments.
     my $anonymous_hash = {
        planet => gettext "earth",
        cakes => ngettext "one cake", "several cakes", $n,
        still => $works,
     };
     # The same without fat comma:
     my $other_hash = {
        'planet', gettext "earth",
        'cakes', ngettext "one cake", "several cakes", $n,
        'still', $works,
     };

     # Parentheses are only significant for the first argument.
     print dngettext 'package', ("one cake", "several cakes", $n), $discarded;

15.5.18.8 長い行を理解するには
..............................

   長いメッセージを必要とすることは、しばしば厄介で読みにくいコーディン
グスタイルを導き出します。Perlは読みにくいコードを記述するのを防ぐいくつ
かのオプションをもっており、‘xgettext’もそれにたいしてベストを尽くします
。これをおこなうにはドット演算子(文字列連結演算子)が手軽でしょう:

     print gettext ("This is a very long"
                    . " message that is still"
                    . " readable, because"
                    . " it is split into"
                    . " multiple lines.\n");

   Perlは、このような文字列定数の断片を、コンパイル時に1つの長い文字列に
結合できるほどにはスマートであり、それは‘xgettext’も同様です。あなたは処
理結果のPOTには1つの長いメッセージしかないことを見出すでしょう。

   将来のPerl 6では、ドット(‘.’)はdereferencing用となり、文字列の結合演
算子として、おそらくアンダースコア(‘_’)が使われることに注意してください
。‘xgettext’では、この新しい文法はまだサポートされていません。

   改行を埋め込むのが問題ない(むしろ望んでいる)場合には、クォートされた
文字列の内側のどこでも改行を挿入できます:

     print gettext ("<em>In HTML output
     embedded newlines are generally no
     problem, since adjacent whitespace
     is always rendered into a single
     space character.</em>");

   ヒアドキュメントの使用を考えるかもしれません:

     print gettext <<EOF;
     <em>In HTML output
     embedded newlines are generally no
     problem, since adjacent whitespace
     is always rendered into a single
     space character.</em>
     EOF

   行は実際に改行されることを忘れないでください(例: これらは改行文字に変
換されて、POTファイル中に出現します)。

15.5.18.9 バグ、落とし穴、動作しない事柄
........................................

   ここまでのセクションでは、Perlのソースから翻訳可能な文字列を抽出点に
おいて、‘xgettext’がとてもスマートであることが証明されました。しかし動作
すると期待されていたエキゾチックな構成物のうちのいくつかは、多かれ少なか
れ動作しません。

   それに関係する制限のうちの1つは、クォートされた文字列内の変数の補間に
関する実装で見つけることができます。クォートされた文字列の場合、単純な
hash lookupしか使うことができません:

     print <<EOF;
     $gettext{"The dot operator"
               . " does not work"
               . "here!"}
     Likewise, you cannot @{[ gettext ("interpolate function calls") ]}
     inside quoted strings or quote-like expressions.
     EOF

   これは有効なPerlのコードであり、実行時には実際に‘gettext’関数を呼び出
します。しかし‘xgettext’のPerl parserは、文字列の認識に失敗します。これ
ほど明確ではない実相の制限は、正規表現の補間で見つけることができます:

     s/<!--START_OF_WEEK-->/gettext ("Sunday")/e;

   修飾子‘e’は、評価可能なステートメントとして解釈して置き換えを行います
。その結果、実行時に‘gettext()’関数が呼び出されまが、この場合もparserは
文字列“Sunday”を抽出することに失敗します。この機能を本当に使いたいならば
、シンプルな回避策は一時的な変数を使うことです:

     my $sunday = gettext "Sunday";
     s/<!--START_OF_WEEK-->/$sunday/;

   hash slicesも手軽ですが、認識されません:

     my @weekdays = @gettext{'Sunday', 'Monday', 'Tuesday', 'Wednesday',
                             'Thursday', 'Friday', 'Saturday'};
     # Or even:
     @weekdays = @gettext{qw (Sunday Monday Tuesday Wednesday Thursday
                              Friday Saturday) };

   これはtied hash %gettextの完全に有効な使い方ですが、文字列は認識され
ないため、抽出もされません。

   現在のバージョンにたいするその他の注意点は、識別子の中の非アスキー文
字にたいするお粗末なサポートがあげられます。’A’-’Z’、’a’-’z’、’0’-’9’、
およびアンダースコアー ’_’ の範囲外の文字を識別子に使った場合、あなたは
深刻な問題に直面するでしょう。

   これらの存在しない機能のうちのいくつかは将来のバージョンで実装される
かもしれませんが、最小限の努力により回避できるものばかりなので、開発の優
先度は低くなっています。

   たちの悪いのは、普通のテキストの中の一部にすでにbraceが含まれているよ
うなbrace format stringsの問題です。たとえば、プログラムの使い方を説明す
る文字列は、プログラムの中で普通に出会うものです:

     die "usage: $0 {OPTIONS} FILENAME...\n";

   このPerlのbrace format stringsを含んだコードをインターナショナライズ
しようとすると、問題が起きます:

     die __x ("usage: {program} {OPTIONS} FILENAME...\n", program => $0);

   ‘{program}’はplaceholderです。一方‘{OPTIONS}’はplaceholderではなく、
おそらく翻訳される必要があります。しかし最初のものを認識して、他のものを
そのままにしておくように‘xgettext’のPerl parserに教える術はありません。

   この問題を回避するためには2つの方法が考えられます。プログラムが
(‘printf()’で位置パラメーターを扱える)Perl 5.8.0以降で実行されることがわ
かっている場合か、翻訳者が引数の順番を変える必要がないことがわかっている
場合 – たとえば文字列に1つしかbraceのplaceholderがない場合や、上記の例の
ように構文を説明するためのものの場合 – 文字列をno-perl-brace-formatとマ
ークして‘printf()’を使うことができます:

     # xgettext: no-perl-brace-format
     die sprintf ("usage: %s {OPTIONS} FILENAME...\n", $0);

   もっと可搬性のあるPerlのbrace formatを使いたいときは、placeholdersを
リテラルのbracesの中に配置します:

     die __x ("usage: {program} {[}OPTIONS{]} FILENAME...\n",
              program => $0, '[' => '{', ']' => '}');

   Perlのbrace を使った書式文字列は、エスケープするための仕組みを知りま
せん。このエスケープするための仕組みがどのようなものであれ、これはプログ
ラマーに困難な時をもたらし、Perlのbrace を使った書式文字列の翻訳を困難に
するか、format命令が実行されるときの実行時の性能を劣化させるでしょう。こ
のような特別なケースでは、‘printf()’のために幸せな時間のほとんどを費やす
ことになります。

15.5.19 PHP ハイパーテキストプリプロセッサー
--------------------------------------------

RPM
     mod_php4、mod_php4-core、phpdoc

ファイル拡張子
     ‘php’、‘php3’、‘php4’

文字列構文
     ‘"abc"’、‘'abc'’

gettextの略記
     ‘_("abc")’

gettext/ngettext関数
     ‘gettext’、‘dgettext’、‘dcgettext’
     PHP 4.2.0からは‘ngettext’、‘dngettext’、‘dcngettext’

textdomain
     ‘textdomain’関数

bindtextdomain
     ‘bindtextdomain’関数

setlocale
     プログラマーは、‘setlocale (LC_ALL, "")’を呼び出さなければなりませ
     ん。

必要条件
     —

GNU gettextの使用またはエミュレート
     使用

抽出プログラム
     ‘xgettext’

位置の書式
     ‘printf "%2\$d %1\$d"’

可搬性
     gettextのないプラットフォームでは、上記の関数は利用できません。

po-modeでのマーキング
     —

   ‘examples’ディレクトリーの、例‘hello-php’が利用できます

15.5.20 Pike
------------

RPM
     roxen

ファイル拡張子
     ‘pike’

文字列構文
     ‘"abc"’

gettextの略記
     —

gettext/ngettext関数
     ‘gettext’、‘dgettext’、‘dcgettext’

textdomain
     ‘textdomain’関数

bindtextdomain
     ‘bindtextdomain’関数

setlocale
     ‘setlocale’ function

必要条件
     ‘import Locale.Gettext;’

GNU gettextの使用またはエミュレート
     使用

抽出プログラム
     —

位置の書式
     —

可搬性
     gettextのないプラットフォームでは、上記の関数は利用できません。

po-modeでのマーキング
     —

15.5.21 GNU Compiler Collectionソース
-------------------------------------

RPM
     gcc

ファイル拡張子
     ‘c’、‘h’

文字列構文
     ‘"abc"’

gettextの略記
     ‘_("abc")’

gettext/ngettext関数
     ‘gettext’、‘dgettext’、‘dcgettext’、‘ngettext’、‘dngettext’、
     ‘dcngettext’

textdomain
     ‘textdomain’関数

bindtextdomain
     ‘bindtextdomain’関数

setlocale
     プログラマーは、‘setlocale (LC_ALL, "")’を呼び出さなければなりませ
     ん。

必要条件
     ‘#include "intl.h"’

GNU gettextの使用またはエミュレート
     使用

抽出プログラム
     ‘xgettext -k_’

位置の書式
     —

可搬性
     autoconfマクロを使用します

po-modeでのマーキング
     yes

15.5.22 Lua
-----------

RPM
     lua

ファイル拡張子
     ‘lua’

文字列構文

        • ‘"abc"’

        • ‘'abc'’

        • ‘[[abc]]’

        • ‘[=[abc]=]’

        • ‘[==[abc]==]’

        • ...

gettextの略記
     ‘_("abc")’

gettext/ngettext関数
     ‘gettext.gettext’、‘gettext.dgettext’、‘gettext.dcgettext’、
     ‘gettext.ngettext’、‘gettext.dngettext’、‘gettext.dcngettext’

textdomain
     ‘textdomain’関数

bindtextdomain
     ‘bindtextdomain’関数

setlocale
     自動

必要条件
     ‘require 'gettext'’、または‘-l gettext’オプションでluaインタープリ
     ターを実行

GNU gettextの使用またはエミュレート
     使用

抽出プログラム
     ‘xgettext’

位置の書式
     —

可搬性
     gettextのないプラットフォームでは、上記の関数は利用できません。

po-modeでのマーキング
     —

15.5.23 Java Script
-------------------

RPM
     js

ファイル拡張子
     ‘js’

文字列構文

        • ‘"abc"’

        • ‘'abc'’

gettextの略記
     ‘_("abc")’

gettext/ngettext関数
     ‘gettext’、‘dgettext’、‘dcgettext’、‘ngettext’、‘dngettext’

textdomain
     ‘textdomain’関数

bindtextdomain
     ‘bindtextdomain’関数

setlocale
     自動

必要条件
     —

GNU gettextの使用またはエミュレート
     使用、またはエミュレート

抽出プログラム
     ‘xgettext’

位置の書式
     —

可搬性
     gettextのないプラットフォームでは、上記の関数は利用できません。

po-modeでのマーキング
     —

15.6 インターナショナライズ可能なデータ
=======================================

   以下は、GNU gettextを使用してインターナショナライズできる、その他のデ
ータ型のリストです。

15.6.1 POT - Portable Object Template
-------------------------------------

RPM
     gettext

ファイル拡張子
     ‘pot’、‘po’

抽出プログラム
     ‘xgettext’

15.6.2 Resource String Table
----------------------------

RPM
     fpk

ファイル拡張子
     ‘rst’

抽出プログラム
     ‘xgettext’、‘rstconv’

15.6.3 Glade - GNOME user interface description
-----------------------------------------------

RPM
     glade、libglade、glade2、libglade2、intltool

ファイル拡張子
     ‘glade’、‘glade2’、‘ui’

抽出プログラム
     ‘xgettext’、‘libglade-xgettext’、‘xml-i18n-extract’、
     ‘intltool-extract’

16 結びの言葉
*************

   そして最後に、Native Language Supportに関してもっと研究したり読みたい
人のために、いくつかの指標を示してGNU ‘gettext’のマニュアルを結びたいと
思います。

16.1 GNU ‘gettext’の歴史
========================

   国際対応の重要性やアルゴリズムは、非公式にではありますがが毎日のよう
に数年に渡ってGNUで論議されてきました。ときにはGNU ‘libc’に関係して、あ
るときは‘Hurd’に関係して、あるいはその他のものに関係してです(誰もはっき
り とは覚えていません)。そしてそれから作業は実際に始まりましたが、これは
先だっての議論とは独立したものでした。

   全ては、Patrick D’CruzeがGNU ‘fileutils’バージョン3.9.2の国際対応につ
いてのアイディアそして主導権を得たとき、つまり1994年の7月に始まりました
。彼はそれから保守担当者であるJim Meyeringに、国際対応に関する変更をどの
ようにして正式リリースに含めるかについて尋ねました。最初のドラフトは
‘#ifdef’の塊で面食らうような代物でしたので、Jimはもっと良い方法を求め て
いました。PatrickとJimはこの分野においての試みや経験を共有していました。
そして、結局のところこの作業はGNUに大きなインパクトを与えると感じたので
、 Jimは標準がどのようなものであるかを知りたくなり、そして彼はRichard
Stallmanにコンタクトを取りました。Richardはその時点で、‘glocale’となるコ
ード全体のデザインについて非常に手早くかつ丁寧に記述しました。

   Jimは‘glocale’を実装し、PatrickやRichardから多くのフィードバックを受
けました。もちろん、Mitchum DSouza(‘catgets’のようなパッケージを記述した
)やRoland McGrath,またDavid MacKenzieやPinard、Paul Eggertらからのフィー
ドバックもありました。様々な方向性が入り乱れ、しかもそれら全てに互換性が
あるというわけではなかったため、二、三のテストリリー スの後、‘glocale’は
破棄されました。

   Jimがある程度距離と時間をおき、そして二人目のパパになった間に、
Rolandは GNU ‘libc’を国際対応させたいと望んでおり、Ulrich Drepperがその
プロジェ クトに加わりました。‘glocale’から作業を始める代わりに、Ulrichは
一からコードを書き直しましたが、それは‘glocale’の作業で明らかになったガ
イドラインにより一層従う形になっていました。それからUlrichは以前のフォー
ラムから新しいプロジェクト用に人員を獲得し、‘glocale’をまず‘msgutils’と
改称しました。それは後に‘nlsutils’という名前になり、さらに‘gettext’とい
う名称になりました。これは1995年5月頃にRichardによって公式に受諾されまし
た。

   Ulrich Drepperが1995年の四月にGNU ‘gettext’で書いたことに言及してまと
めとしようかと思います。POモードを含んだパッケージの最初の公式リリースは
1995年の7月に行われ、そのバージョン番号は0.7でした。その他の人々は
Ulrichの回りの議論フォーラムで作成された、小さなコードのかけらやテストの
結 果といった諸々のものを寄贈しました。彼らの名前はGNU ‘gettext’に付随す
る‘THANKS’ファイルに納められました。

   この作業が進んでいた間、Françoisは最初に半ダースのGNUパッケージに
‘glocale’を、続いて‘gettext’を現在のように適用してプリテストの状態にし、
進化するツールを微調整するための効果的なユーザ環境を準備しました。 彼は
また、翻訳プロジェクトを組織化し統合する責任をも引き受けました。 Patrick
D’Cruzeは多くのネイティブランゲージのための20の非モデレートなメーリング
リスト、そして二つのモデレートされたリスト(一つは全てのチームに直ちに届
くもの、もう一つは国際化されたフリーソフトウェアパッケージの全ての自発的
な管理者に連絡するためのもの)を作成し管理しました。そしてほぼ一年の間に
多くの国々の人々の間で非公式な情報交換が行われ、翻訳者チームが1995年5月
に 発足しました。

   FrançoisはまたGreg McGaryの協力を受け、1995年の六月にPOモードを書きあ
げています。これはUlrichのパッケージに寄贈されました。彼はまたGNU
‘gettext’のTexinfoマニュアルも寄贈しています。

   1997年に、Ulrich DrepperはGNU libc 2.0をリリースし、これには関数
‘gettext’、‘textdomain’、‘bindtextdomain’が含まれていました。

   2000年に、Ulrich Drepperはplural form処理(‘ngettext’関数)をGNU libcに
追加しました。その後2001年、彼はGNU libc 2.2.xをリリースし、これには完全
なインターナショナリゼーションをもつ、最初のフリーなCライブラリーでした
。

   GNU libcのGeneral Maintainerとしての役割によりUlrichは極めて多忙にな
ったため、2000年にGNU gettextのメンテナンスをBruno Haibleに譲り渡しまし
た。Brunoもツールにplural form処理を追加し、UTF-8とCJK localeのサポート
の追加、およびPOファイルを取り扱うための新しいツールをいくつか記述しまし
た。

16.2 参考文献
=============

   *注意: *このセクションの文書は時代遅れになっているので、改訂する必要
があります。

   Eugene H. Dorr(‘dorre@well.com’)は‘Internationalization Reference
List’という国際化対応に関する興味深い文献の保守を行っています。 これは次
の場所で入手可能です。
     ftp://ftp.ora.com/pub/examples/nutshell/ujip/doc/i18n-books.txt

   Michael Gschwind(‘mike@vlsivie.tuwien.ac.at’)はProgramming for
Internationalisationというタイトルの「良くある質問」(Frequently Asked
Questions (FAQ))のリストを保守しています。このFAQは異なる言語慣習、 キャ
ラクタセットなどを扱うことが可能なプログラムの記述について論じています。
そしてこれは、特にUsenet: ISO 8859-1及び全てのキャラクタセットエンコーデ
ィング に対して適用できます。これは‘comp.unix.questions’、
‘comp.std.internat’、‘comp.software.international’、‘comp.lang.c’、
‘comp.windows.x’、‘comp.std.c’、‘comp.answers’、‘news.answers’から定期的
に公布されています。この文書は以下にあります:
     ftp://ftp.vlsivie.tuwien.ac.at/pub/8bit/ISO-programming

   Patrick D’Cruze(‘pdcruze@li.org’)はNLSに関するチュートリアルを書きま
した。そしてJochen Hein(‘Hein@student.tu-clausthal.de’)はそれに関する保
守作業を引き継ぎました。この文書は次の場所にあります。
     ftp://sunsite.unc.edu/pub/Linux/utils/nls/catalogs/Incoming/...
          ...locale-tutorial-0.8.txt.gz
このサイトは以下のサイトへミラーリングされています。
     ftp://ftp.ibp.fr/pub/linux/sunsite/

   同じチュートリアルのフランス語版は以下にあります。
     ftp://ftp.ibp.fr/pub/linux/french/docs/
ここには、フランス語に訳されたLinux関係のドキュメントもあります。

Appendix A Language Codes
*************************

   ISO 639は多くの言語に対して2文字のコード、より珍しい言語に対して3文字
のコードを規定しています。翻訳プロジェクトが言語に対して使用している省略
形には、この標準が採用されています。

A.1 Usual Language Codes
========================

   一般的に使用される言語にたいしては、ISO 639-1標準が2文字のコードを定
義しています。

‘aa’
     Afar.
‘ab’
     Abkhazian.
‘ae’
     Avestan.
‘af’
     Afrikaans.
‘ak’
     Akan.
‘am’
     Amharic.
‘an’
     Aragonese.
‘ar’
     Arabic.
‘as’
     Assamese.
‘av’
     Avaric.
‘ay’
     Aymara.
‘az’
     Azerbaijani.
‘ba’
     Bashkir.
‘be’
     Belarusian.
‘bg’
     Bulgarian.
‘bh’
     Bihari.
‘bi’
     Bislama.
‘bm’
     Bambara.
‘bn’
     Bengali; Bangla.
‘bo’
     Tibetan.
‘br’
     Breton.
‘bs’
     Bosnian.
‘ca’
     Catalan.
‘ce’
     Chechen.
‘ch’
     Chamorro.
‘co’
     Corsican.
‘cr’
     Cree.
‘cs’
     Czech.
‘cu’
     Church Slavic.
‘cv’
     Chuvash.
‘cy’
     Welsh.
‘da’
     Danish.
‘de’
     German.
‘dv’
     Divehi; Maldivian.
‘dz’
     Dzongkha; Bhutani.
‘ee’
     Éwé.
‘el’
     Greek.
‘en’
     English.
‘eo’
     Esperanto.
‘es’
     Spanish.
‘et’
     Estonian.
‘eu’
     Basque.
‘fa’
     Persian.
‘ff’
     Fulah.
‘fi’
     Finnish.
‘fj’
     Fijian; Fiji.
‘fo’
     Faroese.
‘fr’
     French.
‘fy’
     Western Frisian.
‘ga’
     Irish.
‘gd’
     Scottish Gaelic.
‘gl’
     Galician.
‘gn’
     Guarani.
‘gu’
     Gujarati.
‘gv’
     Manx.
‘ha’
     Hausa.
‘he’
     Hebrew (formerly iw).
‘hi’
     Hindi.
‘ho’
     Hiri Motu.
‘hr’
     Croatian.
‘ht’
     Haitian; Haitian Creole.
‘hu’
     Hungarian.
‘hy’
     Armenian.
‘hz’
     Herero.
‘ia’
     Interlingua.
‘id’
     Indonesian (formerly in).
‘ie’
     Interlingue; Occidental.
‘ig’
     Igbo.
‘ii’
     Sichuan Yi; Nuosu.
‘ik’
     Inupiak; Inupiaq.
‘io’
     Ido.
‘is’
     Icelandic.
‘it’
     Italian.
‘iu’
     Inuktitut.
‘ja’
     Japanese.
‘jv’
     Javanese.
‘ka’
     Georgian.
‘kg’
     Kongo.
‘ki’
     Kikuyu; Gikuyu.
‘kj’
     Kuanyama; Kwanyama.
‘kk’
     Kazakh.
‘kl’
     Kalaallisut; Greenlandic.
‘km’
     Central Khmer; Cambodian.
‘kn’
     Kannada.
‘ko’
     Korean.
‘kr’
     Kanuri.
‘ks’
     Kashmiri.
‘ku’
     Kurdish.
‘kv’
     Komi.
‘kw’
     Cornish.
‘ky’
     Kirghiz.
‘la’
     Latin.
‘lb’
     Letzeburgesch; Luxembourgish.
‘lg’
     Ganda.
‘li’
     Limburgish; Limburger; Limburgan.
‘ln’
     Lingala.
‘lo’
     Lao; Laotian.
‘lt’
     Lithuanian.
‘lu’
     Luba-Katanga.
‘lv’
     Latvian; Lettish.
‘mg’
     Malagasy.
‘mh’
     Marshallese.
‘mi’
     Maori.
‘mk’
     Macedonian.
‘ml’
     Malayalam.
‘mn’
     Mongolian.
‘mo’
     Moldavian.
‘mr’
     Marathi.
‘ms’
     Malay.
‘mt’
     Maltese.
‘my’
     Burmese.
‘na’
     Nauru.
‘nb’
     Norwegian Bokmål.
‘nd’
     Ndebele, North.
‘ne’
     Nepali.
‘ng’
     Ndonga.
‘nl’
     Dutch.
‘nn’
     Norwegian Nynorsk.
‘no’
     Norwegian.
‘nr’
     Ndebele, South.
‘nv’
     Navajo; Navaho.
‘ny’
     Chichewa; Nyanja.
‘oc’
     Occitan; Provençal.
‘oj’
     Ojibwa.
‘om’
     (Afan) Oromo.
‘or’
     Oriya.
‘os’
     Ossetian; Ossetic.
‘pa’
     Panjabi; Punjabi.
‘pi’
     Pali.
‘pl’
     Polish.
‘ps’
     Pashto; Pushto.
‘pt’
     Portuguese.
‘qu’
     Quechua.
‘rm’
     Romansh.
‘rn’
     Rundi; Kirundi.
‘ro’
     Romanian.
‘ru’
     Russian.
‘rw’
     Kinyarwanda.
‘sa’
     Sanskrit.
‘sc’
     Sardinian.
‘sd’
     Sindhi.
‘se’
     Northern Sami.
‘sg’
     Sango; Sangro.
‘si’
     Sinhala; Sinhalese.
‘sk’
     Slovak.
‘sl’
     Slovenian.
‘sm’
     Samoan.
‘sn’
     Shona.
‘so’
     Somali.
‘sq’
     Albanian.
‘sr’
     Serbian.
‘ss’
     Swati; Siswati.
‘st’
     Sesotho; Sotho, Southern.
‘su’
     Sundanese.
‘sv’
     Swedish.
‘sw’
     Swahili.
‘ta’
     Tamil.
‘te’
     Telugu.
‘tg’
     Tajik.
‘th’
     Thai.
‘ti’
     Tigrinya.
‘tk’
     Turkmen.
‘tl’
     Tagalog.
‘tn’
     Tswana; Setswana.
‘to’
     Tonga.
‘tr’
     Turkish.
‘ts’
     Tsonga.
‘tt’
     Tatar.
‘tw’
     Twi.
‘ty’
     Tahitian.
‘ug’
     Uighur.
‘uk’
     Ukrainian.
‘ur’
     Urdu.
‘uz’
     Uzbek.
‘ve’
     Venda.
‘vi’
     Vietnamese.
‘vo’
     Volapük; Volapuk.
‘wa’
     Walloon.
‘wo’
     Wolof.
‘xh’
     Xhosa.
‘yi’
     Yiddish (formerly ji).
‘yo’
     Yoruba.
‘za’
     Zhuang.
‘zh’
     Chinese.
‘zu’
     Zulu.

A.2 Rare Language Codes
=======================

   より珍しい言語にたいしては、ISO 639-2が3文字のコードを定義しています
。以下は、その言語を話す人が少なくとも100万人いるおうな、生きている言語
だけに絞り込んだリストです。

‘ace’
     Achinese.
‘awa’
     Awadhi.
‘bal’
     Baluchi.
‘ban’
     Balinese.
‘bej’
     Beja; Bedawiyet.
‘bem’
     Bemba.
‘bho’
     Bhojpuri.
‘bik’
     Bikol.
‘bin’
     Bini; Edo.
‘bug’
     Buginese.
‘ceb’
     Cebuano.
‘din’
     Dinka.
‘doi’
     Dogri.
‘fil’
     Filipino; Pilipino.
‘fon’
     Fon.
‘gon’
     Gondi.
‘gsw’
     Swiss German; Alemannic; Alsatian.
‘hil’
     Hiligaynon.
‘hmn’
     Hmong.
‘ilo’
     Iloko.
‘kab’
     Kabyle.
‘kam’
     Kamba.
‘kbd’
     Kabardian.
‘kmb’
     Kimbundu.
‘kok’
     Konkani.
‘kru’
     Kurukh.
‘lua’
     Luba-Lulua.
‘luo’
     Luo (Kenya and Tanzania).
‘mad’
     Madurese.
‘mag’
     Magahi.
‘mai’
     Maithili.
‘mak’
     Makasar.
‘man’
     Mandingo.
‘men’
     Mende.
‘min’
     Minangkabau.
‘mni’
     Manipuri.
‘mos’
     Mossi.
‘mwr’
     Marwari.
‘nap’
     Neapolitan.
‘nso’
     Pedi; Sepedi; Northern Sotho.
‘nym’
     Nyamwezi.
‘nyn’
     Nyankole.
‘pag’
     Pangasinan.
‘pam’
     Pampanga; Kapampangan.
‘raj’
     Rajasthani.
‘sas’
     Sasak.
‘sat’
     Santali.
‘scn’
     Sicilian.
‘shn’
     Shan.
‘sid’
     Sidamo.
‘srr’
     Serer.
‘suk’
     Sukuma.
‘sus’
     Susu.
‘tem’
     Timne.
‘tiv’
     Tiv.
‘tum’
     Tumbuka.
‘umb’
     Umbundu.
‘wal’
     Walamo.
‘war’
     Waray.
‘yao’
     Yao.

Appendix B Country Codes
************************

   ISO 3166標準は、多くの国と地域に対して、2文字のコードを定義します。
Translation Project内で使用される国にたいする略記は、この標準が由来です
。

‘AD’
     Andorra.
‘AE’
     United Arab Emirates.
‘AF’
     Afghanistan.
‘AG’
     Antigua and Barbuda.
‘AI’
     Anguilla.
‘AL’
     Albania.
‘AM’
     Armenia.
‘AN’
     Netherlands Antilles.
‘AO’
     Angola.
‘AQ’
     Antarctica.
‘AR’
     Argentina.
‘AS’
     Samoa (American).
‘AT’
     Austria.
‘AU’
     Australia.
‘AW’
     Aruba.
‘AX’
     Aaland Islands.
‘AZ’
     Azerbaijan.
‘BA’
     Bosnia and Herzegovina.
‘BB’
     Barbados.
‘BD’
     Bangladesh.
‘BE’
     Belgium.
‘BF’
     Burkina Faso.
‘BG’
     Bulgaria.
‘BH’
     Bahrain.
‘BI’
     Burundi.
‘BJ’
     Benin.
‘BM’
     Bermuda.
‘BN’
     Brunei.
‘BO’
     Bolivia.
‘BR’
     Brazil.
‘BS’
     Bahamas.
‘BT’
     Bhutan.
‘BV’
     Bouvet Island.
‘BW’
     Botswana.
‘BY’
     Belarus.
‘BZ’
     Belize.
‘CA’
     Canada.
‘CC’
     Cocos (Keeling) Islands.
‘CD’
     Congo (Dem.  Rep.).
‘CF’
     Central African Republic.
‘CG’
     Congo (Rep.).
‘CH’
     Switzerland.
‘CI’
     Côte d’Ivoire.
‘CK’
     Cook Islands.
‘CL’
     Chile.
‘CM’
     Cameroon.
‘CN’
     China.
‘CO’
     Colombia.
‘CR’
     Costa Rica.
‘CU’
     Cuba.
‘CV’
     Cape Verde.
‘CX’
     Christmas Island.
‘CY’
     Cyprus.
‘CZ’
     Czech Republic.
‘DE’
     Germany.
‘DJ’
     Djibouti.
‘DK’
     Denmark.
‘DM’
     Dominica.
‘DO’
     Dominican Republic.
‘DZ’
     Algeria.
‘EC’
     Ecuador.
‘EE’
     Estonia.
‘EG’
     Egypt.
‘EH’
     Western Sahara.
‘ER’
     Eritrea.
‘ES’
     Spain.
‘ET’
     Ethiopia.
‘FI’
     Finland.
‘FJ’
     Fiji.
‘FK’
     Falkland Islands.
‘FM’
     Micronesia.
‘FO’
     Faeroe Islands.
‘FR’
     France.
‘GA’
     Gabon.
‘GB’
     Britain (United Kingdom).
‘GD’
     Grenada.
‘GE’
     Georgia.
‘GF’
     French Guiana.
‘GG’
     Guernsey.
‘GH’
     Ghana.
‘GI’
     Gibraltar.
‘GL’
     Greenland.
‘GM’
     Gambia.
‘GN’
     Guinea.
‘GP’
     Guadeloupe.
‘GQ’
     Equatorial Guinea.
‘GR’
     Greece.
‘GS’
     South Georgia and the South Sandwich Islands.
‘GT’
     Guatemala.
‘GU’
     Guam.
‘GW’
     Guinea-Bissau.
‘GY’
     Guyana.
‘HK’
     Hong Kong.
‘HM’
     Heard Island and McDonald Islands.
‘HN’
     Honduras.
‘HR’
     Croatia.
‘HT’
     Haiti.
‘HU’
     Hungary.
‘ID’
     Indonesia.
‘IE’
     Ireland.
‘IL’
     Israel.
‘IM’
     Isle of Man.
‘IN’
     India.
‘IO’
     British Indian Ocean Territory.
‘IQ’
     Iraq.
‘IR’
     Iran.
‘IS’
     Iceland.
‘IT’
     Italy.
‘JE’
     Jersey.
‘JM’
     Jamaica.
‘JO’
     Jordan.
‘JP’
     Japan.
‘KE’
     Kenya.
‘KG’
     Kyrgyzstan.
‘KH’
     Cambodia.
‘KI’
     Kiribati.
‘KM’
     Comoros.
‘KN’
     St Kitts and Nevis.
‘KP’
     Korea (North).
‘KR’
     Korea (South).
‘KW’
     Kuwait.
‘KY’
     Cayman Islands.
‘KZ’
     Kazakhstan.
‘LA’
     Laos.
‘LB’
     Lebanon.
‘LC’
     St Lucia.
‘LI’
     Liechtenstein.
‘LK’
     Sri Lanka.
‘LR’
     Liberia.
‘LS’
     Lesotho.
‘LT’
     Lithuania.
‘LU’
     Luxembourg.
‘LV’
     Latvia.
‘LY’
     Libya.
‘MA’
     Morocco.
‘MC’
     Monaco.
‘MD’
     Moldova.
‘ME’
     Montenegro.
‘MG’
     Madagascar.
‘MH’
     Marshall Islands.
‘MK’
     Macedonia.
‘ML’
     Mali.
‘MM’
     Myanmar (Burma).
‘MN’
     Mongolia.
‘MO’
     Macao.
‘MP’
     Northern Mariana Islands.
‘MQ’
     Martinique.
‘MR’
     Mauritania.
‘MS’
     Montserrat.
‘MT’
     Malta.
‘MU’
     Mauritius.
‘MV’
     Maldives.
‘MW’
     Malawi.
‘MX’
     Mexico.
‘MY’
     Malaysia.
‘MZ’
     Mozambique.
‘NA’
     Namibia.
‘NC’
     New Caledonia.
‘NE’
     Niger.
‘NF’
     Norfolk Island.
‘NG’
     Nigeria.
‘NI’
     Nicaragua.
‘NL’
     Netherlands.
‘NO’
     Norway.
‘NP’
     Nepal.
‘NR’
     Nauru.
‘NU’
     Niue.
‘NZ’
     New Zealand.
‘OM’
     Oman.
‘PA’
     Panama.
‘PE’
     Peru.
‘PF’
     French Polynesia.
‘PG’
     Papua New Guinea.
‘PH’
     Philippines.
‘PK’
     Pakistan.
‘PL’
     Poland.
‘PM’
     St Pierre and Miquelon.
‘PN’
     Pitcairn.
‘PR’
     Puerto Rico.
‘PS’
     Palestine.
‘PT’
     Portugal.
‘PW’
     Palau.
‘PY’
     Paraguay.
‘QA’
     Qatar.
‘RE’
     Reunion.
‘RO’
     Romania.
‘RS’
     Serbia.
‘RU’
     Russia.
‘RW’
     Rwanda.
‘SA’
     Saudi Arabia.
‘SB’
     Solomon Islands.
‘SC’
     Seychelles.
‘SD’
     Sudan.
‘SE’
     Sweden.
‘SG’
     Singapore.
‘SH’
     St Helena.
‘SI’
     Slovenia.
‘SJ’
     Svalbard and Jan Mayen.
‘SK’
     Slovakia.
‘SL’
     Sierra Leone.
‘SM’
     San Marino.
‘SN’
     Senegal.
‘SO’
     Somalia.
‘SR’
     Suriname.
‘ST’
     Sao Tome and Principe.
‘SV’
     El Salvador.
‘SY’
     Syria.
‘SZ’
     Swaziland.
‘TC’
     Turks and Caicos Islands.
‘TD’
     Chad.
‘TF’
     French Southern and Antarctic Lands.
‘TG’
     Togo.
‘TH’
     Thailand.
‘TJ’
     Tajikistan.
‘TK’
     Tokelau.
‘TL’
     Timor-Leste.
‘TM’
     Turkmenistan.
‘TN’
     Tunisia.
‘TO’
     Tonga.
‘TR’
     Turkey.
‘TT’
     Trinidad and Tobago.
‘TV’
     Tuvalu.
‘TW’
     Taiwan.
‘TZ’
     Tanzania.
‘UA’
     Ukraine.
‘UG’
     Uganda.
‘UM’
     US minor outlying islands.
‘US’
     United States.
‘UY’
     Uruguay.
‘UZ’
     Uzbekistan.
‘VA’
     Vatican City.
‘VC’
     St Vincent and the Grenadines.
‘VE’
     Venezuela.
‘VG’
     Virgin Islands (UK).
‘VI’
     Virgin Islands (US).
‘VN’
     Vietnam.
‘VU’
     Vanuatu.
‘WF’
     Wallis and Futuna.
‘WS’
     Samoa (Western).
‘YE’
     Yemen.
‘YT’
     Mayotte.
‘ZA’
     South Africa.
‘ZM’
     Zambia.
‘ZW’
     Zimbabwe.

Appendix C Licenses
*******************

   このパッケージのファイルは、特定のファイルやディレクトリーに示された
ライセンスにより保護されます。以下はサマリーです:

   • ‘libintl’および‘libasprintf’ライブラリーは、GNU Lesser General
     Public License(LGPL)で保護されます、このライセンスのコピーは
     GNU LGPLに含まれます。

   • このパッケージの実行可能ファイルおよび‘libgettextpo’ライブラリーは
     、GNU General Public License(GPL)により保護されます。このライセンス
     のコピーはGNU GPLに含まれます。

   • This manual is free documentation.  It is dually licensed under the
     GNU FDL and the GNU GPL. This means that you can redistribute this
     manual under either of these two licenses, at your choice.
     This manual is covered by the GNU FDL. Permission is granted to
     copy, distribute and/or modify this document under the terms of the
     GNU Free Documentation License (FDL), either version 1.2 of the
     License, or (at your option) any later version published by the
     Free Software Foundation (FSF); with no Invariant Sections, with no
     Front-Cover Text, and with no Back-Cover Texts.  A copy of the
     license is included in GNU FDL.
     This manual is covered by the GNU GPL. You can redistribute it
     and/or modify it under the terms of the GNU General Public License
     (GPL), either version 2 of the License, or (at your option) any
     later version published by the Free Software Foundation (FSF). A
     copy of the license is included in GNU GPL.

C.1 GNU GENERAL PUBLIC LICENSE
==============================

                         Version 2, June 1991

     Copyright © 1989, 1991 Free Software Foundation, Inc.
     51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA

     Everyone is permitted to copy and distribute verbatim copies
     of this license document, but changing it is not allowed.

Preamble
--------

   The licenses for most software are designed to take away your freedom
to share and change it.  By contrast, the GNU General Public License is
intended to guarantee your freedom to share and change free software—to
make sure the software is free for all its users.  This General Public
License applies to most of the Free Software Foundation’s software and
to any other program whose authors commit to using it.  (Some other Free
Software Foundation software is covered by the GNU Library General
Public License instead.)  You can apply it to your programs, too.

   When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it if
you want it, that you can change the software or use pieces of it in new
free programs; and that you know you can do these things.

   To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.

   For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have.  You must make sure that they, too, receive or can get the
source code.  And you must show them these terms so they know their
rights.

   We protect your rights with two steps: (1) copyright the software,
and (2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.

   Also, for each author’s protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software.  If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors’ reputations.

   Finally, any free program is threatened constantly by software
patents.  We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary.  To prevent this, we have made it clear that any
patent must be licensed for everyone’s free use or not licensed at all.

   The precise terms and conditions for copying, distribution and
modification follow.

    TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  0. This License applies to any program or other work which contains a
     notice placed by the copyright holder saying it may be distributed
     under the terms of this General Public License.  The “Program”,
     below, refers to any such program or work, and a “work based on the
     Program” means either the Program or any derivative work under
     copyright law: that is to say, a work containing the Program or a
     portion of it, either verbatim or with modifications and/or
     translated into another language.  (Hereinafter, translation is
     included without limitation in the term “modification”.)  Each
     licensee is addressed as “you”.

     Activities other than copying, distribution and modification are
     not covered by this License; they are outside its scope.  The act
     of running the Program is not restricted, and the output from the
     Program is covered only if its contents constitute a work based on
     the Program (independent of having been made by running the
     Program).  Whether that is true depends on what the Program does.

  1. You may copy and distribute verbatim copies of the Program’s source
     code as you receive it, in any medium, provided that you
     conspicuously and appropriately publish on each copy an appropriate
     copyright notice and disclaimer of warranty; keep intact all the
     notices that refer to this License and to the absence of any
     warranty; and give any other recipients of the Program a copy of
     this License along with the Program.

     You may charge a fee for the physical act of transferring a copy,
     and you may at your option offer warranty protection in exchange
     for a fee.

  2. You may modify your copy or copies of the Program or any portion of
     it, thus forming a work based on the Program, and copy and
     distribute such modifications or work under the terms of Section 1
     above, provided that you also meet all of these conditions:

       a. You must cause the modified files to carry prominent notices
          stating that you changed the files and the date of any change.

       b. You must cause any work that you distribute or publish, that
          in whole or in part contains or is derived from the Program or
          any part thereof, to be licensed as a whole at no charge to
          all third parties under the terms of this License.

       c. If the modified program normally reads commands interactively
          when run, you must cause it, when started running for such
          interactive use in the most ordinary way, to print or display
          an announcement including an appropriate copyright notice and
          a notice that there is no warranty (or else, saying that you
          provide a warranty) and that users may redistribute the
          program under these conditions, and telling the user how to
          view a copy of this License.  (Exception: if the Program
          itself is interactive but does not normally print such an
          announcement, your work based on the Program is not required
          to print an announcement.)

     These requirements apply to the modified work as a whole.  If
     identifiable sections of that work are not derived from the
     Program, and can be reasonably considered independent and separate
     works in themselves, then this License, and its terms, do not apply
     to those sections when you distribute them as separate works.  But
     when you distribute the same sections as part of a whole which is a
     work based on the Program, the distribution of the whole must be on
     the terms of this License, whose permissions for other licensees
     extend to the entire whole, and thus to each and every part
     regardless of who wrote it.

     Thus, it is not the intent of this section to claim rights or
     contest your rights to work written entirely by you; rather, the
     intent is to exercise the right to control the distribution of
     derivative or collective works based on the Program.

     In addition, mere aggregation of another work not based on the
     Program with the Program (or with a work based on the Program) on a
     volume of a storage or distribution medium does not bring the other
     work under the scope of this License.

  3. You may copy and distribute the Program (or a work based on it,
     under Section 2) in object code or executable form under the terms
     of Sections 1 and 2 above provided that you also do one of the
     following:

       a. Accompany it with the complete corresponding machine-readable
          source code, which must be distributed under the terms of
          Sections 1 and 2 above on a medium customarily used for
          software interchange; or,

       b. Accompany it with a written offer, valid for at least three
          years, to give any third party, for a charge no more than your
          cost of physically performing source distribution, a complete
          machine-readable copy of the corresponding source code, to be
          distributed under the terms of Sections 1 and 2 above on a
          medium customarily used for software interchange; or,

       c. Accompany it with the information you received as to the offer
          to distribute corresponding source code.  (This alternative is
          allowed only for noncommercial distribution and only if you
          received the program in object code or executable form with
          such an offer, in accord with Subsection b above.)

     The source code for a work means the preferred form of the work for
     making modifications to it.  For an executable work, complete
     source code means all the source code for all modules it contains,
     plus any associated interface definition files, plus the scripts
     used to control compilation and installation of the executable.
     However, as a special exception, the source code distributed need
     not include anything that is normally distributed (in either source
     or binary form) with the major components (compiler, kernel, and so
     on) of the operating system on which the executable runs, unless
     that component itself accompanies the executable.

     If distribution of executable or object code is made by offering
     access to copy from a designated place, then offering equivalent
     access to copy the source code from the same place counts as
     distribution of the source code, even though third parties are not
     compelled to copy the source along with the object code.

  4. You may not copy, modify, sublicense, or distribute the Program
     except as expressly provided under this License.  Any attempt
     otherwise to copy, modify, sublicense or distribute the Program is
     void, and will automatically terminate your rights under this
     License.  However, parties who have received copies, or rights,
     from you under this License will not have their licenses terminated
     so long as such parties remain in full compliance.

  5. You are not required to accept this License, since you have not
     signed it.  However, nothing else grants you permission to modify
     or distribute the Program or its derivative works.  These actions
     are prohibited by law if you do not accept this License.
     Therefore, by modifying or distributing the Program (or any work
     based on the Program), you indicate your acceptance of this License
     to do so, and all its terms and conditions for copying,
     distributing or modifying the Program or works based on it.

  6. Each time you redistribute the Program (or any work based on the
     Program), the recipient automatically receives a license from the
     original licensor to copy, distribute or modify the Program subject
     to these terms and conditions.  You may not impose any further
     restrictions on the recipients’ exercise of the rights granted
     herein.  You are not responsible for enforcing compliance by third
     parties to this License.

  7. If, as a consequence of a court judgment or allegation of patent
     infringement or for any other reason (not limited to patent
     issues), conditions are imposed on you (whether by court order,
     agreement or otherwise) that contradict the conditions of this
     License, they do not excuse you from the conditions of this
     License.  If you cannot distribute so as to satisfy simultaneously
     your obligations under this License and any other pertinent
     obligations, then as a consequence you may not distribute the
     Program at all.  For example, if a patent license would not permit
     royalty-free redistribution of the Program by all those who receive
     copies directly or indirectly through you, then the only way you
     could satisfy both it and this License would be to refrain entirely
     from distribution of the Program.

     If any portion of this section is held invalid or unenforceable
     under any particular circumstance, the balance of the section is
     intended to apply and the section as a whole is intended to apply
     in other circumstances.

     It is not the purpose of this section to induce you to infringe any
     patents or other property right claims or to contest validity of
     any such claims; this section has the sole purpose of protecting
     the integrity of the free software distribution system, which is
     implemented by public license practices.  Many people have made
     generous contributions to the wide range of software distributed
     through that system in reliance on consistent application of that
     system; it is up to the author/donor to decide if he or she is
     willing to distribute software through any other system and a
     licensee cannot impose that choice.

     This section is intended to make thoroughly clear what is believed
     to be a consequence of the rest of this License.

  8. If the distribution and/or use of the Program is restricted in
     certain countries either by patents or by copyrighted interfaces,
     the original copyright holder who places the Program under this
     License may add an explicit geographical distribution limitation
     excluding those countries, so that distribution is permitted only
     in or among countries not thus excluded.  In such case, this
     License incorporates the limitation as if written in the body of
     this License.

  9. The Free Software Foundation may publish revised and/or new
     versions of the General Public License from time to time.  Such new
     versions will be similar in spirit to the present version, but may
     differ in detail to address new problems or concerns.

     Each version is given a distinguishing version number.  If the
     Program specifies a version number of this License which applies to
     it and “any later version”, you have the option of following the
     terms and conditions either of that version or of any later version
     published by the Free Software Foundation.  If the Program does not
     specify a version number of this License, you may choose any
     version ever published by the Free Software Foundation.

  10. If you wish to incorporate parts of the Program into other free
     programs whose distribution conditions are different, write to the
     author to ask for permission.  For software which is copyrighted by
     the Free Software Foundation, write to the Free Software
     Foundation; we sometimes make exceptions for this.  Our decision
     will be guided by the two goals of preserving the free status of
     all derivatives of our free software and of promoting the sharing
     and reuse of software generally.

                              NO WARRANTY

  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO
     WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE
     LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS
     AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY
     OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
     PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
     DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR
     OR CORRECTION.

  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
     WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY
     MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE
     LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
     INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
     INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
     DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU
     OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY
     OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN
     ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

                      END OF TERMS AND CONDITIONS

Appendix: How to Apply These Terms to Your New Programs
-------------------------------------------------------

   If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these
terms.

   To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
“copyright” line and a pointer to where the full notice is found.

     ONE LINE TO GIVE THE PROGRAM'S NAME AND A BRIEF IDEA OF WHAT IT DOES.
     Copyright (C) YYYY  NAME OF AUTHOR

     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2 of the License, or
     (at your option) any later version.

     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.

     You should have received a copy of the GNU General Public License
     along with this program; if not, write to the Free Software
     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

   Also add information on how to contact you by electronic and paper
mail.

   If the program is interactive, make it output a short notice like
this when it starts in an interactive mode:

     Gnomovision version 69, Copyright (C) 19YY NAME OF AUTHOR
     Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
     This is free software, and you are welcome to redistribute it
     under certain conditions; type `show c' for details.

   The hypothetical commands ‘show w’ and ‘show c’ should show the
appropriate parts of the General Public License.  Of course, the
commands you use may be called something other than ‘show w’ and ‘show
c’; they could even be mouse-clicks or menu items—whatever suits your
program.

   You should also get your employer (if you work as a programmer) or
your school, if any, to sign a “copyright disclaimer” for the program,
if necessary.  Here is a sample; alter the names:

     Yoyodyne, Inc., hereby disclaims all copyright interest in the program
     `Gnomovision' (which makes passes at compilers) written by James Hacker.

     SIGNATURE OF TY COON, 1 April 1989
     Ty Coon, President of Vice

   This General Public License does not permit incorporating your
program into proprietary programs.  If your program is a subroutine
library, you may consider it more useful to permit linking proprietary
applications with the library.  If this is what you want to do, use the
GNU Library General Public License instead of this License.

C.2 GNU LESSER GENERAL PUBLIC LICENSE
=====================================

                      Version 2.1, February 1999

     Copyright © 1991, 1999 Free Software Foundation, Inc.
     51 Franklin St – Fifth Floor, Boston, MA 02110-1301, USA

     Everyone is permitted to copy and distribute verbatim copies
     of this license document, but changing it is not allowed.

     [This is the first released version of the Lesser GPL.  It also counts
     as the successor of the GNU Library Public License, version 2, hence the
     version number 2.1.]

Preamble
--------

   The licenses for most software are designed to take away your freedom
to share and change it.  By contrast, the GNU General Public Licenses
are intended to guarantee your freedom to share and change free
software—to make sure the software is free for all its users.

   This license, the Lesser General Public License, applies to some
specially designated software—typically libraries—of the Free Software
Foundation and other authors who decide to use it.  You can use it too,
but we suggest you first think carefully about whether this license or
the ordinary General Public License is the better strategy to use in any
particular case, based on the explanations below.

   When we speak of free software, we are referring to freedom of use,
not price.  Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of it
in new free programs; and that you are informed that you can do these
things.

   To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights.  These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.

   For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you.  You must make sure that they, too, receive or can get the source
code.  If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling it.
And you must show them these terms so they know their rights.

   We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.

   To protect each distributor, we want to make it very clear that there
is no warranty for the free library.  Also, if the library is modified
by someone else and passed on, the recipients should know that what they
have is not the original version, so that the original author’s
reputation will not be affected by problems that might be introduced by
others.

   Finally, software patents pose a constant threat to the existence of
any free program.  We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder.  Therefore, we insist that any
patent license obtained for a version of the library must be consistent
with the full freedom of use specified in this license.

   Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License.  This license, the GNU Lesser
General Public License, applies to certain designated libraries, and is
quite different from the ordinary General Public License.  We use this
license for certain libraries in order to permit linking those libraries
into non-free programs.

   When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library.  The ordinary
General Public License therefore permits such linking only if the entire
combination fits its criteria of freedom.  The Lesser General Public
License permits more lax criteria for linking other code with the
library.

   We call this license the “Lesser” General Public License because it
does _Less_ to protect the user’s freedom than the ordinary General
Public License.  It also provides other free software developers Less of
an advantage over competing non-free programs.  These disadvantages are
the reason we use the ordinary General Public License for many
libraries.  However, the Lesser license provides advantages in certain
special circumstances.

   For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it
becomes a de-facto standard.  To achieve this, non-free programs must be
allowed to use the library.  A more frequent case is that a free library
does the same job as widely used non-free libraries.  In this case,
there is little to gain by limiting the free library to free software
only, so we use the Lesser General Public License.

   In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of free
software.  For example, permission to use the GNU C Library in non-free
programs enables many more people to use the whole GNU operating system,
as well as its variant, the GNU/Linux operating system.

   Although the Lesser General Public License is Less protective of the
users’ freedom, it does ensure that the user of a program that is linked
with the Library has the freedom and the wherewithal to run that program
using a modified version of the Library.

   The precise terms and conditions for copying, distribution and
modification follow.  Pay close attention to the difference between a
“work based on the library” and a “work that uses the library”.  The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.

                   GNU LESSER GENERAL PUBLIC LICENSE

    TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  0. This License Agreement applies to any software library or other
     program which contains a notice placed by the copyright holder or
     other authorized party saying it may be distributed under the terms
     of this Lesser General Public License (also called “this License”).
     Each licensee is addressed as “you”.

     A “library” means a collection of software functions and/or data
     prepared so as to be conveniently linked with application programs
     (which use some of those functions and data) to form executables.

     The “Library”, below, refers to any such software library or work
     which has been distributed under these terms.  A “work based on the
     Library” means either the Library or any derivative work under
     copyright law: that is to say, a work containing the Library or a
     portion of it, either verbatim or with modifications and/or
     translated straightforwardly into another language.  (Hereinafter,
     translation is included without limitation in the term
     “modification”.)

     “Source code” for a work means the preferred form of the work for
     making modifications to it.  For a library, complete source code
     means all the source code for all modules it contains, plus any
     associated interface definition files, plus the scripts used to
     control compilation and installation of the library.

     Activities other than copying, distribution and modification are
     not covered by this License; they are outside its scope.  The act
     of running a program using the Library is not restricted, and
     output from such a program is covered only if its contents
     constitute a work based on the Library (independent of the use of
     the Library in a tool for writing it).  Whether that is true
     depends on what the Library does and what the program that uses the
     Library does.

  1. You may copy and distribute verbatim copies of the Library’s
     complete source code as you receive it, in any medium, provided
     that you conspicuously and appropriately publish on each copy an
     appropriate copyright notice and disclaimer of warranty; keep
     intact all the notices that refer to this License and to the
     absence of any warranty; and distribute a copy of this License
     along with the Library.

     You may charge a fee for the physical act of transferring a copy,
     and you may at your option offer warranty protection in exchange
     for a fee.

  2. You may modify your copy or copies of the Library or any portion of
     it, thus forming a work based on the Library, and copy and
     distribute such modifications or work under the terms of Section 1
     above, provided that you also meet all of these conditions:

       a. The modified work must itself be a software library.

       b. You must cause the files modified to carry prominent notices
          stating that you changed the files and the date of any change.

       c. You must cause the whole of the work to be licensed at no
          charge to all third parties under the terms of this License.

       d. If a facility in the modified Library refers to a function or
          a table of data to be supplied by an application program that
          uses the facility, other than as an argument passed when the
          facility is invoked, then you must make a good faith effort to
          ensure that, in the event an application does not supply such
          function or table, the facility still operates, and performs
          whatever part of its purpose remains meaningful.

          (For example, a function in a library to compute square roots
          has a purpose that is entirely well-defined independent of the
          application.  Therefore, Subsection 2d requires that any
          application-supplied function or table used by this function
          must be optional: if the application does not supply it, the
          square root function must still compute square roots.)

     These requirements apply to the modified work as a whole.  If
     identifiable sections of that work are not derived from the
     Library, and can be reasonably considered independent and separate
     works in themselves, then this License, and its terms, do not apply
     to those sections when you distribute them as separate works.  But
     when you distribute the same sections as part of a whole which is a
     work based on the Library, the distribution of the whole must be on
     the terms of this License, whose permissions for other licensees
     extend to the entire whole, and thus to each and every part
     regardless of who wrote it.

     Thus, it is not the intent of this section to claim rights or
     contest your rights to work written entirely by you; rather, the
     intent is to exercise the right to control the distribution of
     derivative or collective works based on the Library.

     In addition, mere aggregation of another work not based on the
     Library with the Library (or with a work based on the Library) on a
     volume of a storage or distribution medium does not bring the other
     work under the scope of this License.

  3. You may opt to apply the terms of the ordinary GNU General Public
     License instead of this License to a given copy of the Library.  To
     do this, you must alter all the notices that refer to this License,
     so that they refer to the ordinary GNU General Public License,
     version 2, instead of to this License.  (If a newer version than
     version 2 of the ordinary GNU General Public License has appeared,
     then you can specify that version instead if you wish.)  Do not
     make any other change in these notices.

     Once this change is made in a given copy, it is irreversible for
     that copy, so the ordinary GNU General Public License applies to
     all subsequent copies and derivative works made from that copy.

     This option is useful when you wish to copy part of the code of the
     Library into a program that is not a library.

  4. You may copy and distribute the Library (or a portion or derivative
     of it, under Section 2) in object code or executable form under the
     terms of Sections 1 and 2 above provided that you accompany it with
     the complete corresponding machine-readable source code, which must
     be distributed under the terms of Sections 1 and 2 above on a
     medium customarily used for software interchange.

     If distribution of object code is made by offering access to copy
     from a designated place, then offering equivalent access to copy
     the source code from the same place satisfies the requirement to
     distribute the source code, even though third parties are not
     compelled to copy the source along with the object code.

  5. A program that contains no derivative of any portion of the
     Library, but is designed to work with the Library by being compiled
     or linked with it, is called a “work that uses the Library”.  Such
     a work, in isolation, is not a derivative work of the Library, and
     therefore falls outside the scope of this License.

     However, linking a “work that uses the Library” with the Library
     creates an executable that is a derivative of the Library (because
     it contains portions of the Library), rather than a “work that uses
     the library”.  The executable is therefore covered by this License.
     Section 6 states terms for distribution of such executables.

     When a “work that uses the Library” uses material from a header
     file that is part of the Library, the object code for the work may
     be a derivative work of the Library even though the source code is
     not.  Whether this is true is especially significant if the work
     can be linked without the Library, or if the work is itself a
     library.  The threshold for this to be true is not precisely
     defined by law.

     If such an object file uses only numerical parameters, data
     structure layouts and accessors, and small macros and small inline
     functions (ten lines or less in length), then the use of the object
     file is unrestricted, regardless of whether it is legally a
     derivative work.  (Executables containing this object code plus
     portions of the Library will still fall under Section 6.)

     Otherwise, if the work is a derivative of the Library, you may
     distribute the object code for the work under the terms of Section
     6.  Any executables containing that work also fall under Section 6,
     whether or not they are linked directly with the Library itself.

  6. As an exception to the Sections above, you may also combine or link
     a “work that uses the Library” with the Library to produce a work
     containing portions of the Library, and distribute that work under
     terms of your choice, provided that the terms permit modification
     of the work for the customer’s own use and reverse engineering for
     debugging such modifications.

     You must give prominent notice with each copy of the work that the
     Library is used in it and that the Library and its use are covered
     by this License.  You must supply a copy of this License.  If the
     work during execution displays copyright notices, you must include
     the copyright notice for the Library among them, as well as a
     reference directing the user to the copy of this License.  Also,
     you must do one of these things:

       a. Accompany the work with the complete corresponding
          machine-readable source code for the Library including
          whatever changes were used in the work (which must be
          distributed under Sections 1 and 2 above); and, if the work is
          an executable linked with the Library, with the complete
          machine-readable “work that uses the Library”, as object code
          and/or source code, so that the user can modify the Library
          and then relink to produce a modified executable containing
          the modified Library.  (It is understood that the user who
          changes the contents of definitions files in the Library will
          not necessarily be able to recompile the application to use
          the modified definitions.)

       b. Use a suitable shared library mechanism for linking with the
          Library.  A suitable mechanism is one that (1) uses at run
          time a copy of the library already present on the user’s
          computer system, rather than copying library functions into
          the executable, and (2) will operate properly with a modified
          version of the library, if the user installs one, as long as
          the modified version is interface-compatible with the version
          that the work was made with.

       c. Accompany the work with a written offer, valid for at least
          three years, to give the same user the materials specified in
          Subsection 6a, above, for a charge no more than the cost of
          performing this distribution.

       d. If distribution of the work is made by offering access to copy
          from a designated place, offer equivalent access to copy the
          above specified materials from the same place.

       e. Verify that the user has already received a copy of these
          materials or that you have already sent this user a copy.

     For an executable, the required form of the “work that uses the
     Library” must include any data and utility programs needed for
     reproducing the executable from it.  However, as a special
     exception, the materials to be distributed need not include
     anything that is normally distributed (in either source or binary
     form) with the major components (compiler, kernel, and so on) of
     the operating system on which the executable runs, unless that
     component itself accompanies the executable.

     It may happen that this requirement contradicts the license
     restrictions of other proprietary libraries that do not normally
     accompany the operating system.  Such a contradiction means you
     cannot use both them and the Library together in an executable that
     you distribute.

  7. You may place library facilities that are a work based on the
     Library side-by-side in a single library together with other
     library facilities not covered by this License, and distribute such
     a combined library, provided that the separate distribution of the
     work based on the Library and of the other library facilities is
     otherwise permitted, and provided that you do these two things:

       a. Accompany the combined library with a copy of the same work
          based on the Library, uncombined with any other library
          facilities.  This must be distributed under the terms of the
          Sections above.

       b. Give prominent notice with the combined library of the fact
          that part of it is a work based on the Library, and explaining
          where to find the accompanying uncombined form of the same
          work.

  8. You may not copy, modify, sublicense, link with, or distribute the
     Library except as expressly provided under this License.  Any
     attempt otherwise to copy, modify, sublicense, link with, or
     distribute the Library is void, and will automatically terminate
     your rights under this License.  However, parties who have received
     copies, or rights, from you under this License will not have their
     licenses terminated so long as such parties remain in full
     compliance.

  9. You are not required to accept this License, since you have not
     signed it.  However, nothing else grants you permission to modify
     or distribute the Library or its derivative works.  These actions
     are prohibited by law if you do not accept this License.
     Therefore, by modifying or distributing the Library (or any work
     based on the Library), you indicate your acceptance of this License
     to do so, and all its terms and conditions for copying,
     distributing or modifying the Library or works based on it.

  10. Each time you redistribute the Library (or any work based on the
     Library), the recipient automatically receives a license from the
     original licensor to copy, distribute, link with or modify the
     Library subject to these terms and conditions.  You may not impose
     any further restrictions on the recipients’ exercise of the rights
     granted herein.  You are not responsible for enforcing compliance
     by third parties with this License.

  11. If, as a consequence of a court judgment or allegation of patent
     infringement or for any other reason (not limited to patent
     issues), conditions are imposed on you (whether by court order,
     agreement or otherwise) that contradict the conditions of this
     License, they do not excuse you from the conditions of this
     License.  If you cannot distribute so as to satisfy simultaneously
     your obligations under this License and any other pertinent
     obligations, then as a consequence you may not distribute the
     Library at all.  For example, if a patent license would not permit
     royalty-free redistribution of the Library by all those who receive
     copies directly or indirectly through you, then the only way you
     could satisfy both it and this License would be to refrain entirely
     from distribution of the Library.

     If any portion of this section is held invalid or unenforceable
     under any particular circumstance, the balance of the section is
     intended to apply, and the section as a whole is intended to apply
     in other circumstances.

     It is not the purpose of this section to induce you to infringe any
     patents or other property right claims or to contest validity of
     any such claims; this section has the sole purpose of protecting
     the integrity of the free software distribution system which is
     implemented by public license practices.  Many people have made
     generous contributions to the wide range of software distributed
     through that system in reliance on consistent application of that
     system; it is up to the author/donor to decide if he or she is
     willing to distribute software through any other system and a
     licensee cannot impose that choice.

     This section is intended to make thoroughly clear what is believed
     to be a consequence of the rest of this License.

  12. If the distribution and/or use of the Library is restricted in
     certain countries either by patents or by copyrighted interfaces,
     the original copyright holder who places the Library under this
     License may add an explicit geographical distribution limitation
     excluding those countries, so that distribution is permitted only
     in or among countries not thus excluded.  In such case, this
     License incorporates the limitation as if written in the body of
     this License.

  13. The Free Software Foundation may publish revised and/or new
     versions of the Lesser General Public License from time to time.
     Such new versions will be similar in spirit to the present version,
     but may differ in detail to address new problems or concerns.

     Each version is given a distinguishing version number.  If the
     Library specifies a version number of this License which applies to
     it and “any later version”, you have the option of following the
     terms and conditions either of that version or of any later version
     published by the Free Software Foundation.  If the Library does not
     specify a license version number, you may choose any version ever
     published by the Free Software Foundation.

  14. If you wish to incorporate parts of the Library into other free
     programs whose distribution conditions are incompatible with these,
     write to the author to ask for permission.  For software which is
     copyrighted by the Free Software Foundation, write to the Free
     Software Foundation; we sometimes make exceptions for this.  Our
     decision will be guided by the two goals of preserving the free
     status of all derivatives of our free software and of promoting the
     sharing and reuse of software generally.

                              NO WARRANTY

  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
     WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE
     LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS
     AND/OR OTHER PARTIES PROVIDE THE LIBRARY “AS IS” WITHOUT WARRANTY
     OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
     PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE
     DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR
     OR CORRECTION.

  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
     WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY
     MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE
     LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
     INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
     INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF
     DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU
     OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY
     OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN
     ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

                      END OF TERMS AND CONDITIONS

How to Apply These Terms to Your New Libraries
----------------------------------------------

   If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change.  You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of
the ordinary General Public License).

   To apply these terms, attach the following notices to the library.
It is safest to attach them to the start of each source file to most
effectively convey the exclusion of warranty; and each file should have
at least the “copyright” line and a pointer to where the full notice is
found.

     ONE LINE TO GIVE THE LIBRARY'S NAME AND AN IDEA OF WHAT IT DOES.
     Copyright (C) YEAR  NAME OF AUTHOR

     This library is free software; you can redistribute it and/or modify it
     under the terms of the GNU Lesser General Public License as published by
     the Free Software Foundation; either version 2.1 of the License, or (at
     your option) any later version.

     This library is distributed in the hope that it will be useful, but
     WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     Lesser General Public License for more details.

     You should have received a copy of the GNU Lesser General Public
     License along with this library; if not, write to the Free Software
     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
     USA.

   Also add information on how to contact you by electronic and paper
mail.

   You should also get your employer (if you work as a programmer) or
your school, if any, to sign a “copyright disclaimer” for the library,
if necessary.  Here is a sample; alter the names:

     Yoyodyne, Inc., hereby disclaims all copyright interest in the library
     `Frob' (a library for tweaking knobs) written by James Random Hacker.

     SIGNATURE OF TY COON, 1 April 1990
     Ty Coon, President of Vice

   That’s all there is to it!

C.3 GNU Free Documentation License
==================================

                      Version 1.2, November 2002

     Copyright © 2000,2001,2002 Free Software Foundation, Inc.
     51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA

     Everyone is permitted to copy and distribute verbatim copies
     of this license document, but changing it is not allowed.

  0. PREAMBLE

     The purpose of this License is to make a manual, textbook, or other
     functional and useful document “free” in the sense of freedom: to
     assure everyone the effective freedom to copy and redistribute it,
     with or without modifying it, either commercially or
     noncommercially.  Secondarily, this License preserves for the
     author and publisher a way to get credit for their work, while not
     being considered responsible for modifications made by others.

     This License is a kind of “copyleft”, which means that derivative
     works of the document must themselves be free in the same sense.
     It complements the GNU General Public License, which is a copyleft
     license designed for free software.

     We have designed this License in order to use it for manuals for
     free software, because free software needs free documentation: a
     free program should come with manuals providing the same freedoms
     that the software does.  But this License is not limited to
     software manuals; it can be used for any textual work, regardless
     of subject matter or whether it is published as a printed book.  We
     recommend this License principally for works whose purpose is
     instruction or reference.

  1. APPLICABILITY AND DEFINITIONS

     This License applies to any manual or other work, in any medium,
     that contains a notice placed by the copyright holder saying it can
     be distributed under the terms of this License.  Such a notice
     grants a world-wide, royalty-free license, unlimited in duration,
     to use that work under the conditions stated herein.  The
     “Document”, below, refers to any such manual or work.  Any member
     of the public is a licensee, and is addressed as “you”.  You accept
     the license if you copy, modify or distribute the work in a way
     requiring permission under copyright law.

     A “Modified Version” of the Document means any work containing the
     Document or a portion of it, either copied verbatim, or with
     modifications and/or translated into another language.

     A “Secondary Section” is a named appendix or a front-matter section
     of the Document that deals exclusively with the relationship of the
     publishers or authors of the Document to the Document’s overall
     subject (or to related matters) and contains nothing that could
     fall directly within that overall subject.  (Thus, if the Document
     is in part a textbook of mathematics, a Secondary Section may not
     explain any mathematics.)  The relationship could be a matter of
     historical connection with the subject or with related matters, or
     of legal, commercial, philosophical, ethical or political position
     regarding them.

     The “Invariant Sections” are certain Secondary Sections whose
     titles are designated, as being those of Invariant Sections, in the
     notice that says that the Document is released under this License.
     If a section does not fit the above definition of Secondary then it
     is not allowed to be designated as Invariant.  The Document may
     contain zero Invariant Sections.  If the Document does not identify
     any Invariant Sections then there are none.

     The “Cover Texts” are certain short passages of text that are
     listed, as Front-Cover Texts or Back-Cover Texts, in the notice
     that says that the Document is released under this License.  A
     Front-Cover Text may be at most 5 words, and a Back-Cover Text may
     be at most 25 words.

     A “Transparent” copy of the Document means a machine-readable copy,
     represented in a format whose specification is available to the
     general public, that is suitable for revising the document
     straightforwardly with generic text editors or (for images composed
     of pixels) generic paint programs or (for drawings) some widely
     available drawing editor, and that is suitable for input to text
     formatters or for automatic translation to a variety of formats
     suitable for input to text formatters.  A copy made in an otherwise
     Transparent file format whose markup, or absence of markup, has
     been arranged to thwart or discourage subsequent modification by
     readers is not Transparent.  An image format is not Transparent if
     used for any substantial amount of text.  A copy that is not
     “Transparent” is called “Opaque”.

     Examples of suitable formats for Transparent copies include plain
     ASCII without markup, Texinfo input format, LaTeX input format,
     SGML or XML using a publicly available DTD, and standard-conforming
     simple HTML, PostScript or PDF designed for human modification.
     Examples of transparent image formats include PNG, XCF and JPG.
     Opaque formats include proprietary formats that can be read and
     edited only by proprietary word processors, SGML or XML for which
     the DTD and/or processing tools are not generally available, and
     the machine-generated HTML, PostScript or PDF produced by some word
     processors for output purposes only.

     The “Title Page” means, for a printed book, the title page itself,
     plus such following pages as are needed to hold, legibly, the
     material this License requires to appear in the title page.  For
     works in formats which do not have any title page as such, “Title
     Page” means the text near the most prominent appearance of the
     work’s title, preceding the beginning of the body of the text.

     A section “Entitled XYZ” means a named subunit of the Document
     whose title either is precisely XYZ or contains XYZ in parentheses
     following text that translates XYZ in another language.  (Here XYZ
     stands for a specific section name mentioned below, such as
     “Acknowledgements”, “Dedications”, “Endorsements”, or “History”.)
     To “Preserve the Title” of such a section when you modify the
     Document means that it remains a section “Entitled XYZ” according
     to this definition.

     The Document may include Warranty Disclaimers next to the notice
     which states that this License applies to the Document.  These
     Warranty Disclaimers are considered to be included by reference in
     this License, but only as regards disclaiming warranties: any other
     implication that these Warranty Disclaimers may have is void and
     has no effect on the meaning of this License.

  2. VERBATIM COPYING

     You may copy and distribute the Document in any medium, either
     commercially or noncommercially, provided that this License, the
     copyright notices, and the license notice saying this License
     applies to the Document are reproduced in all copies, and that you
     add no other conditions whatsoever to those of this License.  You
     may not use technical measures to obstruct or control the reading
     or further copying of the copies you make or distribute.  However,
     you may accept compensation in exchange for copies.  If you
     distribute a large enough number of copies you must also follow the
     conditions in section 3.

     You may also lend copies, under the same conditions stated above,
     and you may publicly display copies.

  3. COPYING IN QUANTITY

     If you publish printed copies (or copies in media that commonly
     have printed covers) of the Document, numbering more than 100, and
     the Document’s license notice requires Cover Texts, you must
     enclose the copies in covers that carry, clearly and legibly, all
     these Cover Texts: Front-Cover Texts on the front cover, and
     Back-Cover Texts on the back cover.  Both covers must also clearly
     and legibly identify you as the publisher of these copies.  The
     front cover must present the full title with all words of the title
     equally prominent and visible.  You may add other material on the
     covers in addition.  Copying with changes limited to the covers, as
     long as they preserve the title of the Document and satisfy these
     conditions, can be treated as verbatim copying in other respects.

     If the required texts for either cover are too voluminous to fit
     legibly, you should put the first ones listed (as many as fit
     reasonably) on the actual cover, and continue the rest onto
     adjacent pages.

     If you publish or distribute Opaque copies of the Document
     numbering more than 100, you must either include a machine-readable
     Transparent copy along with each Opaque copy, or state in or with
     each Opaque copy a computer-network location from which the general
     network-using public has access to download using public-standard
     network protocols a complete Transparent copy of the Document, free
     of added material.  If you use the latter option, you must take
     reasonably prudent steps, when you begin distribution of Opaque
     copies in quantity, to ensure that this Transparent copy will
     remain thus accessible at the stated location until at least one
     year after the last time you distribute an Opaque copy (directly or
     through your agents or retailers) of that edition to the public.

     It is requested, but not required, that you contact the authors of
     the Document well before redistributing any large number of copies,
     to give them a chance to provide you with an updated version of the
     Document.

  4. MODIFICATIONS

     You may copy and distribute a Modified Version of the Document
     under the conditions of sections 2 and 3 above, provided that you
     release the Modified Version under precisely this License, with the
     Modified Version filling the role of the Document, thus licensing
     distribution and modification of the Modified Version to whoever
     possesses a copy of it.  In addition, you must do these things in
     the Modified Version:

       A. Use in the Title Page (and on the covers, if any) a title
          distinct from that of the Document, and from those of previous
          versions (which should, if there were any, be listed in the
          History section of the Document).  You may use the same title
          as a previous version if the original publisher of that
          version gives permission.

       B. List on the Title Page, as authors, one or more persons or
          entities responsible for authorship of the modifications in
          the Modified Version, together with at least five of the
          principal authors of the Document (all of its principal
          authors, if it has fewer than five), unless they release you
          from this requirement.

       C. State on the Title page the name of the publisher of the
          Modified Version, as the publisher.

       D. Preserve all the copyright notices of the Document.

       E. Add an appropriate copyright notice for your modifications
          adjacent to the other copyright notices.

       F. Include, immediately after the copyright notices, a license
          notice giving the public permission to use the Modified
          Version under the terms of this License, in the form shown in
          the Addendum below.

       G. Preserve in that license notice the full lists of Invariant
          Sections and required Cover Texts given in the Document’s
          license notice.

       H. Include an unaltered copy of this License.

       I. Preserve the section Entitled “History”, Preserve its Title,
          and add to it an item stating at least the title, year, new
          authors, and publisher of the Modified Version as given on the
          Title Page.  If there is no section Entitled “History” in the
          Document, create one stating the title, year, authors, and
          publisher of the Document as given on its Title Page, then add
          an item describing the Modified Version as stated in the
          previous sentence.

       J. Preserve the network location, if any, given in the Document
          for public access to a Transparent copy of the Document, and
          likewise the network locations given in the Document for
          previous versions it was based on.  These may be placed in the
          “History” section.  You may omit a network location for a work
          that was published at least four years before the Document
          itself, or if the original publisher of the version it refers
          to gives permission.

       K. For any section Entitled “Acknowledgements” or “Dedications”,
          Preserve the Title of the section, and preserve in the section
          all the substance and tone of each of the contributor
          acknowledgements and/or dedications given therein.

       L. Preserve all the Invariant Sections of the Document, unaltered
          in their text and in their titles.  Section numbers or the
          equivalent are not considered part of the section titles.

       M. Delete any section Entitled “Endorsements”.  Such a section
          may not be included in the Modified Version.

       N. Do not retitle any existing section to be Entitled
          “Endorsements” or to conflict in title with any Invariant
          Section.

       O. Preserve any Warranty Disclaimers.

     If the Modified Version includes new front-matter sections or
     appendices that qualify as Secondary Sections and contain no
     material copied from the Document, you may at your option designate
     some or all of these sections as invariant.  To do this, add their
     titles to the list of Invariant Sections in the Modified Version’s
     license notice.  These titles must be distinct from any other
     section titles.

     You may add a section Entitled “Endorsements”, provided it contains
     nothing but endorsements of your Modified Version by various
     parties—for example, statements of peer review or that the text has
     been approved by an organization as the authoritative definition of
     a standard.

     You may add a passage of up to five words as a Front-Cover Text,
     and a passage of up to 25 words as a Back-Cover Text, to the end of
     the list of Cover Texts in the Modified Version.  Only one passage
     of Front-Cover Text and one of Back-Cover Text may be added by (or
     through arrangements made by) any one entity.  If the Document
     already includes a cover text for the same cover, previously added
     by you or by arrangement made by the same entity you are acting on
     behalf of, you may not add another; but you may replace the old
     one, on explicit permission from the previous publisher that added
     the old one.

     The author(s) and publisher(s) of the Document do not by this
     License give permission to use their names for publicity for or to
     assert or imply endorsement of any Modified Version.

  5. COMBINING DOCUMENTS

     You may combine the Document with other documents released under
     this License, under the terms defined in section 4 above for
     modified versions, provided that you include in the combination all
     of the Invariant Sections of all of the original documents,
     unmodified, and list them all as Invariant Sections of your
     combined work in its license notice, and that you preserve all
     their Warranty Disclaimers.

     The combined work need only contain one copy of this License, and
     multiple identical Invariant Sections may be replaced with a single
     copy.  If there are multiple Invariant Sections with the same name
     but different contents, make the title of each such section unique
     by adding at the end of it, in parentheses, the name of the
     original author or publisher of that section if known, or else a
     unique number.  Make the same adjustment to the section titles in
     the list of Invariant Sections in the license notice of the
     combined work.

     In the combination, you must combine any sections Entitled
     “History” in the various original documents, forming one section
     Entitled “History”; likewise combine any sections Entitled
     “Acknowledgements”, and any sections Entitled “Dedications”.  You
     must delete all sections Entitled “Endorsements.”

  6. COLLECTIONS OF DOCUMENTS

     You may make a collection consisting of the Document and other
     documents released under this License, and replace the individual
     copies of this License in the various documents with a single copy
     that is included in the collection, provided that you follow the
     rules of this License for verbatim copying of each of the documents
     in all other respects.

     You may extract a single document from such a collection, and
     distribute it individually under this License, provided you insert
     a copy of this License into the extracted document, and follow this
     License in all other respects regarding verbatim copying of that
     document.

  7. AGGREGATION WITH INDEPENDENT WORKS

     A compilation of the Document or its derivatives with other
     separate and independent documents or works, in or on a volume of a
     storage or distribution medium, is called an “aggregate” if the
     copyright resulting from the compilation is not used to limit the
     legal rights of the compilation’s users beyond what the individual
     works permit.  When the Document is included in an aggregate, this
     License does not apply to the other works in the aggregate which
     are not themselves derivative works of the Document.

     If the Cover Text requirement of section 3 is applicable to these
     copies of the Document, then if the Document is less than one half
     of the entire aggregate, the Document’s Cover Texts may be placed
     on covers that bracket the Document within the aggregate, or the
     electronic equivalent of covers if the Document is in electronic
     form.  Otherwise they must appear on printed covers that bracket
     the whole aggregate.

  8. TRANSLATION

     Translation is considered a kind of modification, so you may
     distribute translations of the Document under the terms of section
     4.  Replacing Invariant Sections with translations requires special
     permission from their copyright holders, but you may include
     translations of some or all Invariant Sections in addition to the
     original versions of these Invariant Sections.  You may include a
     translation of this License, and all the license notices in the
     Document, and any Warranty Disclaimers, provided that you also
     include the original English version of this License and the
     original versions of those notices and disclaimers.  In case of a
     disagreement between the translation and the original version of
     this License or a notice or disclaimer, the original version will
     prevail.

     If a section in the Document is Entitled “Acknowledgements”,
     “Dedications”, or “History”, the requirement (section 4) to
     Preserve its Title (section 1) will typically require changing the
     actual title.

  9. TERMINATION

     You may not copy, modify, sublicense, or distribute the Document
     except as expressly provided for under this License.  Any other
     attempt to copy, modify, sublicense or distribute the Document is
     void, and will automatically terminate your rights under this
     License.  However, parties who have received copies, or rights,
     from you under this License will not have their licenses terminated
     so long as such parties remain in full compliance.

  10. FUTURE REVISIONS OF THIS LICENSE

     The Free Software Foundation may publish new, revised versions of
     the GNU Free Documentation License from time to time.  Such new
     versions will be similar in spirit to the present version, but may
     differ in detail to address new problems or concerns.  See
     <http://www.gnu.org/copyleft/>.

     Each version of the License is given a distinguishing version
     number.  If the Document specifies that a particular numbered
     version of this License “or any later version” applies to it, you
     have the option of following the terms and conditions either of
     that specified version or of any later version that has been
     published (not as a draft) by the Free Software Foundation.  If the
     Document does not specify a version number of this License, you may
     choose any version ever published (not as a draft) by the Free
     Software Foundation.

ADDENDUM: How to use this License for your documents
----------------------------------------------------

   To use this License in a document you have written, include a copy of
the License in the document and put the following copyright and license
notices just after the title page:

       Copyright (C)  YEAR  YOUR NAME.
       Permission is granted to copy, distribute and/or modify this document
       under the terms of the GNU Free Documentation License, Version 1.2
       or any later version published by the Free Software Foundation;
       with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
       Texts.  A copy of the license is included in the section entitled ``GNU
       Free Documentation License''.

   If you have Invariant Sections, Front-Cover Texts and Back-Cover
Texts, replace the “with...Texts.” line with this:

         with the Invariant Sections being LIST THEIR TITLES, with
         the Front-Cover Texts being LIST, and with the Back-Cover Texts
         being LIST.

   If you have Invariant Sections without Cover Texts, or some other
combination of the three, merge those two alternatives to suit the
situation.

   If your document contains nontrivial examples of program code, we
recommend releasing these examples in parallel under your choice of free
software license, such as the GNU General Public License, to permit
their use in free software.