OSDN Git Service

Import current code.
[osdn-codes/wiki-parser.git] / sfjp / wiki / formatter / buffered_delegator.php
1 <?php
2 namespace sfjp\Wiki\Formatter;
3 class Buffered_DocNode {
4         public $name;
5         public $data;
6         public $parent;
7         public $children = array();
8
9         function __construct($name, $data=null) {
10                 $this->name = $name;
11                 $this->data = $data;
12         }
13
14         function __destruct() {
15                 $this->destroy();
16         }
17
18         public function destroy() {
19                 if (isset($this->children)) {
20                         foreach ($this->children as $c) {
21                                 $c->destroy();
22                         }
23                 }
24                 unset($this->parent);
25                 unset($this->name);
26                 unset($this->data);
27                 unset($this->children);
28         }
29
30         public function __toString() {
31                 return '';
32         }
33
34         public function getParent() {
35                 return $this->parent;
36         }
37
38         public function getPrev() {
39                 $prev = null;
40                 $found = false;
41                 foreach ($this->parent->children as $c) {
42                         if ($c === $this) {
43                                 $found = true;
44                                 break;
45                         }
46                         $prev = $c;
47                 }
48                 return $found ? $prev : null;
49         }
50
51         public function getNext() {
52                 $idx = null;
53                 $list = $this->parent->children;
54                 foreach ($list as $i => $c) {
55                         if ($c === $this) {
56                                 $idx = $i;
57                                 break;
58                         }
59                 }
60                 return (isset($i) && array_key_exists($idx+1, $list)) ? $list[$idx+1] : null;
61         }
62
63         public function hasChildren() {
64                 return !empty($this->children);
65         }
66
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;
72                 return $child;
73         }
74 }
75
76 class Buffered_Delegator extends Base {
77         public $root_node;
78         public $cur_node;
79         public $formatter;
80   
81         function __construct() {
82                 parent::__construct();
83                 $this->reset();
84         }
85
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);
91         }
92
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();
99                 }
100                 $this->formatter->reset();
101         }
102
103         public function cleanup() {
104                 return $this->render();
105         }
106
107         public function render() {
108                 return $this->render_node($this->root_node);
109         }
110
111         protected function render_node($node) {
112                 $fmt = $this->formatter;
113                 $ret = '';
114                 if ($node->name === "*ROOT") {
115                         # nothing
116                                 } elseif ($node->name === "*RAW") {
117                         $ret .= $fmt->raw_node($node->data);
118                 } elseif ($node->name === "*TEXT") {
119                         $ret .= $fmt->text_node($node->data);
120                 } else {
121                         $ret .= $fmt->open_element($node->name, $node->data);
122                 }
123                 foreach ($node->children as $child) {
124                         $ret .= $this->render_node($child);
125                 }
126                 if (substr($node->name, 0, 1) != "*") {
127                         $ret .= $fmt->close_element($node->name, $node->data);
128                 }
129                 return $ret;
130         }
131
132         public function open_element($name, $opt=null) {
133                 $this->cur_node = $this->cur_node->addChild($name, $opt);
134                 return $this->cur_node;
135         }
136
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;
141         }
142
143         public function text_node($text) {
144                 return $this->cur_node->addChild('*TEXT', $text);
145         }
146
147         public function raw_node($string) {
148                 return $this->cur_node->addChild('*RAW', $string);
149         }
150
151         public function _dump_tree() {
152                 return $this->_inspect_node($this->root_node, 0);
153         }
154
155         public function _inspect_node($node, $level) {
156                 $ret = '';
157                 for ($i = 0; $level*2 > $i; $i++) {
158                         $ret .= '&nbsp;';
159                 }
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);
163                 }
164                 return $ret;
165         }
166 }