1 // Scintilla source code edit control
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.
18 #include "StyleContext.h"
20 #include "Scintilla.h"
23 #define SCE_HA_JS (SCE_HJA_START - SCE_HJ_START)
24 #define SCE_HA_VBS (SCE_HBA_START - SCE_HB_START)
25 #define SCE_HA_PYTHON (SCE_HPA_START - SCE_HP_START)
27 enum script_type
{ eScriptNone
= 0, eScriptJS
, eScriptVBS
, eScriptPython
, eScriptPHP
, eScriptXML
, eScriptSGML
, eScriptSGMLblock
};
28 enum script_mode
{ eHtml
= 0, eNonHtmlScript
, eNonHtmlPreProc
, eNonHtmlScriptPreProc
};
30 static inline bool IsAWordChar(const int ch
) {
31 return (ch
< 0x80) && (isalnum(ch
) || ch
== '.' || ch
== '_');
34 static inline bool IsAWordStart(const int ch
) {
35 return (ch
< 0x80) && (isalnum(ch
) || ch
== '_');
38 static inline int MakeLowerCase(int ch
) {
39 if (ch
< 'A' || ch
> 'Z')
42 return ch
- 'A' + 'a';
45 static void GetTextSegment(Accessor
&styler
, unsigned int start
, unsigned int end
, char *s
, size_t len
) {
47 for (; (i
< end
- start
+ 1) && (i
< len
-1); i
++) {
48 s
[i
] = static_cast<char>(MakeLowerCase(styler
[start
+ i
]));
53 static script_type
segIsScriptingIndicator(Accessor
&styler
, unsigned int start
, unsigned int end
, script_type prevValue
) {
55 GetTextSegment(styler
, start
, end
, s
, sizeof(s
));
56 //Platform::DebugPrintf("Scripting indicator [%s]\n", s);
57 if (strstr(s
, "src")) // External script
61 if (strstr(s
, "pyth"))
63 if (strstr(s
, "javas"))
65 if (strstr(s
, "jscr"))
75 static int PrintScriptingIndicatorOffset(Accessor
&styler
, unsigned int start
, unsigned int end
) {
78 GetTextSegment(styler
, start
, end
, s
, sizeof(s
));
79 if (0 == strncmp(s
, "php", 3)) {
86 static script_type
ScriptOfState(int state
) {
87 if ((state
>= SCE_HP_START
) && (state
<= SCE_HP_IDENTIFIER
)) {
89 } else if ((state
>= SCE_HB_START
) && (state
<= SCE_HB_STRINGEOL
)) {
91 } else if ((state
>= SCE_HJ_START
) && (state
<= SCE_HJ_REGEX
)) {
93 } else if ((state
>= SCE_HPHP_DEFAULT
) && (state
<= SCE_HPHP_COMMENTLINE
)) {
95 } else if ((state
>= SCE_H_SGML_DEFAULT
) && (state
< SCE_H_SGML_BLOCK_DEFAULT
)) {
97 } else if (state
== SCE_H_SGML_BLOCK_DEFAULT
) {
98 return eScriptSGMLblock
;
104 static int statePrintForState(int state
, script_mode inScriptType
) {
107 if ((state
>= SCE_HP_START
) && (state
<= SCE_HP_IDENTIFIER
)) {
108 StateToPrint
= state
+ ((inScriptType
== eNonHtmlScript
) ? 0 : SCE_HA_PYTHON
);
109 } else if ((state
>= SCE_HB_START
) && (state
<= SCE_HB_STRINGEOL
)) {
110 StateToPrint
= state
+ ((inScriptType
== eNonHtmlScript
) ? 0 : SCE_HA_VBS
);
111 } else if ((state
>= SCE_HJ_START
) && (state
<= SCE_HJ_REGEX
)) {
112 StateToPrint
= state
+ ((inScriptType
== eNonHtmlScript
) ? 0 : SCE_HA_JS
);
114 StateToPrint
= state
;
120 static int stateForPrintState(int StateToPrint
) {
123 if ((StateToPrint
>= SCE_HPA_START
) && (StateToPrint
<= SCE_HPA_IDENTIFIER
)) {
124 state
= StateToPrint
- SCE_HA_PYTHON
;
125 } else if ((StateToPrint
>= SCE_HBA_START
) && (StateToPrint
<= SCE_HBA_STRINGEOL
)) {
126 state
= StateToPrint
- SCE_HA_VBS
;
127 } else if ((StateToPrint
>= SCE_HJA_START
) && (StateToPrint
<= SCE_HJA_REGEX
)) {
128 state
= StateToPrint
- SCE_HA_JS
;
130 state
= StateToPrint
;
136 static inline bool IsNumber(unsigned int start
, Accessor
&styler
) {
137 return IsADigit(styler
[start
]) || (styler
[start
] == '.') ||
138 (styler
[start
] == '-') || (styler
[start
] == '#');
141 static inline bool isStringState(int state
) {
145 case SCE_HJ_DOUBLESTRING
:
146 case SCE_HJ_SINGLESTRING
:
147 case SCE_HJA_DOUBLESTRING
:
148 case SCE_HJA_SINGLESTRING
:
152 case SCE_HP_CHARACTER
:
154 case SCE_HP_TRIPLEDOUBLE
:
156 case SCE_HPA_CHARACTER
:
158 case SCE_HPA_TRIPLEDOUBLE
:
159 case SCE_HPHP_HSTRING
:
160 case SCE_HPHP_SIMPLESTRING
:
161 case SCE_HPHP_HSTRING_VARIABLE
:
162 case SCE_HPHP_COMPLEX_VARIABLE
:
172 static inline bool stateAllowsTermination(int state
) {
173 bool allowTermination
= !isStringState(state
);
174 if (allowTermination
) {
176 case SCE_HPHP_COMMENT
:
177 case SCE_HP_COMMENTLINE
:
178 case SCE_HPA_COMMENTLINE
:
179 allowTermination
= false;
182 return allowTermination
;
185 // not really well done, since it's only comments that should lex the %> and <%
186 static inline bool isCommentASPState(int state
) {
191 case SCE_HJ_COMMENTLINE
:
192 case SCE_HJ_COMMENTDOC
:
193 case SCE_HB_COMMENTLINE
:
194 case SCE_HP_COMMENTLINE
:
195 case SCE_HPHP_COMMENT
:
196 case SCE_HPHP_COMMENTLINE
:
206 static void classifyAttribHTML(unsigned int start
, unsigned int end
, WordList
&keywords
, Accessor
&styler
) {
207 bool wordIsNumber
= IsNumber(start
, styler
);
208 char chAttr
= SCE_H_ATTRIBUTEUNKNOWN
;
210 chAttr
= SCE_H_NUMBER
;
213 GetTextSegment(styler
, start
, end
, s
, sizeof(s
));
214 if (keywords
.InList(s
))
215 chAttr
= SCE_H_ATTRIBUTE
;
217 if ((chAttr
== SCE_H_ATTRIBUTEUNKNOWN
) && !keywords
)
218 // No keywords -> all are known
219 chAttr
= SCE_H_ATTRIBUTE
;
220 styler
.ColourTo(end
, chAttr
);
223 static int classifyTagHTML(unsigned int start
, unsigned int end
,
224 WordList
&keywords
, Accessor
&styler
, bool &tagDontFold
,
225 bool caseSensitive
) {
227 // Copy after the '<'
229 for (unsigned int cPos
= start
; cPos
<= end
&& i
< 30; cPos
++) {
230 char ch
= styler
[cPos
];
231 if ((ch
!= '<') && (ch
!= '/')) {
232 s
[i
++] = caseSensitive
? ch
: static_cast<char>(MakeLowerCase(ch
));
236 //The following is only a quick hack, to see if this whole thing would work
237 //we first need the tagname with a trailing space...
241 //...to find it in the list of no-container-tags
242 // (There are many more. We will need a keywordlist in the property file for this)
243 tagDontFold
= (NULL
!= strstr("meta link img area br hr input ",s
));
245 //now we can remove the trailing space
248 bool isScript
= false;
249 char chAttr
= SCE_H_TAGUNKNOWN
;
251 chAttr
= SCE_H_SGML_DEFAULT
;
252 } else if (s
[0] == '/') { // Closing tag
253 if (keywords
.InList(s
+ 1))
256 if (keywords
.InList(s
)) {
258 isScript
= 0 == strcmp(s
, "script");
261 if ((chAttr
== SCE_H_TAGUNKNOWN
) && !keywords
) {
262 // No keywords -> all are known
264 isScript
= 0 == strcmp(s
, "script");
266 styler
.ColourTo(end
, chAttr
);
267 return isScript
? SCE_H_SCRIPT
: chAttr
;
270 static void classifyWordHTJS(unsigned int start
, unsigned int end
,
271 WordList
&keywords
, Accessor
&styler
, script_mode inScriptType
) {
272 char chAttr
= SCE_HJ_WORD
;
273 bool wordIsNumber
= IsADigit(styler
[start
]) || (styler
[start
] == '.');
275 chAttr
= SCE_HJ_NUMBER
;
279 for (; i
< end
- start
+ 1 && i
< 30; i
++) {
280 s
[i
] = styler
[start
+ i
];
283 if (keywords
.InList(s
))
284 chAttr
= SCE_HJ_KEYWORD
;
286 styler
.ColourTo(end
, statePrintForState(chAttr
, inScriptType
));
289 static int classifyWordHTVB(unsigned int start
, unsigned int end
, WordList
&keywords
, Accessor
&styler
, script_mode inScriptType
) {
290 char chAttr
= SCE_HB_IDENTIFIER
;
291 bool wordIsNumber
= IsADigit(styler
[start
]) || (styler
[start
] == '.');
293 chAttr
= SCE_HB_NUMBER
;
296 GetTextSegment(styler
, start
, end
, s
, sizeof(s
));
297 if (keywords
.InList(s
)) {
298 chAttr
= SCE_HB_WORD
;
299 if (strcmp(s
, "rem") == 0)
300 chAttr
= SCE_HB_COMMENTLINE
;
303 styler
.ColourTo(end
, statePrintForState(chAttr
, inScriptType
));
304 if (chAttr
== SCE_HB_COMMENTLINE
)
305 return SCE_HB_COMMENTLINE
;
307 return SCE_HB_DEFAULT
;
310 static void classifyWordHTPy(unsigned int start
, unsigned int end
, WordList
&keywords
, Accessor
&styler
, char *prevWord
, script_mode inScriptType
) {
311 bool wordIsNumber
= IsADigit(styler
[start
]);
314 for (; i
< end
- start
+ 1 && i
< 30; i
++) {
315 s
[i
] = styler
[start
+ i
];
318 char chAttr
= SCE_HP_IDENTIFIER
;
319 if (0 == strcmp(prevWord
, "class"))
320 chAttr
= SCE_HP_CLASSNAME
;
321 else if (0 == strcmp(prevWord
, "def"))
322 chAttr
= SCE_HP_DEFNAME
;
323 else if (wordIsNumber
)
324 chAttr
= SCE_HP_NUMBER
;
325 else if (keywords
.InList(s
))
326 chAttr
= SCE_HP_WORD
;
327 styler
.ColourTo(end
, statePrintForState(chAttr
, inScriptType
));
331 // Update the word colour to default or keyword
332 // Called when in a PHP word
333 static void classifyWordHTPHP(unsigned int start
, unsigned int end
, WordList
&keywords
, Accessor
&styler
) {
334 char chAttr
= SCE_HPHP_DEFAULT
;
335 bool wordIsNumber
= IsADigit(styler
[start
]) || (styler
[start
] == '.' && start
+1 <= end
&& IsADigit(styler
[start
+1]));
337 chAttr
= SCE_HPHP_NUMBER
;
340 GetTextSegment(styler
, start
, end
, s
, sizeof(s
));
341 if (keywords
.InList(s
))
342 chAttr
= SCE_HPHP_WORD
;
344 styler
.ColourTo(end
, chAttr
);
347 static bool isWordHSGML(unsigned int start
, unsigned int end
, WordList
&keywords
, Accessor
&styler
) {
350 for (; i
< end
- start
+ 1 && i
< 30; i
++) {
351 s
[i
] = styler
[start
+ i
];
354 return keywords
.InList(s
);
357 static bool isWordCdata(unsigned int start
, unsigned int end
, Accessor
&styler
) {
360 for (; i
< end
- start
+ 1 && i
< 30; i
++) {
361 s
[i
] = styler
[start
+ i
];
364 return (0 == strcmp(s
, "[CDATA["));
367 // Return the first state to reach when entering a scripting language
368 static int StateForScript(script_type scriptLanguage
) {
370 switch (scriptLanguage
) {
372 Result
= SCE_HB_START
;
375 Result
= SCE_HP_START
;
378 Result
= SCE_HPHP_DEFAULT
;
381 Result
= SCE_H_TAGUNKNOWN
;
384 Result
= SCE_H_SGML_DEFAULT
;
387 Result
= SCE_HJ_START
;
393 static inline bool ishtmlwordchar(char ch
) {
394 return !isascii(ch
) ||
395 (isalnum(ch
) || ch
== '.' || ch
== '-' || ch
== '_' || ch
== ':' || ch
== '!' || ch
== '#');
398 static inline bool issgmlwordchar(char ch
) {
399 return !isascii(ch
) ||
400 (isalnum(ch
) || ch
== '.' || ch
== '_' || ch
== ':' || ch
== '!' || ch
== '#' || ch
== '[');
403 static inline bool IsPhpWordStart(const unsigned char ch
) {
404 return (isascii(ch
) && (isalpha(ch
) || (ch
== '_'))) || (ch
>= 0x7f);
407 static inline bool IsPhpWordChar(char ch
) {
408 return IsADigit(ch
) || IsPhpWordStart(ch
);
411 static bool InTagState(int state
) {
412 return state
== SCE_H_TAG
|| state
== SCE_H_TAGUNKNOWN
||
413 state
== SCE_H_SCRIPT
||
414 state
== SCE_H_ATTRIBUTE
|| state
== SCE_H_ATTRIBUTEUNKNOWN
||
415 state
== SCE_H_NUMBER
|| state
== SCE_H_OTHER
||
416 state
== SCE_H_DOUBLESTRING
|| state
== SCE_H_SINGLESTRING
;
419 static bool IsCommentState(const int state
) {
420 return state
== SCE_H_COMMENT
|| state
== SCE_H_SGML_COMMENT
;
423 static bool IsScriptCommentState(const int state
) {
424 return state
== SCE_HJ_COMMENT
|| state
== SCE_HJ_COMMENTLINE
|| state
== SCE_HJA_COMMENT
||
425 state
== SCE_HJA_COMMENTLINE
|| state
== SCE_HB_COMMENTLINE
|| state
== SCE_HBA_COMMENTLINE
;
428 static bool isLineEnd(char ch
) {
429 return ch
== '\r' || ch
== '\n';
432 static bool isOKBeforeRE(char ch
) {
433 return (ch
== '(') || (ch
== '=') || (ch
== ',');
436 static bool isPHPStringState(int state
) {
438 (state
== SCE_HPHP_HSTRING
) ||
439 (state
== SCE_HPHP_SIMPLESTRING
) ||
440 (state
== SCE_HPHP_HSTRING_VARIABLE
) ||
441 (state
== SCE_HPHP_COMPLEX_VARIABLE
);
444 static int FindPhpStringDelimiter(char *phpStringDelimiter
, const int phpStringDelimiterSize
, int i
, const int lengthDoc
, Accessor
&styler
) {
446 while (i
< lengthDoc
&& (styler
[i
] == ' ' || styler
[i
] == '\t'))
448 phpStringDelimiter
[0] = '\n';
449 for (j
= i
; j
< lengthDoc
&& styler
[j
] != '\n' && styler
[j
] != '\r'; j
++) {
450 if (j
- i
< phpStringDelimiterSize
- 2)
451 phpStringDelimiter
[j
-i
+1] = styler
[j
];
455 phpStringDelimiter
[j
-i
+1] = '\0';
459 static void ColouriseHyperTextDoc(unsigned int startPos
, int length
, int initStyle
, WordList
*keywordlists
[],
461 WordList
&keywords
= *keywordlists
[0];
462 WordList
&keywords2
= *keywordlists
[1];
463 WordList
&keywords3
= *keywordlists
[2];
464 WordList
&keywords4
= *keywordlists
[3];
465 WordList
&keywords5
= *keywordlists
[4];
466 WordList
&keywords6
= *keywordlists
[5]; // SGML (DTD) keywords
468 // Lexer for HTML requires more lexical states (7 bits worth) than most lexers
469 styler
.StartAt(startPos
, STYLE_MAX
);
472 char phpStringDelimiter
[200]; // PHP is not limited in length, we are
473 phpStringDelimiter
[0] = '\0';
474 int StateToPrint
= initStyle
;
475 int state
= stateForPrintState(StateToPrint
);
477 // If inside a tag, it may be a script tag, so reread from the start to ensure any language tags are seen
478 if (InTagState(state
)) {
479 while ((startPos
> 0) && (InTagState(styler
.StyleAt(startPos
- 1)))) {
483 state
= SCE_H_DEFAULT
;
485 // String can be heredoc, must find a delimiter first
486 while (startPos
> 0 && isPHPStringState(state
) && state
!= SCE_HPHP_SIMPLESTRING
) {
489 state
= styler
.StyleAt(startPos
);
491 styler
.StartAt(startPos
, STYLE_MAX
);
493 int lineCurrent
= styler
.GetLine(startPos
);
495 if (lineCurrent
> 0) {
496 lineState
= styler
.GetLineState(lineCurrent
);
498 // Default client and ASP scripting language is JavaScript
499 lineState
= eScriptJS
<< 8;
500 lineState
|= styler
.GetPropertyInt("asp.default.language", eScriptJS
) << 4;
502 script_mode inScriptType
= script_mode((lineState
>> 0) & 0x03); // 2 bits of scripting mode
503 bool tagOpened
= (lineState
>> 2) & 0x01; // 1 bit to know if we are in an opened tag
504 bool tagClosing
= (lineState
>> 3) & 0x01; // 1 bit to know if we are in a closing tag
505 bool tagDontFold
= false; //some HTML tags should not be folded
506 script_type aspScript
= script_type((lineState
>> 4) & 0x0F); // 4 bits of script name
507 script_type clientScript
= script_type((lineState
>> 8) & 0x0F); // 4 bits of script name
508 int beforePreProc
= (lineState
>> 12) & 0xFF; // 8 bits of state
510 script_type scriptLanguage
= ScriptOfState(state
);
512 const bool foldHTML
= styler
.GetPropertyInt("fold.html", 0) != 0;
513 const bool fold
= foldHTML
&& styler
.GetPropertyInt("fold", 0);
514 const bool foldHTMLPreprocessor
= foldHTML
&& styler
.GetPropertyInt("fold.html.preprocessor", 1);
515 const bool foldCompact
= styler
.GetPropertyInt("fold.compact", 1) != 0;
516 const bool caseSensitive
= styler
.GetPropertyInt("html.tags.case.sensitive", 0) != 0;
518 int levelPrev
= styler
.LevelAt(lineCurrent
) & SC_FOLDLEVELNUMBERMASK
;
519 int levelCurrent
= levelPrev
;
520 int visibleChars
= 0;
524 char chPrevNonWhite
= ' ';
525 // look back to set chPrevNonWhite properly for better regex colouring
526 if (scriptLanguage
== eScriptJS
&& startPos
> 0) {
530 style
= styler
.StyleAt(back
);
531 if (style
< SCE_HJ_DEFAULT
|| style
> SCE_HJ_COMMENTDOC
)
532 // includes SCE_HJ_COMMENT & SCE_HJ_COMMENTLINE
535 if (style
== SCE_HJ_SYMBOLS
) {
536 chPrevNonWhite
= styler
.SafeGetCharAt(back
);
540 styler
.StartSegment(startPos
);
541 const int lengthDoc
= startPos
+ length
;
542 for (int i
= startPos
; i
< lengthDoc
; i
++) {
543 const char chPrev2
= chPrev
;
545 if (!isspacechar(ch
) && state
!= SCE_HJ_COMMENT
&&
546 state
!= SCE_HJ_COMMENTLINE
&& state
!= SCE_HJ_COMMENTDOC
)
549 char chNext
= styler
.SafeGetCharAt(i
+ 1);
550 const char chNext2
= styler
.SafeGetCharAt(i
+ 2);
552 // Handle DBCS codepages
553 if (styler
.IsLeadByte(ch
)) {
559 if ((!isspacechar(ch
) || !foldCompact
) && fold
)
562 // decide what is the current state to print (depending of the script tag)
563 StateToPrint
= statePrintForState(state
, inScriptType
);
565 // handle script folding
567 switch (scriptLanguage
) {
570 //not currently supported case eScriptVBS:
572 if ((state
!= SCE_HPHP_COMMENT
) && (state
!= SCE_HPHP_COMMENTLINE
) && (state
!= SCE_HJ_COMMENT
) && (state
!= SCE_HJ_COMMENTLINE
) && (state
!= SCE_HJ_COMMENTDOC
) && (!isStringState(state
))) {
573 //Platform::DebugPrintf("state=%d, StateToPrint=%d, initStyle=%d\n", state, StateToPrint, initStyle);
574 //if ((state == SCE_HPHP_OPERATOR) || (state == SCE_HPHP_DEFAULT) || (state == SCE_HJ_SYMBOLS) || (state == SCE_HJ_START) || (state == SCE_HJ_DEFAULT)) {
575 if ((ch
== '{') || (ch
== '}')) {
576 levelCurrent
+= (ch
== '{') ? 1 : -1;
581 if (state
!= SCE_HP_COMMENTLINE
) {
582 if ((ch
== ':') && ((chNext
== '\n') || (chNext
== '\r' && chNext2
== '\n'))) {
584 } else if ((ch
== '\n') && !((chNext
== '\r') && (chNext2
== '\n')) && (chNext
!= '\n')) {
585 // check if the number of tabs is lower than the level
586 int Findlevel
= (levelCurrent
& ~SC_FOLDLEVELBASE
) * 8;
587 for (int j
= 0; Findlevel
> 0; j
++) {
588 char chTmp
= styler
.SafeGetCharAt(i
+ j
+ 1);
591 } else if (chTmp
== ' ') {
599 levelCurrent
-= Findlevel
/ 8;
611 if ((ch
== '\r' && chNext
!= '\n') || (ch
== '\n')) {
612 // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
613 // Avoid triggering two times on Dos/Win
614 // New line -> record any line state onto /next/ line
617 if (visibleChars
== 0)
618 lev
|= SC_FOLDLEVELWHITEFLAG
;
619 if ((levelCurrent
> levelPrev
) && (visibleChars
> 0))
620 lev
|= SC_FOLDLEVELHEADERFLAG
;
622 styler
.SetLevel(lineCurrent
, lev
);
624 levelPrev
= levelCurrent
;
627 styler
.SetLineState(lineCurrent
,
628 ((inScriptType
& 0x03) << 0) |
629 ((tagOpened
& 0x01) << 2) |
630 ((tagClosing
& 0x01) << 3) |
631 ((aspScript
& 0x0F) << 4) |
632 ((clientScript
& 0x0F) << 8) |
633 ((beforePreProc
& 0xFF) << 12));
636 // generic end of script processing
637 else if ((inScriptType
== eNonHtmlScript
) && (ch
== '<') && (chNext
== '/')) {
638 // Check if it's the end of the script tag (or any other HTML tag)
640 // in these cases, you can embed HTML tags (to confirm !!!!!!!!!!!!!!!!!!!!!!)
641 case SCE_H_DOUBLESTRING
:
642 case SCE_H_SINGLESTRING
:
644 case SCE_HJ_COMMENTDOC
:
645 //case SCE_HJ_COMMENTLINE: // removed as this is a common thing done to hide
646 // the end of script marker from some JS interpreters.
647 case SCE_HJ_DOUBLESTRING
:
648 case SCE_HJ_SINGLESTRING
:
653 case SCE_HP_TRIPLEDOUBLE
:
656 // check if the closing tag is a script tag
657 if (state
== SCE_HJ_COMMENTLINE
) {
658 char tag
[7]; // room for the <script> tag
659 char chr
; // current char
661 chr
= styler
.SafeGetCharAt(i
+2);
662 while (j
< 6 && !isspacechar(chr
)) {
663 tag
[j
++] = static_cast<char>(MakeLowerCase(chr
));
664 chr
= styler
.SafeGetCharAt(i
+2+j
);
667 if (strcmp(tag
, "script") != 0) break;
669 // closing tag of the script (it's a closing HTML tag anyway)
670 styler
.ColourTo(i
- 1, StateToPrint
);
671 state
= SCE_H_TAGUNKNOWN
;
672 inScriptType
= eHtml
;
673 scriptLanguage
= eScriptNone
;
674 clientScript
= eScriptJS
;
682 /////////////////////////////////////
683 // handle the start of PHP pre-processor = Non-HTML
684 else if ((state
!= SCE_H_ASPAT
) &&
685 !isPHPStringState(state
) &&
686 (state
!= SCE_HPHP_COMMENT
) &&
689 !IsScriptCommentState(state
) ) {
690 scriptLanguage
= segIsScriptingIndicator(styler
, i
+ 2, i
+ 10, eScriptPHP
);
691 if (scriptLanguage
!= eScriptPHP
&& isStringState(state
)) continue;
692 styler
.ColourTo(i
- 1, StateToPrint
);
693 beforePreProc
= state
;
696 i
+= PrintScriptingIndicatorOffset(styler
, styler
.GetStartSegment() + 2, i
+ 10);
697 if (scriptLanguage
== eScriptXML
)
698 styler
.ColourTo(i
, SCE_H_XMLSTART
);
700 styler
.ColourTo(i
, SCE_H_QUESTION
);
701 state
= StateForScript(scriptLanguage
);
702 if (inScriptType
== eNonHtmlScript
)
703 inScriptType
= eNonHtmlScriptPreProc
;
705 inScriptType
= eNonHtmlPreProc
;
706 // Fold whole script, but not if the XML first tag (all XML-like tags in this case)
707 if (foldHTMLPreprocessor
&& (scriptLanguage
!= eScriptXML
)) {
711 ch
= styler
.SafeGetCharAt(i
);
715 // handle the start of ASP pre-processor = Non-HTML
716 else if (!isCommentASPState(state
) && (ch
== '<') && (chNext
== '%') && !isPHPStringState(state
)) {
717 styler
.ColourTo(i
- 1, StateToPrint
);
718 beforePreProc
= state
;
719 if (inScriptType
== eNonHtmlScript
)
720 inScriptType
= eNonHtmlScriptPreProc
;
722 inScriptType
= eNonHtmlPreProc
;
724 if (chNext2
== '@') {
725 i
+= 2; // place as if it was the second next char treated
728 } else if ((chNext2
== '-') && (styler
.SafeGetCharAt(i
+ 3) == '-')) {
729 styler
.ColourTo(i
+ 3, SCE_H_ASP
);
730 state
= SCE_H_XCCOMMENT
;
731 scriptLanguage
= eScriptVBS
;
734 if (chNext2
== '=') {
735 i
+= 2; // place as if it was the second next char treated
738 i
++; // place as if it was the next char treated
742 state
= StateForScript(aspScript
);
744 scriptLanguage
= eScriptVBS
;
745 styler
.ColourTo(i
, SCE_H_ASP
);
747 if (foldHTMLPreprocessor
)
750 ch
= styler
.SafeGetCharAt(i
);
754 /////////////////////////////////////
755 // handle the start of SGML language (DTD)
756 else if (((scriptLanguage
== eScriptNone
) || (scriptLanguage
== eScriptXML
)) &&
759 (StateToPrint
!= SCE_H_CDATA
) &&
760 (!IsCommentState(StateToPrint
)) &&
761 (!IsScriptCommentState(StateToPrint
)) ) {
762 beforePreProc
= state
;
763 styler
.ColourTo(i
- 2, StateToPrint
);
764 if ((chNext
== '-') && (chNext2
== '-')) {
765 state
= SCE_H_COMMENT
; // wait for a pending command
766 styler
.ColourTo(i
+ 2, SCE_H_COMMENT
);
767 i
+= 2; // follow styling after the --
768 } else if (isWordCdata(i
+ 1, i
+ 7, styler
)) {
771 styler
.ColourTo(i
, SCE_H_SGML_DEFAULT
); // <! is default
772 scriptLanguage
= eScriptSGML
;
773 state
= SCE_H_SGML_COMMAND
; // wait for a pending command
775 // fold whole tag (-- when closing the tag)
776 if (foldHTMLPreprocessor
)
781 // handle the end of a pre-processor = Non-HTML
783 ((inScriptType
== eNonHtmlPreProc
)
784 || (inScriptType
== eNonHtmlScriptPreProc
)) && (
785 ((scriptLanguage
!= eScriptNone
) && stateAllowsTermination(state
) && ((ch
== '%') || (ch
== '?')))
786 ) && (chNext
== '>')) ||
787 ((scriptLanguage
== eScriptSGML
) && (ch
== '>') && (state
!= SCE_H_SGML_COMMENT
))) {
788 if (state
== SCE_H_ASPAT
) {
789 aspScript
= segIsScriptingIndicator(styler
,
790 styler
.GetStartSegment(), i
- 1, aspScript
);
792 // Bounce out of any ASP mode
795 classifyWordHTJS(styler
.GetStartSegment(), i
- 1, keywords2
, styler
, inScriptType
);
798 classifyWordHTVB(styler
.GetStartSegment(), i
- 1, keywords3
, styler
, inScriptType
);
801 classifyWordHTPy(styler
.GetStartSegment(), i
- 1, keywords4
, styler
, prevWord
, inScriptType
);
804 classifyWordHTPHP(styler
.GetStartSegment(), i
- 1, keywords5
, styler
);
806 case SCE_H_XCCOMMENT
:
807 styler
.ColourTo(i
- 1, state
);
810 styler
.ColourTo(i
- 1, StateToPrint
);
813 if (scriptLanguage
!= eScriptSGML
) {
818 styler
.ColourTo(i
, SCE_H_ASP
);
819 else if (scriptLanguage
== eScriptXML
)
820 styler
.ColourTo(i
, SCE_H_XMLEND
);
821 else if (scriptLanguage
== eScriptSGML
)
822 styler
.ColourTo(i
, SCE_H_SGML_DEFAULT
);
824 styler
.ColourTo(i
, SCE_H_QUESTION
);
825 state
= beforePreProc
;
826 if (inScriptType
== eNonHtmlScriptPreProc
)
827 inScriptType
= eNonHtmlScript
;
829 inScriptType
= eHtml
;
830 // Unfold all scripting languages, except for XML tag
831 if (foldHTMLPreprocessor
&& (scriptLanguage
!= eScriptXML
)) {
834 scriptLanguage
= eScriptNone
;
837 /////////////////////////////////////
842 // in HTML, fold on tag open and unfold on tag close
844 tagClosing
= (chNext
== '/');
845 styler
.ColourTo(i
- 1, StateToPrint
);
847 state
= SCE_H_TAGUNKNOWN
;
848 } else if (ch
== '&') {
849 styler
.ColourTo(i
- 1, SCE_H_DEFAULT
);
850 state
= SCE_H_ENTITY
;
853 case SCE_H_SGML_DEFAULT
:
854 case SCE_H_SGML_BLOCK_DEFAULT
:
855 // if (scriptLanguage == eScriptSGMLblock)
856 // StateToPrint = SCE_H_SGML_BLOCK_DEFAULT;
859 styler
.ColourTo(i
- 1, StateToPrint
);
860 state
= SCE_H_SGML_DOUBLESTRING
;
861 } else if (ch
== '\'') {
862 styler
.ColourTo(i
- 1, StateToPrint
);
863 state
= SCE_H_SGML_SIMPLESTRING
;
864 } else if ((ch
== '-') && (chPrev
== '-')) {
865 styler
.ColourTo(i
- 2, StateToPrint
);
866 state
= SCE_H_SGML_COMMENT
;
867 } else if (isascii(ch
) && isalpha(ch
) && (chPrev
== '%')) {
868 styler
.ColourTo(i
- 2, StateToPrint
);
869 state
= SCE_H_SGML_ENTITY
;
870 } else if (ch
== '#') {
871 styler
.ColourTo(i
- 1, StateToPrint
);
872 state
= SCE_H_SGML_SPECIAL
;
873 } else if (ch
== '[') {
874 styler
.ColourTo(i
- 1, StateToPrint
);
875 scriptLanguage
= eScriptSGMLblock
;
876 state
= SCE_H_SGML_BLOCK_DEFAULT
;
877 } else if (ch
== ']') {
878 if (scriptLanguage
== eScriptSGMLblock
) {
879 styler
.ColourTo(i
, StateToPrint
);
880 scriptLanguage
= eScriptSGML
;
882 styler
.ColourTo(i
- 1, StateToPrint
);
883 styler
.ColourTo(i
, SCE_H_SGML_ERROR
);
885 state
= SCE_H_SGML_DEFAULT
;
886 } else if (scriptLanguage
== eScriptSGMLblock
) {
887 if ((ch
== '!') && (chPrev
== '<')) {
888 styler
.ColourTo(i
- 2, StateToPrint
);
889 styler
.ColourTo(i
, SCE_H_SGML_DEFAULT
);
890 state
= SCE_H_SGML_COMMAND
;
891 } else if (ch
== '>') {
892 styler
.ColourTo(i
- 1, StateToPrint
);
893 styler
.ColourTo(i
, SCE_H_SGML_DEFAULT
);
897 case SCE_H_SGML_COMMAND
:
898 if ((ch
== '-') && (chPrev
== '-')) {
899 styler
.ColourTo(i
- 2, StateToPrint
);
900 state
= SCE_H_SGML_COMMENT
;
901 } else if (!issgmlwordchar(ch
)) {
902 if (isWordHSGML(styler
.GetStartSegment(), i
- 1, keywords6
, styler
)) {
903 styler
.ColourTo(i
- 1, StateToPrint
);
904 state
= SCE_H_SGML_1ST_PARAM
;
906 state
= SCE_H_SGML_ERROR
;
910 case SCE_H_SGML_1ST_PARAM
:
911 // wait for the beginning of the word
912 if ((ch
== '-') && (chPrev
== '-')) {
913 if (scriptLanguage
== eScriptSGMLblock
) {
914 styler
.ColourTo(i
- 2, SCE_H_SGML_BLOCK_DEFAULT
);
916 styler
.ColourTo(i
- 2, SCE_H_SGML_DEFAULT
);
918 state
= SCE_H_SGML_1ST_PARAM_COMMENT
;
919 } else if (issgmlwordchar(ch
)) {
920 if (scriptLanguage
== eScriptSGMLblock
) {
921 styler
.ColourTo(i
- 1, SCE_H_SGML_BLOCK_DEFAULT
);
923 styler
.ColourTo(i
- 1, SCE_H_SGML_DEFAULT
);
925 // find the length of the word
927 while (ishtmlwordchar(styler
.SafeGetCharAt(i
+ size
)))
929 styler
.ColourTo(i
+ size
- 1, StateToPrint
);
931 visibleChars
+= size
- 1;
932 ch
= styler
.SafeGetCharAt(i
);
933 if (scriptLanguage
== eScriptSGMLblock
) {
934 state
= SCE_H_SGML_BLOCK_DEFAULT
;
936 state
= SCE_H_SGML_DEFAULT
;
941 case SCE_H_SGML_ERROR
:
942 if ((ch
== '-') && (chPrev
== '-')) {
943 styler
.ColourTo(i
- 2, StateToPrint
);
944 state
= SCE_H_SGML_COMMENT
;
946 case SCE_H_SGML_DOUBLESTRING
:
948 styler
.ColourTo(i
, StateToPrint
);
949 state
= SCE_H_SGML_DEFAULT
;
952 case SCE_H_SGML_SIMPLESTRING
:
954 styler
.ColourTo(i
, StateToPrint
);
955 state
= SCE_H_SGML_DEFAULT
;
958 case SCE_H_SGML_COMMENT
:
959 if ((ch
== '-') && (chPrev
== '-')) {
960 styler
.ColourTo(i
, StateToPrint
);
961 state
= SCE_H_SGML_DEFAULT
;
965 if ((chPrev2
== ']') && (chPrev
== ']') && (ch
== '>')) {
966 styler
.ColourTo(i
, StateToPrint
);
967 state
= SCE_H_DEFAULT
;
972 if ((chPrev2
== '-') && (chPrev
== '-') && (ch
== '>')) {
973 styler
.ColourTo(i
, StateToPrint
);
974 state
= SCE_H_DEFAULT
;
978 case SCE_H_SGML_1ST_PARAM_COMMENT
:
979 if ((ch
== '-') && (chPrev
== '-')) {
980 styler
.ColourTo(i
, SCE_H_SGML_COMMENT
);
981 state
= SCE_H_SGML_1ST_PARAM
;
984 case SCE_H_SGML_SPECIAL
:
985 if (!(isascii(ch
) && isupper(ch
))) {
986 styler
.ColourTo(i
- 1, StateToPrint
);
988 state
= SCE_H_SGML_ERROR
;
990 state
= SCE_H_SGML_DEFAULT
;
994 case SCE_H_SGML_ENTITY
:
996 styler
.ColourTo(i
, StateToPrint
);
997 state
= SCE_H_SGML_DEFAULT
;
998 } else if (!(isascii(ch
) && isalnum(ch
)) && ch
!= '-' && ch
!= '.') {
999 styler
.ColourTo(i
, SCE_H_SGML_ERROR
);
1000 state
= SCE_H_SGML_DEFAULT
;
1005 styler
.ColourTo(i
, StateToPrint
);
1006 state
= SCE_H_DEFAULT
;
1008 if (ch
!= '#' && !(isascii(ch
) && isalnum(ch
)) // Should check that '#' follows '&', but it is unlikely anyway...
1009 && ch
!= '.' && ch
!= '-' && ch
!= '_' && ch
!= ':') { // valid in XML
1010 styler
.ColourTo(i
, SCE_H_TAGUNKNOWN
);
1011 state
= SCE_H_DEFAULT
;
1014 case SCE_H_TAGUNKNOWN
:
1015 if (!ishtmlwordchar(ch
) && !((ch
== '/') && (chPrev
== '<')) && ch
!= '[') {
1016 int eClass
= classifyTagHTML(styler
.GetStartSegment(),
1017 i
- 1, keywords
, styler
, tagDontFold
, caseSensitive
);
1018 if (eClass
== SCE_H_SCRIPT
) {
1020 inScriptType
= eNonHtmlScript
;
1021 scriptLanguage
= clientScript
;
1024 scriptLanguage
= eScriptNone
;
1029 styler
.ColourTo(i
, eClass
);
1030 if (inScriptType
== eNonHtmlScript
) {
1031 state
= StateForScript(scriptLanguage
);
1033 state
= SCE_H_DEFAULT
;
1044 } else if (ch
== '/' && chNext
== '>') {
1045 if (eClass
== SCE_H_TAGUNKNOWN
) {
1046 styler
.ColourTo(i
+ 1, SCE_H_TAGUNKNOWN
);
1048 styler
.ColourTo(i
- 1, StateToPrint
);
1049 styler
.ColourTo(i
+ 1, SCE_H_TAGEND
);
1053 state
= SCE_H_DEFAULT
;
1056 if (eClass
!= SCE_H_TAGUNKNOWN
) {
1057 if (eClass
== SCE_H_SGML_DEFAULT
) {
1058 state
= SCE_H_SGML_DEFAULT
;
1060 state
= SCE_H_OTHER
;
1066 case SCE_H_ATTRIBUTE
:
1067 if (!ishtmlwordchar(ch
) && ch
!= '/' && ch
!= '-') {
1068 if (inScriptType
== eNonHtmlScript
) {
1069 int scriptLanguagePrev
= scriptLanguage
;
1070 clientScript
= segIsScriptingIndicator(styler
, styler
.GetStartSegment(), i
- 1, scriptLanguage
);
1071 scriptLanguage
= clientScript
;
1072 if ((scriptLanguagePrev
!= scriptLanguage
) && (scriptLanguage
== eScriptNone
))
1073 inScriptType
= eHtml
;
1075 classifyAttribHTML(styler
.GetStartSegment(), i
- 1, keywords
, styler
);
1077 styler
.ColourTo(i
, SCE_H_TAG
);
1078 if (inScriptType
== eNonHtmlScript
) {
1079 state
= StateForScript(scriptLanguage
);
1081 state
= SCE_H_DEFAULT
;
1092 } else if (ch
== '=') {
1093 styler
.ColourTo(i
, SCE_H_OTHER
);
1094 state
= SCE_H_VALUE
;
1096 state
= SCE_H_OTHER
;
1102 styler
.ColourTo(i
- 1, StateToPrint
);
1103 styler
.ColourTo(i
, SCE_H_TAG
);
1104 if (inScriptType
== eNonHtmlScript
) {
1105 state
= StateForScript(scriptLanguage
);
1107 state
= SCE_H_DEFAULT
;
1118 } else if (ch
== '\"') {
1119 styler
.ColourTo(i
- 1, StateToPrint
);
1120 state
= SCE_H_DOUBLESTRING
;
1121 } else if (ch
== '\'') {
1122 styler
.ColourTo(i
- 1, StateToPrint
);
1123 state
= SCE_H_SINGLESTRING
;
1124 } else if (ch
== '=') {
1125 styler
.ColourTo(i
, StateToPrint
);
1126 state
= SCE_H_VALUE
;
1127 } else if (ch
== '/' && chNext
== '>') {
1128 styler
.ColourTo(i
- 1, StateToPrint
);
1129 styler
.ColourTo(i
+ 1, SCE_H_TAGEND
);
1132 state
= SCE_H_DEFAULT
;
1134 } else if (ch
== '?' && chNext
== '>') {
1135 styler
.ColourTo(i
- 1, StateToPrint
);
1136 styler
.ColourTo(i
+ 1, SCE_H_XMLEND
);
1139 state
= SCE_H_DEFAULT
;
1140 } else if (ishtmlwordchar(ch
)) {
1141 styler
.ColourTo(i
- 1, StateToPrint
);
1142 state
= SCE_H_ATTRIBUTE
;
1145 case SCE_H_DOUBLESTRING
:
1147 if (inScriptType
== eNonHtmlScript
) {
1148 scriptLanguage
= segIsScriptingIndicator(styler
, styler
.GetStartSegment(), i
, scriptLanguage
);
1150 styler
.ColourTo(i
, SCE_H_DOUBLESTRING
);
1151 state
= SCE_H_OTHER
;
1154 case SCE_H_SINGLESTRING
:
1156 if (inScriptType
== eNonHtmlScript
) {
1157 scriptLanguage
= segIsScriptingIndicator(styler
, styler
.GetStartSegment(), i
, scriptLanguage
);
1159 styler
.ColourTo(i
, SCE_H_SINGLESTRING
);
1160 state
= SCE_H_OTHER
;
1164 if (!ishtmlwordchar(ch
)) {
1165 if (ch
== '\"' && chPrev
== '=') {
1166 // Should really test for being first character
1167 state
= SCE_H_DOUBLESTRING
;
1168 } else if (ch
== '\'' && chPrev
== '=') {
1169 state
= SCE_H_SINGLESTRING
;
1171 if (IsNumber(styler
.GetStartSegment(), styler
)) {
1172 styler
.ColourTo(i
- 1, SCE_H_NUMBER
);
1174 styler
.ColourTo(i
- 1, StateToPrint
);
1177 styler
.ColourTo(i
, SCE_H_TAG
);
1178 if (inScriptType
== eNonHtmlScript
) {
1179 state
= StateForScript(scriptLanguage
);
1181 state
= SCE_H_DEFAULT
;
1193 state
= SCE_H_OTHER
;
1198 case SCE_HJ_DEFAULT
:
1200 case SCE_HJ_SYMBOLS
:
1201 if (iswordstart(ch
)) {
1202 styler
.ColourTo(i
- 1, StateToPrint
);
1203 state
= SCE_HJ_WORD
;
1204 } else if (ch
== '/' && chNext
== '*') {
1205 styler
.ColourTo(i
- 1, StateToPrint
);
1207 state
= SCE_HJ_COMMENTDOC
;
1209 state
= SCE_HJ_COMMENT
;
1210 } else if (ch
== '/' && chNext
== '/') {
1211 styler
.ColourTo(i
- 1, StateToPrint
);
1212 state
= SCE_HJ_COMMENTLINE
;
1213 } else if (ch
== '/' && isOKBeforeRE(chPrevNonWhite
)) {
1214 styler
.ColourTo(i
- 1, StateToPrint
);
1215 state
= SCE_HJ_REGEX
;
1216 } else if (ch
== '\"') {
1217 styler
.ColourTo(i
- 1, StateToPrint
);
1218 state
= SCE_HJ_DOUBLESTRING
;
1219 } else if (ch
== '\'') {
1220 styler
.ColourTo(i
- 1, StateToPrint
);
1221 state
= SCE_HJ_SINGLESTRING
;
1222 } else if ((ch
== '<') && (chNext
== '!') && (chNext2
== '-') &&
1223 styler
.SafeGetCharAt(i
+ 3) == '-') {
1224 styler
.ColourTo(i
- 1, StateToPrint
);
1225 state
= SCE_HJ_COMMENTLINE
;
1226 } else if ((ch
== '-') && (chNext
== '-') && (chNext2
== '>')) {
1227 styler
.ColourTo(i
- 1, StateToPrint
);
1228 state
= SCE_HJ_COMMENTLINE
;
1230 } else if (isoperator(ch
)) {
1231 styler
.ColourTo(i
- 1, StateToPrint
);
1232 styler
.ColourTo(i
, statePrintForState(SCE_HJ_SYMBOLS
, inScriptType
));
1233 state
= SCE_HJ_DEFAULT
;
1234 } else if ((ch
== ' ') || (ch
== '\t')) {
1235 if (state
== SCE_HJ_START
) {
1236 styler
.ColourTo(i
- 1, StateToPrint
);
1237 state
= SCE_HJ_DEFAULT
;
1242 if (!iswordchar(ch
)) {
1243 classifyWordHTJS(styler
.GetStartSegment(), i
- 1, keywords2
, styler
, inScriptType
);
1244 //styler.ColourTo(i - 1, eHTJSKeyword);
1245 state
= SCE_HJ_DEFAULT
;
1246 if (ch
== '/' && chNext
== '*') {
1248 state
= SCE_HJ_COMMENTDOC
;
1250 state
= SCE_HJ_COMMENT
;
1251 } else if (ch
== '/' && chNext
== '/') {
1252 state
= SCE_HJ_COMMENTLINE
;
1253 } else if (ch
== '\"') {
1254 state
= SCE_HJ_DOUBLESTRING
;
1255 } else if (ch
== '\'') {
1256 state
= SCE_HJ_SINGLESTRING
;
1257 } else if ((ch
== '-') && (chNext
== '-') && (chNext2
== '>')) {
1258 styler
.ColourTo(i
- 1, StateToPrint
);
1259 state
= SCE_HJ_COMMENTLINE
;
1261 } else if (isoperator(ch
)) {
1262 styler
.ColourTo(i
, statePrintForState(SCE_HJ_SYMBOLS
, inScriptType
));
1263 state
= SCE_HJ_DEFAULT
;
1267 case SCE_HJ_COMMENT
:
1268 case SCE_HJ_COMMENTDOC
:
1269 if (ch
== '/' && chPrev
== '*') {
1270 styler
.ColourTo(i
, StateToPrint
);
1271 state
= SCE_HJ_DEFAULT
;
1275 case SCE_HJ_COMMENTLINE
:
1276 if (ch
== '\r' || ch
== '\n') {
1277 styler
.ColourTo(i
- 1, statePrintForState(SCE_HJ_COMMENTLINE
, inScriptType
));
1278 state
= SCE_HJ_DEFAULT
;
1282 case SCE_HJ_DOUBLESTRING
:
1284 if (chNext
== '\"' || chNext
== '\'' || chNext
== '\\') {
1287 } else if (ch
== '\"') {
1288 styler
.ColourTo(i
, statePrintForState(SCE_HJ_DOUBLESTRING
, inScriptType
));
1289 state
= SCE_HJ_DEFAULT
;
1290 } else if ((inScriptType
== eNonHtmlScript
) && (ch
== '-') && (chNext
== '-') && (chNext2
== '>')) {
1291 styler
.ColourTo(i
- 1, StateToPrint
);
1292 state
= SCE_HJ_COMMENTLINE
;
1294 } else if (isLineEnd(ch
)) {
1295 styler
.ColourTo(i
- 1, StateToPrint
);
1296 state
= SCE_HJ_STRINGEOL
;
1299 case SCE_HJ_SINGLESTRING
:
1301 if (chNext
== '\"' || chNext
== '\'' || chNext
== '\\') {
1304 } else if (ch
== '\'') {
1305 styler
.ColourTo(i
, statePrintForState(SCE_HJ_SINGLESTRING
, inScriptType
));
1306 state
= SCE_HJ_DEFAULT
;
1307 } else if ((inScriptType
== eNonHtmlScript
) && (ch
== '-') && (chNext
== '-') && (chNext2
== '>')) {
1308 styler
.ColourTo(i
- 1, StateToPrint
);
1309 state
= SCE_HJ_COMMENTLINE
;
1311 } else if (isLineEnd(ch
)) {
1312 styler
.ColourTo(i
- 1, StateToPrint
);
1313 state
= SCE_HJ_STRINGEOL
;
1316 case SCE_HJ_STRINGEOL
:
1317 if (!isLineEnd(ch
)) {
1318 styler
.ColourTo(i
- 1, StateToPrint
);
1319 state
= SCE_HJ_DEFAULT
;
1320 } else if (!isLineEnd(chNext
)) {
1321 styler
.ColourTo(i
, StateToPrint
);
1322 state
= SCE_HJ_DEFAULT
;
1326 if (ch
== '\r' || ch
== '\n' || ch
== '/') {
1328 while (isascii(chNext
) && islower(chNext
)) { // gobble regex flags
1331 chNext
= styler
.SafeGetCharAt(i
+ 1);
1334 styler
.ColourTo(i
, StateToPrint
);
1335 state
= SCE_HJ_DEFAULT
;
1336 } else if (ch
== '\\') {
1337 // Gobble up the quoted character
1338 if (chNext
== '\\' || chNext
== '/') {
1341 chNext
= styler
.SafeGetCharAt(i
+ 1);
1345 case SCE_HB_DEFAULT
:
1347 if (iswordstart(ch
)) {
1348 styler
.ColourTo(i
- 1, StateToPrint
);
1349 state
= SCE_HB_WORD
;
1350 } else if (ch
== '\'') {
1351 styler
.ColourTo(i
- 1, StateToPrint
);
1352 state
= SCE_HB_COMMENTLINE
;
1353 } else if (ch
== '\"') {
1354 styler
.ColourTo(i
- 1, StateToPrint
);
1355 state
= SCE_HB_STRING
;
1356 } else if ((ch
== '<') && (chNext
== '!') && (chNext2
== '-') &&
1357 styler
.SafeGetCharAt(i
+ 3) == '-') {
1358 styler
.ColourTo(i
- 1, StateToPrint
);
1359 state
= SCE_HB_COMMENTLINE
;
1360 } else if (isoperator(ch
)) {
1361 styler
.ColourTo(i
- 1, StateToPrint
);
1362 styler
.ColourTo(i
, statePrintForState(SCE_HB_DEFAULT
, inScriptType
));
1363 state
= SCE_HB_DEFAULT
;
1364 } else if ((ch
== ' ') || (ch
== '\t')) {
1365 if (state
== SCE_HB_START
) {
1366 styler
.ColourTo(i
- 1, StateToPrint
);
1367 state
= SCE_HB_DEFAULT
;
1372 if (!iswordchar(ch
)) {
1373 state
= classifyWordHTVB(styler
.GetStartSegment(), i
- 1, keywords3
, styler
, inScriptType
);
1374 if (state
== SCE_HB_DEFAULT
) {
1376 state
= SCE_HB_STRING
;
1377 } else if (ch
== '\'') {
1378 state
= SCE_HB_COMMENTLINE
;
1379 } else if (isoperator(ch
)) {
1380 styler
.ColourTo(i
, statePrintForState(SCE_HB_DEFAULT
, inScriptType
));
1381 state
= SCE_HB_DEFAULT
;
1388 styler
.ColourTo(i
, StateToPrint
);
1389 state
= SCE_HB_DEFAULT
;
1390 } else if (ch
== '\r' || ch
== '\n') {
1391 styler
.ColourTo(i
- 1, StateToPrint
);
1392 state
= SCE_HB_STRINGEOL
;
1395 case SCE_HB_COMMENTLINE
:
1396 if (ch
== '\r' || ch
== '\n') {
1397 styler
.ColourTo(i
- 1, StateToPrint
);
1398 state
= SCE_HB_DEFAULT
;
1401 case SCE_HB_STRINGEOL
:
1402 if (!isLineEnd(ch
)) {
1403 styler
.ColourTo(i
- 1, StateToPrint
);
1404 state
= SCE_HB_DEFAULT
;
1405 } else if (!isLineEnd(chNext
)) {
1406 styler
.ColourTo(i
, StateToPrint
);
1407 state
= SCE_HB_DEFAULT
;
1410 case SCE_HP_DEFAULT
:
1412 if (iswordstart(ch
)) {
1413 styler
.ColourTo(i
- 1, StateToPrint
);
1414 state
= SCE_HP_WORD
;
1415 } else if ((ch
== '<') && (chNext
== '!') && (chNext2
== '-') &&
1416 styler
.SafeGetCharAt(i
+ 3) == '-') {
1417 styler
.ColourTo(i
- 1, StateToPrint
);
1418 state
= SCE_HP_COMMENTLINE
;
1419 } else if (ch
== '#') {
1420 styler
.ColourTo(i
- 1, StateToPrint
);
1421 state
= SCE_HP_COMMENTLINE
;
1422 } else if (ch
== '\"') {
1423 styler
.ColourTo(i
- 1, StateToPrint
);
1424 if (chNext
== '\"' && chNext2
== '\"') {
1426 state
= SCE_HP_TRIPLEDOUBLE
;
1429 chNext
= styler
.SafeGetCharAt(i
+ 1);
1431 // state = statePrintForState(SCE_HP_STRING,inScriptType);
1432 state
= SCE_HP_STRING
;
1434 } else if (ch
== '\'') {
1435 styler
.ColourTo(i
- 1, StateToPrint
);
1436 if (chNext
== '\'' && chNext2
== '\'') {
1438 state
= SCE_HP_TRIPLE
;
1441 chNext
= styler
.SafeGetCharAt(i
+ 1);
1443 state
= SCE_HP_CHARACTER
;
1445 } else if (isoperator(ch
)) {
1446 styler
.ColourTo(i
- 1, StateToPrint
);
1447 styler
.ColourTo(i
, statePrintForState(SCE_HP_OPERATOR
, inScriptType
));
1448 } else if ((ch
== ' ') || (ch
== '\t')) {
1449 if (state
== SCE_HP_START
) {
1450 styler
.ColourTo(i
- 1, StateToPrint
);
1451 state
= SCE_HP_DEFAULT
;
1456 if (!iswordchar(ch
)) {
1457 classifyWordHTPy(styler
.GetStartSegment(), i
- 1, keywords4
, styler
, prevWord
, inScriptType
);
1458 state
= SCE_HP_DEFAULT
;
1460 state
= SCE_HP_COMMENTLINE
;
1461 } else if (ch
== '\"') {
1462 if (chNext
== '\"' && chNext2
== '\"') {
1464 state
= SCE_HP_TRIPLEDOUBLE
;
1467 chNext
= styler
.SafeGetCharAt(i
+ 1);
1469 state
= SCE_HP_STRING
;
1471 } else if (ch
== '\'') {
1472 if (chNext
== '\'' && chNext2
== '\'') {
1474 state
= SCE_HP_TRIPLE
;
1477 chNext
= styler
.SafeGetCharAt(i
+ 1);
1479 state
= SCE_HP_CHARACTER
;
1481 } else if (isoperator(ch
)) {
1482 styler
.ColourTo(i
, statePrintForState(SCE_HP_OPERATOR
, inScriptType
));
1486 case SCE_HP_COMMENTLINE
:
1487 if (ch
== '\r' || ch
== '\n') {
1488 styler
.ColourTo(i
- 1, StateToPrint
);
1489 state
= SCE_HP_DEFAULT
;
1494 if (chNext
== '\"' || chNext
== '\'' || chNext
== '\\') {
1497 chNext
= styler
.SafeGetCharAt(i
+ 1);
1499 } else if (ch
== '\"') {
1500 styler
.ColourTo(i
, StateToPrint
);
1501 state
= SCE_HP_DEFAULT
;
1504 case SCE_HP_CHARACTER
:
1506 if (chNext
== '\"' || chNext
== '\'' || chNext
== '\\') {
1509 chNext
= styler
.SafeGetCharAt(i
+ 1);
1511 } else if (ch
== '\'') {
1512 styler
.ColourTo(i
, StateToPrint
);
1513 state
= SCE_HP_DEFAULT
;
1517 if (ch
== '\'' && chPrev
== '\'' && chPrev2
== '\'') {
1518 styler
.ColourTo(i
, StateToPrint
);
1519 state
= SCE_HP_DEFAULT
;
1522 case SCE_HP_TRIPLEDOUBLE
:
1523 if (ch
== '\"' && chPrev
== '\"' && chPrev2
== '\"') {
1524 styler
.ColourTo(i
, StateToPrint
);
1525 state
= SCE_HP_DEFAULT
;
1528 ///////////// start - PHP state handling
1530 if (!iswordchar(ch
)) {
1531 classifyWordHTPHP(styler
.GetStartSegment(), i
- 1, keywords5
, styler
);
1532 if (ch
== '/' && chNext
== '*') {
1534 state
= SCE_HPHP_COMMENT
;
1535 } else if (ch
== '/' && chNext
== '/') {
1537 state
= SCE_HPHP_COMMENTLINE
;
1538 } else if (ch
== '#') {
1539 state
= SCE_HPHP_COMMENTLINE
;
1540 } else if (ch
== '\"') {
1541 state
= SCE_HPHP_HSTRING
;
1542 strcpy(phpStringDelimiter
, "\"");
1543 } else if (styler
.Match(i
, "<<<")) {
1544 state
= SCE_HPHP_HSTRING
;
1545 i
= FindPhpStringDelimiter(phpStringDelimiter
, sizeof(phpStringDelimiter
), i
+ 3, lengthDoc
, styler
);
1546 } else if (ch
== '\'') {
1547 state
= SCE_HPHP_SIMPLESTRING
;
1548 } else if (ch
== '$' && IsPhpWordStart(chNext
)) {
1549 state
= SCE_HPHP_VARIABLE
;
1550 } else if (isoperator(ch
)) {
1551 state
= SCE_HPHP_OPERATOR
;
1553 state
= SCE_HPHP_DEFAULT
;
1557 case SCE_HPHP_NUMBER
:
1558 // recognize bases 8,10 or 16 integers OR floating-point numbers
1560 && strchr(".xXabcdefABCDEF", ch
) == NULL
1561 && ((ch
!= '-' && ch
!= '+') || (chPrev
!= 'e' && chPrev
!= 'E'))) {
1562 styler
.ColourTo(i
- 1, SCE_HPHP_NUMBER
);
1564 state
= SCE_HPHP_OPERATOR
;
1566 state
= SCE_HPHP_DEFAULT
;
1569 case SCE_HPHP_VARIABLE
:
1570 if (!IsPhpWordChar(ch
)) {
1571 styler
.ColourTo(i
- 1, SCE_HPHP_VARIABLE
);
1573 state
= SCE_HPHP_OPERATOR
;
1575 state
= SCE_HPHP_DEFAULT
;
1578 case SCE_HPHP_COMMENT
:
1579 if (ch
== '/' && chPrev
== '*') {
1580 styler
.ColourTo(i
, StateToPrint
);
1581 state
= SCE_HPHP_DEFAULT
;
1584 case SCE_HPHP_COMMENTLINE
:
1585 if (ch
== '\r' || ch
== '\n') {
1586 styler
.ColourTo(i
- 1, StateToPrint
);
1587 state
= SCE_HPHP_DEFAULT
;
1590 case SCE_HPHP_HSTRING
:
1591 if (ch
== '\\' && (phpStringDelimiter
[0] == '\"' || chNext
== '$' || chNext
== '{')) {
1592 // skip the next char
1594 } else if (((ch
== '{' && chNext
== '$') || (ch
== '$' && chNext
== '{'))
1595 && IsPhpWordStart(chNext2
)) {
1596 styler
.ColourTo(i
- 1, StateToPrint
);
1597 state
= SCE_HPHP_COMPLEX_VARIABLE
;
1598 } else if (ch
== '$' && IsPhpWordStart(chNext
)) {
1599 styler
.ColourTo(i
- 1, StateToPrint
);
1600 state
= SCE_HPHP_HSTRING_VARIABLE
;
1601 } else if (styler
.Match(i
, phpStringDelimiter
)) {
1602 if (strlen(phpStringDelimiter
) > 1)
1603 i
+= strlen(phpStringDelimiter
) - 1;
1604 styler
.ColourTo(i
, StateToPrint
);
1605 state
= SCE_HPHP_DEFAULT
;
1608 case SCE_HPHP_SIMPLESTRING
:
1610 // skip the next char
1612 } else if (ch
== '\'') {
1613 styler
.ColourTo(i
, StateToPrint
);
1614 state
= SCE_HPHP_DEFAULT
;
1617 case SCE_HPHP_HSTRING_VARIABLE
:
1618 if (!IsPhpWordChar(ch
)) {
1619 styler
.ColourTo(i
- 1, StateToPrint
);
1620 i
--; // strange but it works
1621 state
= SCE_HPHP_HSTRING
;
1624 case SCE_HPHP_COMPLEX_VARIABLE
:
1626 styler
.ColourTo(i
, StateToPrint
);
1627 state
= SCE_HPHP_HSTRING
;
1630 case SCE_HPHP_OPERATOR
:
1631 case SCE_HPHP_DEFAULT
:
1632 styler
.ColourTo(i
- 1, StateToPrint
);
1633 if (IsADigit(ch
) || (ch
== '.' && IsADigit(chNext
))) {
1634 state
= SCE_HPHP_NUMBER
;
1635 } else if (iswordstart(ch
)) {
1636 state
= SCE_HPHP_WORD
;
1637 } else if (ch
== '/' && chNext
== '*') {
1639 state
= SCE_HPHP_COMMENT
;
1640 } else if (ch
== '/' && chNext
== '/') {
1642 state
= SCE_HPHP_COMMENTLINE
;
1643 } else if (ch
== '#') {
1644 state
= SCE_HPHP_COMMENTLINE
;
1645 } else if (ch
== '\"') {
1646 state
= SCE_HPHP_HSTRING
;
1647 strcpy(phpStringDelimiter
, "\"");
1648 } else if (styler
.Match(i
, "<<<")) {
1649 state
= SCE_HPHP_HSTRING
;
1650 i
= FindPhpStringDelimiter(phpStringDelimiter
, sizeof(phpStringDelimiter
), i
+ 3, lengthDoc
, styler
);
1651 } else if (ch
== '\'') {
1652 state
= SCE_HPHP_SIMPLESTRING
;
1653 } else if (ch
== '$' && IsPhpWordStart(chNext
)) {
1654 state
= SCE_HPHP_VARIABLE
;
1655 } else if (isoperator(ch
)) {
1656 state
= SCE_HPHP_OPERATOR
;
1657 } else if ((state
== SCE_HPHP_OPERATOR
) && (isspacechar(ch
))) {
1658 state
= SCE_HPHP_DEFAULT
;
1661 ///////////// end - PHP state handling
1664 // Some of the above terminated their lexeme but since the same character starts
1665 // the same class again, only reenter if non empty segment.
1667 bool nonEmptySegment
= i
>= static_cast<int>(styler
.GetStartSegment());
1668 if (state
== SCE_HB_DEFAULT
) { // One of the above succeeded
1669 if ((ch
== '\"') && (nonEmptySegment
)) {
1670 state
= SCE_HB_STRING
;
1671 } else if (ch
== '\'') {
1672 state
= SCE_HB_COMMENTLINE
;
1673 } else if (iswordstart(ch
)) {
1674 state
= SCE_HB_WORD
;
1675 } else if (isoperator(ch
)) {
1676 styler
.ColourTo(i
, SCE_HB_DEFAULT
);
1678 } else if (state
== SCE_HBA_DEFAULT
) { // One of the above succeeded
1679 if ((ch
== '\"') && (nonEmptySegment
)) {
1680 state
= SCE_HBA_STRING
;
1681 } else if (ch
== '\'') {
1682 state
= SCE_HBA_COMMENTLINE
;
1683 } else if (iswordstart(ch
)) {
1684 state
= SCE_HBA_WORD
;
1685 } else if (isoperator(ch
)) {
1686 styler
.ColourTo(i
, SCE_HBA_DEFAULT
);
1688 } else if (state
== SCE_HJ_DEFAULT
) { // One of the above succeeded
1689 if (ch
== '/' && chNext
== '*') {
1690 if (styler
.SafeGetCharAt(i
+ 2) == '*')
1691 state
= SCE_HJ_COMMENTDOC
;
1693 state
= SCE_HJ_COMMENT
;
1694 } else if (ch
== '/' && chNext
== '/') {
1695 state
= SCE_HJ_COMMENTLINE
;
1696 } else if ((ch
== '\"') && (nonEmptySegment
)) {
1697 state
= SCE_HJ_DOUBLESTRING
;
1698 } else if ((ch
== '\'') && (nonEmptySegment
)) {
1699 state
= SCE_HJ_SINGLESTRING
;
1700 } else if (iswordstart(ch
)) {
1701 state
= SCE_HJ_WORD
;
1702 } else if (isoperator(ch
)) {
1703 styler
.ColourTo(i
, statePrintForState(SCE_HJ_SYMBOLS
, inScriptType
));
1708 StateToPrint
= statePrintForState(state
, inScriptType
);
1709 styler
.ColourTo(lengthDoc
- 1, StateToPrint
);
1711 // Fill in the real level of the next line, keeping the current flags as they will be filled in later
1713 int flagsNext
= styler
.LevelAt(lineCurrent
) & ~SC_FOLDLEVELNUMBERMASK
;
1714 styler
.SetLevel(lineCurrent
, levelPrev
| flagsNext
);
1718 static bool isASPScript(int state
) {
1720 (state
>= SCE_HJA_START
&& state
<= SCE_HJA_REGEX
) ||
1721 (state
>= SCE_HBA_START
&& state
<= SCE_HBA_STRINGEOL
) ||
1722 (state
>= SCE_HPA_DEFAULT
&& state
<= SCE_HPA_IDENTIFIER
);
1725 static void ColouriseHBAPiece(StyleContext
&sc
, WordList
*keywordlists
[]) {
1726 WordList
&keywordsVBS
= *keywordlists
[2];
1727 if (sc
.state
== SCE_HBA_WORD
) {
1728 if (!IsAWordChar(sc
.ch
)) {
1730 sc
.GetCurrentLowered(s
, sizeof(s
));
1731 if (keywordsVBS
.InList(s
)) {
1732 if (strcmp(s
, "rem") == 0) {
1733 sc
.ChangeState(SCE_HBA_COMMENTLINE
);
1735 sc
.SetState(SCE_HBA_DEFAULT
);
1738 sc
.SetState(SCE_HBA_DEFAULT
);
1741 sc
.ChangeState(SCE_HBA_IDENTIFIER
);
1742 sc
.SetState(SCE_HBA_DEFAULT
);
1745 } else if (sc
.state
== SCE_HBA_NUMBER
) {
1746 if (!IsAWordChar(sc
.ch
)) {
1747 sc
.SetState(SCE_HBA_DEFAULT
);
1749 } else if (sc
.state
== SCE_HBA_STRING
) {
1750 if (sc
.ch
== '\"') {
1751 sc
.ForwardSetState(SCE_HBA_DEFAULT
);
1752 } else if (sc
.ch
== '\r' || sc
.ch
== '\n') {
1753 sc
.ChangeState(SCE_HBA_STRINGEOL
);
1754 sc
.ForwardSetState(SCE_HBA_DEFAULT
);
1756 } else if (sc
.state
== SCE_HBA_COMMENTLINE
) {
1757 if (sc
.ch
== '\r' || sc
.ch
== '\n') {
1758 sc
.SetState(SCE_HBA_DEFAULT
);
1762 if (sc
.state
== SCE_HBA_DEFAULT
) {
1763 if (IsADigit(sc
.ch
) || (sc
.ch
== '.' && IsADigit(sc
.chNext
))) {
1764 sc
.SetState(SCE_HBA_NUMBER
);
1765 } else if (IsAWordStart(sc
.ch
)) {
1766 sc
.SetState(SCE_HBA_WORD
);
1767 } else if (sc
.ch
== '\'') {
1768 sc
.SetState(SCE_HBA_COMMENTLINE
);
1769 } else if (sc
.ch
== '\"') {
1770 sc
.SetState(SCE_HBA_STRING
);
1775 static void ColouriseHTMLPiece(StyleContext
&sc
, WordList
*keywordlists
[]) {
1776 WordList
&keywordsTags
= *keywordlists
[0];
1777 if (sc
.state
== SCE_H_COMMENT
) {
1778 if (sc
.Match("-->")) {
1781 sc
.ForwardSetState(SCE_H_DEFAULT
);
1783 } else if (sc
.state
== SCE_H_ENTITY
) {
1785 sc
.ForwardSetState(SCE_H_DEFAULT
);
1786 } else if (sc
.ch
!= '#' && (sc
.ch
< 0x80) && !isalnum(sc
.ch
) // Should check that '#' follows '&', but it is unlikely anyway...
1787 && sc
.ch
!= '.' && sc
.ch
!= '-' && sc
.ch
!= '_' && sc
.ch
!= ':') { // valid in XML
1788 sc
.ChangeState(SCE_H_TAGUNKNOWN
);
1789 sc
.SetState(SCE_H_DEFAULT
);
1791 } else if (sc
.state
== SCE_H_TAGUNKNOWN
) {
1792 if (!ishtmlwordchar(static_cast<char>(sc
.ch
)) && !((sc
.ch
== '/') && (sc
.chPrev
== '<')) && sc
.ch
!= '[') {
1794 sc
.GetCurrentLowered(s
, sizeof(s
));
1796 if (keywordsTags
.InList(s
+ 2)) {
1797 sc
.ChangeState(SCE_H_TAG
);
1800 if (keywordsTags
.InList(s
+ 1)) {
1801 sc
.ChangeState(SCE_H_TAG
);
1805 sc
.ForwardSetState(SCE_H_DEFAULT
);
1806 } else if (sc
.Match('/', '>')) {
1807 sc
.SetState(SCE_H_TAGEND
);
1809 sc
.ForwardSetState(SCE_H_DEFAULT
);
1811 sc
.SetState(SCE_H_OTHER
);
1814 } else if (sc
.state
== SCE_H_ATTRIBUTE
) {
1815 if (!ishtmlwordchar(static_cast<char>(sc
.ch
))) {
1817 sc
.GetCurrentLowered(s
, sizeof(s
));
1818 if (!keywordsTags
.InList(s
)) {
1819 sc
.ChangeState(SCE_H_ATTRIBUTEUNKNOWN
);
1821 sc
.SetState(SCE_H_OTHER
);
1823 } else if (sc
.state
== SCE_H_OTHER
) {
1825 sc
.SetState(SCE_H_TAG
);
1826 sc
.ForwardSetState(SCE_H_DEFAULT
);
1827 } else if (sc
.Match('/', '>')) {
1828 sc
.SetState(SCE_H_TAG
);
1830 sc
.ForwardSetState(SCE_H_DEFAULT
);
1831 } else if (sc
.chPrev
== '=') {
1832 sc
.SetState(SCE_H_VALUE
);
1834 } else if (sc
.state
== SCE_H_DOUBLESTRING
) {
1835 if (sc
.ch
== '\"') {
1836 sc
.ForwardSetState(SCE_H_OTHER
);
1838 } else if (sc
.state
== SCE_H_SINGLESTRING
) {
1839 if (sc
.ch
== '\'') {
1840 sc
.ForwardSetState(SCE_H_OTHER
);
1842 } else if (sc
.state
== SCE_H_NUMBER
) {
1843 if (!IsADigit(sc
.ch
)) {
1844 sc
.SetState(SCE_H_OTHER
);
1848 if (sc
.state
== SCE_H_DEFAULT
) {
1850 if (sc
.Match("<!--"))
1851 sc
.SetState(SCE_H_COMMENT
);
1853 sc
.SetState(SCE_H_TAGUNKNOWN
);
1854 } else if (sc
.ch
== '&') {
1855 sc
.SetState(SCE_H_ENTITY
);
1857 } else if ((sc
.state
== SCE_H_OTHER
) || (sc
.state
== SCE_H_VALUE
)) {
1858 if (sc
.ch
== '\"' && sc
.chPrev
== '=') {
1859 sc
.SetState(SCE_H_DOUBLESTRING
);
1860 } else if (sc
.ch
== '\'' && sc
.chPrev
== '=') {
1861 sc
.SetState(SCE_H_SINGLESTRING
);
1862 } else if (IsADigit(sc
.ch
)) {
1863 sc
.SetState(SCE_H_NUMBER
);
1864 } else if (sc
.ch
== '>') {
1865 sc
.SetState(SCE_H_TAG
);
1866 sc
.ForwardSetState(SCE_H_DEFAULT
);
1867 } else if (ishtmlwordchar(static_cast<char>(sc
.ch
))) {
1868 sc
.SetState(SCE_H_ATTRIBUTE
);
1873 static void ColouriseASPPiece(StyleContext
&sc
, WordList
*keywordlists
[]) {
1874 // Possibly exit current state to either SCE_H_DEFAULT or SCE_HBA_DEFAULT
1875 if ((sc
.state
== SCE_H_ASPAT
|| isASPScript(sc
.state
)) && sc
.Match('%', '>')) {
1876 sc
.SetState(SCE_H_ASP
);
1878 sc
.ForwardSetState(SCE_H_DEFAULT
);
1881 // Handle some ASP script
1882 if (sc
.state
>= SCE_HBA_START
&& sc
.state
<= SCE_HBA_STRINGEOL
) {
1883 ColouriseHBAPiece(sc
, keywordlists
);
1884 } else if (sc
.state
>= SCE_H_DEFAULT
&& sc
.state
<= SCE_H_SGML_BLOCK_DEFAULT
) {
1885 ColouriseHTMLPiece(sc
, keywordlists
);
1888 // Enter new sc.state
1889 if ((sc
.state
== SCE_H_DEFAULT
) || (sc
.state
== SCE_H_TAGUNKNOWN
)) {
1890 if (sc
.Match('<', '%')) {
1891 if (sc
.state
== SCE_H_TAGUNKNOWN
)
1892 sc
.ChangeState(SCE_H_ASP
);
1894 sc
.SetState(SCE_H_ASP
);
1898 sc
.ForwardSetState(SCE_H_ASPAT
);
1903 sc
.SetState(SCE_HBA_DEFAULT
);
1909 static void ColouriseASPDoc(unsigned int startPos
, int length
, int initStyle
, WordList
*keywordlists
[],
1911 // Lexer for HTML requires more lexical states (7 bits worth) than most lexers
1912 StyleContext
sc(startPos
, length
, initStyle
, styler
, 0x7f);
1913 for (; sc
.More(); sc
.Forward()) {
1914 ColouriseASPPiece(sc
, keywordlists
);
1919 static void ColourisePHPPiece(StyleContext
&sc
, WordList
*keywordlists
[]) {
1920 // Possibly exit current state to either SCE_H_DEFAULT or SCE_HBA_DEFAULT
1921 if (sc
.state
>= SCE_HPHP_DEFAULT
&& sc
.state
<= SCE_HPHP_OPERATOR
) {
1922 if (!isPHPStringState(sc
.state
) &&
1923 (sc
.state
!= SCE_HPHP_COMMENT
) &&
1924 (sc
.Match('?', '>'))) {
1925 sc
.SetState(SCE_H_QUESTION
);
1927 sc
.ForwardSetState(SCE_H_DEFAULT
);
1931 if (sc
.state
>= SCE_H_DEFAULT
&& sc
.state
<= SCE_H_SGML_BLOCK_DEFAULT
) {
1932 ColouriseHTMLPiece(sc
, keywordlists
);
1935 // Handle some PHP script
1936 if (sc
.state
== SCE_HPHP_WORD
) {
1937 if (!IsPhpWordChar(static_cast<char>(sc
.ch
))) {
1938 sc
.SetState(SCE_HPHP_DEFAULT
);
1940 } else if (sc
.state
== SCE_HPHP_COMMENTLINE
) {
1941 if (sc
.ch
== '\r' || sc
.ch
== '\n') {
1942 sc
.SetState(SCE_HPHP_DEFAULT
);
1944 } else if (sc
.state
== SCE_HPHP_COMMENT
) {
1945 if (sc
.Match('*', '/')) {
1948 sc
.SetState(SCE_HPHP_DEFAULT
);
1950 } else if (sc
.state
== SCE_HPHP_HSTRING
) {
1951 if (sc
.ch
== '\"') {
1952 sc
.ForwardSetState(SCE_HPHP_DEFAULT
);
1954 } else if (sc
.state
== SCE_HPHP_SIMPLESTRING
) {
1955 if (sc
.ch
== '\'') {
1956 sc
.ForwardSetState(SCE_HPHP_DEFAULT
);
1958 } else if (sc
.state
== SCE_HPHP_VARIABLE
) {
1959 if (!IsPhpWordChar(static_cast<char>(sc
.ch
))) {
1960 sc
.SetState(SCE_HPHP_DEFAULT
);
1962 } else if (sc
.state
== SCE_HPHP_OPERATOR
) {
1963 sc
.SetState(SCE_HPHP_DEFAULT
);
1966 // Enter new sc.state
1967 if ((sc
.state
== SCE_H_DEFAULT
) || (sc
.state
== SCE_H_TAGUNKNOWN
)) {
1968 if (sc
.Match("<?php")) {
1969 sc
.SetState(SCE_H_QUESTION
);
1975 sc
.SetState(SCE_HPHP_DEFAULT
);
1978 if (sc
.state
== SCE_HPHP_DEFAULT
) {
1979 if (IsPhpWordStart(static_cast<char>(sc
.ch
))) {
1980 sc
.SetState(SCE_HPHP_WORD
);
1981 } else if (sc
.ch
== '#') {
1982 sc
.SetState(SCE_HPHP_COMMENTLINE
);
1983 } else if (sc
.Match("<!--")) {
1984 sc
.SetState(SCE_HPHP_COMMENTLINE
);
1985 } else if (sc
.Match('/', '/')) {
1986 sc
.SetState(SCE_HPHP_COMMENTLINE
);
1987 } else if (sc
.Match('/', '*')) {
1988 sc
.SetState(SCE_HPHP_COMMENT
);
1989 } else if (sc
.ch
== '\"') {
1990 sc
.SetState(SCE_HPHP_HSTRING
);
1991 } else if (sc
.ch
== '\'') {
1992 sc
.SetState(SCE_HPHP_SIMPLESTRING
);
1993 } else if (sc
.ch
== '$' && IsPhpWordStart(static_cast<char>(sc
.chNext
))) {
1994 sc
.SetState(SCE_HPHP_VARIABLE
);
1995 } else if (isoperator(static_cast<char>(sc
.ch
))) {
1996 sc
.SetState(SCE_HPHP_OPERATOR
);
2001 static void ColourisePHPDoc(unsigned int startPos
, int length
, int initStyle
, WordList
*keywordlists
[],
2003 // Lexer for HTML requires more lexical states (7 bits worth) than most lexers
2004 StyleContext
sc(startPos
, length
, initStyle
, styler
, 0x7f);
2005 for (; sc
.More(); sc
.Forward()) {
2006 ColourisePHPPiece(sc
, keywordlists
);
2011 static void ColourisePHPScriptDoc(unsigned int startPos
, int length
, int initStyle
, WordList
*keywordlists
[],
2013 if(startPos
== 0) initStyle
= SCE_HPHP_DEFAULT
;
2014 ColouriseHyperTextDoc(startPos
,length
,initStyle
,keywordlists
,styler
);
2017 static const char * const htmlWordListDesc
[] = {
2018 "HTML elements and attributes",
2019 "JavaScript keywords",
2020 "VBScript keywords",
2023 "SGML and DTD keywords",
2027 static const char * const phpscriptWordListDesc
[] = {
2037 LexerModule
lmHTML(SCLEX_HTML
, ColouriseHyperTextDoc
, "hypertext", 0, htmlWordListDesc
, 7);
2038 LexerModule
lmXML(SCLEX_XML
, ColouriseHyperTextDoc
, "xml", 0, htmlWordListDesc
, 7);
2039 // SCLEX_ASP and SCLEX_PHP should not be used in new code: use SCLEX_HTML instead.
2040 LexerModule
lmASP(SCLEX_ASP
, ColouriseASPDoc
, "asp", 0, htmlWordListDesc
, 7);
2041 LexerModule
lmPHP(SCLEX_PHP
, ColourisePHPDoc
, "php", 0, htmlWordListDesc
, 7);
2042 LexerModule
lmPHPSCRIPT(SCLEX_PHPSCRIPT
, ColourisePHPScriptDoc
, "phpscript", 0, phpscriptWordListDesc
, 7);