プログラムを書いた後一定期間が経過すると、一体どうしてこんなコードを書いたかが分からなくなってしまう。私の場合、自分で書いているにも関わらず「1ヶ月後は他人のプログラム」になっている。Perl のプログラムは特に分からなくなりやすい。そこで、何をやっているかをメモしておくことにした。実際に書いていくうちにバグ (というより制限事項) も見つかった。
■ ■ ■
pre 要素内の改行に関するアイデア (nlog(n): pre 要素を自動改行させたい) をもとに,実装したプラグイン(nlog(n): PRE 要素変換プラグイン 0.9) の動作について解説する。メインのルーチンでは、ウェブログの本文の受け渡しとサブルーチンの呼び出しを行う。
sub CPreConv {
...
$out =~ s/(<pre>.*?<\/pre>)/sp2amp($1)/eigs;
...
}
$out には、ウェブログの本文が丸ごと入ってくるようになっている。 この1行の意味は次の通り。
- 「.*?」は、一番近い <pre>...</pre> の組を探す。
- /s 装飾子により、<pre> と </pre> の間に改行が入っていてもマッチする。
- /i 装飾子により、大文字小文字を区別しないで、<PRE> や <Pre> などにもマッチする。
- /g 装飾子により、本文中に複数の <pre>...</pre> の組があっても1つ1つマッチする。
- /e 装飾子により、「sp2amp($1)」を文字列ではなく式として評価する。 すなわち、sp2amp($1) の結果が入ることになる。 「e」は「evalulate」の意味。
「/e」という修飾子を初めて使った。強力過ぎて驚いた。
sp2amp サブルーチンには、<pre> で始まり、</pre> で終わる数行が「@_」にセットされて渡される。
sub sp2amp {
my $code = shift(@_);
$code =~ s|<pre>||i;
$code =~ s|</pre>||i;
$code =~ s|^\n||s;
$code =~ s|(.*?)\t|$1 . (' ' x (8 - length($1) % 8))|eg;
$code =~ s| | |g;
$code =~ s|^ | |mg;
$code =~ s|\n|<br />\n|sg;
$code = q|<div class="precode">| . $code . q|</div>|;
$code;
}
サブルーチン内では、終了タグで使う「/」が頻発するので、 置換のための区切りとして「|」を使うことにする。 「|」を使うと、文字としての「/」をエスケープする必要がなくなり、コードが少しだけ読みやすくなる。
-
my $code = shift(@_);
「@_」に配列として渡される <pre>...</pre> の数行を $code 変数に丸ごと代入する。 「my ($code) = @_;」としてもよいかも知れない。 しかし、「my $code = @_;」としてはいけない。 こうすると、$code には配列の要素数である「1」が代入されてしまう。 「1行」の文字列として渡されているため、要素数は「1」になる。
-
$code =~ s|<pre>||i;
$code =~ s|</pre>||i;
最初の <pre> と最後の </pre> を大文字小文字を区別しないで削除する。
-
$code =~ s|^\n||s;
一番最初に改行のみの行がある場合に、その1行だけを削除する。
-
$code =~ s|(.*?)\t|$1 . (' ' x (8 - length($1) % 8))|eg;
タブ文字を8個のスペースに変換する。 「スペース3個にタブ1個が連続」している場合も8個のスペースにする(11個のスペースではなく)。 length() 関数はスペースも1文字として数えてくれる。
-
$code =~ s| | |g;
連続した2つのスペースを「スペース1個と 」に変換する。
-
$code =~ s|^ | |mg;
行頭にスペースがある場合は、「 」に変換する。 /m 修飾子により、複数行として扱うようになるので、各行の行頭にマッチすることになる。
-
$code =~ s|\n|<br />\n|sg;
行末の改行文字を「<br />」タグに変換する。 変換後も読みやすくするために、さらに改行文字を追加している。
-
$code = q|<div class="precode">| . $code . q|</div>|;
最後の手順として、前後に <div>, </div> タグを追加する。
詳細を書いていて、考えに入れていなかった書式があることに気がついた。 pre 要素の中に、強調などのタグが入っていることを考慮していない。 現時点でのバグは以下の通り。
- タグの後ろにタブ文字があると、スペースの数が正しくなくなる
- タグの中にスペースが2つ以上連続していると、スペースが「 」に変換されてしまう
つまり,pre 要素内にタグを書かなければ問題は発生しない。タグを書いた場合でも,連続してスペースを書かなければ大きな問題にはならない。
Posted by n at 2004-10-28 23:15 | Edit | Comments (0) | Trackback(0)