2007年10月20日 (土)

PerlのNKFモジュール(NKF.pm)のつたない解説

初めてのPerl
初めてのPerl
posted with amazlet at 08.10.11
ランダル・L. シュワルツ トム フェニックス
オライリージャパン
売り上げランキング: 2957
おすすめ度の平均: 4.5
5 素晴らしきPerlの世界への案内
5 読み物としても十分面白い
5 定番書
5 初心者も持っておきたい一冊
5 CGI言語としてのPerl


今日は珍しくお仕事系の話。
先日メール関連処理のために使ったPerlのNKFモジュールが非常に使い勝手が良かったので、ご紹介です。
僕と同様、Perl付属のEncodeライブラリに四苦八苦している方は参考になると思いますよ。


NKF.pmについて
NKF.pmは文字コード変換プログラム nkf のPerlモジュール版です。
往年のPCユーザは「nkf」と聞くと懐かしく感じるのでは。
unix系マシンとWindowsマシンでテキストファイルをやり取りしたりする上では必須のアプリでしたよね。

このnkf、地道にバージョンアップを続けていて、この記事を書いている時点での最新版は「Ver2.0.8b」です(安定板は2.0.7)。nkfは知らないうちに非常に便利なオプションが追加されていて、これ1つでメール周りの処理を簡単に行うことができるようになっています。
また、同時にPerlモジュール版もバージョンアップを続けていて、nkfの便利な機能をPerlのプログラム内で簡単に利用できるようになっています。


なぜNKF.pmか?
Perlの文字コード変換関連には様々なモジュールがあります。
Perl標準のEncodeライブラリのほか、Jcode や jcode.pl(最近は使わないかな)などなど。
ですが、その中でNKFを選んだ理由は下記です。

・必要な十分な機能
文字コード変換(utf8、半角カナ変換対応)、MIMEエンコード/デコード、マッピング不可文字の変換(「〓」で表現)など、Perlで日本語を扱うときに必要そうな機能はたいてい入ってます。
これらがモジュール1つで賄えるところが便利。

・バイナリ版nkfとの親和性
基本的な使い方は $result = nkf("オプション",$source) という感じ。で、オプションの指定のしかたはバイナリ版のnkfと共通です。
なので、昔からnkfを使っている人にとってはわかりやすいです。

・見通しがいい
Perl標準のEncodeライブラリは非常に強力なのですが、「utf8フラグ」などの概念を理解しないと難しいです。僕もひととおりは勉強したつもり…なのですが、いまだにencodeを2回呼んでしまっておかしくなったりというミスが多いです。
# もちろん僕の技術力によるところが大きいんですけどね。
NKFモジュールはutf8フラグなどを気にしなくていいので、ミスしにくいというところがいいと思います。


利用前の準備(宣言)
まずは準備です。
Perlプログラム内で利用するため、useで宣言しましょう。

use NKF;

はい準備完了。簡単ですね。
おっと、インストールはこれ以前に済ませて置いてくださいね。
マニュアルどおりやれば問題ないはずです。


主な使い方
主な使い方は下記のような感じ。
サンプルを見たほうが早いですよね。

■$input の文字列をShift-jisに変換
基本的に入力文字列の文字コードは自動判別するので、変換したい先の文字コードのみをオプションで指定します。

$output = nkf("-s",$input);

これで $output に $input をShift-jisに変換した文字列が入ります。

■ヘッダのMIMEエンコード、デコード
メール内の日本語のヘッダ(FromやSubjectなど)はMIMEでエンコードする必要がありますが、NKFモジュールを使うとエンコード後文字列の行分割までひっくるめてちゃんと処理してくれます。

(1)エンコード

$subject = nkf("-M","【転送】ガジェットWatchでこんな記事見つけました");

これで$subjectにMIMEエンコードされた文字列が入ります。

(2)デコード

$subject_decoded = nkf("-m",$subject);

MIMEエンコードされた $subject をデコードし、普通の日本語として $subject_decoded に格納します。同時に出力文字コードの指定も可能なので、いきなりEUCにすることもできます。
(単純にデコードしただけだとJISになりますよね。)

