Emacsのバッファや文字列は、多種多様な文字体系にわたる膨大な文字レパートリーをサポートしており、ユーザーは既知のほぼあらゆる書き言葉でテキストを入力・表示することができます。
こうした膨大な数の文字やスクリプトに対応するため、EmacsはUnicode標準に厳密に準拠しています。Unicode標準では、あらゆる文字に対してコードポイントと呼ばれる一意の番号を割り当てています。Unicodeで定義されているコードポイントの範囲、すなわちUnicodeのコードスペースは、0..#x10FFFF(16進表記)までを含みます。Emacsはこの範囲を#x110000..#x3FFFFFまでのコードポイントで拡張しており、Unicodeに統一されていない文字や、文字として解釈できない生の8ビットバイトの表現にこれを利用しています。したがって、Emacsにおける文字のコードポイントは22ビットの整数となります。
メモリを節約するため、Emacsはバッファや文字列内のテキスト文字のコードポイントとして、固定長の22ビット数値を保持しません。その代わりに、Emacsは文字の可変長内部表現を採用しており、コードポイントの大きさに応じて、各文字を1〜5個の8ビットバイトのシーケンスとして格納します28。例えば、任意のASCII文字は1バイト、Latin-1文字は2バイトを占有します。このようなテキストの表現方式をマルチバイトと呼びます。
Emacs外部では、文字はISO-8859-1、GB-2312、Big-5など、さまざまなエンコーディングで表現できます。Emacsは、テキストをバッファや文字列に読み込む際、あるいはテキストをディスクファイルに書き込んだり他のプロセスに渡したりする際に、状況に応じてこれらの外部エンコーディングと内部表現との間で変換を行います。
Emacsでは、バッファや文字列内でエンコード済みテキストやバイナリの非テキストデータを保持・操作する必要がある場合があります。例えば、Emacsがファイルを読み込む際は、まずファイルのテキストをそのままバッファに読み込み、その後になって初めて内部表現に変換します。変換前、バッファにはエンコード済みテキストが保持されています。
Emacsにとって、エンコードされたテキストは本来の意味でのテキストではなく、むしろ生の8ビットバイト列です。エンコードされたテキストを保持するバッファや文字列をユニバイトバッファや文字列と呼ぶのは、Emacsがそれらを個々のバイト列として扱うためです。通常、Emacsはユニバイトバッファや文字列を\237のような8進数コードで表示します。エンコードされたテキストやバイナリの非テキストデータを扱う場合を除き、ユニバイトバッファや文字列は決して使用しないことを推奨します。
バッファにおいて、変数 enable-multibyte-characters
のバッファローカル値が、使用される表現を指定します。文字列の表現は、文字列が構築される際に決定され、文字列に記録されます。
この変数は、現在のバッファのテキスト表現を指定します。値が nil
以外の場合、バッファにはマルチバイトテキストが含まれています。それ以外の場合は、ユニバイト符号化テキストまたはバイナリの非テキストデータが含まれています。
この変数を直接設定することはできません。代わりに、関数 set-buffer-multibyte
を使用してバッファの表現を変更してください。
バッファ位置は文字単位で計測されます。この関数は、現在のバッファにおけるバッファ位置 position
に対応するバイト位置を返します。これはバッファの先頭で 1 となり、バイト単位で順に増加します。position が範囲外の場合、値は nil となります。
現在のバッファにおいて、指定された byte-position
に対応するバッファ位置を文字単位で返します。byte-position が範囲外の場合、値は nil となります。マルチバイトバッファでは、byte-position
の値が文字境界ではなく、単一の文字を表すマルチバイトシーケンスの内部にある場合があります。この場合、本関数は byte-position
を含むマルチバイトシーケンスを持つ文字のバッファ位置を返します。言い換えれば、同一の文字に属するすべてのバイト位置に対して値が変化することはありません。
以下の2つの関数は、Lispプログラムがバッファの訪問先ファイルにおけるバッファ位置をバイトオフセットにマッピングする必要がある場合に有用です。
この関数は position-bytes
に似ていますが、現在のバッファにおけるバイト位置の代わりに、バッファ内の指定された文字 position
に対応するバイトが、現在のバッファのファイル先頭からどれだけ離れているかというオフセットを返します。この変換には、バッファのファイル内でテキストがどのようにエンコードされているかを知る必要があり、そのために
coding-system 引数が用意されています(デフォルト値は buffer-file-coding-system です)。オプション引数 quality は、結果の精度を指定するもので、以下のいずれかである必要があります:
exact結果は正確でなければなりません。この関数はバッファの大部分をエンコードおよびデコードする必要があるかもしれず、これはコストが高く、処理が遅くなる可能性があります。
approximate値は近似値である場合があります。関数はコストの高い処理を回避し、不正確な結果を返すことがあります。
nil厳密な結果の算出にコストのかかる処理が必要な場合、関数は近似値ではなく nil
を返します。引数を省略した場合のデフォルト動作はこれです。
この関数は、ファイルの先頭からの0ベースのバイトオフセットである byte
で指定されたファイル位置に対応するバッファ位置を返します。この関数は、bufferpos-to-filepos とは逆の変換を行います。オプション引数 quality および coding-system は、bufferpos-to-filepos と同じ意味と値を持ちます。
string がマルチバイト文字列の場合は t
を、それ以外の場合は nil を返します。また、この関数は string が文字列以外のオブジェクトである場合にも nil
を返します。
この関数は、string のバイト数を返します。string
がマルチバイト文字列の場合、この値は (length string) より大きくなることがあります。
この関数は、すべての引数 bytes を連結し、その結果をユニバイト文字列とします。
この内部表現は、任意のUnicodeコードポイントを表現するためにUnicode標準で定義されているUTF-8と呼ばれるエンコーディングの一つに基づいていますが、EmacsはUTF-8を拡張し、生の8ビットバイトやUnicodeに統合されていない文字に使用する追加のコードポイントを表現しています。