\documentstyle[a4j]{jarticle}
\setcounter{secnumdepth}{6}
\setcounter{tocdepth}{6}
\topsep=0.1cm
\parsep=0.1cm
\itemsep=0.0cm
\begin{document}
\title{
tm における文字 code の取り扱いについて}
\author{
守岡 知彦\\
}
\date{
1996年7月18日}
\maketitle
\medskip

\section{charset 取り扱いに関する基本原則}
\medskip
\par
tm では原則として MIME で定められた charset 機構に基づいて文字 code
を取り扱う。これを実現するために、message を表示するための buffer
(preview buffer; cooked buffer) の他に生の（即ち、code 変換されておら
ず network code のままの）message が入った buffer (original article
buffer, raw buffer) を用いることとする。この条件が満たされれば、base64
や quoted-printable 等の encode を行なっていない場合でも、１つの
message に複数の文字 code を混在させることができる。
\medskip
\par
しかしながら、現実には幾つかの問題が存在する。１つは非 MIME message
の取り扱いであり、もう一つは上記のような方法をとることが困難な MUA を
利用する場合である。非 MIME message に対しては、tm は default の
charset を仮定することで対処している。後者の問題に関しては MUA 毎に
code 変換 program を設定し、raw buffer を作成することが困難な MUA の場
合、7bit, 8bit, binary のような encode されていない message の charset
による code 変換をやめるようにすることで対処している。
\medskip
\par
以下、実際の機構に関して説明する。
\medskip
\medskip

\section{文字 code の取り扱いに関する layer 構造}
\medskip
\par
tm は
\medskip
{\baselineskip=10pt
\begin{verbatim}
        (4) user interface layer (tm)
        (3) non-interactive MIME feature layer (tm)
        (2) MIME encoding layer (MEL) / utility function layer (tl)
        (1) emu API layer
        (0) (API of emacs variants)
\end{verbatim}}
\medskip
\par
という５層構造になっているが、文字 code の取り扱いも同様である。
\medskip
\par
第１層である emu API で全ての emacs variant で利用可能な基本関数を提
供し、第３層で tm-view で利用するための基本的な機能を実現し、第４層で
その界面を定義する。
\medskip
\medskip

