--- messaging/manakai/doc/introduction.ja.html 2002/03/21 04:03:45 1.1 +++ messaging/manakai/doc/introduction.ja.html 2002/04/01 09:14:50 1.3 @@ -53,8 +53,8 @@ $hdr->add ('Subject' => $subject); $msg->body ($body); -# $smtp->send は SMTP で送信する method と仮定。 -$smtp->send ($msg); +# $smtp->send は SMTP で送信する method と仮定。 +$smtp->send ($msg);

CPAN を探すと、 @@ -69,7 +69,7 @@

参考: 「.」の場合は RFC 2822 的には正しく解釈 されなければなりませんが (出力はすべきでない)、 -これ以外の文字、例えば制御文字 ESCAPE でも同じようになります。 +これ以外の文字、例えば制御文字 ESCAPE でも同じようになります。 こちらは完全に間違いです。

参考: 実装方針としては不正な値はモジュールに 渡す前に弾くべきという考え方もあるでしょう。 @@ -79,33 +79,99 @@ を書くつもりでしたが、なんだかごちゃごちゃしていて、 それなら車輪の再発明になっても一から書いてみようと考えました。

-

実装状況

+

特色 (という程のものでもない。)

    -
  1. RFC 822, RFC 2822 の頭領域 (header field) を解釈出来ます。
  2. -
  3. 電子ニュース (RFC 1036 など), MIME, その他の追加頭領域の幾つかを解釈出来ます。
  4. -
  5. RFC 822/2822 の group なメイル・アドレスの領域内容を解釈出来ます。
  6. -
  7. 日付形式では RFC 822/1123, RFC 733, asctime, ISO 8601 (HTTP) などに対応。他の用途に転用出来ます。
  8. +
  9. 結構(謎)オブジェクト指向です。
  10. +
  11. RFC 822/2822 の group を解釈出来ます。
  12. draft-ietf-usefor-msg-id-alt-00 に基づいた送信アドレスなどによる Message-ID を生成出来ます。
  13. -
  14. まだ解釈出来ない構造化 (structured) 頭領域について、表示のために quoted-pair を unquote して値を返すなど出来ます。
  15. -
  16. MIME 本体 (body) にはまだ対応していません。 (text/plain 8bit 固定)
  17. -
  18. 説明はまだ不備です。各モジュールに pod で説明が入っていますが、 -抜けていたり実態に合っていなかったりもします。 -今の段階では code そのものが簡単に理解出来るとは思いますが。
  19. +
  20. 文字コード独立 (CSI) です。 (但し RFC 822 である都合上(謎)、 +ASCII 互換である必要はあります。 EBCDIC とかは無理です:-<)
  21. +
+ +

各仕様への対応状況

+ +
    +
  1. 電子メイルのメッセージ (RFC 822, RFC 2822) +の全機能に (抜けが無ければ) 対応しています。 +但し長さ制限などはチェックしていません。 (MIME の +Content-Transfer-Encoding +と一緒に実装予定)
  2. +
  3. 電子ニュース記事 (RFC 1036, +son-of-RFC1036, + +draft-usefor-article (06)) の頭領域の多くに対応しています。
  4. +
  5. MIME の本体部分 (body part) にはまだ対応していません。
  6. +
  7. MIME の追加頭領域 +(RFC 2045, +Content-Disposition) に対応しています。 +パラメーター値拡張 (RFC 2231) +も入出力ともに実装しました。
  8. +
  9. MIME 符号化語 (encoded-word) +の解読に対応しています:-) 但し別途変換処理を指定する必要があります。 +(文字コードの扱い参照)
  10. +
  11. HTTP/1.0, HTTP/1.1, CGI/1.1, CGI/1.2 の頭領域のうち、 +ごく一部に対応しています。 MHTML の +Content-Location にも対応しています。
  12. +
  13. 日付形式では RFC 822/1123, +RFC 733, asctime, ISO 8601 (HTML) +などに対応しています。
  14. +
+ +

制限事項

+ +
    +
  1. 類似モジュール(謎)のように、ファイル名やファイル・ハンドルを +渡して読み込ませることが出来ません。
  2. +
  3. 大きなメッセージでも一気に読み込み、全て主記憶領域で +保持しています。ですからあまり大きなメッセージの処理には +向いていないでしょう。
  4. +
  5. CRLF が単体で出現する場合、 +正しく処理出来ません。 (CRLF と等価とみなします。) +将来の版ではオプションで制御可能になるかもしれません。
  6. +
  7. あったら良さそうな機能が未実装かもしれません。 +(電子メイルなどで教えて下さい。)
  8. +
  9. 各モジュールのオプション体系があまり整備されていません。 +(それでも気持ち悪くない程度には体系的だと思います。)
  10. +
  11. 説明文 (document) が良い加減です。

