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