\section{文字 code に関する emu API の機能}
\medskip
\par
EMACS には、元来、文字という概念は存在しなかった。よって、それを扱う
ための機能は存在しなかった。
\medskip
\par
emacs の世界に文字 code という概念を持ち込んだのは NEmacs である（多
分(\verb+^+\_\verb+^+;）。NEmacs は `JIS', `EUC', `Shift JIS'（および無変換）という３
種類の『漢字 code』を導入した。そして、これを数値で表現した。
\medskip
\par
NEmacs は日本語（の subset）しか扱う必要がなかったので高々３種類の文
字 code が使えれば十分であったが、これを多言語化した MULE ではより多数
の文字 code が扱うことが要求され、また、user が文字 code を定義できる
ことも必要であった。このため、数値ではなく、先頭と末尾に `*' を付けた
自己評価形式の定数で表現される coding-system という概念が導入された。
\medskip
\par
XEmacs に mule 機能を導入しようとした人達は自己評価形式の定数の代わ
りに coding-system を表す新たな型を導入することにした。また、この型に
対応する名前を symbol で与えた。このため、coding-system を表す大量の定
数は一掃された。
\medskip
\par
このように、現存する emacs variants の間では文字 code の表現法はさま
ざまである。もともと、emu はこの分野でもっとも機能の高い MULE をお手本
にこれの機能を emulate する関数を各 emacs variant に対して定義する方法
を採ったが、MULE を元に EMACS/MULE 統合版や XEmacs/mule が生まれるに従
い、coding-system 機能をそのまま使うのは得策ではないと判断するに至った。
代わりにより抽象度の高い MIME charset に関する API を用意することにし
た。
\medskip
\par
MIME charset は文字 code を表すものであり、MULE でいうところの
leading-char や EMACS/MULE や XEmacs/mule でいうところの charset に相
当するものではなく、mule の coding-system に相当する機能である。実際、
mule の coding-system の名前と MIME charset の名前は共通するものも少な
くない。
\medskip
\par
MIME charset の表現の仕方として、emu API では XEmacs/mule と同様、
symbol を用いることにした。MULE のような変数を使うと束縛に関する check
が必要であるが、symbol ではこのような check は不要である。また、将来的
に、XEmacs/mule の方法に統合されることを期待する意味もある。実際、
XEmacs/mule と emu API の間の gap は少なく、将来、全ての MIME charset
が XEmacs/mule の coding-system として定義されれば、emu としてこれを用
意する必要はなくなるだろう。
\medskip
\par
さて、以下では実際の機能を解説する。
\medskip
\begin{description}
\item[{[}変数{]}]charsets-mime-charset-alist
\medskip
\par
Key 部に charset の list, value 部に mime-charset をとる連想リ
スト。関数 charsets-to-mime-charset や関数
detect-mime-charset-region がこの変数を参照する。
\medskip
\item[{[}変数{]}]default-mime-charset
\medskip
\par
変数 charsets-mime-charset-alist で定義されていない charset の
list に対してつける MIME charset を示す。関数
charsets-to-mime-charset や関数 detect-mime-charset-region が
この変数を参照する。
\medskip
\item[{[}関数{]}]charsets-to-mime-charset         CHARSETS
\medskip
\par
charset の list `CHARSETS' に対応する MIME charset を返す。
\medskip
\item[{[}関数{]}]detect-mime-charset-region       start end
\medskip
\par
`START' と `END' で囲まれた領域に対応する MIME charset を返す。
\medskip
\item[{[}関数{]}]encode-mime-charset-region       START END CHARSET
\medskip
\par
`START' と `END' で囲まれた領域を MIME charset `CHARSET' で
encode する。
\medskip
\item[{[}関数{]}]encode-mime-charset-string       STRING CHARSET
\medskip
\par
文字列 `STRING' を MIME charset `CHARSET' で encode する。
\medskip
\item[{[}関数{]}]decode-mime-charset-string       STRING CHARSET
\medskip
\par
文字列 `STRING' を MIME charset `CHARSET' で decode する。
\medskip
\medskip
\end{description}

\section{文字 code に関する tm の実装}
\medskip
\par
もし、素直に charset を実現するだけなら emu API をそのまま使えば良い
のだが、実際には VM や RMAIL（および昔の GNUS, Gnus）といった raw
buffer を実現しにくい MUA では charset に対応することが困難である。こ
のため、tm-view はこのような MUA では純粋な意味での raw buffer の実現
を諦め original article buffer 中に既に charset に依らずに code 変換し
た message を入れることを認めている。
\medskip
\par
よって、以下の２種類の code 変換関数を使い分ける必要がある。
\medskip
\begin{description}
\item[{[}関数{]}]mime-charset/decode-buffer       charset \&optional encoding
\medskip
\par
current buffer を MIME charset `charset' で内部 code に変換す
る。この関数は `encoding' に依らず必ず code 変換を行なう。
\medskip
\item[{[}関数{]}]mime-charset/maybe-decode-buffer charset \&optional encoding
\medskip
\par
`encoding' が nil, "7bit", "8bit", "binary" 以外の時、即ち、
ASCII printable な encode が施されている時のみ、実際に、
current buffer を MIME charset `charset' で内部 code に変換す
る。それ以外の時は、何もしない。
\medskip
\medskip
\end{description}

\section{文字 code に関する tm の界面}
\medskip
\par
MUA によって文字 code を使い分けるために tm はここで述べるような界面
を提供する。
\medskip
\begin{description}
\item[{[}変数{]}]mime-viewer/code-converter-alist
\medskip
\par
この変数は key 部を major-mode, value 部を code 変換関数とする
連想 list である。これを用いて各 MUA 毎の code 変換関数を設定
する。code 変換関数は全節で述べた実装を用いること。
\medskip
\item[{[}変数{]}]mime::article/code-converter
\medskip
\par
method で用いられる code 変換関数を指定するための original
article buffer の buffer local 変数である。変数
`mime-viewer/code-converter-alist' よりも高い優先度で参照され
る。
\medskip
\item[{[}関数{]}]mime-preview/decode-text-buffer  charset encoding
\medskip
\par
MIME charset `charset', MIME encoding `encoding' で符号化され
た current buffer を decode する。code 変換は変数
`mime::article/code-converter' および
`mime-viewer/code-converter-alist' を参照して得られた関数によっ
て実行される。
\medskip
\medskip
\end{description}

\section{文字 code 関係の関数の使い方の指針}
\medskip
\par
tm-view の method がある content をある charset, encoding に従って
decode する場合は関数 mime-preview/decode-text-buffer を用いることとす
る。
\medskip
\par
tm-view の method において、ある content に対して再帰的に preview
buffer を作成するような場合で、変数 mime::article/code-converter を設
定する必要がある場合は、関数 mime-charset/decode-buffer および
mime-charset/maybe-decode-buffer を用いることとする。
\medskip
\par
それ以外の場合において、実際に code 変換を行なうような場合は、emu
API の機能を用いることとする。
\end{document}
