[TASK] Remove SVN auto properties $Id$
[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 * [CLASS/FUNCTION INDEX of SCRIPT]
34 *
35 *
36 *
37 * 84: class t3lib_syntaxhl
38 *
39 * SECTION: Markup of Data Structure, <T3DataStructure>
40 * 156: function highLight_DS($str)
41 * 183: function highLight_DS_markUpRecursively($struct,$parent='',$app='')
42 *
43 * SECTION: Markup of Data Structure, <T3FlexForms>
44 * 268: function highLight_FF($str)
45 * 295: function highLight_FF_markUpRecursively($struct,$parent='',$app='')
46 *
47 * SECTION: Various
48 * 376: function getAllTags($str)
49 * 407: function splitXMLbyTags($tagList,$str)
50 *
51 * TOTAL FUNCTIONS: 6
52 * (This index is automatically created/updated by the extension "extdeveval")
53 *
54 */
55
56
57 /**
58 * Syntax Highlighting class.
59 *
60 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
61 * @package TYPO3
62 * @subpackage t3lib
63 */
64 class t3lib_syntaxhl {
65
66 // Internal, dynamic:
67 var $htmlParse; // Parse object.
68
69 // External, static:
70 var $DS_wrapTags = array(
71 'T3DataStructure' => array('<span style="font-weight: bold;">', '</span>'),
72 'type' => array('<span style="font-weight: bold; color: #000080;">', '</span>'),
73 'section' => array('<span style="font-weight: bold; color: #000080;">', '</span>'),
74 'el' => array('<span style="font-weight: bold; color: #800000;">', '</span>'),
75 'meta' => array('<span style="font-weight: bold; color: #800080;">', '</span>'),
76 '_unknown' => array('<span style="font-style: italic; color: #666666;">', '</span>'),
77
78 '_applicationTag' => array('<span style="font-weight: bold; color: #FF6600;">', '</span>'),
79 '_applicationContents' => array('<span style="font-style: italic; color: #C29336;">', '</span>'),
80
81 'sheets' => array('<span style="font-weight: bold; color: #008000;">', '</span>'),
82 'parent:sheets' => array('<span style="color: #008000;">', '</span>'),
83
84 'ROOT' => array('<span style="font-weight: bold; color: #008080;">', '</span>'),
85 'parent:el' => array('<span style="font-weight: bold; color: #008080;">', '</span>'),
86
87 'langDisable' => array('<span style="color: #000080;">', '</span>'),
88 'langChildren' => array('<span style="color: #000080;">', '</span>'),
89 );
90
91 var $FF_wrapTags = array(
92 'T3FlexForms' => array('<span style="font-weight: bold;">', '</span>'),
93 'meta' => array('<span style="font-weight: bold; color: #800080;">', '</span>'),
94 'data' => array('<span style="font-weight: bold; color: #800080;">', '</span>'),
95 'el' => array('<span style="font-weight: bold; color: #80a000;">', '</span>'),
96 'itemType' => array('<span style="font-weight: bold; color: #804000;">', '</span>'),
97 'section' => array('<span style="font-weight: bold; color: #604080;">', '</span>'),
98 'numIndex' => array('<span style="color: #333333;">', '</span>'),
99 '_unknown' => array('<span style="font-style: italic; color: #666666;">', '</span>'),
100
101
102 'sDEF' => array('<span style="font-weight: bold; color: #008000;">', '</span>'),
103 'level:sheet' => array('<span style="font-weight: bold; color: #008000;">', '</span>'),
104
105 'lDEF' => array('<span style="font-weight: bold; color: #000080;">', '</span>'),
106 'level:language' => array('<span style="font-weight: bold; color: #000080;">', '</span>'),
107
108 'level:fieldname' => array('<span style="font-weight: bold; color: #666666;">', '</span>'),
109
110 'vDEF' => array('<span style="font-weight: bold; color: #008080;">', '</span>'),
111 'level:value' => array('<span style="font-weight: bold; color: #008080;">', '</span>'),
112
113 'currentSheetId' => array('<span style="color: #000080;">', '</span>'),
114 'currentLangId' => array('<span style="color: #000080;">', '</span>'),
115 );
116
117
118 /*************************************
119 *
120 * Markup of Data Structure, <T3DataStructure>
121 *
122 *************************************/
123
124 /**
125 * Makes syntax highlighting of a Data Structure, <T3DataStructure>
126 *
127 * @param string Data Structure XML, must be valid since it's parsed.
128 * @return string HTML code with highlighted content. Must be wrapped in <PRE> tags
129 */
130 function highLight_DS($str) {
131
132 // Parse DS to verify that it is valid:
133 $DS = t3lib_div::xml2array($str);
134 if (is_array($DS)) {
135 $completeTagList = array_unique($this->getAllTags($str)); // Complete list of tags in DS
136
137 // Highlighting source:
138 $this->htmlParse = t3lib_div::makeInstance('t3lib_parsehtml'); // Init parser object
139 $struct = $this->splitXMLbyTags(implode(',', $completeTagList), $str); // Split the XML by the found tags, recursively into LARGE array.
140 $markUp = $this->highLight_DS_markUpRecursively($struct); // Perform color-markup on the parsed content. Markup preserves the LINE formatting of the XML.
141
142 // Return content:
143 return $markUp;
144 } else {
145 $error = 'ERROR: The input content failed XML parsing: ' . $DS;
146 }
147 return $error;
148 }
149
150 /**
151 * Making syntax highlighting of the parsed Data Structure XML.
152 * Called recursively.
153 *
154 * @param array The structure, see splitXMLbyTags()
155 * @param string Parent tag.
156 * @param string "Application" - used to denote if we are 'inside' a section
157 * @return string HTML
158 */
159 function highLight_DS_markUpRecursively($struct, $parent = '', $app = '') {
160 $output = '';
161 foreach ($struct as $k => $v) {
162 if ($k % 2) {
163 $nextApp = $app;
164 $wrap = array('', '');
165
166 switch ($app) {
167 case 'TCEforms':
168 case 'tx_templavoila':
169 $wrap = $this->DS_wrapTags['_applicationContents'];
170 break;
171 case 'el':
172 default:
173 if ($parent == 'el') {
174 $wrap = $this->DS_wrapTags['parent:el'];
175 $nextApp = 'el';
176 } elseif ($parent == 'sheets') {
177 $wrap = $this->DS_wrapTags['parent:sheets'];
178 } else {
179 $wrap = $this->DS_wrapTags[$v['tagName']];
180 $nextApp = '';
181 }
182
183 // If no wrap defined, us "unknown" definition
184 if (!is_array($wrap)) {
185 $wrap = $this->DS_wrapTags['_unknown'];
186 }
187
188 // Check for application sections in the XML:
189 if ($app == 'el' || $parent == 'ROOT') {
190 switch ($v['tagName']) {
191 case 'TCEforms':
192 case 'tx_templavoila':
193 $nextApp = $v['tagName'];
194 $wrap = $this->DS_wrapTags['_applicationTag'];
195 break;
196 }
197 }
198 break;
199 }
200
201 $output .= $wrap[0] . htmlspecialchars($v['tag']) . $wrap[1];
202 $output .= $this->highLight_DS_markUpRecursively($v['sub'], $v['tagName'], $nextApp);
203 $output .= $wrap[0] . htmlspecialchars('</' . $v['tagName'] . '>') . $wrap[1];
204 } else {
205 $output .= htmlspecialchars($v);
206 }
207 }
208
209 return $output;
210 }
211
212
213 /*************************************
214 *
215 * Markup of Data Structure, <T3FlexForms>
216 *
217 *************************************/
218
219 /**
220 * Makes syntax highlighting of a FlexForm Data, <T3FlexForms>
221 *
222 * @param string Data Structure XML, must be valid since it's parsed.
223 * @return string HTML code with highlighted content. Must be wrapped in <PRE> tags
224 */
225 function highLight_FF($str) {
226
227 // Parse DS to verify that it is valid:
228 $DS = t3lib_div::xml2array($str);
229 if (is_array($DS)) {
230 $completeTagList = array_unique($this->getAllTags($str)); // Complete list of tags in DS
231
232 // Highlighting source:
233 $this->htmlParse = t3lib_div::makeInstance('t3lib_parsehtml'); // Init parser object
234 $struct = $this->splitXMLbyTags(implode(',', $completeTagList), $str); // Split the XML by the found tags, recursively into LARGE array.
235 $markUp = $this->highLight_FF_markUpRecursively($struct); // Perform color-markup on the parsed content. Markup preserves the LINE formatting of the XML.
236
237 // Return content:
238 return $markUp;
239 } else {
240 $error = 'ERROR: The input content failed XML parsing: ' . $DS;
241 }
242 return $error;
243 }
244
245 /**
246 * Making syntax highlighting of the parsed FlexForm XML.
247 * Called recursively.
248 *
249 * @param array The structure, see splitXMLbyTags()
250 * @param string Parent tag.
251 * @param string "Application" - used to denote if we are 'inside' a section
252 * @return string HTML
253 */
254 function highLight_FF_markUpRecursively($struct, $parent = '', $app = '') {
255 $output = '';
256
257 // Setting levels:
258 if ($parent == 'data') {
259 $app = 'sheet';
260 } elseif ($app == 'sheet') {
261 $app = 'language';
262 } elseif ($app == 'language') {
263 $app = 'fieldname';
264 } elseif ($app == 'fieldname') {
265 $app = 'value';
266 } elseif ($app == 'el' || $app == 'numIndex') {
267 $app = 'fieldname';
268 }
269
270 // Traverse structure:
271 foreach ($struct as $k => $v) {
272 if ($k % 2) {
273 $wrap = array('', '');
274
275 if ($v['tagName'] == 'numIndex') {
276 $app = 'numIndex';
277 }
278
279 // Default wrap:
280 $wrap = $this->FF_wrapTags[$v['tagName']];
281
282 // If no wrap defined, us "unknown" definition
283 if (!is_array($wrap)) {
284 switch ($app) {
285 case 'sheet':
286 case 'language':
287 case 'fieldname':
288 case 'value':
289 $wrap = $this->FF_wrapTags['level:' . $app];
290 break;
291 default:
292 $wrap = $this->FF_wrapTags['_unknown'];
293 break;
294 }
295 }
296
297 if ($v['tagName'] == 'el') {
298 $app = 'el';
299 }
300
301 $output .= $wrap[0] . htmlspecialchars($v['tag']) . $wrap[1];
302 $output .= $this->highLight_FF_markUpRecursively($v['sub'], $v['tagName'], $app);
303 $output .= $wrap[0] . htmlspecialchars('</' . $v['tagName'] . '>') . $wrap[1];
304 } else {
305 $output .= htmlspecialchars($v);
306 }
307 }
308
309 return $output;
310 }
311
312
313 /*************************************
314 *
315 * Various
316 *
317 *************************************/
318
319 /**
320 * Returning all tag names found in XML/HTML input string
321 *
322 * @param string HTML/XML input
323 * @return array Array with all found tags (starttags only)
324 */
325 function getAllTags($str) {
326
327 // Init:
328 $tags = array();
329 $token = md5(microtime());
330
331 // Markup all tag names with token.
332 $markUpStr = preg_replace('/<([[:alnum:]_]+)[^>]*>/', $token . '${1}' . $token, $str);
333
334 // Splitting by token:
335 $parts = explode($token, $markUpStr);
336
337 // Traversing parts:
338 foreach ($parts as $k => $v) {
339 if ($k % 2) {
340 $tags[] = $v;
341 }
342 }
343
344 // Returning tags:
345 return $tags;
346 }
347
348 /**
349 * Splitting the input source by the tags listing in $tagList.
350 * Called recursively.
351 *
352 * @param string Commalist of tags to split source by (into blocks, ALL being block-tags!)
353 * @param string Input string.
354 * @return array Array with the content arranged hierarchically.
355 */
356 function splitXMLbyTags($tagList, $str) {
357 $struct = $this->htmlParse->splitIntoBlock($tagList, $str);
358
359 // Traverse level:
360 foreach ($struct as $k => $v) {
361 if ($k % 2) {
362 $tag = $this->htmlParse->getFirstTag($v);
363 $tagName = $this->htmlParse->getFirstTagName($tag, TRUE);
364 $struct[$k] = array(
365 'tag' => $tag,
366 'tagName' => $tagName,
367 'sub' => $this->splitXMLbyTags($tagList, $this->htmlParse->removeFirstAndLastTag($struct[$k]))
368 );
369 }
370 }
371
372 return $struct;
373 }
374 }
375
376
377 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_syntaxhl.php'])) {
378 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_syntaxhl.php']);
379 }
380
381 ?>