作者: 閑舎
日時: 2006/7/07(11:18)
最後に、Zazel さんが言われていたように、クラスレベルでなく、関数レベルの
再帰を使い、各要素のデータをハッシュに格納するのだと、未整理だけれど、こ
んな感じで一応動いたようです(かなり見にくい状態なので、本当はここからタ
グを増やしていくのが面倒そう)。

<?php
$obj = new mkhtml("\n\nab\nc\n\ndef");

class mkhtml {
  function mkhtml($str) {
    $body = new Block($str, "body");
    $body->parse();
    $body->toText();
  }
}
class Block {
  function Block(&$line, $name) {
    $this->length = strlen($line);
    $this->line =& $line;
    $this->pt = 0;
    $this->elem[0] = array(
      'name' => $name,
      'len' => 0,
      'start' => 0,
      'next' => -1
      );
    $this->ei = 0;
  }
  function parse() {
    if (preg_match("/\n\n+/", $this->line, $matches ,PREG_OFFSET_CAPTURE, $this->pt)) {
      $this->elem[$this->ei]['len'] = $matches[0][1] - $this->elem[$this->ei]['start'];
      $this->pt = $matches[0][1] + strlen($matches[0][0]);
      $this->add("p", $this->pt);
      $this->parse();
    } else if ($this->elem[$this->ei]['name'] != "body") {
      $this->elem[$this->ei]['len'] = $this->length - $this->elem[$this->ei]['start'];
      $this->add("body", $this->length);
    }
  }
  function add($name, $start) {
    $this->elem[$this->ei]['next'] = $this->ei++ + 1;
    $this->elem[$this->ei] = array(
      'name' => $name,
      'len' => 0,
      'start' => $start,
      'next' => -1);
  }
  function toText() {
    for ($i = 0; $i < count($this->elem); $i++) {
      if ($this->elem[$i]['name'] != "body") echo "<" . $this->elem[$i]['name'] . ">";
      echo substr($this->line, $this->elem[$i]['start'],  $this->elem[$i]['len']);
      if ($this->elem[$i]['name'] != "body") echo "</" . $this->elem[$i]['name'] . ">\n";
    }
  }
}
?>

--
本田博通(閑舎)
テキストとスクリプトの http://www.rakunet.org/TSNET/