[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[debian-devel:10295] Draft 1 (Re: I18N Document)



久保田です。

Draft 1 in Japanese です。
こんなの出すのめちゃくちゃ恥ずかしいんですが。

INTRODUCTION TO I18N






CONTENTS

1. Introduction

2. Coding Systems
   2.1. General Discussion
      2.1.1. Stateless and Stateful
      2.1.2. Bytes, Characters, and Columns
   2.2. ASCII and ISO 646
   2.3. ISO 8859-* 
   2.4. ISO 2022-*

3. Output to Display
   3.1. Console Programs
      3.1.1. Invoked in the Console
      3.1.2. Invoked in a Terminal Emulator
   3.2. X Clients
4. Input from Keyboard
   4.1. Console Programs
      4.1.1. Invoked in the Console
      4.1.2. Invoked in a Terminal Emulator
   4.2. X Clients
5. Internal Processing and File I/O

6. Other Special Topics
   6.1. Tcl/Tk Programs
   6.2. Perl Scripts
   6.3. Shell Scripts

7. Examples of I18N








1. Introduction

Debian には、数多くのソフトウェアが存在する。そのなかには、
テキストデータを扱ったり、文字を表示したり入力したりするものが
数多くある。しかし、それらのなかには英語 (ASCII コード) しか
使えないものも多く、それらは、英語以外の言語を使う人々にとって、
存在しないも同然である。

プログラムが英語以外の言語を扱えるようにするために、
いくつかのアプローチがある。
それぞれの違いを知り、どのアプローチをとるのかを考えなければならない。

L10N (localization)
	英語以外の特定の言語のサポートだけを追加すること。
	たとえば、Nemacs (Nihongo Emacs) は英語と日本語を扱える。

I18N (internationalization)
	多くの言語を扱えるようにすること。ただし、LANG 環境変数
	などによって、起動時に言語を指定しなければならない。
	同時に扱えるのは英語ともう一つである。LOCALE や gettext
	に基づくプログラムは、このアプローチである。

M17N (multilingualization)
	多くの言語を同時に扱えるようにすること。いまのところ、
	じゅうぶんにこれを達成しているのは Mule (MULtilingual
	enhancement of GNU Emacs) くらいのものである。

プログラマから見れば、

L10N は、自分の言語の直接の知識だけで行うことができる。たとえば、
SHIFT-JIS というコーディングシステムに関する知識を直接
コーディングすれば、それだけで L10N は達成できる。これだけ
でも、よく似たコーディングシステムを持つ他の言語での使用に
耐えることもある。たとえば、EUC-JP を意識はしないが破壊しない
ように作ったプログラムは、EUC-KR をも破壊しない。

I18N は、C だと locale や wchar_t などの枠組を用いることで
達成することができる。特定のコーディングシステムについての
知識を使うべきではないが、locale などのような枠組が存在しない
分野では使わざるを得ない (たとえばコンソールでの文字入力)。

M17N は、多数の言語に関する実装を、locale などの枠組を用いずに
自前で行わなければならない。Mule など、非常に少数のプログラム
のみが、M17N を達成している。

ここでは、I18N を中心に述べることにする。しかし、
I18N では、たとえば日本語と韓国語を両方含むようなテキストを
扱うことができないことに注意せよ。この場合には M17N が必要で
あるが、それはこの文書の範囲を超えている。

ラテン文字以外を用いる人々にとって、必要な国際化とは、
自国語でメッセージが出て来たり、自国語のファイル名が
使えたりすることではない。それはもちろん、できたほうがいいには
違いないが、私達の現状から見ると、そのような要求はどちらかというと
ぜいたくな要求である。私達がぜひ必要としている I18N とは、
私達が使う文字が正しいフォントで画面を破壊したり誤動作したり
することなく表示されること、私達が使う文字を入力する方法が
提供され、正しく入力されることである。grep や perl などの
テキスト処理プログラムが誤動作することなく正しく私達の
文字を扱ってくれれば、なおよい。

私達が置かれている以上のような現状にかんがみ、このドキュメントでは、
正しい、あるべき、理想の I18N よりも、いま最低限の要求を
満たすには何が必要か、ということに重点を置くことにする。










2. Coding Systems

ここでは、まず、文字コードについて説明する。
この章の最後では、個別の言語について、
文字コードにまつわる現状について
説明している。この部分は、それぞれの言語圏に属する人からの
contribution を期待したい。


2.1. General Discussion

2.1.1. Stateless and Stateful

文字コードには、stateful なものと stateless なものがある。
文字コードには衝突があり、エスケープシーケンスで切替えて
使うのが sateful、そうでないのが stateless である。


2.1.2. Bytes, Characters, and Columns

ASCII 文字は、1 文字は必ず 1 バイトで表現され、
かつ、1 文字はコンソール上や X の固定幅フォントでは
必ず 1 カラムを占有する。I18N では、このような
仮定に基づくべきではない。バイト数、文字数、カラム数の
うちのどれを扱っているのかを意識してプログラミング
しなければならない。



2.2. ASCII and ISO 646-*

ASCII コードは、7 ビットの文字コードである。0x21 - 0x7e の範囲に
表示可能文字が含められている。これについては説明は不要だろう。
ASCII コードに基づいて決められたのが ISO 646 BCT (Basic Code Table)
である。ASCII コードのうち、0x23, 0x24, 0x40, 0x5b, 0x5c, 0x5d,
0x5e, 0x60, 0x7b, 0x7c, 0x7d, 0x7e の文字は、国ごとに違う文字を
割り当ててもよい。たとえば日本では、0x5c にはバックスラッシュでは
なく円の通貨記号があてはめられている。

私の知る限り、世界中の全ての文字コードは、ASCII あるいは ISO 646 と
共存できるように工夫されてある。

0x00 - 0x1f の範囲は制御コードである。


2.3. ISO 8859-* 

ASCII, ISO 646 が 7 ビットしか使わなかったのに対し、8 ビットすべてを
使うのが ISO 8859 である。ISO-8859-1, ISO-8859-2, ... と複数の
バリエーションがある。0x21 - 0x7e の範囲は ASCII と同一である。

0x80 - 0x9f の範囲は制御コードであり、実際に文字が割り当てられて
いるのは 0xa0 - 0xff の範囲である。


2.4. ISO 2022

日本語、韓国語、中国語などは、非常に多くの文字を持つので、
ISO 8859 のような単純な方法で文字を扱うことができない。
そこで用いられているのが、ISO 2022 である。ISO 2022 では、
ISO 646-* のような1バイト code set と日本語のような
multibyte code set を含む複数の code sets を切り替えながら
扱うための規格である。

ISO 2022 は、非常に複雑な規格であり、ここですべて説明
することはできないが、簡単に説明する。

ISO 2022 は、複数の cod set を切替えて使うための仕組みに
ついて定義している。7 ビット版と 8 ビット版がある。まず、
7 ビット版について説明する。

まず、各々の言語の code set は、0x21 - 0x7e の範囲の 1 バイトの 
code set または、0x21 - 0x7e の範囲の複数バイトの code set で
なければならない。たとえば、ASCII は 1 バイト code set、
JIS X 0208 (日本語) は 2 バイト code set である。

次に、G0, G1, G2, G3 の 4 つの buffer を考える。その 4 つの
buffer に、各々の code set を "designate" (指示する) する。
それには、ESC で始まる 3 または 4 バイトのコードを用いる。

最後に、実際の 7 ビット空間に、G0, G1, G2, G3 のいずれかを
"invoke" (呼び出す) する。それには、1 バイトのコードを用いる。

8 ビット版は、7 ビット版の拡張である。8 ビット空間は 7 ビット
空間の倍の広さがあるので、最上位ビットが 0 である「左」と
1 である「右」とで、別々の buffer (G0, G1, G2, G3) を
"呼び出す" ことができる。

ISO 2022 は非常に複雑なので、そのサブセットがよく用いられる。
たとえば、ISO-2022-JP、ISO-2022-INT-1、EUC (Extended Unix Code)-JP、
Compound Text がその例である。

これらのサブセットでは、code set に制限があったり、designate や
invoke に制限があったりする。
たとえば、Compound Text は X での文字データのやりとりに用いられる
coding system であるが、「左」には G0, 「右」には G1 を
invoke した状態で固定されている。


2.5. ISO/IEC 10646 (UCS-4, UCS-2), UNICODE, UTF-8, UTF-16



2.6. Current Situation in Each Country

それぞれの言語についての各論である。
さまざまな言語圏の人々からの contribution を期待する。
そのとき、

  1. どのような文字コードがあり、どの文字コードをサポートすることが必要か。
  2. 1文字あたりのバイト数 (stateful/stateless の別も)
  3. 1文字あたりのカラム数

を含むようにしてほしい。また、文字の合成が可能な文字コードや、
左から右へと表記できない文字を持つ言語圏の著者は、
それについて、どのように解決しているのかの説明もしてほしい。



2.6.1. Japanese

日本で使われているコードセットは、すべて、日本語コードと ASCII
コードの組合せになっている。そこで、最初に日本語コードを、次に
組合せについて説明する。


2.6.1.1. 日本語コード

日本語コードには、

JIS X 0201 (about 60 characters)
JIS X 0208 (about 7000 characters)
JIS X 0212 (about 6000 characters)

の文字コードがある。最近、もうひとつ新しいコードが決められた。
JIS X 0201 は 8 ビットコンピュータ時代の産物であり、obsolate である。
JIS X 0212 はほとんど使われていない。したがって、JIS X 0208 のみを
サポートすれば、たいがいの用は足りる。

JIS X 0208 は、ISO-2022 の枠組に従うように、0x21 - 0x7e の範囲の
バイト 2 つによってできている。

2.6.1.2. ASCII と JIS X 0208 との組合せ方法

3つの組合せ方法、したがって、3つの code system がある。

 * ISO-2022-JP (aka JIS code)
    - stateful
    - 7bit
    - ASCII, JIS X 0201, JIS X 0208, JIS X 0212 can be used.
    - used for e-mail and web.
 * EUC-JP (Extended UNIX Code)
    - stateless
    - 8bit
    - ASCII, JIS X 0201, JIS X 0208, JIS X 0212 can be used.
    - widely used for UNIX. For example, almost all Japanese 
      message catalogs for gettext is written in EUC-JP.
    - Japanese code is mapped in 0xa0 - 0xff. 
 * SHIFT-JIS (aka Microsoft Kanji Code)
    - stateless
    - 8bit
    - ASCII, JIS X 0201, and JIS X 0208 can be expressed.
    - The only Japanese code for Windows/Macintosh. This makes
      SHIFT-JIS the most popular code in Japan.

I think it is almost sufficient to support EUC-JP or even
its subset (without JIS X 0201 nor JIS X 0212).

UNICODE はほとんど使われていない。


2.6.1.3. Conclusion and Information for Programmers

通常は、EUC-JP のみをサポートすればいい。あるいは、EUC-JP のサブセット
(ASCII and JIS X 0208) のみをサポートすればいい。この場合、
0x21 - 0x7e は ASCII と同じで、0xa0 - 0xff のバイトは JIS X 0208 
日本文字で必ず 2 バイトで 1 文字である。日本語表示可能なコンソール
(kon, kterm, krxvt) では日本文字は 2 カラムを占有する。







3. Output to Display

ここで表示とは、gettext を使ったメッセージの i18n のことではない。
フォントが正しく表示されるかどうか、という問題である。たとえば、
libcanna1g パッケージをインストールし、コンソール上で、あるいは 
xterm 上で、/usr/doc/libcanna1g/README.jp.gz を表示したらどうなるか、
試してみればよい。この文章は日本語で書かれているが、日本人でさえ
こんな文章は読めない。このような状況で、gettext を使いてたとえば
日本語メッセージを用意したら、意味不明の記号が表示されてしまう。
英語メッセージが表示されるよりもずっと悪い。

私は日本語を母語としているので、日本語に即して説明する。ほかの
言語では状況が違うかも知れない。しかし、少なくとも、韓国語と
中国語に関しては日本語とよく似た状況であろうと想像する。


3.1. コンソール上で動くプログラム

コンソール上で動くプログラムは、「表示」は自分自身の責任ではなく、
コンソールの責任である。そして、X Window System 上では各国語が
表示できる kterm、krxvt、cterm、hanterm などのターミナルエミュレータ
が存在するし、コンソール画面上でも、kon2 というプログラムがある。

だから、表示に関して言えば、quick hack として、8ビットクリーン化
だけでいい場合もある。ただし、(私が手を加える以前の
minicom のように) 1文字表示するたびに位置指定コードを送るプログラム
は、2バイト文字を分断させてしまうので、直さなければならない。

フォントの「幅」についてはいかなる standard も存在しない。
これが、ncurses などを使って画面のレイアウトを行うプログラムでは
問題になる。これには正しい解決法は存在しない。日本語の場合、韓国語の
場合、というように個別に対応する必要がある。私は Mule (MULtilingual
Emacs, GNU Emacs20 は Mule を取り込んでいる) がどんな実装をしているか
興味があるが、残念ながらソースを読む時間も能力もない。なお、
日本語フォントは、必ず 2 columns を占有する (JIS X 0201 は
1 column しか占有しないが、これは obsolate である)。
韓国語と中国語も ASCII の倍の幅がある。したがって、EUC を使う場合、
2 バイト文字は 1 バイト文字の倍の幅があるので、2 バイト文字のために
特別な処理をしなくても「偶然にも」レイアウトを崩さずに表示できる。

ただしそのときでさえ、1文字を表す2バイトを分断させないように、
注意を払わなければならない。

たとえば、行の折り返しによって文字が分断される可能性がある。
文字がある場所に別の文字を上書きするとき、もとの文字の半分が残ってしまうと
画面が崩れる原因になる。このとき、「カラム数が偶数なら大丈夫」とか
「上書きするときにカラム位置が偶数なら大丈夫」というのは誤りである。
なぜなら、2カラムを占有する文字と1カラムを占有する文字とが
混在しているからである。


3.2. X Window System

X は国際化されているので、フォントさえ用意してやれば、日本語や
その他の言語を表示することができる。そして、フォントを用意するのは
ユーザーの責任であり、プログラムの責任ではない。プログラムの側で
必要なことは、

  * LOCALE を使うことを宣言すること。setlocale()
  * X の国際化機能を有効にすること?
  * フォントの指定に注意すること (たとえば、-adobe-* に合致する
    日本語フォントは存在しない)。
  * i18n された Widget を使うこと。たとえば、Athena Widget や GTK++ は
    i18n されている。

私は X Window System 上のプログラミングの経験は (Tcl/Tk script 以外には)
まったくないので、どなたか詳しい説明に置き換えて欲しい。










4. Input from Keyboard

キーボード入力の I18N は、画面出力の I18N を前提とする。
Yes/No を入力すればいいだけのような場合、I18N は必要ではない。
入力のために変換を必要とする日本語で Y/N を答えるのは煩わしい
ことであると、ほとんどの日本人は考えている。韓国人や中国人も
同様であろう。


4.1. コンソールプログラム

4.1.1. Invoked in the Console

「入力」に関しては、Canna, Wnn などの個々の変換エンジンに直接
接続するしか方法はない。これに関しては、I18N の基板となる
standard は存在しないので、言語別に個別に対応しなければならない。

いくつかのプログラムは直接 Canna などの変換エンジンと接続できる
ように作られている。nvi-m17n-canna など。これに関しても、GNU 
Emacs 20 はコンソール上でさまざまな言語を入力できる機能を
持っていて、興味が持てる。もし GNU Emacs 20 の入力部分が
ライブラリとして利用可能なら、それはすばらしいことだと思う。


4.1.2. Invoked in X Terminal Emulator

X Window System には XIM という標準があり、一方、Canna や Wnn などの
個々の変換エンジンと XIM との仲介を行う kinput2 という
プログラムがあるので、ターミナルエミュレータの中で使うのであれば、
quick hack として8ビットクリーン化だけでいい。この意味でなら、
bash (libreadlineg2) (2.02.1-1.6) や tcsh (6.08.01-3) でさえ
2バイト文字の入力を受け付ける。

ただし、この段階では、2バイト文字を意識していないので、2バイト
文字をまたいでカーソル移動したり、2バイト文字を消去したりするときは、
ユーザーは2回操作しなければならない。これを間違えると、入力した文字列が
壊れてしまい、復旧できなくなる。


4.2. X Clinents

必要なことは、

  * XIM からの入力を受け付けること。On-the-Spot (その場変換) を
    受け付けるのが望ましいが必須ではない。
  * Compound Text を含むペーストを受け付けること。

である。