1 |
<?xml version="1.0" encoding="iso-2022-jp"?> |
<?xml version="1.0" encoding="iso-2022-jp"?> |
2 |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" |
<?xml-stylesheet href="/s/simpledoc.css" type="text/css" ?> |
3 |
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" |
4 |
<html xml:lang="ja" xmlns="http://www.w3.org/1999/xhtml"> |
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> |
5 |
<head> |
<html xml:lang="ja" xmlns="http://www.w3.org/1999/xhtml"> |
6 |
<title xml:lang="en">Message::* Perl modules</title> |
<head> |
7 |
<link rel="index" href="./" /> |
<title xml:lang="en">Message::* Perl modules</title> |
8 |
<?xml-stylesheet href="/s/simpledoc"?> |
<link rel="index" href="./" /> |
9 |
<link rel="stylesheet" href="/s/simpledoc" /> |
<link rel="stylesheet" href="/s/simpledoc.css" type="text/css" /> |
10 |
<link rev="made" href="mailto:w@suika.fam.cx" /> |
<link rev="made" href="mailto:w@suika.fam.cx" /> |
11 |
<link rel="copyright" href="/c/pd" title="Public Domain." /> |
<link rel="copyright" href="/c/pd" title="Public Domain." /> |
12 |
<meta name="author" content="若葉" /> |
<meta name="author" content="$B<cMU(B" /> |
13 |
<meta name="keywords" content="Perl, module, pm, Message, RFC 822, RFC 2822, RFC 1036, son-of-RFC 1036, MIME, Usefor, HTTP, CGI, header, field" /> |
<meta name="keywords" content="Perl, module, pm, Message, RFC 822, RFC 2822, RFC 1036, son-of-RFC1036, MIME, Usefor, HTTP, CGI, header, field" /> |
14 |
</head> |
</head> |
15 |
<body> |
<body> |
16 |
<h1>Message::* Perl modules</h1> |
<h1>Message::* Perl modules</h1> |
17 |
|
|
18 |
<h2>はじめのはじめに</h2> |
<h2>$B$O$8$a$N$O$8$a$K(B</h2> |
19 |
|
|
20 |
<p>たとえば Perl で書かれた CGI script, それも掲示板なんかには、 |
<p>$B$?$H$($P(B Perl $B$G=q$+$l$?(B CGI script, $B$=$l$b7G<(HD$J$s$+$K$O!"(B |
21 |
こんなくだらない code が載っていたりします。</p> |
$B$3$s$J$_$C$H$b$J$$(B code $B$,:\$C$F$$$?$j$7$^$9!#(B</p> |
22 |
|
|
23 |
<pre class="application-x-perl"> |
<pre class="application-x-perl"> |
24 |
jcode'convert(*from, "jis"); |
jcode'convert(*from, "jis"); |
25 |
jcode'convert(*subject, "jis"); |
jcode'convert(*subject, "jis"); |
26 |
jcode'convert(*message, "jis"); |
jcode'convert(*message, "jis"); |
27 |
open (MAIL, "| $sendmail"); |
open (MAIL, "| $sendmail"); |
28 |
print MAIL "From: $mail ($from)\n"; |
print MAIL "From: $mail ($from)\n"; |
29 |
print MAIL "To: $mailto\n"; |
print MAIL "To: $mailto\n"; |
30 |
print MAIL "Subject: $subject\n"; |
print MAIL "Subject: $subject\n"; |
31 |
print MAIL "\n"; |
print MAIL "\n"; |
32 |
print MAIL "$message"; |
print MAIL "$message"; |
33 |
print MAIL "\n"; |
print MAIL "\n"; |
34 |
close (MAIL); |
close (MAIL); |
35 |
</pre> |
</pre> |
36 |
|
|
37 |
<p>これでは視認性も良くないですし、うっかり修正し間違えると |
<p>$B$3$l$G$O;kG'@-$bNI$/$J$$$G$9$7!"$&$C$+$j=$@5$74V0c$($k$H(B |
38 |
変なメッセージを送信してしまいます。 |
$BJQ$J%a%C%;!<%8$rAw?.$7$F$7$^$$$^$9!#(B |
39 |
(筆者はしょっちゅうはまってました:-) |
($BI.<T$O$7$g$C$A$e$&$O$^$C$F$^$7$?(B:-) |
40 |
(それに多くの code では、 |
($B$=$l$KB?$/$N(B code $B$G$O!"(B |
41 |
HTML でのクロスサイトスクリプティング (CSS) 問題と |
HTML $B$G$N%/%m%9%5%$%H%9%/%j%W%F%#%s%0(B (CSS) $BLdBj$H(B |
42 |
類似の問題への対処をしていません。)</p> |
$BN`;w$NLdBj$X$NBP=h$r$7$F$$$^$;$s!#(B)</p> |
43 |
|
|
44 |
<p>オブジェクト指向を取り入れて次のような感じでメッセージを |
<p>$B%*%V%8%'%/%H;X8~$r<h$jF~$l$F<!$N$h$&$J46$8$G%a%C%;!<%8$r(B |
45 |
構成したいところです。</p> |
$B9=@.$7$?$$$H$3$m$G$9!#(B</p> |
46 |
|
|
47 |
<pre class="application-x-perl"> |
<pre class="application-x-perl"> |
48 |
use Message::Entity; |
use Message::Entity; |
49 |
my $msg = new Message::Entity; |
my $msg = new Message::Entity; |
50 |
my $hdr = $msg->header; |
my $hdr = $msg->header; |
51 |
$hdr->add ('From')->add ('me@bar.example'); |
$hdr->add ('From')->add ('me@bar.example'); |
52 |
$hdr->add ('To')->add ('foo@bar.example', display_name => 'Mr. foo'); |
$hdr->add ('To')->add (['foo@bar.example', display_name => 'Mr. foo']); |
53 |
$hdr->add ('Subject' => $subject); |
$hdr->add (Subject => $subject); |
54 |
$msg->body ($body); |
$msg->body ($body); |
55 |
|
|
56 |
# $smtp->send は SMTP で送信する method と仮定。 |
# $smtp->send $B$O(B SMTP $B$GAw?.$9$k(B method $B$H2>Dj!#(B |
57 |
$smtp->send ($msg); |
$smtp->send ($msg); |
58 |
</pre> |
</pre> |
59 |
|
|
60 |
<p><a href="http://www.cpan.org/" xml:lang="en">CPAN</a> を探すと、 |
<p><a href="http://www.cpan.org/" xml:lang="en">CPAN</a> $B$rC5$9$H!"(B |
61 |
これに似たようなことができそうなモジュールはあるようですが、 |
$B$3$l$K;w$?$h$&$J$3$H$,$G$-$=$&$J%b%8%e!<%k$O$"$k$h$&$G$9$,!"(B |
62 |
実際に使ってみると、与える値によっては <a href="urn:ietf:rfc:822">RFC 822</a>/<a href="urn:ietf:rfc:2822">2822</a> に違反する |
$B<B:]$K;H$C$F$_$k$H!"M?$($kCM$K$h$C$F$O(B <a href="urn:ietf:rfc:822">RFC 822</a>/<a href="urn:ietf:rfc:2822">2822</a> $B$K0cH?$9$k(B |
63 |
結果を出力するなどの不満があります。 (例えば今の例で |
$B7k2L$r=PNO$9$k$H$+!"$=$b$=$b$=$l0JA0$K!"(B |
64 |
<code xml:lang="en">To:</code> 領域に使っている |
<code>$hdr->addr ('Foo Bar <foo@bar.example>')</code> |
65 |
<code xml:lang="en">display_name</code> で「.」が含まれますが、 |
$B$N$h$&$K%a%C%;!<%87A<0$r%b%8%e!<%kFb$K1#F?$7$-$l$F$$$J$$$H$+!"Hs(B |
66 |
RFC 2822 的には新しいメッセージでは互換性のため |
ASCII $BJ8;z$r9MN8$7$F$$$J$$$H$+$NITK~$,$"$j$^$9!#(B</p> |
67 |
<code xml:lang="en" class="bnf rfc2822">quoted-string</code> |
|
68 |
にする必要があります。しかしそのまま出力されます。)</p> |
<p class="note">($B<BAuJ}?K$H$7$F$OIT@5$JCM$O%b%8%e!<%k$KEO$9A0$KCF$/$Y$-$H$$$&9M$(J}$b$"$k$G$7$g$&$1$I!"0lHLE*$JMxMQ$K:]$7$F$O8-$$@_7W$@$H$O;W$($^$;$s!#(B)</p> |
69 |
|
|
70 |
<p class="note">参考: 「.」の場合は RFC 2822 的には正しく解釈 |
<p>$B$H$$$&$3$H$G!"$O$8$a$O4{B8$N%b%8%e!<%k$N(B wrapper ($B$"$k$$$OJd40(B) |
71 |
されなければなりませんが (出力はすべきでない)、 |
$B$r=q$/$D$b$j$G$7$?$,!"$J$s$@$+$4$A$c$4$A$c$7$F$$$F!"(B |
72 |
これ以外の文字、例えば制御文字 <code class="character">ESCAPE</code> でも同じようになります。 |
$B$=$l$J$i<VNX$N:FH/L@$K$J$C$F$b0l$+$i=q$$$F$_$h$&$H9M$($^$7$?!#(B</p> |
73 |
こちらは完全に間違いです。</p> |
|
74 |
<p class="note">参考: 実装方針としては不正な値はモジュールに |
<h2>$BFC?'(B ($B$H$$$&Dx$N$b$N$G$b$J$$!#(B)</h2> |
75 |
渡す前に弾くべきという考え方もあるでしょう。 |
|
76 |
でもそんなのは不便です。</p> |
<ol> |
77 |
|
<li>$B7k9=%*%V%8%'%/%H;X8~$G$9!#(B</li> |
78 |
<p>ということで、はじめは既存のモジュールの wrapper (あるいは補完) |
<li>RFC 822/2822 $B$N(B <code class="bnf rfc2822">group</code> $B$r2r<a=PMh$^$9!#(B</li> |
79 |
を書くつもりでしたが、なんだかごちゃごちゃしていて、 |
<li><a href="urn:ietf:id:draft-ietf-usefor-msg-id-alt-00">draft-ietf-usefor-msg-id-alt-00</a> $B$K4p$E$$$?Aw?.%"%I%l%9$J$I$K$h$k(B <code class="rfc2822">Message-ID</code> $B$r@8@.=PMh$^$9!#(B</li> |
80 |
それなら車輪の再発明になっても一から書いてみようと考えました。</p> |
<li>$BJ8;z%3!<%IFHN)(B (CSI) $B$G$9!#(B ($BC"$7(B RFC 822 $B$G$"$kET9g>e(B($BFf(B)$B!"(B |
81 |
|
ASCII $B8_49$G$"$kI,MW$O$"$j$^$9!#(B EBCDIC $B$H$+$OL5M}$G$9(B:-< |
82 |
<h2>特色 (という程のものでもない。)</h2> |
($B$H$$$&$N$O%a%C%;!<%89=B$$NItJ,$N$3$H$G$9!#(B |
83 |
|
MIME $B$r;H$C$F(B EBCDIC $B$J$I$r%a%C%;!<%8K\J8$KF~$l$k$3$H$O2DG=$G$9!#(B))</li> |
84 |
<ol> |
<li>MIME (<a href="urn:ietf:rfc:2045">RFC 2045</a>, |
85 |
<li>結構(謎)オブジェクト指向です。</li> |
<a href="urn:ietf:rfc:2046">2046</a>) $B$K$[$\40A4$KBP1~$7$F$$$^$9!#(B</li> |
86 |
<li>RFC 822/2822 の <code class="bnf rfc2822">group</code> を解釈出来ます。</li> |
</ol> |
87 |
<li><a href="urn:ietf:id:draft-ietf-usefor-msg-id-alt-00">draft-ietf-usefor-msg-id-alt-00</a> に基づいた送信アドレスなどによる <code class="rfc2822">Message-ID</code> を生成出来ます。</li> |
|
88 |
<li>文字コード独立 (CSI) です。 (但し RFC 822 である都合上(謎)、 |
<h2>$B3F;EMM$X$NBP1~>u67(B</h2> |
89 |
ASCII 互換である必要はあります。 EBCDIC とかは無理です:-<)</li> |
|
90 |
</ol> |
<ol> |
91 |
|
<li>$BEE;R%a%$%k$N%a%C%;!<%8(B (RFC 822, RFC 2822) |
92 |
<h2>各仕様への対応状況</h2> |
$B$NA45!G=$KBP1~$7$F$$$^$9!#(B</li> |
93 |
|
<li>$BEE;R%K%e!<%95-;v(B (<a href="/uri-res/N2L?urn:ietf:rfc:1036">RFC 1036</a>, |
94 |
<ol> |
<a href="spec/son-of-RFC1036">son-of-RFC1036</a>, |
95 |
<li>電子メイルのメッセージ (RFC 822, RFC 2822) |
<a href="/uri-res/N2L?urn:ietf:id:draft-usefor-article-06"> |
96 |
の全機能に (抜けが無ければ) 対応しています。 |
draft-usefor-article (06)</a>) $B$NF,NN0h$NB?$/$KBP1~$7$F$$$^$9!#(B</li> |
97 |
但し長さ制限などはチェックしていません。 (MIME の |
<li>MIME $B$NK\J8ItJ,(B (body part) $B$KBP1~$7$F$$$^$9!#(B |
98 |
<code class="mime">Content-Transfer-Encoding</code> |
<ul> |
99 |
と一緒に実装予定)</li> |
<li>$BB?ItJ,(B (multipart) $B$dJ,3d(B (message/partial), |
100 |
<li>電子ニュース記事 (<a href="/uri-res/N2L?urn:ietf:rfc:1036">RFC 1036</a>, |
$B30ItK\J,(B (message/external-body) $B$r07$&$3$H$,=PMh$^$9!#(B</li> |
101 |
<a href="spec/son-of-RFC1036">son-of-RFC1036</a>, |
<li>text/plain; format=flowed |
102 |
<a href="/uri-res/N2L?urn:ietf:id:draft-usefor-article-06"> |
(<a href="urn:ietf:rfc:2646">RFC 2646</a>) |
103 |
draft-usefor-article (06)</a>) の頭領域の多くに対応しています。</li> |
$B$KBP1~$7$F$$$^$9!#(B</li> |
104 |
<li>MIME の本体部分 (body part) にはまだ対応していません。</li> |
<li>Content-Transfer-Encoding $B$O(B Base64, Quoted-Printable |
105 |
<li>MIME の追加頭領域 |
$B$OL^O@!"(B x-uuencode, x-gzip64 $B$K$bBP1~!#(B |
106 |
(<a href="/uri-res/N2L?urn:ietf:rfc:2045">RFC 2045</a>, |
RFC 2822 $B%a%$%k=PNO%b!<%I$G$O!"K\J8$,(B8$B%S%C%H$G$b<+F0E*$KE,@Z$J(B |
107 |
<code class="mime">Content-Disposition</code>) に対応しています。 |
CTE $B$GId9f2=$7$^$9!#(B</li> |
108 |
パラメーター値拡張 (<a href="/uri-res/N2L?urn:ietf:rfc:2231">RFC 2231</a>) |
</ul> |
109 |
も入出力ともに実装しました。</li> |
</li> |
110 |
<li>MIME 符号化語 (<code class="mime bnf">encoded-word</code>) |
<li>MIME $B$NF,NN0h(B |
111 |
の解読に対応しています:-) 但し別途変換処理を指定する必要があります。 |
(<a href="/uri-res/N2L?urn:ietf:rfc:2045">RFC 2045</a>, |
112 |
(<a href="#code">文字コードの扱い</a>参照)</li> |
<code class="mime">Content-Disposition</code>) $B$KBP1~$7$F$$$^$9!#(B |
113 |
<li>HTTP/1.0, HTTP/1.1, CGI/1.1, CGI/1.2 の頭領域のうち、 |
$B%Q%i%a!<%?!<CM3HD%(B (<a href="/uri-res/N2L?urn:ietf:rfc:2231">RFC 2231</a>) |
114 |
ごく一部に対応しています。 MHTML の |
$B$bF~=PNO$H$b$K<BAu$7$^$7$?!#(B</li> |
115 |
<code class="mime">Content-Location</code> にも対応しています。</li> |
<li>MIME $BId9f2=8l(B (<code class="mime bnf">encoded-word</code>) |
116 |
<li>日付形式では RFC 822/<a href="urn:ietf:rfc:1123">1123</a>, |
$B$N2rFI$KBP1~$7$F$$$^$9(B:-)</li> |
117 |
<a href="urn:ietf:rfc:733">RFC 733</a>, asctime, ISO 8601 (HTML) |
<li>HTTP/1.0, HTTP/1.1, CGI/1.1, CGI/1.2 $B$NF,NN0h$N$&$A!"(B |
118 |
などに対応しています。</li> |
$B$4$/0lIt$KBP1~$7$F$$$^$9!#(B MHTML $B$N(B |
119 |
</ol> |
<code class="mime">Content-Location</code> $B$K$bBP1~$7$F$$$^$9!#(B</li> |
120 |
|
<li>$BF|IU7A<0$G$O(B RFC 822/<a href="urn:ietf:rfc:1123">1123</a>, |
121 |
<h2>制限事項</h2> |
<a href="urn:ietf:rfc:733">RFC 733</a>, asctime, ISO 8601 (HTML) |
122 |
|
$B$J$I$KBP1~$7$F$$$^$9!#F|IU$N=PNO$O(B sprintf |
123 |
<ol> |
$B$NMM$J=q<0J8;zNs$rM?$($k$3$H$G!"B?<oB?MM$J7A<0$KBP1~!#(B</li> |
124 |
<li>類似モジュール(謎)のように、ファイル名やファイル・ハンドルを |
<li>X-Moe $B%7%j!<%:$KBP1~$7$F$$$^$9(B:-)</li> |
125 |
渡して読み込ませることが出来ません。</li> |
</ol> |
126 |
<li>大きなメッセージでも一気に読み込み、全て主記憶領域で |
|
127 |
保持しています。ですからあまり大きなメッセージの処理には |
<h2>$B@)8B;v9`(B</h2> |
128 |
向いていないでしょう。</li> |
|
129 |
<li><code>CR</code> や <code>LF</code> が単体で出現する場合、 |
<ol> |
130 |
正しく処理出来ません。 (<code>CRLF</code> と等価とみなします。) |
<li>$BN`;w%b%8%e!<%k(B($BFf(B)$B$N$h$&$K!"%U%!%$%kL>$d%U%!%$%k!&%O%s%I%k$r(B |
131 |
将来の版ではオプションで制御可能になるかもしれません。</li> |
$BEO$7$FFI$_9~$^$;$k$3$H$,=PMh$^$;$s!#(B</li> |
132 |
<li>あったら良さそうな機能が未実装かもしれません。 |
<li>$BBg$-$J%a%C%;!<%8$G$b0l5$$KFI$_9~$_!"A4$F<g5-21NN0h$G(B |
133 |
(<a href="mailto:w@suika.fam.cx">電子メイル</a>などで教えて下さい。)</li> |
$BJ];}$7$F$$$^$9!#$G$9$+$i$"$^$jBg$-$J%a%C%;!<%8$N=hM}$K$O(B |
134 |
<li>各モジュールのオプション体系があまり整備されていません。 |
$B8~$$$F$$$J$$$G$7$g$&!#(B</li> |
135 |
(それでも気持ち悪くない程度には体系的だと思います。)</li> |
<li><code>CR</code> $B$d(B <code>LF</code> $B$,C1BN$G=P8=$9$k>l9g!"(B |
136 |
<li>説明文 (document) が良い加減です。</li> |
$B@5$7$/=hM}=PMh(B<del>$B$^$;$s(B</del><ins>$B$J$$$3$H$,$"$j$^$9(B |
137 |
</ol> |
($B6a$$>-Mh$NHG$G2~A1$NM=Dj(B)</ins>$B!#(B (<code>CRLF</code> $B$HEy2A$H$_$J$7$^$9!#(B) |
138 |
|
$B>-Mh$NHG$G$O%*%W%7%g%s$G@)8f2DG=$K$J$k$+$b$7$l$^$;$s!#(B</li> |
139 |
<h2>今後の予定</h2> |
<li>$B$"$C$?$iNI$5$=$&$J5!G=$,L$<BAu$+$b$7$l$^$;$s!#(B |
140 |
|
($BM_$7$$5!G=$,L$<BAu$@$C$?$i!"(B |
141 |
<ol> |
<a href="mailto:w@suika.fam.cx">$BEE;R%a%$%k(B</a>$B$d(B |
142 |
<li>電子ニュースの頭領域 (RFC 1036, |
<a href="news://suika.fam.cx/suika.msg">suika.msg</a> |
143 |
<a href="spec/son-of-RFC1036">son-of-RFC1036</a>, |
$B$J$I$G65$($F2<$5$$!#(B)</li> |
144 |
draft-usefor-article) の完全実装</li> |
<li>$B3F%b%8%e!<%k$N%*%W%7%g%sBN7O$,$"$^$j@0Hw$5$l$F$$$^$;$s!#(B |
145 |
<li><del>MIME の頭領域の実装。</del></li> |
($B$=$l$G$b5$;}$A0-$/$J$$DxEY$K$OBN7OE*$@$H;W$$$^$9!#(B)</li> |
146 |
<li>追加/非標準の頭領域の実装。</li> |
<li>$B@bL@J8(B (document) $B$,NI$$2C8:$G$9!#(B</li> |
147 |
<li>MIME 本体 (<code class="bnf rfc822">body</code>) の実装。</li> |
</ol> |
148 |
<li><del>文字符号変換のための hook の実装?</del></li> |
|
149 |
<li>documentation。</li> |
<h2>$B:#8e$NM=Dj(B</h2> |
150 |
<li>使用例の作成。</li> |
|
151 |
</ol> |
<ol> |
152 |
|
<li>$BEE;R%K%e!<%9$NF,NN0h(B (RFC 1036, |
153 |
<h2>必要環境</h2> |
<a href="spec/son-of-RFC1036">son-of-RFC1036</a>, |
154 |
|
draft-usefor-article) $B$N40A4<BAu(B</li> |
155 |
<ol> |
<li>$BDI2C(B/$BHsI8=`$NF,NN0h$N<BAu!#(B</li> |
156 |
<li>perl (Perl 5.6 以降または<span title="human parser">人間解析者</span>:-)) |
<li>documentation$B!#(B</li> |
157 |
<p class="note"><code class="bnf rfc822">comment</code> |
<li>$B;HMQNc$N:n@.!#(B</li> |
158 |
を表すのに正規表現 <code class="regex">(??{ <var>code</var> })</code> |
<li>$B4{B8%b%8%e!<%k$,MxMQ=PMh$kItJ,$O!"$=$l$r8F$S=P$9$h$&$K$9$k$+(B |
159 |
を使っているので、これを解釈出来る、 |
$B$=$N(B code $B$rN.MQ$9$k!#(B</li> |
160 |
5.6 以降の版である必要があります。</p> |
<li>$BN`;w%b%8%e!<%k$H$N3&LL$N6&DL2=(B</li> |
161 |
</li> |
</ol> |
162 |
<li>Digest::MD2, Digest::MD5, Digest::SHA1 |
|
163 |
<p>Message-ID の生成にこれらを使用する場合のみ、 |
<h2>$BI,MW4D6-(B</h2> |
164 |
<code>Message::Field::MsgID::MsgID</code> が使います。</p> |
|
165 |
<p>これらが用意されていない環境ではエラーになるので、 |
<ol> |
166 |
(現状では) 上記モジュールの該当部分を書き換えて対処して下さい。</p> |
<li>Perl (perl 5.6 $B0J9_$^$?$O(B<span title="human parser">$B?M4V2r@O<T(B</span>:-)) |
167 |
</li> |
<p class="note"><code class="bnf rfc822">comment</code> |
168 |
<li>文字コード変換処理 |
$B$rI=$9$N$K@55,I=8=(B <code class="regex">(??{ <var>code</var> })</code> |
169 |
<p>日本語メッセージを扱うなら必須でしょう。 |
$B$r;H$C$F$$$k$N$G!"$3$l$r2r<a=PMh$k!"(B |
170 |
詳しくは<a href="#code">文字コードの扱い</a> |
5.6 $B0J9_$NHG$G$"$kI,MW$,$"$j$^$9!#(B</p> |
171 |
の章をご参照下さい。</p> |
</li> |
172 |
</li> |
<li>Digest::MD2, Digest::MD5, Digest::SHA1 |
173 |
</ol> |
<p>Message-ID $B$N@8@.$K$3$l$i$r;HMQ$9$k>l9g$N$_!"(B |
174 |
|
<code>Message::Field::MsgID</code> $B$,;H$$$^$9!#(B</p> |
175 |
<h2>入手</h2> |
<p>$B$3$l$i$,MQ0U$5$l$F$$$J$$4D6-$G$O%(%i!<$K$J$k$N$G!"(B |
176 |
|
($B8=>u$G$O(B) $B>e5-%b%8%e!<%k$N3:EvItJ,$r=q$-49$($FBP=h$7$F2<$5$$!#(B</p> |
177 |
<p>suika.fam.cx の SSH account をお持ちの場合、 CVS から入手出来ます。</p> |
</li> |
178 |
|
<li>MIME::Base64 |
179 |
<p class="example">$ cvs -d :ext:<var xml:lang="en">username</var>@suika.fam.cx:/home/cvs -d perl/lib/Message/</p> |
<p>$B$A$J$_$K!"(B Quoted-Printable $B$d(B RFC 2231 $B$N(B |
180 |
|
% $BId9f2=$O<+NO$GI|9f$7$^$9!#(B</p> |
181 |
<p>Web からも取り出せます。 <<a href="/gate/cvs/perl/lib/Message/">http://suika.fam.cx/gate/cvs/perl/lib/Message/</a>> (tarball で一括取得も出来ます。)</p> |
</li> |
182 |
|
<li>$BJ8;z%3!<%IJQ49=hM}(B |
183 |
<h2>ライセンス</h2> |
<p>$BF|K\8l%a%C%;!<%8$r07$&$J$iI,?\$G$7$g$&!#(B |
184 |
|
$B>\$7$/$O(B<a href="#code">$BJ8;z%3!<%I$N07$$(B</a> |
185 |
<p>Message::* Perl modules は自由ソフトウェアです。 |
$B$N>O$r$4;2>H2<$5$$!#(B</p> |
186 |
GNU GPL に従って利用出来ます。詳しくは各ファイルを御覧下さい。</p> |
</li> |
187 |
|
</ol> |
188 |
<h2>参考文献</h2> |
|
189 |
|
<h2>$BF~<j(B</h2> |
190 |
<ul> |
|
191 |
<li><a href="spec/">関連する仕様書 (RFC, Internet-Draft 等)</a></li> |
<p>suika.fam.cx $B$N(B SSH account $B$r$*;}$A$N>l9g!"(B CVS $B$+$iF~<j=PMh$^$9!#(B</p> |
192 |
</ul> |
|
193 |
|
<p class="example">$ cvs -d :ext:<var xml:lang="en">username</var>@suika.fam.cx:/home/cvs -d perl/lib/Message/</p> |
194 |
<h2 id="code">文字コードの扱い</h2> |
|
195 |
|
<p>Web $B$+$i$b<h$j=P$;$^$9!#(B <<a href="/gate/cvs/perl/lib/Message/">http://suika.fam.cx/gate/cvs/perl/lib/Message/</a>> (tarball $B$G0l3g<hF@$b=PMh$^$9!#(B)</p> |
196 |
<p>卑しいことで頭を悩ますのは嫌なので(藁)、 |
|
197 |
Message::* は符号化方法独立 (CSI) を目指して実装しています。 |
<h2>$B%i%$%;%s%9(B</h2> |
198 |
(但し ASCII のしがらみだけは断ち切っていません:-)) |
|
199 |
0x00 〜 0x7F が ASCII (または ASCII と見なして良いもの) である |
<p>Message::* Perl modules $B$O<+M3%=%U%H%&%'%"$G$9!#(B |
200 |
場合は、 Message::* を通したことでデータが壊れることは |
GNU GPL $B$K=>$C$FMxMQ=PMh$^$9!#>\$7$/$O3F%U%!%$%k$r8fMw2<$5$$!#(B</p> |
201 |
無いと思います。</p> |
|
202 |
|
<h2>$B;29MJ88%(B</h2> |
203 |
<p>(もちろん、 RFC 822 など各仕様に照らして正統(的)で |
|
204 |
ある必要があります。 <code class="bnf rfc822">atom</code> |
<ul> |
205 |
に8ビット・コードが含まれていると正しく扱えません。) |
<li><a href="spec/">$B4XO"$9$k;EMM=q(B (RFC, Internet-Draft $BEy(B)</a></li> |
206 |
(早い話が、 <code class="bnf rfc822">quoted-string</code> |
</ul> |
207 |
などでは8ビット透過だということです。回りくどくてごめんなさい。)</p> |
|
208 |
|
<h2 id="code">$BJ8;z%3!<%I$N07$$(B</h2> |
209 |
<p>既定の状態では文字コードに関係する変換処理は行われません。 |
|
210 |
しかし、フック関数っぽいもの(謎)を指定することで、 |
<p>$BH\$7$$$3$H$GF,$rG:$^$9$N$O7y$J$N$G(B($BON(B)$B!"(B |
211 |
変換処理をさせられます。</p> |
[[ $B"*(B<a href="#code-easy">$B<j$C<h$jAa$/J}K!$@$1FI$`(B</a>$B!#(B ]] |
212 |
|
Message::* $B$OId9f2=J}K!FHN)(B (CSI) $B$rL\;X$7$F<BAu$7$F$$$^$9!#(B |
213 |
<p>指定出来るフック関数っぽいものは2種類です。 |
($BC"$7(B ASCII $B$N$7$,$i$_$@$1$OCG$A@Z$C$F$$$^$;$s(B:-)) |
214 |
<code>DECODER</code> は、元のメッセージを解析する時 |
0x00 $B!A(B 0x7F $B$,(B ASCII ($B$^$?$O(B ASCII $B$H8+$J$7$FNI$$$b$N(B) $B$G$"$k(B |
215 |
(<code class="perl">parse ()</code>) に適宜呼び出されます。 |
$B>l9g$O!"(B Message::* $B$rDL$7$?$3$H$G%G!<%?$,2u$l$k$3$H$O(B |
216 |
<code>ENCODER</code> は、メッセージとして文字列化する際 |
$BL5$$$H;W$$$^$9!#(B</p> |
217 |
(<code class="perl">stringify ()</code> など) に適宜呼び出されます。</p> |
|
218 |
|
<p>($B$b$A$m$s!"(B RFC 822 $B$J$I3F;EMM$K>H$i$7$F@5E}(B($BE*(B)$B$G(B |
219 |
<p>これらの関数は、当然、当該処理が呼び出される前に指定しておく |
$B$"$kI,MW$,$"$j$^$9!#(B <code class="bnf rfc822">atom</code> |
220 |
必要があります。 |
$B$K(B8$B%S%C%H!&%3!<%I$,4^$^$l$F$$$k$H@5$7$/07$($^$;$s!#(B) |
221 |
<samp class="perl">Message::Entity->parse</samp> などする前に |
($BAa$$OC$,!"(B <code class="bnf rfc822">quoted-string</code> |
222 |
定義しておくと良いでしょう。</p> |
$B$J$I$G$O(B8$B%S%C%HF)2a$@$H$$$&$3$H$G$9!#2s$j$/$I$/$F$4$a$s$J$5$$!#(B)</p> |
223 |
|
|
224 |
<pre class="example perl"> |
<p>$B4{Dj$N>uBV$G$OJ8;z%3!<%I$K4X78$9$kJQ49=hM}$O9T$o$l$^$;$s!#(B |
225 |
require Message::MIME::Charset; |
$B$7$+$7!"%U%C%/4X?t$C$]$$$b$N(B($BFf(B)$B$r;XDj$9$k$3$H$G!"(B |
226 |
$Message::MIME::Charset::DECODER{'*default'} = sub {jcode::euc ($_[1])}; |
$BJQ49=hM}$r$5$;$i$l$^$9!#(B</p> |
227 |
$Message::MIME::Charset::ENCODER{'*default'} = sub {jcode::jis ($_[1], 'euc')}; |
|
228 |
</pre> |
<p>$B;XDj=PMh$k%U%C%/4X?t$C$]$$$b$N$O(B2$B<oN`$G$9!#(B |
229 |
|
<code>DECODER</code> $B$O!"85$N%a%C%;!<%8$r2r@O$9$k;~(B |
230 |
<p>この例では、 jcode.pl を変換処理に使います。 |
(<code class="perl">parse ()</code>) $B$KE,598F$S=P$5$l$^$9!#(B |
231 |
(もちろん、既に <code class="perl">require</code> |
<code>ENCODER</code> $B$O!"%a%C%;!<%8$H$7$FJ8;zNs2=$9$k:](B |
232 |
されていると仮定しています。)</p> |
(<code class="perl">stringify ()</code> $B$J$I(B) $B$KE,598F$S=P$5$l$^$9!#(B</p> |
233 |
<p>最初の <code class="perl">require</code> で、変換処理を担当している |
|
234 |
<code class="perl">Message::MIME::Charset</code> を読み込みます。 |
<p>$B$3$l$i$N4X?t$O!"EvA3!"Ev3:=hM}$,8F$S=P$5$l$kA0$K;XDj$7$F$*$/(B |
235 |
(こうしておかないと、後から既定値 (= 無変換) で |
$BI,MW$,$"$j$^$9!#(B |
236 |
<code class="perl">*default</code> が上書きされてしまいます。)</p> |
<samp class="perl">Message::Entity->parse</samp> $B$J$I$9$kA0$K(B |
237 |
|
$BDj5A$7$F$*$/$HNI$$$G$7$g$&!#(B</p> |
238 |
<p>この code を使ったスクリプトは内部処理を日本語 EUC |
|
239 |
で行うと仮定しています。ですから、 <code class="perl">DECODER</code> |
<pre class="example perl"> |
240 |
で日本語 EUC に変換します。</p> |
require Message::MIME::Charset; |
241 |
<p>また、日本語メッセージでは <code>ISO-2022-JP</code> |
$Message::MIME::Charset::DECODER{'*default'} = sub {jcode::euc ($_[1])}; |
242 |
を使うのが慣習ですから、 <code class="perl">ENCODER</code> |
$Message::MIME::Charset::ENCODER{'*default'} = sub {jcode::jis ($_[1], 'euc')}; |
243 |
では 7ビット JIS に変換しています。</p> |
</pre> |
244 |
<p>処理を行う関数は、引数が2つ以上与えられます。 |
|
245 |
1つ目の引数は呼び出した class module, いわゆる |
<p>$B$3$NNc$G$O!"(B jcode.pl $B$rJQ49=hM}$K;H$$$^$9!#(B |
246 |
<code class="perl">$self</code> です。(この場合 self ではありませんが:-) |
($B$b$A$m$s!"4{$K(B <code class="perl">require</code> |
247 |
でも普通は必要ないでしょう。</p> |
$B$5$l$F$$$k$H2>Dj$7$F$$$^$9!#(B)</p> |
248 |
<p>2つ目の引数は処理対象の文字列です。</p> |
<p>$B:G=i$N(B <code class="perl">require</code> $B$G!"JQ49=hM}$rC4Ev$7$F$$$k(B |
249 |
<p>3つ目以降の引数は、追加オプションのハッシュです。 |
<code class="perl">Message::MIME::Charset</code> $B$rFI$_9~$_$^$9!#(B |
250 |
ただし、現在追加オプションは定義されていません。</p> |
($B$3$&$7$F$*$+$J$$$H!"8e$+$i4{DjCM(B (= $BL5JQ49(B) $B$G(B |
251 |
<p>関数が返す値は(今のところ)一つだけです。 |
<code class="perl">*default</code> $B$,>e=q$-$5$l$F$7$^$$$^$9!#(B)</p> |
252 |
処理が終わった文字列です。変換結果として何もなくなってしまったら、 |
|
253 |
もちろん空文字列を返して構いません。 (<code class="perl">undef</code> |
<p>$B$3$N(B code $B$r;H$C$?%9%/%j%W%H$OFbIt=hM}$rF|K\8l(B EUC |
254 |
よりも空文字列の方が望ましいでしょう。)</p> |
$B$G9T$&$H2>Dj$7$F$$$^$9!#$G$9$+$i!"(B <code class="perl">DECODER</code> |
255 |
|
$B$GF|K\8l(B EUC $B$KJQ49$7$^$9!#(B</p> |
256 |
<p>さて、上記の例では「<code>*default</code>」の EN/DECODER |
<p>$B$^$?!"F|K\8l%a%C%;!<%8$G$O(B <code>ISO-2022-JP</code> |
257 |
を指定しましたが、ここには代わりに charset 名を指定出来ます。</p> |
$B$r;H$&$N$,47=,$G$9$+$i!"(B <code class="perl">ENCODER</code> |
258 |
|
$B$G$O(B 7$B%S%C%H(B JIS $B$KJQ49$7$F$$$^$9!#(B</p> |
259 |
<pre class="perl example"> |
<p>$B=hM}$r9T$&4X?t$O!"0z?t$,(B2$B$D0J>eM?$($i$l$^$9!#(B |
260 |
$Message::MIME::Charset::DECODER{'iso-2022-jp'} = sub {jcode::euc ($_[1], 'jis')}; |
1$B$DL\$N0z?t$O8F$S=P$7$?(B class module, $B$$$o$f$k(B |
261 |
</pre> |
<code class="perl">$self</code> $B$G$9!#(B($B$3$N>l9g(B self $B$G$O$"$j$^$;$s$,(B:-) |
262 |
|
$B$G$bIaDL$OI,MW$J$$$G$7$g$&!#(B</p> |
263 |
<p>ここでは、 <code>ISO-2022-JP</code> を内部コードに変換する |
<p>2$B$DL\$N0z?t$O=hM}BP>]$NJ8;zNs$G$9!#(B</p> |
264 |
方法を定義しています。 charset 名 (および「<code>*default</code>」 |
<p>3$B$DL\0J9_$N0z?t$O!"DI2C%*%W%7%g%s$N%O%C%7%e$G$9!#(B |
265 |
は必ず小文字で書いて下さい!)</p> |
$B$?$@$7!"8=:_DI2C%*%W%7%g%s$ODj5A$5$l$F$$$^$;$s!#(B</p> |
266 |
<p>MIME body や、 encoded-word, RFC 2231 の拡張パラメーター値 |
<p>$B4X?t$,JV$9CM$O(B($B:#$N$H$3$m(B)$B0l$D$@$1$G$9!#(B |
267 |
など、 charset が指定されている時はその charset 名の変換関数が |
$B=hM}$,=*$o$C$?J8;zNs$G$9!#JQ497k2L$H$7$F2?$b$J$/$J$C$F$7$^$C$?$i!"(B |
268 |
呼び出されます。 (指定された charset 名の変換関数が未定義の時は、 |
$B$b$A$m$s6uJ8;zNs$rJV$7$F9=$$$^$;$s!#(B (<code class="perl">undef</code> |
269 |
何も処理しません。) これ以外の場面では、 <code>*default</code> |
$B$h$j$b6uJ8;zNs$NJ}$,K>$^$7$$$G$7$g$&!#(B)</p> |
270 |
で定義された関数が使われます。</p> |
|
271 |
|
<p>$B$5$F!">e5-$NNc$G$O!V(B<code>*default</code>$B!W$N(B EN/DECODER |
272 |
<p>最後に、日本語メッセージを扱う際の例を挙げておきます。</p> |
$B$r;XDj$7$^$7$?$,!"$3$3$K$OBe$o$j$K(B charset $BL>$r;XDj=PMh$^$9!#(B</p> |
273 |
|
|
274 |
<pre class="example perl"> |
<pre class="perl example"> |
275 |
<span class="comment">## jcode.pl を使用</span> |
$Message::MIME::Charset::DECODER{'iso-2022-jp'} = sub {jcode::euc ($_[1], 'jis')}; |
276 |
require 'jcode.pl'; |
</pre> |
277 |
require Message::MIME::Charset; |
|
278 |
$Message::MIME::Charset::DECODER{'*default'} = sub {jcode::euc ($_[1])}; |
<p>$B$3$3$G$O!"(B <code>ISO-2022-JP</code> $B$rFbIt%3!<%I$KJQ49$9$k(B |
279 |
$Message::MIME::Charset::DECODER{'iso-2022-jp'} = sub {jcode::euc ($_[1], 'jis')}; |
$BJ}K!$rDj5A$7$F$$$^$9!#(B charset $BL>(B ($B$*$h$S!V(B<code>*default</code>$B!W(B |
280 |
$Message::MIME::Charset::DECODER{'euc-jp'} = sub {$_[1]}; |
$B$OI,$:>.J8;z$G=q$$$F2<$5$$(B!)</p> |
281 |
$Message::MIME::Charset::DECODER{'shift_jis'} = sub {jcode::euc ($_[1], 'sjis')}; |
<p>MIME body $B$d!"(B encoded-word, RFC 2231 $B$N3HD%%Q%i%a!<%?!<CM(B |
282 |
$Message::MIME::Charset::ENCODER{'*default'} = sub { |
$B$J$I!"(B charset $B$,;XDj$5$l$F$$$k;~$O$=$N(B charset $BL>$NJQ494X?t$,(B |
283 |
my $s = $_[1]; |
$B8F$S=P$5$l$^$9!#(B ($B;XDj$5$l$?(B charset $BL>$NJQ494X?t$,L$Dj5A$N;~$O!"(B |
284 |
<span class="comment">## 正規化</span> |
$B2?$b=hM}$7$^$;$s!#(B) $B$3$l0J30$N>lLL$G$O!"(B <code>*default</code> |
285 |
jcode::tr(\$s, |
$B$GDj5A$5$l$?4X?t$,;H$o$l$^$9!#(B</p> |
286 |
"\xa3\xb0-\xa3\xb9\xa3\xc1-\xa3\xda\xa3\xe1-\xa3\xfa\xa1\xf5". |
|
287 |
"\xa1\xa4\xa1\xa5\xa1\xa7\xa1\xa8\xa1\xa9\xa1\xaa\xa1\xae". |
<!-- |
288 |
"\xa1\xb0\xa1\xb2\xa1\xbf\xa1\xc3\xa1\xca\xa1\xcb\xa1\xce". |
<p>$B:G8e$K!"F|K\8l%a%C%;!<%8$r07$&:]$NNc$r5s$2$F$*$-$^$9!#(B</p> |
289 |
"\xa1\xcf\xa1\xd0\xa1\xd1\xa1\xdc\xa1\xf0\xa1\xf3\xa1\xf4". |
|
290 |
"\xa1\xf6\xa1\xf7\xa1\xe1\xa2\xaf\xa2\xb0\xa2\xb2\xa2\xb1". |
<pre class="example perl"> |
291 |
"\xa1\xe4\xa1\xe3\xA1\xC0\xA1\xA1" |
<span class="comment">## jcode.pl $B$r;HMQ(B</span> |
292 |
=> '0-9A-Za-z&,.:;?!`^_/|()[]{}+$%#*@=\'"~-><\\ '); |
require 'jcode.pl'; |
293 |
jcode::jis ($s, 'euc', 'z') |
require Message::MIME::Charset; |
294 |
}; |
$Message::MIME::Charset::DECODER{'*default'} = sub {jcode::euc ($_[1])}; |
295 |
</pre> |
$Message::MIME::Charset::DECODER{'iso-2022-jp'} = sub {jcode::euc ($_[1], 'jis')}; |
296 |
|
$Message::MIME::Charset::DECODER{'euc-jp'} = sub {$_[1]}; |
297 |
<pre class="example perl"> |
$Message::MIME::Charset::DECODER{'shift_jis'} = sub {jcode::euc ($_[1], 'sjis')}; |
298 |
<span class="comment">## Jcode.pm を使用</span> |
$Message::MIME::Charset::ENCODER{'*default'} = sub { |
299 |
use Jcode; |
my $s = $_[1]; |
300 |
require Message::MIME::Charset; |
<span class="comment">## $B@55,2=(B</span> |
301 |
$Message::MIME::Charset::DECODER{'*default'} = sub {jcode::euc ($_[1])}; |
jcode::tr(\$s, |
302 |
$Message::MIME::Charset::DECODER{'iso-2022-jp'} = sub {Jcode->new ($_[1], 'jis')->euc}; |
"\xa3\xb0-\xa3\xb9\xa3\xc1-\xa3\xda\xa3\xe1-\xa3\xfa\xa1\xf5". |
303 |
$Message::MIME::Charset::DECODER{'euc-jp'} = sub {$_[1]}; |
"\xa1\xa4\xa1\xa5\xa1\xa7\xa1\xa8\xa1\xa9\xa1\xaa\xa1\xae". |
304 |
$Message::MIME::Charset::DECODER{'shift_jis'} = sub {Jcode->new ($_[1], 'sjis')->euc}; |
"\xa1\xb0\xa1\xb2\xa1\xbf\xa1\xc3\xa1\xca\xa1\xcb\xa1\xce". |
305 |
$Message::MIME::Charset::DECODER{'utf-8'} = sub {Jcode->new ($_[1], 'utf8')->euc}; |
"\xa1\xcf\xa1\xd0\xa1\xd1\xa1\xdc\xa1\xf0\xa1\xf3\xa1\xf4". |
306 |
$Message::MIME::Charset::ENCODER{'*default'} = sub {Jcode->new ($_[1], 'euc')->jis}; |
"\xa1\xf6\xa1\xf7\xa1\xe1\xa2\xaf\xa2\xb0\xa2\xb2\xa2\xb1". |
307 |
$Message::MIME::Charset::ENCODER{'utf-8'} = sub {Jcode->new ($_[1], 'euc')->utf8}; |
"\xa1\xe4\xa1\xe3\xA1\xC0\xA1\xA1" |
308 |
</pre> |
=> '0-9A-Za-z&,.:;?!`^_/|()[]{}+$%#*@=\'"~-><\\ '); |
309 |
|
jcode::jis ($s, 'euc', 'z') |
310 |
<p>Perl 5.8 で Encode モジュールが使えるようになれば、 |
}; |
311 |
もっと楽になると期待しています。</p> |
</pre> |
312 |
|
|
313 |
<div class="navigation"> |
<pre class="example perl"> |
314 |
[<a href="/" title="このサーバーの首頁">/</a> |
<span class="comment">## Jcode.pm $B$r;HMQ(B</span> |
315 |
<a href="/map" title="このサーバーの案内" rel="index">地図</a> |
use Jcode; |
316 |
<a href="/search/" title="このサーバーの検索">検索</a>] |
require Message::MIME::Charset; |
317 |
<a href="http://validator.w3.org/check/referer" xml:lang="en"><img |
$Message::MIME::Charset::DECODER{'*default'} = sub {jcode::euc ($_[1])}; |
318 |
src="http://www.w3.org/Icons/valid-xhtml11" id="w3c-html" |
$Message::MIME::Charset::DECODER{'iso-2022-jp'} = sub {Jcode->new ($_[1], 'jis')->euc}; |
319 |
alt="Valid XHTML 1.1!" style="height: 31px; width: 88px" /></a> |
$Message::MIME::Charset::DECODER{'euc-jp'} = sub {$_[1]}; |
320 |
<a href="http://jigsaw.w3.org/css-validator/validator?uri=http://suika.fam.cx/~wakaba/Message-pm/introduction.ja.html" xml:lang="en"> |
$Message::MIME::Charset::DECODER{'shift_jis'} = sub {Jcode->new ($_[1], 'sjis')->euc}; |
321 |
<img style="width: 88px; height: 31px" id="w3c-css" |
$Message::MIME::Charset::DECODER{'utf-8'} = sub {Jcode->new ($_[1], 'utf8')->euc}; |
322 |
src="http://jigsaw.w3.org/css-validator/images/vcss" |
$Message::MIME::Charset::ENCODER{'*default'} = sub {Jcode->new ($_[1], 'euc')->jis}; |
323 |
alt="Valid CSS!" /></a> |
$Message::MIME::Charset::ENCODER{'utf-8'} = sub {Jcode->new ($_[1], 'euc')->utf8}; |
324 |
</div> |
</pre> |
325 |
<div class="update">$Date$</div> |
--> |
326 |
<ul class="myuri"> |
|
327 |
<li><URL:<a href="http://suika.fam.cx/~wakaba/Message-pm/introduction">http://suika.fam.cx/~wakaba/Message-pm/introduction</a>></li> |
<p id="code-easy">$B$d$d$3$7$$@bL@$r$7$F$-$^$7$?$,!"<B:]LLE]$J$N$G!"F|K\8lJ8;z%3!<%IJQ49$KNI$/;H$o$l$k!"(B |
328 |
<li><CVS:<a href="http://suika.fam.cx/gate/cvs/perl/web/Message-pm/">suika.fam.cx:/home/cvs/perl/web/Message-pm/</a>></li> |
jcode.pl $B$d(B Jcode.pm $B$J$I$N$?$a$N@_Dj$OM=$aMQ0U$7$F$"$j$^$9!#(B</p> |
329 |
</ul> |
|
330 |
</body></html> |
<pre class="example perl"> |
331 |
|
<span class="comment">## $B$I$A$i$+9%$-$JJ}$r$I$&$>!#(B</span> |
332 |
|
use Message::MIME::Charset::Jcode 'jcode.pl'; |
333 |
|
use Message::MIME::Charset::Jcode 'Jcode'; |
334 |
|
</pre> |
335 |
|
|
336 |
|
<p>$B$3$N(B1$B9T$@$1$G!"(B ISO-2022-JP, EUC-JP, Shift_JIS |
337 |
|
$B$*$h$S4v$D$+$N4XO"(B charset $B$,MxMQ2DG=$K$J$j$^$9!#(B</p> |
338 |
|
|
339 |
|
<p>Perl 5.8 $B$K$J$C$F(B Encode $B%b%8%e!<%k$,;H$($k$h$&$K$J$l$P!"(B |
340 |
|
$B$b$C$H?'!9$JJ8;z%3!<%I$,3Z$KMxMQ$G$-$k$h$&$K$J$k$H4|BT$7$F$$$^$9!#(B</p> |
341 |
|
|
342 |
|
<p>$B$H$3$m$G!"$3$N$h$&$K(B charset $BBP1~=hM}$r$7$J$/$F$b!"(B |
343 |
|
MIME $B$G(B charset $B;%IU$1$5$l$F%a%C%;!<%8$K4^$a$i$l$F$$$kL$CN$N(B |
344 |
|
charset $B$N%G!<%?$,GK2u$5$l$k$3$H$O$"$j$^$;$s!#(B ($B$O$:$G$9!#(B) |
345 |
|
($B$=$3$$$i$,!"(B Unicoder $B$N%=%U%H%&%'%"$H$N0c$$$G$9(B($B>P(B)$B!#(B)</p> |
346 |
|
|
347 |
|
<div class="navigation"> |
348 |
|
[<a href="/" title="$B$3$N%5!<%P!<$N<sJG(B">/</a> |
349 |
|
<a href="/map" title="$B$3$N%5!<%P!<$N0FFb(B" rel="index">$BCO?^(B</a> |
350 |
|
<a href="/search/" title="$B$3$N%5!<%P!<$N8!:w(B">$B8!:w(B</a>] |
351 |
|
<a href="http://validator.w3.org/check/referer" xml:lang="en"><img |
352 |
|
src="http://www.w3.org/Icons/valid-xhtml11" id="w3c-html" |
353 |
|
alt="Valid XHTML 1.1!" style="height: 31px; width: 88px" /></a> |
354 |
|
<a href="http://jigsaw.w3.org/css-validator/validator?uri=http://suika.fam.cx/~wakaba/Message-pm/introduction.ja.html" xml:lang="en"> |
355 |
|
<img style="width: 88px; height: 31px" id="w3c-css" |
356 |
|
src="http://jigsaw.w3.org/css-validator/images/vcss" |
357 |
|
alt="Valid CSS!" /></a> |
358 |
|
</div> |
359 |
|
<div class="update">$Date$</div> |
360 |
|
<ul class="myuri"> |
361 |
|
<li><URL:<a href="http://suika.fam.cx/~wakaba/Message-pm/introduction">http://suika.fam.cx/~wakaba/Message-pm/introduction</a>></li> |
362 |
|
<li><CVS:<a href="http://suika.fam.cx/gate/cvs/perl/web/Message-pm/">suika.fam.cx:/home/cvs/perl/web/Message-pm/</a>></li> |
363 |
|
</ul> |
364 |
|
</body></html> |