PHP/PukiWiki

Last-modified: 2011-02-27 (日) 20:53:33

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"');
	}
}

あまり良いシステムの利用の仕方でない気がすこしするが、動く。このソースは自由に利用して欲しい。もし不具合を引き起こす恐れがある部分があったら、修正してください。