2 namespace sfjp\Wiki\Formatter;
3 class Buffered_DocNode {
7 public $children = array();
9 function __construct($name, $data=null) {
14 function __destruct() {
18 public function destroy() {
19 if (isset($this->children)) {
20 foreach ($this->children as $c) {
27 unset($this->children);
30 public function __toString() {
34 public function getParent() {
38 public function getPrev() {
41 foreach ($this->parent->children as $c) {
48 return $found ? $prev : null;
51 public function getNext() {
53 $list = $this->parent->children;
54 foreach ($list as $i => $c) {
60 return (isset($i) && array_key_exists($idx+1, $list)) ? $list[$idx+1] : null;
63 public function hasChildren() {
64 return !empty($this->children);
67 public function addChild($name, $data=null) {
68 $myclass = get_called_class();
69 $child = new $myclass($name, $data);
70 $child->parent = $this;
71 $this->children []= $child;
76 class Buffered_Delegator extends Base {
81 function __construct() {
82 parent::__construct();
86 function __destruct() {
87 if ($this->root_node) $this->root_node->destroy();
88 unset($this->root_node);
89 unset($this->cur_node);
90 unset($this->formatter);
93 public function reset() {
94 if ($this->root_node) $this->root_node->destroy();
95 $this->root_node = new Buffered_DocNode('*ROOT');
96 $this->cur_node = $this->root_node;
97 if (!$this->formatter) {
98 $this->formatter = new HTML();
100 $this->formatter->reset();
103 public function cleanup() {
104 return $this->render();
107 public function render() {
108 return $this->render_node($this->root_node);
111 protected function render_node($node) {
112 $fmt = $this->formatter;
114 if ($node->name === "*ROOT") {
116 } elseif ($node->name === "*RAW") {
117 $ret .= $fmt->raw_node($node->data);
118 } elseif ($node->name === "*TEXT") {
119 $ret .= $fmt->text_node($node->data);
121 $ret .= $fmt->open_element($node->name, $node->data);
123 foreach ($node->children as $child) {
124 $ret .= $this->render_node($child);
126 if (substr($node->name, 0, 1) != "*") {
127 $ret .= $fmt->close_element($node->name, $node->data);
132 public function open_element($name, $opt=null) {
133 $this->cur_node = $this->cur_node->addChild($name, $opt);
134 return $this->cur_node;
137 public function close_element($name, $opt=null) {
138 // TODO: now all options are ignored.
139 $this->cur_node = $this->cur_node->parent;
140 return $this->cur_node;
143 public function text_node($text) {
144 return $this->cur_node->addChild('*TEXT', $text);
147 public function raw_node($string) {
148 return $this->cur_node->addChild('*RAW', $string);
151 public function _dump_tree() {
152 return $this->_inspect_node($this->root_node, 0);
155 public function _inspect_node($node, $level) {
157 for ($i = 0; $level*2 > $i; $i++) {
160 $ret .= "+ [" . $node->name . "] (" . htmlspecialchars(substr(print_r($node->data, 1), 0, 80)) . ")<br />";
161 foreach ($node->children as $c) {
162 $ret .= $this->_inspect_node($c, $level+1);