[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2. MIME メッセージの作成

MIME メッセージの作成はうんざりする仕事だし簡単でもありません。 そこで、MML (MIME Meta Language) という言語を解析し て、MIME メッセージを生成するための、mml というライブラ リーが作られました。

主要なインターフェース関数は mml-generate-mime です。これは現在 の (狭められた) バッファーの内容物を調べて、MIME メッセージを 含む文字列を返します。


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.1 単純な MML の例

multipart/alternative’ の単純な例です:

 
<#multipart type=alternative>
This is a plain text part.
これはプレーンテキストのパートです。
<#part type=text/enriched>
<center>This is a centered enriched part</center>
<center>これは中心に置かれる enriched パートです</center>
<#/multipart>

これを mml-generate-mime に通すと、次のものが得られます:

 
Content-Type: multipart/alternative; boundary="=-=-="

--=-=-=
Content-Type: text/plain; charset=iso-2022-jp

This is a plain text part.
これはプレーンテキストのパートです。

--=-=-=
Content-Type: text/enriched; charset=iso-2022-jp

<center>This is a centered enriched part</center>
<center>これは中心に置かれる enriched パートです</center>

--=-=-=--

(実際には、日本語の部分は ‘charset=iso-2022-jp’ でエンコードされた ものになります。)


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.2 MML の定義

MML 言語はとても単純です。SGML アプリケーションに少し似ていま すが、異なるものです。

MML の主要な概念は「パート」です。それぞれのパートを異なるタイ プにしたり、異なる文字セットを使うことができます。パート は ‘<#part ...>’ タグで記述します。マルチパート型のパート は ‘<#multipart ...>’ タグで始めます。それぞれのパート は ‘<#/part>’ タグか ‘<#/multipart>’ タグで終端しますが、(それ らが無くても) ‘<#part ...>’ で始まったタグは次のパートの始まりによっ ても閉じられます。

<#external ...>’ タグというものもあります。これ は ‘external/message-body’ 型のパートを記述するために使われます。

それぞれのタグは「parameter=値」の形式で、一つ以上のパラメーターを含むこ とができます (もちろん無いこともあります)。値をクォーテーションマー ク ("...") で囲むことができますが、値が空白文字を含む場合以外は囲む必要 がありません。したがって、‘filename=/home/user/#hello$^yes’ は完全 に有効です。

以下のパラメーターは MML で使われるものです。意味を持たないパ ラメーターは無視されます。MML パラメーターの名前 は MIME パラメーターの名前と同じで、括弧の中に付記してあるのは、 それが使われるヘッダーです。

type

パートの MIME タイプです (Content-Type)。

filename

そのパートの本体が含むことになるファイルの名前で す (Content-Disposition)。

charset

パートの内容物をエンコードするときに使われる文字セットで す (Content-Type)。See section 文字セットの変換.

name

パートをファイルに保存するときのファイル名を示唆するために使われるかもし れません (Content-Type)。

disposition

配置指定に使います。有効な値は ‘inline’ と ‘attachment’ で す (Content-Disposition)。

encoding

有効な値は ‘7bit’, ‘8bit’, ‘quoted-printable’ およ び ‘base64’ です (Content-Transfer-Encoding)。See section 文字セットの変換.

description

パートの説明書きです (Content-Description)。

creation-date

パートが作成された時刻 (RFC822 形式) です (Content-Disposition)。

modification-date

パートが変更された時刻 (RFC822 形式) です (Content-Disposition)。

read-date

パートが読まれた時刻 (RFC822 形式) です (Content-Disposition)。

recipients

パートを誰宛てに暗号化/署名するかを指定します。これは To/CC を基にした自 動検出よりも優先されます。

sender

パートに署名するときの名義です。このフィールドはディフォルトの鍵が使われ ないようにするために使われます。

size

パートのサイズを octet (8-bit) の単位で表しま す (Content-Disposition)。

sign

この MML のパートに、何の技術手段 (smime, pgp ま たは pgpmime) で署名するかを指定します。

encrypt

この MML のパートを、何の技術手段 (smime, pgp ま たは pgpmime) で暗号化するかを指定します。

以下は ‘text/plain’ のためのパラメーターです:

format

テキストを整形するためのパラメーターで、有効な値は ‘fixed’ (ディフォ ルト) と ‘flowed’ です。普通はこれを手で設定しません。それは、テキ ストの本文が、RFC 2646 で定められた特別な方法で整形されることを必要とす るからです。See section 流動テキスト.

以下は ‘application/octet-stream’ のためのパラメーターです:

type

パートのタイプです (Content-Type)。これは人間が読むことを想定した、 非公式なものです。

以下は ‘message/external-body’ のためのパラメーターです:

access-type

ファイルを取得するための、サポートされているアクセス手段を示す語です。値 は ‘ftp’, ‘anon-ftp’, ‘tftp’, ‘localfile’ およ び ‘mailserver’ のどれかです。(Content-Type.)

expiration

ファイルが取得できなくなるかもしれない日時 (RFC822 形式) です。 (Content-Type.)

size

Octet (8-bit) の単位で表したファイルのサイズです。(Content-Type.)

permission

有効な値は ‘read’ と ‘read-write’ です (Content-Type)。

以下は ‘sign=smime’ のためのパラメーターです:

keyfile

署名する人の鍵と証明書を含んでいるファイルです。

以下は ‘encrypt=smime’ のためのパラメーターです:

certfile

受取人の証明書を含んでいるファイルです。


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.3 高度な MML の例

複雑なマルチパート・メッセージの例です。これは ‘multipart/mixed’ で す。多数のパートを含んでいて、その一つは ‘multipart/alternative’ で す。

 
<#multipart type=mixed>
<#part type=image/jpeg filename=~/rms.jpg disposition=inline>
<#multipart type=alternative>
This is a plain text part.
これはプレーンテキストのパートです。
<#part type=text/enriched name=enriched.txt>
<center>This is a centered enriched part</center>
<center>これは中心に置かれる enriched パートです</center>
<#/multipart>
This is a new plain text part.
これは新しいプレーンテキストのパートです。
<#part disposition=attachment>
This plain text part is an attachment.
このプレーンテキストのパートは添付ファイルです。
<#/multipart>

そして、これが結果の MIME メッセージです:

 
Content-Type: multipart/mixed; boundary="=-=-="

--=-=-=
Content-Type: image/jpeg
Content-Disposition: inline; filename=rms.jpg
Content-Transfer-Encoding: base64

/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRof
Hh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/wAALCAAwADABAREA/8QAHwAA
AQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQR
BRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RF
RkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ip
qrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/9oACAEB
AAA/AO/rifFHjldNuGsrDa0qcSSHkA+gHrXKw+LtWLrMb+RgTyhbr+HSug07xNqV9fQtZrNI
AyiaE/NuBPOOOP0rvRNE880KOC8TbXXGCv1FPqjrF4LDR7u5L7SkTFT/ALWOP1xXgTuXfc7E
sx6nua6rwp4IvvEM8chCxWxOdzn7wz6V9AaB4S07w9p5itow0rDLSY5Pt9K43xO66P4xs71m
2QXiGCbA4yOVJ9+1aYORkdK434lyNH4ahCnG66VT9Nj15JFbPdX0MS43M4VQf5/yr2vSpLnw
5ZW8dlCZ8KFXjOPX0/mK6rSPEGt3Angu44fNEReHYNvIH3TzXDeKNO8RX+kSX2ouZkicTIOc
L+g7E810ulFjpVtv3bwgB3HJyK5L4quY/C9sVxk3ij/xx6850u7t1mtp/wDlpEw3An3Jr3Dw
34gsbWza4nBlhC5LDsaW6+IFgupQyCF3iHH7gA7c9R9ay7zx6t7aX9jHC4smhfBkGCvHGfrm
tLQ7hbnRrV1GPkAP1x1/Hr+Ncr8Vzjwrbf8AX6v/AKA9eQRyYlQk8Yx9K6XTNbkgia2ciSIn
7p5Ga9Atte0LTLKO6it4i7dVRFJDcZ4PvXN+JvEMF9bILVGXJLSZ4zkjivRPDaeX4b08HOTC
pOffmua+KkbS+GLVUGT9tT/0B68eeIpIFYjB70+OOVXyoOM9+M1eaWeCLzHPyHGO/NVWvJJm
jQ8KGH1NfQWhXSXmh2c8eArRLwO3HSv/2Q==
--=-=-=
Content-Type: multipart/alternative; boundary="==-=-="

--==-=-=
Content-Type: text/plain; charset=iso-2022-jp

This is a plain text part.
これはプレーンテキストのパートです。

--==-=-=
Content-Type: text/enriched; charset=iso-2022-jp; name=enriched.txt

<center>This is a centered enriched part</center>
<center>これは中心に置かれる enriched パートです</center>

--==-=-=--

--=-=-=
Content-Type: text/plain; charset=iso-2022-jp

This is a new plain text part.
これは新しいプレーンテキストのパートです。

--=-=-=
Content-Type: text/plain; charset=iso-2022-jp
Content-Disposition: attachment

This plain text part is an attachment.
このプレーンテキストのパートは添付ファイルです。

--=-=-=--

(実際には、日本語の部分は ‘charset=iso-2022-jp’ でエンコードされた ものになります。)


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.4 エンコーディングのカスタマイズ

mm-body-charset-encoding-alist

MIME 文字セットに割り当てるエンコーディングです。この変数は、 例えば他の要件によって特定のエンコーディングが強制されないときに、通常使 われます (電子署名されたメッセージは 7bit エンコーディングを必要とします)。 ディフォルト値は次の通りです。

 
((iso-2022-jp . 7bit)
 (iso-2022-jp-2 . 7bit)
 (utf-16 . base64)
 (utf-16be . base64)
 (utf-16le . base64))

例えば ISO-8859-1 文字セットが quoted-printable でエンコードされないよう にしたい場合は、この変数に (iso-8859-1 . 8bit) を追加すれば良いで しょう。MMLencoding タグを使って、メッセージ毎にそ れで指定した値をこの変数より優先させることもできま す (see section MML の定義)。

mm-coding-system-priorities

送出するメッセージで使う coding system の優先度を指定します。ディフォル ト値は nil です (その場合は Emacs におけるディフォルトの優先順位 が適用されます) が、日本語環境で Emacs を実行する場合 は (iso-8859-1 iso-2022-jp iso-2022-jp-2 shift_jis utf-8) になり ます。値は coding system のシンボルのリストです (coding system の別名を 使っても構いません。設定するときは M-x describe-coding-system を使っ て、coding system の名前が正確であることを確かめてください)。例え ば UTF-8 を最優先とするように Emacs を設定したものの、可能な場合 は ISO-8859-1 でメッセージを送信するようにしたいという場合だったら、こ の変数を (iso-8859-1) にすれば良いでしょう。 MMLcharset タグを使って、メッセージ毎にそれで指定し た値をこの変数より優先させることもできます (see section MML の定義)。

訳注: 日本語環境とは current-language-environment 変数の値 が ‘Japanese’ になっている環境のことです。日本語のメッセージのエン コードには伝統的に iso-2022-jp が使われているのに対し、Emacs で定 められた優先順位に基づくと euc-jpshift_jis などが第一 候補になってしまうので、この値が nil ではよろしくないのです。

なお、ラテン語圏の人たちに宛てて送るメッセージが、彼らがデコードできない かもしれない iso-2022-jp-2 などでエンコードされてしまうのを防ぐた めに、ディフォルト値の先頭に iso-8859-1 が置かれています。

ニュースグループ階層ごとに優先するべき文字セットが異なるので、Gnus で は mm-coding-system-priorities の値を階層によって切り替える必要が あるでしょう。そのための例です:

 
(add-to-list 'gnus-newsgroup-variables 'mm-coding-system-priorities)
(setq gnus-parameters
      (nconc
       ;; Some charsets are just examples!
       '(("^cn\\." ;; Chinese
          (mm-coding-system-priorities
           '(iso-8859-1 cn-big5 chinese-iso-7bit utf-8)))
         ("^cz\\.\\|^pl\\." ;; Central and Eastern European
          (mm-coding-system-priorities '(iso-8859-2 utf-8)))
         ("^de\\." ;; German language
          (mm-coding-system-priorities '(iso-8859-1 iso-8859-15 utf-8)))
         ("^fr\\." ;; French
          (mm-coding-system-priorities '(iso-8859-15 iso-8859-1 utf-8)))
         ("^fj\\." ;; Japanese
          (mm-coding-system-priorities
           '(iso-8859-1 iso-2022-jp iso-2022-jp-2 shift_jis utf-8)))
         ("^ru\\." ;; Cyrillic
          (mm-coding-system-priorities
           '(koi8-r iso-8859-5 iso-8859-1 utf-8))))
       gnus-parameters))
mm-content-transfer-encoding-defaults

MIME のタイプに割り当てるエンコーディングです。この変数は、例 えば他の要件によってより安全なエンコーディングが強制されないときに、通常 使われます (電子署名されたメッセージは 7bit エンコーディングを必要としま す)。通常の MIME エンコーディングの他に、 quoted-printable と base64 のうちで最も効率的な方を個々の場合に使うべき であることを示す qp-or-base64 を使うこともできます (訳 注: qp-or-base64 の実際の動作は、quoted-printable と base64 の両 方でエンコードしてみて、サイズが小さくなる方を採用することです)。

qp-or-base64 にはもう一つの効果があります。それ は MIME のパートが MTA によって壊されないようにするために、長 い行を折り畳みます。quoted-printablebase64 もそうです。

パートが受信したときのままの生の転送されたメッセージ (例えば、引数 に 2 を与えた gnus-summary-mail-forward によって作られるもの) で あるか、‘text/*’ タイプや ‘message/*’ ではない場合に、これが本 文のエンコーディグに影響を及ぼすことに注意してください。それらの場合でさ え、MMLencoding タグを使って、メッセージ毎にそ れで指定した値をこの変数より優先させることもできま す (see section MML の定義)。

mm-use-ultra-safe-encoding

これが非-nil である場合、本文に 76 文字よりも長い行や "From " で 始まる行があったら、それらのテキストのパートは quoted-printable でエンコー ドされます。非-7bit エンコーディング (8bit, バイナリー) は一般に認められ ていません。この変数を nil 以外の値に設定しておくことは、8bit を 通さない MTA か MDA がメッセージを改変してしまう確率を下げます。これは直 接に設定されるのではなく、他の関数によって (例えば、電子署名されるメッセー ジをエンコードするときに) 必要に応じて束縛されるべきです。


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.5 文字セットの変換

MMLMIME に変換するときに、Emacs の内部で作られ た MIME パートのそれぞれについて、適切な文字セットを選ばなけれ ばなりません。

MULE 機能が無い Emacs を走らせている場合だったら、この処理は単純で す。パートがどんな非-ASCII (8-bit) 文字を含んでいても、 mail-parse-charset で与えられる MIME 文字セット (シンボ ル) を使えば良いのです。(もっとも、この変数を直接に設定しないでください。 ディフォルトの文字セットを変更したい場合は、MIME メッセージを 処理するために使うパッケージの説明書を調べてください。例えば: see (message-ja)Various Message Variables section ‘いろいろなメッセージ変数’ in The Message Manual)。ASCII 文字セットしか無ければ、 US-ASCII が MIME 文字セットとして使われるのはもちろんです。

MULE 機能を備えた Emacs を走らせている場合は、ものごとは多少複雑に なります。この場合は、パートで使われている MULE 文字セットのリスト を取得し、Emacs 自身が提供するテーブルか、XEmacs のため の mm-mime-mule-charset-alist 変数の値に基づいて、それら の MULE 文字セットを MIME 文字セットに変換します。結果が 単一の MIME 文字セットだったら、それを使ってパートをエンコード します。しかし、結果の MIME 文字セットのリストが二つ以上の要素 を含んでいる場合には、二つのことが起こり得ます。もしパートを UTF-8 でエ ンコードすることが可能だったら、その文字セットを使います。(このため に Emacs は utf-8 coding system をサポートしていなければなりませ ん。また、そのパートを構成するすべての文字に対応するものが、Unicode の定 義に存在していなければなりません。) 何らかの理由によって UTF-8 を利用で きない場合、そのパートは、それぞれが単一の MIME 文字セットでエ ンコードすることができるように、いくつかに分割されます。もっとも、パート は行の境界でしか分割することができないので、単一の行をエンコードするため に複数の MIME 文字セットが必要だとすると、そのパートをエンコー ドすることは不可能です。

MULE 機能を備えた Emacs を走らせている場合、どの coding system を使 うかの優先順位は Emacs 自身から継承されます。これは、も し Emacs が UTF-8 を優先するように設定されていると、それがメッセージのエ ンコードに使われるということです。ただ し mm-coding-system-priorities 変数の値を変えることによって、これ を変更することはできます (see section エンコーディングのカスタマイズ)。

メッセージを作成するときに MMLcharset タグを設定す ることによって、使われる文字セットをそれにすることができます。

文字列のエンコーディング (quoted-printable, 8bit など) はここでの議論と 直交する概念です。それは mm-body-charset-encoding-alist 変数 と mm-content-transfer-encoding-defaults 変数によって制御されま す (see section エンコーディングのカスタマイズ)。


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.6 変換

mime-to-mml 関数を使って MIME メッセージ (マルチパート でも可) を MML に変換することができます。これは現在のバッファー にある MIME メッセージに作用して、MIME の境界 を MML の印付け (markup) で置き換えます。テキストではないパー トの内容物は、そのバッファーに置かれる代わりに MML タグを介し て参照される別のバッファーに置かれます。

mml-to-mime 関数を使って、逆に MML メッセージ を MIME に変換することができます。

これらの関数が行なうことはある意味で「不可逆」(lossy) です。 mime-to-mml を実行し、次に mml-to-mime を実行すると、元と まったく同じメッセージには戻らないでしょう。ヘッダーの順序のようなどうで も良いことが違ってしまうだけでなく、それぞれのヘッダーの内容も変化してし まうかもしれません。例えば、元のメッセージが base64 でテキストをエンコー ドしてあっても、mml-to-mime は quoted-printable を使うかもしれな い、というようなことです。

しかし本質的には、これら二つは互いに逆関数であるべきです。結果として生成 されるメッセージの内容物が、同一でないにしても等価なままであるような。


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.7 流動テキスト

Emacs MIME ライブラリーは、メッセージをエンコードするとき は use-hard-newlines 変数 (see (emacs)Hard and Soft Newlines section ‘Hard and Soft Newlines’ in Emacs Manual) に従い、メッセージをデコードす るときは Content-Type パラメーターの“format=flowed”を尊重します。

テキストをエンコードするとき、ソフト改行文字で終端されている各行 は、use-hard-newlines に関わらず に fill-flowed-encode-column で決定される桁の後ろで折り畳まれて、 耳を揃えられ (filled され) ます。引用の印 (‘^>* ?’) は尊重されます。 その変数は、流動テキストをサポートしないクライアントにおけるテキストの見 え方を制御し、ディフォルトでは 66文字の後ろで折り畳みます。バッファーに ハード改行文字が無ければ、流動 (flowed) テキストのためのエンコードは行な いません。

バッファーに改行文字があるとき、流動テキストにエンコードすることを有効ま たは無効にするために mml-enable-flowed 変数をカスタマイズできます。

流動 (flowed) テキストをデコードするとき、ソフト改行文字を持つ各行 は fill-flowed-display-column で決定される桁の後ろで折り畳まれて 耳を揃えられ (filled され) ます。ディフォルトでは fill-column の 後ろで折り畳みます。

mm-fill-flowed

非-nil だったら、format=flowed の記事は流動的に表示されます。


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Yasutaka SHINDOH on May 11, 2011 using texi2html 1.82.