MHonArc の日本語化 [ISO-2022-JP 編]

必要に応じて [序論] なぜ化けるのか? もご参照下さい。
手っ取り早く結論を知りたいという方は まとめ をごらんください。

1. まずは ISO-2022-JP を使うことの宣言

次のリソースにより、生成される HTML ファイルの文字コードを ISO-2022-JP に設定します。
<CHARSETCONVERTERS>
iso-2022-jp; iso_2022_jp::str2html; iso2022jp.pl
</CHARSETCONVERTERS>
これは「charset が iso-2022-jp のメイルに対しては、iso2022jp.pl というファイル (MHonArc のアーカイヴに含まれています) の iso_2022_jp::str2html という関数を使って変換する」という意味になります。

2. 本文の日本語を通す

実は MHonArc でメール本文の日本語を通すためには、特になにもする必要がありません。 mhtxtplain.pl を見ると分かるように、すでに日本語化がされているのです。 しかし、実際にやってみるといくつかのメールが化けることがあります。 これは主に、

  1. MIME message でない (Mime-Version: header が無い)
  2. MIME message だが charset が指定されていない (つまり Content-Type: が ``text/plain; charset=iso-2022-jp'' ではなく ``text/plain'' などになっている)
  3. charset=iso-2022-jp と宣言しておきながら本文が Shift-JIS だったり、Shift-JIS を base64 で encode している
ことが原因です。 1. と 2. は共に charset が指定されていないため charset=us-ascii として扱われてしまいます。 (RFC 2045, 5.2. Content-Type Defaults 等を参照)。

後者はともかく、前者が化けるのはちょっと悲しいので、どうにかしましょう。 そのためには、MHonArc のリソースを、

<DEFCHARSET>
iso-2022-jp
</DEFCHARSET>
のようにします。
注意!
v2.6.0 から指定方法が変更になっています。 v2.6.0 より前の MHonArc を使っていた人は rcfile の設定を直すのを忘れないようにしましょう。
この設定によって、charset の default を iso-2022-jp にすることができます。 ただし、この方法は charset が無い message を全て iso-2022-jp として扱ってしまうので、Content-Type: の正しくない (= 本文が iso-2022-jp なのに Content-Type: に ``charset=iso-2022-jp'' が無い) message まできちんと読めてしまうのが欠点です。

なお、3. については化けるのが「正しい」と思われますので、ここでは考慮しません。

3. Header の日本語を通す

3.1 Subject: の日本語を通す

まず MIME encode された Subject: を decode するために、

<DECODEHEADS>
というリソースを設定します。

また、直接 iso-2022-jp を含んだ Subject: を認めるかどうかは議論の余地があるところでしょうが、 これを処理しておかないと他のところにも影響してしまう (tag がきちんと閉じられなかったりする) ことがあるので、次のようにして、 MIME encode されていない日本語サブジェクトのフィルターを指定しておいた方が良いでしょう。

<CHARSETCONVERTERS>
plain; iso_2022_jp::str2html; iso2022jp.pl
</CHARSETCONVERTERS>

3.2 From: の日本語を通す

MHonArc では、From: が MIME encode されていても、decode され た文字列に @ 等が含まれていると、正しく変換されないことがあります。

もう少し詳しく説明すると、mhutil.pl の field_add_links (という関数) のなかの正規表現

