init
[garradin.git] / include / libs / template_lite / class.tokenparser.php
1 <?php
2
3 class Template_Syntax_Exception extends Exception
4 {
5 }
6
7 class Template_Parser
8 {
9 const CONTEXT_ARGUMENT = 10;
10 const CONTEXT_STRING = 11;
11
12 public $left_delimiter = '{';
13 public $right_delimiter = '}';
14
15 protected $_allowed_in_variable = array(T_VARIABLE, T_OBJECT_OPERATOR, T_STRING,
16 T_CONSTANT_ENCAPSED_STRING, T_ENCAPSED_AND_WHITESPACE, T_DOUBLE_COLON, '(', ')');
17
18 protected $_allowed_in_string = array(T_STRING,
19 T_CONSTANT_ENCAPSED_STRING, T_ENCAPSED_AND_WHITESPACE);
20
21 public $reserved_var_name = '(?:smarty|tpl|templatelite)';
22
23 public function __construct()
24 {
25 }
26
27 protected function processVariable($variable, $modifiers = array())
28 {
29 return '--var('.$variable.')';
30 }
31
32 /*
33 public function parse($content)
34 {
35 $in_literal = false;
36
37 $pos = strpos($content, $this->left_delimiter);
38
39 while ($pos !== false)
40 {
41 if (($end = strpos($content,
42 if ($in_literal)
43 }
44
45 $tokens = token_get_all('<?php '.$content.' ?>');
46
47 foreach ($tokens as $token)
48 {
49 if (is_array($token))
50 list($token, $text, $line) = $token;
51
52 switch ($token)
53 {
54 case T_OPEN_TAG:
55 break;
56 default:
57 if ($token >= 300)
58 echo token_name($token) . ": ".$text;
59 else echo $token;
60 echo "\n";
61 break;
62 }
63 }
64 }
65 */
66
67 public function parseArguments($string)
68 {
69 $args = array();
70 $status = 0; // 0 = nothing, 1 = arg named, waiting for equal sign, 2 = waiting for content
71 $arg_name = null;
72 $arg_value = null;
73
74 foreach (token_get_all('<?php '.$string.'?>') as $t)
75 {
76 switch ($t[0])
77 {
78 case T_OPEN_TAG:
79 case T_CLOSE_TAG:
80 continue(2);
81 case T_STRING:
82 if ($status == 0)
83 {
84 $arg_name = $t[1];
85 $arg_value = '';
86 $status++;
87 }
88 elseif ($status == 2)
89 {
90 $arg_value .= $t[1];
91 }
92 break;
93 case "\"":
94 case "\'":
95 if ($status != 2)
96 {
97 throw new Template_Syntax_Exception("Expecting '=' sign after argument name");
98 }
99 $arg_value .= $t;
100 break;
101 case '=':
102 if ($status != 1)
103 {
104 throw new Template_Syntax_Exception("Unexpected '=' sign");
105 }
106 $status++;
107 break;
108 case T_ENCAPSED_AND_WHITESPACE:
109 case T_VARIABLE:
110 case T_OBJECT_OPERATOR:
111 case T_CONSTANT_ENCAPSED_STRING:
112 case T_DOUBLE_COLON:
113 if ($status != 2)
114 {
115 throw new Template_Syntax_Exception("Expecting '=' sign after argument name");
116 }
117
118 if ($t[0] == T_CONSTANT_ENCAPSED_STRING)
119 $arg_value = substr($t[1], 1, -1);
120 else
121 $arg_value .= $t[1];
122
123 break;
124 case T_WHITESPACE:
125 if ($status == 2)
126 {
127 $args[$arg_name] = $arg_value;
128 $arg_name = $arg_value = null;
129 $status = 0;
130 }
131 break;
132 case !isset($t[1]):
133 if ($status != 2)
134 {
135 throw new Template_Syntax_Exception("Expecting '=' sign after argument name");
136 }
137
138 $arg_value .= $t;
139 break;
140 default:
141 break;
142 }
143 }
144
145 if ($arg_value != null && $arg_name != null && !array_key_exists($arg_name, $args))
146 {
147 $args[$arg_name] = $arg_value;
148 }
149
150 return $args;
151 }
152
153 public function parseArgumentContent($content)
154 {
155 $content = trim($content);
156
157 if (empty($content))
158 return $content;
159
160 $quotes = $content[0] . substr($content, -1);
161
162 if ($quotes == "\"\"" || $quotes == '\'\'')
163 {
164 $content = substr($content, 1, -1);
165 $inline = ($quotes == "\'\'") ? false : true;
166 $out = '';
167 $current_var = false;
168
169 foreach (token_get_all('<?php "'.$content.'" ?>') as $t)
170 {
171 if ($current_var === true)
172 {
173 if ($t[0] == T_VARIABLE || ($t[0] == T_STRING && $t[1][0] == '$'))
174 {
175 $current_var = $t[1];
176 }
177 else
178 {
179 $out .= '`';
180 $current_var = false;
181 }
182 }
183
184 if ($current_var)
185 {
186 list($variable, $modifiers) = $this->parseVariable($current_var);
187 $out .= $this->processVariable($variable, $modifiers, self::CONTEXT_STRING);
188 $current_var = false;
189 }
190 elseif ($inline && $t[0] == T_VARIABLE)
191 {
192 $current_var = $t[1];
193 }
194 elseif ($t[0] == '`')
195 {
196 $current_var = true;
197 }
198
199 if ($current_var === false && in_array($t[0], $this->_allowed_in_string))
200 {
201 $out .= isset($t[1]) ? $t[1] : $t[0];
202 }
203 else
204 {
205 echo (isset($t[1]) ? token_name($t[0]) . ' ' . htmlspecialchars($t[1]) : htmlspecialchars($t[0])). "<br />";
206 }
207 }
208
209 return $out;
210 }
211 else
212 {
213 list($variable, $modifiers) = $this->parseVariable($content);
214 return $this->processVariable($variable, $modifiers, self::CONTEXT_ARGUMENT);
215 }
216 }
217
218 public function parseVariable($string)
219 {
220 $variable = '';
221 $modifiers = array();
222 $current_modifier = false;
223 $current_arg = false;
224
225 foreach (token_get_all('<?php '.$string.'?>') as $t)
226 {
227 if ($t[0] == T_STRING)
228 {
229 if ($current_modifier === true)
230 {
231 $modifiers[] = array($t[1]);
232 $current_modifier = count($modifiers) - 1;
233 $current_arg = 1;
234 continue;
235 }
236 }
237
238 $content = isset($t[1]) ? $t[1] : $t[0];
239
240 if ($t[0] == T_CONSTANT_ENCAPSED_STRING)
241 $content = substr($content, 1, -1);
242
243 if ($t[0] == '|')
244 $current_modifier = true;
245 elseif ($t[0] == ':')
246 $current_arg++;
247 elseif ($current_modifier === false && in_array($t[0], $this->_allowed_in_variable))
248 {
249 $variable .= $content;
250 }
251 elseif (is_int($current_modifier) && in_array($t[0], $this->_allowed_in_variable))
252 {
253 if (!array_key_exists($current_arg, $modifiers[$current_modifier]))
254 {
255 $modifiers[$current_modifier][$current_arg] = '';
256 }
257
258 $modifiers[$current_modifier][$current_arg] .= $content;
259 }
260 else
261 {
262 }
263 }
264
265 return array($variable, $modifiers);
266 }
267
268 public function parseTokens($string)
269 {
270 echo '<table>';
271 foreach (token_get_all('<?php '.$string.'?>') as $t)
272 {
273 echo "<tr>";
274 if (is_array($t))
275 {
276 echo '<th>'.token_name($t[0]).'</th>';
277 echo '<td>'.htmlspecialchars($t[1]).'</td>';
278 echo '<td>'.($t[2]).'</td>';
279 }
280 else
281 {
282 echo '<th>--</th>';
283 echo '<td>'.htmlspecialchars($t).'</td>';
284 echo '<td></td>';
285 }
286 echo '</tr>';
287 }
288 }
289 }
290
291 ?>