Emacsのバッファーと文字列は、既知のスクリプトで記述されたほとんどすべてのテキストをユーザーがタイプしたり表示できるように、多種多様な言語の広大な文字レパートリーをサポートします。
多種多様な文字やスクリプトをサポートするために、EmacsはUnicode標準(Unicode
Standard)に厳密にしたがいます。Unicode標準はすべての文字それぞれにたいして、コードポイント(codepoint)と呼ばれる一意な番号を割り当てています。コードポイントの範囲はUnicode、またはUnicodeコード空間(codespace)により定義され、範囲は0..#x10FFFF
(16進表記、範囲両端を含む)です。Emacsはこれを範囲#x110000..#x3FFFFF
のコードポイント範囲に拡張します。この範囲はUnicodeとして統一されていない文字や、文字として解釈できない8ビットrawバイト(raw
8-bit bytes)を表すために使用します。したがってEmacs内の文字コードポイントは22ビットの整数になります。
メモリー節約のために、Emacsはバッファーや文字列内のテキスト文字にたいするコードポイントである22ビットの整数を固定長で保持しません。かわりにEmacsは文字の内部表現として可変長を使用します。これはそのコードポイントの値に応じて、各文字を5ビットから8ビットのバイトシーケンスとして格納するものです25。たとえばすべてのASCII文字は1バイト、Latin-1文字は2バイトといった具合です。わたしたちはこれをテキストのマルチバイト(multibyte)表現と呼んでいます。
Emacs外部ではISO-8859-1、GB-2312、Big-5等のような多種の異なるエンコーディングで文字を表すことができます。Emacsはバッファーや文字列へのテキスト読み込み時、およびディスク上のファイルへのテキスト書き込みや他プロセスへの引き渡し時に、これらの外部エンコーディングと内部表現の間で適切な変換を行います。
Emacsがエンコード済みテキストや非テキストデータをバッファーや文字列に保持したり操作する必要がある場合も時折あります。たとえばEmacsがファイルをvisitする際には、まずそのファイルのテキストをそのままバッファーに読み込んで、その後にのみそれを内部表現に変換します。この変換前にバッファーに保持されいるのはエンコード済みテキストです。
Emacsに関する限り、エンコードされたテキストは実際のテキストではなく8ビットrawバイトです。エンコード済みテキストを保持するバッファーや文字列は、Emacsがそれらを個々のバイトシーケンスとして扱うことから、ユニバイト(unibyte)のバッファー(文字列)と呼んでいます。Emacsは通常はユニバイトのバッファーや文字列を\237
のような8進コードで表示します。エンコード済みテキストやバイナリー非テキストデータを処理する場合を除いて、ユニバイトバッファーとユニバイト文字列は決して使用しないよう推奨します。
バッファーでは変数enable-multibyte-characters
のバッファーローカルな値が使用する表現を指定します。文字列での表現は文字列構築時に判断して、それを文字列内に記録します。
この変数はカレントバッファーのテキスト表現を指定する。非nil
ならバッファーはマルチバイトテキスト、それ以外ならエンコード済みユニバイトテキスト、またはバイナリー非テキストデータが含れる。
この変数は直接セットできない。バッファーの表現の変更には、かわりに関数set-buffer-multibyte
を使用すること。
バッファー位置は文字単位で測られる。この関数はカレントバッファー内のバッファー位置を、それに対応するバイト位置でリターンする。これはバッファー先頭を1としてバイト単位で増加方向に数えられる。positionが範囲外なら値はnil
。
カレントバッファー内で与えられたbyte-positionに対応するバッファー位置を文字単位でリターンする。byte-positionが範囲外なら値はnil
。マルチバイトバッファーではbyte-positionの任意の値が文字境界上になく、1文字として表現されたマルチバイトシーケンス内にあるかもしれない。この場合には関数はその文字のマルチバイトシーケンスがbyte-positionを含むようなバッファー位置をリターンする。言い換えるとこの値は同じ文字に属するすべてのバイト位置にたいして変化しない。
以下の2つの関数はバッファーにvisitされているファイル内でのバイトオフセットとバッファー位置をLispプログラムがマッピングする際に有用です。
この関数はposition-bytes
と似ているがカレントバッファー内でのバイト位置ではなく、バッファー内のpositionにより与えられる文字に対応するカレントバッファーのファイル先頭からのオフセットをリターンする点が異なる。この変換にはバッファーのファイル内でテキストがエンコードされる方法を知ることが要求される。これがcoding-system引数の存在意義であり、デフォルトはbuffer-file-coding-system
の値。オプション引数qualityは結果のあるべき正確さを指定する。これは以下いずれかであること:
exact
正確な結果でなければならない。関数は高価で低速になり得るバッファーの大きな範囲のエンコードとデコードを要するかもしれない。
approximate
近似的な値が可能。関数は高価な処理を回避して不正確な結果をリターンするかもしれない。
nil
正確な結果に高価な処理を要するなら、関数は近似値ではなくnil
をリターンするだろう。これは引数が省略された場合のデフォルト。
この関数はbyte
(ファイル先頭からの0基準のバイトオフセット)が指定するファイル位置に対応するバッファー位置をリターンする。この関数はbufferpos-to-filepos
が行う変換と逆の処理を行う。オプション引数qualityとcoding-systemのもつ意味と値はbufferpos-to-filepos
の場合と同様。
stringがマルチバイト文字列ならt
、それ以外はnil
をリターンする。この関数はstringが文字列以外でもnil
をリターンする。
この関数はstring内のバイト数をリターンする。stringがマルチバイト文字列なら、これは(length
string)
より大きいかもしれない。
この関数は引数bytesをすべて結合して、その結果をユニバイト文字列で作成する。
この内部表現は任意のUnicodeコードポイントを表すための、UTF-8と呼ばれるUnicode標準によるエンコーディングの1つにもとづいたものですが、8ビットrawバイトおよびUnicodeに統一されていない文字を使用する追加のコードポイントを表現するためにEmacsはUTF-8を拡張しています。