1番、おや? と思うところは、各タグ(PやBODY)に関する処理の
実装がBlockに含まれている点です。以降、サポートするタグを増やす
ごとにBlockが肥大していくことになり、メンテも大変です。
各subClassが、自分で取り込める部分のみとりだすparseをサポートし、
それを元に戻す(?)部分のみのtoTextを提供してつくりになるのでは
ないかとおもうのですが・・・(自分のことは自分が知っている)
基底クラスのparse/toTextは、自分の持つツリーのparse/toTextを
順に呼び出すだけ みたいな。
# 結果として、parse結果はBaseClassがBlockのツリー構造になる・・
# と思う。
# どのメールアドレスで登録してあったかがわからない・・・・これかな?
----- Original Message -----
>Date: Thu, 06 Jul 2006 00:03:23 +0900 (JST)
>From: 閑舎 <raku@...>
>Subject: [TSfree:1651] HTML 変換器を PHP
> で作ると
>To: TSfree@...
>
>
>皆さん、こんにちは。
>
>最近 PHP でクラスを使うのに慣れたいと思っていろいろやっている私です。
>
>例えば、以下のコードは、改行が連続すると段落 p が始まるととらえ(他のタグ
>はないと仮定する単純な解析器)、
>
> ab
> c
>
> def
>
>という文字列を、
>
> <p>ab
> c</p>
> <p>def</p>
>
>というようにタグ付けしてくれるものです。
>
>Block というクラスには、解析を受け持つ parse とタグ化を受け持つ toText
>メソッドがあり、これを拡張(extends)した Body, P というクラスにも受け継が
>れています。
>
>$body = new Body(0) は $body = new Block("body", 0) と同じものなので、こ
>の場合、Body, P クラスを作るのはある意味資源の浪費なのですが、まあ、もう
>少しいろいろ作っていくとたぶん役に立つだろうということです(^^;。
>
>こうしてできた PHP のコードを、Perl とか、ruby とか、Python とかで書くと
>一体どんな感じになるのでしょう? 私はこうしたオブジェクト指向の表現にあ
>まり慣れていないので、純粋に知りたいです。
>
><?php
>$line = "\n\nab\nc\n\ndef";
>$length = strlen($line);
>$pt = 0; // $line の処理中のポインタ
>
>$body = new Body(0); // $body = new Block("body", 0); と等価
>$body->parse(); // 解析し next を作る
>$body->toText(); // html出力
>
>class Block {
> function Block($name, $start) { // Block クラスの初期化
> list($this->name, $this->next, $this->start, $this->len) = array($name, n
ull, $start, 0);
> }
> function parse() {
> global $line, $length, $pt;
> if (preg_match("/\n\n+/", $line, $matches ,PREG_OFFSET_CAPTURE, $pt)) {
> $this->len = $matches[0][1] - $this->start;
> $pt = $matches[0][1] + strlen($matches[0][0]);
> $this->next = new Block("p", $pt);
> $this->next->parse();
> } else if ($this->name != "body") {
> $this->len = $length - $this->start;
> $this->next = new Block("body", $length);
> }
> }
> function toText() {
> global $line;
> if ($this->name != "body") echo "<" . $this->name . ">";
> echo substr($line, $this->start, $this->len);
> if ($this->name != "body") echo "</" . $this->name . ">\n";
> if ($this->next != null) $this->next->totext();
> }
>}
>class Body extends Block {
> function Body($start) {
> parent::Block("body", $start);
> }
>}
>class P extends Block {
> function P($start) {
> parent::Block("p", $start);
> }
>}
>?>
>
>--
>本田博通(閑舎)
>テキストとスクリプトの http://www.rakunet.org/TSNET/
>