Mhフォーマットは、慣れてしまえば簡単であるが、ちょっと触りづらい。 Mhは、そのほとんどの出力の方法が、フォーマット・ファイルにより制御される。 あまりにも、カスタマイズ可能なように 書かれていることと、その制御コマンドのややこしさに圧倒され、 なかなか取りつきにくいものになってしまっている。
さらに詳しく説明した本が……ないんです(苦笑)。
一番詳しくかいてあるのが、「UNIX Magazine 1990.9」です。
ここには、mh-format の関数一覧がついているので、まずこれを
読んでください。(ちょっとウソも書いてあるけど)
## 1992年3月時点。まぁ今(1995年5月)でも、あまりいい本はないですが。
## ちなみに mh-6.8 から mh-format のオンラインマニュアルがついた。
## 兎に角、man mh-format してみれば、どーにかなるかと:-)
ここでは、簡単そうなファイルの実例と、私の設定ファイルの内容 を紹介しておく。
/usr/local/lib/mh/scan.timely は、
となっている。これをコマンドラインから用いるのには、
% scan +メールフォルダー名 -form scan.timely
で使用できる。この「scan.timely」フォーマットファイルを使用
すると、
のように、メッセージ番号、時刻、差出人、Subject、内容の一部
が 表示される。
このscan.timelyでは、条件判別で表示を変えるようになっている。
:> %4(msg)%<(cur)+%| %>%<{replied}-%|%<{encrypted}E%| %>%>\
まず、「%4(msg)」で、メッセージ番号(戻り値:整数)を4桁で
表示している。
次に、「%<(cur)+%| %>」とは、
ってことで、そのメールにカーソルがあれば「+」を表示し、
なければ1文字空白を表示する、ということである。
(カーソルの位置は、.mh_sequence ファイルを参照する)
「%<{replied}-%|%<{encrypted}E%| %>%>」 も同様に、ヘッダに「replied」がついていれば、「-」を 表示し、ない場合、さらに「encrypted」であれば、「E」 を表示し、どちらもなければ1文字空白を表示するという ものである。
「\」は行の連続を意味している。
さあここから、「第1の条件設定」である。
そのメールの date の値により、いろいろ判別しているのである。
:> %(void(rclock{date}))\
「(rclock{date})」は、{date}で、ヘッダから date の内容を
取りだし、組み込み関数 rclock で 「現時間との差」を求め、
その値を、num レジスタに void 関数でセットしている。
# (void ...)としないと、画面に表示されてしまう。
あとは、この numレジスタの値との比較を行なっている。
:> %<(gt 15768000)%03(month{date})%02(year{date})%|\
if その値が、15768000 より大きければ、日を3文字、年を2文字 で表示する。(分だから、半年か?)
:> %<(gt 604800)%02(mday{date})%03(month{date})%|\
else if 604800 (1週間)より大きければ…、
:> %<(gt 86400) %(day{date}) %|\
else if 86400 (1日)より大きければ…、
:> %02(hour{date}):%02(min{date})%>%>%>\
else 時を2文字+「:」+分を2文字 表示。
endif endif endif
:> %<{date} %|*%>\
ヘッダに date フィールドがあったら、1文字空白、
なければ、「*」を表示。
これで、「時刻の条件表示」は終了。
次に、「差出人の条件表示」である。
:> %<(mymbox{from})To:%14(friendly{to})%|%17(friendly{from})%> \
(mymbox)は、from行をみて、自分が出したメールかどうかを判別する
関数である。つまり、この書き方は、
「mymbox(from)が真なら、To:%14(friendly{to}) を、
偽であれば、%17(friendly{from})を実行する」
ってわけである。
(friendly)は、そのアドレスを、読みやすいカタチに変換する関数である。
自分が出したものであれば、「To:」+14文字でヘッダのtoフィールドを、
でなければ、17文字でヘッダのfromフィールドを表示するのである。
:> %{subject}%<{body}<<%{body}%>
あとは、%{subject} で、ヘッダの subject フィールドが表示され、 {body} がある、つまり中身があれば、「<<」のあとに表示する、って 訳である。ここで偉いのは、その文字列が長くとも、scan コマンドが 勝手に切ってくれるのである。
以上が scan.timely の説明である。
--
/* はやし☆はるひさ (hayashi@kuic.kyoto-u.ac.jp) 京大・分子・中西研 */
多少改定 10May1995 by はやし はるひさ
## ちなみに上記の関数の説明は、mh-6.7.2 レベルでの話で、
## mh-6.8 では多少変更されている。
基本的にはほとんど一緒ですが、
mh-6.7.x
mh-6.8.x
最初から説明します
:> %4(msg)%<(cur)+%| %>%<{replied}-%?{encrypted}E%| %>\
:> %(void(rclock{date}))\
:> %<(gt 15768000)%03(month{date})%(void(year{date}))%02(modulo 100)\
まずここね。
mh-6.7 までのように甘くなく:-)、%02(year{date}) と数値(year関数はinteger)を
文字列的直接操作が出来なくなったので、一旦 void で num レジスタに退避させ、
次の modulo 関数で、100 で割った余り(つまり西暦の下2桁)を str レジスタに
放り込み、%02 で出力している。
## 扱いが厳しくなったのね:-)
:> %?(gt 604800)%02(mday{date})%03(month{date})\
:> %?(gt 86400) %(day{date}) %|\
:> %02(hour{date}):%02(min{date})%>\
このあたりは、%? (=elsif) が使えるようになったから。
:> %<{date} %|*%>\
:> %<(mymbox{from})%<{to}To:%14(friendly{to})%>%>%<(zero)%17(friendly{from})%> \
ここは若干丁寧に判別を増やしたのと、 mymbox{} が そのアドレスが user のものであれば 1、なければ 0 を num レジスタに返すので、「zero」(num レジスタが 0 であれば真)を 用いて判別しているんですね。
:> %{subject}%<{body}<<%{body}%>
あとは同じ:-)
次に、私の inc.form、scan.form ファイルを紹介する。
scan.timely をいじっただけなので、ほとんど同じである。
inc.form と scan.form は、それぞれ inc, scan コマンドを用
いるときの為に、私が.mh_profile で設定した format ファイル
である。(別に同じファイルでも良いのだが。)
私の場合、inc したときには、差出人によって少し表示を変更し、
また scan したときには、Mailing List からのメールについて
は、そのメール番号を表示するように設定している。
(これは、実は書いた当時(1月頃)の話です。現在は slocal を
はっているので、inc する必要が全くなくなってしまったの(^^))
## ちなみに「1月」って…………、1992年1月です(遠い彼方を見つめる…^^;;)
1.inc.form
:> %4(msg)%<(cur)+%| %>%<{replied}-%|%<{encrypted}E%| %>%>\
:> %(void(rclock{date}))\
:> %<(gt 15768000)%03(month{date})%02(year{date})%|\
:> %<(gt 604800)%02(mday{date})%03(month{date})%|\
:> %<(gt 86400) %(day{date}) %|\
:> %02(hour{date}):%02(min{date})%>%>%>\
:> %<{date} %|*%>\
ここは全く同じである。
:> %(void{Reply-To})\
:> %<(match 98game)[98] %|\
:> %<(match hayashi)(^^;)%|\
:> %>%> \
これは差出人によって、メッセージ番号、時刻のあとに、 ちょっとした表示がつくように、判別している。
本来なら、from フィールドを参照すればよいのであるが、 ML(メーリングリスト)などからのメールでは、その from が、ML名でなく、そのメールをMLに投稿した人 になっている場合が多い。
# このへんは、どのフィールドを参照するべきか、自分で考えるように。
私の場合、
:> %(void{Reply-To})\
で、Reply-To フィールドを str レジスタにセットし、
:> %<(match 98game)[98] %|\
:> %<(match hayashi)(^^;)%|\
その Reply-To 文字列の中に、「98game」という文字列があれば (match コマンドによる)「[98] 」と表示し、それ以外のメールで 自分が出したメールであれば、「(^^;;)」を表示する。
:> %>%> \
^^^^^ 更にそれ以外のメールでは、5文字分の空白を表示している。
気をつけなければならないのは、その後にある、1文字分の 空白である。
:> %>%> \
これにより、1文字分の空白が表示される。
:> %<(mymbox{from})=>%15(friendly{to})%|%17(friendly{from})%> \
:> %{subject}%<{body}<<%{body}%>
あとここも、ほとんどかわらない。
自分からのメールの場合、「To:」でなく、「=>」にしているだけである。
この format ファイルを用いると、
1 Thu (^^;) => hayashi test< < This is test mail, sorry!! 2 12:48 [98] => 98game@ariel10 Souieba....< < そういえば、今度発売の 3+ 14:29 [98] Nyan-chan Re: Souieba....< < おひさしぶりです、 4 15:39 p-honda@axis.uec. Re: How are you ?< < 土曜日はどうしまてな具合になる。
## 前回にも書いたように、mh-6.8.X では 数値の文字列操作に対して
## 厳しくなったので、「%02(year{date})」は通りません。
## 「%(void(year{date}))%02(modulo 100)」でないと駄目です。
## また勿論、mh-6.8.X では %? (=elsif) が使えますので、
## もう少し綺麗:-)に書けるはずです。
2. scan.form
これも大筋で変化はない。 ただ、頭の部分がちょっと違うだけである。
:> %4(msg)\
:> %<{X-Ml-Count} %4(compval{X-Ml-Count})%>\
まず4文字分で、メッセージ番号を表示している。
次にヘッダに{X-Ml-Count}というフィールドがあれば、その値を compval 関数で、取りだしてnumレジスタにセットしている。 このとき、「入れ子」になっていないので、4文字で表示される。
私の入っているMLからのメールには、「X-Ml-Count」という フィールドがあり、ここにトータルのメール番号が書かれている。 このフィールドを読み込み、表示することで、メールが整理される。
:> %(lit)\
lit 関数は、その arg を str にセットする関数であるが、 ここでは、str のクリアに用いている。(あまり意味はないが。)
あとは、inc.form と同じ。
:> %<(cur)+%| %>%<{replied}-%|%<{encrypted}E%| %>%>\
:> %(void(rclock{date}))\
:> %<(gt 15768000)%03(month{date})%02(year{date})%|\
:> %<(gt 604800)%02(mday{date})%03(month{date})%|\
:> %<(gt 86400) %(day{date}) %|\
:> %02(hour{date}):%02(min{date})%>%>%>\
:> %<{date} %|*%>\
:> %(void{Reply-To})\
:> %<(match 98game)[98] %|\
:> %<(match hayashi)(^^;)%|\
:> %>%> \
:> %<(mymbox{from})=>%15(friendly{to})%|%17(friendly{from})%> \
:> %{subject}%<{body}<<%{body}%>
んでこれを使うと、
% scan +98game -form scan.form 1 101 Mon =>98game@ariel10. Re: about PM<<はやしです。In message 2 102 Thu Pon-Ponko Honda Re: about PM<<ども、ぽ です。In messa 3 103 12:48 =>98game@ariel10. Souieba....<<そういえば、今度発売のあ 4+ 104 14:29 Nyan-chan Re: Souieba....<<おひさしぶりです、どてな具合になる。
# さぁ次回からは、このいい加減な好評連載も、山場(私が一番書きたい)の 「slocalをはろう!」に突入します。
slocalとは、届いたメールを、ヘッダの部分のキーワードに対応して、 自動的にメールフォルダーに分類して放り込んでくれる、というMhの 便利なツールなんです。(誰が使うんだ?>自分) (いつポスト出来ることやら………)
--
/* はやし☆はるひさ (hayashi@kuic.kyoto-u.ac.jp) 京大・分子・中西研 */
多少改定 10May1995 by はやし はるひさ
ってことで:-)、mh-6.8.X-jp2x では、mime-encode/decode に対応しています。
mh-6.8-JP-README.2 の「[3.6.2] mh-format による方法」を参照して下さい。
つまり:-)、mh-format の関数に、
argument return hencode expr string 日本語文字列を RFC-1342 形式に変換 hdecode expr string RFC-1342 形式を 日本語文字列に変換という2つの文字列操作関数が拡張されているのです。
## 『RFCー1342形式』については、RFC-1342を読んで下さい:-p
## つまりは、「=?ISO-2022-JP?…………=?=」な文字列のことです。
## ちなみに:-)、この文字列を見て「MIMEメール」とか言う人も居るようですが、
## これは飽く迄、MIME ヘッダでの encode/decode 規格ですので。
## 本来の「MIME」とは、Multipurpose Internet Mail Extensions ですので。
これを scan/inc/repl 等 format 中の RFC-1342形式文字列が出てくるところ、 例えば 「%17(friendly{from})」を「%17(hdecode(friendly{from}))」とか、 噛ませてやるだけで OK です。
## hdecode() を使用したこの format ファイルを使用することで
## decode されて表示されているのですから、勿論元のメールファイル自体は
## なんら変更されていません。
あ、そうそう、この mh-6.8.x-jp2x での hencode/hdecode 関数拡張は、 MH config 時の option MIME とは無関係ですので。
jp2x パッチを当てると、これらの関数が使えるようになります。 ここいらは、そのサイトでの Mh の configuration に依存しますが。
参考) mh-6.8 の日本語化の歴史(笑)。
知らぬ間(笑)に、日本各地の anonymous-ftp に、 mh-6.8.3-jp2c.tar.gz と、オリジナルとパッチを1つにまとめた のが置かれている:-)
## mh-6.8 -> mh-6.8.? のどこかの version Up で、
## 本当に些細な変更のために、jp-patch が通らないので、
## 誰かが一つにまとめて下さったのでしょう。