波線(波ダッシュ)の文字化けが解決!
以前書いた「コメント欄での文字化けについて」 (2006/04/24 22:11)の記事で、今使っているブログシステム「blosxom」の「writeback」プラグインにおいてコメント投稿時に記号「~(波線or波ダッシュ)」の文字化けが起こることを書いた。で、しばらくこの問題は放置してコメント投稿欄に注意書きをするに留めていた。(利用者には不便をかけました。申し訳ない…)
で、今日やっと試行錯誤を繰り返してこの問題を解決することができたので、ここにメモをしておく。結構うちのサイトに「波線」などの検索語で訪問してくる方が多いので、参考になれば幸い。
1. まず問題点と解決方法の概略
Jcodeを使った日本語変換に問題があったもよう。bsk同梱のwritebackプラグイン(おそらくKyo Nagashimaさんのアレンジ版)は日本語のエンコードとしてJcodeを使っている。
問題の中身は検証していないが、これをEncodeモジュール(Perl5.8以降で標準装備)を使って文字データを読み込み時にデコード、出力時にエンコード処理することで解決した。
2. blosxom以外でも
おそらくこの問題が起こっているのはblosxomに限らないと思う。Perlを使って文字処理をしているならば、同じようにEncodeモジュールを利用してPerlの内部バイト列に変換してから文字をゴニョゴニョ処理すれば、どうにかなるのでは。
3. 参考書籍
Impress社の「まるごとPerl!」という本の中の、小飼弾さんの記事「まるごとEncode」が参考になった。ちなみに小飼弾さんはEncodeモジュールの作者、管理者。
この「まるごとPerl!」という本はちょっと高いけど読み応えがあって良かった。弾さんもブログで告知しているので気になる人は参照してください。
4. やったことのまとめ(@blosxom, writebackプラグイン)
自分でプラグインをちょこちょこいじっていたため、行数は自分のファイルと元のものとでずれていると思うので示しません。分かりにくい書き方になってしまうけど許してください(><)
(1) Jcodeを利用する部分の除去
具体的には以下の部分。(多分ここは原文のまま)
if ($conv_charset) { require Jcode; $temp = Jcode->new(\$temp)->$charset(); }
以上の部分をコメントアウトした。
(2) 入力部分でPerl内部バイト列(←用語適当)にデコード
bskのwritebackプラグインで、postされたパラメータを読む部分「my $p = &sanitize(param($_));」に対して、右辺(代入値)をさらにEncode::decodeさせた。
my $p = Encode::decode($charset, &sanitize(param($_)));- ここはsanitizeを先にやるべきなのだろうか??
- あとデコード元も$charsetで良いのか自信がない。Guessにすべき??
(3) 出力部分で再度エンコード
開いてあったファイルハンドル ($fh) にバッファを追加出力する部分「print $fh $temp;」で再度Encode::encodeさせた。
print $fh Encode::encode($charset, $temp);
5. あとがき?
- 言うまでもないけど、プログラム(プラグイン)の冒頭で必ず「
use Encode;」をしておいてください。(←自分が忘れてたorz) - 参考書籍に挙げた「まるごとPerl!」の記述どおりにencodeやdecodeのサブルーチンを使おうとしたらエラーになった。これらのサブルーチンはやはりEncode::encode, Encode::decodeとして使うのが正解らしい。
- 「まるごとPerl!」の記述は誤植なの?よく分からない(><)
- あープラグイン内でwritebackパッケージを定義してたから、それがデフォルトになっちゃってたのかなぁ?
- そういえば「use Encode qw/encode decode/;」みたいに関数を指定してインポートすればそのまま使えるんだったっけ…?
- 訂正や、より良い対策方法など歓迎します。コメントやトラックバックでどうぞ。
(当ブログ "web :: programming" カテゴリ 内の記事です)
というわけで、テスト書き込み~~~!
名前: shunkoh posted at 2006/09/09 (Sat) 21:47:31