w3m の mailto: と Gnus の連携

よく考えりゃ firefox との連携 (http://d.hatena.ne.jp/emacsjjj/20050621/p1) よりもこっちのほうが使用頻度からして重要だった。

以前から w3m でも mailto: 上で RET すると Gnus に跳ぶようにはしていたのだが、Cc や Subject の対応はサボっていたのでこの機会にやることにする。


w3m では MozEx の代わりに Local CGI の仕組を使う。前回と同様の構成だとこの CGI 側で url のパーズやデコードをやる必要があるのだが、今後の自由度も考慮して url 解析は elisp で一本化することにした。つまり

firefox → MozEx(url 解析) → emacsclient → Emacs → Gnus
                                  ↑
w3m → Local CGI(url 解析) →→→→

こんなんだったのを

firefox → MozEx → emacsclient → Emacs(url 解析) → Gnus
                        ↑
w3m → Local CGI →→→→
                        ↑
client-X →→→→→→→→

こうしておこうと。これなら将来 client-X が増えたとしてもそちらは何も考えずに mailto: の url を生で渡してやればいいのでなにかと楽だろう。


という訳で

Local CGI の設置

以下のようなスクリプトを ~/.w3m/cgi-bin/mailto.cgi として置いてやる。

#!/bin/sh
url=${QUERY_STRING#mailto:}
/path/to/emacseval "(compose-mail-mozex \"$url\")"
echo "w3m-control: BACK"

compose-mail-mozex に url 解析分を追加

(defun compose-mail-mozex (url)
  (unless (fboundp 'w3m-url-decode-string) (require 'w3m))
  (let (to subject other)
    (while (string-match "[ \t]+" url)
      (setq url (replace-match "" nil nil url)))
    (when (string-match "\\`mailto:\\(.*\\)" url)
      (setq url (match-string 1 url)))
    (while (string-match "&" url)
      (setq url (replace-match "&" nil nil url)))
    (when (string-match "\\`\\([^?]+\\)\\(.*\\)" url)
      (setq to (match-string 1 url))
      (setq url (match-string 2 url))
      (setq to (w3m-url-decode-string to)))
    (while (string-match "\\`[?&]\\([^=]+\\)=\\([^&]*\\)\\(.*\\)" url)
      (let ((hname (match-string 1 url))
	    (hvalue (match-string 2 url)))
	(setq url (match-string 3 url))
	(setq hname (w3m-url-decode-string hname))
	(setq hvalue (w3m-url-decode-string hvalue))
	(while (string-match "[ \t\n]+" hname)
	  (setq hname (replace-match "" nil nil hname)))
	(when (string-match "[ \t\n]+\\'" hvalue)
	  (setq hvalue (replace-match "" nil nil hvalue)))
	(cond
	 ((string-match "\\`to\\'" hname)
	  (if to
	      (setq to (concat to ", " hvalue))
	    (setq to hvalue)))
	 ((string-match "\\`subject\\'" hname)
 	  (setq subject hvalue))
	 (t
	  (setq other (cons (cons (capitalize hname) hvalue) other))))))
    (compose-mail to subject other)))

MozEx の設定変更

こちらは url を生で渡してやるように変更する。

/path/to/emacseval (compose-mail-mozex "%r")


こんなかんじで。url 解析部分は Mew から拝借。相変わらず BODY の処理をサボっているのだが、まぁそれはそのうち…。


動作確認用アンカー
↑が

To: to@exsample.com
Cc: cc1@exsample.com, cc2@exsample.com
Bcc: bcc@exsample.com
X-Test: mailto test
Subject: サブジェクト

本文

こんなかんじになれば正常。おめでとう。