今後の予定

    -
  1. 電子ニュースの頭領域 (RFC 1036, son-of-RFC1036, draft-usefor) の実装
  2. -
  3. MIME の頭領域の実装。
  4. +
  5. 電子ニュースの頭領域 (RFC 1036, +son-of-RFC1036, +draft-usefor-article) の完全実装
  6. +
  7. MIME の頭領域の実装。
  8. 追加/非標準の頭領域の実装。
  9. MIME 本体 (body) の実装。
  10. -
  11. 文字符号変換のための hook の実装?
  12. +
  13. 文字符号変換のための hook の実装?
  14. documentation。
  15. 使用例の作成。
+

必要環境

+ +
    +
  1. perl (Perl 5.6 以降または人間解析者:-)) +

    comment + を表すのに正規表現 (??{ code }) + を使っているので、これを解釈出来る、 + 5.6 以降の版である必要があります。

    +
  2. +
  3. Digest::MD2, Digest::MD5, Digest::SHA1 +

    Message-ID の生成にこれらを使用する場合のみ、 + Message::Field::MsgID::MsgID が使います。

    +

    これらが用意されていない環境ではエラーになるので、 + (現状では) 上記モジュールの該当部分を書き換えて対処して下さい。

    +
  4. +
  5. 文字コード変換処理 +

    日本語メッセージを扱うなら必須でしょう。 + 詳しくは文字コードの扱い + の章をご参照下さい。

    +
  6. +
+

入手

suika.fam.cx の SSH account をお持ちの場合、 CVS から入手出来ます。

