PHPでWiki記法を以下のようにHTMLに変換したいのですが、入れ子でかつ、リストと番号付きリストが混在しても問題なく出力できるやり方が思いつきません。


ソース付きで、かつ問題なく動いた回答には300ポイントお支払いさせて頂きます。よろしくお願いします。

■Wiki記法
- リスト1
- リスト2
-+ 番号付きリスト1
-+ 番号付きリスト2
-++ 番号付きリスト3
-++ 番号付きリスト4
-- リスト3
-- リスト4

■HTMLに変換
<ul><li>リスト1</li>
<li>リスト2
<ol><li>番号付きリスト1</li>
<li>番号付きリスト2
<ol><li>番号付きリスト3</li>
<li>番号付きリスト4</li></ol></li></ol>
<ul><li>リスト3</li>
<li>リスト4</li></ul></li></ul>

回答の条件
  • 1人2回まで
  • 13歳以上
  • 登録:2010/06/17 13:37:00
  • 終了:2010/06/21 09:36:16

ベストアンサー

id:GoldenDawn No.1

GoldenDawn回答回数426ベストアンサー獲得回数812010/06/17 17:02:43

ポイント300pt

wiki記法のあとのスペースはそのままにしてあります。

<pre>
<?php
$text = <<< ENDTEXT
- リスト1
- リスト2
-+ 番号付きリスト1
-+ 番号付きリスト2
-++ 番号付きリスト3
-++ 番号付きリスト4
-- リスト3
-- リスト4
ENDTEXT;

function close_list($list) {
  $ret = '' ;
  while ($t = array_pop($list)) $ret .= '</li>'.($t == '-' ? '</ul>' : '</ol>') ;
  return $ret."\n" ;
}

$lines = preg_split('/[\r\n]+/', $text) ;
$output = '' ;
$list = array() ;

foreach ($lines as $one) {
  if ($one == '' || preg_match('/^\s+$/', $one)) continue ;
  $cl = trim($one, '-+') ;
  if (preg_match('/^[-+]+/', $one, $cl)) {
    $cl = str_split($cl[0]) ;

    if ($cl == $list) $output .= "</li>\n" ;
    else {
      $cp = $cl ;

      while($cp && $cp[0] == $list[0]) {
        array_shift($cp) ;
        array_shift($list) ;
      }

      if ($list) $output .= close_list($list) ;
      elseif ($output != '') $output .= "\n" ;
      foreach ($cp as $t) $output .= $t == '-' ? '<ul>' : '<ol>' ;
    }

    $output .= '<li>'.ltrim($one, '-+') ;
    $list = $cl ;
  }
}
$output .= close_list($list) ;


echo htmlspecialchars($output) ;
?>
</pre>
id:xxmasaxx

動作確認はまだ行ってませんが、問題ないようなら有り難く使わせて頂きます。

回答有り難うございます。

2010/06/17 18:48:00

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません