2c0364f3aaafbd842b7f942332358dca54d46891
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_syntaxhl.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2013 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 /**
29 * Contains a class for various syntax highlighting.
30 *
31 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
32 * @deprecated since 6.0, will be removed with 6.2
33 */
34 class t3lib_syntaxhl {
35
36 // Internal, dynamic:
37 // Parse object.
38 /**
39 * @todo Define visibility
40 */
41 public $htmlParse;
42
43 // External, static:
44 /**
45 * @todo Define visibility
46 */
47 public $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 '_applicationTag' => array('<span style="font-weight: bold; color: #FF6600;">', '</span>'),
55 '_applicationContents' => array('<span style="font-style: italic; color: #C29336;">', '</span>'),
56 'sheets' => array('<span style="font-weight: bold; color: #008000;">', '</span>'),
57 'parent:sheets' => array('<span style="color: #008000;">', '</span>'),
58 'ROOT' => array('<span style="font-weight: bold; color: #008080;">', '</span>'),
59 'parent:el' => array('<span style="font-weight: bold; color: #008080;">', '</span>'),
60 'langDisable' => array('<span style="color: #000080;">', '</span>'),
61 'langChildren' => array('<span style="color: #000080;">', '</span>')
62 );
63
64 /**
65 * @todo Define visibility
66 */
67 public $FF_wrapTags = array(
68 'T3FlexForms' => array('<span style="font-weight: bold;">', '</span>'),
69 'meta' => array('<span style="font-weight: bold; color: #800080;">', '</span>'),
70 'data' => array('<span style="font-weight: bold; color: #800080;">', '</span>'),
71 'el' => array('<span style="font-weight: bold; color: #80a000;">', '</span>'),
72 'itemType' => array('<span style="font-weight: bold; color: #804000;">', '</span>'),
73 'section' => array('<span style="font-weight: bold; color: #604080;">', '</span>'),
74 'numIndex' => array('<span style="color: #333333;">', '</span>'),
75 '_unknown' => array('<span style="font-style: italic; color: #666666;">', '</span>'),
76 'sDEF' => array('<span style="font-weight: bold; color: #008000;">', '</span>'),
77 'level:sheet' => array('<span style="font-weight: bold; color: #008000;">', '</span>'),
78 'lDEF' => array('<span style="font-weight: bold; color: #000080;">', '</span>'),
79 'level:language' => array('<span style="font-weight: bold; color: #000080;">', '</span>'),
80 'level:fieldname' => array('<span style="font-weight: bold; color: #666666;">', '</span>'),
81 'vDEF' => array('<span style="font-weight: bold; color: #008080;">', '</span>'),
82 'level:value' => array('<span style="font-weight: bold; color: #008080;">', '</span>'),
83 'currentSheetId' => array('<span style="color: #000080;">', '</span>'),
84 'currentLangId' => array('<span style="color: #000080;">', '</span>')
85 );
86
87 /**
88 * Deprecation constructor
89 */
90 public function __construct() {
91 \TYPO3\CMS\Core\Utility\GeneralUtility::deprecationLog('Class t3lib_syntaxhl is deprecated and unused since TYPO3 6.0. It will be removed with version 6.2.');
92 }
93
94
95 /*************************************
96 *
97 * Markup of Data Structure, <T3DataStructure>
98 *
99 *************************************/
100 /**
101 * Makes syntax highlighting of a Data Structure, <T3DataStructure>
102 *
103 * @param string $str Data Structure XML, must be valid since it's parsed.
104 * @return string HTML code with highlighted content. Must be wrapped in <PRE> tags
105 * @todo Define visibility
106 */
107 public function highLight_DS($str) {
108 // Parse DS to verify that it is valid:
109 $DS = \TYPO3\CMS\Core\Utility\GeneralUtility::xml2array($str);
110 if (is_array($DS)) {
111 // Complete list of tags in DS
112 $completeTagList = array_unique($this->getAllTags($str));
113 // Highlighting source:
114 // Init parser object
115 $this->htmlParse = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Html\\HtmlParser');
116 // Split the XML by the found tags, recursively into LARGE array.
117 $struct = $this->splitXMLbyTags(implode(',', $completeTagList), $str);
118 // Perform color-markup on the parsed content. Markup preserves the LINE formatting of the XML.
119 $markUp = $this->highLight_DS_markUpRecursively($struct);
120 // Return content:
121 return $markUp;
122 } else {
123 $error = 'ERROR: The input content failed XML parsing: ' . $DS;
124 }
125 return $error;
126 }
127
128 /**
129 * Making syntax highlighting of the parsed Data Structure XML.
130 * Called recursively.
131 *
132 * @param array $struct The structure, see splitXMLbyTags()
133 * @param string $parent Parent tag.
134 * @param string $app "Application" - used to denote if we are 'inside' a section
135 * @return string HTML
136 * @todo Define visibility
137 */
138 public function highLight_DS_markUpRecursively($struct, $parent = '', $app = '') {
139 $output = '';
140 foreach ($struct as $k => $v) {
141 if ($k % 2) {
142 $nextApp = $app;
143 $wrap = array('', '');
144 switch ($app) {
145 case 'TCEforms':
146
147 case 'tx_templavoila':
148 $wrap = $this->DS_wrapTags['_applicationContents'];
149 break;
150 case 'el':
151
152 default:
153 if ($parent == 'el') {
154 $wrap = $this->DS_wrapTags['parent:el'];
155 $nextApp = 'el';
156 } elseif ($parent == 'sheets') {
157 $wrap = $this->DS_wrapTags['parent:sheets'];
158 } else {
159 $wrap = $this->DS_wrapTags[$v['tagName']];
160 $nextApp = '';
161 }
162 // If no wrap defined, us "unknown" definition
163 if (!is_array($wrap)) {
164 $wrap = $this->DS_wrapTags['_unknown'];
165 }
166 // Check for application sections in the XML:
167 if ($app == 'el' || $parent == 'ROOT') {
168 switch ($v['tagName']) {
169 case 'TCEforms':
170
171 case 'tx_templavoila':
172 $nextApp = $v['tagName'];
173 $wrap = $this->DS_wrapTags['_applicationTag'];
174 break;
175 }
176 }
177 break;
178 }
179 $output .= $wrap[0] . htmlspecialchars($v['tag']) . $wrap[1];
180 $output .= $this->highLight_DS_markUpRecursively($v['sub'], $v['tagName'], $nextApp);
181 $output .= $wrap[0] . htmlspecialchars(('</' . $v['tagName'] . '>')) . $wrap[1];
182 } else {
183 $output .= htmlspecialchars($v);
184 }
185 }
186 return $output;
187 }
188
189 /*************************************
190 *
191 * Markup of Data Structure, <T3FlexForms>
192 *
193 *************************************/
194 /**
195 * Makes syntax highlighting of a FlexForm Data, <T3FlexForms>
196 *
197 * @param string $str Data Structure XML, must be valid since it's parsed.
198 * @return string HTML code with highlighted content. Must be wrapped in <PRE> tags
199 * @todo Define visibility
200 */
201 public function highLight_FF($str) {
202 // Parse DS to verify that it is valid:
203 $DS = \TYPO3\CMS\Core\Utility\GeneralUtility::xml2array($str);
204 if (is_array($DS)) {
205 // Complete list of tags in DS
206 $completeTagList = array_unique($this->getAllTags($str));
207 // Highlighting source:
208 // Init parser object
209 $this->htmlParse = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Html\\HtmlParser');
210 // Split the XML by the found tags, recursively into LARGE array.
211 $struct = $this->splitXMLbyTags(implode(',', $completeTagList), $str);
212 // Perform color-markup on the parsed content. Markup preserves the LINE formatting of the XML.
213 $markUp = $this->highLight_FF_markUpRecursively($struct);
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 $struct The structure, see splitXMLbyTags()
227 * @param string $parent Parent tag.
228 * @param string $app "Application" - used to denote if we are 'inside' a section
229 * @return string HTML
230 * @todo Define visibility
231 */
232 public function highLight_FF_markUpRecursively($struct, $parent = '', $app = '') {
233 $output = '';
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 // Traverse structure:
247 foreach ($struct as $k => $v) {
248 if ($k % 2) {
249 $wrap = array('', '');
250 if ($v['tagName'] == 'numIndex') {
251 $app = 'numIndex';
252 }
253 // Default wrap:
254 $wrap = $this->FF_wrapTags[$v['tagName']];
255 // If no wrap defined, us "unknown" definition
256 if (!is_array($wrap)) {
257 switch ($app) {
258 case 'sheet':
259
260 case 'language':
261
262 case 'fieldname':
263
264 case 'value':
265 $wrap = $this->FF_wrapTags['level:' . $app];
266 break;
267 default:
268 $wrap = $this->FF_wrapTags['_unknown'];
269 break;
270 }
271 }
272 if ($v['tagName'] == 'el') {
273 $app = 'el';
274 }
275 $output .= $wrap[0] . htmlspecialchars($v['tag']) . $wrap[1];
276 $output .= $this->highLight_FF_markUpRecursively($v['sub'], $v['tagName'], $app);
277 $output .= $wrap[0] . htmlspecialchars(('</' . $v['tagName'] . '>')) . $wrap[1];
278 } else {
279 $output .= htmlspecialchars($v);
280 }
281 }
282 return $output;
283 }
284
285 /*************************************
286 *
287 * Various
288 *
289 *************************************/
290 /**
291 * Returning all tag names found in XML/HTML input string
292 *
293 * @param string $str HTML/XML input
294 * @return array Array with all found tags (starttags only)
295 * @todo Define visibility
296 */
297 public function getAllTags($str) {
298 // Init:
299 $tags = array();
300 $token = md5(microtime());
301 // Markup all tag names with token.
302 $markUpStr = preg_replace('/<([[:alnum:]_]+)[^>]*>/', $token . '${1}' . $token, $str);
303 // Splitting by token:
304 $parts = explode($token, $markUpStr);
305 // Traversing parts:
306 foreach ($parts as $k => $v) {
307 if ($k % 2) {
308 $tags[] = $v;
309 }
310 }
311 // Returning tags:
312 return $tags;
313 }
314
315 /**
316 * Splitting the input source by the tags listing in $tagList.
317 * Called recursively.
318 *
319 * @param string $tagList Commalist of tags to split source by (into blocks, ALL being block-tags!)
320 * @param string $str Input string.
321 * @return array Array with the content arranged hierarchically.
322 * @todo Define visibility
323 */
324 public function splitXMLbyTags($tagList, $str) {
325 $struct = $this->htmlParse->splitIntoBlock($tagList, $str);
326 // Traverse level:
327 foreach ($struct as $k => $v) {
328 if ($k % 2) {
329 $tag = $this->htmlParse->getFirstTag($v);
330 $tagName = $this->htmlParse->getFirstTagName($tag, TRUE);
331 $struct[$k] = array(
332 'tag' => $tag,
333 'tagName' => $tagName,
334 'sub' => $this->splitXMLbyTags($tagList, $this->htmlParse->removeFirstAndLastTag($struct[$k]))
335 );
336 }
337 }
338 return $struct;
339 }
340
341 }
342
343 ?>