@@ -125,6 +191,125 @@
  • 関連する仕様書 (RFC, Internet-Draft 等)
  • +

    文字コードの扱い

    + +

    卑しいことで頭を悩ますのは嫌なので(藁)、 +Message::* は符号化方法独立 (CSI) を目指して実装しています。 +(但し ASCII のしがらみだけは断ち切っていません:-)) +0x00 〜 0x7F が ASCII (または ASCII と見なして良いもの) である +場合は、 Message::* を通したことでデータが壊れることは +無いと思います。

    + +

    (もちろん、 RFC 822 など各仕様に照らして正統(的)で +ある必要があります。 atom +に8ビット・コードが含まれていると正しく扱えません。) +(早い話が、 quoted-string +などでは8ビット透過だということです。回りくどくてごめんなさい。)

    + +

    既定の状態では文字コードに関係する変換処理は行われません。 +しかし、フック関数っぽいもの(謎)を指定することで、 +変換処理をさせられます。

    + +

    指定出来るフック関数っぽいものは2種類です。 +DECODER は、元のメッセージを解析する時 +(parse ()) に適宜呼び出されます。 +ENCODER は、メッセージとして文字列化する際 +(stringify () など) に適宜呼び出されます。

    + +

    これらの関数は、当然、当該処理が呼び出される前に指定しておく +必要があります。 +Message::Entity->parse などする前に +定義しておくと良いでしょう。

    + +
    +require Message::MIME::Charset;
    +$Message::MIME::Charset::DECODER{'*default'} = sub {jcode::euc ($_[1])};
    +$Message::MIME::Charset::ENCODER{'*default'} = sub {jcode::jis ($_[1], 'euc')};
    +
    + +

    この例では、 jcode.pl を変換処理に使います。 +(もちろん、既に require +されていると仮定しています。)

    +

    最初の require で、変換処理を担当している +Message::MIME::Charset を読み込みます。 +(こうしておかないと、後から既定値 (= 無変換) で +*default が上書きされてしまいます。)

    + +

    この code を使ったスクリプトは内部処理を日本語 EUC +で行うと仮定しています。ですから、 DECODER +で日本語 EUC に変換します。

    +

    また、日本語メッセージでは ISO-2022-JP +を使うのが慣習ですから、 ENCODER +では 7ビット JIS に変換しています。

    +

    処理を行う関数は、引数が2つ以上与えられます。 +1つ目の引数は呼び出した class module, いわゆる +$self です。(この場合 self ではありませんが:-) +でも普通は必要ないでしょう。

    +

    2つ目の引数は処理対象の文字列です。

    +

    3つ目以降の引数は、追加オプションのハッシュです。 +ただし、現在追加オプションは定義されていません。

    +

    関数が返す値は(今のところ)一つだけです。 +処理が終わった文字列です。変換結果として何もなくなってしまったら、 +もちろん空文字列を返して構いません。 (undef +よりも空文字列の方が望ましいでしょう。)

    + +

    さて、上記の例では「*default」の EN/DECODER +を指定しましたが、ここには代わりに charset 名を指定出来ます。

    + +
    +$Message::MIME::Charset::DECODER{'iso-2022-jp'} = sub {jcode::euc ($_[1], 'jis')};
    +
    + +

    ここでは、 ISO-2022-JP を内部コードに変換する +方法を定義しています。 charset 名 (および「*default」 +は必ず小文字で書いて下さい!)

    +

    MIME body や、 encoded-word, RFC 2231 の拡張パラメーター値 +など、 charset が指定されている時はその charset 名の変換関数が +呼び出されます。 (指定された charset 名の変換関数が未定義の時は、 +何も処理しません。) これ以外の場面では、 *default +で定義された関数が使われます。

    + +

    最後に、日本語メッセージを扱う際の例を挙げておきます。

    + +
    +## jcode.pl を使用
    +require 'jcode.pl';
    +require Message::MIME::Charset;
    +$Message::MIME::Charset::DECODER{'*default'} = sub {jcode::euc ($_[1])};
    +$Message::MIME::Charset::DECODER{'iso-2022-jp'} = sub {jcode::euc ($_[1], 'jis')};
    +$Message::MIME::Charset::DECODER{'euc-jp'} = sub {$_[1]};
    +$Message::MIME::Charset::DECODER{'shift_jis'} = sub {jcode::euc ($_[1], 'sjis')};
    +$Message::MIME::Charset::ENCODER{'*default'} = sub {
    +  my $s = $_[1];
    +  ## 正規化
    +  jcode::tr(\$s,
    +      "\xa3\xb0-\xa3\xb9\xa3\xc1-\xa3\xda\xa3\xe1-\xa3\xfa\xa1\xf5".
    +      "\xa1\xa4\xa1\xa5\xa1\xa7\xa1\xa8\xa1\xa9\xa1\xaa\xa1\xae".
    +      "\xa1\xb0\xa1\xb2\xa1\xbf\xa1\xc3\xa1\xca\xa1\xcb\xa1\xce".
    +      "\xa1\xcf\xa1\xd0\xa1\xd1\xa1\xdc\xa1\xf0\xa1\xf3\xa1\xf4".
    +      "\xa1\xf6\xa1\xf7\xa1\xe1\xa2\xaf\xa2\xb0\xa2\xb2\xa2\xb1".
    +      "\xa1\xe4\xa1\xe3\xA1\xC0\xA1\xA1"
    +      => '0-9A-Za-z&,.:;?!`^_/|()[]{}+$%#*@=\'"~-><\\ ');
    +  jcode::jis ($s, 'euc', 'z')
    +};
    +
    + +
    +## Jcode.pm を使用
    +use Jcode;
    +require Message::MIME::Charset;
    +$Message::MIME::Charset::DECODER{'*default'} = sub {jcode::euc ($_[1])};
    +$Message::MIME::Charset::DECODER{'iso-2022-jp'} = sub {Jcode->new ($_[1], 'jis')->euc};
    +$Message::MIME::Charset::DECODER{'euc-jp'} = sub {$_[1]};
    +$Message::MIME::Charset::DECODER{'shift_jis'} = sub {Jcode->new ($_[1], 'sjis')->euc};
    +$Message::MIME::Charset::DECODER{'utf-8'} = sub {Jcode->new ($_[1], 'utf8')->euc};
    +$Message::MIME::Charset::ENCODER{'*default'} = sub {Jcode->new ($_[1], 'euc')->jis};
    +$Message::MIME::Charset::ENCODER{'utf-8'} = sub {Jcode->new ($_[1], 'euc')->utf8};
    +
    + +

    Perl 5.8 で Encode モジュールが使えるようになれば、 +もっと楽になると期待しています。

    + -
    $date: $
    +
    $Date: 2002/04/01 09:14:50 $