■$input の文字コードの推定
文字コードの推定をする場合はバイナリ版nkfとちょっとやり方が違います。
一旦nkfモジュールをその文字に対して適用したあとで、「inputcode()」関数を使います。

nkf("",$input);
print inputcode(); # 「EUC-JP」「ASCII」などの文字列を表示

inputcode()関数で、最後に評価した文字列の推定文字コードを取得できます。

■$input に含まれる「まずそうな文字」をつぶした上でEUC変換
ケータイの絵文字など、JISで表現できない文字を「〓」に変換します。
当然その部分は読めなくなりますが、変なコードと認識して誤動作しちゃう~という最悪の状態は避けられます。

$output = nkf("-Ie",$input);

「〓」に変換するのが「-I」、EUCで出力するのが「-e」オプションです。
オプションは上記のように重ねて「-Ie」などと書くことができます。


まとめ
このほかにもNKF2.0.7ではバイナリデータもMIMEストリームに変換できる( = 添付ファイルが簡単に作れる)など、便利な機能が増えています。
本当にちゃんとしたメール処理を行うならMIME::Entityなどを利用することになると思いますが、そこまでの機能が不要で簡単に書くならNKF.pmモジュールは非常に見通しがいいと思います。

Perl5.6以降の日本語関連で困っている方がいればぜひご参考に。
あ、一応正しいつもりで書いていますが、上記コードが間違っていたらぜひともご指摘ください。


関連サイト
Project Info - nkf Network Kanji Filter (SourceForge)
現在のnkfプロジェクトです。
ソースのダウンロードやマニュアルの取得はここから。

| | コメント (0) | トラックバック (0)

2007年5月18日 (金)

JavaScriptでHTMLを出力するときの小技(ヘッダメニューの続き)

HTML Source image

以前の記事で、ココログのヘッダ部分にメニューを設置した話を書きました。メニュー作成のHTMLを全部JavaScriptで記述し、外部ファイルに追い出してしまうことで、内容が変わっても「ブログへの反映」が必要なくなるというアイディアです。
ただ、このやりかただとJavaScriptが「document.write()」の嵐になってしまいますので、多少エレガントな方法を考えてみました。
# タイトル画像は特に記事に関係あるわけじゃないです(^-^;)。

基礎知識
JavaScriptファイルの中で行末に「\」を書くと、そのあとの改行が抑制され、「次の行もつながってるんだよ」という意味になります。
前回の例ではHTMLを1行書くたびに「document.write()」を使ってましたが、「\」を使うともう少し簡単に書けるみたいです。

具体例
今までの例と改善後の例を見てみます。

(1)今までの例

document.write('<hr>');
document.write('<a href="xxxx.html"><br>');
document.write('<img alt="test" src="xxxx.jpg">');
document.write('<hr>');

(2)改善例

document.write(' \
<hr> \
<a href="xxxx.html"><br> \
<img alt="test" src="xxxx.jpg"> \
<hr> \
');

必ず行末に「\」をつけなきゃならないですが、それでもこっちのほうが幾分スマートですよね。
ご参考になれば。

まとめ
本当はJavaScriptにもPerlなどのような「ヒアドキュメント」があればよいのですが、現状は実装されていませんので、上記のようなやりかたになるのかな~という感じ。
中にはJavaScriptの関数で擬似的にヒアドキュメントを実装しちゃったような方もいますが、今回の話はそこまでやるほどのことじゃないですしね。
もっと大量のHTMLをJavaScript上から吐き出す必要がでてきたら、擬似ヒアドキュメントライブラリも使ってみたいと思います。

関連サイト
JavaScript用ヒアドキュメントライブラリを試作 (風柳亭 - 別館:書庫のある庵様)
出力するHTMLが増えたらこれですね。
ブログパーツなど、結構な量のHTMLを吐き出す必要があるときに使えそう。

2007夏モデルFMV新登場

| | コメント (0) | トラックバック (4)

2007年4月24日 (火)

ココログにヘッダメニューを設置する方法

Blogのタイトルと説明が出ている部分にヘッダメニューを設置してみました。
ちょっと無理やりな方法なのですが、ヘッダメニュー以外にもいろいろ応用が利くやりかたです。
ご存知の方も多いと思いますが、ご参考になれば。

