多段階箇条書きリスト対応のアルゴリズム

2006-10-17 21:43:15 | | このエントリーを含むはてなブックマーク | Tag: php wiki アルゴリズム プログラミング

無理矢理実装してみました。Wiki スタイルの箇条書きを、ネストのある状態で HTML へコンバートする部分です。

Wiki スタイル多段階箇条書き→HTML コンバートアルゴリズム

// Unordered/Ordered item list
$ul_mark = '-'; $regex_ul = '\\';
$ol_mark = '+'; $regex_ol = '';
while (preg_match("!^([$regex_ul$ul_mark$regex_ol$ol_mark]*)([$regex_ul$ul_mark$regex_ol$ol_mark])([^$regex_ul$ul_mark$regex_ol$ol_mark].*)$!m", $body, $match)) {
	$tag = ($match[2] == $ul_mark) ? 'ul' : 'ol';
	$body = str_replace($match[0], $match[1] . "<$tag><li>" . trim($match[3]) . "</li></$tag>", $body);
}
while (preg_match('!(</li></[uo]l>)</li></ul>\n<ul><li>(<[uo]l><li>)!', $body, $match)
	|| preg_match('!(</li></[uo]l>)</li></ol>\n<ol><li>(<[uo]l><li>)!', $body, $match)) {
	$body = str_replace($match[0], $match[1] . "\n" . $match[2], $body);
}
$body = str_replace("</ul>\n<ul>", "\n", $body);
$body = str_replace("</ol>\n<ol>", "\n", $body);
$body = str_replace("</li>\n<li><ul>", "\n<ul>", $body);
$body = str_replace("</li>\n<li><ol>", "\n<ol>", $body);
$body = str_replace("</li></ul>\n<li>", "</li></ul></li>\n<li>", $body);
$body = str_replace("</li></ol>\n<li>", "</li></ol></li>\n<li>", $body);

カスタマイズ

$ul_mark とかを適当に変えるとカスタマイズ出来ます。$regex_ulpreg_match 関数のメタ文字に当たる場合、'\\' を指定してあげます。

アルゴリズム

処理的には最初の while ループで記号を HTML へ変換し、次の while ループでネストされているリスト構造を整理します。最初の 2 つの str_replace 関数で前後のタグが同じものを取り除き、真ん中 2 つはネスト開始タグの調整、最後の 2 つはネスト終了タグの調整を行います。最後の 4 つの str_replace タグは preg_replace を用いることでスマートに書けますが、速度を向上させるために str_replace を用いています。

サンプル

  1. 一段目
  2. ふたつめ
    1. 二段目
    2. ふたつめ
    3. みっつめ
      • 三段目
      • ふたつめ
        1. ふたつめ
          1. ふたつめ
          2. ほげたん
            • ふたつめ
            • ふたつめ
              1. ふたつめ
          3. ふたつめ
    • 二段目
      1. 三段目
    • 二段目
  3. 一段目

Related Entries

There is not related articles.

Trackbacks

Trackback URI: http://blog.c--v.net/trackback/2006/10/17/3

There is no trackback.

Comments

There is no comment.

Name
URI (Homepage or Email)
Body