新しい MH-E を MH-JP とともに使う

未だに MH-JP 上で MH-E を使って 電子メールを読み書きしている人は少数派なのでしょうが、私は昔からずっとこ れ一本です。

最近の MH-E は、 表示がカラーになって きれいになったり、MIME の添付ファイルの扱いが可能になっていたり、キー 割り当てが再編されて系統的になったり、宛て先入力時に alias の補完が可能 になったり、と以前に比べて使いやすくなっているのですが、日本ではあまり知 られていないようです。

先日最新の MH-E 8.0 がリリースされ、その後さらに MH-E 8.1, MH-E 8.2 もリリースされています。日本でこれを使うためのノウハウを多少公開 してみようと思います。

注意

従来の mh-e の使用法には慣れているものとします。ここでは、その説明は いちいちしません。

私はあまり高度な機能は使っていません。speedbar, PGP, anti-spam software の併用、thread 表示などに関する情報は扱っていませんのであしから ず。

また、Emacs のバージョンは 21.4 及び 22 とします。XEmacs には手を出 していませんので、ここで書いてあることがそのまま当てはまるとは限らないこ とにご注意ください。

さらに、システムの標準の日本語コードは EUC であることを仮定しておきま す。したがって、~/.mh_profile には


File-Coding:	ja_JP.euc
Display-Coding: ja_JP.euc
Process-Coding: ja_JP.euc

のような行があって、表示・ファイル・プロセス間の日 本語が EUC でやりとりされているものとします。

また LANG 環境変数などで日本語 EUC locale が指定されていて、Emacs の 標準文字コードも日本語 EUC になっているものとします。

ベースとなる MH

MH-E 8 がサポートするのは

の3種ですが、このうち nmh と mailutils は日本のメール固有の事情に対応し ていない部分が多く(※2006年5月現在)、日本で使うならオリジナルの MH を 日本語化した MH-JP 以外の選択肢は事実上ないでしょう。これは MIME への対応状況がやや古い、という問題があるのですが、しかたありま せん。nmh には存在する group reply 機能も MH-JP にはないので、どなたか nmh の日本語化をやってくださると嬉しいのですが…。

