PageRenderTime 37ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/t3lib/class.t3lib_syntaxhl.php

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