前提知識
具体的なやりかたの前にちょっと前提知識を。

ココログではHTMLタグをヘッダやサイドメニューに入れることができます。
ヘッダの場合、入れる場所は「ブログのサブタイトル(キャッチフレーズ)」の部分。
管理画面の「ブログ」→「設定」→「基本設定」のところにあります。

ココログサブタイトル

ここ、普通はテキストのみを書いていると思いますが、HTMLタグをそのまま書くことが可能です。
ここをうまく利用すると、今回のようなメニューを作成したり、標準のスタイルシートを書き換えたり、アクセス解析用のタグを埋め込んだりできるわけです。

ちなみにサイドメニューに入れる場合は「マイリスト」の「リンク」を使い、コメント欄にタグを入れます。
これについてはいろいろなページで解説されているので、探してみてください。

基本設計
さて、サブタイトル欄に直接タグを書いてもいいのですが、そうするとちょっとした変更のたびに「ブログへの反映」が必要になります。
時間もかかる作業ですし、トラブルの可能性もゼロではないので、できればそんな作業は避けたい。

というわけで、今回はサブタイトル欄から一旦外部JavaScriptを呼び出し、そのScript内でHTMLを生成することにしました。(このあたりが「ちょっと無理やり」なところ)。
Scriptは「document.write()」の嵐になってしまうのですが、こうしておけば「コントロールパネル」→「ファイル」でJavaScriptを上書きするだけで、サイト全体へ設定を反映させることが可能です。ここが今回のキモですね。

具体的な設定
(1)JavaScriptを書いてアップロードし、(2)ヘッダから呼び出すという2段階で進めます。

(1)JavaScript
下記のようなファイルをメモ帳などでローカル(あなたのPC)の中に作ります。
ファイル名は何でもいいですが、慣例的に ○○.js とするのが普通です。
ただ、保存するときの文字コードはUTF-8にしてください。
ココログのデフォルト文字コードはUTF-8なので、それ以外の文字コードでスクリプトを記述してしまうと、呼び出されたときに日本語が化けてしまいます。

// ヘッダメニュー
document.write('<div style="margin:15px 0px 0px 0px; width:665px; padding:5px; background:#abb3cd; color:#ffffff; float:left">'); //←色は適当に。
document.write('<a style="color:#ffffff" href="http://gadgetwatch.cocolog-nifty.com/">トップページ</a> | ');
document.write('<a style="color:#ffffff" href="http://gadgetwatch.cocolog-nifty.com/gadgetwatch/archives.html">バックナンバー</a> | ');
// ↑こんな感じでHTMLを出力し、リンクを追加します。
document.write('</div>');
document.write('<div style="clear:both"></div>');

1行目のスタイルで指定している「float:left」と最後のの「clear:both」がポイント。
これがないとFirefox系で表示が崩れます。

保存したら、ファイルをココログへアップロードします。
場所はどこでもいいですが、「common」などのフォルダを作っておくと修正がやりやすいかも。
アップロードしたら一旦ファイルをクリックして、URLを取得しておきましょう。

(2)サブタイトル
サブタイトルの設定はこのスクリプトを呼び出す記述だけです。
設定が終わったら、「ブログへの反映」が1回必要です。

(あなたのココログのサブタイトル)
<script src="ここにJavaScriptファイルのURLを記述" type="text/javascript"></script>

あとは見栄えなどを調整しながら、(1)のファイル修正~アップロードを繰り返せばOK。
多少手間はかかりますが、それでも毎回反映がいらないぶんこちらのほうが楽だと思いますよ。
工夫次第では何でもできるので、お試しください。

関連サイト
メニューをつけてみました (KOROPPYの本棚 様)
まさにココログを「使い倒している(^-^;)」感じです。
メニューもきれいにまとまっていていい感じですよね。

第35回:サブタイトル部分に簡易メニューを付けてみよう (初めてのココログ・カスタマイズ 様)
これがココログでできるんだ~という発見がいっぱいです。

| | コメント (4) | トラックバック (1)