PEAR::Text_Wikiを試してみた
このサイトで公開している日記やテキストは、Pukiwiki文法で書かれている。
テキストをHTMLに変換する際、これまではお手製の変換プログラムで変換していた。
だが、ちゃんと変換できているか、自信がなかった。
また、メンテナンスも大変だった。
そこで、PEARに公開されている「Text_Wiki」を使ってみることにした。
Text_Wikiを使うに当たって、検索する力が足りないせいか、Text_Wikiについて解説しているサイトが見つからなかった。
なので、Text_Wikiのコードを読んでみることにした。
以下に、コードを読んだ際にまとめたメモを公開する。
インストール
まず、Text_Wikiがインストールされているか確認する。
$ pear list
インストールされていなかったら、Text_Wikiをインストールする。
$ pear install Text_Wiki
例
とりあえず使ってみる。
require_once "Text/Wiki.php"; $wiki = new Text_Wiki(); print $wiki->transform("+ Heading\n\nThis is a test.\nこれはテスト。", "Xhtml");
これでは、日本語が変換できない。
Googleで調べると、transform()を呼ぶ前に以下の一行を入れる必要があることがわかった。
$wiki->setFormatConf("Xhtml", "translate", HTML_SPECIALCHARS);
これで、日本語も変換できた。
動き
最低限動かすためには、Text_Wikiクラスのオブジェクトを生成して、transform()を呼べばよい。
transform()の内部では、parse()とrender()を順番に呼んでいる。
parse()
parse()は、ルールと呼ばれる各規則に従いテキストをパースする。
ルールには、Heading、Url、Wikilinkなどがある。
ルールは、ルールごとにText_Wiki_Parseを継承したクラス(パースクラス)として書かれている。
パースクラスのファイルは、parseディレクトリに配置されており、ファイル名は、ルール名.php(例:Heading.php)である。
また、パースクラスの名前は、Text_Wiki_Parse_ルール名(例:Text_Wiki_Parse_Heading)である。
パースクラスにはクラスの外から設定できる設定値があり、Text_WikiクラスのsetParseConf($rule, $arg1, $arg2)で設定する。
$ruleがルール名、$arg1が設定値名と設定値が格納された配列となる。
$arg1を設定値名、$arg2を設定値にしてもよい。
パースクラスの上の方に、設定できる設定値名とその説明が書いてある。
Text_Wikiクラスのparse()は、Text_Wikiクラスの$rulesで指定されたルールのパースクラスを生成し、各クラスのparse()を呼ぶ。
パースクラスのparse()は、内部でpreg_replace_callback()を呼び、その返り値をText_Wikiクラスの$sourceに格納する。
内部で呼ばれるpreg_replace_callback()の引数は、次の通りである。
まず、第1引数である正規表現のパターンには、パースクラスの$regexが入る。
$regexにマッチさせたい正規表現を記述する。
第2引数のコールバック関数には、パースクラスのprocess(&$matches)が指定されている。
第3引数の正規表現を適用したい文字列には、元のテキスト(Text_Wikiクラスの$source)が入る。
parse()から呼ばれるprocess(&$matches)は、レンダーを行うためのトークンを埋め込んだテキストを返す。
render()
render($format)は、parse()でパースしたテキストを指定したフォーマット(xhtmlやlatexなど)に変換する。
フォーマットの詳細な設定は、Text_WikiクラスのsetFormatConf($format, $arg1, $arg2)で設定する。
レンダーの各ルールの詳細な設定は、Text_WikiクラスのsetRenderConf($format, $rule, $arg1, $arg2)で設定する。
$formatに適用したいフォーマット(例:Xhtml)を入れる。
$rule、$arg1、$arg2はsetParseConf()と同じである。
設定できる内容は、フォーマットクラス(例:Text_Wiki_Render_Xhtml)とレンダークラス(Text_Wiki_Render_Xhtml_Heading)の$confの説明を参照する。
カスタマイズ
レンダーは、デフォルトに任せてしまってほぼ問題ない。
レンダーのオプション設定でかなりカスタマイズできる。
パースも、デフォルトの記法を使うのであれば、このままでよい。
しかし、できればPukiwiki記法を使いたい。
なので、Text_Wikiクラスを継承し、自前のパーサーを作成することにする。
カスタマイズするに当たって、PEARにある既にカスタマイズされたパッケージが参考になる。
例えば、Text_Wiki_Creoleをインストールしてみて、コードを見てみるとよい。
$ pear install Text_Wiki_Creole
まず、Text_Wikiクラスを継承して、新しいwikiクラスを作成する。
新しいwikiクラスのコンストラクタでは、適用したいルールの名前と、パースクラスがあるディレクトリを設定する。
適用するルールは、$rulesにルール名の配列を入れることで設定できる。
なお、ルールは$rulesに格納された配列の先頭から順番に適用される。
パースクラスがあるディレクトリは、addPath($type, $dir)で追加できる。
次に、パースクラスを作成する。
新しいパースクラスは、Text_Wiki_Parseを継承してを作る。
クラス名は、Text_Wiki_Parse_ルール名(例:Text_Wiki_Parse_Heading)とする。
パースクラスのコンストラクタで、ルールを適用したい正規表現のパターンを設定する。
正規表現のパターンは$regexに設定する。
正規表現のマッチはパースクラスのparse()で行われるが、親クラスであるText_Wiki_Parseクラスのparse()では不具合があるときだけオーバーライドする。
parse()では、preg_match_replace()を呼び、コールバック関数にprocess()を指定する。
必要に応じて、正規表現がマッチした場合に呼ばれるprocess(&$matches)をオーバーライドする。
process(&$matches)では、$matchesにトークンを埋め込んだり、$matchesを適当に変換したりし、その結果を返す。
トークンの埋め込みは、Text_WikiクラスのaddToken($rule, $option)で行う。