メイドめーるでは日本語のメールを送信するために、
ヽ( ・∀・)ノくまくまー(07-31[長年日記])で書いていただいている、Iso2022jpMailerを使っています。
クラスを継承するだけでつかえるとてもいいアイデアだったのですが、たった一つ問題が。
「~」が文字化けするのです。普通のアプリケーションだったら、まあ横棒でいいか、とか言えるし、実際メイドめーるも今日までそうやってごまかしてきたのですけど。萌え萌えなメイドさんがメールをくれるアプリケーションにおいて「~」がつかえないと言うことは、「おはようございます~」がつかえないことになってしまいます。
「おはようございますー」と「おはようございます~」は断じて違うのです!
とまあそんなわけで、技術的に追求した結果、一応「~」が出せるようになりましたのでご報告です。
やり方としては、Iso2022jpMailer の
@mail.body = NKF::nkf('-j', @mail.body)
の部分を
@mail.body = NKF::nkf('-Wxm0 --oc=ISO-2022-JP-1', @mail.body)
に置き換えます。
ついでに、タイトルとかに「~」がはいることもあるだろうから、
text = NKF.nkf('-j -m0', text)
も、
text = NKF.nkf('-Wxm0 --oc=ISO-2022-JP-1', text)
にしちゃいました。
技術的な話
正直に言うと、なんでこれで化けないのか、最終的な理由は理解できていません。
ただ、あれこれやっているうちに、化ける時と化けない時があって、比較するとこうなっていることが分りました。
上がうまくいく場合で、下が駄目な場合です。日本語メールなのでJISコードでエンコードしてあります。
OKな時は1B 24 42で始まっていて、駄目な時は1B 24 48で始まる…、つまり、JIS X 0208-1983でエンコードしてあればOKで、JIS X 0212-1990だと駄目なことが分ります。
NKFのコマンド詳細を見ながら、irbでいろいろやってみると。
>> NKF::nkf('-jWxm0', "~").each_byte{|b| print b.to_s(16)+","};print "\n" 1b,24,28,44,22,37,1b,28,42, => nil >>NKF::nkf('-Wxm0 --oc=ISO-2022-JP', "~").each_byte{|b| print b.to_s(16)+","};print "\n" 1b,24,28,44,22,37,1b,28,42, => nil >> NKF::nkf('-Wxm0 --oc=ISO-2022-JP-1', "~").each_byte{|b| print b.to_s(16)+","};print "\n" 1b,24,42,21,41,1b,28,42, => nil >> NKF::nkf('-Wxm0 --oc=ISO-2022-JP-3', "~").each_byte{|b| print b.to_s(16)+","};print "\n" 1b,24,28,50,28,37,1b,28,42, => nil
–oc=ISO-2022-JP-1の時だけ、ねらい通りの変換をしてくれるようです。ということで、Iso2022jpMailerにも、同じ引数を渡してあげると、「~」が出るようになった次第。
「ISO-2022-JP-1」って、JIS X 0212に対応させるための引数で。むしろ逆のような気がするし、なんでISO-2022-JP-3で駄目なのかも謎です。