[BUGFIX] Autoloader Cache is not updated
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_syntaxhl.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2011 Kasper Skårhøj (kasperYYYY@typo3.com)
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27 /**
28 * Contains a class for various syntax highlighting.
29 *
30 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
31 */
32
33
34 /**
35 * Syntax Highlighting class.
36 *
37 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
38 * @package TYPO3
39 * @subpackage t3lib
40 */
41 class t3lib_syntaxhl {
42
43 // Internal, dynamic:
44 var $htmlParse; // Parse object.
45
46 // External, static:
47 var $DS_wrapTags = array(
48 'T3DataStructure' => array('<span style="font-weight: bold;">', '</span>'),
49 'type' => array('<span style="font-weight: bold; color: #000080;">', '</span>'),
50 'section' => array('<span style="font-weight: bold; color: #000080;">', '</span>'),
51 'el' => array('<span style="font-weight: bold; color: #800000;">', '</span>'),
52 'meta' => array('<span style="font-weight: bold; color: #800080;">', '</span>'),
53 '_unknown' => array('<span style="font-style: italic; color: #666666;">', '</span>'),
54
55 '_applicationTag' => array('<span style="font-weight: bold; color: #FF6600;">', '</span>'),
56 '_applicationContents' => array('<span style="font-style: italic; color: #C29336;">', '</span>'),
57
58 'sheets' => array('<span style="font-weight: bold; color: #008000;">', '</span>'),
59 'parent:sheets' => array('<span style="color: #008000;">', '</span>'),
60
61 'ROOT' => array('<span style="font-weight: bold; color: #008080;">', '</span>'),
62 'parent:el' => array('<span style="font-weight: bold; color: #008080;">', '</span>'),
63
64 'langDisable' => array('<span style="color: #000080;">', '</span>'),
65 'langChildren' => array('<span style="color: #000080;">', '</span>'),
66 );
67
68 var $FF_wrapTags = array(
69 'T3FlexForms' => array('<span style="font-weight: bold;">', '</span>'),
70 'meta' => array('<span style="font-weight: bold; color: #800080;">', '</span>'),
71 'data' => array('<span style="font-weight: bold; color: #800080;">', '</span>'),
72 'el' => array('<span style="font-weight: bold; color: #80a000;">', '</span>'),
73 'itemType' => array('<span style="font-weight: bold; color: #804000;">', '</span>'),
74 'section' => array('<span style="font-weight: bold; color: #604080;">', '</span>'),
75 'numIndex' => array('<span style="color: #333333;">', '</span>'),
76 '_unknown' => array('<span style="font-style: italic; color: #666666;">', '</span>'),
77
78
79 'sDEF' => array('<span style="font-weight: bold; color: #008000;">', '</span>'),
80 'level:sheet' => array('<span style="font-weight: bold; color: #008000;">', '</span>'),
81
82 'lDEF' => array('<span style="font-weight: bold; color: #000080;">', '</span>'),
83 'level:language' => array('<span style="font-weight: bold; color: #000080;">', '</span>'),
84
85 'level:fieldname' => array('<span style="font-weight: bold; color: #666666;">', '</span>'),
86
87 'vDEF' => array('<span style="font-weight: bold; color: #008080;">', '</span>'),
88 'level:value' => array('<span style="font-weight: bold; color: #008080;">', '</span>'),
89
90 'currentSheetId' => array('<span style="color: #000080;">', '</span>'),
91 'currentLangId' => array('<span style="color: #000080;">', '</span>'),
92 );
93
94
95 /*************************************
96 *
97 * Markup of Data Structure, <T3DataStructure>
98 *
99 *************************************/
100
101 /**
102 * Makes syntax highlighting of a Data Structure, <T3DataStructure>
103 *
104 * @param string Data Structure XML, must be valid since it's parsed.
105 * @return string HTML code with highlighted content. Must be wrapped in <PRE> tags
106 */
107 function highLight_DS($str) {
108
109 // Parse DS to verify that it is valid:
110 $DS = t3lib_div::xml2array($str);
111 if (is_array($DS)) {
112 $completeTagList = array_unique($this->getAllTags($str)); // Complete list of tags in DS
113
114 // Highlighting source:
115 $this->htmlParse = t3lib_div::makeInstance('t3lib_parsehtml'); // Init parser object
116 $struct = $this->splitXMLbyTags(implode(',', $completeTagList), $str); // Split the XML by the found tags, recursively into LARGE array.
117 $markUp = $this->highLight_DS_markUpRecursively($struct); // Perform color-markup on the parsed content. Markup preserves the LINE formatting of the XML.
118
119 // Return content:
120 return $markUp;
121 } else {
122 $error = 'ERROR: The input content failed XML parsing: ' . $DS;
123 }
124 return $error;
125 }
126
127 /**
128 * Making syntax highlighting of the parsed Data Structure XML.
129 * Called recursively.
130 *
131 * @param array The structure, see splitXMLbyTags()
132 * @param string Parent tag.
133 * @param string "Application" - used to denote if we are 'inside' a section
134 * @return string HTML
135 */
136 function highLight_DS_markUpRecursively($struct, $parent = '', $app = '') {
137 $output = '';
138 foreach ($struct as $k => $v) {
139 if ($k % 2) {
140 $nextApp = $app;
141 $wrap = array('', '');
142
143 switch ($app) {
144 case 'TCEforms':
145 case 'tx_templavoila':
146 $wrap = $this->DS_wrapTags['_applicationContents'];
147 break;
148 case 'el':
149 default:
150 if ($parent == 'el') {
151 $wrap = $this->DS_wrapTags['parent:el'];
152 $nextApp = 'el';
153 } elseif ($parent == 'sheets') {
154 $wrap = $this->DS_wrapTags['parent:sheets'];
155 } else {
156 $wrap = $this->DS_wrapTags[$v['tagName']];
157 $nextApp = '';
158 }
159
160 // If no wrap defined, us "unknown" definition
161 if (!is_array($wrap)) {
162 $wrap = $this->DS_wrapTags['_unknown'];
163 }
164
165 // Check for application sections in the XML:
166 if ($app == 'el' || $parent == 'ROOT') {
167 switch ($v['tagName']) {
168 case 'TCEforms':
169 case 'tx_templavoila':
170 $nextApp = $v['tagName'];
171 $wrap = $this->DS_wrapTags['_applicationTag'];
172 break;
173 }
174 }
175 break;
176 }
177
178 $output .= $wrap[0] . htmlspecialchars($v['tag']) . $wrap[1];
179 $output .= $this->highLight_DS_markUpRecursively($v['sub'], $v['tagName'], $nextApp);
180 $output .= $wrap[0] . htmlspecialchars('</' . $v['tagName'] . '>') . $wrap[1];
181 } else {
182 $output .= htmlspecialchars($v);
183 }
184 }
185
186 return $output;
187 }
188
189
190 /*************************************
191 *
192 * Markup of Data Structure, <T3FlexForms>
193 *
194 *************************************/
195
196 /**
197 * Makes syntax highlighting of a FlexForm Data, <T3FlexForms>
198 *
199 * @param string Data Structure XML, must be valid since it's parsed.
200 * @return string HTML code with highlighted content. Must be wrapped in <PRE> tags
201 */
202 function highLight_FF($str) {
203
204 // Parse DS to verify that it is valid:
205 $DS = t3lib_div::xml2array($str);
206 if (is_array($DS)) {
207 $completeTagList = array_unique($this->getAllTags($str)); // Complete list of tags in DS
208
209 // Highlighting source:
210 $this->htmlParse = t3lib_div::makeInstance('t3lib_parsehtml'); // Init parser object
211 $struct = $this->splitXMLbyTags(implode(',', $completeTagList), $str); // Split the XML by the found tags, recursively into LARGE array.
212 $markUp = $this->highLight_FF_markUpRecursively($struct); // Perform color-markup on the parsed content. Markup preserves the LINE formatting of the XML.
213
214 // Return content:
215 return $markUp;
216 } else {
217 $error = 'ERROR: The input content failed XML parsing: ' . $DS;
218 }
219 return $error;
220 }
221
222 /**
223 * Making syntax highlighting of the parsed FlexForm XML.
224 * Called recursively.
225 *
226 * @param array The structure, see splitXMLbyTags()
227 * @param string Parent tag.
228 * @param string "Application" - used to denote if we are 'inside' a section
229 * @return string HTML
230 */
231 function highLight_FF_markUpRecursively($struct, $parent = '', $app = '') {
232 $output = '';
233
234 // Setting levels:
235 if ($parent == 'data') {
236 $app = 'sheet';
237 } elseif ($app == 'sheet') {
238 $app = 'language';
239 } elseif ($app == 'language') {
240 $app = 'fieldname';
241 } elseif ($app == 'fieldname') {
242 $app = 'value';
243 } elseif ($app == 'el' || $app == 'numIndex') {
244 $app = 'fieldname';
245 }
246
247 // Traverse structure:
248 foreach ($struct as $k => $v) {
249 if ($k % 2) {
250 $wrap = array('', '');
251
252 if ($v['tagName'] == 'numIndex') {
253 $app = 'numIndex';
254 }
255
256 // Default wrap:
257 $wrap = $this->FF_wrapTags[$v['tagName']];
258
259 // If no wrap defined, us "unknown" definition
260 if (!is_array($wrap)) {
261 switch ($app) {
262 case 'sheet':
263 case 'language':
264 case 'fieldname':
265 case 'value':
266 $wrap = $this->FF_wrapTags['level:' . $app];
267 break;
268 default:
269 $wrap = $this->FF_wrapTags['_unknown'];
270 break;
271 }
272 }
273
274 if ($v['tagName'] == 'el') {
275 $app = 'el';
276 }
277
278 $output .= $wrap[0] . htmlspecialchars($v['tag']) . $wrap[1];
279 $output .= $this->highLight_FF_markUpRecursively($v['sub'], $v['tagName'], $app);
280 $output .= $wrap[0] . htmlspecialchars('</' . $v['tagName'] . '>') . $wrap[1];
281 } else {
282 $output .= htmlspecialchars($v);
283 }
284 }
285
286 return $output;
287 }
288
289
290 /*************************************
291 *
292 * Various
293 *
294 *************************************/
295
296 /**
297 * Returning all tag names found in XML/HTML input string
298 *
299 * @param string HTML/XML input
300 * @return array Array with all found tags (starttags only)
301 */
302 function getAllTags($str) {
303
304 // Init:
305 $tags = array();
306 $token = md5(microtime());
307
308 // Markup all tag names with token.
309 $markUpStr = preg_replace('/<([[:alnum:]_]+)[^>]*>/', $token . '${1}' . $token, $str);
310
311 // Splitting by token:
312 $parts = explode($token, $markUpStr);
313
314 // Traversing parts:
315 foreach ($parts as $k => $v) {
316 if ($k % 2) {
317 $tags[] = $v;
318 }
319 }
320
321 // Returning tags:
322 return $tags;
323 }
324
325 /**
326 * Splitting the input source by the tags listing in $tagList.
327 * Called recursively.
328 *
329 * @param string Commalist of tags to split source by (into blocks, ALL being block-tags!)
330 * @param string Input string.
331 * @return array Array with the content arranged hierarchically.
332 */
333 function splitXMLbyTags($tagList, $str) {
334 $struct = $this->htmlParse->splitIntoBlock($tagList, $str);
335
336 // Traverse level:
337 foreach ($struct as $k => $v) {
338 if ($k % 2) {
339 $tag = $this->htmlParse->getFirstTag($v);
340 $tagName = $this->htmlParse->getFirstTagName($tag, TRUE);
341 $struct[$k] = array(
342 'tag' => $tag,
343 'tagName' => $tagName,
344 'sub' => $this->splitXMLbyTags($tagList, $this->htmlParse->removeFirstAndLastTag($struct[$k]))
345 );
346 }
347 }
348
349 return $struct;
350 }
351 }
352
353
354 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_syntaxhl.php'])) {
355 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_syntaxhl.php']);
356 }
357
358 ?>