PageRenderTime 57ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/LexHTML.cxx

https://bitbucket.org/th3flyboy/ogre-nullrenderexperiment
C++ | 2042 lines | 1862 code | 98 blank | 82 comment | 1346 complexity | 9179db5d6ae2745b7798210e0bf8c181 MD5 | raw file
Possible License(s): MIT, LGPL-2.1

Large files files are truncated, but you can click here to view the full file

  1. // Scintilla source code edit control
  2. /** @file LexHTML.cxx
  3. ** Lexer for HTML.
  4. **/
  5. // Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
  6. // The License.txt file describes the conditions under which this software may be distributed.
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <ctype.h>
  10. #include <stdio.h>
  11. #include <stdarg.h>
  12. #include "Platform.h"
  13. #include "PropSet.h"
  14. #include "Accessor.h"
  15. #include "StyleContext.h"
  16. #include "KeyWords.h"
  17. #include "Scintilla.h"
  18. #include "SciLexer.h"
  19. #define SCE_HA_JS (SCE_HJA_START - SCE_HJ_START)
  20. #define SCE_HA_VBS (SCE_HBA_START - SCE_HB_START)
  21. #define SCE_HA_PYTHON (SCE_HPA_START - SCE_HP_START)
  22. enum script_type { eScriptNone = 0, eScriptJS, eScriptVBS, eScriptPython, eScriptPHP, eScriptXML, eScriptSGML, eScriptSGMLblock };
  23. enum script_mode { eHtml = 0, eNonHtmlScript, eNonHtmlPreProc, eNonHtmlScriptPreProc };
  24. static inline bool IsAWordChar(const int ch) {
  25. return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
  26. }
  27. static inline bool IsAWordStart(const int ch) {
  28. return (ch < 0x80) && (isalnum(ch) || ch == '_');
  29. }
  30. static inline int MakeLowerCase(int ch) {
  31. if (ch < 'A' || ch > 'Z')
  32. return ch;
  33. else
  34. return ch - 'A' + 'a';
  35. }
  36. static void GetTextSegment(Accessor &styler, unsigned int start, unsigned int end, char *s, size_t len) {
  37. size_t i = 0;
  38. for (; (i < end - start + 1) && (i < len-1); i++) {
  39. s[i] = static_cast<char>(MakeLowerCase(styler[start + i]));
  40. }
  41. s[i] = '\0';
  42. }
  43. static script_type segIsScriptingIndicator(Accessor &styler, unsigned int start, unsigned int end, script_type prevValue) {
  44. char s[100];
  45. GetTextSegment(styler, start, end, s, sizeof(s));
  46. //Platform::DebugPrintf("Scripting indicator [%s]\n", s);
  47. if (strstr(s, "src")) // External script
  48. return eScriptNone;
  49. if (strstr(s, "vbs"))
  50. return eScriptVBS;
  51. if (strstr(s, "pyth"))
  52. return eScriptPython;
  53. if (strstr(s, "javas"))
  54. return eScriptJS;
  55. if (strstr(s, "jscr"))
  56. return eScriptJS;
  57. if (strstr(s, "php"))
  58. return eScriptPHP;
  59. if (strstr(s, "xml"))
  60. return eScriptXML;
  61. return prevValue;
  62. }
  63. static int PrintScriptingIndicatorOffset(Accessor &styler, unsigned int start, unsigned int end) {
  64. int iResult = 0;
  65. char s[100];
  66. GetTextSegment(styler, start, end, s, sizeof(s));
  67. if (0 == strncmp(s, "php", 3)) {
  68. iResult = 3;
  69. }
  70. return iResult;
  71. }
  72. static script_type ScriptOfState(int state) {
  73. if ((state >= SCE_HP_START) && (state <= SCE_HP_IDENTIFIER)) {
  74. return eScriptPython;
  75. } else if ((state >= SCE_HB_START) && (state <= SCE_HB_STRINGEOL)) {
  76. return eScriptVBS;
  77. } else if ((state >= SCE_HJ_START) && (state <= SCE_HJ_REGEX)) {
  78. return eScriptJS;
  79. } else if ((state >= SCE_HPHP_DEFAULT) && (state <= SCE_HPHP_COMMENTLINE)) {
  80. return eScriptPHP;
  81. } else if ((state >= SCE_H_SGML_DEFAULT) && (state < SCE_H_SGML_BLOCK_DEFAULT)) {
  82. return eScriptSGML;
  83. } else if (state == SCE_H_SGML_BLOCK_DEFAULT) {
  84. return eScriptSGMLblock;
  85. } else {
  86. return eScriptNone;
  87. }
  88. }
  89. static int statePrintForState(int state, script_mode inScriptType) {
  90. int StateToPrint;
  91. if ((state >= SCE_HP_START) && (state <= SCE_HP_IDENTIFIER)) {
  92. StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_PYTHON);
  93. } else if ((state >= SCE_HB_START) && (state <= SCE_HB_STRINGEOL)) {
  94. StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_VBS);
  95. } else if ((state >= SCE_HJ_START) && (state <= SCE_HJ_REGEX)) {
  96. StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_JS);
  97. } else {
  98. StateToPrint = state;
  99. }
  100. return StateToPrint;
  101. }
  102. static int stateForPrintState(int StateToPrint) {
  103. int state;
  104. if ((StateToPrint >= SCE_HPA_START) && (StateToPrint <= SCE_HPA_IDENTIFIER)) {
  105. state = StateToPrint - SCE_HA_PYTHON;
  106. } else if ((StateToPrint >= SCE_HBA_START) && (StateToPrint <= SCE_HBA_STRINGEOL)) {
  107. state = StateToPrint - SCE_HA_VBS;
  108. } else if ((StateToPrint >= SCE_HJA_START) && (StateToPrint <= SCE_HJA_REGEX)) {
  109. state = StateToPrint - SCE_HA_JS;
  110. } else {
  111. state = StateToPrint;
  112. }
  113. return state;
  114. }
  115. static inline bool IsNumber(unsigned int start, Accessor &styler) {
  116. return IsADigit(styler[start]) || (styler[start] == '.') ||
  117. (styler[start] == '-') || (styler[start] == '#');
  118. }
  119. static inline bool isStringState(int state) {
  120. bool bResult;
  121. switch (state) {
  122. case SCE_HJ_DOUBLESTRING:
  123. case SCE_HJ_SINGLESTRING:
  124. case SCE_HJA_DOUBLESTRING:
  125. case SCE_HJA_SINGLESTRING:
  126. case SCE_HB_STRING:
  127. case SCE_HBA_STRING:
  128. case SCE_HP_STRING:
  129. case SCE_HP_CHARACTER:
  130. case SCE_HP_TRIPLE:
  131. case SCE_HP_TRIPLEDOUBLE:
  132. case SCE_HPA_STRING:
  133. case SCE_HPA_CHARACTER:
  134. case SCE_HPA_TRIPLE:
  135. case SCE_HPA_TRIPLEDOUBLE:
  136. case SCE_HPHP_HSTRING:
  137. case SCE_HPHP_SIMPLESTRING:
  138. case SCE_HPHP_HSTRING_VARIABLE:
  139. case SCE_HPHP_COMPLEX_VARIABLE:
  140. bResult = true;
  141. break;
  142. default :
  143. bResult = false;
  144. break;
  145. }
  146. return bResult;
  147. }
  148. static inline bool stateAllowsTermination(int state) {
  149. bool allowTermination = !isStringState(state);
  150. if (allowTermination) {
  151. switch (state) {
  152. case SCE_HPHP_COMMENT:
  153. case SCE_HP_COMMENTLINE:
  154. case SCE_HPA_COMMENTLINE:
  155. allowTermination = false;
  156. }
  157. }
  158. return allowTermination;
  159. }
  160. // not really well done, since it's only comments that should lex the %> and <%
  161. static inline bool isCommentASPState(int state) {
  162. bool bResult;
  163. switch (state) {
  164. case SCE_HJ_COMMENT:
  165. case SCE_HJ_COMMENTLINE:
  166. case SCE_HJ_COMMENTDOC:
  167. case SCE_HB_COMMENTLINE:
  168. case SCE_HP_COMMENTLINE:
  169. case SCE_HPHP_COMMENT:
  170. case SCE_HPHP_COMMENTLINE:
  171. bResult = true;
  172. break;
  173. default :
  174. bResult = false;
  175. break;
  176. }
  177. return bResult;
  178. }
  179. static void classifyAttribHTML(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
  180. bool wordIsNumber = IsNumber(start, styler);
  181. char chAttr = SCE_H_ATTRIBUTEUNKNOWN;
  182. if (wordIsNumber) {
  183. chAttr = SCE_H_NUMBER;
  184. } else {
  185. char s[100];
  186. GetTextSegment(styler, start, end, s, sizeof(s));
  187. if (keywords.InList(s))
  188. chAttr = SCE_H_ATTRIBUTE;
  189. }
  190. if ((chAttr == SCE_H_ATTRIBUTEUNKNOWN) && !keywords)
  191. // No keywords -> all are known
  192. chAttr = SCE_H_ATTRIBUTE;
  193. styler.ColourTo(end, chAttr);
  194. }
  195. static int classifyTagHTML(unsigned int start, unsigned int end,
  196. WordList &keywords, Accessor &styler, bool &tagDontFold,
  197. bool caseSensitive) {
  198. char s[30 + 2];
  199. // Copy after the '<'
  200. unsigned int i = 0;
  201. for (unsigned int cPos = start; cPos <= end && i < 30; cPos++) {
  202. char ch = styler[cPos];
  203. if ((ch != '<') && (ch != '/')) {
  204. s[i++] = caseSensitive ? ch : static_cast<char>(MakeLowerCase(ch));
  205. }
  206. }
  207. //The following is only a quick hack, to see if this whole thing would work
  208. //we first need the tagname with a trailing space...
  209. s[i] = ' ';
  210. s[i+1] = '\0';
  211. //...to find it in the list of no-container-tags
  212. // (There are many more. We will need a keywordlist in the property file for this)
  213. tagDontFold = (NULL != strstr("meta link img area br hr input ",s));
  214. //now we can remove the trailing space
  215. s[i] = '\0';
  216. bool isScript = false;
  217. char chAttr = SCE_H_TAGUNKNOWN;
  218. if (s[0] == '!') {
  219. chAttr = SCE_H_SGML_DEFAULT;
  220. } else if (s[0] == '/') { // Closing tag
  221. if (keywords.InList(s + 1))
  222. chAttr = SCE_H_TAG;
  223. } else {
  224. if (keywords.InList(s)) {
  225. chAttr = SCE_H_TAG;
  226. isScript = 0 == strcmp(s, "script");
  227. }
  228. }
  229. if ((chAttr == SCE_H_TAGUNKNOWN) && !keywords) {
  230. // No keywords -> all are known
  231. chAttr = SCE_H_TAG;
  232. isScript = 0 == strcmp(s, "script");
  233. }
  234. styler.ColourTo(end, chAttr);
  235. return isScript ? SCE_H_SCRIPT : chAttr;
  236. }
  237. static void classifyWordHTJS(unsigned int start, unsigned int end,
  238. WordList &keywords, Accessor &styler, script_mode inScriptType) {
  239. char chAttr = SCE_HJ_WORD;
  240. bool wordIsNumber = IsADigit(styler[start]) || (styler[start] == '.');
  241. if (wordIsNumber)
  242. chAttr = SCE_HJ_NUMBER;
  243. else {
  244. char s[30 + 1];
  245. unsigned int i = 0;
  246. for (; i < end - start + 1 && i < 30; i++) {
  247. s[i] = styler[start + i];
  248. }
  249. s[i] = '\0';
  250. if (keywords.InList(s))
  251. chAttr = SCE_HJ_KEYWORD;
  252. }
  253. styler.ColourTo(end, statePrintForState(chAttr, inScriptType));
  254. }
  255. static int classifyWordHTVB(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, script_mode inScriptType) {
  256. char chAttr = SCE_HB_IDENTIFIER;
  257. bool wordIsNumber = IsADigit(styler[start]) || (styler[start] == '.');
  258. if (wordIsNumber)
  259. chAttr = SCE_HB_NUMBER;
  260. else {
  261. char s[100];
  262. GetTextSegment(styler, start, end, s, sizeof(s));
  263. if (keywords.InList(s)) {
  264. chAttr = SCE_HB_WORD;
  265. if (strcmp(s, "rem") == 0)
  266. chAttr = SCE_HB_COMMENTLINE;
  267. }
  268. }
  269. styler.ColourTo(end, statePrintForState(chAttr, inScriptType));
  270. if (chAttr == SCE_HB_COMMENTLINE)
  271. return SCE_HB_COMMENTLINE;
  272. else
  273. return SCE_HB_DEFAULT;
  274. }
  275. static void classifyWordHTPy(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord, script_mode inScriptType) {
  276. bool wordIsNumber = IsADigit(styler[start]);
  277. char s[30 + 1];
  278. unsigned int i = 0;
  279. for (; i < end - start + 1 && i < 30; i++) {
  280. s[i] = styler[start + i];
  281. }
  282. s[i] = '\0';
  283. char chAttr = SCE_HP_IDENTIFIER;
  284. if (0 == strcmp(prevWord, "class"))
  285. chAttr = SCE_HP_CLASSNAME;
  286. else if (0 == strcmp(prevWord, "def"))
  287. chAttr = SCE_HP_DEFNAME;
  288. else if (wordIsNumber)
  289. chAttr = SCE_HP_NUMBER;
  290. else if (keywords.InList(s))
  291. chAttr = SCE_HP_WORD;
  292. styler.ColourTo(end, statePrintForState(chAttr, inScriptType));
  293. strcpy(prevWord, s);
  294. }
  295. // Update the word colour to default or keyword
  296. // Called when in a PHP word
  297. static void classifyWordHTPHP(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
  298. char chAttr = SCE_HPHP_DEFAULT;
  299. bool wordIsNumber = IsADigit(styler[start]) || (styler[start] == '.' && start+1 <= end && IsADigit(styler[start+1]));
  300. if (wordIsNumber)
  301. chAttr = SCE_HPHP_NUMBER;
  302. else {
  303. char s[100];
  304. GetTextSegment(styler, start, end, s, sizeof(s));
  305. if (keywords.InList(s))
  306. chAttr = SCE_HPHP_WORD;
  307. }
  308. styler.ColourTo(end, chAttr);
  309. }
  310. static bool isWordHSGML(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
  311. char s[30 + 1];
  312. unsigned int i = 0;
  313. for (; i < end - start + 1 && i < 30; i++) {
  314. s[i] = styler[start + i];
  315. }
  316. s[i] = '\0';
  317. return keywords.InList(s);
  318. }
  319. static bool isWordCdata(unsigned int start, unsigned int end, Accessor &styler) {
  320. char s[30 + 1];
  321. unsigned int i = 0;
  322. for (; i < end - start + 1 && i < 30; i++) {
  323. s[i] = styler[start + i];
  324. }
  325. s[i] = '\0';
  326. return (0 == strcmp(s, "[CDATA["));
  327. }
  328. // Return the first state to reach when entering a scripting language
  329. static int StateForScript(script_type scriptLanguage) {
  330. int Result;
  331. switch (scriptLanguage) {
  332. case eScriptVBS:
  333. Result = SCE_HB_START;
  334. break;
  335. case eScriptPython:
  336. Result = SCE_HP_START;
  337. break;
  338. case eScriptPHP:
  339. Result = SCE_HPHP_DEFAULT;
  340. break;
  341. case eScriptXML:
  342. Result = SCE_H_TAGUNKNOWN;
  343. break;
  344. case eScriptSGML:
  345. Result = SCE_H_SGML_DEFAULT;
  346. break;
  347. default :
  348. Result = SCE_HJ_START;
  349. break;
  350. }
  351. return Result;
  352. }
  353. static inline bool ishtmlwordchar(char ch) {
  354. return !isascii(ch) ||
  355. (isalnum(ch) || ch == '.' || ch == '-' || ch == '_' || ch == ':' || ch == '!' || ch == '#');
  356. }
  357. static inline bool issgmlwordchar(char ch) {
  358. return !isascii(ch) ||
  359. (isalnum(ch) || ch == '.' || ch == '_' || ch == ':' || ch == '!' || ch == '#' || ch == '[');
  360. }
  361. static inline bool IsPhpWordStart(const unsigned char ch) {
  362. return (isascii(ch) && (isalpha(ch) || (ch == '_'))) || (ch >= 0x7f);
  363. }
  364. static inline bool IsPhpWordChar(char ch) {
  365. return IsADigit(ch) || IsPhpWordStart(ch);
  366. }
  367. static bool InTagState(int state) {
  368. return state == SCE_H_TAG || state == SCE_H_TAGUNKNOWN ||
  369. state == SCE_H_SCRIPT ||
  370. state == SCE_H_ATTRIBUTE || state == SCE_H_ATTRIBUTEUNKNOWN ||
  371. state == SCE_H_NUMBER || state == SCE_H_OTHER ||
  372. state == SCE_H_DOUBLESTRING || state == SCE_H_SINGLESTRING;
  373. }
  374. static bool IsCommentState(const int state) {
  375. return state == SCE_H_COMMENT || state == SCE_H_SGML_COMMENT;
  376. }
  377. static bool IsScriptCommentState(const int state) {
  378. return state == SCE_HJ_COMMENT || state == SCE_HJ_COMMENTLINE || state == SCE_HJA_COMMENT ||
  379. state == SCE_HJA_COMMENTLINE || state == SCE_HB_COMMENTLINE || state == SCE_HBA_COMMENTLINE;
  380. }
  381. static bool isLineEnd(char ch) {
  382. return ch == '\r' || ch == '\n';
  383. }
  384. static bool isOKBeforeRE(char ch) {
  385. return (ch == '(') || (ch == '=') || (ch == ',');
  386. }
  387. static bool isPHPStringState(int state) {
  388. return
  389. (state == SCE_HPHP_HSTRING) ||
  390. (state == SCE_HPHP_SIMPLESTRING) ||
  391. (state == SCE_HPHP_HSTRING_VARIABLE) ||
  392. (state == SCE_HPHP_COMPLEX_VARIABLE);
  393. }
  394. static int FindPhpStringDelimiter(char *phpStringDelimiter, const int phpStringDelimiterSize, int i, const int lengthDoc, Accessor &styler) {
  395. int j;
  396. while (i < lengthDoc && (styler[i] == ' ' || styler[i] == '\t'))
  397. i++;
  398. phpStringDelimiter[0] = '\n';
  399. for (j = i; j < lengthDoc && styler[j] != '\n' && styler[j] != '\r'; j++) {
  400. if (j - i < phpStringDelimiterSize - 2)
  401. phpStringDelimiter[j-i+1] = styler[j];
  402. else
  403. i++;
  404. }
  405. phpStringDelimiter[j-i+1] = '\0';
  406. return j;
  407. }
  408. static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
  409. Accessor &styler) {
  410. WordList &keywords = *keywordlists[0];
  411. WordList &keywords2 = *keywordlists[1];
  412. WordList &keywords3 = *keywordlists[2];
  413. WordList &keywords4 = *keywordlists[3];
  414. WordList &keywords5 = *keywordlists[4];
  415. WordList &keywords6 = *keywordlists[5]; // SGML (DTD) keywords
  416. // Lexer for HTML requires more lexical states (7 bits worth) than most lexers
  417. styler.StartAt(startPos, STYLE_MAX);
  418. char prevWord[200];
  419. prevWord[0] = '\0';
  420. char phpStringDelimiter[200]; // PHP is not limited in length, we are
  421. phpStringDelimiter[0] = '\0';
  422. int StateToPrint = initStyle;
  423. int state = stateForPrintState(StateToPrint);
  424. // If inside a tag, it may be a script tag, so reread from the start to ensure any language tags are seen
  425. if (InTagState(state)) {
  426. while ((startPos > 0) && (InTagState(styler.StyleAt(startPos - 1)))) {
  427. startPos--;
  428. length++;
  429. }
  430. state = SCE_H_DEFAULT;
  431. }
  432. // String can be heredoc, must find a delimiter first
  433. while (startPos > 0 && isPHPStringState(state) && state != SCE_HPHP_SIMPLESTRING) {
  434. startPos--;
  435. length++;
  436. state = styler.StyleAt(startPos);
  437. }
  438. styler.StartAt(startPos, STYLE_MAX);
  439. int lineCurrent = styler.GetLine(startPos);
  440. int lineState;
  441. if (lineCurrent > 0) {
  442. lineState = styler.GetLineState(lineCurrent);
  443. } else {
  444. // Default client and ASP scripting language is JavaScript
  445. lineState = eScriptJS << 8;
  446. lineState |= styler.GetPropertyInt("asp.default.language", eScriptJS) << 4;
  447. }
  448. script_mode inScriptType = script_mode((lineState >> 0) & 0x03); // 2 bits of scripting mode
  449. bool tagOpened = (lineState >> 2) & 0x01; // 1 bit to know if we are in an opened tag
  450. bool tagClosing = (lineState >> 3) & 0x01; // 1 bit to know if we are in a closing tag
  451. bool tagDontFold = false; //some HTML tags should not be folded
  452. script_type aspScript = script_type((lineState >> 4) & 0x0F); // 4 bits of script name
  453. script_type clientScript = script_type((lineState >> 8) & 0x0F); // 4 bits of script name
  454. int beforePreProc = (lineState >> 12) & 0xFF; // 8 bits of state
  455. script_type scriptLanguage = ScriptOfState(state);
  456. const bool foldHTML = styler.GetPropertyInt("fold.html", 0) != 0;
  457. const bool fold = foldHTML && styler.GetPropertyInt("fold", 0);
  458. const bool foldHTMLPreprocessor = foldHTML && styler.GetPropertyInt("fold.html.preprocessor", 1);
  459. const bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
  460. const bool caseSensitive = styler.GetPropertyInt("html.tags.case.sensitive", 0) != 0;
  461. int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
  462. int levelCurrent = levelPrev;
  463. int visibleChars = 0;
  464. char chPrev = ' ';
  465. char ch = ' ';
  466. char chPrevNonWhite = ' ';
  467. // look back to set chPrevNonWhite properly for better regex colouring
  468. if (scriptLanguage == eScriptJS && startPos > 0) {
  469. int back = startPos;
  470. int style = 0;
  471. while (--back) {
  472. style = styler.StyleAt(back);
  473. if (style < SCE_HJ_DEFAULT || style > SCE_HJ_COMMENTDOC)
  474. // includes SCE_HJ_COMMENT & SCE_HJ_COMMENTLINE
  475. break;
  476. }
  477. if (style == SCE_HJ_SYMBOLS) {
  478. chPrevNonWhite = styler.SafeGetCharAt(back);
  479. }
  480. }
  481. styler.StartSegment(startPos);
  482. const int lengthDoc = startPos + length;
  483. for (int i = startPos; i < lengthDoc; i++) {
  484. const char chPrev2 = chPrev;
  485. chPrev = ch;
  486. if (!isspacechar(ch) && state != SCE_HJ_COMMENT &&
  487. state != SCE_HJ_COMMENTLINE && state != SCE_HJ_COMMENTDOC)
  488. chPrevNonWhite = ch;
  489. ch = styler[i];
  490. char chNext = styler.SafeGetCharAt(i + 1);
  491. const char chNext2 = styler.SafeGetCharAt(i + 2);
  492. // Handle DBCS codepages
  493. if (styler.IsLeadByte(ch)) {
  494. chPrev = ' ';
  495. i += 1;
  496. continue;
  497. }
  498. if ((!isspacechar(ch) || !foldCompact) && fold)
  499. visibleChars++;
  500. // decide what is the current state to print (depending of the script tag)
  501. StateToPrint = statePrintForState(state, inScriptType);
  502. // handle script folding
  503. if (fold) {
  504. switch (scriptLanguage) {
  505. case eScriptJS:
  506. case eScriptPHP:
  507. //not currently supported case eScriptVBS:
  508. if ((state != SCE_HPHP_COMMENT) && (state != SCE_HPHP_COMMENTLINE) && (state != SCE_HJ_COMMENT) && (state != SCE_HJ_COMMENTLINE) && (state != SCE_HJ_COMMENTDOC) && (!isStringState(state))) {
  509. //Platform::DebugPrintf("state=%d, StateToPrint=%d, initStyle=%d\n", state, StateToPrint, initStyle);
  510. //if ((state == SCE_HPHP_OPERATOR) || (state == SCE_HPHP_DEFAULT) || (state == SCE_HJ_SYMBOLS) || (state == SCE_HJ_START) || (state == SCE_HJ_DEFAULT)) {
  511. if ((ch == '{') || (ch == '}')) {
  512. levelCurrent += (ch == '{') ? 1 : -1;
  513. }
  514. }
  515. break;
  516. case eScriptPython:
  517. if (state != SCE_HP_COMMENTLINE) {
  518. if ((ch == ':') && ((chNext == '\n') || (chNext == '\r' && chNext2 == '\n'))) {
  519. levelCurrent++;
  520. } else if ((ch == '\n') && !((chNext == '\r') && (chNext2 == '\n')) && (chNext != '\n')) {
  521. // check if the number of tabs is lower than the level
  522. int Findlevel = (levelCurrent & ~SC_FOLDLEVELBASE) * 8;
  523. for (int j = 0; Findlevel > 0; j++) {
  524. char chTmp = styler.SafeGetCharAt(i + j + 1);
  525. if (chTmp == '\t') {
  526. Findlevel -= 8;
  527. } else if (chTmp == ' ') {
  528. Findlevel--;
  529. } else {
  530. break;
  531. }
  532. }
  533. if (Findlevel > 0) {
  534. levelCurrent -= Findlevel / 8;
  535. if (Findlevel % 8)
  536. levelCurrent--;
  537. }
  538. }
  539. }
  540. break;
  541. default:
  542. break;
  543. }
  544. }
  545. if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
  546. // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
  547. // Avoid triggering two times on Dos/Win
  548. // New line -> record any line state onto /next/ line
  549. if (fold) {
  550. int lev = levelPrev;
  551. if (visibleChars == 0)
  552. lev |= SC_FOLDLEVELWHITEFLAG;
  553. if ((levelCurrent > levelPrev) && (visibleChars > 0))
  554. lev |= SC_FOLDLEVELHEADERFLAG;
  555. styler.SetLevel(lineCurrent, lev);
  556. visibleChars = 0;
  557. levelPrev = levelCurrent;
  558. }
  559. lineCurrent++;
  560. styler.SetLineState(lineCurrent,
  561. ((inScriptType & 0x03) << 0) |
  562. ((tagOpened & 0x01) << 2) |
  563. ((tagClosing & 0x01) << 3) |
  564. ((aspScript & 0x0F) << 4) |
  565. ((clientScript & 0x0F) << 8) |
  566. ((beforePreProc & 0xFF) << 12));
  567. }
  568. // generic end of script processing
  569. else if ((inScriptType == eNonHtmlScript) && (ch == '<') && (chNext == '/')) {
  570. // Check if it's the end of the script tag (or any other HTML tag)
  571. switch (state) {
  572. // in these cases, you can embed HTML tags (to confirm !!!!!!!!!!!!!!!!!!!!!!)
  573. case SCE_H_DOUBLESTRING:
  574. case SCE_H_SINGLESTRING:
  575. case SCE_HJ_COMMENT:
  576. case SCE_HJ_COMMENTDOC:
  577. //case SCE_HJ_COMMENTLINE: // removed as this is a common thing done to hide
  578. // the end of script marker from some JS interpreters.
  579. case SCE_HJ_DOUBLESTRING:
  580. case SCE_HJ_SINGLESTRING:
  581. case SCE_HJ_REGEX:
  582. case SCE_HB_STRING:
  583. case SCE_HP_STRING:
  584. case SCE_HP_TRIPLE:
  585. case SCE_HP_TRIPLEDOUBLE:
  586. break;
  587. default :
  588. // check if the closing tag is a script tag
  589. if (state == SCE_HJ_COMMENTLINE) {
  590. char tag[7]; // room for the <script> tag
  591. char chr; // current char
  592. int j=0;
  593. chr = styler.SafeGetCharAt(i+2);
  594. while (j < 6 && !isspacechar(chr)) {
  595. tag[j++] = static_cast<char>(MakeLowerCase(chr));
  596. chr = styler.SafeGetCharAt(i+2+j);
  597. }
  598. tag[j] = '\0';
  599. if (strcmp(tag, "script") != 0) break;
  600. }
  601. // closing tag of the script (it's a closing HTML tag anyway)
  602. styler.ColourTo(i - 1, StateToPrint);
  603. state = SCE_H_TAGUNKNOWN;
  604. inScriptType = eHtml;
  605. scriptLanguage = eScriptNone;
  606. clientScript = eScriptJS;
  607. i += 2;
  608. visibleChars += 2;
  609. tagClosing = true;
  610. continue;
  611. }
  612. }
  613. /////////////////////////////////////
  614. // handle the start of PHP pre-processor = Non-HTML
  615. else if ((state != SCE_H_ASPAT) &&
  616. !isPHPStringState(state) &&
  617. (state != SCE_HPHP_COMMENT) &&
  618. (ch == '<') &&
  619. (chNext == '?') &&
  620. !IsScriptCommentState(state) ) {
  621. scriptLanguage = segIsScriptingIndicator(styler, i + 2, i + 10, eScriptPHP);
  622. if (scriptLanguage != eScriptPHP && isStringState(state)) continue;
  623. styler.ColourTo(i - 1, StateToPrint);
  624. beforePreProc = state;
  625. i++;
  626. visibleChars++;
  627. i += PrintScriptingIndicatorOffset(styler, styler.GetStartSegment() + 2, i + 10);
  628. if (scriptLanguage == eScriptXML)
  629. styler.ColourTo(i, SCE_H_XMLSTART);
  630. else
  631. styler.ColourTo(i, SCE_H_QUESTION);
  632. state = StateForScript(scriptLanguage);
  633. if (inScriptType == eNonHtmlScript)
  634. inScriptType = eNonHtmlScriptPreProc;
  635. else
  636. inScriptType = eNonHtmlPreProc;
  637. // Fold whole script, but not if the XML first tag (all XML-like tags in this case)
  638. if (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) {
  639. levelCurrent++;
  640. }
  641. // should be better
  642. ch = styler.SafeGetCharAt(i);
  643. continue;
  644. }
  645. // handle the start of ASP pre-processor = Non-HTML
  646. else if (!isCommentASPState(state) && (ch == '<') && (chNext == '%') && !isPHPStringState(state)) {
  647. styler.ColourTo(i - 1, StateToPrint);
  648. beforePreProc = state;
  649. if (inScriptType == eNonHtmlScript)
  650. inScriptType = eNonHtmlScriptPreProc;
  651. else
  652. inScriptType = eNonHtmlPreProc;
  653. if (chNext2 == '@') {
  654. i += 2; // place as if it was the second next char treated
  655. visibleChars += 2;
  656. state = SCE_H_ASPAT;
  657. } else if ((chNext2 == '-') && (styler.SafeGetCharAt(i + 3) == '-')) {
  658. styler.ColourTo(i + 3, SCE_H_ASP);
  659. state = SCE_H_XCCOMMENT;
  660. scriptLanguage = eScriptVBS;
  661. continue;
  662. } else {
  663. if (chNext2 == '=') {
  664. i += 2; // place as if it was the second next char treated
  665. visibleChars += 2;
  666. } else {
  667. i++; // place as if it was the next char treated
  668. visibleChars++;
  669. }
  670. state = StateForScript(aspScript);
  671. }
  672. scriptLanguage = eScriptVBS;
  673. styler.ColourTo(i, SCE_H_ASP);
  674. // fold whole script
  675. if (foldHTMLPreprocessor)
  676. levelCurrent++;
  677. // should be better
  678. ch = styler.SafeGetCharAt(i);
  679. continue;
  680. }
  681. /////////////////////////////////////
  682. // handle the start of SGML language (DTD)
  683. else if (((scriptLanguage == eScriptNone) || (scriptLanguage == eScriptXML)) &&
  684. (chPrev == '<') &&
  685. (ch == '!') &&
  686. (StateToPrint != SCE_H_CDATA) &&
  687. (!IsCommentState(StateToPrint)) &&
  688. (!IsScriptCommentState(StateToPrint)) ) {
  689. beforePreProc = state;
  690. styler.ColourTo(i - 2, StateToPrint);
  691. if ((chNext == '-') && (chNext2 == '-')) {
  692. state = SCE_H_COMMENT; // wait for a pending command
  693. styler.ColourTo(i + 2, SCE_H_COMMENT);
  694. i += 2; // follow styling after the --
  695. } else if (isWordCdata(i + 1, i + 7, styler)) {
  696. state = SCE_H_CDATA;
  697. } else {
  698. styler.ColourTo(i, SCE_H_SGML_DEFAULT); // <! is default
  699. scriptLanguage = eScriptSGML;
  700. state = SCE_H_SGML_COMMAND; // wait for a pending command
  701. }
  702. // fold whole tag (-- when closing the tag)
  703. if (foldHTMLPreprocessor)
  704. levelCurrent++;
  705. continue;
  706. }
  707. // handle the end of a pre-processor = Non-HTML
  708. else if ((
  709. ((inScriptType == eNonHtmlPreProc)
  710. || (inScriptType == eNonHtmlScriptPreProc)) && (
  711. ((scriptLanguage != eScriptNone) && stateAllowsTermination(state) && ((ch == '%') || (ch == '?')))
  712. ) && (chNext == '>')) ||
  713. ((scriptLanguage == eScriptSGML) && (ch == '>') && (state != SCE_H_SGML_COMMENT))) {
  714. if (state == SCE_H_ASPAT) {
  715. aspScript = segIsScriptingIndicator(styler,
  716. styler.GetStartSegment(), i - 1, aspScript);
  717. }
  718. // Bounce out of any ASP mode
  719. switch (state) {
  720. case SCE_HJ_WORD:
  721. classifyWordHTJS(styler.GetStartSegment(), i - 1, keywords2, styler, inScriptType);
  722. break;
  723. case SCE_HB_WORD:
  724. classifyWordHTVB(styler.GetStartSegment(), i - 1, keywords3, styler, inScriptType);
  725. break;
  726. case SCE_HP_WORD:
  727. classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType);
  728. break;
  729. case SCE_HPHP_WORD:
  730. classifyWordHTPHP(styler.GetStartSegment(), i - 1, keywords5, styler);
  731. break;
  732. case SCE_H_XCCOMMENT:
  733. styler.ColourTo(i - 1, state);
  734. break;
  735. default :
  736. styler.ColourTo(i - 1, StateToPrint);
  737. break;
  738. }
  739. if (scriptLanguage != eScriptSGML) {
  740. i++;
  741. visibleChars++;
  742. }
  743. if (ch == '%')
  744. styler.ColourTo(i, SCE_H_ASP);
  745. else if (scriptLanguage == eScriptXML)
  746. styler.ColourTo(i, SCE_H_XMLEND);
  747. else if (scriptLanguage == eScriptSGML)
  748. styler.ColourTo(i, SCE_H_SGML_DEFAULT);
  749. else
  750. styler.ColourTo(i, SCE_H_QUESTION);
  751. state = beforePreProc;
  752. if (inScriptType == eNonHtmlScriptPreProc)
  753. inScriptType = eNonHtmlScript;
  754. else
  755. inScriptType = eHtml;
  756. // Unfold all scripting languages, except for XML tag
  757. if (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) {
  758. levelCurrent--;
  759. }
  760. scriptLanguage = eScriptNone;
  761. continue;
  762. }
  763. /////////////////////////////////////
  764. switch (state) {
  765. case SCE_H_DEFAULT:
  766. if (ch == '<') {
  767. // in HTML, fold on tag open and unfold on tag close
  768. tagOpened = true;
  769. tagClosing = (chNext == '/');
  770. styler.ColourTo(i - 1, StateToPrint);
  771. if (chNext != '!')
  772. state = SCE_H_TAGUNKNOWN;
  773. } else if (ch == '&') {
  774. styler.ColourTo(i - 1, SCE_H_DEFAULT);
  775. state = SCE_H_ENTITY;
  776. }
  777. break;
  778. case SCE_H_SGML_DEFAULT:
  779. case SCE_H_SGML_BLOCK_DEFAULT:
  780. // if (scriptLanguage == eScriptSGMLblock)
  781. // StateToPrint = SCE_H_SGML_BLOCK_DEFAULT;
  782. if (ch == '\"') {
  783. styler.ColourTo(i - 1, StateToPrint);
  784. state = SCE_H_SGML_DOUBLESTRING;
  785. } else if (ch == '\'') {
  786. styler.ColourTo(i - 1, StateToPrint);
  787. state = SCE_H_SGML_SIMPLESTRING;
  788. } else if ((ch == '-') && (chPrev == '-')) {
  789. styler.ColourTo(i - 2, StateToPrint);
  790. state = SCE_H_SGML_COMMENT;
  791. } else if (isascii(ch) && isalpha(ch) && (chPrev == '%')) {
  792. styler.ColourTo(i - 2, StateToPrint);
  793. state = SCE_H_SGML_ENTITY;
  794. } else if (ch == '#') {
  795. styler.ColourTo(i - 1, StateToPrint);
  796. state = SCE_H_SGML_SPECIAL;
  797. } else if (ch == '[') {
  798. styler.ColourTo(i - 1, StateToPrint);
  799. scriptLanguage = eScriptSGMLblock;
  800. state = SCE_H_SGML_BLOCK_DEFAULT;
  801. } else if (ch == ']') {
  802. if (scriptLanguage == eScriptSGMLblock) {
  803. styler.ColourTo(i, StateToPrint);
  804. scriptLanguage = eScriptSGML;
  805. } else {
  806. styler.ColourTo(i - 1, StateToPrint);
  807. styler.ColourTo(i, SCE_H_SGML_ERROR);
  808. }
  809. state = SCE_H_SGML_DEFAULT;
  810. } else if (scriptLanguage == eScriptSGMLblock) {
  811. if ((ch == '!') && (chPrev == '<')) {
  812. styler.ColourTo(i - 2, StateToPrint);
  813. styler.ColourTo(i, SCE_H_SGML_DEFAULT);
  814. state = SCE_H_SGML_COMMAND;
  815. } else if (ch == '>') {
  816. styler.ColourTo(i - 1, StateToPrint);
  817. styler.ColourTo(i, SCE_H_SGML_DEFAULT);
  818. }
  819. }
  820. break;
  821. case SCE_H_SGML_COMMAND:
  822. if ((ch == '-') && (chPrev == '-')) {
  823. styler.ColourTo(i - 2, StateToPrint);
  824. state = SCE_H_SGML_COMMENT;
  825. } else if (!issgmlwordchar(ch)) {
  826. if (isWordHSGML(styler.GetStartSegment(), i - 1, keywords6, styler)) {
  827. styler.ColourTo(i - 1, StateToPrint);
  828. state = SCE_H_SGML_1ST_PARAM;
  829. } else {
  830. state = SCE_H_SGML_ERROR;
  831. }
  832. }
  833. break;
  834. case SCE_H_SGML_1ST_PARAM:
  835. // wait for the beginning of the word
  836. if ((ch == '-') && (chPrev == '-')) {
  837. if (scriptLanguage == eScriptSGMLblock) {
  838. styler.ColourTo(i - 2, SCE_H_SGML_BLOCK_DEFAULT);
  839. } else {
  840. styler.ColourTo(i - 2, SCE_H_SGML_DEFAULT);
  841. }
  842. state = SCE_H_SGML_1ST_PARAM_COMMENT;
  843. } else if (issgmlwordchar(ch)) {
  844. if (scriptLanguage == eScriptSGMLblock) {
  845. styler.ColourTo(i - 1, SCE_H_SGML_BLOCK_DEFAULT);
  846. } else {
  847. styler.ColourTo(i - 1, SCE_H_SGML_DEFAULT);
  848. }
  849. // find the length of the word
  850. int size = 1;
  851. while (ishtmlwordchar(styler.SafeGetCharAt(i + size)))
  852. size++;
  853. styler.ColourTo(i + size - 1, StateToPrint);
  854. i += size - 1;
  855. visibleChars += size - 1;
  856. ch = styler.SafeGetCharAt(i);
  857. if (scriptLanguage == eScriptSGMLblock) {
  858. state = SCE_H_SGML_BLOCK_DEFAULT;
  859. } else {
  860. state = SCE_H_SGML_DEFAULT;
  861. }
  862. continue;
  863. }
  864. break;
  865. case SCE_H_SGML_ERROR:
  866. if ((ch == '-') && (chPrev == '-')) {
  867. styler.ColourTo(i - 2, StateToPrint);
  868. state = SCE_H_SGML_COMMENT;
  869. }
  870. case SCE_H_SGML_DOUBLESTRING:
  871. if (ch == '\"') {
  872. styler.ColourTo(i, StateToPrint);
  873. state = SCE_H_SGML_DEFAULT;
  874. }
  875. break;
  876. case SCE_H_SGML_SIMPLESTRING:
  877. if (ch == '\'') {
  878. styler.ColourTo(i, StateToPrint);
  879. state = SCE_H_SGML_DEFAULT;
  880. }
  881. break;
  882. case SCE_H_SGML_COMMENT:
  883. if ((ch == '-') && (chPrev == '-')) {
  884. styler.ColourTo(i, StateToPrint);
  885. state = SCE_H_SGML_DEFAULT;
  886. }
  887. break;
  888. case SCE_H_CDATA:
  889. if ((chPrev2 == ']') && (chPrev == ']') && (ch == '>')) {
  890. styler.ColourTo(i, StateToPrint);
  891. state = SCE_H_DEFAULT;
  892. levelCurrent--;
  893. }
  894. break;
  895. case SCE_H_COMMENT:
  896. if ((chPrev2 == '-') && (chPrev == '-') && (ch == '>')) {
  897. styler.ColourTo(i, StateToPrint);
  898. state = SCE_H_DEFAULT;
  899. levelCurrent--;
  900. }
  901. break;
  902. case SCE_H_SGML_1ST_PARAM_COMMENT:
  903. if ((ch == '-') && (chPrev == '-')) {
  904. styler.ColourTo(i, SCE_H_SGML_COMMENT);
  905. state = SCE_H_SGML_1ST_PARAM;
  906. }
  907. break;
  908. case SCE_H_SGML_SPECIAL:
  909. if (!(isascii(ch) && isupper(ch))) {
  910. styler.ColourTo(i - 1, StateToPrint);
  911. if (isalnum(ch)) {
  912. state = SCE_H_SGML_ERROR;
  913. } else {
  914. state = SCE_H_SGML_DEFAULT;
  915. }
  916. }
  917. break;
  918. case SCE_H_SGML_ENTITY:
  919. if (ch == ';') {
  920. styler.ColourTo(i, StateToPrint);
  921. state = SCE_H_SGML_DEFAULT;
  922. } else if (!(isascii(ch) && isalnum(ch)) && ch != '-' && ch != '.') {
  923. styler.ColourTo(i, SCE_H_SGML_ERROR);
  924. state = SCE_H_SGML_DEFAULT;
  925. }
  926. break;
  927. case SCE_H_ENTITY:
  928. if (ch == ';') {
  929. styler.ColourTo(i, StateToPrint);
  930. state = SCE_H_DEFAULT;
  931. }
  932. if (ch != '#' && !(isascii(ch) && isalnum(ch)) // Should check that '#' follows '&', but it is unlikely anyway...
  933. && ch != '.' && ch != '-' && ch != '_' && ch != ':') { // valid in XML
  934. styler.ColourTo(i, SCE_H_TAGUNKNOWN);
  935. state = SCE_H_DEFAULT;
  936. }
  937. break;
  938. case SCE_H_TAGUNKNOWN:
  939. if (!ishtmlwordchar(ch) && !((ch == '/') && (chPrev == '<')) && ch != '[') {
  940. int eClass = classifyTagHTML(styler.GetStartSegment(),
  941. i - 1, keywords, styler, tagDontFold, caseSensitive);
  942. if (eClass == SCE_H_SCRIPT) {
  943. if (!tagClosing) {
  944. inScriptType = eNonHtmlScript;
  945. scriptLanguage = clientScript;
  946. eClass = SCE_H_TAG;
  947. } else {
  948. scriptLanguage = eScriptNone;
  949. eClass = SCE_H_TAG;
  950. }
  951. }
  952. if (ch == '>') {
  953. styler.ColourTo(i, eClass);
  954. if (inScriptType == eNonHtmlScript) {
  955. state = StateForScript(scriptLanguage);
  956. } else {
  957. state = SCE_H_DEFAULT;
  958. }
  959. tagOpened = false;
  960. if (!tagDontFold){
  961. if (tagClosing) {
  962. levelCurrent--;
  963. } else {
  964. levelCurrent++;
  965. }
  966. }
  967. tagClosing = false;
  968. } else if (ch == '/' && chNext == '>') {
  969. if (eClass == SCE_H_TAGUNKNOWN) {
  970. styler.ColourTo(i + 1, SCE_H_TAGUNKNOWN);
  971. } else {
  972. styler.ColourTo(i - 1, StateToPrint);
  973. styler.ColourTo(i + 1, SCE_H_TAGEND);
  974. }
  975. i++;
  976. ch = chNext;
  977. state = SCE_H_DEFAULT;
  978. tagOpened = false;
  979. } else {
  980. if (eClass != SCE_H_TAGUNKNOWN) {
  981. if (eClass == SCE_H_SGML_DEFAULT) {
  982. state = SCE_H_SGML_DEFAULT;
  983. } else {
  984. state = SCE_H_OTHER;
  985. }
  986. }
  987. }
  988. }
  989. break;
  990. case SCE_H_ATTRIBUTE:
  991. if (!ishtmlwordchar(ch) && ch != '/' && ch != '-') {
  992. if (inScriptType == eNonHtmlScript) {
  993. int scriptLanguagePrev = scriptLanguage;
  994. clientScript = segIsScriptingIndicator(styler, styler.GetStartSegment(), i - 1, scriptLanguage);
  995. scriptLanguage = clientScript;
  996. if ((scriptLanguagePrev != scriptLanguage) && (scriptLanguage == eScriptNone))
  997. inScriptType = eHtml;
  998. }
  999. classifyAttribHTML(styler.GetStartSegment(), i - 1, keywords, styler);
  1000. if (ch == '>') {
  1001. styler.ColourTo(i, SCE_H_TAG);
  1002. if (inScriptType == eNonHtmlScript) {
  1003. state = StateForScript(scriptLanguage);
  1004. } else {
  1005. state = SCE_H_DEFAULT;
  1006. }
  1007. tagOpened = false;
  1008. if (!tagDontFold){
  1009. if (tagClosing){
  1010. levelCurrent--;
  1011. } else {
  1012. levelCurrent++;
  1013. }
  1014. }
  1015. tagClosing = false;
  1016. } else if (ch == '=') {
  1017. styler.ColourTo(i, SCE_H_OTHER);
  1018. state = SCE_H_VALUE;
  1019. } else {
  1020. state = SCE_H_OTHER;
  1021. }
  1022. }
  1023. break;
  1024. case SCE_H_OTHER:
  1025. if (ch == '>') {
  1026. styler.ColourTo(i - 1, StateToPrint);
  1027. styler.ColourTo(i, SCE_H_TAG);
  1028. if (inScriptType == eNonHtmlScript) {
  1029. state = StateForScript(scriptLanguage);
  1030. } else {
  1031. state = SCE_H_DEFAULT;
  1032. }
  1033. tagOpened = false;
  1034. if (!tagDontFold){
  1035. if (tagClosing){
  1036. levelCurrent--;
  1037. } else {
  1038. levelCurrent++;
  1039. }
  1040. }
  1041. tagClosing = false;
  1042. } else if (ch == '\"') {
  1043. styler.ColourTo(i - 1, StateToPrint);
  1044. state = SCE_H_DOUBLESTRING;
  1045. } else if (ch == '\'') {
  1046. styler.ColourTo(i - 1, StateToPrint);
  1047. state = SCE_H_SINGLESTRING;
  1048. } else if (ch == '=') {
  1049. styler.ColourTo(i, StateToPrint);
  1050. state = SCE_H_VALUE;
  1051. } else if (ch == '/' && chNext == '>') {
  1052. styler.ColourTo(i - 1, StateToPrint);
  1053. styler.ColourTo(i + 1, SCE_H_TAGEND);
  1054. i++;
  1055. ch = chNext;
  1056. state = SCE_H_DEFAULT;
  1057. tagOpened = false;
  1058. } else if (ch == '?' && chNext == '>') {
  1059. styler.ColourTo(i - 1, StateToPrint);
  1060. styler.ColourTo(i + 1, SCE_H_XMLEND);
  1061. i++;
  1062. ch = chNext;
  1063. state = SCE_H_DEFAULT;
  1064. } else if (ishtmlwordchar(ch)) {
  1065. styler.ColourTo(i - 1, StateToPrint);
  1066. state = SCE_H_ATTRIBUTE;
  1067. }
  1068. break;
  1069. case SCE_H_DOUBLESTRING:
  1070. if (ch == '\"') {
  1071. if (inScriptType == eNonHtmlScript) {
  1072. scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment(), i, scriptLanguage);
  1073. }
  1074. styler.ColourTo(i, SCE_H_DOUBLESTRING);
  1075. state = SCE_H_OTHER;
  1076. }
  1077. break;
  1078. case SCE_H_SINGLESTRING:
  1079. if (ch == '\'') {
  1080. if (inScriptType == eNonHtmlScript) {
  1081. scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment(), i, scriptLanguage);
  1082. }
  1083. styler.ColourTo(i, SCE_H_SINGLESTRING);
  1084. state = SCE_H_OTHER;
  1085. }
  1086. break;
  1087. case SCE_H_VALUE:
  1088. if (!ishtmlwordchar(ch)) {
  1089. if (ch == '\"' && chPrev == '=') {
  1090. // Should really test for being first character
  1091. state = SCE_H_DOUBLESTRING;
  1092. } else if (ch == '\'' && chPrev == '=') {
  1093. state = SCE_H_SINGLESTRING;
  1094. } else {
  1095. if (IsNumber(styler.GetStartSegment(), styler)) {
  1096. styler.ColourTo(i - 1, SCE_H_NUMBER);
  1097. } else {
  1098. styler.ColourTo(i - 1, StateToPrint);
  1099. }
  1100. if (ch == '>') {
  1101. styler.ColourTo(i, SCE_H_TAG);
  1102. if (inScriptType == eNonHtmlScript) {
  1103. state = StateForScript(scriptLanguage);
  1104. } else {
  1105. state = SCE_H_DEFAULT;
  1106. }
  1107. tagOpened = false;
  1108. if (!tagDontFold){
  1109. if (tagClosing){
  1110. levelCurrent--;
  1111. } else {
  1112. levelCurrent++;
  1113. }
  1114. }
  1115. tagClosing = false;
  1116. } else {
  1117. state = SCE_H_OTHER;
  1118. }
  1119. }
  1120. }
  1121. break;
  1122. case SCE_HJ_DEFAULT:
  1123. case SCE_HJ_START:
  1124. case SCE_HJ_SYMBOLS:
  1125. if (iswordstart(ch)) {
  1126. styler.ColourTo(i - 1, StateToPrint);
  1127. state = SCE_HJ_WORD;
  1128. } else if (ch == '/' && chNext == '*') {
  1129. styler.ColourTo(i - 1, StateToPrint);
  1130. if (chNext2 == '*')
  1131. state = SCE_HJ_COMMENTDOC;
  1132. else
  1133. state = SCE_HJ_COMMENT;
  1134. } else if (ch == '/' && chNext == '/') {
  1135. styler.ColourTo(i - 1, StateToPrint);
  1136. state = SCE_HJ_COMMENTLINE;
  1137. } else if (ch == '/' && isOKBeforeRE(chPrevNonWhite)) {
  1138. styler.ColourTo(i - 1, StateToPrint);
  1139. state = SCE_HJ_REGEX;
  1140. } else if (ch == '\"') {
  1141. styler.ColourTo(i - 1, StateToPrint);
  1142. state = SCE_HJ_DOUBLESTRING;
  1143. } else if (ch == '\'') {
  1144. styler.ColourTo(i - 1, StateToPrint);
  1145. state = SCE_HJ_SINGLESTRING;
  1146. } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') &&
  1147. styler.SafeGetCharAt(i + 3) == '-') {
  1148. styler.ColourTo(i - 1, StateToPrint);
  1149. state = SCE_HJ_COMMENTLINE;
  1150. } else if ((ch == '-') && (chNext == '-') && (chNext2 == '>')) {
  1151. styler.ColourTo(i - 1, StateToPrint);
  1152. state = SCE_HJ_COMMENTLINE;
  1153. i += 2;
  1154. } else if (isoperator(ch)) {
  1155. styler.ColourTo(i - 1, StateToPrint);
  1156. styler.ColourTo(i, statePrintForState(SCE_HJ_SYMBOLS, inScriptType));
  1157. state = SCE_HJ_DEFAULT;
  1158. } else if ((ch == ' ') || (ch == '\t')) {
  1159. if (state == SCE_HJ_START) {
  1160. styler.ColourTo(i - 1, StateToPrint);
  1161. state = SCE_HJ_DEFAULT;
  1162. }
  1163. }
  1164. break;
  1165. case SCE_HJ_WORD:
  1166. if (!iswordchar(ch)) {
  1167. classifyWordHTJS(styler.GetStartSegment(), i - 1, keywords2, styler, inScriptType);
  1168. //styler.ColourTo(i - 1, eHTJSKeyword);
  1169. state = SCE_HJ_DEFAULT;
  1170. if (ch == '/' && chNext == '*') {
  1171. if (chNext2 == '*')
  1172. state = SCE_HJ_COMMENTDOC;
  1173. else
  1174. state = SCE_HJ_COMMENT;
  1175. } else if (ch == '/' && chNext == '/') {
  1176. state = SCE_HJ_COMMENTLINE;
  1177. } else if (ch == '\"') {
  1178. state = SCE_HJ_DOUBLESTRING;
  1179. } else if (ch == '\'') {
  1180. state = SCE_HJ_SINGLESTRING;
  1181. } else if ((ch == '-') && (chNext == '-') && (chNext2 == '>')) {
  1182. styler.ColourTo(i - 1, StateToPrint);
  1183. state = SCE_HJ_COMMENTLINE;
  1184. i += 2;
  1185. } else if (isoperator(ch)) {
  1186. styler.ColourTo(i, statePrintForState(SCE_HJ_SYMBOLS, inScriptType));
  1187. state = SCE_HJ_DEFAULT;
  1188. }
  1189. }
  1190. break;
  1191. case SCE_HJ_COMMENT:
  1192. case SCE_HJ_COMMENTDOC:
  1193. if (ch == '/' && chPrev == '*') {
  1194. styler.ColourTo(i, StateToPrint);
  1195. state = SCE_HJ_DEFAULT;
  1196. ch = ' ';
  1197. }
  1198. break;
  1199. case SCE_HJ_COMMENTLINE:
  1200. if (ch == '\r' || ch == '\n') {
  1201. styler.ColourTo(i - 1, statePrintForState(SCE_HJ_COMMENTLINE, inScriptType));
  1202. state = SCE_HJ_DEFAULT;
  1203. ch = ' ';
  1204. }
  1205. break;
  1206. case SCE_HJ_DOUBLESTRING:
  1207. if (ch == '\\') {
  1208. if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
  1209. i++;
  1210. }
  1211. } else if (ch == '\"') {
  1212. styler.ColourTo(i, statePrintForState(SCE_HJ_DOUBLESTRING, inScriptType));
  1213. state = SCE_HJ_DEFAULT;
  1214. } else if ((inScriptType == eNonHtmlScript) && (ch == '-') && (chNext == '-') && (chNext2 == '>')) {
  1215. styler.ColourTo(i - 1, StateToPrint);
  1216. state = SCE_HJ_COMMENTLINE;
  1217. i += 2;
  1218. } else if (isLineEnd(ch)) {
  1219. styler.ColourTo(i - 1, StateToPrint);
  1220. state = SCE_HJ_STRINGEOL;
  1221. }
  1222. break;
  1223. case SCE_HJ_SINGLESTRING:
  1224. if (ch == '\\') {
  1225. if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
  1226. i++;
  1227. }
  1228. } else if (ch == '\'') {
  1229. styler.ColourTo(i, statePrintForState(SCE_HJ_SINGLESTRING, inScriptType));
  1230. state = SCE_HJ_DEFAULT;
  1231. } else if ((inScriptType == eNonHtmlScript) && (ch == '-') && (chNext == '-') && (chNext2 == '>')) {
  1232. styler.ColourTo(i - 1, StateToPrint);
  1233. state = SCE_HJ_COMMENTLINE;
  1234. i += 2;
  1235. } else if (isLineEnd(ch)) {
  1236. styler.ColourTo(i - 1, StateToPrint);
  1237. state = SCE_HJ_STRINGEOL;
  1238. }
  1239. break;
  1240. case SCE_HJ_STRINGEOL:
  1241. if (!isLineEnd(ch)) {
  1242. styler.ColourTo(i - 1, StateToPrint);
  1243. state = SCE_HJ_DEFAULT;
  1244. } else if (!isLineEnd(chNext)) {
  1245. styler.ColourTo(i, StateToPrint);
  1246. state = SCE_HJ_DEFAULT;
  1247. }
  1248. break;
  1249. case SCE_HJ_REGEX:
  1250. if (ch == '\r' || ch == '\n' || ch == '/') {
  1251. if (ch == '/') {
  1252. while (isascii(chNext) && islower(chNext)) { // gobble regex flags
  1253. i++;
  1254. ch = chNext;
  1255. chNext = styler.SafeGetCharAt(i + 1);
  1256. }
  1257. }
  1258. styler.ColourTo(i, StateToPrint);
  1259. state = SCE_HJ_DEFAULT;
  1260. } else if (ch == '\\') {
  1261. // Gobble up the quoted character
  1262. if (chNext == '\\' || chNext == '/') {
  1263. i++;
  1264. ch = chNext;
  1265. chNext = styler.SafeGetCharAt(i + 1);
  1266. }
  1267. }
  1268. break;
  1269. case SCE_HB_DEFAULT:
  1270. case SCE_HB_START:
  1271. if (iswordstart(ch)) {
  1272. styler.ColourTo(i - 1, StateToPrint);
  1273. state = SCE_HB_WORD;
  1274. } else if (ch == '\'') {
  1275. styler.ColourTo(i - 1, StateToPrint);
  1276. state = SCE_HB_COMMENTLINE;
  1277. } else if (ch == '\"') {
  1278. styler.ColourTo(i - 1, StateToPrint);
  1279. state = SCE_HB_STRING;
  1280. } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') &&
  1281. styler.SafeGetCharAt(i + 3) == '-') {
  1282. styler.ColourTo(i - 1, StateToPrint);
  1283. state = SCE_HB_COMMENTLINE;
  1284. } else if (isoperator(ch)) {
  1285. styler.ColourTo(i - 1, StateToPrint);
  1286. styler.ColourTo(i, statePrintForState(SCE_HB_DEFAULT, inScriptType));
  1287. state = SCE_HB_DEFAULT;
  1288. } else if ((ch == ' ') || (ch == '\t')) {
  1289. if (state == SCE_HB_START) {
  1290. styler.ColourTo(i - 1, StateToPrint);
  1291. state = SCE_HB_DEFAULT;
  1292. }
  1293. }
  1294. break;
  1295. case SCE_HB_WORD:
  1296. if (!iswordchar(ch)) {
  1297. state = classifyWordHTVB(styler.GetStartSegment(), i - 1, keywords3, styler, inScriptType);
  1298. if (state == SCE_HB_DEFAULT) {
  1299. if (ch == '\"') {
  1300. state = SCE_HB_STRING;
  1301. } else if (ch == '\'') {
  1302. state = SCE_HB_COMMENTLINE;
  1303. } else if (isoperator(ch)) {
  1304. styler.ColourTo(i, statePrintForState(SCE_HB_DEFAULT, inScriptType));
  1305. state = SCE_HB_DEFAULT;
  1306. }
  1307. }
  1308. }
  1309. break;
  1310. case SCE_HB_STRING:
  1311. if (ch == '\"') {
  1312. styler.ColourTo(i, StateToPrint);
  1313. state = SCE_HB_DEFAULT;
  1314. } else if (ch == '\r' || ch == '\n') {
  1315. styler.ColourTo(i - 1, StateToPrint);
  1316. state = SCE_HB_STRINGEOL;
  1317. }
  1318. break;
  1319. case SCE_HB_COMMENTLINE:
  1320. if (ch == '\r' || ch == '\n') {
  1321. styler.ColourTo(i - 1, StateToPrint);
  1322. state = SCE_HB_DEFAULT;
  1323. }
  1324. break;
  1325. case SCE_HB_STRINGEOL:
  1326. if (!isLineEnd(ch)) {
  1327. styler.ColourTo(i - 1, StateToPrint);
  1328. state = SCE_HB_DEFAULT;
  1329. } else if (!isLineEnd(chNext)) {
  1330. styler.ColourTo(i, StateToPrint);
  1331. state = SCE_HB_DEFAULT;
  1332. }
  1333. break;
  1334. case SCE_HP_DEFAULT:
  1335. case SCE_HP_START:
  1336. if (iswordstart(ch)) {
  1337. styler.ColourTo(i - 1, StateToPrint);
  1338. state = SCE_HP_WORD;
  1339. } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') &&
  1340. styler.SafeGetCharAt(i + 3) == '-') {
  1341. styler.ColourTo(i - 1, StateToPrint);
  1342. state = SCE_HP_COMMENTLINE;
  1343. } else if (ch == '#') {
  1344. styler.ColourTo(i - 1, StateToPrint);
  1345. state = SCE_HP_COMMENTLINE;
  1346. } else if (ch == '\"') {
  1347. styler.ColourTo(i - 1, StateToPrint);
  1348. if (chNext == '\"' && chNext2 == '\"') {
  1349. i += 2;
  1350. state = SCE_HP_TRIPLEDOUBLE;
  1351. ch = ' ';
  1352. chPrev = ' ';
  1353. chNext = styler.SafeGetCharAt(i + 1);
  1354. } else {
  1355. // state = statePrintForState(SCE_HP_STRING,inScriptType);
  1356. state = SCE_HP_STRING;
  1357. }
  1358. } else if (ch == '\'') {
  1359. styler.ColourTo(i - 1, StateToPrint);
  1360. if (chNext == '\'' && chNext2 == '\'') {
  1361. i += 2;
  1362. state = SCE_HP_TRIPLE;
  1363. ch = ' ';
  1364. chPrev = ' ';
  1365. chNext = styler.SafeGetCharAt(i + 1);
  1366. } else {
  1367. state = SCE_HP_CHARACTER;
  1368. }
  1369. } else if (isoperator(ch)) {
  1370. styler.ColourTo(i - 1, StateToPrint);
  1371. styler.ColourTo(i, statePrintForState(SCE_HP_OPERATOR, inScriptType));
  1372. } else if ((ch == ' ') || (ch == '\t')) {
  1373. if (state == SCE_HP_START) {
  1374. styler.ColourTo(i - 1, StateToPrint);
  1375. state = SCE_HP_DEFAULT;
  1376. }
  1377. }
  1378. break;
  1379. case SCE_HP_WORD:
  1380. if (!iswordchar(ch)) {
  1381. classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType);
  1382. state = SCE_HP_DEFAULT;
  1383. if (ch == '#') {
  1384. state = SCE_HP_COMMENTLINE;
  1385. } else if (ch == '\"') {
  1386. if (chNext == '\"' && chNext2 == '\"') {
  1387. i += 2;
  1388. state = SCE_HP_TRIPLEDOUBLE;
  1389. ch = ' ';
  1390. chPrev = ' ';
  1391. chNext = styler.SafeGetCharAt(i + 1);
  1392. } else {
  1393. state = SCE_HP_STRING;
  1394. }
  1395. } else if (ch == '\'') {
  1396. if (chNext == '\'' && chNext2 == '\'') {
  1397. i += 2;
  1398. state = SCE_HP_TRIPLE;
  1399. ch = ' ';
  1400. chPrev = ' ';
  1401. chNext = styler.SafeGetCharAt(i + 1);
  1402. } else {
  1403. state = SCE_HP_CHARACTER;
  1404. }
  1405. } else if (isoperator(ch)) {
  1406. styler.ColourTo(i, statePrintForState(SCE_HP_OPERATOR, inScriptType));
  1407. }
  1408. }
  1409. break;
  1410. case SCE_HP_COMMENTLINE:
  1411. if (ch == '\r' || ch == '\n') {
  1412. styler.ColourTo(i - 1, StateToPrint);
  1413. state = SCE_HP_DEFAULT;
  1414. }
  1415. break;
  1416. case SCE_HP_STRING:
  1417. if (ch == '\\') {
  1418. if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
  1419. i++;
  1420. ch = chNext;
  1421. chNext = styler.SafeGetCharAt(i + 1);
  1422. }
  1423. } else if (ch == '\"') {
  1424. styler.ColourTo(i, StateToPrint);
  1425. state = SCE_HP_DEFAULT;
  1426. }
  1427. break;
  1428. case SCE_HP_CHARACTER:
  1429. if (ch == '\\') {
  1430. if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
  1431. i++;
  1432. ch = chNext;
  1433. chNext = styler.SafeGetCharAt(i + 1);
  1434. }
  1435. } else if (ch == '\'') {
  1436. styler.ColourTo(i, StateToPrint);
  1437. state = SCE_HP_DEFAULT;
  1438. }
  1439. break;
  1440. case SCE_HP_TRIPLE:
  1441. if (ch == '\'' && chPrev == '\'' && chPrev2 == '\'') {
  1442. styler.ColourTo(i, StateToPrint);
  1443. state = SCE_HP_DEFAULT;
  1444. }
  1445. break;
  1446. case SCE_HP_TRIPLEDOUBLE:
  1447. if (ch == '\"' && chPrev == '\"' && chPrev2 == '\"') {
  1448. styler.ColourTo(i, StateToPrint);
  1449. state = SCE_HP_DEFAULT;
  1450. }
  1451. break;
  1452. ///////////// start - PHP state handling
  1453. case SCE_HPHP_WORD:
  1454. if (!iswordchar(ch)) {
  1455. classifyWordHTPHP(styler.GetStartSegment(), i - 1, keywords5, styler);
  1456. if (ch == '/' && chNext == '*') {
  1457. i++;
  1458. state = SCE_HPHP_COMMENT;
  1459. } else if (ch == '/' && chNext == '/') {
  1460. i++;
  1461. state = SCE_HPHP_COMMENTLINE;
  1462. } else if (ch == '#') {
  1463. state = SCE_HPHP_COMMENTLINE;
  1464. } else if (ch == '\"') {
  1465. state = SCE_HPHP_HSTRING;
  1466. strcpy(phpStringDelimiter, "\"");
  1467. } else if (styler.Match(i, "<<<")) {
  1468. state = SCE_HPHP_HSTRING;
  1469. i = FindPhpStringDelimiter(phpStringDelimiter, sizeof(phpStringDelimiter), i + 3, lengthDoc, styler);
  1470. } else if (ch == '\'') {
  1471. state = SCE_HPHP_SIMPLESTRING;
  1472. } else if (ch == '$' && IsPhpWordStart(chNext)) {
  1473. state = SCE_HPHP_VARIABLE;
  1474. } else if (isoperator(ch)) {
  1475. state = SCE_HPHP_OPERATOR;
  1476. } else {
  1477. state = SCE_HPHP_DEFAULT;
  1478. }
  1479. }
  1480. break;
  1481. case SCE_HPHP_NUMBER:
  1482. // recognize bases 8,10 or 16 integers OR floating-point numbers
  1483. if (!IsADigit(ch)
  1484. && strchr(".xXabcdefABCDEF", ch) == NULL
  1485. && ((ch != '-' && ch != '+') || (chPrev != 'e' && chPrev != 'E'))) {
  1486. styler.ColourTo(i - 1, SCE_HPHP_NUMBER);
  1487. if (isoperator(ch))
  1488. state = SCE_HPHP_OPERATOR;
  1489. else
  1490. state = SCE_HPHP_DEFAULT;
  1491. }
  1492. break;
  1493. case SCE_HPHP_VARIABLE:
  1494. if (!IsPhpWordChar(ch)) {
  1495. styler.ColourTo(i - 1, SCE_HPHP_VARIABLE);
  1496. if (isoperator(ch))
  1497. state = SCE_HPHP_OPERATOR;
  1498. else
  1499. state = SCE_HPHP_DEFAULT;
  1500. }
  1501. break;
  1502. case SCE_HPHP_COMMENT:
  1503. if (ch == '/' && chPrev == '*') {
  1504. styler.ColourTo(i, StateToPrint);
  1505. state = SCE_HPHP_DEFAULT;
  1506. }
  1507. break;
  1508. case SCE_HPHP_COMMENTLINE:
  1509. if (ch == '\r' || ch == '\n') {
  1510. styler.ColourTo(i - 1, StateToPrint);
  1511. state = SCE_HPHP_DEFAULT;
  1512. }
  1513. break;
  1514. case SCE_HPHP_HSTRING:
  1515. if (ch == '\\' && (phpStringDelimiter[0] == '\"' || chNext == '$' || chNext == '{')) {
  1516. // skip the next char
  1517. i++;
  1518. } else if (((ch == '{' && chNext == '$') || (ch == '$' && chNext == '{'))
  1519. && IsPhpWordStart(chNext2)) {
  1520. styler.ColourTo(i - 1, StateToPrint);
  1521. state = SCE_HPHP_COMPLEX_VARIABLE;
  1522. } else if (ch == '$' && IsPhpWordStart(chNext)) {
  1523. styler.ColourTo(i - 1, StateToPrint);
  1524. state = SCE_HPHP_HSTRING_VARIABLE;
  1525. } else if (styler.Match(i, phpStringDelimiter)) {
  1526. if (strlen(phpStringDelimiter) > 1)
  1527. i += strlen(phpStringDelimiter) - 1;
  1528. styler.ColourTo(i, StateToPrint);
  1529. state = SCE_HPHP_DEFAULT;
  1530. }
  1531. break;
  1532. case SCE_HPHP_SIMPLESTRING:
  1533. if (ch == '\\') {
  1534. // skip the next char
  1535. i++;
  1536. } else if (ch == '\'') {
  1537. styler.ColourTo(i, StateToPrint);
  1538. state = SCE_HPHP_DEFAULT;
  1539. }
  1540. break;
  1541. case SCE_HPHP_HSTRING_VARIABLE:
  1542. if (!IsPhpWordChar(ch)) {
  1543. styler.ColourTo(i - 1, StateToPrint);
  1544. i--; // strange but it works
  1545. state = SCE_HPHP_HSTRING;
  1546. }
  1547. break;
  1548. case SCE_HPHP_COMPLEX_VARIABLE:
  1549. if (ch == '}') {
  1550. styler.ColourTo(i, StateToPrint);
  1551. state = SCE_HPHP_HSTRING;
  1552. }
  1553. break;
  1554. case SCE_HPHP_OPERATOR:
  1555. case SCE_HPHP_DEFAULT:
  1556. styler.ColourTo(i - 1, StateToPrint);
  1557. if (IsADigit(ch) || (ch == '.' && IsADigit(chNext))) {
  1558. state = SCE_HPHP_NUMBER;
  1559. } else if (iswordstart(ch)) {
  1560. state = SCE_HPHP_WORD;
  1561. } else if (ch == '/' && chNext == '*') {
  1562. i++;
  1563. state = SCE_HPHP_COMMENT;
  1564. } else if (ch == '/' && chNext == '/') {
  1565. i++;
  1566. state = SCE_HPHP_COMMENTLINE;
  1567. } else if (ch == '#') {
  1568. state = SCE_HPHP_COMMENTLINE;
  1569. } else if

Large files files are truncated, but you can click here to view the full file