以下、MH-JP と MH-E 8 はインストール済みとします。Emacs 21 を使って いる場合、~/.emacs(require 'mh-autoloads) と書いておかないと動作しない点に注意しましょう(Emacs 22 では不要)。 Emacs 21 に最初からついている mh-e 5.0.2 の方が間違って起動されたりしない ように気をつけてください。

また、新しい MH-E では変数名に多少の変更が行われているので、これまで ~/.emacs でカスタマイズを行っていた人は 文書 によく目を通しておきましょう。

メールを読む

Summary 表示

文字化け

メールを読むとき、まず、素の状態で困るのが、Summary バッファにおいて 「差出人名」と「表題」が日本語の場合、「=?ISO-2022-JP?B…」といった表示 になっていて全然読めないことでしょう。これは、以前の mh-e では なかったことです。

こうなる理由は、現在の MH-E では、scan 時に独自の format パターンを与えているため、MH-JP の scan の RFC-2047 decode 機能が抑制されてしまっているためです。これを解決する簡単な方法としては、 ~/.emacs


(setq mh-scan-format-file nil
      mh-adaptive-cmd-note-flag nil)

と書き、独自 format を使用しないようにしておくとよ いでしょう。これで文字化けが起きるとしたら、~/.mh_profile での日本語コード指定に誤りがあるか、Emacs の process-coding-system 周り の設定のどこかがおかしいのだと思います。

なお、MH-E の独自 format は、新機能「メール番号の桁数への動的対応」の ために必要とされるもののようなのですが、上記の設定はそれを殺しています。 なので、「桁数固定じゃいやだ!」という人は、mh-scan.elmh-scan-format-nmh をもとにして、MH-JP の hdecode 関数を用いた format file を作り、そのファイル名を mh-scan-format-file に指定するとよいでしょう(未確認)。

色づけがずれる

文字化け以外の問題点として、font lock を利用してカラー表示をしている 場合、差出人名が日本語のメールは、色づけの境界がずれてしまっていることに 気づくと思います(差出人名を修飾するはずの黒色が、一部表題にまではみ出す; ごめんなさい、スクリーンショットは用意してません)。

この問題を完全に解決するのは難しいのですが、部分的な解決については 項を改めて後述します

本文表示

さて、上の設定で Summary バッファでの表示については大体問題はなくなっ たはずで、本文の表示にも大体は不都合はないはずですが、これだけでは、本文 を読むとき、次の条件をみたすメールが文字化けしてしまいます(ヘッダ、本文 ともに)。

これもやはり、従来の mh-e ではなかった現象で、MIME 周りの処理を MH-E が自前で行うようになったことによるとばっちりです。

このようなメールは、最近では受け取ることも少なくなっているので、特に 問題が起きない、という人も多いでしょう。しかし、MIME が普及するよりも前 に受け取ったり、送ったりしたメールが資産として手元にある人にとっては、こ れでは困ります。日本で使うメールソフトとしては、MIME 関連のヘッダが 何もついていないメールを読むときは、JIS コードで記述されているという前提 で動作してくれないとものの役には立たないのです。 (何かのスクリプトで、まとめて MIME-Version ヘッダと Content-Type ヘッダ を付加してしまえばよい、ですって?嫌ですよ、そんなもん)

これを解決するため、私は以下のようなパッチを当て た上で、 ~/.emacs


(defadvice mh-decode-message-body (around autodecode activate)
  "MIME-Version ヘッダなしでも、メール本文を decode させる。"
  (let ((mail-parse-charset 'undecided))
    ad-do-it))

としています(多少汎用性を持たせるため、 'iso-2022-jp を直接指定するのではなく、 'undecided(自動判別)を利用しています)。

なお、文字化けを避ける別解として mh-mhl-format-filet または mhl 用の適切な format file を指定する、という手も あるのですが、これだと添付ファイルを「ボタン」化して扱える、という MH-E の新機能(※ 注)の恩恵が受けられない、というデメリットがあります。もち ろん、「添付ファイルなんかどうでもいい」という人はその方法でも構いません。 これだと、「ヘッダの表示される順番を format file で指定できる」というメ リットもありますしね!(mhl を使わなければ、ヘッダの順番は元のメールのま まソートされない)

※ ただし、Emacs 21.4 の rfc2231.el には不備があって、添 付ファイル名が日本語になってると正しく扱われません。ご注意。Emacs 22 で はこの問題は修正されています。

[2007, 8/5]さらに、PGP 署名されたメッセー ジ(multipart/signed ではなく、署名されたメッセージ全体が text/plain になっ てるタイプ)を受け取った場合も、日本語部分が decode されず読めない、とい う問題が起こることもわかりました。

これを回避するには、次のようにしてください。


(setq mm-uu-text-plain-type '("text/plain" (charset . undecided)))

なお、これは、本来は上記のような ad hoc な対処ではなく、 mm-uu-pgp-signed-extract-1 に decode 処理を入れるのが筋なの でしょう。mm-uu-pgp-encrypted-extract-1 みたいに(つまり、 gnus で日本語メールを読むときも、PGP 署名された文書では、MH-E と同様日本 語が decodeされない?)。

もっとも、mm-uu-pgp-encrypted-extract-1


(setq charset (mail-fetch-field "charset")))

なんて処理が入っていて、正しく動作するのかどうかは 極めて怪しいですが(「charset」なんて field あるんかいな)。PGP は積極的 には全然使ってないので、その辺の詳しいことはよくわかりません。

※ この他に、日本語部分が Unicode で書かれたメールが Base 64 encoding されて届いたりすると、Emacs 21 上ではやはり文字化けを起こして読めないの ですが、これは lv などの Unicode pager をインストールした上で、コマンド ラインから show -moreproc lv のようにして読んでください (Emacs 22 なら、このようなメールでも問題なく読めます。Emacs 21 上でも、 Mule-UCS を入れたりすれば読めるのかもしれませんが、未確認です)。

メールを書く

さて、ここまでで「受け取ったメールの表示」についての問題はおおよそ解 決できます。しかし、これだけではまだ、「自分が書いて、出すメール」に重大 な問題が残っています。

文字化け対策

上述のように、新しい MH-E では MIME 処理を自前で行うようになっている のですが、その副作用で、日本語でメールを書いて出すと JIS コードではなく EUC コードにされた上、Base 64 符号化がなされて送信されるようになってしま います(※ Emacs 21 での話。Emacs 22 ではそんな問題はなく、普通に JIS コー ドで MIME 化されて送信されるようです)。規格上誤りとは言えないでしょうが、 ちょっと避けたい形式です(※MH-JP の文書に従って、 送信メールが自動的に全部 MIME 形式になるような設定をしていると、ちょっ と動作が違うかもしれません)。それに、これでは +outbox に Fcc しているとき、差出人名や表題を日本語で書いていると Summary バッファ で文字化けします(自分に Cc: しているような場合も同様)。

これを解決するには、~/.emacs


(setq mm-coding-system-priorities
  '(iso-2022-jp iso-2022-jp-2 japanese-shift-jis utf-8))

のように書いておけばよいようです(参考: http://www.m17n.org/mlarchive/mule-ja/200209/msg00007.html)。こうす ると、日本語で書いたメールは原則としてすべて JIS コードで MIME 化されて 送られます。

なお、私は個人的に MIME というものが嫌いなので、添付ファイルを送る必 要がある場合を除き(つまり、本文が全文単なる平文で済む場合)、送信メール が MIME 形式にならないようにしています。現行の MH-E をそのように振る舞わ せるのには少々苦労しましたが、


(defadvice mh-ascii-buffer-p (around disguise-all-ascii activate)
  "mh-ascii-buffer-p を無効化する。"
  (setq ad-return-value (or (eq mail-send-nonascii t) ad-do-it)))
(setq mail-send-nonascii t)

(add-hook 'mh-compose-letter-function
	  (lambda (to subject cc)
	    (set-buffer-file-coding-system default-sendmail-coding-system)))

とすることによって、一応狙いどおりのことはできてい ます(これまた、多少汎用性を持たせるため、'iso-2022-jpを直 接指定するのではなく default-sendmail-coding-system を利用し ています)(※ これは、「自分が送る日本語メールはちゃんと全部 MIME 形式 にしたい」という人はやってはいけない設定です。くれぐれ もご注意ください)。

Emacs 22 の更なる問題 [2007, 10/26]

Emacs 22 で使う場合、これまでに問題が2つ見つかっています。

ひとつは、上記でも何度か使っていた default-sendmail-coding-system正しい値に設定されなくなっ たこと。これは、emacs 起動時に呼ばれる関数 set-locale-environment


          ;; Fixme: perhaps prefer-coding-system should set this too.
          ;; But it's not the time to do such a fundamental change.
          (setq default-sendmail-coding-system coding-system)

という処理が追加されたために、 default-sendmail-coding-system が上書きされるようになって しまったからです。が、以下のような事情を考えると、この処置は疑問です。

  1. locale というのは、そのマシン・OS でローカルに使われる言語 環境・文字コードを指定するもの
  2. 一方、電子メールに代表される、第三者とオープンにやりとりする文書で 使う文字コードは、OS の違いを超えて共通のものを使う取り決 めがなされている
  3. だからこそ、default-sendmail-coding-system の値は、 locale 処理とは無関係に set-language-environment によっ て設定されていた

emacs の起動時の処理順を、set-locale-environmentset-language-environment の順になるように修正すればいいんで しょうかねえ(それとも、こういった考え方はすでに時代遅れで、「locale な んてものは utf 中心指向に移行するべき。EUC, ISO-2022-JP, SJIS を複雑に使 い分ける時代は終わった」と考えるべきなんでしょうか。私 unicode ってキラ イなんですけど…)。

ですので、~/.emacs 内で独自に set-language-environment を実行していた人は、 default-sendmail-coding-system が再度上書きされ、この問題は発 生していなかったはずです。そうでない人は、とりあえず、日本国内で使う限り は、~/.emacs


;; for emacs 22
(if (>= emacs-major-version 22)
    (setq default-sendmail-coding-system 'iso-2022-jp))

とでも書いておけばよいでしょう。なお、この設定は、 上に例として挙げた色々な設定よりも必ずに置かなければ いけません。また、同じ問題は MH-E だけでなく、emacs 標準の電子メール送信 機能を使う場合も起きるはずですが、それも上のようにすることで解消します。

もうひとつの問題ですが、emacs 22 では、「ヘッダが MIME 符号化されたメー ルに対して返信を書く」とき、 送信時に2重に MIME 符号化されてしまい、結果受け取った相手がまともに読め ない、という問題が発生するようになりました。これを解消するには、更に


;; for emacs 22
(setq rfc2047-encode-encoded-words nil)

という設定を追加する必要があります。こちらは、 ~/.emacs 内なら置く位置はどこでもよいです。

段落処理

メールを書いているときの推敲中、段落移動や、段落の整形処理がうまく働か ないことがあります。具体的には、1段落だけ整形するつもり で M-q と打ったのに、次の段落までまとめて1段落と見なされて整 形処理に巻き込まれる、というような現象が発生したりします。これは、メール を書くモードでの標準の「段落認識設定」が日本語文章向けにチューンされてい ないからです。

以下のような処理を ~/.emacs に追加するとよいでしょう。


(add-hook 'mh-letter-mode-hook
	  (lambda ()
	    ;; 空白から始まる行も段落の始めにする。欧米人はそうはしない
	    ;; のかもしれないけど、日本じゃこうなってないと困るよ…。
	    (paragraph-indent-minor-mode)
	    (setq paragraph-start (concat " .\\|" paragraph-start))))

本当は、current-language-environment をチェックして、日本 語環境の時だけ上記処理を実行する…というように丁寧に書く必要があるんでしょ うけど、そこまでは踏み込まないでおきます。

なお、emacs 21 だと paragraph-indent-minor-modeほ とんど意図された動作をせず、使い物にならないシロモノなので、さらに 以下のような処理も追加しておきましょう(これは、emacs 22 では不要です)。


(add-hook 'paragraph-indent-text-mode-hook
	  (lambda ()
	    (set (make-local-variable 'paragraph-separate)
		 (default-value 'paragraph-separate))
	    (set (make-local-variable 'indent-line-function)
		 (default-value 'indent-line-function))))

※ なお、上述の「日本語文書に対する段落認識処理」の 問題は、MH-E とは無関係に、text mode 系統の major mode 全般に見られるよ うになっています(emacs 20 頃から。確か、mule 2 の頃はこんなではなかった はず…)。ですので、少なくとも純正 text mode に対しては、次のような行を 追加しておくことをお勧めします(これは、emacs 22 でもそうでなくても)。


(add-hook 'text-mode-hook (lambda ()
	(if (eq major-mode 'text-mode)
	    (paragraph-indent-minor-mode))))

また、段落開始を表す字下げを全角空白で行うタイプの人は、上記 mh-letter-mode-hook への hook を参考にして、 paragraph-start に全角空白を追加する処理を hook に加えるとよ いでしょう。

純正 text mode 以外でも、必要に応じて paragraph-indent-minor-mode を呼び出す hook を追加するとよい と思います。

その他

バグ修正

[2012, 1/31] 以下のパッチは、emacs 23.4 付属の MH-E にもそのまま当たるようです。

MH-E 8.2 に見つけたいくつかのバグに対するパッチを置いておきます。 本家にパッチを提 出するには sourceforge のアカウントを取らねばならないらしいので、こ こにひっそりと置いておくだけにします―――と思ったら、いつの間にかアカウ ント不要になったのかな?まだ確かめていません。

------>mh-e-8.2-patch.gz [2009, 6/15]

バグとパッチの内容を説明しておきます。

  1. mh-acros.el に対するパッチは単なる typo の修正ですが、 そもそもこの行の内容は describe-function のとき一番上 に表示されるので、取っぱらってしまった方がいいような気もします。
  2. forw コマンドに対する -mime オプションは MH 6.8.4 に対しても存在するはずですので、mh-comp.el でベー ス MH によらず mh-compose-forward-as-mime-flag を見るよ うにしました。
  3. mh-e.el は一部アクセントつきアルファベット母音を UTF で記述していますが、これが正しく解釈されない(日本語 EUC locale で はもちろん、C locale であっても)ので、Local Variables に coding 指定を明示しました。
  4. Summary バッファ中最後のメールを SPC で読んでいって、最 後まで到達して「End of message (Type SPC to read next(previous) undeleted message)」と表示された時点で、DEL で逆スクロー ルしたとします。ここで再度 SPC を叩いたときは再スクロー ルして欲しいのですが、そうはならずに next(previous) undeleted message を表示しようとしてしまうので、mh-folder.el で この愚直な動作を修正しました。
  5. search-pattern バッファでは C-c C-f C-t などのキーバイン ドが使えるはずなのですが、mh-letter.el をロードするまで はこれらが使えなかったバグを修正しました。
  6. search-pattern バッファで C-c C-f C-b などで Bcc: ヘッダ を指定すると read only エラーが出るのですが、ここで Bcc: ヘッダを必 要とすることはないはずなので、mh-search.el でそのキーバ インドを削除しました([2007, 6/20] うーんそうか、でも draft フォルダー に残る書きかけのメールでは Bcc: ヘッダが残っていることもありうるか。 でも、書きかけのメールがそんなに検索を必要とするほどたくさん残ってる、 という事態は想定する必要はないかな?)。
  7. これは MH-E 8.1 で修正されました。→MH 従来の MIME 化手法を使っ てメールを書く設定にしているとき (mh-compose-insertion を 'mh にする)、返信や転送など を行ったときの annotate が失われてしまうことがあります(例えば、書 いたメールの最後の数行にたまたま Local Variables パートが含まれて いて major mode が指定されている場合。また、emacs 21 では ~/.mh_profile で draft folder 名に「drafts」を指定し ていた場合も含む)。これは major mode が(不必要に)更新されてしま うのが原因なので、mh-mime.el を修正。
  8. F v で他のフォルダに移るとき、document には
    it will show all the messages in the buffer as long there are fewer than `mh-large-folder' messages. If there are more, then you are prompted for a range of messages to scan.
    と書いてあるのですが、環境によっては後半の動作をせず、たくさんのメー ルが入っているフォルダに移るときも全メッセージを scan してしまうことがありました(もちろん、prefix argument をつければ range を訊いてこさせることは可能でしたが)。これは、 mh-seq.el の正規表現の不備が原因だったので、修正しま した。
  9. 本文を読むとき、In-Reply-To ヘッダを表示させる設定にしていても、大 文字小文字が合わないと正しく着色されなかった問題を mh-show.el で修正しました。ついでに、 という2点も修正してあります。
  10. Byte compiler の warning を避けるためだけの defvar が 何ヶ所かありますが、それら(の一部)に eval-when-compile を追加。 The MH-E Developers Guide には「eval-when-compile でくるむな」と書いてあるのですが、 そこで 引用されてるメッセージって、少なくとも Emacs 21 では正しくなく て、私が追加した eval-when-compile がないと、 describe-variable したときの「このファイルで定義され てるよ!」のハイパーリンクが誤って当該 MH-E elisp file を指してし まうようになります。
  11. ツールバー上の、alias 未登録な相手を新たに登録するボタンが機能して いなかったのを修正。ただ、このせいで、フォルダを開いたときは常に mh-alias.el がロードされるようになってしまいました。
  12. メニューとツールバーについて、いくつかの項目について、フォルダモー ドでカーソルがメッセージ行の上にない場合は無効化されるようにしまし た。※ そういう場合も、prefix argument を付ければ range が指定でき るので、一律無効化するのは適切ではないかもしれません。
  13. Auto fill を自動では on にせず、状況に応じて後から手で on にするか どうかを選択する主義の人のため、letter mode で normal-auto-fill-function を設定しておきました。
  14. [2009, 2/1]「どうも送信時、 C-u を付けて C-c C-c とすると Message-ID が 付かないな…?」と思っていたらバグだったので、修正しました。
  15. これはバグとは言い切れませんが、上の方でも解説した通り、MIME 形式で はない日本語メールを読むときに、文字化けしてしまうのを解消する変更 を入れてあります。(その結果、RFC に厳密には沿わなくなったモノを処 理することになっているはずなので、ちょっとインチキな修正ではありま す。が、おそらくそこら辺の処理には干渉しないはずなので、読むだけな らたぶんこれでも大丈夫)

    mh-mime.el では、 mh-decode-message-header した後で mh-show-addr している部分があるなあ…。これだと、MIME decode の結果、quote・escape さ れていた特殊文字が生で出てきているかもしれないので、アドレス解析が正しく 行く保証がないので、厳密にはバグじゃないだろうか。

  16. その他明白な typo 修正。

※ 上で修正したバグ以外に、日本語 Subject を持つメー ルに対し、フォルダモードで / s は大抵効かない、という不具合が あります。MH-JP の pick コマンドは、引数に RFC 2047 decode の文字列を与えなければいけないことが原因ですが、この問題には 対処していません。

あと、ついでに、MH-E 8.2 マニュアル用 のパッチも置いておきます。

色づけ再び

上で書いた通り、font-lock を利用している場合、 差出人名が日本語で書いてある メールは、Summary バッファでは色づけの境界位置がおかしくなるという問 題があります。これは、

ということから発生しています。

上の問題を、正規表現を工夫するだけで解決することは私には無理だったの で、とりあえず以下のような強引な手段によって mh-scan-subject-regexp を使わないようにして色づけをさせていま す。


(eval-after-load "mh-folder"
 '(defun mh-folder-font-lock-subject (limit)
    "Return MH-E scan subject strings to font-lock between point and LIMIT."
    (when (save-excursion
	     (or (bolp) (forward-line 1))
	     (move-to-column (+ mh-cmd-note mh-scan-field-subject-start-offset))
	     (if (< (point) limit)
		 (looking-at
		  "\\(\\(?:[Rr][Ee]\\(\\[[0-9]+\\]\\)?:\\s-*\\)*\\)\\([^<\n]*\\)")))
      (goto-char (match-end 0))
      (if (< (match-beginning 1) (match-end 1))
	   (set-match-data (list (match-beginning 1) (match-end 3)
				 (match-beginning 1) (match-end 3) nil nil))
	 (set-match-data (list (match-beginning 3) (match-end 3)
			       nil nil (match-beginning 3) (match-end 3))))
      t)))

が、これで問題が解決したわけではありません。正規表現が hard code され ていることにはまだ目をつぶるとしても、

という大きな問題が残っていて、猛烈にヘボヘボです。 この2つは色づけとは無関係な問題であり、font-lock を利用しているかどうか にかかわらず発生します。

また、類似の問題として、

というものもあります。

これらの問題を解決するのは、私にはちょっと無理そうなので、どなたかぜ ひ頑張ってください。どうぞよろしく(他力本願)。


コンピュータ関連のページ目次へ
トップページへ
井汲 景太 <ikumi@ikumi.que.jp.NOSPAM.>(迷惑メールお断り)
最終更新日: 2012年2月1日