([\!\%\w\.\-+=/]+@[\w\.\-]+)
にマッチするような場合に、正しく変換されません (なお \w は英数字と `_' にマッチします)。 例えば、「垣野内」さんの場合、
^[ $ B 3 @ L n F b ^[ ( B
となり、B 3 @ L n F b の部分がこの正規表現にマッチしてしまい、 E-mail address とみなされてしまうために、
^[$<A HREF="mailto:B3@LnFb">B3@3</A>@ ...
のような謎のタグが生成されることになります。

これに問題を廻避するには、

<NOMAILTO>
として、mailto: タグを生成しないようにすると良いでしょう。 これにより、From: の部分はそのまま表示されるようになります (もちろん、根本的に対処するにはソースに手を入れるしかありません)。

なお「From: の日本語を通す」と書いていますが、

To:, From:, Cc:, Sender:, Reply-To:, Resent-To:, Resent-Cc:
などについて、同様の問題があります。

4. 日本語の clipping を正しく行う

<MsgPgBegin> リソースなどで

<TITLE>$SUBJECTNA:72$</TITLE>
のように clipping (上の場合、`:72' は 72 文字で clipping せよ、の意) を指定すると正しく clipping できない場合があります。
これを正しく処理するには、
<TEXTCLIPFUNC>
iso_2022_jp::clip; iso2022jp.pl
</TEXTCLIPFUNC>
として、ISO-2022-JP 用の clipping 関数を使うように指定します。

5. 日本語でリソースファイルを書くには?

例えば [Date Next] の部分を [次へ] のように変更したいかもしれません。 が、日本語をそのままリソースファイルに記述してしまうと、$ が含まれている場合に問題が起こります。
具体的に見てみましょう。 「次へ」は ISO-2022-JP では、

ESC $ B < ! $ X ESC ( B
となりますから、これをリソースファイルに書いてしまうと、 「$B<!$ なんてリソース変数はない」 (Warning: Unrecognized variable: "B<!")、とおこられてしまいます。

これを解決するには、

<VARREGEX>
\$([^\033\$]*)\$(?![^\033]*\033\()
</VARREGEX>
を指定しましょう (http://www.namazu.org/FAQ.html.ja にあるものとほぼ等価です)。

非常に読みにくいですが、この意味は、色で対応させると次のようになります (色の付かないブラウザーで見てる方、ごめんなさい)。

\$ ([^\033\$]*) \$ (?! [^\033]*\033\( )
(なお「文字列」は 0 文字のものを含む)、 つまり、ESC + ( + [BJ] が続くもの ([BJ] は明示的には指定していませんが) は日本語の中であり、リソース変数ではないとみなす、ということになります。

6. charset を指定する

(追記: 2011/06/02)

一部のブラウザでは charset の指定がないと文字化けし、しかもブラウザで文字エンコードとして ISO-2022-JP を指定できないという問題があります。
これに対処するため、 <IdxPgBegin>, <MsgPgBegin>, <TIdxPgBegin> のそれぞれについて、 <head> から </head> の間に、

<meta http-equiv="content-type" content="text/html; charset=ISO-2022-JP">
を入れるとよいでしょう。

7. まとめ

MHonArc で日本語を通すには、リソースを

<CHARSETCONVERTERS>
plain;       iso_2022_jp::str2html; iso2022jp.pl
iso-2022-jp; iso_2022_jp::str2html; iso2022jp.pl
</CHARSETCONVERTERS>

<DEFCHARSET>
iso-2022-jp
</DEFCHARSET>

<DECODEHEADS>
<NOMAILTO>

<TEXTCLIPFUNC>
iso_2022_jp::clip; iso2022jp.pl
</TEXTCLIPFUNC>

<VARREGEX>
\$([^\033\$]*)\$(?![^\033]*\033\()
</VARREGEX>


<IdxPgBegin>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-2022-JP">
<title>$IDXTITLE$</title>
</head>
<body>
<h1>$IDXTITLE$</h1>
</IdxPgBegin>

<MsgPgBegin>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-2022-JP">
<title>$SUBJECTNA$</title>
<link rev="made" href="mailto:$FROMADDR$">
</head>
<body>
</MsgPgBegin>

<TIdxPgBegin>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-2022-JP">
<title>$TIDXTITLE$</title>
</head>
<body>
<h1>$TIDXTITLE$</h1>
</TIdxPgBegin>
のように設定すると良いでしょう。



Last modified: Sat Jun 11 07:40:36 JST 2011