lib/convert_html.phpをいじる
新しい、複雑な書式を追加したいときはここをいじる必要があるが、他のpukiwikiソースと比べてもかなりとっつきにくいように思う。
自分の欲しい機能をどうやれば追加出来るかを解説する。
インライン要素を子に持つ時
あまりブロック要素を子にもつタグはそもそも多くない。そこでインライン要素を子にもつものだけを紹介しておく。
構造
ほとんどすべての、このファイルに含まれるクラスはElementから拡張されている(エレメントを継承している)。エレメントの構造や機能の概要は次のようなものだ。
- $elements:自分の子エレメントの配列。HTMLを展開するような、ネスト構造をつくる。
- $last:$elementsの最後のものに一致する。DOMでいえばLastChildとかそんなやつ。
- $parent:親インスタンス。setParent()で変更する。
- add():与えられたオブジェクトが自分に従属できれば従属させ、出来なければ次の要素にする。線形処理
- insert():与えられたオブジェクトを自分にマージする。
- toString():自分の持つデータを吐き出す。これはオーバーライドし、それぞれのやり方で吐き出したり、再帰的に子のデータを返したりして使われるようだ。
- wrap():タグで中身を包む。ほとんど機能関数。
- canContain():自分が何を子要素にするかを指定する。ElementではTRUEだが、一般的には
return is_a($obj,'Inline');
のように書く。
convert_html.phpの最後の方にBodyクラスがあるが、ここがすべての処理の流れを作っている。
自分で機能を追加したいときは、ここの$classesに追記するのが一般的になるだろう。$classesでは連想配列で'対象文字' => 'クラス名'
を管理する。$factoriesも同じに見えるが、こちらはfunction & Factory_Div(& $root, $text)という関数が呼ばれるところが異なる。
それぞれ呼び出し部は次の部分である。if (isset($this->classes[$head])) { ... } if (isset($this->factories[$head])) { ... }
作ってみる
以上の知識を使ってインライン子要素をもつ構文が作れる。次のようなものはどうだろうか。
class New extends Element { function New(& $root, $text) { parent::Element(); parent::insert( new Inline(substr($text,1)) );//erase the letter for calling. ex.'%' } function canContain(& $obj) { return is_a($obj, 'Inline'); } function & insert(& $obj) { $this->elements[] = $obj->elements[0]; return $this; } function toString() { return $this->wrap(parent::toString(), 'div', ' class="new"'); } }
あまり良いシステムの利用の仕方でない気がすこしするが、動く。このソースは自由に利用して欲しい。もし不具合を引き起こす恐れがある部分があったら、修正してください。