[ < ] | [ > ] | [Contents] | [Index] | [ ? ] |
gettext
utilitiesThis manual documents the GNU gettext tools and the GNU libintl library, version 0.18.3.
1 イントロダクション | Introduction | |
2 ユーザーの視点 | The User’s View | |
3 POファイルのフォーマット | The Format of PO Files | |
4 プログラムソースの準備 | Preparing Program Sources | |
5 POテンプレートファイルのマーク | Making the PO Template File | |
6 新しいPOファイルの作成 | Creating a New PO File | |
7 既存のPOファイルの更新 | Updating Existing PO Files | |
8 POファイルの編集 | Editing PO Files | |
9 POファイルの操作 | Manipulating PO Files | |
10 バイナリーのMOファイルの生成 | Producing Binary MO Files | |
11 プログラマーの視点 | The Programmer’s View | |
12 翻訳者の視点 | The Translator’s View | |
13 メンテナーの視点 | The Maintainer’s View | |
14 インストーラーと配布者の視点 | The Installer’s and Distributor’s View | |
15 その他のプログラミング言語 | Other Programming Languages | |
16 結びの言葉 | Concluding Remarks | |
Appendix A Language Codes | ISO 639 language codes | |
Appendix B Country Codes | ISO 3166 country codes | |
Appendix C Licenses | ||
Program Index | Index of Programs | |
Option Index | Index of Command-Line Options | |
Variable Index | Index of Environment Variables | |
PO Mode Index | Index of Emacs PO Mode Commands | |
Autoconf Macro Index | Index of Autoconf Macros | |
General Index | ||
— The Detailed Node Listing — Introduction | ||
1.1 GNU gettext の目的 | The Purpose of GNU gettext
| |
1.2 i18n、l10n、などなど | I18n, L10n, and Such | |
1.3 ネイティブ言語サポートの側面 | Aspects in Native Language Support | |
1.4 翻訳を伝達するファイル | Files Conveying Translations | |
1.5 GNU gettext の概要 | Overview of GNU gettext
| |
The User’s View | ||
2.1 オペレーティングシステムのインストール | Questions During Operating System Installation | |
2.2 GUIプログラムを使用したlocaleのセッティング | How to Specify the Locale Used by GUI Programs | |
2.3 環境変数を通じたlocaleのセッティング | How to Specify the Locale According to POSIX | |
2.4 特定のプログラムにたいして翻訳をインストールする | How to Install Additional Translations | |
Setting the POSIX Locale | ||
2.3.1 locale名 | How a Locale Specification Looks Like | |
2.3.2 localeの環境変数 | Which Environment Variable Specfies What | |
2.3.3 言語の優先リストを指定する | How to Specify a Priority List of Languages | |
Preparing Program Sources | ||
4.1 gettext 宣言のインポート | Importing the gettext declaration
| |
4.2 gettext 処理のトリガー | Triggering gettext Operations
| |
4.3 翻訳可能な文字列の準備 | Preparing Translatable Strings | |
4.4 ソース内でマークはどのように見えるか | How Marks Appear in Sources | |
4.5 翻訳可能文字列のマーク | Marking Translatable Strings | |
4.6 キーワードの前の特別なコメント | Telling something about the following string | |
4.7 翻訳可能文字列の特別なケース | Special Cases of Translatable Strings | |
4.8 翻訳バグの報告をユーザーに奨励する | Letting Users Report Translation Bugs | |
4.9 翻訳にたいして正確な名前をマークする | Marking Proper Names for Translation | |
4.10 ライブラリーソースの準備 | Preparing Library Sources | |
Making the PO Template File | ||
5.1 xgettext プログラムの呼び出し | Invoking the xgettext Program
| |
Creating a New PO File | ||
6.1 msginit プログラムの呼び出し | Invoking the msginit Program
| |
6.2 ヘッダーエントリーを入力する | Filling in the Header Entry | |
Updating Existing PO Files | ||
7.1 msgmerge プログラムの呼び出し | Invoking the msgmerge Program
| |
Editing PO Files | ||
8.1 KDEのPOファイルエディター | KDE’s PO File Editor | |
8.2 GNOMEのPOファイルエディター | GNOME’s PO File Editor | |
8.3 EmacsのPOファイルエディター | Emacs’s PO File Editor | |
8.4 翻訳compendiaの使用 | Using Translation Compendia | |
Emacs’s PO File Editor | ||
8.3.1 GNU gettext のインストールを完了する | Completing GNU gettext Installation
| |
8.3.2 主要なPOモードのコマンド | Main Commands | |
8.3.3 エントリーの決定 | Entry Positioning | |
8.3.4 エントリー内の文字列の正規化 | Normalizing Strings in Entries | |
8.3.5 翻訳済みのエントリー | Translated Entries | |
8.3.6 fuzzyエントリー | Fuzzy Entries | |
8.3.7 未翻訳エントリー | Untranslated Entries | |
8.3.8 陳腐化したエントリー | Obsolete Entries | |
8.3.9 翻訳の修正 | Modifying Translations | |
8.3.10 コメントの修正 | Modifying Comments | |
8.3.11 サブエディションの詳細 | Mode for Editing Translations | |
8.3.12 Cソースのコンテキスト | C Sources Context | |
8.3.13 追加POファイルを調べる | Consulting Auxiliary PO Files | |
Using Translation Compendia | ||
8.4.1 compendiaの作成 | Merging translations for later use | |
8.4.2 compendiaの使用 | Using older translations if they fit | |
Manipulating PO Files | ||
9.1 msgcat プログラムの呼び出し | Invoking the msgcat Program
| |
9.2 msgconv プログラムの呼び出し | Invoking the msgconv Program
| |
9.3 msggrep プログラムの呼び出し | Invoking the msggrep Program
| |
9.4 msgfilter プログラムの呼び出し | Invoking the msgfilter Program
| |
9.5 msguniq プログラムの呼び出し | Invoking the msguniq Program
| |
9.6 msgcomm プログラムの呼び出し | Invoking the msgcomm Program
| |
9.7 msgcmp プログラムの呼び出し | Invoking the msgcmp Program
| |
9.8 msgattrib プログラムの呼び出し | Invoking the msgattrib Program
| |
9.9 msgen プログラムの呼び出し | Invoking the msgen Program
| |
9.10 msgexec プログラムの呼び出し | Invoking the msgexec Program
| |
9.11 POファイルの一部をハイライトする | Highlighting parts of PO files | |
9.12 POファイルを処理するプログラムを独自に記述する | Writing your own programs that process PO files | |
Highlighting parts of PO files | ||
9.11.1 --color オプション | Triggering colorized output | |
9.11.2 環境変数TERM | The environment variable TERM
| |
9.11.3 --style オプション | The --style option
| |
9.11.4 POファイルのスタイルルール | Style rules for PO files | |
9.11.5 POファイルを閲覧するためにless をカスタマイズする | Customizing less for viewing PO files
| |
Producing Binary MO Files | ||
10.1 msgfmt プログラムの呼び出し | Invoking the msgfmt Program
| |
10.2 msgunfmt プログラムの呼び出し | Invoking the msgunfmt Program
| |
10.3 GNU MOファイルのフォーマット | The Format of GNU MO Files | |
The Programmer’s View | ||
11.1 catgets について | About catgets
| |
11.2 gettext について | About gettext
| |
11.3 2つのインターフェースの比較 | Comparing the two interfaces | |
11.4 独自のプログラム内でlibintl.aを使用する | Using libintl.a in own programs | |
11.5 gettext を根底から理解する | Being a gettext grok
| |
11.6 プログラマの章についての一時的なメモ | Temporary Notes for the Programmers Chapter | |
About | ||
11.1.1 インターフェース | The interface | |
11.1.2 catgets インターフェースに関する問題点?! | Problems with the catgets interface?!
| |
About | ||
11.2.1 インターフェース | The interface | |
11.2.2 あいまいざの解決 | Solving ambiguities | |
11.2.3 メッセージカタログファイルの配置 | Locating message catalog files | |
11.2.4 gettext が使用する出力文字セットの指定方法 | How to request conversion to Unicode | |
11.2.5 あいまいさの解決のためにコンテキストを使用する | Solving ambiguities in GUI programs | |
11.2.6 複数形(plural forms)にたいする追加の関数 | Additional functions for handling plurals | |
11.2.7 *gettext関数の最適化 | Optimization of the *gettext functions | |
Temporary Notes for the Programmers Chapter | ||
11.6.1 一時的な情報 - 二つの実装 | Temporary - Two Possible Implementations | |
11.6.2 一時的な情報 - catgets について | Temporary - About catgets
| |
11.6.3 一時的な情報 - なぜ一つの実装なのか | Temporary - Why a single implementation | |
11.6.4 一時的な情報 - ノート | Temporary - Notes | |
The Translator’s View | ||
12.1 イントロダクション0 | Introduction 0 | |
12.2 イントロダクション1 | Introduction 1 | |
12.3 議論 | Discussions | |
12.4 組織 | Organization | |
12.5 情報の流れ | Information Flow | |
12.6 複数形の翻訳 | How to fill in msgstr[0] ,
msgstr[1]
| |
12.7 メッセージの優先度: 最初に翻訳すべきメッセージを決める方法 | How to find which messages to translate first | |
Organization | ||
12.4.1 中央による調整 | Central Coordination | |
12.4.2 国家チーム | National Teams | |
12.4.3 メーリングリスト | Mailing Lists | |
National Teams | ||
12.4.2.1 サブカルチャー | Sub-Cultures | |
12.4.2.2 組織化へのアイディア | Organizational Ideas | |
The Maintainer’s View | ||
13.1 非フラットなディレクトリー階層 | Flat or Non-Flat Directory Structures | |
13.2 前提となる作業 | Prerequisite Works | |
13.3 gettextize プログラムの呼び出し | Invoking the gettextize Program
| |
13.4 作成または変更しなければならないファイル | Files You Must Create or Alter | |
13.5 configure.ac内でのautoconfマクロの使用 | Autoconf macros for use in configure.ac | |
13.6 CVSによる統合 | Integrating with CVS | |
13.7 配布用tarballの作成 | Creating a Distribution Tarball | |
Files You Must Create or Alter | ||
13.4.1 po/内のPOTFILES.in | POTFILES.in in po/ | |
13.4.2 po/内のLINGUAS | LINGUAS in po/ | |
13.4.3 po/内のMakevars | Makevars in po/ | |
13.4.4 po/内のMakefileの拡張 | Extending Makefile in po/ | |
13.4.5 トップレベルのconfigure.ac | configure.ac at top level | |
13.4.6 トップレベルのconfig.guess、config.sub | config.guess, config.sub at top level | |
13.4.7 トップレベルのmkinstalldirs | mkinstalldirs at top level | |
13.4.8 トップレベルのaclocal.m4 | aclocal.m4 at top level | |
13.4.9 トップレベルのacconfig.h | acconfig.h at top level | |
13.4.10 トップレベルのconfig.h.in | config.h.in at top level | |
13.4.11 トップレベルのMakefile.in | Makefile.in at top level | |
13.4.12 src/内のMakefile.in | Makefile.in in src/ | |
13.4.13 lib/内のgettext.h | gettext.h in lib/ | |
Autoconf macros for use in configure.ac | ||
13.5.1 gettext.m4内のAM_GNU_GETTEXT | AM_GNU_GETTEXT in gettext.m4 | |
13.5.2 gettext.m4内のAM_GNU_GETTEXT_VERSION | AM_GNU_GETTEXT_VERSION in gettext.m4 | |
13.5.3 gettext.m4内のAM_GNU_GETTEXT_NEED | AM_GNU_GETTEXT_NEED in gettext.m4 | |
13.5.4 intldir.m4内のAM_GNU_GETTEXT_INTL_SUBDIR | AM_GNU_GETTEXT_INTL_SUBDIR in intldir.m4 | |
13.5.5 po.m4内のAM_PO_SUBDIRS | AM_PO_SUBDIRS in po.m4 | |
13.5.7 iconv.m4内のAM_ICONV | AM_ICONV in iconv.m4 | |
Integrating with CVS | ||
13.6.1 分散開発におけるバージョンミスマッチを避ける | Avoiding version mismatch in distributed development | |
13.6.2 CVSバージョンコントロールの配下に置くファイル | Files to put under CVS version control | |
13.6.3 autopoint プログラムの呼び出し | Invoking the autopoint Program
| |
Other Programming Languages | ||
15.1 言語実装者の視点 | The Language Implementor’s View | |
15.2 プログラマーの視点 | The Programmer’s View | |
15.3 翻訳者の視点 | The Translator’s View | |
15.4 メンテナーの視点 | The Maintainer’s View | |
15.5 個別のプログラミング言語 | Individual Programming Languages | |
15.6 インターナショナライズ可能なデータ | Internationalizable Data | |
The Translator’s View | ||
15.3.1 Cフォーマット文字列 | C Format Strings | |
15.3.2 Objective Cフォーマット文字列 | Objective C Format Strings | |
15.3.3 Shellフォーマット文字列 | Shell Format Strings | |
15.3.4 Pythonフォーマット文字列 | Python Format Strings | |
15.3.5 Lispフォーマット文字列 | Lisp Format Strings | |
15.3.6 Emacs Lispフォーマット文字列 | Emacs Lisp Format Strings | |
15.3.7 librepフォーマット文字列 | librep Format Strings | |
15.3.8 Schemeフォーマット文字列 | Scheme Format Strings | |
15.3.9 Smalltalkフォーマット文字列 | Smalltalk Format Strings | |
15.3.10 Javaフォーマット文字列 | Java Format Strings | |
15.3.11 C#フォーマット文字列 | C# Format Strings | |
15.3.12 awkフォーマット文字列 | awk Format Strings | |
15.3.13 Object Pascalフォーマット文字列 | Object Pascal Format Strings | |
15.3.14 YCPフォーマット文字列 | YCP Format Strings | |
15.3.15 Tclフォーマット文字列 | Tcl Format Strings | |
15.3.16 Perlフォーマット文字列 | Perl Format Strings | |
15.3.17 PHPフォーマット文字列 | PHP Format Strings | |
15.3.18 GCC internalフォーマット文字列 | GCC internal Format Strings | |
15.3.19 GFC internalフォーマット文字列 | GFC internal Format Strings | |
15.3.20 Qtフォーマット文字列 | Qt Format Strings | |
15.3.21 Qtフォーマット文字列 | Qt Plural Format Strings | |
15.3.22 KDEフォーマット文字列 | KDE Format Strings | |
15.3.23 Boostフォーマット文字列 | Boost Format Strings | |
15.3.24 Luaフォーマット文字列 | Lua Format Strings | |
15.3.25 Java Scriptフォーマット文字列 | JavaScript Format Strings | |
Individual Programming Languages | ||
15.5.1 C、C++、Objective | C, C++, Objective C | |
15.5.2 sh - シェルスクリプト | sh - Shell Script | |
15.5.3 bash - Bourne-Againシェルスクリプト | bash - Bourne-Again Shell Script | |
15.5.4 Python | ||
15.5.5 GNU clisp - Common Lisp | ||
15.5.6 GNU clisp ソース | GNU clisp C sources | |
15.5.7 Emacs Lisp | ||
15.5.8 librep | ||
15.5.9 GNU guile - Scheme | ||
15.5.10 GNU Smalltalk | ||
15.5.11 Java | ||
15.5.12 C# | ||
15.5.13 GNU awk | ||
15.5.14 Pascal - フリーPascalコンパイラー | Pascal - Free Pascal Compiler | |
15.5.15 wxWidgetsライブラリー | wxWidgets library | |
15.5.16 YCP - YaST2スクリプト言語 | YCP - YaST2 scripting language | |
15.5.17 Tcl - Tkのスクリプト言語 | Tcl - Tk’s scripting language | |
15.5.18 Perl | ||
15.5.19 PHP ハイパーテキストプリプロセッサー | PHP Hypertext Preprocessor | |
15.5.20 Pike | ||
15.5.21 GNU Compiler Collectionソース | GNU Compiler Collection sources | |
15.5.22 Lua | ||
15.5.23 Java Script | ||
sh - Shell Script | ||
15.5.2.1 インターナショナリゼーションのためにシェルスクリプトを準備する | Preparing Shell Scripts for Internationalization | |
15.5.2.2 gettext.sh の内容 | Contents of gettext.sh
| |
15.5.2.3 gettext プログラムの呼び出し | Invoking the gettext program
| |
15.5.2.4 ngettext プログラムの呼び出し | Invoking the ngettext program
| |
15.5.2.5 envsubst プログラムの呼び出し | Invoking the envsubst program
| |
15.5.2.6 eval_gettext プログラムの呼び出し | Invoking the eval_gettext function
| |
15.5.2.7 eval_ngettext プログラムの呼び出し | Invoking the eval_ngettext function
| |
Perl | ||
15.5.18.1 Perlコードをパースするときの一般的な問題 | General Problems Parsing Perl Code | |
15.5.18.2 xgettextが探すキーワードはどれ? | Which Keywords Will xgettext Look For? | |
15.5.18.3 ハッシュキーを抽出する方法 | How to Extract Hash Keys | |
15.5.18.4 何が文字列で、何がクォート風の式なのか? | What are Strings And Quote-like Expressions? | |
15.5.18.5 文字列内挿の無効な使い方 | Invalid String Interpolation | |
15.5.18.6 文字列内挿の有効な使い方 | Valid String Interpolation | |
15.5.18.7 カッコを使用すべきとき | When To Use Parentheses | |
15.5.18.8 長い行を理解するには | How To Grok with Long Lines | |
15.5.18.9 バグ、落とし穴、動作しない事柄 | Bugs, Pitfalls, and Things That Do Not Work | |
Internationalizable Data | ||
15.6.1 POT - Portable Object Template | ||
15.6.2 Resource String Table | ||
15.6.3 Glade - GNOME user interface description | ||
Concluding Remarks | ||
16.1 GNU gettext の歴史 | History of GNU gettext
| |
16.2 参考文献 | Related Readings | |
Language Codes | ||
A.1 Usual Language Codes | Two-letter ISO 639 language codes | |
A.2 Rare Language Codes | Three-letter ISO 639 language codes | |
Licenses | ||
C.1 GNU GENERAL PUBLIC LICENSE | GNU General Public License | |
C.2 GNU LESSER GENERAL PUBLIC LICENSE | GNU Lesser General Public License | |
C.3 GNU Free Documentation License | ||
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このチャプターでは、GNU
gettext
が作られた目的と、フリーの翻訳プロジェクトについて説明します。それから、ネイティブ言語サポート(NLS: Native
Language
Support)にまつわる広義の概念をいくつか説明します。また国や文化の差異を他の側面から考慮した際に、翻訳したメッセージをプログラムに適用することが、どのような位置づけになるかを説明します。さらに翻訳に使用されるファイルを説明し、最初の翻訳において様々なツールがそれらのファイルをどのように生成、相互作用するのか、そして通常のメンテナンスサイクルにおいてどのように処理されるかについて説明します。
このマニュアルでは、プログラマーやメンテナーを指すときには彼という言葉を使用します。そして翻訳者を指すときは彼女、翻訳されたプログラムをインストールする人やエンドユーザーのことを指すときは彼らという言葉を使用します。これの目的はドキュメントを明解にするのが唯一の目的であり、決して各々の役割が男性、もしくは女性に適しているという意味ではまったくありません。あなたが想像するように、GNU
gettext
は性別、人種、宗教、国籍に関わらず、コンピュータを使用する人にとって有用なものなのです!
提案や訂正は下記にメールしてください:
Internet address:
bug-gnu-gettext@gnu.org
メールのメッセージに、マニュアルのバージョン番号と更新日付を記入してください。
1.1 GNU gettext の目的 | The Purpose of GNU gettext
| |
1.2 i18n、l10n、などなど | I18n, L10n, and Such | |
1.3 ネイティブ言語サポートの側面 | Aspects in Native Language Support | |
1.4 翻訳を伝達するファイル | Files Conveying Translations | |
1.5 GNU gettext の概要 | Overview of GNU gettext
|
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
gettext
の目的プログラムは通常、英語でドキュメントされており、実行時にユーザーと相互作用する場合にも英語が使用されます。これはGNUソフトウェアに限らず、多くのフリーソフトウェアにも当てはまる話です。開発者やメンテナー、すべての国々のユーザー同士でコミュニケーションする場合、共通の言語を使用するほうが便利です。一方、ほとんどの人は英語より自分の母国語を好み、日々の仕事にも可能な限り母国語を使用しています。単純に言うと、ほとんどの人は英語より母国語がコンピューターのスクリーンに表示されるのを愛するのです。
しかし多くの人にとって、これは時間をかけて考える価値がないと片付けてしまう夢かもしれません。彼らは結局、この夢を実現できる自信がないのです。しかし希望を失わずに、組織を作った人たちもいます。この翻訳プロジェクトは、これらの希望を作業可能な形に形式化して、私たちのすべてが真の多言語機能を兼ね揃えたプログラムと呼べるものを手にするチャンスなのです。
GNU
gettext
は、他の多くのステップを構築する資産であり、翻訳プロジェクトにとって重要なステップです。このパッケージは、プログラマー、翻訳者、そしてユーザーにたいして、統合されたツールとドキュメントを提供します。特に
GNU
gettext
ユーティリティーは、他のパッケージに多言語化されたメッセージを生成するためのフレームワークを提供するツール群です。このツールには以下のものが含まれます:
GNU
gettext
は、プログラムのソースを国際化する際の影響を最小化し、その影響を可能な限り小さく保つようにデザインされています。プログラムソースを見たときに、その影響が軽微、または少なくとも軽微に見えることにより、国際化が成功する可能性が高くなります。
翻訳プロジェクトは、翻訳プロジェクトの構造や手法を記述する手段としても、GNU
gettext
ディストリビューションを使用しています。これは、この文書がGNU
gettext
の技術面に限定して適切に記述された文書であることを超えるものであることを意味します。そうすることにより、翻訳者は翻訳作業を適切に行うために知る必要のあるすべてのことを、可能な限り単一の場所で見つけることができます。この補足的な文書により、プログラマーさらに好奇心のあるユーザーは、GNU
gettext
が翻訳プロジェクト以外の場所とどのように関連しているかを理解し、大きな絵を垣間見ることができます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プログラムによるネイティブ言語サポートを議論する際に、2つの長い単語が出現します。これらの単語には正確な意味づけがあり、このドキュメントでも使用する単語なので、ここで説明しておきましょう。使用される2つの長い単語とは、インターナショナリゼーション(internationalization)とローカリゼーション(localization)です。これらの単語を何度も何度も書くうちに、多くの人たちがi18nやl10nと記述するようになりました。この表現は単語の最初と最後の文字と、それらの文字の間にある文字数によって、それぞれの単語を略記したものです。しかしこのマニュアルではわかりやすくするために、略記を用いずに正式な単語を使用することにします。
インターナショナリゼーション(国際化)とは、プログラムやパッケージに含まれるプログラムのセットが多言語を認識しサポートする操作のことを指します。インターナショナリゼーションとは、英語の文字列でしかプログラムがを呼び出せないとか、英語以外の特定の言語の持つ習慣に縛られるといったことなく、同じ操作を一般的な方法で結びつけさせるための汎化のプロセスです。プログラムの開発者は、彼のプログラムをインターナショナライズするために様々なテクニックを使うことでしょう。それらのいくつかは標準化されています。そのうちの1つが
GNU gettext
なのです。プログラマーの視点を参照してください。
ローカリゼーション(地域化)とは、それを行うことによりすでにインターナショナライズされた一連のプログラムが必要とするすべての情報を受けとることができ、任意のネイティブ言語や文化的な習慣に従った方法による入出力に適応させることができるような操作のことを意味します。ローカリゼーションとは、一般的なメソッドを実装済みのインターナショナライズされたプログラムを特定の方法で使用する、特化のプロセスです。プログラミング環境はプログラマーにたいして、実行時に設定できるいくつかの機能を提供します。翻訳対象の単位として同じネイティブ言語同士をまとめた、任意の国がもつ特定の文化的な習慣の形式的な説明を、その言語や国のlocaleと呼びます。ローカライズされたプログラムを使用するユーザーは、プログラムを実行する前にプログラムがどのlocaleを使用するべきかを、特定の環境変数に設定します。
実際にはlocaleメッセージのサポートとは、特定のlocaleを形成する文化的なデータの単一のコンポーネントのことです。インターナショナライズされたソフトウェアを開発するプログラマーを支援するために、特定のlocale に保存されたデータにアクセスできるルーチンと関数を提供するライブラリーがあります。誰かが特定のlocaleを参照する場合には、特定のlocaleに保存されているデータを参照することになります。同様に、プログラマーが “locale ルーチンへのアクセス” を参照するということは、すべてのlocale情報にアクセスできる完全なルーチンの一式を参照するのと同じです。
ネイティブ言語サポート(Native Language Support、または単にNLS)という表現は、インターナショナリゼーションとローカリゼーションの両方により、プログラムが多言語と相互作用できる動作や機能の全体を指すときに使用します。一言で言うと、インターナショナリゼーションとはローカリゼーションを可能にする操作とも言えます。
大まかに言うと、多言語によるメッセージを処理する場合、インターナショナリゼーションはプログラマーによって処理され、ローカリゼーションは翻訳者によって処理されるとも言えます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
完全な多言語ディストリビューションを配付するためには、出力メッセージの翻訳以外に多くの事柄があります。
gettext
が提供するのは、Cプログラムが出力するメッセージを翻訳するための完全なツールセットです。しかしperlスクリプトとシェルスクリプトも同様に翻訳される必要があります。現在これらを翻訳するための方法があったとしても、本来あるべき形での統合はされていません。
autoconf
やbison
のような一部のプログラムは、他のプログラム(またはスクリプト)を生成することができます。たとえプログラムを生成するプログラムがインターナショナライズされていても、生成されたプログラムは独自にインターナショナリゼーションする必要がありますが、これらの間接的に行われるインターナショナリゼーションは生成プログラムで自動化できるはずです。しかし実際は生成するプログラムと生成されるプログラムは、それぞれ独自にインターナショナライズされるのが極めて一般的です。
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
はこれを完全に実装しており、その他の現代的なシステムも、欠けているコンポーネントにたいする、必要最小限のより実用的なサポートを提供しています。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
.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のフォーマットを使用しています。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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ソースを編集するのに、あなた自身が慣れ親しんだものを使用することもできます。その他に必要となる標準的な変更としては、翻訳用のライブラリーを正しく初期化することなどです。これらに関する詳細はプログラムソースの準備を参照してください。
新しく記述するソフトウェアについては、ソフトウェアを記述するときにそのような文字列をマークできますし、そうするべきでしょう。このような文字列にたいする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
プログラムが呼び出されるかについては、xgettext
プログラムの呼び出しを参照してください。もしあなたが本当に怠け者の場合、少し手間をかけてディストリビューション全体をセットアップするのに興味があるかもしれません(メンテナーの視点を参照してください)。この方法では、xgettext
コマンドをタイプするのを省略してmake
とタイプするだけで、自動的に適切なものを生成することができます。
最初はまだlang.poがないので、msgmerge
のステップはとばして、単にpackage.potがlang.poとしてコピーされます。ここでlangは対象となる言語です。詳細については、新しいPOファイルの作成を参照してください。
次はメッセージの最初の翻訳です。翻訳それ自身が全体として今だ人手に頼らねばならないものであり、その複雑さはこのマニュアルの取り扱う範囲を超えるものです。翻訳チームに連絡したり、チームの一員になって、同じネイティブ言語を作業対象とする他の人たちとあなたの翻訳を共有する方法等、いくつかのヒントについては、このマニュアルの他のチャプターで触れています(翻訳者の視点を参照してください)。
POファイルlang.poに翻訳したメッセージを追加するときに、POファイル編集用のエディター(POファイルの編集を参照してください)を使用していない場合は、POファイルのフォーマットに合わせて作業したり、文字列を引用符で括る規則など(POファイルのフォーマットを参照してください)について自分で気を遣わなければなりません。これは不可能な作業ではなく、実際に1995年頃には多くの人がPOファイルを取り扱っていた方法です。一方、POファイルエディターは、POファイルエディター自身の使い方を覚える必要はありますが、あなたにかわってエディターがPOファイルに関する詳細を取り扱ってくれます。
既に何らかの翻訳がCompendium POファイルに保存されている場合、翻訳者はPOモードを使って翻訳されていないエントリーをCompendiumから初期化したり、翻訳を選択してCompendiumに保存したり更新することができます(翻訳compendiaの使用を参照してください)。Compendiumファイルは、翻訳チームのメンバー間で共有するように意図されたものです。
プログラムやプログラムのパッケージは、ユーザーがバグ報告や改良のための提案をして、メンテナーが様々な方法でプログラムを変更して対応するという、動的な性質を持ちます。パッケージがすでにインターナショナライズされているという事実により、メンテナーがパッケージに文字列を追加したり、すでに翻訳された文字列を変更することをためらうようにさせるべきではありません。彼らは、彼ら自身がスムーズに作業できるようにベストを尽くすだけです。メンテナーはすでに負荷の掛かった双肩に、翻訳に関する心配事を背負いこまなないようにしてください。そして翻訳者はプログラミングの心配事からは自由でいるようにしてください。
メンテナーが心配すべきなのは、文字列が翻訳されるべきときに翻訳可能であるように文字列をマークすることであり、文字列がいつ翻訳されるかについては、適切な時がくれば翻訳されるものだと割り切るべきです。xgettext
は、時間をかけて進化してきたpackage.potを再び構築し、その結果、翻訳を含んだlang.poは徐々に古くなっていきます。
翻訳者(そしてメンテナー)にとって重要なのは、パッケージの翻訳はパッケージが誕生した時に1度行えばよいというものではなく、パッケージの生涯において繰り替えされる継続的なプロセスだと理解することです。あるパッケージにたいして最初の翻訳を行った後、時々手入れをすることが必要です。なぜなら翻訳が必要な新しい未翻訳の文字列が出現することにより、翻訳された文字列があちこちで古くなっていくからです。
msgmerge
プログラムは、すでに存在するlang.poファイルを、xgettext
で最新の C
ソースから抽出された、より新しいpackage.potテンプレートファイルと比較して更新するという目的を持っています。更新の処理はプログラムの変更により変更された、Cソース中の文字列の位置にたいする参照を調整します。同様に、msgmerge
はすでに翻訳されているがプログラムのソースに存在しなくなった、古い翻訳のコメントアウトも行います(陳腐化したエントリーを参照してください)。そして最後に新しい文字列を未翻訳の文字列として、結果であるPOファイルに挿入します(未翻訳エントリーを参照してください)。msgmergeが実際に何を行うかについては、msgmerge
プログラムの呼び出しを参照してください。
目的に至る経路と手段が何であれ、翻訳のためのすべての文字列を提供する更新されたlang.poがゴールなのです。
POファイルが変動し流動する一時的なものであるという性質は、翻訳というゲームでの不可欠な部分であり、よく理解して受け入れる必要があります。翻訳プロジェクトに参加する人はこの性質に苦労し、他の翻訳プロジェクトのメンバーに苦労をかけることもあるのです! 特にメンテナーは、たとえ最近は更新されていないディストリビューションでも、翻訳チームに早く仕事を終えるようにプレッシャーを与えず、リラックスして利用可能でオフィシャルなすべてのPOファイルをディストリビューションに含めましょう。プレッシャーを与えるのはむしろ、特定の言語を話すコミュニティーのユーザーなので、メンテナー自身も安心して翻訳ファイルの妥当性を考慮するべきです。一方翻訳者は、パッケージがオフィシャルのディストリビューションに向けた事前テストを行っているときに、自分が担当するPOファイルを合理的に更新する事を試みる必要があります。
1度POファイルが完成して信頼できる物になると、POファイルはmsgfmt
プログラムによって、パッケージのプログラムが実行時に必要な時はいつでも効率的に翻訳を取得できるよう、マシン向けのフォーマットに変換されます(GNU MOファイルのフォーマットを参照してください)。msgfmt
プログラムのすべての実行モードについては、msgfmt
プログラムの呼び出しを参照してください。
最後に、変更およびマークされたCソースがコンパイルされて、GNU
gettext
ライブラリーとリンクされます。これは通常、プロジェクトのための適切なMakefileと共に、make
コマンドを実行することにより行われ、結果としてユーザーが見つけることのできる場所に実行可能ファイルがインストールされます。MOファイル自身も適切にインストールされる必要があります。これで適切な環境変数(環境変数を通じたlocaleのセッティングを参照してください)をセットすると、プログラムを実行すればいつでも自分で自動的にローカライズするようになります。
このマニュアルの残りの部分では、上述の様々なステップを掘り下げて説明することを目的とします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
最近では、ユーザーがコンピューターにログインしたときには通常、プログラムがネイティブ言語でメッセージを表示するのを目にすることができます – 少なくともフリーソフトウェアやGNUプロジェクトに関わる人が少ないHindiやFilipinoなどの言語ではない、FrenchやGermanなどの言語による活発なフリーソフトウェアコミュニティーのユーザーは目にすることができるでしょう。
これはどのような仕組みで動くのでしょう? ユーザーはどのようにして、プログラムで使用する言語にたいして影響を与えることができるのでしょうか? このチャプターではこれらの疑問にお答えします。
2.1 オペレーティングシステムのインストール | Questions During Operating System Installation | |
2.2 GUIプログラムを使用したlocaleのセッティング | How to Specify the Locale Used by GUI Programs | |
2.3 環境変数を通じたlocaleのセッティング | How to Specify the Locale According to POSIX | |
2.4 特定のプログラムにたいして翻訳をインストールする | How to Install Additional Translations |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
デフォルトで使用する言語は、すでにオペレーティングシステムのインストールの時点で決定されている場合があります。オペレーティングシステムがインストールされるときは通常、インストーラーがインストール中に使用する言語とは別に、インストールされるシステムで使用する言語を尋ねます。言語を1度しか尋ねないOSインストーラーもあります。
これにより、すべてのユーザーにたいする、システム全体でのデフォルト言語が決定されます。追加の言語としてデフォルト言語以外のローカリゼーションを指定できるインストーラーもあります。たとえばKDE(K Desktop Environment)のローカリゼーションやOpenOffice.orgは、言語ごとにインストールできるパッケージが個別にバンドルされています。
これはマシンの使用目的を考える、よい機会です。個人的に使用するマシンの場合、追加のローカリゼーションはおそらく必要ありません。国際的なつながりをもつ組織や企業で使用するマシンの場合、ゲストユーザーのことも考えられます。海外から1週間程度の予定でゲストを迎える場合、彼のお好みのlocaleは何でしょうか? そのコストがディスクスペースを少し余分に消費するだけならば、あらかじめ追加のローカリゼーションをインストールする価値があるかもしれません。
システム全体のデフォルト言語は、新しいアカウントを作成するときのlocale設定で使用されます。しかしユーザーは同じマシンの他のユーザーとは異なる、自分自身のlocale設定を持つことができます。次のセクションで説明するようにユーザーは通常、最初のログイン後に自分のlocaleを指定することができます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
すぐに利用可能なプログラムは、“デスクトップ環境”とも呼ばれるユーザーのデスクトップで、それにはウィンドウマネージャーやウェブブラウザー、それにテキストエディターなどが含まれます。一般的なデスクトップとしてはKDE、GNOME、Xfceなどがあります。
デスクトップ環境のGUIプログラムで使用されるlocaleは、“control center”、“language settings”、“country settings”などと呼ばれる設定画面で指定できます。
デスクトップ環境に属さない個別のGUIプログラムは、設定パネルや環境変数を通じて、自身のlocaleを持つことができます。
環境変数を通じてlocaleを指定できるプログラムには、デスクトップのlocaleとは異なるlocaleを指定できるものもあります。これはプログラムをメニューやファイルシステムから起動するかわりに、コマンドラインから環境変数を指定した後にプログラムを起動するということです。環境変数の設定については、次のセクション(環境変数を通じたlocaleのセッティング)で説明します。ただしKDEのあるバージョンでは、localeをLANG
やLC_ALL
ではなくKDE_LANG
で設定します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
もっとも単純なケースは、あなたの言語がこのパッケージにしたがってインストールされている場合で、環境変数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名 | How a Locale Specification Looks Like | |
2.3.2 localeの環境変数 | Which Environment Variable Specfies What | |
2.3.3 言語の優先リストを指定する | How to Specify a Priority List of Languages |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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のときもあります)を使用します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
localeは複数のlocaleカテゴリー(locale categories)から構成されています(ネイティブ言語サポートの側面を参照してください)。プログラムがlocaleに依存する値を参照する場合は、以下の環境変数を優先度順に参照します:
LANGUAGE
LC_ALL
LC_xxx
は、xxxに対応するlocaleカテゴリーです:
LC_CTYPE
, LC_NUMERIC
, LC_TIME
, LC_COLLATE
,
LC_MONETARY
, LC_MESSAGES
, ...
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
変数については、つぎのセクションで説明します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
すべてのプログラムが、すべての言語に翻訳されている訳ではありません。翻訳されたメッセージが存在しない場合、デフォルトでは英語のメッセージが表示されます。あなたが他の言語を理解できる場合は、言語の優先順位のリストを設定することができます。これは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’以外に設定する必要があります。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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で略記された言語の翻訳されたメッセージが含まれています。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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エントリーを参照してください。
c-format
no-c-format
これらは人間によって追加されるフラグではなく、xgettext
プログラムだけが挿入するフラグです。ここで提案しているようなPOファイルを自動生成するシステムでは、ユーザーが変更を行っても、xgettext
プログラムが新しいテンプレートファイルを生成するたびに、変更は上書きされてしまいます。
c-format
フラグは、翻訳前の文字列と翻訳された文字列が、C形式の文字列であることを示します。no-c-format
フラグは逆に、文字列が一見して(‘%’ディレクティブによる)C形式の文字列に見えても、C形式ではないことを示します。
文字列にc-format
フラグが設定されていると、msgfmt
プログラムは、翻訳にたいして妥当性チェックのテストを追加で行います。msgfmt
プログラムの呼び出し、およびキーワードの前の特別なコメントとCフォーマット文字列を参照してください。
objc-format
no-objc-format
Objective Cの場合も同様です。Objective Cフォーマット文字列を参照してください。
sh-format
no-sh-format
shellの場合も同様です。Shellフォーマット文字列を参照してください。
python-format
no-python-format
Pythonの場合も同様です。Pythonフォーマット文字列を参照してください。
python-brace-format
no-python-brace-format
Python braceの場合も同様です。Pythonフォーマット文字列を参照してください。
lisp-format
no-lisp-format
Lispの場合も同様です。Lispフォーマット文字列を参照してください。
elisp-format
no-elisp-format
Emacs Lispの場合も同様です。Emacs Lispフォーマット文字列を参照してください。
librep-format
no-librep-format
librepの場合も同様です。librepフォーマット文字列を参照してください。
scheme-format
no-scheme-format
Schemeの場合も同様です。Schemeフォーマット文字列を参照してください。
smalltalk-format
no-smalltalk-format
Smalltalkの場合も同様です。Smalltalkフォーマット文字列を参照してください。
java-format
no-java-format
Javaの場合も同様です。Javaフォーマット文字列を参照してください。
csharp-format
no-csharp-format
C#の場合も同様です。C#フォーマット文字列を参照してください。
awk-format
no-awk-format
awkの場合も同様です。awkフォーマット文字列を参照してください。
object-pascal-format
no-object-pascal-format
Object Pascalの場合も同様です。Object Pascalフォーマット文字列を参照してください。
ycp-format
no-ycp-format
YCPの場合も同様です。YCPフォーマット文字列を参照してください。
tcl-format
no-tcl-format
Tclの場合も同様です。Tclフォーマット文字列を参照してください。
perl-format
no-perl-format
Perlの場合も同様です。Perlフォーマット文字列を参照してください。
perl-brace-format
no-perl-brace-format
Perl braceの場合も同様です。Perlフォーマット文字列を参照してください。
php-format
no-php-format
PHPの場合も同様です。PHPフォーマット文字列を参照してください。
gcc-internal-format
no-gcc-internal-format
GCCソースの場合も同様です。GCC internalフォーマット文字列を参照してください。
gfc-internal-format
no-gfc-internal-format
GNU Fortranコンパイラーのソースの場合も同様です。GFC internalフォーマット文字列を参照してください。
qt-format
no-qt-format
Qtの場合も同様です。Qtフォーマット文字列を参照してください。
qt-plural-format
no-qt-plural-format
Qt plural形式の場合も同様です。Qtフォーマット文字列を参照してください。
kde-format
no-kde-format
KDEの場合も同様です。KDEフォーマット文字列を参照してください。
boost-format
no-boost-format
Boostの場合も同様です。Boostフォーマット文字列を参照してください。
lua-format
no-lua-format
Luaの場合も同様です。Luaフォーマット文字列を参照してください。
javascript-format
no-javascript-format
JavaScriptの場合も同様です。Java Scriptフォーマット文字列を参照してください。
以下のように、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は、メタ情報が含まれたヘッダーエントリー(ヘッダーエントリーを入力するを参照してください)のために予約されています。このヘッダーエントリーはファイルの最初のエントリーにすべきです。空の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’で開始しなければなりません2。それぞれの文字列の括りの終端を改行(‘\n’)の直後にしている理由は、そうしても支障がないからというだけで、任意の文字の後で括りを終端して構いません。
文字列の括りの内側にある、行末を示す‘\n’は文字列の一部で、文字列の括りの外側の改行はPOファイル自身の行末を示し、文字列に影響を与えない点に注意してください。
文字列の外側では、空白文字とコメントを自由に使うことができます。行頭の‘#’から、その行の行末までがコメントとなります。翻訳者が記入するコメントは‘#’の後ろに空白文字をいくつか記述する必要があります。‘#’の後ろに空白文字がない場合、それは特定のGNUツールで生成・管理されるコメントとみなされ、POファイルがmsgmerge
で処理されるとき、予期せず削除される可能性があります。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プログラマーのために、Cのソースコードの変更を3つにカテゴリーに分けます。1番目は、ローカリゼーション関数にメッセージ翻訳を必要とするすべてのモジュールを教えることです。2番目は、プログラムの初期化(通常はmain関数の内部)で、GNU
gettext
の操作を的確にトリガーすることです。3番目に、翻訳が必要なプログラム内のすべての文字列定数を識別・調整・マークする必要があります。
4.1 gettext 宣言のインポート | Importing the gettext declaration
| |
4.2 gettext 処理のトリガー | Triggering gettext Operations
| |
4.3 翻訳可能な文字列の準備 | Preparing Translatable Strings | |
4.4 ソース内でマークはどのように見えるか | How Marks Appear in Sources | |
4.5 翻訳可能文字列のマーク | Marking Translatable Strings | |
4.6 キーワードの前の特別なコメント | Telling something about the following string | |
4.7 翻訳可能文字列の特別なケース | Special Cases of Translatable Strings | |
4.8 翻訳バグの報告をユーザーに奨励する | Letting Users Report Translation Bugs | |
4.9 翻訳にたいして正確な名前をマークする | Marking Proper Names for Translation | |
4.10 ライブラリーソースの準備 | Preparing Library Sources |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
gettext
宣言のインポートGNU
gettext
が必要とするすべてのファイルが利用可能で、Makefileファイルも調整済み(メンテナーの視点を参照してください)だとすると、翻訳対象の文字列を含むCモジュールには以下の行を含める必要があります:
#include <libintl.h>
翻訳可能なCの書式指定文字列(他のCモジュールで文字列が定義されている場合も含まれます)を引数として呼び出される、printf()
/fprintf()
/...を含むCモジュールにも以下の行を含める必要があります:
#include <libintl.h>
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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_ALLLC_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の切り替えがスレッドセーフではないこと等の理由により、通常は行われません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
文字列が翻訳可能とマークされる前に、調整が必要なこともあります。翻訳可能な文字列の準備は、その文字列をマーク(次のセクションで説明)する前に行います。文字列を準備する際に留意すべきは以下の点です。
上記のガイドラインにたいする例を、いくつか見てみましょう。
翻訳可能な文字列は、正しい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であるかは検証しないことに留意してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Cソース中で翻訳される文字列は、すべてマークする必要があります。マーキングは翻訳可能な文字列を、関数やプリプロセッサーのマクロに、単独の引数として引き渡す方法で行われます。翻訳のために利用可できる関数またはマクロは少なく、マーキングのキーワードとしてそれらの名前が使用されます。マーキングは翻訳される文字列自体に何かを行うよりは、文字列にアタッチすることによりマーキングを行なう方法が、より多く使用されます。明らかな例としては、フォーマット文字列によりエラーメッセージを生成する場合です。フォーマット文字列は翻訳する必要があり、フォーマット文字列の‘%s’で指定した箇所に挿入される文字列も同様だとすると、たとえばsprintf
の結果には、‘error_string_out()’のようなルーチンからなる、多くの異なるインスタンスが含まれることになり、これらをすべてリストするのは非現実的です。
マーキングには2つの目的があります。1つ目は実行時に翻訳を取得するトリガーとなることです。キーワードは引数となる文字列にたいして、可能なかぎり(そして望む限り)、動的に適切なトランスレーションを返すルーチンへと解決されます。ローカライズ可能な文字列は、変数にあてがわれていたり、関数の引数になっている場合がほとんどです。しかし翻訳可能な文字列が構造体の初期化時に使用される等の例外もあります。翻訳可能文字列の特別なケースを参照してください。
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とpo.m4内のAM_XGETTEXT_OPTIONで説明します。
長い文字列は複数行に分けられることに注意してください。コンパイル時にはISO CおよびISO
C++にもとづく文字列の自動連結が行われますが、xgettext
もこの構文をサポートしています。
後でメンテナンスするのも簡単になります。もしあなたがプログラマーで、文字列を追加、変更した場合、その文字列が翻訳される必要があると考えた場合は、‘_()’でマークすればよいのです。たとえば‘"%s"’は、翻訳しない文字列だとします。しかし‘"%s: %d"’は翻訳するような場合です(Frenchの場合は通常、Englishとは異なり、コロンの前にスペースを挿入する翻訳が必要になります)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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
)。
検索された最後の文字列を‘_()’でマークします(po-mark-translatable
)。
検索された最後の文字列を、利用可能なキーワードによりマークします。プレフィックスと一緒にこのコマンドを使うことにより、キーワードを管理することができます(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ファイルを入力することにより、後から変更することができます。Tag Tables in The Emacs Editorを参照してください。
,コマンドは毎回、前回に検索した箇所から検索を再開し、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-,コマンドに割り当てられているので、お勧めにするには便利ではありません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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
というフラグによりマークされます(POファイルのフォーマットを参照してください)。
注意深い読者は、まだ問題があると気づくでしょう。発見されたものが間違っている場合です。これは真実であり、そのためにxgettext
は、プログラマーが意志決定すべき特別な種類のコメントを認識することができるのです。gettext
キーワードと同じ行、またはそれに続く行にxgettext:c-format
という単語を含むコメントを発見すると、xgettext
はどのような場合であれ、文字列をc-format
フラグでマークします。この種のコメントは、xgettext
が文字列を書式文字列と認識しない場合(テストしてみて実際に認識されない場合)に使う必要があります。gettext
キーワードと同じ行にコメントがある場合、翻訳される前にコメントを挿入しなければならないことに注意してください。
このような状況は頻繁に発生します。printf
関数にわたされる文字列に書式指定子が含まれない場合もあります。そのようなケースでは通常、fputs
を使用するのでしょうが、それでもこのような状況はあり得ます。このような場合、xgettext
はそれを書式文字列として認識しませんが、翻訳に書式指定子として認識されるような文字列が含まれていると何が起こるでしょうか?
printf
関数はパラメーターにアクセスしようとしますが、翻訳前の文字列には何も引数がわたされないため、パラメーターは存在しません。
もちろん他の原因により、xgettext
が間違って書式文字列ではない文字列を、書式文字列と認識することがあります。このような場合、msgfmt
は多くの警告を出力し、.poファイルへの変換は失敗します。このように間違って書式文字列と認識されるのを防ぐには、上記と同様にxgettext:no-c-format
という文字列を含むコメントを使用します。
文字列がc-format
と間違ってマークされている場合、ユーザーは何が原因なのか調べることができます。--debug
オプション使用して、どのように問題を解決するかについては、xgettext
プログラムの呼び出しを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
注意深い読者なら、常に翻訳可能な文字列を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
プログラムが文字列を見つけ出せるように文字列をマークします(xgettext
プログラムの呼び出しを参照してください)。次に実行時に文字列を出力する前に、文字列を翻訳するのです。
最初のタスクは、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
を認識するかについては、xgettext
プログラムの呼び出しを参照してください。
もちろん、これが唯一の解決策という訳ではありません。以下の方法のうちのいずれかを使用することもできます:
#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番目の方法を使用することもできます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
コードにはバグが付き物ですが、翻訳も同様です。ユーザーがそれらのバグを報告できるようにする必要があります。メンテナーが同時に翻訳者であるような場合を除き、メンテナーが翻訳を変更することはないため、プログラマーやパッケージのメンテナーに翻訳のバグを報告するのは得策ではありません。したがって翻訳のバグは翻訳者に報告されなければなりません。
ここで紹介する方法で組織化することにより、メンテナーが翻訳のバグ報告をどこかへ転送したり、翻訳者や翻訳チームのアドレスのリストを維持する必要もなくなります。
すべてのプログラムには、バグを報告するためのアドレスを示す場所があります。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 ""
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
人や都市、場所の名前などは翻訳用にマークする必要があるでしょうか? 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ç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ç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ç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)"
このように名前の翻訳は微妙な領域に属する話題なので、翻訳を提出する前にテストすることをお勧めします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
あなたがプログラムではなくライブラリーを作成する場合、gettext
の使用方法にはわずかな違いしかありません。ここでは前提として、ライブラリーが自分自身の翻訳ドメインとPOTファイルを持つとします(ライブラリーがメインプログラムの翻訳ドメインとPOTファイルを使用する場合は、前のセクションを変更なしに適用できます)。
setlocale (LC_ALL,
"")
を呼び出しません。localeのセットはメインプログラムの責任です。ライブラリーのドキュメントにはこの事実を明記して、ライブラリーを使用するプログラム開発者が認識できるようにする必要があります。
textdomain (PACKAGE)
を呼び出しません。text
domainのセットはメインプログラムの責任です。
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. */ ... }
#include <libintl.h> #define _(String) gettext (String)
自身の翻訳ドメインを持つライブラリーの場合は、以下のようになります:
#include <libintl.h> #define _(String) dgettext (PACKAGE, String)
別の言い方をすると、gettext
のかわりにdgettext
を使用するということです。同様に、ngettext
が使用される箇所には、dngettext
を使用する必要があります。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ソースの準備ができたら、プログラマーはPOテンプレートファイルを作成します。このセクションでは、その目的のためにxgettext
をどのように使用するかについて説明します。
xgettext
は、domainname.poという名前のファイルを作成します。あなたはそれをdomainname.potという名前にリネームする必要があります(xgettext
は、どうして直接domainname.potを作成しないのでしょうか?
これは歴史的な理由からです。xgettext
が設計されたときはPOファイルとPOテンプレートファイルの区別があいまいで、拡張子の‘.pot’も使用されていなかったからです)。
5.1 xgettext プログラムの呼び出し | Invoking the xgettext Program
|
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
xgettext
プログラムの呼び出しxgettext [option] [inputfile] …
xgettext
プログラムは、与えられた入力ファイルから、翻訳可能な文字列を抽出します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
入力ファイルを指定します。
入力ファイルの名前を、コマンドラインからではなく、fileから読み込みます。
ディレクトリーのリストにdirectoryを追加します。このディレクトリーのリストからソースファイルを検索します。しかし.poファイルが出力されるのは、カレントディレクトリーです。
inputfileに‘-’が指定された場合は、標準入力から読み込みます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
出力ファイルとして、(messages.poのかわりに)name.poを使用します。
(name.poやmessages.poではなく)指定されたファイルに出力を書き込みます。
ファイルはdirに出力されます。
出力のfileに‘-’または‘/dev/stdout’が指定された場合、出力は標準出力に書き込まれます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
入力ファイルの言語を指定します。サポートされている言語は、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
です。
--language=C++
の省略指定です。
デフォルトでは、入力ファイルの言語は拡張子により推測されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
入力ファイルのエンコーディングを指定します。このオプションはメッセージ文字列や、それらのコメントに非ASCII文字が含まれている場合のみ必要です。TclとGladeの入力ファイルは、このオプションの指定に関わらず、UTF-8が想定されることに注意してください。
デフォルトでは、入力ファイルのエンコーディングはASCIIであると仮定されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
既存のファイルのメッセージを結合します。
fileのエントリーは抽出されません。fileには、POファイルかPOTファイルを指定します。
tagで始まるコメントブロックを、出力ファイル中のキーワード行の前に配置します。このオプションでtagを指定しない場合には、出力ファイル中のすべてのキーワード行の前にコメントブロックが配置されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
すべての文字列を抽出します。
このオプションはほとんどの言語、すなわち、C、C++、Objective-C、Shell、Python、Lisp、EmacsLisp、librep、Java、C#、awk、Tcl、Perl、PHP、GCC-source、Glade、Lua、JavaScript、Valaに影響を与えます。
検索する追加のキーワードを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に影響を与えます。
明示的に無効化されていない限り、常に検索されるデフォルトキーワードの指定は、言語に依存します:
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
。
NSLocalizedString
、_
、NSLocalizedStaticString
、__
も該当します。
gettext
、ngettext:1,2
、eval_gettext
、eval_ngettext:1,2
。
gettext
、ugettext
、dgettext:2
、ngettext:1,2
、ungettext:1,2
、dngettext:2,3
、_
。
gettext
、ngettext:1,2
、gettext-noop
。
_
。
_
。
gettext
、ngettext:1,2
、gettext-noop
。
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
。
GetString
、GetPluralString:1,2
、GetParticularString:1c,2
、GetParticularPluralString:1c,2,3
。
dcgettext
、dcngettext:1,2
。
::msgcat::mc
。
gettext
、%gettext
、$gettext
、dgettext:2
、dcgettext:2
、ngettext:1,2
、dngettext:2,3
、dcngettext:2,3
、gettext_noop
。
_
、gettext
、dgettext:2
、dcgettext:2
、ngettext:1,2
、dngettext:2,3
、dcngettext:2,3
。
label
、title
、text
、format
、copyright
、comments
、preview_text
、tooltip
。
_
、gettext.gettext
、gettext.dgettext:2
、gettext.dcgettext:2
、gettext.ngettext:1,2
、gettext.dngettext:2,3
、gettext.dcngettext:2,3
。
_
、gettext
、dgettext:2
、dcgettext:2
、ngettext:1,2
、dngettext:2,3
、pgettext:1c,2
、dpgettext:2c,3
。
_
、Q_
、N_
、NC_
、dgettext:2
、dcgettext:2
、ngettext:1,2
、dngettext:2,3
、dpgettext:2c,3
、dpgettext2:2c,3
。
デフォルトキーワードの指定は、‘-k’オプション、‘--keyword’を指定するか、keywordspecを指定せずに‘--keyword=’として無効にすることができます。
関数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(つまり、ほとんどの言語)に影響を与えます。
入力におけるANSI Cの三連表記(trigraph)を理解します。
このオプションは言語がC、C++、ObjectiveCの場合のみ効果があります。
Qtの書式指定文字列を認識します。
このオプションは言語がC++の場合のみ効果があります。
KDE 4の書式指定文字列を認識します。
このオプションは言語がC++の場合のみ効果があります。
Boostの書式指定文字列を認識します。
このオプションは言語がC++の場合のみ効果があります。
メッセージ中の書式指定文字列を、c-format
やpossible-c-format
フラグでマークすることにより、誰がマークしたかを表示します。後者の形式は、xgettext
が決定したときに使用され、前者はプログラマーが決定したときに使用されます。
デフォルトではc-format
形式だけが使用されます。翻訳者はそれらの詳細について気にする必要はありません。
このxgettext
の実装は、プリプロセッサーのマクロの中の文字列や、ANSIによる隣接した文字列の結合、エスケープ文字による行の継続等の厄介なケースを処理することができます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
色や色以外のテキスト属性を使うか、いつ使うかを指定します。詳細は--color
オプションを参照してください。
--color
にたいしてCSS style ruleファイルを使うかを指定します。詳細は--style
オプションを参照してください。
何もメッセージが定義されていない場合でも、常に出力ファイルに書き込みます。
インデントされた形式で.poファイルを書き込みます。
‘#: filename:line’のような行を書き込みません。このオプションを使用することにより、熟練した翻訳者が、どのようなコンテキストでメッセージが使用されるのかを理解するのが困難になることに注意してください。
‘#: filename:line’という行を生成します(デフォルト)。
Uniforumに厳密に準拠したPOファイルを出力します。このUniforum形式はGNUの拡張をサポートしないため避けたほうがよいでしょう。
Javaの.properties
の書式で、Java ResourceBundleを出力します。このファイル形式はplural
formをサポートせず、廃止されたメッセージを暗黙で除去することに注意してください。
.strings
の書式で、NeXTstep/GNUstepのローカライズされたリソースファイルを出力します。このファイル形式はplural
formをサポートしないことに注意してください。
出力ページの幅をセットします。これにより出力ファイル中の長い文字列が指定した幅(例:スクリーンの列数)に収まるように、各行の長さがnumber以下のような複数の行に分割されます。
長いメッセージ行を分割しません。出力ページの幅を超えるようなメッセージ行も、複数行に分割されません。出力ページの幅を超えるファイル参照行だけが分割されます。
ソートされた出力を生成します。このオプションを使用することにより翻訳者が、メッセージがどのようなコンテキストで使用されるかを理解するのが、困難になることに注意してください。
ファイルの場所により出力をソートします。
‘msgid ""’というエントリーにたいして、ヘッダーを書き込みません。
これはソースファイルの変更をテストする等の目的で、.gmo
ファイルを生成するときに便利です。--omit-header
を使用すると、同じファイルにたいして、同じオプションでxgettext
を実行すれば、実行した時が異なっていても同じ結果を得ることができます。
このオプションをASCII以外の文字が含まれたファイルにたいして使用した場合、エラーとなることに注意してください。
出力に著作権所有者(copyright holder)をセットします。stringにはパッケージの著作権所有者を指定する必要があります(パッケージのソースから抽出されたmsgstr文字列の著作権は、パッケージの著作権所有者に帰属することに注意してください)。翻訳者は、翻訳物の著作権を譲渡、もしくは放棄することが望まれます。これによりパッケージのメンテナーは法的なリスクなしでそれらを配布できるのです。stringが空の場合、出力ファイルはパブリックドメインに属するとマークされます。この場合も翻訳者は著作権を譲渡、もしくは放棄することが望まれます。繰り返しになりますが、そうすることによりパッケージのメンテナーは法的なリスクなしでそれらを配布できるのです。
stringのデフォルト値はFree Software Foundation,
Inc.です。これは単にxgettext
が最初に使用されたのが GNU プロジェクトであることが理由です。
出力からFSFの著作権を省略します。これは‘--copyright-holder=''’とするのと同じです。これはGNUプロジェクト以外で、翻訳物をパブリックドメインにしたいときに便利です。
出力のヘッダーに、パッケージ名をセットします。
出力のヘッダーにパッケージのバージョンをセットします。このオプションは、同時に‘--package-name’を指定したときだけ効果があります。
msgidに関するバグの報告先アドレスをセットします。このアドレスは、翻訳者が未翻訳文字列のバグを報告するための電子メールのアドレス、またはURLです。
このアドレスは、あなたのメールアドレスでも構いませんし、翻訳者が登録しなくても投稿できるメーリングリストのアドレスや、翻訳者があなたに連絡をとることができるウェブページのアドレスにすることもできます。
デフォルトは空文字列が設定されており、これは翻訳者にはこれらの情報が分からないことを意味します! このオプションを指定するのを忘れないでください。
msgstrの値に前置する文字列としてstring(指定されていない場合は"")を使用します。
msgstrの値に後置する文字列としてstring(指定されていない場合は"")を使用します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このヘルプを表示して終了します。
バージョン情報を表示して終了します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
新しい翻訳を開始する場合、翻訳者はpackage.potの初期コメント(ファイルの先頭にあります)とヘッダーのエントリー(最初のエントリーで、これもファイルの先頭付近にあります)に変更を加えたものをコピーして、LANG.poを作成します。
これを行う一番簡単な方法は、‘msginit’を使うことです:
$ cd PACKAGE-VERSION $ cd po $ msginit
かわりにコピーしてから手で変更する方法もあります。この場合、翻訳者はpackage.potをLANG.poというファイル名でコピーしてから、ファイル内の初期コメントとヘッダーエントリーを修正します。
6.1 msginit プログラムの呼び出し | Invoking the msginit Program
| |
6.2 ヘッダーエントリーを入力する | Filling in the Header Entry |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
msginit
プログラムの呼び出しmsginit [option]
msginit
プログラムは、新しいPOファイルを作成して、メタ情報をユーザーの環境にもとづいて初期化します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
入力となるPOTファイルです。
inputfileが指定されなかった場合、カレントディレクトリからPOTファイルを検索します。‘-’を指定すると、標準入力から読み込みます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
指定されたPOファイルに出力を書き込みます。
出力ファイルが指定されなかった場合は、ユーザーのロケール設定の‘--locale’オプションに依存します。‘-’を指定すると、出力は標準出力に書き込まれます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
入力ファイルがPOファイルの構文ではなく、Javaの.properties
の構文にのっとったJava
ResourceBundleファイルだとみなします。
入力ファイルがPOファイルの構文ではなく、NeXTstep/GNUstepのlocalized
resourceの.strings
の構文にのっとったファイルだとみなします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
対象のlocaleを設定します。llにはlanguage codeを、CCにはcountry codeを設定する必要があります。インストールされているすべてのlocaleのリストを出力するには、‘locale -a’コマンドを使用できます。デフォルトはユーザーのlocale設定が使用されます。
POファイルが翻訳者の手で作成されたものではなく、自動的に生成されたものであることを宣言します。
色や色以外のテキスト属性を使うか、いつ使うかを指定します。詳細は--color
オプションを参照してください。
--color
にたいしてCSS style ruleファイルを使うかを指定します。詳細は--style
オプションを参照してください。
Javaの.properties
の書式で、Java ResourceBundleを出力します。このファイル形式はplural
formをサポートせず、廃止されたメッセージを暗黙で除去することに注意してください。
.strings
の書式で、NeXTstep/GNUstepのローカライズされたリソースファイルを出力します。このファイル形式はplural
formをサポートしないことに注意してください。
出力ページの幅をセットします。これにより出力ファイル中の長い文字列が指定した幅(例:スクリーンの列数)に収まるように、各行の長さがnumber以下のような複数の行に分割されます。
長いメッセージ行を分割しません。出力ページの幅を超えるようなメッセージ行も、複数行に分割されません。出力ページの幅を超えるファイル参照行だけが分割されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このヘルプを表示して終了します。
バージョン情報を表示して終了します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
新規作成したときに初期値として入力されている、"SOME DESCRIPTIVE TITLE"、"YEAR"、および"FIRST AUTHOR <EMAIL@ADDRESS>、YEAR"などのコメントは、意味のある情報に書き換えるべきです。これはテキストエディターにより行うこともできますが、Emacsを使っていれば(拡張子を識別して)自動的にPOモードに切り替わります。これはM-x fundamental-modeと入力して無効にすることができます。
ヘッダーのエントリーの変更も、POモードで行うことができます。Emacsで、M-x po-mode RETと入力して、さらにRETを押すと、エントリーの編集が開始できるので、以下のフィールドに入力してください。
パッケージの名前とバージョンです。xgettext
により入力されていない場合は入力してください。
これはxgettext
によってすでに入力されています。未翻訳の文字列に関するバグを報告するための、電子メールアドレスかURLが含まれています:
これはxgettext
によってすでに入力されています。
これはPOファイルのためのエディターが、ファイルを保存するときに入力される項目なので、あなたは入力する必要はありません。
名前と電子メールアドレス(ダブルクォーテーションなし)を入力してください。
言語の英語名と、あなたが所属するlanguage teamの電子メールアドレスか、ホームページのURLを入力してください。
重複して作業するの防ぐためだけではなく、言語に関する難しい問題を調整するためにも、翻訳を開始する前にtranslation teamに連絡することをお勧めします。
フリーな翻訳プロジェクトでは、それぞれの翻訳チームが、チーム自身のメーリングリストを持っています。チームの最新のメーリングリスト一覧は、Free Translation Projectのホームページ(http://translationproject.org/) の"Teams"という場所にあります。
あなたの言語の言語コードを入力してください。以下の3つの形式のいずれかになります:
‘ll_CC’の命名規則は、システムがGNU libcにもとづいてlocale名を決定する方法でもありますが、重要な違いが3つあります。
そのため、あなたのlocale名が‘de_DE.UTF-8’の場合、POファイルのlanguage specificationは‘de’だけになります。
‘CHARSET’を、あなたのlocaleのlanguageで使用するcharacter
encodingかUTF-8で置き換えてください。この項目は、msgmerge
とmsgfmt
の正しい動作のために必要です。同様にlocaleのcharacter
encodingが、あなたのものとは異なるユーザーにとっても必要です(gettext
が使用する出力文字セットの指定方法を参照してください)。
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ではサポートされていません。
文字のエンコーディング名は、大文字または小文字で記述することができますが、通常は大文字が好まれます。
8bit
にセットしてください。
このフィールドはオプションで、POファイルにplural formがあるときだけ必要です。これは‘msgid_plural’というキーワードを検索すればわかります。plural formのフィールドの書式については複数形(plural forms)にたいする追加の関数と複数形の翻訳を参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
7.1 msgmerge プログラムの呼び出し | Invoking the msgmerge Program
|
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
msgmerge
プログラムの呼び出しmsgmerge [option] def.po ref.pot
msgmerge
プログラムは、Uniforumスタイルの2つの.poファイルをマージして1つにします。def.poファイルは既存のPOファイルで、メッセージが一致していれば既存の翻訳は新しいファイルに引き継がれます。その際、コメントは残されますが、抽出されたコメントやファイル内の位置などは破棄されます。ref.potは、最新のソースより作られたPOファイルですが、古い翻訳や、(通常はxgettext
により作成された)PO
Templateファイルを参照するため、ドットコメント(訳注:プログラマーから翻訳者へのコメント#.のこと)やファイル内の位置情報は保存されますが、ファイル内のいくつかの翻訳やコメントは、破棄されるでしょう。完全に一致するメッセージが見つからない場合、より良い結果を生成するためにfuzzy一致が使用されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
古いソースを参照する翻訳です。
新しいソースへの参照です。
ディレクトリーのリストにdirectoryを追加します。このディレクトリーのリストよりソースファイルを検索します。しかし.poファイルが出力されるのは、カレントディレクトリーです。
メッセージを翻訳するための追加のライブラリーを指定します。翻訳compendiaの使用を参照してください。このオプションは複数指定することができます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
def.poファイルを更新します。すでにdef.poが最新の場合は何もしません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
指定されたファイルに出力を書き込みます。
出力ファイルが指定されていない、または‘-’が指定された場合、結果は標準出力に出力されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
処理結果はdef.poファイルに書き戻されます。
def.poのバックアップを作成します。
通常使用されるバックアップの接尾辞を上書きします。
--backup
オプション、もしくは環境変数VERSION_CONTROL
を通じてバージョン管理の方式を選択します。以下の値が指定できます:
(--backup
オプションが指定されていたとしても)バックアップを作成しません。
番号付きのバックアップを作成します。
このファイルの番号付きのバックアップがすでに存在する場合、番号付きバックアップを作成し、そうでなければ単純なバックアップを作成します。
常に単純なバックアップを作成します。
--suffix
または環境変数SIMPLE_BACKUP_SUFFIX
が設定されていない場合は、バックアップの接尾辞として‘~’を使用します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
def.po内の各ドメインにたいして、ref.potを適用します。
完全に一致するものが見つからない場合、fuzzyマッチングを行いません。これにより処理のスピードが大幅に改善されます。
翻訳されたメッセージをもつ古いmsgidにたいしてfuzzyマーカーを追加するときに、‘#|’マークをつけて古いメッセージを保持します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
入力ファイルがPOファイルの構文ではなく、Javaの.properties
の構文にのっとったJava
ResourceBundleファイルだとみなします。
入力ファイルがPOファイルの構文ではなく、NeXTstep/GNUstepのlocalized
resourceの.strings
の構文にのっとったファイルだとみなします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ヘッダーのエントリーで使用される‘Language’フィールドを指定します。このフィールドの意味についてはヘッダーエントリーを入力するを参照してください。‘Language-Team’と‘Plural-Forms’のフィールドは変更されないことに注意してください。このオプションを指定しない場合、‘Language-Team’フィールドから最適なものを推測して、‘Language’フィールドに入力します。
色や色以外のテキスト属性を使うか、いつ使うかを指定します。詳細は--color
オプションを参照してください。
--color
にたいしてCSS style ruleファイルを使うかを指定します。詳細は--style
オプションを参照してください。
メッセージが何も含まれていない場合でも、常に出力ファイルに書き込みます。
インデントされた形式で.poファイルを書き込みます。
‘#: filename:line’という行を書き込みません。
‘#: filename:line’という行を生成します(デフォルト)。
Uniforumに厳密に準拠したPOファイルを出力します。このUniforum形式はGNUの拡張をサポートしないため避けたほうがよいでしょう。
Javaの.properties
の書式で、Java ResourceBundleを出力します。このファイル形式はplural
formをサポートせず、廃止されたメッセージを暗黙で除去することに注意してください。
.strings
の書式で、NeXTstep/GNUstepのローカライズされたリソースファイルを出力します。このファイル形式はplural
formをサポートしないことに注意してください。
出力ページの幅をセットします。これにより出力ファイル中の長い文字列が指定した幅(例:スクリーンの列数)に収まるように、各行の長さがnumber以下のような複数の行に分割されます。
長いメッセージ行を分割しません。出力ページの幅を超えるようなメッセージ行も、複数行に分割されません。出力ページの幅を超えるファイル参照行だけが分割されます。
ソートされた出力を生成します。このオプションを使用することにより翻訳者が、メッセージがどのようなコンテキストで使用されるかを理解するのが、困難になることに注意してください。
ファイルの場所により出力をソートします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このヘルプを表示して終了します。
バージョン情報を表示して終了します。
診断レベルを上げます。
プログレスインジケーターを表示しません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
8.1 KDEのPOファイルエディター | KDE’s PO File Editor | |
8.2 GNOMEのPOファイルエディター | GNOME’s PO File Editor | |
8.3 EmacsのPOファイルエディター | Emacs’s PO File Editor | |
8.4 翻訳compendiaの使用 | Using Translation Compendia |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
幸運にもあなたがEmacsのユーザーならば、POファイルの編集・変更のための快適な環境を提供するために特別に作成されたPOモードがあります。POファイルを編集するときPOモードを使えば、追加のPOファイルやcompendium POファイルを閲覧したり、POファイルの元となるCプログラムのソースへの参照を追跡するのが簡単になります。またプログラム中の文字列にたいして対話的に翻訳可能のマークをつけたり、POファイルを検証してエラーのある行を再配置するための特別な機能があります。
POモードを使うにはまず、主要なPOモードのコマンド(主要なPOモードのコマンドを参照してください)以外に、エントリー間の移動(エントリーの決定を参照してください)や、翻訳されていないエントリーの処理方法(未翻訳エントリーを参照してください)を理解する必要があります。
8.3.1 GNU gettext のインストールを完了する | Completing GNU gettext Installation
| |
8.3.2 主要なPOモードのコマンド | Main Commands | |
8.3.3 エントリーの決定 | Entry Positioning | |
8.3.4 エントリー内の文字列の正規化 | Normalizing Strings in Entries | |
8.3.5 翻訳済みのエントリー | Translated Entries | |
8.3.6 fuzzyエントリー | Fuzzy Entries | |
8.3.7 未翻訳エントリー | Untranslated Entries | |
8.3.8 陳腐化したエントリー | Obsolete Entries | |
8.3.9 翻訳の修正 | Modifying Translations | |
8.3.10 コメントの修正 | Modifying Comments | |
8.3.11 サブエディションの詳細 | Mode for Editing Translations | |
8.3.12 Cソースのコンテキスト | C Sources Context | |
8.3.13 追加POファイルを調べる | Consulting Auxiliary PO Files |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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をクリックして)違うフォントセットを試してみてください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
GNU gettext
のインストールを完了するで説明されているような行を追加してEmacsを設定した後は、POファイルを検知するとEmacsがそのウィンドウにたいしてPOモードを有効にします。これによりそのウィンドウは読み取り専用となり、po-mode-mapが設定されます。これはテキストモードから継承されたのではなく、純粋なEmacsのモードです。もしpo-mode-hook
に指定された関数があれば、実行されます。
あるウィンドウにたいしてPOモードが有効になると、‘PO’という文字が、そのウィンドウのモードラインに表示されます。モードラインにはPOファイルに含まれている各種エントリーがいくつあるかも表示されます。たとえば‘132t+3f+10u+2o’という文字列が表示されている場合、POモードには132個の翻訳済みのエントリー(翻訳済みのエントリーを参照してください)と、3個のfuzzyエントリー(fuzzyエントリーを参照してください)、それに10個の未翻訳のエントリー(未翻訳エントリーを参照してください)と、2個の廃止されたエントリー(陳腐化したエントリーを参照してください)が含まれていることを翻訳者に示しています。この際、エントリーが0個のものは表示されません。この例にならうと、fuzzyエントリーが解消され、未翻訳のエントリーが翻訳され、廃止されたエントリーが削除されれば、モードラインには‘145t’だけが表示されることになります。
主要なPOコマンドの中には、以下のセクションのカテゴリー分けに適合しないものもあります。それらのコマンドとは、POモードやPOモードが管理するウィンドウを、特別な方法で終了する方法などです。
POファイルにたいする最後の変更を取り消します(po-undo
)。
処理を終了してPOファイルを保存します(po-quit
)。
問い合わせの後に処理を終了します(po-confirm-and-quit
)。
一時的にPOファイルのウィンドウを離れます(po-other-window
)。
POモードのヘルプを表示します(po-help
)。
POファイルに関する統計情報を取得します(po-statistics
)。
POファイル全体のフォーマットを検証します(po-validate
)。
_コマンド(po-undo
)は、Emacsのundo機能と連携します。Undoing
Changes in The Emacs
Editorを参照してください。_を入力する度に、翻訳者が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モードのコマンドを選択することができます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
POファイルのウィンドウの中のカーソルは、ほとんど常にエントリ一部となります。唯一の例外は、カーソルがファイルの最後のエントリーの後ろにあったり、POファイルが空だったりという、特別なケースのときだけです。カーソルのある位置のエントリーのことを、カレントエントリーと呼びます。POモードのコマンドの多くは、カレントエントリーにたいして操作を行うので、翻訳者にとってカーソルを動かすことはPOファイルを閲覧できるだけでなく、エントリーに作用するコマンドの対象エントリーを選択することでもあるのです。
POモードのコマンドには、特別な方法によりカーソルの位置を変更するものがあります。それらの特別な目的に対応する位置へカーソルを動かす方法については、ここで説明します。他の方法については、以降のセクションで説明します(C-h mで完全な一覧を得ることもできます)。
カレントエントリーを再表示します(po-current-entry
)。
カレントエントリーの次のエントリーを選択します(po-next-entry
)。
カレントエントリーの前のエントリーを選択します(po-previous-entry
)。
POファイルの最初のエントリーを選択します(po-first-entry
)。
POファイルの最後のエントリーを選択します(po-last-entry
)。
後で利用できるように、現在のエントリーの場所を記録します(po-push-location
)。
以前に記録したエントリーの場所に戻ります(po-pop-location
)。
現在のエントリーの場所と、以前に記録したエントリーの場所を交換します(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モードを開発するプランもあります。翻訳可能文字列のマークを参照してください。
翻訳者が特定のエントリーを翻訳する前には、そのエントリーに関連する用語や言い回しを探すために、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つのエントリー間を行き来することができます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
特定の文字列をPOファイルのエントリーにエンコードする場合、複数行を分割したり括ったりする方法、さらには特殊な文字をバックスラッシュでエスケープする方法までもが異なっている等、とても多くの方法があります。POモードには、特定のエンコードの文字列をmsgid
フィールドに挿入するために、既存のPOファイルをスキャンする機能があります。POモードにはこれらを簡単に認識するためのビルトイン機能が内部的に存在しますが、これを高速に行うのは技術的に困難です。この効率に関する問題の解決を容易にするために、わたしたちは文字列の正規表現を採択しました。
POファイル内の文字列の標準的な表現方法については現在も議論されていますが、POモードでは正規表現を実験的に採用しています。xgettext
とPOモードで、同じ文字列を統一された方法で表示するのは、POモードで必要となる内部的な正規化が、GNU
gettext
からのxgettext
の使用をも自動的に満たすので便利なのです。明示的なPOモードの正規化は、POファイルが他の場所からインポートされたときや、慣例そのものが変更されたときに必要です。
正規表現が必要なPOファイルの文字列を正規化するために、以下のPOモードのコマンドが利用可能です:
エントリーをより標準化することにより、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"
文字列の初期化に関しては、まだ未解決の点もあります。これらの問題については、解決されたものからこのドキュメントに記載されるでしょう。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
POファイル中のエントリーのmsgstr
が翻訳されて、fuzzy(fuzzyエントリーを参照してください)もマークされていない場合、そのエントリーを翻訳済みのエントリーと呼びます。以後の処理では、翻訳済みのエントリーだけがGNU
msgfmt
でコンパイルされて、プログラムで利用できるようになります。他の種類のエントリーは除外され、それらにたいする翻訳は出力されません。
翻訳済みのエントリーを処理するためのコマンドがいくつかあります。
次の翻訳済みエントリーを検索します(po-next-translated-entry
)。
前の翻訳済みのエントリーを検索します(po-previous-translated-entry
)。
tコマンド(po-next-translated-entry
)とTコマンド(po-previous-translated-entry
)は、翻訳済みのエントリーを見つけて、前方または後方に移動するためのコマンドです。翻訳済みのエントリーが見つからなかった場合、POファイルのバッファーの先頭または終端に戻って検索します。
翻訳済みのエントリーは通常、翻訳者が翻訳を編集した結果です。翻訳の修正を参照してください。ただし変数po-auto-fuzzy-on-edit
がnil
でない場合、新しく翻訳されたエントリーは、公式な翻訳となる前に、最初はfuzzyエントリーになります。この場合、後でこのfuzzyエントリーのfuzzyを解消して、正式な翻訳済みのエントリーにする必要があります。fuzzyエントリーを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
POファイルのエントリーは、一連の属性を持っています。それらは名前から得られるような性質をもち、翻訳に関するシステムコメントを明示するために使用されます。その属性1つがfuzzy
で、この属性をもつエントリーがfuzzy(あいまいな)な翻訳であることを示します。この属性がつけられたエントリーのことを、fuzzyエントリーと呼びます。
通常fuzzyエントリーは、おおよそ目的にあった翻訳であるような翻訳済みエントリーにたいして、翻訳者が見直しのために使用するものです。これらのfuzzyエントリーは、古い翻訳済みのPOファイルを新しいPOテンプレートファイルに対応して更新するために、msgmerge
プログラムを適用することにより生成されることもあり、それはこのツールが、新しいmsgid
が、古いものをわずかに修正したものであって、新しい修正されたエントリーに古い翻訳を選択できると推測したときです。元の文字列(msgid
文字列)にたいするわずかな変更は、翻訳にも影響を与える場合があり、これは翻訳者による判断が必要です。あるエントリーにたいしてmsgmerge
がfuzzyのマークを付与するのには、このような理由があるのです。
翻訳者が後で再検討する必要があるエントリーを覚えておくために、彼女自身の都合でエントリーをfuzzyとすることもあります。したがって特にfuzzyエントリーを処理するためのコマンドが、いくつかあります。
次のfuzzyエントリーを検索します(po-next-fuzzy-entry
)。
前のfuzzyエントリーを検索します(po-previous-fuzzy-entry
)。
カレントエントリーの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エントリーが残っている場合は、終了してもよいか確認を求められます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
xgettext
で元となるPOファイルを作成する場合には、msgid
は未翻訳の文字列で初期化され、msgstr
には空文字列がセットされます。このように翻訳に空文字列がセットされているエントリーのことを、未翻訳(untranslated)のエントリーと呼びます。プログラマーがプログラム内の文字列に変更を加えた場合、変更された文字列にたいする新しい未翻訳のエントリーとしてPOファイル中に現れることになります。
未翻訳のエントリーにたいしても、有効なエントリー間の移動に通常使用するコマンドと同様のレベルで考えることができます。未翻訳のエントリーは、最後に‘msgstr ""’があるので、容易に識別できます。
翻訳者の作業は(非常に簡単に表現するならば)、未翻訳のエントリーを探して編集・翻訳して、未翻訳のエントリーがなくなるまでそれを繰り返していくことではないでしょうか。特に未翻訳のエントリーを処理するためのコマンドが、いくつかあります。
次の未翻訳のエントリーを検索します(po-next-untranslated-entry
)。
前の未翻訳のエントリーを検索します(po-previous-untransted-entry
)。
カレントエントリーを未翻訳にします(po-kill-msgstr
)。
uコマンド(po-next-untranslated-entry
)とUコマンド(po-previous-untransted-entry
)は、前方もしくは後方の未翻訳のエントリーに移動します。未翻訳のエントリーが見つからなかった場合、POファイルのバッファーの先頭または終端に戻って検索します。
kコマンド(po-kill-msgstr
)は、単に翻訳された文字列を空文字列にすることによって、エントリーを未翻訳のエントリーにするコマンドです。翻訳の修正を参照してください。
翻訳者が作業を終えてPOファイルのバッファーをqコマンドで閉じるとき、まだ未翻訳のエントリーが残っている場合は、終了してもよいか確認を求められます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
POファイルの陳腐化したエントリーとは、msgmerge
によりローカライズされるパッケージ内で、その翻訳がもはや必要ないのでコメントアウトされているエントリーのことです。
陳腐化したエントリーにたいしても、有効なエントリー間の移動に通常使用するコマンドと同様のレベルで考えることができます。行にmsgid
やmsgstr
が含まれているか否かに関係なく、行が#
で開始されているという事実により、陳腐化したエントリーを識別できます。
再初期化するために翻訳を空文字列に置き換えて、元の未翻訳の空文字列にするコマンドがあります。これらのコマンドはEmacsのkillリングと互換性があるので、以前にkillリングに保存された文字列を翻訳として挿入することもできます。またユーザーは翻訳を対話的に編集することができます。これらすべてのコマンドは廃止されたエントリーの編集にも適用できますが、エントリーは廃止された状態のままになります。
陳腐化したエントリーに特化したコマンドがいくつかあります。
次の陳腐化エントリーを検索します(po-next-obsolete-entry
)。
前の陳腐化したエントリーを検索します(po-previous-obsolete-entry
)。
有効なエントリーにたいしては、それを陳腐化したエントリーにします。陳腐化したエントリーの場合は、エントリーを削除します(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ファイルの、(通常は)未翻訳のエントリに再使用するのは簡単です。翻訳の修正を参照してください。
今後POモードを開発していく上で、あなたを寝不足とさせるような、解決すべき興味深い問題が存在します。POモードをよりよくするこのアイデアとは、新しく出現した文字列にたいする翻訳として、すべての陳腐化したエントリーの中から最適な候補を推測することです。これはアルゴリズム的に解決するには困難な問題であり、文字列の相似をより効果的に計測するための開発を行う必要があると私は考えています。現在ではこれらの作業は翻訳者がすべて決定しなければなりませんが、いつの日か陳腐化したエントリーから翻訳を検索することができる便利なツールを提供できるように努力しています。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
POモードは、通常Emacsのバッファーを変更するような方法でPOファイルを直接編集することを防ぎます。そうすることで、直接編集してファイル全体のフォーマットや文字列の引用符を誤って編集してしまう等の、容易に発生し得るエラーを防ぎます。他の種類のエラーもありますが、それらのエラーは翻訳者がVコマンドを使っていつでも、バッチ検証プロセスにより発見・診断することができます。その他のエラーについては、翻訳者自身の判断と、彼女が翻訳したパッケージにたいする同じ母国語ユーザーによる、言語的な判定に頼る必要があります。
翻訳を作成し、機械的な診断およびユーザーによる報告を経た後、翻訳者は以下のコマンドを使って翻訳を変更します。
翻訳を対話的に編集します(po-edit-msgstr
)。
翻訳を元の未翻訳の文字列で再初期化します(po-msgid-to-msgstr
)。
翻訳をkillリングに保存してから、削除します(po-kill-msgstr
)。
翻訳をkillリングに保存するだけで、削除はしません(po-kill-ring-save-msgstr
)。
翻訳をkillリングのもので置き換えます(po-yank-msgstr
)。
RETコマンド(po-edit-msgstr
)は、新しい翻訳を編集したり既存の翻訳を変更するための、新しいEmacsのウィンドウをオープンします。新しいウィンドウにはPOファイルのカレントエントリーの、翻訳のコピーが含まれています。翻訳のコピーは、すぐに編集できるように引用符を除かれていて、Emacsによる編集コマンドのすべてが使用できます。翻訳者が文字列の変更を終えたら、C-c C-cにより、自動的に引用符を付加した形式で結果を保存し、編集用のサブウィンドウを閉じることができます。変更を保存せずに取り消す場合には、C-c C-kを使用してください。詳細は、サブエディションの詳細を参照してください。
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 in The Emacs
Editorを参照してください。最初に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 in The Emacs Editorを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
翻訳とは、言語的な難しさをともなう作業です。翻訳においてどのような決定をしたのか、その選択に関してドキュメントを残す必要があるでしょう。これらのドキュメントは、翻訳者のコメントとしてPOファイルに保存されます。これは、翻訳者が自由に作成・削除、または変更ができるコメントで、彼女が後でPOファイルを見直すときなどに便利です。
最初の‘#’の後に空白がないコメント、たとえば‘#.’や‘#:’ではじまるコメントは、翻訳者のコメントではありません。これらは、gettext
ツールにより作成されたコメントです。それらのシステムが追加したコメントは、翻訳者が変更するべきではないコメントなので、以下で説明するコマンドの対象外です。POファイルのフォーマットを参照してください。
以下のコマンドは翻訳を変更するコマンドと似ているので、一般的な原則は同様に適用できます。翻訳の修正を参照してください。
翻訳者のコメントを対話的に編集します(po-edit-comment
)。
翻訳者のコメントをkillリングに保存してから、削除します(po-kill-comment
)。
翻訳者のコメントをkillリングに保存するだけで、削除はしません(po-kill-ring-save-comment
)。
翻訳者のコメントを、killリングのもので置き換えます(po-yank-comment
)。
これらの、翻訳文字列を変更するためのPOモードの類似コマンドは、翻訳文字列の代わりに翻訳者のコメントを処理する以外は、同じように動作します。詳細はすでに説明済みなので、以下ではこれらのコマンドを簡単に説明します。翻訳の修正を参照してください。
#コマンド(po-edit-comment
)は、POファイルのカレントエントリーにたいする翻訳者コメントのコピーを含む、新しいEmacsウィンドウをオープンします。エントリーにそのようなコメントがない場合、POモードは翻訳者がエントリーにコメントを追加したいと解釈し、空のスクリーンが表示されます。編集前にコメントマーク(#
)とそれに続くスペースは自動的に削除され、編集後に自動的に再付加されます。陳腐化したエントリーにたいする翻訳者コメントは、非コメント化とコメント化の操作が2度行われます。編集ウィンドウでC-c C-cキーを押すと、コメントの編集を終了します。詳細については、サブエディションの詳細を参照してください。
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
)で、以前の翻訳を取得できます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
PO subeditマイナーモードは、ここで詳細な説明をする価値のある特殊なモードです。これによりEmacsの通常の編集コマンド以外に、以下で説明するコマンドがインストールされます。
編集を完了します(po-subedit-exit
)。
編集を中止します(po-subedit-abort
)。
追加(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ファイルがある場合ですが(追加POファイルを調べるを参照してください)。
po-subedit-mode-hook
に関数が登録されている場合には、編集バッファーに文字列が挿入されたときに実行されます。
編集中には、翻訳文字列の最後で意図せずRET(改行)キーを入力したり、必要な改行を誤って削除していまわないよう注意を払う必要があります。そのような文字が編集バッファーで非表示になっていると、容易に間違いを犯してしまいます。そのような間違いが起きないように、RETコマンドでは、編集している文字列の最後に自動的に<
が付加されます。この<
は実際のメッセージ文字列ではありません。C-c C-cで編集ウィンドウを閉じると、POモードは自動的にそのような<文字を削除して、適切な空白文字に置き換えます。翻訳者が末尾の<
の後ろに文字を追加すると、<
は区切り文字としての性質を失って、翻訳文字列の一部となります。<
を削除した場合には、編集文字列はそのまま評価され、たとえ非表示であったとしても、末尾に改行があればそれもそのまま評価されます。翻訳した文字列が本物の<
で終わる場合には、区切り文字の<
も削除されずに表示されるので、編集ウィンドウの文字列の終端には2つの<
が表示されます。
翻訳(またはコメント)を編集するとき、翻訳者はカーソルをPOファイルのバッファーに戻してから、エントリーを表示するために自由に他のエントリーに移動を行えます。編集を保留して、POファイルバッファーの他の箇所に移動したり、他のエントリーの編集をはじめることもできます。それぞれのエントリーは、それら自身のサブエディットバッファーで編集されます。1つのエントリーにたいする特定の翻訳やコメントを同時に編集したり、異なるPOファイルのエントリーを同時に編集することも可能です。すでに編集中のエントリーにたいしてRETをタイプすると、単にそのエントリーの編集を再開します。Emacsの複数のウィンドウの扱いに慣れれば、翻訳者はより快適になるでしょう。
保留したサブエディットの完了または中止は、編集を開始した順番に関わらず任意の順番で行うことができます。複数のサブエディットを保留している状態で、(qコマンドで)POファイルを閉じようとすると、サブエディットが1つずつ順番に再開されるので、翻訳者それら個々について決定していくことができます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
POモードは、GNU
gettext
ユーティリティーで作成されたPOファイルの場合、それらのユーティリティーが生成したPOファイルに特別なコメントを挿入するので、特に威力を発揮します。それらの特別なコメントの中には、POファイルのエントリーの未翻訳の文字列が、プログラムのソース中で出現する位置を示すものがあります。
翻訳者が未翻訳の文字列を翻訳するとき、その元文字列があまりに簡潔すぎたり、不可解あったり、曖昧である等、通常のように有効でない場合があります。そのような文字列をどのように翻訳するか決める前に、その文字列が本当は何を意味するのか、そしてそれにぴったりな翻訳は何なのかを理解する必要があります。このような問題を判断するために残された唯一の方法は、プログラムのソースからその文字列の場所を探し、その周辺に残されたプログラマーのコメントや、他に助けになりそうな何かを探すことに時間を割くことです。
翻訳者が有能なプログラマーである場合、プログラムのソースを見ることにより多くの助けを得ることができるでしょう。しかしプログラミングに精通していなくて、Cのコードを見ると不安な気持ちになったとしても、恥ずかしがらずにたまにはソースを見てみましょう。そうすれば彼女が必要とする何らかのヒントを得られるようになれるでしょう。プログラマーのコメント、そして(彼が適切な名前をつけていれば)変数名や関数名、プログラムコード自体の全体的な構成などに注意を払って学習することにより、すぐにプログラムのコードを見ても違和感を感じないようになるでしょう。
以下は、翻訳者がPOファイルのエントリーから、プログラムのソースコンテキストを参照するのに助けとなるコマンドです。
プログラムのソースコンテキストを表示、またはソースコンテキストのサイクル表示を再開します(po-cycle-source-reference
)。
メニューで選択されたプログラムソースのコンテキストを表示します(po-select-source-reference
)。
ソースファイルの検索パスにディレクトリを追加します(po-consider-source-path
)。
ソースファイルの検索パスからディレクトリを削除します(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
)は、検索パスから削除したいディレクトリーを選択して削除するのに使用されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
POモードには、複数の言語に通じている翻訳者が、彼女の知っている言語への既存の翻訳を利用するための機能があります。この機能は、他の言語への翻訳を追加のコンテキストとして、彼女の作業に提供することができます。また一度に複数の言語への翻訳を作成したいような場合にも、翻訳者にたいして作業を容易にするための機能をもっています。
追加(auxiliary)のPOファイルとは、翻訳者が作業するパッケージの、他の言語用の既存のPOファイルのことです。追加のPOファイルを定義・処理したり、作業中のエントリーのコンテキストを表示するためのコマンドが存在します。
以下は、POモードで利用可能な、追加のPOファイルのコマンドです。
追加のPOファイルから、同じエントリーにたいする他の翻訳を探します(po-cycle-auxiliary
)。
追加のPOファイルを指定して、それに切り替えます(po-select-auxiliary
)。
表示しているPOファイルを、追加のPOファイルとして定義します(po-consider-as-auxiliary
)。
表示している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
ツール間の矛盾を解決するまでは、翻訳者は正規化の問題に留意してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
compendium(要約)とは、多くのパッケージで繰り返し使用される翻訳を含んだ特別なPOファイルのことです。翻訳者はgettextツールを使って、新しいcompendiumを構築して、compendiumに含まれた翻訳から、エントリーをcompendium に追加したり、未翻訳エントリーの初期化、既存の翻訳済みエントリーの更新できます。
8.4.1 compendiaの作成 | Merging translations for later use | |
8.4.2 compendiaの使用 | Using older translations if they fit |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
基本的に、すべてのPOファイルに含まれる翻訳済みエントリーだけを、有効なcompendiumとして定義できます。翻訳者が特別なcompendiaを所有したい場合があります。連結POファイル(concatenating PO files)とPOファイルからメッセージを抽出したサブセット(extracting a message subset from a PO file)という、2つのケースを考えてみましょう。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
複数の有効な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’を使って入力ファイルを前処理するか、結果ファイルを後処理しなければなりません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
同じメッセージを何度も翻訳したいと思う人はいないでしょう。たとえば、あなたがgetopt.cのメッセージを含んだcompendiumファイルが欲しいと思うかもしれません。
既存のPOファイルから1つのcompendiumにメッセージのサブセット(例: getopt.cのすべてのメッセージ)を抽出する場合は、‘msggrep’を使用できます。
msggrep --location src/getopt.c -o compendium.po file.po
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
compendiumファイルを使用して、スクラッチから翻訳を初期化したり、既存の翻訳を更新できます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
まだ翻訳されたPOファイルが存在しないときは、“古い”翻訳済みファイルとして/dev/nullを使用できます。
msgmerge --compendium compendium.po -o file.po /dev/null file.pot
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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 プログラムの呼び出し | Invoking the msgcat Program
| |
9.2 msgconv プログラムの呼び出し | Invoking the msgconv Program
| |
9.3 msggrep プログラムの呼び出し | Invoking the msggrep Program
| |
9.4 msgfilter プログラムの呼び出し | Invoking the msgfilter Program
| |
9.5 msguniq プログラムの呼び出し | Invoking the msguniq Program
| |
9.6 msgcomm プログラムの呼び出し | Invoking the msgcomm Program
| |
9.7 msgcmp プログラムの呼び出し | Invoking the msgcmp Program
| |
9.8 msgattrib プログラムの呼び出し | Invoking the msgattrib Program
| |
9.9 msgen プログラムの呼び出し | Invoking the msgen Program
| |
9.10 msgexec プログラムの呼び出し | Invoking the msgexec Program
| |
9.11 POファイルの一部をハイライトする | Highlighting parts of PO files | |
9.12 POファイルを処理するプログラムを独自に記述する | Writing your own programs that process PO files |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
msgcat
プログラムの呼び出しmsgcat [option] [inputfile]...
msgcat
プログラムは、指定されたPOファイルを結合・マージするプログラムです。プログラムは、指定された複数のPOファイルの中から、2つ以上のファイルで使用されている共通のメッセージを見つけます。--more-than
オプションを使うと、指定したファイル数より多くのファイルで共通のメッセージを出力するか指定できます。反対に--less-than
オプションでは、指定したファイル数より少ないファイルで共通のメッセージを出力するか指定できます(例
‘--less-than=2’
と指定すると一意なメッセージだけが出力されます)。翻訳やコメントは累積されますが、--use-first
を指定した場合は、指定されたPOファイルのうちで最初のものを採用します。すべてのPOファイルの位置情報も累積されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
入力ファイルです。
入力ファイルの名前を、コマンドラインからではなく、fileから読み込みます。
ディレクトリーのリストにdirectoryを追加します。このディレクトリーのリストよりソースファイルを検索します。しかし.poファイルが出力されるのは、カレントディレクトリーです。
inputfileに‘-’が指定された場合は、標準入力から読み込みます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
指定されたファイルに出力を書き込みます。
出力ファイルが指定されていない、または‘-’が指定された場合、結果は標準出力に出力されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
numberに指定した数より少ないメッセージを出力します。指定しなかった場合のデフォルトは無限大です。
numberに指定した数より大きいメッセージを出力します。指定しなかった場合のデフォルトは0です。
‘--less-than=2’の省略指定です。一意なメッセージだけを出力します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
入力ファイルがPOファイルの構文ではなく、Javaの.properties
の構文にのっとったJava
ResourceBundleファイルだとみなします。
入力ファイルがPOファイルの構文ではなく、NeXTstep/GNUstepのlocalized
resourceの.strings
の構文にのっとったファイルだとみなします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
出力のエンコーディングを指定します。
各メッセージで利用可能な最初のメッセージを使用します。複数の翻訳を1つにマージしません。
ヘッダーのエントリーで使用される、‘Language’フィールドを指定します。このフィールドの意味については、ヘッダーエントリーを入力するを参照してください。‘Language-Team’と‘Plural-Forms’のフィールドは変更されないことに注意してください。
色や色以外のテキスト属性を使うか、いつ使うかを指定します。詳細は--color
オプションを参照してください。
--color
にたいしてCSS style ruleファイルを使うかを指定します。詳細は--style
オプションを参照してください。
メッセージが何も含まれていない場合でも、常に出力ファイルに書き込みます。
インデントされた形式で.poファイルを書き込みます。
‘#: filename:line’という行を書き込みません。
‘#: filename:line’という行を生成します(デフォルト)。
Uniforumに厳密に準拠したPOファイルを出力します。このUniforum形式はGNUの拡張をサポートしないため避けたほうがよいでしょう。
Javaの.properties
の書式で、Java ResourceBundleを出力します。このファイル形式はplural
formをサポートせず、陳腐化したメッセージを暗黙で除去することに注意してください。
.strings
の書式で、NeXTstep/GNUstepのローカライズされたリソースファイルを出力します。このファイル形式はplural
formをサポートしないことに注意してください。
出力ページの幅をセットします。これにより出力ファイル中の長い文字列が指定した幅(例:スクリーンの列数)に収まるように、各行の長さがnumber以下のような複数の行に分割されます。
長いメッセージ行を分割しません。出力ページの幅を超えるようなメッセージ行も、複数行に分割されません。出力ページの幅を超えるファイル参照行だけが分割されます。
ソートされた出力を生成します。このオプションを使用することにより翻訳者が、メッセージがどのようなコンテキストで使用されるかを理解するのが、困難になることに注意してください。
ファイルの場所により出力をソートします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このヘルプを表示して終了します。
バージョン情報を表示して終了します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
msgconv
プログラムの呼び出しmsgconv [option] [inputfile]
msgconv
は、ある翻訳カタログを別の文字エンコーディングに変換するプログラムです。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
入力となるPOファイルです。
ディレクトリーのリストにdirectoryを追加します。このディレクトリーのリストよりソースファイルを検索します。しかし.poファイルが出力されるのは、カレントディレクトリーです。
inputfileが指定されていないか、‘-’が指定された場合は、標準入力から読み込みます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
指定されたファイルに出力を書き込みます。
出力ファイルが指定されていない、または‘-’が指定された場合、結果は標準出力に出力されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
出力のエンコーディングを指定します。
デフォルトのエンコーディングは、現在のロケールのエンコーディングです。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
入力ファイルがPOファイルの構文ではなく、Javaの.properties
の構文にのっとったJava
ResourceBundleファイルだとみなします。
入力ファイルがPOファイルの構文ではなく、NeXTstep/GNUstepのlocalized
resourceの.strings
の構文にのっとったファイルだとみなします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
色や色以外のテキスト属性を使うか、いつ使うかを指定します。詳細は--color
オプションを参照してください。
--color
にたいしてCSS style ruleファイルを使うかを指定します。詳細は--style
オプションを参照してください。
メッセージが何も含まれていない場合でも、常に出力ファイルに書き込みます。
インデントされた形式で.poファイルを書き込みます。
‘#: filename:line’という行を書き込みません。
‘#: filename:line’という行を生成します(デフォルト)。
Uniforumに厳密に準拠したPOファイルを出力します。このUniforum形式はGNUの拡張をサポートしないため避けたほうがよいでしょう。
Javaの.properties
の書式で、Java ResourceBundleを出力します。このファイル形式はplural
formをサポートせず、陳腐化したメッセージを暗黙で除去することに注意してください。
.strings
の書式で、NeXTstep/GNUstepのローカライズされたリソースファイルを出力します。このファイル形式はplural
formをサポートしないことに注意してください。
出力ページの幅をセットします。これにより出力ファイル中の長い文字列が指定した幅(例:スクリーンの列数)に収まるように、各行の長さがnumber以下のような複数の行に分割されます。
長いメッセージ行を分割しません。出力ページの幅を超えるようなメッセージ行も、複数行に分割されません。出力ページの幅を超えるファイル参照行だけが分割されます。
ソートされた出力を生成します。このオプションを使用することにより翻訳者が、メッセージがどのようなコンテキストで使用されるかを理解するのが、困難になることに注意してください。
ファイルの場所により出力をソートします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このヘルプを表示して終了します。
バージョン情報を表示して終了します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
msggrep
プログラムの呼び出しmsggrep [option] [inputfile]
msggrep
は翻訳カタログから、指定したパターン、指定したソースファイルに属するすべてのメッセージを抽出するプログラムです。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
入力となるPOファイルです。
ディレクトリーのリストにdirectoryを追加します。このディレクトリーのリストよりソースファイルを検索します。しかし.poファイルが出力されるのは、カレントディレクトリーです。
inputfileが指定されていないか、‘-’が指定された場合は、標準入力から読み込みます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
指定されたファイルに出力を書き込みます。
出力ファイルが指定されていない、または‘-’が指定された場合、結果は標準出力に出力されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
[-N sourcefile]... [-M domainname]... [-J msgctxt-pattern] [-K msgid-pattern] [-T 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を指定してください。
sourcefileから抽出されたメッセージを選択します。sourcefileにはファイル名の文字列、またはワイルドカード文字列を指定できます。
ドメインdomainnameに属するメッセージを選択します。
msgctxtを選択するためのパターンの開始を宣言します。
msgidを選択するためのパターンの開始を宣言します。
msgstrを選択するためのパターンの開始を宣言します。
翻訳者コメントを選択するためのパターンの開始を宣言します。
抽出コメントを選択するためのパターンの開始を宣言します。
patternが、拡張された正規表現であることを指定します。
patternが、改行で区切られた一連の文字列であることを指定します。
patternを、正規表現として使用します。
patternを、fileから取得します。
大文字と小文字を区別しません。
条件に一致するメッセージではなく、一致しないメッセージだけを出力します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
入力ファイルがPOファイルの構文ではなく、Javaの.properties
の構文にのっとったJava
ResourceBundleファイルだとみなします。
入力ファイルがPOファイルの構文ではなく、NeXTstep/GNUstepのlocalized
resourceの.strings
の構文にのっとったファイルだとみなします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
色や色以外のテキスト属性を使うか、いつ使うかを指定します。詳細は--color
オプションを参照してください。
--color
にたいしてCSS style ruleファイルを使うかを指定します。詳細は--style
オプションを参照してください。
メッセージが何も含まれていない場合でも、常に出力ファイルに書き込みます。
インデントされた形式で.poファイルを書き込みます。
‘#: filename:line’という行を書き込みません。
‘#: filename:line’という行を生成します(デフォルト)。
Uniforumに厳密に準拠したPOファイルを出力します。このUniforum形式はGNUの拡張をサポートしないため避けたほうがよいでしょう。
Javaの.properties
の書式で、Java ResourceBundleを出力します。このファイル形式はplural
formをサポートせず、陳腐化したメッセージを暗黙で除去することに注意してください。
.strings
の書式で、NeXTstep/GNUstepのローカライズされたリソースファイルを出力します。このファイル形式はplural
formをサポートしないことに注意してください。
出力ページの幅をセットします。これにより出力ファイル中の長い文字列が指定した幅(例:スクリーンの列数)に収まるように、各行の長さがnumber以下のような複数の行に分割されます。
長いメッセージ行を分割しません。出力ページの幅を超えるようなメッセージ行も、複数行に分割されません。出力ページの幅を超えるファイル参照行だけが分割されます。
ソートされた出力を生成します。このオプションを使用することにより翻訳者が、メッセージがどのようなコンテキストで使用されるかを理解するのが、困難になることに注意してください。
ファイルの場所により出力をソートします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このヘルプを表示して終了します。
バージョン情報を表示して終了します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
msgfilter
プログラムの呼び出しmsgfilter [option] filter [filter-option]
msgfilter
は、翻訳カタログ内の翻訳にフィルターを適用するためのプログラムです。
それぞれのfilter呼び出しにおいて、環境変数のMSGFILTER_MSGID
とMSGFILTER_LOCATION
に、メッセージのmsgidとメッセージを含むPOファイルの場所がバインドされます。メッセージがコンテキストを保有する場合は、環境変数MSGFILTER_MSGCTXT
がメッセージのコンテキストにバインドされます(コンテキストを保有していない場合にはバインドされません)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
入力となるPOファイルです。
ディレクトリーのリストにdirectoryを追加します。このディレクトリーのリストよりソースファイルを検索します。しかし.poファイルが出力されるのは、カレントディレクトリーです。
inputfileが指定されていないか、‘-’が指定された場合は、標準入力から読み込みます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
指定されたファイルに出力を書き込みます。
出力ファイルが指定されていない、または‘-’が指定された場合、結果は標準出力に出力されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
filterは、標準入力から翻訳を読み込み、それに変更を加えて標準出力に書き込むプログラムです。フィルターとして頻繁に使用されるプログラムとしては‘sed’があります。その他にも認識できるビルトインフィルターがいくつか存在します。
注意:
ビルトインではないフィルターの場合には、エンコーディングに注意する必要があります。filterが、入力となる翻訳カタログのエンコードに対処できるようにするのは、あなたの責任となります。filterが入力として特定のエンコーディングを期待する場合には、‘msgfilter’を呼び出す前に、最初のステップとして‘msgconv’で翻訳カタログをそのエンコーディングに変換できます。filterが入力としてlocaleのエンコーディングを期待しているけれど、あなたはlocaleのエンコーディングを無視したいときには、最初に‘msgconv’で翻訳カタログをUTF-8に変換してから、環境変数LC_ALL
にUTF-8
localeを指定して、‘msgfilter’を使うことができます。
注意: 翻訳カタログ内のほとんどの翻訳は改行で終端されていません。そのため、入力の最終行が改行で終端されていなくても、filterがそれを認識すること、そして最終行に余分な改行を付加しないことが重要になります。いくつかのプラットフォームにおいて‘sed’が、改行で終端されていない最終行を無視することが知られています。代用として、このような制限を持たないGNU ‘sed’を使うことができます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
実行するコマンドにscriptを追加します。
実行するコマンドに、scriptfileの内容を追加します。
パターンの空白の出力を自動的に抑制します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
‘recode-sr-latin’はビルトインのフィルターとして認識されます。‘recode-sr-latin’は、Cyrillic文字で記述されたSerbianのテキストを、Latin文字に変換するコマンドです。‘msgfilter recode-sr-latin’コマンドにより、POファイルの翻訳にたいしてこの変換を適用できます。これを使えばsr.poファイルを、sr@latin.poファイルに変換できます。
ビルトインのフィルターは、現在のロケールのエンコーディングとは無関係です。またビルトインのフィルターを使う場合、‘msgfilter’はメッセージカタログのエンコーディングを自動的にUTF-8に変換することができます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
入力ファイルがPOファイルの構文ではなく、Javaの.properties
の構文にのっとったJava
ResourceBundleファイルだとみなします。
入力ファイルがPOファイルの構文ではなく、NeXTstep/GNUstepのlocalized
resourceの.strings
の構文にのっとったファイルだとみなします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
色や色以外のテキスト属性を使うか、いつ使うかを指定します。詳細は--color
オプションを参照してください。
--color
にたいしてCSS style ruleファイルを使うかを指定します。詳細は--style
オプションを参照してください。
メッセージが何も含まれていない場合でも、常に出力ファイルに書き込みます。
インデントされた形式で.poファイルを書き込みます。
ヘッダーのエントリーを保持します(例: ‘msgid ""’にフィルターを適用しないで未変更にします)。デフォルトでは、ヘッダーのエントリーにたいしても、他のメッセージと同様にフィルタリングの対象になります。
‘#: filename:line’という行を書き込みません。
‘#: filename:line’という行を生成します(デフォルト)。
Uniforumに厳密に準拠したPOファイルを出力します。このUniforum形式はGNUの拡張をサポートしないため避けたほうがよいでしょう。
Javaの.properties
の書式で、Java ResourceBundleを出力します。このファイル形式はplural
formをサポートせず、陳腐化したメッセージを暗黙で除去することに注意してください。
.strings
の書式で、NeXTstep/GNUstepのローカライズされたリソースファイルを出力します。このファイル形式はplural
formをサポートしないことに注意してください。
出力ページの幅をセットします。これにより出力ファイル中の長い文字列が指定した幅(例:スクリーンの列数)に収まるように、各行の長さがnumber以下のような複数の行に分割されます。
長いメッセージ行を分割しません。出力ページの幅を超えるようなメッセージ行も、複数行に分割されません。出力ページの幅を超えるファイル参照行だけが分割されます。
ソートされた出力を生成します。このオプションを使用することにより翻訳者が、メッセージがどのようなコンテキストで使用されるかを理解するのが、困難になることに注意してください。
ファイルの場所により出力をソートします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このヘルプを表示して終了します。
バージョン情報を表示して終了します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
msguniq
プログラムの呼び出しmsguniq [option] [inputfile]
msguniq
は、翻訳カタログ内の重複した翻訳を統一するためのプログラムです。このプログラムは、同じメッセージIDにたいする、重複した翻訳を探します。このような重複したメッセージは、msgfmt
、msgmerge
、msgcat
の入力としては無効です。デフォルトでは重複はマージされます。‘--repeated’オプションを指定すると、重複したメッセージだけが出力され、他のすべてのメッセージは破棄されます。コメント、および抽出されたコメントは累積されます。ただし‘--use-first’が指定された場合には、最初の翻訳のものが使用されます。‘--unique’オプションを使用すると、重複は破棄されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
入力となるPOファイルです。
ディレクトリーのリストにdirectoryを追加します。このディレクトリーのリストよりソースファイルを検索します。しかし.poファイルが出力されるのは、カレントディレクトリーです。
inputfileが指定されていないか、‘-’が指定された場合は、標準入力から読み込みます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
指定されたファイルに出力を書き込みます。
出力ファイルが指定されていない、または‘-’が指定された場合、結果は標準出力に出力されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
重複したメッセージだけを出力します。
一意なメッセージだけを出力します(重複したメッセージは破棄されます)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
入力ファイルがPOファイルの構文ではなく、Javaの.properties
の構文にのっとったJava
ResourceBundleファイルだとみなします。
入力ファイルがPOファイルの構文ではなく、NeXTstep/GNUstepのlocalized
resourceの.strings
の構文にのっとったファイルだとみなします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
出力のエンコーディングを指定します。
各メッセージで利用可能な最初のメッセージを使用します。複数の翻訳を1つにマージしません。
色や色以外のテキスト属性を使うか、いつ使うかを指定します。詳細は--color
オプションを参照してください。
--color
にたいしてCSS style ruleファイルを使うかを指定します。詳細は--style
オプションを参照してください。
メッセージが何も含まれていない場合でも、常に出力ファイルに書き込みます。
インデントされた形式で.poファイルを書き込みます。
‘#: filename:line’という行を書き込みません。
‘#: filename:line’という行を生成します(デフォルト)。
Uniforumに厳密に準拠したPOファイルを出力します。このUniforum形式はGNUの拡張をサポートしないため避けたほうがよいでしょう。
Javaの.properties
の書式で、Java ResourceBundleを出力します。このファイル形式はplural
formをサポートせず、知能化したメッセージを暗黙で除去することに注意してください。
.strings
の書式で、NeXTstep/GNUstepのローカライズされたリソースファイルを出力します。このファイル形式はplural
formをサポートしないことに注意してください。
出力ページの幅をセットします。これにより出力ファイル中の長い文字列が指定した幅(例:スクリーンの列数)に収まるように、各行の長さがnumber以下のような複数の行に分割されます。
長いメッセージ行を分割しません。出力ページの幅を超えるようなメッセージ行も、複数行に分割されません。出力ページの幅を超えるファイル参照行だけが分割されます。
ソートされた出力を生成します。このオプションを使用することにより翻訳者が、メッセージがどのようなコンテキストで使用されるかを理解するのが、困難になることに注意してください。
ファイルの場所により出力をソートします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このヘルプを表示して終了します。
バージョン情報を表示して終了します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
msgcomm
プログラムの呼び出しmsgcomm [option] [inputfile]...
msgcomm
は、指定された2つ以上のファイルから、共通のメッセージを探すプログラムです。--more-than
オプションを使用すると、指定された数より多くのファイルで共通のメッセージを出力します。反対に--less-than
オプションを使用すると、指定された数より少ないファイルで共通のメッセージを出力します(例:
‘--less-than=2’は一意なメッセージだけを出力します)。翻訳、コメント、および抽出されたコメントは蓄積されます(最初のPOファイルのものを使用するように指定した場合を除く)。POファイルのファイル位置の情報も蓄積されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
入力ファイルです。
入力ファイルの名前を、コマンドラインからではなく、fileから読み込みます。
ディレクトリーのリストにdirectoryを追加します。このディレクトリーのリストよりソースファイルを検索します。しかし.poファイルが出力されるのは、カレントディレクトリーです。
inputfileに‘-’が指定された場合は、標準入力から読み込みます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
指定されたファイルに出力を書き込みます。
出力ファイルが指定されていない、または‘-’が指定された場合、結果は標準出力に出力されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
numberに指定した数より少ないメッセージを出力します。指定しなかった場合のデフォルトは無限大です。
numberに指定した数より大きいメッセージを出力します。指定しなかった場合のデフォルトは1です。
‘--less-than=2’の省略指定です。一意なメッセージだけを出力します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
入力ファイルがPOファイルの構文ではなく、Javaの.properties
の構文にのっとったJava
ResourceBundleファイルだとみなします。
入力ファイルがPOファイルの構文ではなく、NeXTstep/GNUstepのlocalized
resourceの.strings
の構文にのっとったファイルだとみなします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
色や色以外のテキスト属性を使うか、いつ使うかを指定します。詳細は--color
オプションを参照してください。
--color
にたいしてCSS style ruleファイルを使うかを指定します。詳細は--style
オプションを参照してください。
メッセージが何も含まれていない場合でも、常に出力ファイルに書き込みます。
インデントされた形式で.poファイルを書き込みます。
‘#: filename:line’という行を書き込みません。
‘#: filename:line’という行を生成します(デフォルト)。
Uniforumに厳密に準拠したPOファイルを出力します。このUniforum形式はGNUの拡張をサポートしないため避けたほうがよいでしょう。
Javaの.properties
の書式で、Java ResourceBundleを出力します。このファイル形式はplural
formをサポートせず、陳腐化したメッセージを暗黙で除去することに注意してください。
.strings
の書式で、NeXTstep/GNUstepのローカライズされたリソースファイルを出力します。このファイル形式はplural
formをサポートしないことに注意してください。
出力ページの幅をセットします。これにより出力ファイル中の長い文字列が指定した幅(例:スクリーンの列数)に収まるように、各行の長さがnumber以下のような複数の行に分割されます。
長いメッセージ行を分割しません。出力ページの幅を超えるようなメッセージ行も、複数行に分割されません。出力ページの幅を超えるファイル参照行だけが分割されます。
ソートされた出力を生成します。このオプションを使用することにより翻訳者が、メッセージがどのようなコンテキストで使用されるかを理解するのが、困難になることに注意してください。
ファイルの場所により出力をソートします。
Don’t write header with ‘msgid ""’ entry.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このヘルプを表示して終了します。
バージョン情報を表示して終了します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
msgcmp
プログラムの呼び出しmsgcmp [option] def.po ref.pot
msgcmp
プログラムは、Uniforum形式の2つの.poファイルを比較して、同じmsgid文字列を含んでいるかチェックするプログラムです。def.poファイルは、翻訳を含んだ既存のPOファイルです。ref.potは、最後に作成したPOファイル、またはPO
Templateファイル(通常xgettext
により作成される)です。このプログラムは、プログラム内のメッセージが翻訳されているかチェックするときに便利です。完全に一致するエントリーが見つからない場合は、より良い診断メッセージを生成するためにfuzzyマッチングが行われます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
翻訳です。
ソースへの参照です。
ディレクトリーのリストにdirectoryを追加します。このディレクトリーのリストよりソースファイルを検索します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
def.po 内の各ドメインにたいしてref.potを適用します。
完全に一致するものが見つからない場合、fuzzyマッチングを行いません。これにより処理のスピードが大幅に改善されます。
def.po内のfuzzyメッセージを、翻訳されたメッセージとみなします。fuzzyメッセージは翻訳者により検証されていないので、普通はこのオプションを使うのは正しくないことに注意してください。
def.po内の未翻訳のメッセージを、翻訳されたメッセージとみなします。普通はこのオプションを使うのは正しくないことに注意してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
入力ファイルがPOファイルの構文ではなく、Javaの.properties
の構文にのっとったJava
ResourceBundleファイルだとみなします。
入力ファイルがPOファイルの構文ではなく、NeXTstep/GNUstepのlocalized
resourceの.strings
の構文にのっとったファイルだとみなします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このヘルプを表示して終了します。
バージョン情報を表示して終了します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
msgattrib
プログラムの呼び出しmsgattrib [option] [inputfile]
msgattrib
プログラムは、翻訳カタログのメッセージの属性にしたがってフィルターを適用したり、属性を操作するためのプログラムです。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
入力となるPOファイルです。
ディレクトリーのリストにdirectoryを追加します。このディレクトリーのリストよりソースファイルを検索します。しかし.poファイルが出力されるのは、カレントディレクトリーです。
inputfileが指定されていないか、‘-’が指定された場合は、標準入力から読み込みます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
指定されたファイルに出力を書き込みます。
出力ファイルが指定されていない、または‘-’が指定された場合、結果は標準出力に出力されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
翻訳されたメッセージを残して、未翻訳のメッセージは削除します。
未翻訳のメッセージを残して、翻訳済みのメッセージは削除します。
削除: ‘fuzzy’ とマークされたメッセージを削除します。
保持: ‘fuzzy’ とマークされたメッセージを残して、他のすべてのメッセージは削除します。
#~のついた廃止されたメッセージを削除します。
#~のついた廃止されたメッセージを残して、他のすべてのメッセージは削除します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
メッセージの選択・削除が実行された後に、属性は変更されます。‘--only-file’か‘--ignore-file’オプションを指定すると、only-fileに記載されたメッセージ、もしくはignore-fileに記載されていないメッセージにだけ、変更が適用されます。
すべてのメッセージに、 ‘fuzzy’をセットします。
すべてのメッセージに、 非‘fuzzy’をセットします。
すべてのメッセージを、陳腐化したメッセージにします。
陳腐化したメッセージを、陳腐化していないメッセージにセットします。
もし ‘fuzzy’ とマークされているとき、翻訳されたメッセージの“以前のmsgid”を残します。
すべてのメッセージから、“以前のmsgid”であることを示すコメントマーク(‘#|’)がついたものを削除します。
fileに記載されたエントリーの属性だけを変更します。fileにはPO、またはPOTファイルを指定します。
fileに記載されていないエントリーの属性だけを変更します。fileにはPO、またはPOTファイルを指定します。
‘--only-fuzzy --clear-fuzzy’の省略指定です。fuzzyメッセージだけを残すとともに、それらのメッセージの ‘fuzzy’ マークを外します。
‘--only-obsolete --clear-obsolete’の省略指定です。廃止されたメッセージだけを残すとともに、それらのメッセージが陳腐化していることを示すマークを外します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
入力ファイルがPOファイルの構文ではなく、Javaの.properties
の構文にのっとったJava
ResourceBundleファイルだとみなします。
入力ファイルがPOファイルの構文ではなく、NeXTstep/GNUstepのlocalized
resourceの.strings
の構文にのっとったファイルだとみなします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
色や色以外のテキスト属性を使うか、いつ使うかを指定します。詳細は--color
オプションを参照してください。
--color
にたいしてCSS style ruleファイルを使うかを指定します。詳細は--style
オプションを参照してください。
メッセージが何も含まれていない場合でも、常に出力ファイルに書き込みます。
インデントされた形式で.poファイルを書き込みます。
‘#: filename:line’という行を書き込みません。
‘#: filename:line’という行を生成します(デフォルト)。
Uniforumに厳密に準拠したPOファイルを出力します。このUniforum形式はGNUの拡張をサポートしないため避けたほうがよいでしょう。
Javaの.properties
の書式で、Java ResourceBundleを出力します。このファイル形式はplural
formをサポートせず、陳腐化したメッセージを暗黙で除去することに注意してください。
.strings
の書式で、NeXTstep/GNUstepのローカライズされたリソースファイルを出力します。このファイル形式はplural
formをサポートしないことに注意してください。
出力ページの幅をセットします。これにより出力ファイル中の長い文字列が指定した幅(例:スクリーンの列数)に収まるように、各行の長さがnumber以下のような複数の行に分割されます。
長いメッセージ行を分割しません。出力ページの幅を超えるようなメッセージ行も、複数行に分割されません。出力ページの幅を超えるファイル参照行だけが分割されます。
ソートされた出力を生成します。このオプションを使用することにより翻訳者が、メッセージがどのようなコンテキストで使用されるかを理解するのが、困難になることに注意してください。
ファイルの場所により出力をソートします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このヘルプを表示して終了します。
バージョン情報を表示して終了します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
msgen
プログラムの呼び出しmsgen [option] inputfile
msgen
は、Englishの翻訳カタログを作成するプログラムです。最後に作成されたEnglishのPOファイル、またはPO
Template(xgettext により生成されます)を入力とし、未翻訳エントリーの翻訳に、msgidと同じ文字列を割り当てます。
注意: ‘msginit --no-translator
--locale=en’でも、同じような処理を行うことができます。異なるのは、msginit
はヘッダーエントリーにたいして特別な配慮を払いますが、msgen
は異なるという点です。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
入力となるPOまたはPOTファイルです。
ディレクトリーのリストにdirectoryを追加します。このディレクトリーのリストよりソースファイルを検索します。しかし.poファイルが出力されるのは、カレントディレクトリーです。
inputfileに‘-’が指定された場合は、標準入力から読み込みます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
指定されたファイルに出力を書き込みます。
出力ファイルが指定されていない、または‘-’が指定された場合、結果は標準出力に出力されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
入力ファイルがPOファイルの構文ではなく、Javaの.properties
の構文にのっとったJava
ResourceBundleファイルだとみなします。
入力ファイルがPOファイルの構文ではなく、NeXTstep/GNUstepのlocalized
resourceの.strings
の構文にのっとったファイルだとみなします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ヘッダーエントリーで使用される、‘Language’フィールドを指定します。このフィールドの意味については、ヘッダーエントリーを入力するを参照してください。注意: このオプションでは、‘Language-Team’と‘Plural-Forms’はセットされません。
色や色以外のテキスト属性を使うか、いつ使うかを指定します。詳細は--color
オプションを参照してください。
--color
にたいしてCSS style ruleファイルを使うかを指定します。詳細は--style
オプションを参照してください。
メッセージが何も含まれていない場合でも、常に出力ファイルに書き込みます。
インデントされた形式で.poファイルを書き込みます。
‘#: filename:line’という行を書き込みません。
‘#: filename:line’という行を生成します(デフォルト)。
Uniforumに厳密に準拠したPOファイルを出力します。このUniforum形式はGNUの拡張をサポートしないため避けたほうがよいでしょう。
Javaの.properties
の書式で、Java ResourceBundleを出力します。このファイル形式はplural
formをサポートせず、陳腐化したメッセージを暗黙で除去することに注意してください。
.strings
の書式で、NeXTstep/GNUstepのローカライズされたリソースファイルを出力します。このファイル形式はplural
formをサポートしないことに注意してください。
出力ページの幅をセットします。これにより出力ファイル中の長い文字列が指定した幅(例:スクリーンの列数)に収まるように、各行の長さがnumber以下のような複数の行に分割されます。
長いメッセージ行を分割しません。出力ページの幅を超えるようなメッセージ行も、複数行に分割されません。出力ページの幅を超えるファイル参照行だけが分割されます。
ソートされた出力を生成します。このオプションを使用することにより翻訳者が、メッセージがどのようなコンテキストで使用されるかを理解するのが、困難になることに注意してください。
ファイルの場所により出力をソートします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このヘルプを表示して終了します。
バージョン情報を表示して終了します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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を処理するようにできます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
入力となるPOファイルです。
ディレクトリーのリストにdirectoryを追加します。このディレクトリーのリストよりソースファイルを検索します。しかし.poファイルが出力されるのは、カレントディレクトリーです。
inputfileが指定されていないか、‘-’が指定された場合は、標準入力から読み込みます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
入力ファイルがPOファイルの構文ではなく、Javaの.properties
の構文にのっとったJava
ResourceBundleファイルだとみなします。
入力ファイルがPOファイルの構文ではなく、NeXTstep/GNUstepのlocalized
resourceの.strings
の構文にのっとったファイルだとみなします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このヘルプを表示して終了します。
バージョン情報を表示して終了します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
翻訳者は通常、POファイル中の未翻訳、およびfuzzyメッセージを見ることだけに関心を持っています。また、msgidが変更されたことによりメッセージにfuzzyがセットされたときに、以前のメッセージと現在のメッセージの差分を見たいと望みます(長いmsgidの中の数語が変更されたときは特に)。そして最後に、POファイル内のセクションのメッセージ(コメント、msgid、msgstrなど)の違いを強調するのは、いつでも歓迎します。
このような強調表示は、msgcat
の‘--color’と‘--style’オプションで可能になります。
9.11.1 --color オプション | Triggering colorized output | |
9.11.2 環境変数TERM | The environment variable TERM
| |
9.11.3 --style オプション | The --style option
| |
9.11.4 POファイルのスタイルルール | Style rules for PO files | |
9.11.5 POファイルを閲覧するためにless をカスタマイズする | Customizing less for viewing PO files
|
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
--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
オプションで生成した結果をファイルに保存する必要はありません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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’により設定を検証するとともに、適切なカラーマップに見えるか出力を視認できます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
--style
オプション‘--style=style_file’オプションで、着色時に使用するスタイルファイルを指定できます。この指定は--color
が有効なときだけ効果があります。
--style
オプションが指定されていないときは、環境変数PO_STYLE
が使用されます。この環境変数にはユーザーが好むPOファイル用のスタイルファイルを指定します。
デフォルトのスタイルファイルは、$prefix/share/gettext/styles/po-default.cssです。$prefix
はインストールした場所です。
いくつかのスタイルファイルが事前に定義されています:
このスタイルはvim 7の表示を模倣します。
このスタイルは、X11ウィンドウでのGNU Emacs 21、22の表示を模倣します。
このスタイルは、‘xterm’(8色)、‘xterm-16color’(16色)、‘xterm-256color’(256色)の端末でGNU Emacs 22を実行したときの表示を模倣します。
これらのスタイルについてはディレクトリーを指定しなくても使うことができます。これらのスタイルファイルは$prefix/share/gettext/styles/にあります。$prefix
はインストールした場所です。
あなた自身でスタイルをデザインできます。これは次のセクションで説明します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
端末出力とHTML出力で、同じPOファイル用スタイルを使用できます。POファイル用のスタイルはCSS(Cascading Style Sheet)の書式で記述します。CSSの正式な定義については、http://www.w3.org/TR/css2/cover.htmlを参照してください。CSSについての説明を含んだ、HTML記述のチュートリアルも数多く存在します。
HTML出力の場合、スタイルファイルはHTML出力中に埋め込まれます。テキスト出力の場合、スタイルファイルはmsgcat
プログラムにより逐次解釈されます。これは@import
に関連するファイル名が指定されていて、そのファイル名が以下のような場合、特に意味をもちます:
@import
を含む、関係のあるスタイルシート(実際にこのようなケースでは、libcrocoの制限により@importはまだサポートされていません)。
CSSルールはselectorとdeclarationにより構築されます。declarationにはグラフィカルなプロパティーを指定し、selectorにはそれをいつ適用するかを指定します。
POファイル用に、以下の簡単なselectorがサポートされています("CSS classes"を基本とします。詳細はCSS2 specのsection 5.8.3を参照してください)。
.header
POファイルのヘッダーエントリーにマッチします。
.translated
翻訳されたメッセージにマッチします。
.untranslated
未翻訳のメッセージにマッチします(例: 翻訳が空のメッセージ)。
.fuzzy
fuzzyメッセージにマッチします(例: 翻訳者のレビューが必要な翻訳をともなうメッセージ)。
.obsolete
陳腐化したメッセージにマッチします(例: 現在のPOTファイルでは必要とされない翻訳済みのメッセージ)。
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重引用符)を含む文字列にマッチします。
.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
に制限されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
less
をカスタマイズする‘less’は、テキストスクリーンやterminal emulatorでテキストファイルを閲覧するための一般的なプログラムです。このプログラムは、色表示や文字飾りのための埋め込みエスケープシーケンスもサポートします。
以下のようにして、POファイルの閲覧にless
を使用できます(UTF-8 環境の場合):
msgcat --to-code=UTF-8 --color xyz.po | less -R
これと同じことを、次ような簡単なコマンドで行うための方法を説明します:
less xyz.po
以下の3つの準備が必要です:
LESS
に‘-R’と‘-f’のオプションを追加します:
$ LESS="$LESS -R -f" $ export LESS
LESSOPEN
、LESSCLOSE
にセットします。
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
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
‘msgattrib’や‘msgcat’などの組み合わせによる処理では十分でない場合のために、一連のC関数がライブラリにより提供されています。これを使うことにより、あなたのプログラムからPOファイルを処理できるようになります。ライブラリーを使う場合は、POファイルをパースするルーチンを自分で記述する必要はありません。かわりにPOファイル内の各メッセージに対応するメモリーへのポインターを取得することができます。現時点では、POファイルへ書き込むための関数は提供されていません。
関数はヘッダーファイル‘<gettext-po.h>’で宣言されており、‘libgettextpo’というライブラリーで定義されています。
POファイルのコンテンツをメモリーに読み込んだ後に、それらを参照するためのポインター型です。
一連のメッセージを生成するiteratorを参照するためのポインター型です。
POファイルのメッセージ(翻訳を含む)を参照するためのポインター型です。
関数po_file_read
は、引数としてファイル名を受け取り、そのPOファイルをメモリー内に読み込みます。戻り値はPOファイル内のコンテンツへのハンドルで、そのハンドルはpo_file_free
が呼び出されるまで有効です。エラーが発生したときの戻り値はNULL
で、errno
がセットされます。
関数po_file_free
は、メモリー内のPOファイルのコンテンツを解放します。iteratorを通じて暗黙にアクセス可能なすべてのメッセージも解放されます。
関数po_file_domains
は、メッセージを所有するPOファイルのdomainを戻します。戻り値はNULL
で終端された配列で、この配列はfileのハンドルが有効な間は有効です。‘domain’指定を持たないPOファイルの場合は、デフォルトのドメインである"messages"
という名前のドメインだけが戻されます。
po_message_iterator
は、与えられたdomainに属するfileのメッセージを生成するiteratorを戻します。domainがNULL
のときは、かわりにデフォルトのdomainが使用されます。関数po_next_message
を繰り返し呼び出すと、メッセージをリストすることができます。
関数po_message_iterator_free
は、関数po_message_iterator
により割り当てられたiteratorを開放します。
関数po_next_message
は、iteratorから次のメッセージを戻すとともにiteratorを1つ進めます。メッセージリストの終端に達すると、NULL
が戻されます。
以下はpo_message_t
のメンバーを戻す関数です。fileハンドルが有効な間は、呼び出しによる結果も有効です。
関数po_message_msgid
は、メッセージのmsgid
(未翻訳のEnglish文字列)を戻します。この結果は、非NULL
であることが保証されています。
関数po_message_msgid_plural
は、pluralをもつメッセージのmsgid_plural
(未翻訳のEnglish
plural文字列)を戻します。メッセージがpluralをもたない場合には、NULL
が戻されます。
関数po_message_msgstr
は、メッセージのmsgstr
(翻訳済み)を戻します。未翻訳のメッセージの場合は、空文字列が戻されます。
関数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);
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
10.1 msgfmt プログラムの呼び出し | Invoking the msgfmt Program
| |
10.2 msgunfmt プログラムの呼び出し | Invoking the msgunfmt Program
| |
10.3 GNU MOファイルのフォーマット | The Format of GNU MO Files |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
msgfmt
プログラムの呼び出しmsgfmt [option] filename.po …
msgfmt
は、翻訳済みのテキストのメッセージから、バイナリーのメッセージカタログを生成するプログラムです。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ディレクトリーのリストにdirectoryを追加します。このディレクトリーのリストよりソースファイルを検索します。しかし、結果となるバイナリーファイルが出力されるのは、カレントディレクトリーです。
入力ファイルに‘-’が指定された場合は、標準入力から読み込みます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Javaモード: JavaのResourceBundle
クラスを生成します。
–javaと同様ですがJava2(JDK 1.2以上)とみなします。
C#モード: GettextResourceSet
のサブクラスを含んだ、.NETの.dllファイルを生成します。
C# resourcesモード: .NETの.resourcesファイルを生成します。
Tclモード: tcl/msgcatの.msgファイルを生成します。
Qtモード: Qtの.qmファイルを生成します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
指定されたファイルに出力を書き込みます。
プログラムがUniforum/Sun実装にしたがうように指定します。これは現時点では、出力ファイルの名前に影響を与えるだけです。オプションにファイル名を指定しなかった場合、出力ファイルは同じdomain 名になります。厳密なUniforumモードが有効でファイル名が与えられなかった場合には、ファイル名に.moが付加されます。
わたしたちはこのSun実装は意味がないと考え、デフォルトではこのモードは選択されません。
出力となるfileに‘-’が指定されたときは、出力は標準出力に書き込まれます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
リソース名を指定します。
locale名を指定します。ll形式による言語指定と、国と言語指定を組み合わせたll_CCのどちらでも指定できます。
classのディレクトリー階層のベースとなるディレクトリーを指定します。
クラス名はリソース名の後ろに区切り文字のアンダースコアーとlocale名を付加して決定されます。‘-d’オプションは必須です。クラスは指定されたディレクトリーに出力されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
リソース名を指定します。
locale名を指定します。ll形式による言語指定と、国と言語指定を組み合わせたll_CCのどちらでも指定できます。
localeに依存する.dllファイルを出力するベースディレクトリーを指定します。
\‘-l’と‘-d’が必須オプションです。.dllファイルは、localeに依存した名前の指定ディレクトリーのサブディレクトリーに出力されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
locale名を指定します。ll形式による言語指定と、国と言語指定を組み合わせたll_CCのどちらでも指定できます。
メッセージカタログ.msgのベースディレクトリーを指定します。
‘-l’と‘-d’は必須オプションです。.msgは指定されたディレクトリーに出力されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
入力ファイルがPOファイルの構文ではなく、Javaの.properties
の構文にのっとったJava
ResourceBundleファイルだとみなします。
入力ファイルがPOファイルの構文ではなく、NeXTstep/GNUstepのlocalized
resourceの.strings
の構文にのっとったファイルだとみなします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
--check-format
、--check-header
、--check-domain
がすべて指定されたとみなしてチェックを行います。
languageに依存した書式文字列をチェックします。
文字列がprintf
のような関数で使用される書式文字列の場合、書式指定子‘%’と、それらに対応する型の変数の個数は一致するはずです。エントリーにたいして#,コメントでc-format
やpossible-c-format
フラグが指定されている場合は、チェックが行われます。たとえば、‘%s’が期待される箇所に‘%.*s’や‘%d’が使われていたり、‘%x’が期待される箇所に‘%d’が使われている場合、チェックは診断メッセージを出力します。このチェックは位置パラメーターを処理することさえできるのです。
xgettext
プログラムは通常、ある文字列が書式文字列かどうかを、自動的に判定します。しかしこのアルゴリズムも完全ではありません。そのため、printf
のような関数で使用されていない文字列を書式文字列とみなしてしまい、エラーが存在しないにもかかわらずmsgfmt
がエラーを報告する場合があります。
プログラマーがxgettext
に判定結果を指示することにより、この問題を解決することができます(Cフォーマット文字列を参照してください)。翻訳者は#,行からフラグを削除しようと考える必要はありません。なぜならこの"fix"は、次にmsgmerge
を呼び出したときに元に戻されてしまうからです。
ヘッダーエントリーの存在および内容をチェックします。ヘッダーエントリーのさまざまなフィールドの説明は、ヘッダーエントリーを入力するを参照してください。
domain指定と--output-file
オプションの競合をチェックします。
GNU msgfmtがX/Open msgfmtのように振る舞うかをチェックします。GNU拡張を使用しているとエラーになります。
メニューアイテムにたいしてキーボードアクセラレーターの存在をチェックします。このチェックは、いくつかのGUIにおいてメニューアイテム文字列内のキーボードアクセラレーターが、‘&’のすぐ後ろに続く文字としてデザインされていることにもとづきます。キーボードアクセラレーターが"keyboard mnemonic"と呼ばれることもあります。このチェックは、未翻訳文字列に‘&’が1つあるとき、翻訳文字列にも1つの‘&’があるかをチェックします。このオプションの引数にcharが与えらる場合、charには非英数文字を指定します。指定した文字は‘&’のかわりに、キーボードアクセラレーターのマークとして使用されます。
出力にfuzzyエントリーを使用します。これらのfuzzyメッセージは人間の翻訳者により検証されたものではないため、このオプションの使用は通常は正しくないことに注意してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
文字列をnumberバイトに揃えます(デフォルトは1)。
32ビットの数字を与えられたバイト順で書き出します。big
とlittle
を指定できます。デフォルトはプラットフォーム、正確に言うとCPUのインディアンに依存します。
任意のインディアンをもつMOファイルは、任意のプラットフォームで使用できます。MOファイルのインディアンがプラットフォームのものでない場合、32ビットの数値は実行時に交換されます。パフォーマンスに与える影響は無視できるものです。
このオプションは、プラットフォームに束縛されずMOを作成するために便利です。
バイナリーファイルにハッシュテーブルを含めないようにします。(ハッシュテーブルを参照するかわりに、バイナリーサーチが行われるため)実行時の検索が、より高価な処理となります。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このヘルプを表示して終了します。
バージョン情報を表示して終了します。
翻訳の統計情報を表示します。--statistics
とともに--verbose
オプションが指定された場合は、統計行の前に入力ファイルの名前が出力されます。
診断レベルを上げます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
msgunfmt
プログラムの呼び出しmsgunfmt [option] [file]...
msgunfmt
は、バイナリーのメッセージカタログを、Uniforum形式の.poファイルに変換するプログラムです。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Javaモード: JavaのResourceBundle
class が入力となります。
C#モード: GettextResourceSet
のサブクラスを含む.NETの.dllファイルが入力となります。
C# resourcesモード: .NETの.resourcesファイルが入力となります。
Tclモード: tcl/msgcatの.msgファイルが入力となります。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
入力となる.moファイルです。
fileが指定されていないか、‘-’が指定された場合は、標準入力から読み込みます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
リソース名を指定します。
locale名を指定します。ll形式による言語指定と、国と言語指定を組み合わせたll_CCのどちらでも指定できます。
class名は、resource名の後ろにアンダースコアーをつけて、その後ろにlocale
名を付加することにより決定されます。classは、CLASSPATH
によって配置されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
リソース名を指定します。
locale名を指定します。ll形式による言語指定と、国と言語指定を組み合わせたll_CCのどちらでも指定できます。
localeに依存する.dllファイルを出力するベースディレクトリーを指定します。
‘-l’と‘-d’が必須オプションです。.msgファイルは、locale に依存した名前の指定ディレクトリーのサブディレクトリーに配置されています。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
locale名を指定します。ll形式による言語指定と、国と言語指定を組み合わせたll_CCのどちらでも指定できます。
メッセージカタログ.msgのベースディレクトリーを指定します。
‘-l’と‘-d’は必須オプションです。.msgは指定されたディレクトリーに配置されています。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
指定されたファイルに出力を書き込みます。
出力ファイルが指定されていない、または‘-’が指定された場合、結果は標準出力に出力されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
色や色以外のテキスト属性を使うか、いつ使うかを指定します。詳細は--color
オプションを参照してください。
--color
にたいしてCSS style ruleファイルを使うかを指定します。詳細は--style
オプションを参照してください。
メッセージが何も含まれていない場合でも、常に出力ファイルに書き込みます。
インデントされた形式で.poファイルを書き込みます。
Uniforumに厳密に準拠したPOファイルを出力します。このUniforum形式はGNUの拡張をサポートしないため避けたほうがよいでしょう。
Javaの.properties
の書式で、Java ResourceBundleを出力します。このファイル形式はplural
formをサポートせず、陳腐化したメッセージを暗黙で除去することに注意してください。
.strings
の書式で、NeXTstep/GNUstepのローカライズされたリソースファイルを出力します。このファイル形式はplural
formをサポートしないことに注意してください。
出力ページの幅をセットします。これにより出力ファイル中の長い文字列が指定した幅(例:スクリーンの列数)に収まるように、各行の長さがnumber以下のような複数の行に分割されます。
長いメッセージ行を分割しません。出力ページの幅を超えるようなメッセージ行も、複数行に分割されません。出力ページの幅を超えるファイル参照行だけが分割されます。
ソートされた出力を生成します。このオプションを使用することにより翻訳者が、メッセージがどのようなコンテキストで使用されるかを理解するのが、困難になることに注意してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このヘルプを表示して終了します。
バージョン情報を表示して終了します。
診断レベルを上げます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
生成された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 <-----------------' | | ... ... | | +------------------------------------------+
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
GNU
gettext
により提供される現在のメッセージカタログの実装は、インストーラーにより選択された場合にはシステムによるメッセージカタログ処理を使用することを目標にしています。そのため、まず最初に既知の解決策を概観しておく必要があるかもしれません。POSIXコミティーの人たちは、以下で説明する準公式な標準候補のうちから1つを採択して管理しませんでした。実際、彼らは何も採択せず、インターフェースの例を含めるだけに決めました。Unixのメジャーなベンダーによるのインターフェースの採用は、X/Openのcatgetsと、Uniforumのgettextに二分されました。以下ではそれらのインターフェースについて説明するとともに、このジレンマにたいするわたしたちの解決策を説明します。
11.1 catgets について | About catgets
| |
11.2 gettext について | About gettext
| |
11.3 2つのインターフェースの比較 | Comparing the two interfaces | |
11.4 独自のプログラム内でlibintl.aを使用する | Using libintl.a in own programs | |
11.5 gettext を根底から理解する | Being a gettext grok
| |
11.6 プログラマの章についての一時的なメモ | Temporary Notes for the Programmers Chapter |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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 インターフェース | The interface | |
11.1.2 catgets インターフェースに関する問題点?! | Problems with the catgets interface?!
|
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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
の呼び出しには使用できません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
catgets
インターフェースに関する問題点?!これを説明するのはとても簡単に見えます — わたしたちが話してきたインターフェースのどこに問題があったのでしょうか?
実際のところ、分別のある使い方をするかぎり、そのインターフェースを使うことはできます。しかしメッセージカタログを構築するのは苦痛をともないます。その理由はcatgets
の3番目の引数となる、一意なmessage
IDです。これには、すべてのメッセージのペアごとに、数字を割り当てなければなりません。ソースコードの変更、たとえばメッセージを追加したり削除するときに、このリストを保守する際に発生する問題を想像してみてください。もちろん、この混沌を組織化するためのツールもたくさん開発されました。しかし、あるツールで処理できるのに、他のツールでは読み込めないといった様相でした。より簡単に管理できて問題もない、他のやり方はあるのですが、述べないでおきましょう。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
gettext
についてgettext
のインターフェースの定義は、Uniforumの提案によるものです。これはSunから提出されたもので、Sunは1990頃に、SunOS4でgettext
を実装済みでした。現在では、gettext
のインターフェースは、OpenI18N標準により規定されています。
この解決策の主要な点は、通常のファイル処理の手順(open-use-close)を踏襲しないことと、プログラマーに負担(特に一意なキーの取扱いにたいして)をかけないことにあります。もちろん一意なキーは必要なので、(メッセージの長短に関わらず)メッセージ自身をキーとします。比較に関する2つの方法の詳細については、2つのインターフェースの比較を参照してください。
以下のセクションでは、より詳細にインターフェースを説明します。インターフェースについて詳細を掘り下げて説明するのは、それが GNU
gettext
ライブラリーに密接に関係しているからです。ライブラリーの使い方に興味をもつプログラマーは、この説明にも興味をもつことでしょう。
11.2.1 インターフェース | The interface | |
11.2.2 あいまいざの解決 | Solving ambiguities | |
11.2.3 メッセージカタログファイルの配置 | Locating message catalog files | |
11.2.4 gettext が使用する出力文字セットの指定方法 | How to request conversion to Unicode | |
11.2.5 あいまいさの解決のためにコンテキストを使用する | Solving ambiguities in GUI programs | |
11.2.6 複数形(plural forms)にたいする追加の関数 | Additional functions for handling plurals | |
11.2.7 *gettext関数の最適化 | Optimization of the *gettext functions |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
インターフェースは最小限、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関数により処理されます。これだけでパッケージがあなたの言語で話し出すのです。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ほとんどのアプリケーションでは、単一のドメイン名でうまく動作するかもしれませんが、複数のドメインから翻訳を取得する必要があるアプリケーションも存在します。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
コマンドを呼び出すことにより、カレントディレクトリーに関連づいた相対パスは、再計算されます。相対パスの使用により、常に非依存性と信頼性が無効にされます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
さまざまなパッケージごとに、多くの異なる言語を保存する必要があるという理由により、わたしたちにはこれらの情報をメッセージカタログファイルに記録するための、何らかの方法が必要です。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
になります3。locale
category の名前は、setlocale (LC_category,
NULL)
を通じて決定されます4。dcgettext
関数では、3番目の引数にlocale
categoryを指定できます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
gettext
が使用する出力文字セットの指定方法gettext
は、メッセージカタログ内の翻訳を取得するだけでなく、オンザフライで翻訳出力の文字セットを変換することもできます。これは、翻訳者がメッセージカタログを作ったときとは異なる文字セットを使っているユーザーにとって便利です。これにより、文字セットだけが異なるメッセージカタログをいくつも作らなくてよくなるからです。
出力される文字セットのデフォルトはnl_langinfo
(CODESET)
です。これは現在のlocaleのLC_CTYPE
の部分に依存します。文字列をlocaleとは関係のない文字セット(例:
UTF-8)で保存するプログラムは、gettext
や、それに関連するプログラムにたいして、そのエンコードで翻訳を戻すように要求することができます。これは、bind_textdomain_codeset
関数により行います。
gettext
の引数であるmsgidは、文字セットの変換の対象外であることに注意してください。gettext
が、msgidに対応する翻訳を見つけられなかったときは、現在の出力の文字セットとは関係なく、元のmsgidが変更されずに出力されます。すべてのmsgidに
US-ASCII 文字列が推奨されているのは、これが理由です。
関数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に対応するエラーがセットされます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
グラフィカルユーザーインターフェース(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’が付加されていないマクロのほうが効率的です。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
いままで説明してきた既存のアプローチでは完全に無視してきましたが、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つの異なる事象が存在しました:
単一の形式しかもたない言語ファミリーや、多数の形式をもつ言語ファミリーがあります。これに関する更なる情報は、このセクションの範囲を超えています。
これらの理由により、アプリケーションを記述する人は、これらの問題をコードで解決するべきではないという結論になります。これは言語環境にたいしてハードコードされた状態においてのみ有用なローカリゼーションでしょう。かわりに拡張されたgettext
のインターフェースを使うべきです。
これらの追加の関数は、単一のキー文字列ではなく、2つの文字列と、数値の引数をとります。この考え方の背景には、数値の引数と最初の文字列をキー文字列として使用することにより、翻訳者が指定した正しいplural
formを実装が選択できるようにするというアイデアがあります。それから、2つの文字列引数は、メッセージカタログが見つからなかったときの戻り値を提供するために使用されます(これは通常のgettext
の振る舞いと同じです)。このケースではGermanic言語のルールが適用され、最初の文字列引数はsingular
form、2番目の文字列引数はplural formとみなされます。
この結果、言語カタログをもたないプログラムは、それがGermanic言語のルールにしたがって記述された場合のみ正しい文字列を表示できるということになります。これは確かに制限なのですが、GNU
C library(とGNU
gettext
パッケージ)がGNUパッケージの一部として記述されていること、そしてGNUプロジェクトのコーディング規約がEnglishによるプログラム記述を要請しているので、制限があるにもかかわらずこの解決策により要件を満足することができるのです。
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);
このように引数の配置を指定する文法についての詳細は、Cフォーマット文字列を参照してください。
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であるかを判定するためだけに使用されています。
dngettext
は、選択されたメッセージカタログにたいして、dgettext
と同様な方法で使用します。異なるのは、正しいplural
formのために、2つの余分なパラメーターを指定できる点です。この2つのパラメーターは、ngettext
のときと同様に処理されます。
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
に指定した値より小さくなければなりません。
複数形の使い分けについては、以下のルールが知られています。言語と言語のファミリーが記載されていますが、この情報を言語ファミリー全体に適用する必要があるという訳ではありません(見やすくするために併記しています)。5
1つの形式しか必要としない言語があります。これらの言語ではsingular formとplural formの区別はありません。この場合の適切なヘッダーエントリーは以下のようになるでしょう:
Plural-Forms: nplurals=1; plural=0;
このような特性をもつのは以下の言語です:
Japanese, Vietnamese, Korean
この形式はEnglishで使われているもので、既存のプログラムでも一番多く使用されています。この場合のヘッダーエントリーは以下のようになるでしょう:
Plural-Forms: nplurals=2; plural=n != 1;
(注意: これはCの真偽値が0か1の2値をとる機能を使用しています。)
このような特性をもつのは以下の言語です:
English, German, Dutch, Swedish, Danish, Norwegian, Faroese
Spanish, Portuguese, Italian, Bulgarian
Greek
Finnish, Estonian
Hebrew
Esperanto
同じヘッダーエントリーを使う他の言語:
Hungarian
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を区別します。
言語ファミリーの例外的なケースです。ヘッダーエントリーは以下のようになります:
Plural-Forms: nplurals=2; plural=n>1;
このような特性をもつのは以下の言語です:
Brazilian Portuguese, French
ヘッダーエントリーは以下のようになります:
Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2;
このような特性をもつのは以下の言語です:
Latvian
ヘッダーエントリーは以下のようになります:
Plural-Forms: nplurals=3; plural=n==1 ? 0 : n==2 ? 1 : 2;
このような特性をもつのは以下の言語です:
Gaeilge (Irish)
ヘッダーエントリーは以下のようになります:
Plural-Forms: nplurals=3; \ plural=n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < 20)) ? 1 : 2;
このような特性をもつのは以下の言語です:
Romanian
ヘッダーエントリーは以下のようになります:
Plural-Forms: nplurals=3; \ plural=n%10==1 && n%100!=11 ? 0 : \ n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2;
このような特性をもつのは以下の言語です:
Lithuanian
ヘッダーエントリーは以下のようになります:
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;
このような特性をもつのは以下の言語です:
Russian, Ukrainian, Belarusian, Serbian, Croatian
ヘッダーエントリーは以下のようになります:
Plural-Forms: nplurals=3; \ plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;
このような特性をもつのは以下の言語です:
Czech, Slovak
ヘッダーエントリーは以下のようになります:
Plural-Forms: nplurals=3; \ plural=n==1 ? 0 : \ n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;
このような特性をもつのは以下の言語です:
Polish
ヘッダーエントリーは以下のようになります:
Plural-Forms: nplurals=4; \ plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3;
このような特性をもつのは以下の言語です:
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にたいする翻訳者の考え方については、複数形の翻訳で説明しています。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
この点を議論するには、GNU
gettext
の実装の優位性について話す必要があります。インターナショナライズされたプログラムは、翻訳する必要のある文字列がループ内にあるような場合に性能が劣化すると思う読者がいるかもしれません。たしかにループを実行するごとに文字列が評価されることによる劣化は無視できません。ループの実行中に文字列が変化しない場合に毎回文字列を翻訳する場合は、時間の無駄になります。以下の例で考えてみましょう:
{ while (…) { puts (gettext ("Hello world")); } }
選択したlocaleが実行中に変更されないような場合、翻訳結果の文字列は常に同じです。以下のようなやり方も1つの方法です:
{ str = gettext ("Hello world"); while (…) { puts (str); } }
しかしこの解決策は、すべての状況で使える訳ではありません(例: 実行中にlocaleが変更される場合)。また、コードも読みにくくなってしまいます。
この理由により、GNU
gettext
は以前の結果をキャッシュしています。同じ翻訳が2度要求された場合、要求の間に新たなメッセージカタログがロードされていなければ、2度目の呼び出しではgettext
は結果をキャッシュから取得します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下の議論は幾分誇張されたものかもしれません。これまで述べてきたように、わたしたちは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
呼び出しでも行うことができます(翻訳可能文字列の特別なケースを参照してください)。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
では同じ元文字列にたいして異なる翻訳をもたせることはできませんが、この種のあいまいさによる問題を解決する、よりスケーラブルな解決策があります。あいまいざの解決を参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ライブラリーのバージョン0.9.4から始める場合、libintl.h
は自己充足的になっています(例:
追加の関数なしでプログラムで使用できます)。ヘッダーとライブラリーはMakefileにより、$(prefix)
で選択されたディレクトリーに配置されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
gettext
を根底から理解する注意: このセクションの文書は時代遅れになっているので、改訂する必要があります。
ソースコードを読むことは、GNU
gettext
の機能を完全に活用するための助けになるでしょう。しかし、(時として込み入った内容の)コードを読むために時間
費やすことを望まない人々のために、幾つかのコメントを挙げておきます:
対話的なプログラムにおいては、使用する言語を実行時に尋ねたほうが有用であることがあります。これを理解するためには、gettext
関数が使用する言語をどのように決定しているのかを知る必要があります。ここに示す方法はGNUによるgettext
関数の実装においてのみ正しいものです。
dcgettext関数は呼出しごとに、環境変数の中で最高のプライオリティを持つものを探し出して使用します。プライオリティは以下のリストで示されます。プライオリティは下にいくにつれて低くなります。
その後、検索された値を用いてパスが設定され、可能であれば翻訳ファイルがロー ドされます。
「今」とは、LANGUAGE
が変更されたときです。上で説明した過程に従い、この変数の新しい値はdcgettext
関数が呼び出された時点で決定されます。これは(おそらく)異なったメッセージカタログがロードされることを意味します。即ち、使用する言語が変更されるのです。
しかし、これは一つの小さなフックに過ぎません。 gcc
2.7.0以上のコードでは幾分の最適化が図られています。この最適化は通常、dcgettext
関数の呼び出しによって新しいカタログがロードされる前に行われます。しかし、もしdcgettextが呼び出されなければ、プログラムもまたLANGUAGE
変数の値が変更されたことを知ることができないでしょう(*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実装なのかを決定するために使用できます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
注意: このセクションの文書は時代遅れになっているので、改訂する必要があります。
11.6.1 一時的な情報 - 二つの実装 | Temporary - Two Possible Implementations | |
11.6.2 一時的な情報 - catgets について | Temporary - About catgets
| |
11.6.3 一時的な情報 - なぜ一つの実装なのか | Temporary - Why a single implementation | |
11.6.4 一時的な情報 - ノート | Temporary - Notes |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
言語に依存せずにメッセージを扱う二つの手法があります。一つは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)を参照して下さい。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
catgets
についてcatgets
を基盤として使用することに関する討議の末期には、幾つかの議論がありました。その議論の両側を提示することは大切だと思いますし、これから、私はちょっとしたことに対して「悪魔の弁護士」となってみることにします。
catgets
はもっと良くデザイン出来たでだろうということは否定しません。その実装には既に指摘したような制限が少なからずあります。
しかしながら、その一貫性と標準化の度合いについては申し分ありません。UNIXソフトウェアを書くときに繰り返し発生する問題とは、UNIXプラットフォーム間での移植性に関する問題です。それは全ての UNIXベンダがオペレーティングシステム上を調べて改良する部分を見つけたようなものです。疑いもなく、これらの修正は革新的なものであり、現実の問題を解決するものです。しかしながら、ソフトウェアベンダがこれらの変更を多くのプラットフォームで行いつづけるには、多くの労力が必要です。
そしてこれは各UNIXベンダが自社のシステムを標準化することを促進します。Spec1170に準拠するためにです。各主要UNIXベンダはこの標準化のために委員会を設けました。そして全てのUNIXソフトウェア開発者はこの標準に従ってソフトウェアを作成し、異なるプラットフォームへソフトウェアを導入する際には (autoconfを使うことなく)リコンパイルするだけで済むようになる日を心待ちにし ているのです。
私の理解しているところでは、Spec1170はX/Open Portability
Guidelinesのバージョン4(XPG4)に基づいたものです。catgets
とその眷属がXPG4で定義されているので、私はcatgets
がSpec1170の一部であり、それがすべてのUNIXシステムの標準的なコンポーネントになることを信じています。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
メッセージカタログにアクセスするために二つの異なるシステムをインストールすることは不経済なことのように思えます。我々がcatgets
の不足しているものを改善したいと思ったのなら、なぜ新しいシステムを実装するのではなく、catgets
を(互換性を保ちながら)拡張しようとしないのでしょうか?
いずれにせよ我々は、メッセージカタログにアクセスするためのシステムをオペレーティ
ングシステムに対して二つインストールすることになるでしょう。一つはGNUソフ
トウェアのためルーチン群であり、もう一つはその他全てのソフトウェアのためのルーチン群(catgets)です。傲慢でしょうか?
カタログにアクセスする別のシステムが実装されたと仮定してみましょう。我々がお奨めするのはどちらでしょうか?
少なくともLinuxシステムに対しては、我々は可能な限り多くのソフトウェア開発者を呼び込む必要があります。そのため、我々はソフトウェア開発者が彼らのソフトウェアを移植しやすいようにする必要があります。そしてそれはcatgets
をサポートすることを意味します。我々は
libintl
コードをlibc
中に実装するでしょうが、libc
には別のメッセージカタログに対するアクセス方法を同じように取り込まなければいけないということなのでしょうか?
そして、libintl
と非catgets
ルーチンを組み合わせて使おうとする人達に関してはどうでしょうか?ソフトウェア開発者が彼らのソフトウェアを他のプラットフォームに移植する際、彼らはそのソフトウェアに単にlibintl
を含めるだけでなく、フロントエンド(libintl
)コードと、バックエンド(非catgets
アクセスルーチン)コードを付け加えようとするでしょう。
しかしメッセージカタログのサポートは氷山の一角に過ぎません。他のロカールカテゴリのデータはどうでしょうか。それらもまた、多くの相違点を持っています。我々はそれに対処することを諦めて、重複したルーチン群を別々に開発せねばならないのでしょうか(libintl
をメッセージカタログサポート以上のものにすべきなのでしょうか)?
UNIX上の改良可能な多くの部分と同じように、我々は将来に向けて改良を加えつつも、過去のものに対する互換性を落とさないようにしていました。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
多くの実装が最終形式からかけ離れたものであったため、X/Openが標準形式を承認するのは非常に遅くなりました。私の使っている両方のシステム(古いLinux catgetsとUltrix-4)には奇妙なバリエーションがあります。
最後の変更を加えた後、私はGNU/Linux
libc
のgettext
関数群を作成するために時間を割かねばなりませんでした。従って、将来的にはSolarisがgettext
を備えた唯一のシステムであるということはなくなります。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
12.1 イントロダクション0 | Introduction 0 | |
12.2 イントロダクション1 | Introduction 1 | |
12.3 議論 | Discussions | |
12.4 組織 | Organization | |
12.5 情報の流れ | Information Flow | |
12.6 複数形の翻訳 | How to fill in msgstr[0] ,
msgstr[1]
| |
12.7 メッセージの優先度: 最初に翻訳すべきメッセージを決める方法 | How to find which messages to translate first |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
注意: このセクションの文書は時代遅れになっているので、改訂する必要があります。
GNUは国際化しつつあります! 翻訳プロジェクトは保守担当者、翻訳者、そしてユーザーを全てまとめるもので、そのためGNUソフトウェアは徐々に多くの言語を喋ることが出来るようになります。
GNU
gettext
ツールセットには、保守担当者がパッケージのメッセージを国際化するために必要となる全てがあります。また、パッケージが国際化された後で、翻訳者がメッセージの地域化を行う際の助けになるような便利なツールもあります。
翻訳プロジェクトを完遂するために、我々は自分の国の言葉を愛し、良く書くことが出来、そして他の翻訳者が話しているのと同じ言語で助けることの出来る(synergize)能力を持った人間を数多く必要としています。もしあなたが翻訳チームでボランティアとして働くことを望むなら、該当する翻訳チームにメー ルを出して下さい。
各チームはLinux Internationalの好意による自身のメーリングリストを持っています。ll@li.orgというアドレスのllをあなたの注目する言語のISO 639の二文字コードに置き換えることによって、その言語の翻訳チームに連絡できます。言語コードはISO 3166に定められている国コードと同じではありません。現時点では以下の翻訳チームが存在します。
Chinese
zh
、Czechcs
、Danishda
、Dutchnl
、Esperantoeo
、Finnishfi
、Frenchfr
、Irishga
、Germande
、Greekel
、Italianit
、Japaneseja
、Indonesianin
、Norwegianno
、Polishpl
、Portuguesept
、Russianru
、Spanishes
、Swedishsv
、Turkishtr
。
仮に中国語翻訳チームにメールを出すとすれば、zh@li.orgとなります。翻訳チームのメンバーになるには、その言語チームのメーリングリストに登録する必要があります。例えば、スウェーデン人は本文に以下の内容を記述してsv-request@li.orgにメールを出します。
subscribe
チームのメンバーは翻訳作業に興味を持つべきだということを心に留めて置いて下さい。そうでなければ翻訳を果たすことは難しいのです。もしが希望する言語のチームがまだ存在せず、その言語のチームを作りたいという場合にはcoordinator@translationproject.orgまで連絡して下さい。それによって全ての翻訳チームの調整者に連絡が取れます。
一握りのGNUパッケージには幾つかの言語に対するメッセージの翻訳が適用・提供 されています。翻訳チームは組織化され始めており、これらのパッケージを起点として使っています。しかしまだまだ多くのパッケージがあり、多くの言語についてはボランティアの翻訳者がいません。もし翻訳チームでボランティアとして作業したいと思うのでしたら、coordinator@translationproject.orgに作業することの出来る言語を明記してメールを送って下さい。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
注意: このセクションの文書は時代遅れになっているので、改訂する必要があります。
現在公式に、GNUは国際化しつつあります! 以下は1995年1月のGNU Bulletinで述べられた声明です。
一握りのGNUパッケージには幾つかの言語に対するメッセージの翻訳が適用・提供されています。翻訳チームは組織化され始めており、これらのパッケージを起点として使っています。しかしまだまだ多くのパッケージがあり、多くの言語についてはボランティアの翻訳者がいません。もし翻訳チームでボランティアとして作業したいと思うのでしたら、‘coordinator@translationproject.org’に作業することの出来る言語を明記してメールを送って下さい。
本ドキュメントはその過程に興味を持ったり、貢献したいと考えている人々が持つ多くの疑問に答えます。願わくばざっと目を通し、GNUの国際化に対するこの集合的努力から産み出される大量のメールの幾ばくかでもを担当して下さい。
広く共用される多くのフリーソフトウェアのプログラミングは英語で行われています。そして現在のところ、英語はGNUプロジェクトに協力する国家的コミュニ ティ間での主要なコミュニケーション言語として使われています。このドキュメントでさえも英語で書かれています。これは当面変わらないでしょう。
しかしながら、多くのソフトウェアで自国語や自国の習慣を用いたいという、国家的コミュニティからの強い欲求があります。また、GNUソフトウェアをそのようにするための努力が現在も行われています。この試みは今までのところプリテスタからの熱心な反応の向上によって動かされており、我々はGNUの国際化は成功すると信じています。
このドキュメントに対する内容の明確化、追加、訂正に関する提案については、coordinator@translationproject.orgまでメールを送って下さい。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
注意: このセクションの文書は時代遅れになっているので、改訂する必要があります。
この国際化の効果を目の当たりにして、幾人かのユーザが彼らの考えを表明しています。紹介され議論されたこれらの疑問の幾つかをここに挙げてみましょう。
幾つかの言語は多くの人々によって話されていないため、その言語を話す人々はフリーソフトウェアパッケージの当該言語版に対する必要性はあまりないと考えています。更に、幾つかの国にいるコンピュータの中にいる多くの人々は一般的に英語版ソフトウェアのほうを好むようです。
一方で、人々は自分達の言語を非常に好きですし、彼らのお気に入りのフリーソフトウェアが彼らの母国語を喋ることが出来るように努力します。彼らは個人的な楽しみのためにそれを行います。そしてどのくらいの人間がその作業によって便益を得るかなどといったことは考えません。
ある種の誤ったプロパガンダのせいか、一部のユーザは自身の言語を押し出すことについて臆病になっています。ある人は、ネットワークの向こう側にはその言語をうるさくせがむユーザがいるに違いないと考えています。
しかしあらゆる言語には地域化される価値があります。なぜなら、その言語が大切で敬愛されるものであると考える人々がその言語の向こうにいるからです。
誰もがメッセージを理解出来るためには、正しい翻訳を見つけ出すことがもっとも大きな問題となります。翻訳は通常、少し変なものなのです。一部の人々は、「どちらかといえば押しが強く、嫌でときどき滑稽な」彼らの言語に対する翻訳を行うことが出来る程度には英語を扱うことが出来ます。フランス語を話す人間として、私は韓国または台湾において商品の取扱説明書を貧弱なフランス語へと翻訳した経験があります。...
我々はときどきある種の国家的計算機文化を作り上げる必要があるというのは事実です。そして、その作業は彼らの母国語によって繋がっている多くの人間の協調作業なしに簡単に出来ることではありません。翻訳は彼ら自身の言語を知りそして愛する人々によってより良く行われ、より良い結果を得るという点において一緒に作業されるものなのです。
何人かの人々は、彼らが彼らのプログラムをフリーにしたくない場合、又は別の種類の自由を与えたい場合に、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
を含める権利を与えます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
注意: このセクションの文書は時代遅れになっているので、改訂する必要があります。
大きな尺度で見れば、真の解決方法は有志が参加できるようなある種の正しく厳密な集合を組織化することでしょう。私は、最近このアイディアについて幾つかの考察を行い、幾つかの微妙なポイントがあるであろうことを認識しています。私は、そのようなプロジェクトを開始するために、Richard Stallmanに連絡することを考えましたが、まず最初に我々の間でアイディアを揺り落とすことが良いだろうと感じました。おそらく、Linux Internationalは既にこの分野における幾らかの経験、または、有志の作業のオーケストラのようなものを持っています。あらゆる場合に、思考のための食物を!
我々は早々に何らかの方法で何かをセットアップせねばならないと考えます。同じ言語に対する作業のインターロックと重複を避けるという点で、それは多くの言語のコントリビュータを助けるでしょう。そして、更にそれらの言語(大部分の言語では技術的な英語の翻訳について独特な多くの問題点があります)についての独特な問題を共に解決するように連絡が取れるようにします。スウェーデンのコントリビュータはこれらの問題点を認め、そして私はフランス語においてのそれらの問題点に相当に気が付いています。
確かにこれは技術的問題ではありません、しかし我々は、コントリビュータ、及び管理者間の国家チーム層のインターフェースに関わらず、ロカールコントリビュータの努力が最大限に有益になるように管理するべきです。
翻訳プロジェクトは言語コーディネータを統合するためにある準備を必要とします。一度この作業が始められたなら、発展中のプログラムのローカライズは、確かにフリーソフトウェアコミュニティにおいて永久の、そして、連続的な動きになるでしょう。GNU
gettext
が公式の現実になる前に、最小限の準備が完了し、そしてテストされているべきです。電子メールアドレスcoordinator@translationproject.orgは、これらの話題に基づくボランティア、及び、一般的な電子メールから申し出を受けるための準備でした。このアドレスは、翻訳プロジェクトのコーディネータに届きます。
12.4.1 中央による調整 | Central Coordination | |
12.4.2 国家チーム | National Teams | |
12.4.3 メーリングリスト | Mailing Lists |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
そのことについて考えるよりも更に早く、GNUは誰かがそれらのグループを組織化し調整する方法を準備する必要があると私もまた考えます。ある種のグループのグループです。GNUは直ちに共同で働いているボランティアの小さなグループにこのタスクを委託することが良いだろうと、私は考えています。 おそらく、この国家委員会的なグループのリストはgnu.announceにおいて公表され得ます。
コーディネータとしての私の役割は単に、Ulrichをフリーソフトウェアの地域化に興味を持っているドイツ語を話すボランティアに紹介すること、そして国家的グループの準備が出来るまでの国家的登録機関のメンテナンス中に、国家的グループの最初の組織化を助けることです。実際、コーディネータは、ボランティアが国家チーム(言語または国(局地的言語)について1人のコーディネータを選択するべきです)を作成するために相互と連絡を取りやすくせねばなりません。これが正しく行われたならば、コーディネーションは不可抗力的作業を除いて便利なものとなり、代理人に時間を任せることが出来るようになります。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
私は、我々が個々の言語のための有志のコーディネータ/エディタを捜すことを提案します。これらの人々は彼ら自身の言語のために、様々なプログラムの翻訳ファイルを探し出し、そして、語法に対する高度で一定の標準を保証することになるで しょう。
今までの他の人々との間の私の現在の経験によれば、地域化を実現する人々はこのプロセスに対して非常に熱心であり、彼らは自分自身が地域化するプログラムよりも地域化のプロセスにほうに興味を持ち、それだけでなく多くのプログラムを地域化したいと思うものです。この事実は、各言語のためのコーディネータ/エディタを持つことは良いアイディアであることを確信させます。
我々は、問題となる言語において明瞭かつ簡潔な文章を書く際、適任となる人物を選択する必要があります。これは難しい作業です — 我々は、自分自身でそれをチェックすることができません。従って、我々は数人の人間対してに互いの記述を判断するように要請し、そして最適任者を選択する必要があります。
私は私のプレリリースを20人から30人の人々に発表ましたが、そのプレリリースが既に生み出した全ての議論をあなたは信じないでしょう。私は、真に、公式に、世界中でこの作業が開始されるときに起こるであろうことを想像すると身震いがします。例えば、相互に反論しあう二人のチェコスロヴァキアのユーザーの間を仲裁するのは私なのでしょうか?
私がこれらの公式化について判断することが出来ないように、あなたのドイツ語が私のフランス語よりはるかに良いとは限らないと推測します。私が提案するものは、各言語に対してPOファイルをメンテナンスしその変更を判定する人々のグループを置くということです。そのような人々のグループがどのように行動するかについて、グループ間には文化的な相違点があると考えます。幾つかのグループはは緩い方法を採用し、簡単にコンセンサスの一致に達し、グループ中の誰もが保守者に関わることができます。一方は死ぬまで戦い、重い管理を国家の標準にまで組織化し、厳密なチャネルを使用するでしょう。
ドイツのチームは良い例を出しています。直ちに、彼らはおそらくお互いの翻訳を訂正する半数の人々と言語上の論点について議論する半ダースの人々です。私は全ての名前を知っているわけではありません。Ulrich Drepperはドイツのチームのコーディネートを担当しています。彼は私のプレテストのリストの購読を申し込みました。従って、私は彼に対して、連絡されるリリースの詳細について警告する必要は特にありません。
各言語を担当する翻訳チームを得るためには、それはよいアイディアだと思います。 翻訳を更に良く首尾一貫した状態にするでしょう。
12.4.2.1 サブカルチャー | Sub-Cultures | |
12.4.2.2 組織化へのアイディア | Organizational Ideas |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フランス語を例に取ってみましょう。コンピュータの世界では、意味が異なる語彙を持つ幾つかのサブカルチャーがあります。組織化された方法でこの問題を提起することなしにあちこちでボランティアを選んでいると、プロジェクトにはすぐに国際化されたプログラムのごちゃ混ぜ状態が発生します。そしてことによると、実際にこの問題を気にする人々の間で終りなき口論が始まるでしょう。
国際化されたプログラムをフランス語へ地域化する過程において、ある種の統一を保つことは難しい(そしてデリケートな)仕事です。フランス人のラテンな人柄
(:-)
を知っていても、もし我々がこのことを間違った方法で捉えれば、我々はどことも知れぬ場所で終わってしまうか、多くのエネルギーを無駄にしてしまうことでしょう。おそらく我々は、GNU
gettext
が公式に発表される前に真剣にこの問題に取り組まなければならないでしょう。そして、それはすぐではないかと私は推測します!
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
私は、公式リリース後に次の大きな変更があると考えています。どうか、私が短いGPLメッセージのドイツ語翻訳を用いることに注目してください。我々は、フリーソフトウェアコミュニティにおける真の地域化が消え去ってしまう前に2、3の良い例を示す必要があります、ここでは、議論が必要ないくつかのポイントを示します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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において各国のチームのためのメーリングリストを提供することは確かに有益でしょう。そうです、私にどのようにメーリングリストを作成し扱えばよいかを説明して下さい。
我々は一時的なメーリングリストを、人々を組織化しやすいように国ごとに一つずつ作らねばなりません。なぜ一時的か、なぜなら一度再構成されたなら、各国のボ ランティアは彼らのリストへと戻ってきて、そして自分達が望むように管理するだろうからです。このことについては、個々のチームは自分達の国の中から 自分達のリストを動かすだろうと思います。全てのチームが購読することの出来る、 中央のメーリングリストも作る必要があるでしょう。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
注意: このセクションの文書は時代遅れになっているので、改訂する必要があります。
パッケージが最終的にリリースされた後、このメッセージについての幾つかの議論があることでしょう。今、人々が更に良い幾つかのメッセージを提案したとしたら、あなたはどうしますか? Jim、私が提供する1ダース近い地域化されたプログラムと同様、どうか直ちにそれらのメッセージに注目して下さい。私は翻訳とそれらに関する調整の両方を受け取るのです。
私が事前にテストするものを一つ置いたならば、Ulrichはその告知を受け取り、そしてそれを最後に修正するドイツ語のチームに渡します。そして彼は保守者として私に翻訳ファイルを引き渡します。私が保守していないフリーのパッケー ジについては何も聞きません。私が思うに、全ての翻訳プロジェクトにおいてこのスキームが作られるでしょう。セキュリティに関わる理由のために、おそらく Ulrich(実際の国家的コーディネータ)は時折翻訳プロジェクト(Jim、私、又はLenの新人)によって保持される中央のレジストリをアップデートすべきです。
私は小さなGNUパッケージは一週間に一つずつ、より大きなパッケージは数週間か数ヵ月をかけるという責務を私自身に課し、12月か1月には私はにGNUの全パッケー ジを国際化する準備を積極的に整えていました。しかし、それはそのようには動きません。私は最初に、私が責任を持つ全てのことを行いました。私は他の保守者の幾らかの伝道作業に対して何も持っていませんでした。しかし私もまた多くのエネルギーを失いました — 同じ議論を繰り返します。
そして、最初に地域化されたパッケージがリリースされるとき、我々は、醜悪な翻訳 :-) についての多くの反応を得るでことしょう。確かに、そして我々は事前に、パッケージ保守者と国家チームの間の情報の流れを制御することに関する良いアイディアを持つ必要があります。
どうかどこかに各POファイルの迅速なヒストリを保存し始めて下さい。コメントを認めることによってファイルフォーマットがいずれ変更されるであろうことを私は知っています。各ファイルがログのようなもの、そしてコメントや不平の申し立て、又はその他の貢献をしたいと思う人々へのリファレンスを持つほうがよいでしょう。私は高速でフレキシブルなフォーマットに関する申し立てをしましたが、しかしそれはまだGNUの意思決定者によって受け入れられていません。私がこれについてより多くの情報を得たなら、このことについてお話しすることになるでしょう。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
あなたが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についての詳細は、複数形(plural forms)にたいする追加の関数で説明しています。
最初に見る必要があるのは、POファイルのヘッダーエントリーのPlural-Forms
という行です。この行にはplural
formを判定するための数字と式が記述されています。まだPOファイルにそのような行がない場合は、追加する必要があります。これは、あなたが翻訳しようとしている言語に依存します。この情報はmsginit
コマンド(新しいPOファイルの作成を参照してください)
– これには既知の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...などのときにも使用するので、書式指定子を省くことはできません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
翻訳者が週のうちパッケージに避ける時間が限られているにもかかわらず、パッケージにはとても多くのメッセージ(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)から入手します。もし彼女が、そのパッケージの最初の翻訳者の場合は、新規作成することになります(新しいPOファイルの作成を参照してください)。それから彼女は、以下のコマンドを使って、緊急ではないメッセージにたいして "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を翻訳します(POファイルの編集を参照してください)。(FIXME: KBabelとgtranslatorが期待通りobsolete messageを保持してくれるかどうかについては、わたしにはわかりません) そして彼女は最後に、以下のコマンドで緊急ではないメッセージ(およびすでに翻訳済みのメッセージの初期の"翻訳")を復元します:
$ msgmerge --no-fuzzy-matching $domain.$lang-urgent.po $package/po/$domain.pot \ > $domain.$lang.po
$domain.$lang.poを投稿したら、彼女は次のドメインを処理できます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
パッケージのメンテナーには多くの責任があります。そのうちの1つは、たくさんのプラットフォームでパッケージを簡単にインストールできるようにすることで、わたしたちが前に説明したマジック(ユーザーの視点を参照してください)を、インストーラーとエンドユーザーにたいして働くようにすることです。
GNU
gettext
をディストリビューションに統合できるようにする方法はたくさんありますが、このチャプターではそれらを総括的にカバーすることはしません。かわりにGNU標準、さらにはGnits標準にしたがった、多くのフリーソフトウェアディストリビューションで利用可能なアプローチの詳細について議論します。なぜならGNU
gettext
は、GNUプロジェクト全体のインターナショナリゼーションを助けるのを目的としているので、多くの有用でフリーなパッケージが対象となるからです。そのためこのチャプターでは、すでにconfigure.acがあり、GNU
Autoconfを使うパッケージを対象とします。
それにもかかわらずGNU
gettext
は、GNU標準やその類にしたがっていないフリーパッケージにたいしても有用です。そのようなパッケージのメンテナーは自分の想像力と独創力によりディストリビューションを組織化する必要がありますが、gettext
はすべての状況で動作するでしょう(そしてそのようなパッケージはたくさん存在します)。
gettext
のメソッドは現在安定しているとはいえ、gettext
の各バージョン間でちょっとした調整は必要になるでしょう。そのため、このチャプターの内容は、新たなリリースによる変更にしたがって読み替える必要があります。
13.1 非フラットなディレクトリー階層 | Flat or Non-Flat Directory Structures | |
13.2 前提となる作業 | Prerequisite Works | |
13.3 gettextize プログラムの呼び出し | Invoking the gettextize Program
| |
13.4 作成または変更しなければならないファイル | Files You Must Create or Alter | |
13.5 configure.ac内でのautoconfマクロの使用 | Autoconf macros for use in configure.ac | |
13.6 CVSによる統合 | Integrating with CVS | |
13.7 配布用tarballの作成 | Creating a Distribution Tarball |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
フリーなソフトウェアパッケージの中には、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にするメンテナーもいるかもしれません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
パッケージにたいして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
のインストールが必要になります。
POファイルが投稿されたとき、メンテナーとしてどのように振る舞うのが理想的なのか、少し説明をしておきましょう。メンテナーとしてのあなたの役割は、その投稿が翻訳プロジェクト内の対応する翻訳チーム(わからないときはcoordinator@translationproject.orgに転送してください)によるものであることを証明し、POファイルのフォーマットが壊れていてインストールできないくなっていないか確認し、それらのPOファイルを配布物のpo/ディレクトリーに配置することです。
メンテナーとしては、翻訳が十分なのか、または完璧なのかをチェックする責任を負う必要はないので、語学に関する事柄については無視するべきです。翻訳チームは、チーム自身の運営と翻訳プロジェクトでの言語学的な選択について完全な責任を負います。翻訳チームがメンテナーにより運営されるのではないことを覚えておいてください。ユーザーからの言語上の指摘や報告などを、適切な翻訳チームに転送したり、ユーザーが翻訳チームに参加する方法を説明するような手助けをすることはできます。もっとも簡単なのはABOUT-NLSファイルを送ることでしょう。
メンテナーが翻訳チームを介さずに、自分でPOファイルに関するバグ報告を受けるのは決して行うべきではないことです。ある問題について翻訳者が彼女のチームと一致した見解をもつのが困難なとき、彼女が直接メンテナーと交渉するようなオプションが存在するべきではありません。どんな問題にせよ、彼らは問題をチーム自身で解決するべきです。メンテナーとしては、もしチームに本当に問題があると思えるときでも、あなた自身がチームの問題を解決しようとはしないでください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
gettextize
プログラムの呼び出しgettextize
プログラムは、GNU
gettext
によりインターナショナライズされたパッケージのメンテナーを助けるための対話的なツールで、2つの目的のために使用されます:
gettext
を使ってパッケージをするときは、ウィザードとして使用されます。
gettext
サポートを、以前のGNU
gettext
から新しいバージョンにアップグレードするための、移行ツールとして使用します。
このプログラムは以下のタスクを処理します:
gettext
によりインターナショナライズされた、すべてのパッケージで必要なファイルをパッケージにコピーします。
gettext
で使われていた陳腐化したファイルやイディオムを削除して、現在のバージョンのGNU
gettext
で推奨される形式にします。
gettextize
で自動的に処理できないタスクの要約をプリントします。
呼び出し方は以下のようになります:
gettextize [ option… ] [ directory ]
以下のオプションを指定できます:
すでに存在するファイルを強制的に置き換えます。
libintlのソースを、intl/というサブディレクトリーにインストールします。このlibintlは、GNU
libintlがインストールされていないシステムでインターナショナリゼーションを提供するのに使用されます。このオプションが省略された場合は、configure.acのAM_GNU_GETTEXT
呼び出しが読み込まれます。しかし‘AM_GNU_GETTEXT([external])’とインターナショナリゼーションは、GNU
gettextのないシステムでは利用できないでしょう。
POファイルを含むディレクトリを指定します。このようなディレクトリーには、特定のPOTファイルをさまざまな言語に翻訳したファイルが含まれています。このオプションは、翻訳ドメインどとに複数回指定することができます。指定されなかったときは、po/というディレクトリーが更新されます。
ChangeLogの作成・更新をしません。デフォルトではgettextize
は、影響を受けるディレクトリーごとの‘ChangeLog’というファイルに、すべての変更(ファイルの追加・変更・削除)を記録します。
必要なファイルをコピーするかわりに、シンボリックリンクを作成します。これはディスク容量を数キロバイト節約するのには便利ですが、自分自身を含む形式のtarballの作成には特別な配慮が必要になり、メンテナーがソースに適用できるいくつかの機能が使えなくなり、システムに新しいバージョンのgettext
がインストールされたときにバグ(のような状態)を招きます。
変更を出力しますが、処理は行いません。普通にgettextize
を実行したときのアクションはすべて抑止され、かわりにリストが標準出力に出力されるだけになります。
このヘルプを表示して終了します。
バージョン情報を表示して終了します。
directoryを指定した場合、そのディレクトリーはGNU
gettext
を使う準備をしたいパッケージの、トップレベルのディレクトリーになります。
プログラムgettextize
は、以下のファイルを提供します。しかし--force
(-f
)オプションを指定しなければ、既存のファイルは置き換えられません。
gettextize
により提供されるABOUT-NLSよりも、新しいコピーを使いたいと思うかもしれません。より新しいABOUT-NLSファイルのコピーを、翻訳プロジェクト、またはGNU
archive siteから入手することもできます。
gettext
によるpo/Makefile.in.in(ファイル名に‘.in’が2つあることに注意してください)と、いくつかの予備ファイルしか含まれていません。すでにpo/というディレクトリーがあるときは、そのディレクトリーのファイルは保持され、Makefile.in.inと予備ファイルだけが上書きされます。
‘--po-dir’が指定されたときは、po/のかわりに‘--po-dir’で指定されたそれぞれのディレクトリーに配置されます。
gettext
のintl/ディレクトリーから、ほとんどのファイルがコピーされます。--force
(-f
)も指定されたときは、まず最初にintl/が空にされます。
AM_GNU_GETTEXT
で必要です。
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
を呼び出した後、作成または変更しなければならないファイルを読む必要があるでしょう。
特に‘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
プログラムの呼び出しを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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 | POTFILES.in in po/ | |
13.4.2 po/内のLINGUAS | LINGUAS in po/ | |
13.4.3 po/内のMakevars | Makevars in po/ | |
13.4.4 po/内のMakefileの拡張 | Extending Makefile in po/ | |
13.4.5 トップレベルのconfigure.ac | configure.ac at top level | |
13.4.6 トップレベルのconfig.guess、config.sub | config.guess, config.sub at top level | |
13.4.7 トップレベルのmkinstalldirs | mkinstalldirs at top level | |
13.4.8 トップレベルのaclocal.m4 | aclocal.m4 at top level | |
13.4.9 トップレベルのacconfig.h | acconfig.h at top level | |
13.4.10 トップレベルのconfig.h.in | config.h.in at top level | |
13.4.11 トップレベルのMakefile.in | Makefile.in at top level | |
13.4.12 src/内のMakefile.in | Makefile.in in src/ | |
13.4.13 lib/内のgettext.h | gettext.h in lib/ |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ディレクトリー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
#マークのコメントと空行は無視されます。それ以外の行は翻訳用にマークされた文字列を含むソースファイルをリストした行(ソース内でマークはどのように見えるかを参照してください)で、相対パスはPOTFILES.inのあるディレクトリーではなく、ディストリビューション全体のトップレベルからの相対パスです。
flex
やbison
のような、それ自身では翻訳可能な文字列を提供しないようなツールによりCファイルが自動生成されるときは、po/POTFILES.inには自動生成されたCファイルではなく、本当のソースファイル(flex
のときは.lで終わるファイル、bison
のときは.yというファイル)を記述することをお勧めします。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ディレクトリーpo/には、LINGUASというファイルも必要です。このファイルは利用可能な翻訳がリストされています。これは空白区切りのリストで、#マークのコメントと空行は無視されます。以下は例です:
# Set of available languages. de fr
この例はGermanとFrenchのPOファイルが利用可能で、パッケージでは現在それらの言語がサポートされていることを意味しています。インストール時に、インストールされる言語にさらに制限をかけたいときは、ファイルLINGUASを変更するのではなく、環境変数LINGUAS
を使用します(インストーラーと配布者の視点を参照してください)。
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
を実行することによりインストールされます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ディレクトリーpo/には、Makevarsというファイルもあります。このファイルには、プロジェクトで固有の変数が含まれています。po/Makevarsが作成されるときに、po/Makefileが挿入されます。そのため、変数はPOTファイルが作成・更新されたときや、メッセージカタログがインストールされたときに効果を及ぼします。
あなたのパッケージが単一のメッセージドメイン(1つのpo/ディレクトリーしかない)のときは、最初の3つの変数は変更する必要はありません。別々の場所に複数のpo/ディレクトリーをもつパッケージの場合だけ、Makevarsの最初に定義された3つの変数を調整する必要があります。
XGETTEXT_OPTIONS
変数のかわりに、autoconfマクロのAM_XGETTEXT_OPTION
により、xgettext
のオプションを指定することもできます。詳細はpo.m4内のAM_XGETTEXT_OPTIONを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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
プログラムの呼び出しを参照してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
configure.acまたはconfigure.in –
これはautoconf
がconfigureスクリプトを生成するときのソースになるファイルです。
これは以下のように宣言します:
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)にそのまま使用されます。
以下のマクロは、インターナショナリゼーションにたいするサポートを発動するためにメインとなる、m4
のマクロです。この行をconfigure.acに追加します:
AM_GNU_GETTEXT
マクロはconfigure時に多くのチェックと処理を行いますが、呼び出しは故意に単純にしています。
gettextize
を呼び出すとき、‘--intl’オプションを指定せず、intl/を作成しない場合は、以下の呼び出しが読み込まれます:
AM_GNU_GETTEXT([external])
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による制限により必要です。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
サブディレクトリー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])
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
初期のバージョンのGNU gettextでは、配布物にGNU mkinstalldirsスクリプトを追加する必要がありました。これは今では必要ありません。使用しているautomakeが、automake 1.9以降であれば削除することができます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
配布物に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
を使うプロジェクトでは同一だからです。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
初期のバージョンのGNU
gettext
では、acconfig.hファイル内でENABLE_NLS
、HAVE_GETTEXT
and HAVE_LC_MESSAGES
、HAVE_STPCPY
、PACKAGE
and
VERSION
を定義することが要求されました。これは今では必要ないので、パッケージがintl/ディレクトリーから独自に使用していなければ、削除することができます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
以下は、トップレベルにあるメインのMakefile.inファイルにたいして必要な変更です。
PACKAGE = @PACKAGE@ VERSION = @VERSION@
DISTFILES
に、ファイルABOUT-NLSを追加して、このファイルが配布されるように変更します。
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
があるのは、これが理由です。
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’の実行よって修正済みであることに注意してください。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
メインのMakefile.inで行ったいくつかの修正は、あなたのパッケージソースのMakefile.in(ここではsrc/サブディレクトリーにあると仮定します)でも必要です。以下は、src/Makefile.in内で必要な修正のすべてです:
PACKAGE = @PACKAGE@ VERSION = @VERSION@
top_srcdir
を定義する必要があります。これはcpp
のインクルードファイルのための定義で、以下の行を追加するだけです:
top_srcdir = @top_srcdir@
subdir
を‘src’と定義したいと思うかもしれません。以下は、このゴール‘dist:’のために必要な定義です:
subdir = src
main
関数は通常、bindtextdomain
(gettext
処理のトリガーを参照してください)を呼び出します:
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’になることに注意してください。
@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@
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に必要な変更は以下になります:
<module>_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\"
またはコンパイル単位については以下のようにMakefile.amに記述します。
AM_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\"
これはすべてのモジュール、またはコンパイル単位のためのものです。さらにAutoconfのバージョンが2.60より古いものを使用している場合、以下の行を追加して‘localedir’を定義します:
localedir = $(datadir)/locale
@LIBINTL@
または@LTLIBINTL@
を使うことを保証するために、以下をMakefile.amに追加します:
<program>_LDADD = @LIBINTL@
特定のプログラムごとには上記のように記述します。
LDADD = @LIBINTL@
これはすべてのプログラムの場合です。プログラムのリンクにlibtool
を使うときは、プログラム用に@LIBINTL@ではなく、@LTLIBINTL@を使う必要があることを忘れないでください。
gettextize
により作成されたものである場合は、以下のような行をMakefile.amに追加して、すべての状況において、Cプリプロセッサーがインクルード
ファイルをそこから検索することを保証するようにしてください:
AM_CPPFLAGS = -I../intl -I$(top_srcdir)/intl
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
GNU
gettext
により提供される、パッケージのインターナショナリゼーションはオプションであり、2つの状況でオフに切り替えることが考えられます:
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
をパブリックな場所にインストールしないでください。このファイルを必要とするすべてのパッケージは、パッケージ自身にそのファイルのコピーが含まれているからです。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
GNU
gettext
は、パッケージのconfigure.ac(またはconfigure.in)で使用されるマクロをインストールします。詳細については、Introduction in The Autoconf
Manualを参照してください。その中でも主要なマクロは、もちろんAM_GNU_GETTEXT
です。
13.5.1 gettext.m4内のAM_GNU_GETTEXT | AM_GNU_GETTEXT in gettext.m4 | |
13.5.2 gettext.m4内のAM_GNU_GETTEXT_VERSION | AM_GNU_GETTEXT_VERSION in gettext.m4 | |
13.5.3 gettext.m4内のAM_GNU_GETTEXT_NEED | AM_GNU_GETTEXT_NEED in gettext.m4 | |
13.5.4 intldir.m4内のAM_GNU_GETTEXT_INTL_SUBDIR | AM_GNU_GETTEXT_INTL_SUBDIR in intldir.m4 | |
13.5.5 po.m4内のAM_PO_SUBDIRS | AM_PO_SUBDIRS in po.m4 | |
13.5.6 po.m4内のAM_XGETTEXT_OPTION | AM_XGETTEXT_OPTION in po.m4 | |
13.5.7 iconv.m4内のAM_ICONV | AM_ICONV in iconv.m4 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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
が対処する複雑さは、以下のようなものです:
gettext
をもちます。GNU
libintl
は、GNU gettext
の一部としてインストールされたのかもしれません。
libintl
がインストールされていて、検索パス(インクルードファイルの検索パスはCPPFLAGS
、ライブラリーの検索パスはLDFLAGS
)にあるが、必要ない場合。
gettext
は、必要なlocale依存の機能をもたず、カタログのテキストのエンコーディングから、ユーザーのlocaleのエンコーディングにメッセージを変換できません。
libintl
がインストールされていて、実行時ライブラリーの検索パスにあるが、必要ない場合。LD_LIBRARY_PATH
のような環境変数による設定を無視するために、このマクロは適切な実行時の検索パスオプションを、変数LIBINTL
およびLTLIBINTL
に追加します。これはほとんどシステムで動作しますが、SCOのように共有ライブラリーに制限のあるいくつかのオペレーティングシステムではうまく動作しません。
libintl
は、POSIX/XSIのiconv
に依存します。このマクロはiconvを使うために必要なリンカーオプションをチェックして、変数LIBINTL
およびLTLIBINTL
に追加します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
AM_GNU_GETTEXT_VERSION
マクロは、パッケージで使用するGNU
gettextインフラストラクチャーのバージョン番号を宣言します。
このマクロの使用はオプションで、これを使用するプログラムはautopoint
だけです(CVSによる統合を参照してください)。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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
呼び出しの前後どちらでもよく、順番は関係ありません。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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以降で使用できます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このマクロはC、C++、Objective C以外のプログラム言語(例:
sh
、Python
、Lisp
)による、インターナショナライズされたプログラムで使う必要があります。PO
ファイルによるローカリゼーションをサポートするプログラム言語のリストは、その他のプログラミング言語を参照してください。
AM_PO_SUBDIRS
マクロは、インターナショナリゼーションを使う必要があるかを決定します。使う必要がある場合にはUSE_NLS
変数に‘yes’をセットし、必要ない場合には‘no’をセットします。このマクロは、各po/ディレクトリーのMakefileの変数にたいする適切な値も決定します。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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
に指定できるオプションのリストは、xgettext
プログラムの呼び出しを参照してください。
このマクロの使用は、po/Makevarsの中の‘XGETTEXT_OPTIONS’変数の代用となります。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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
が対処する複雑さは、以下のようなものです:
iconv
のあるオペレーティングシステムとしては、たとえばglibcがあり、ライブラリーlibiconv
に分割されているシステムには、たとえばOSF/1、FreeBSDがあります。種類の如何にかかわらず、GNU
libiconv
がインストールされたオペレーティングシステムの場合、オペレーティングシステムのネイティブのiconv
のかわりに使用されます。
libiconv
がインストールされていて、検索パス(インクルードファイルの検索パス
CPPFLAGS
、ライブラリーの検索パスLDFLAGS
)にあるが、必要ない場合。
libiconv
は、いくつかのオペレーティングシステムのネイティブのiconv
にたいしてバイナリーの非互換があります(例:
FreeBSD)。適合していないiconv.hおよびlibiconv.soの使用は、プログラムのクラッシュを招きます。
libiconv
がインストールされていて、実行時ライブラリーの検索パスにあるが、必要ない場合。LD_LIBRARY_PATH
のような環境変数による設定を無視するために、このマクロは適切なランタイムのサーチパスオプションを、変数LIBICONV
に追加します。これはほとんどシステムで動作しますが、SCOのように共有ライブラリーに制限のあるいくつかのオペレーティングシステムではうまく動作しません。
gettext.m4が依存しているので、iconv.m4はGNU gettextの一部として配布されます。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
多くのプロジェクトでは分散開発におけるバージョンコントロールとソースのバックアップにCVSを使用しています。このセクションではcvs
、gettextize
、autopoint
、autoconf
の使用をどのように管理するかについてのアドバイスを与えます
13.6.1 分散開発におけるバージョンミスマッチを避ける | Avoiding version mismatch in distributed development | |
13.6.2 CVSバージョンコントロールの配下に置くファイル | Files to put under CVS version control | |
13.6.3 autopoint プログラムの呼び出し | Invoking the autopoint Program
|
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
複数の開発者によるCVSを使ったプロジェクト開発では、gettext
の新しいバージョンにアップグレードしたいと望む一人の開発者が、gettextize
を実行して作成または変更しなければならないファイルにリストした変更をほどこした後に、その変更をCVSにコミットするようなことが時折あります。
プロジェクトのすべての開発者が、パッケージのGNU
gettext
に、同じバージョンのものを使用することを強く推奨します。別の言い方をすると、gettextize
を実行したら、開発者はプロジェクト全体と同じ方法で必要な変更をほどこしてCVSにコミットする必要があります。さもないと以下のような損傷が発生します:
Makefile.am
およびMakefile.in
内のgettext
に関係する特定の箇所は、gettext
のバージョンに依存しており、異なるバージョンのgettext
による基礎的なファイルの使用により、容易にビルドエラーが発生します。
gettext
を使ってリリース用のtarファイルを作ったら、その配布物は同じバージョンのgettext
を使ってテストされたものに比べてテストされていないことになり、たとえばそれがプラットフォームに固有の未知のバグにもなり得るのです。
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
CVSレポジトリーのコンテキストで作成されるファイル、たとえばconfigure.acにより生成されるconfigure、parser.y
から生成されるparser.c
、gettextize
やautopoint
により自動インストールされるpo/Makefile.in.in
のようなファイルを取り扱うには、基本的に3つの方法があります。
これら3つの方法には、それぞれ異なる利点と欠点があります。
automake
、GNU autoconf
、GNU
m4
のようなツールがインストールされている必要があり、ときには特定のバージョンが必要になる。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’呼び