1 // Scintilla source code edit control
5 // Copyright 1998-2003 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 script_type
segIsScriptingIndicator(Accessor
&styler
, unsigned int start
, unsigned int end
, script_type prevValue
) {
41 for (; i
< end
- start
+ 1 && i
< 30; i
++) {
42 s
[i
] = static_cast<char>(tolower(styler
[start
+ i
]));
45 //Platform::DebugPrintf("Scripting indicator [%s]\n", s);
46 if (strstr(s
, "src")) // External script
50 if (strstr(s
, "pyth"))
52 if (strstr(s
, "javas"))
54 if (strstr(s
, "jscr"))
64 static int PrintScriptingIndicatorOffset(Accessor
&styler
, unsigned int start
, unsigned int end
) {
68 for (; i
< end
- start
+ 1 && i
< 30; i
++) {
69 s
[i
] = static_cast<char>(tolower(styler
[start
+ i
]));
72 if (0 == strncmp(s
, "php", 3)) {
79 static script_type
ScriptOfState(int state
) {
80 if ((state
>= SCE_HP_START
) && (state
<= SCE_HP_IDENTIFIER
)) {
82 } else if ((state
>= SCE_HB_START
) && (state
<= SCE_HB_STRINGEOL
)) {
84 } else if ((state
>= SCE_HJ_START
) && (state
<= SCE_HJ_REGEX
)) {
86 } else if ((state
>= SCE_HPHP_DEFAULT
) && (state
<= SCE_HPHP_COMMENTLINE
)) {
88 } else if ((state
>= SCE_H_SGML_DEFAULT
) && (state
< SCE_H_SGML_BLOCK_DEFAULT
)) {
90 } else if (state
== SCE_H_SGML_BLOCK_DEFAULT
) {
91 return eScriptSGMLblock
;
97 static int statePrintForState(int state
, script_mode inScriptType
) {
100 if ((state
>= SCE_HP_START
) && (state
<= SCE_HP_IDENTIFIER
)) {
101 StateToPrint
= state
+ ((inScriptType
== eNonHtmlScript
) ? 0 : SCE_HA_PYTHON
);
102 } else if ((state
>= SCE_HB_START
) && (state
<= SCE_HB_STRINGEOL
)) {
103 StateToPrint
= state
+ ((inScriptType
== eNonHtmlScript
) ? 0 : SCE_HA_VBS
);
104 } else if ((state
>= SCE_HJ_START
) && (state
<= SCE_HJ_REGEX
)) {
105 StateToPrint
= state
+ ((inScriptType
== eNonHtmlScript
) ? 0 : SCE_HA_JS
);
107 StateToPrint
= state
;
113 static int stateForPrintState(int StateToPrint
) {
116 if ((StateToPrint
>= SCE_HPA_START
) && (StateToPrint
<= SCE_HPA_IDENTIFIER
)) {
117 state
= StateToPrint
- SCE_HA_PYTHON
;
118 } else if ((StateToPrint
>= SCE_HBA_START
) && (StateToPrint
<= SCE_HBA_STRINGEOL
)) {
119 state
= StateToPrint
- SCE_HA_VBS
;
120 } else if ((StateToPrint
>= SCE_HJA_START
) && (StateToPrint
<= SCE_HJA_REGEX
)) {
121 state
= StateToPrint
- SCE_HA_JS
;
123 state
= StateToPrint
;
129 static inline bool IsNumber(unsigned int start
, Accessor
&styler
) {
130 return IsADigit(styler
[start
]) || (styler
[start
] == '.') ||
131 (styler
[start
] == '-') || (styler
[start
] == '#');
134 static inline bool isStringState(int state
) {
138 case SCE_HJ_DOUBLESTRING
:
139 case SCE_HJ_SINGLESTRING
:
140 case SCE_HJA_DOUBLESTRING
:
141 case SCE_HJA_SINGLESTRING
:
146 case SCE_HPHP_HSTRING
:
147 case SCE_HPHP_SIMPLESTRING
:
148 case SCE_HPHP_HSTRING_VARIABLE
:
149 case SCE_HPHP_COMPLEX_VARIABLE
:
159 // not really well done, since it's only comments that should lex the %> and <%
160 static inline bool isCommentASPState(int state
) {
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
:
180 static void classifyAttribHTML(unsigned int start
, unsigned int end
, WordList
&keywords
, Accessor
&styler
) {
181 bool wordIsNumber
= IsNumber(start
, styler
);
182 char chAttr
= SCE_H_ATTRIBUTEUNKNOWN
;
184 chAttr
= SCE_H_NUMBER
;
188 for (; i
< end
- start
+ 1 && i
< 30; i
++) {
189 s
[i
] = static_cast<char>(tolower(styler
[start
+ i
]));
192 if (keywords
.InList(s
))
193 chAttr
= SCE_H_ATTRIBUTE
;
195 if ((chAttr
== SCE_H_ATTRIBUTEUNKNOWN
) && !keywords
)
196 // No keywords -> all are known
197 chAttr
= SCE_H_ATTRIBUTE
;
198 styler
.ColourTo(end
, chAttr
);
201 static int classifyTagHTML(unsigned int start
, unsigned int end
,
202 WordList
&keywords
, Accessor
&styler
, bool &tagDontFold
,
203 bool caseSensitive
) {
205 // Copy after the '<'
207 for (unsigned int cPos
= start
; cPos
<= end
&& i
< 30; cPos
++) {
208 char ch
= styler
[cPos
];
209 if ((ch
!= '<') && (ch
!= '/')) {
210 s
[i
++] = caseSensitive
? ch
: static_cast<char>(tolower(ch
));
214 //The following is only a quick hack, to see if this whole thing would work
215 //we first need the tagname with a trailing space...
219 //...to find it in the list of no-container-tags
220 // (There are many more. We will need a keywordlist in the property file for this)
221 tagDontFold
= (NULL
!= strstr("meta link img area br hr input ",s
));
223 //now we can remove the trailing space
226 bool isScript
= false;
227 char chAttr
= SCE_H_TAGUNKNOWN
;
229 chAttr
= SCE_H_SGML_DEFAULT
;
230 } else if (s
[0] == '/') { // Closing tag
231 if (keywords
.InList(s
+ 1))
234 if (keywords
.InList(s
)) {
236 isScript
= 0 == strcmp(s
, "script");
239 if ((chAttr
== SCE_H_TAGUNKNOWN
) && !keywords
) {
240 // No keywords -> all are known
242 isScript
= 0 == strcmp(s
, "script");
244 styler
.ColourTo(end
, chAttr
);
245 return isScript
? SCE_H_SCRIPT
: chAttr
;
248 static void classifyWordHTJS(unsigned int start
, unsigned int end
,
249 WordList
&keywords
, Accessor
&styler
, script_mode inScriptType
) {
250 char chAttr
= SCE_HJ_WORD
;
251 bool wordIsNumber
= IsADigit(styler
[start
]) || (styler
[start
] == '.');
253 chAttr
= SCE_HJ_NUMBER
;
257 for (; i
< end
- start
+ 1 && i
< 30; i
++) {
258 s
[i
] = styler
[start
+ i
];
261 if (keywords
.InList(s
))
262 chAttr
= SCE_HJ_KEYWORD
;
264 styler
.ColourTo(end
, statePrintForState(chAttr
, inScriptType
));
267 static int classifyWordHTVB(unsigned int start
, unsigned int end
, WordList
&keywords
, Accessor
&styler
, script_mode inScriptType
) {
268 char chAttr
= SCE_HB_IDENTIFIER
;
269 bool wordIsNumber
= IsADigit(styler
[start
]) || (styler
[start
] == '.');
271 chAttr
= SCE_HB_NUMBER
;
275 for (; i
< end
- start
+ 1 && i
< 30; i
++) {
276 s
[i
] = static_cast<char>(tolower(styler
[start
+ i
]));
279 if (keywords
.InList(s
)) {
280 chAttr
= SCE_HB_WORD
;
281 if (strcmp(s
, "rem") == 0)
282 chAttr
= SCE_HB_COMMENTLINE
;
285 styler
.ColourTo(end
, statePrintForState(chAttr
, inScriptType
));
286 if (chAttr
== SCE_HB_COMMENTLINE
)
287 return SCE_HB_COMMENTLINE
;
289 return SCE_HB_DEFAULT
;
292 static void classifyWordHTPy(unsigned int start
, unsigned int end
, WordList
&keywords
, Accessor
&styler
, char *prevWord
, script_mode inScriptType
) {
293 bool wordIsNumber
= IsADigit(styler
[start
]);
296 for (; i
< end
- start
+ 1 && i
< 30; i
++) {
297 s
[i
] = styler
[start
+ i
];
300 char chAttr
= SCE_HP_IDENTIFIER
;
301 if (0 == strcmp(prevWord
, "class"))
302 chAttr
= SCE_HP_CLASSNAME
;
303 else if (0 == strcmp(prevWord
, "def"))
304 chAttr
= SCE_HP_DEFNAME
;
305 else if (wordIsNumber
)
306 chAttr
= SCE_HP_NUMBER
;
307 else if (keywords
.InList(s
))
308 chAttr
= SCE_HP_WORD
;
309 styler
.ColourTo(end
, statePrintForState(chAttr
, inScriptType
));
313 // Update the word colour to default or keyword
314 // Called when in a PHP word
315 static void classifyWordHTPHP(unsigned int start
, unsigned int end
, WordList
&keywords
, Accessor
&styler
) {
316 char chAttr
= SCE_HPHP_DEFAULT
;
317 bool wordIsNumber
= IsADigit(styler
[start
]);
319 chAttr
= SCE_HPHP_NUMBER
;
323 for (; i
< end
- start
+ 1 && i
< 100; i
++) {
324 s
[i
] = static_cast<char>(tolower(styler
[start
+ i
]));
327 if (keywords
.InList(s
))
328 chAttr
= SCE_HPHP_WORD
;
330 styler
.ColourTo(end
, chAttr
);
333 static bool isWordHSGML(unsigned int start
, unsigned int end
, WordList
&keywords
, Accessor
&styler
) {
336 for (; i
< end
- start
+ 1 && i
< 30; i
++) {
337 s
[i
] = styler
[start
+ i
];
340 return keywords
.InList(s
);
343 static bool isWordCdata(unsigned int start
, unsigned int end
, Accessor
&styler
) {
346 for (; i
< end
- start
+ 1 && i
< 30; i
++) {
347 s
[i
] = styler
[start
+ i
];
350 return (0 == strcmp(s
, "[CDATA["));
353 // Return the first state to reach when entering a scripting language
354 static int StateForScript(script_type scriptLanguage
) {
356 switch (scriptLanguage
) {
358 Result
= SCE_HB_START
;
361 Result
= SCE_HP_START
;
364 Result
= SCE_HPHP_DEFAULT
;
367 Result
= SCE_H_TAGUNKNOWN
;
370 Result
= SCE_H_SGML_DEFAULT
;
373 Result
= SCE_HJ_START
;
379 static inline bool ishtmlwordchar(char ch
) {
380 return !isascii(ch
) ||
381 (isalnum(ch
) || ch
== '.' || ch
== '-' || ch
== '_' || ch
== ':' || ch
== '!' || ch
== '#');
384 static inline bool issgmlwordchar(char ch
) {
385 return !isascii(ch
) ||
386 (isalnum(ch
) || ch
== '.' || ch
== '_' || ch
== ':' || ch
== '!' || ch
== '#' || ch
== '[');
389 static inline bool IsPhpWordStart(const unsigned char ch
) {
390 return (isascii(ch
) && (isalpha(ch
) || (ch
== '_'))) || (ch
>= 0x7f);
393 static inline bool IsPhpWordChar(char ch
) {
394 return IsADigit(ch
) || IsPhpWordStart(ch
);
397 static bool InTagState(int state
) {
398 return state
== SCE_H_TAG
|| state
== SCE_H_TAGUNKNOWN
||
399 state
== SCE_H_SCRIPT
||
400 state
== SCE_H_ATTRIBUTE
|| state
== SCE_H_ATTRIBUTEUNKNOWN
||
401 state
== SCE_H_NUMBER
|| state
== SCE_H_OTHER
||
402 state
== SCE_H_DOUBLESTRING
|| state
== SCE_H_SINGLESTRING
;
405 static bool IsCommentState(const int state
) {
406 return state
== SCE_H_COMMENT
|| state
== SCE_H_SGML_COMMENT
;
409 static bool isLineEnd(char ch
) {
410 return ch
== '\r' || ch
== '\n';
413 static bool isOKBeforeRE(char ch
) {
414 return (ch
== '(') || (ch
== '=') || (ch
== ',');
417 static bool isPHPStringState(int state
) {
419 (state
== SCE_HPHP_HSTRING
) ||
420 (state
== SCE_HPHP_SIMPLESTRING
) ||
421 (state
== SCE_HPHP_HSTRING_VARIABLE
) ||
422 (state
== SCE_HPHP_COMPLEX_VARIABLE
);
425 static int FindPhpStringDelimiter(char *phpStringDelimiter
, const int phpStringDelimiterSize
, int i
, const int lengthDoc
, Accessor
&styler
) {
427 phpStringDelimiter
[0] = '\n';
428 for (j
= i
; j
< lengthDoc
&& styler
[j
] != '\n' && styler
[j
] != '\r'; j
++) {
429 if (j
- i
< phpStringDelimiterSize
- 2)
430 phpStringDelimiter
[j
-i
+1] = styler
[j
];
434 phpStringDelimiter
[j
-i
+1] = '\0';
438 static void ColouriseHyperTextDoc(unsigned int startPos
, int length
, int initStyle
, WordList
*keywordlists
[],
440 WordList
&keywords
= *keywordlists
[0];
441 WordList
&keywords2
= *keywordlists
[1];
442 WordList
&keywords3
= *keywordlists
[2];
443 WordList
&keywords4
= *keywordlists
[3];
444 WordList
&keywords5
= *keywordlists
[4];
445 WordList
&keywords6
= *keywordlists
[5]; // SGML (DTD) keywords
447 // Lexer for HTML requires more lexical states (7 bits worth) than most lexers
448 styler
.StartAt(startPos
, STYLE_MAX
);
451 char phpStringDelimiter
[200]; // PHP is not limited in length, we are
452 phpStringDelimiter
[0] = '\0';
453 int StateToPrint
= initStyle
;
454 int state
= stateForPrintState(StateToPrint
);
456 // If inside a tag, it may be a script tag, so reread from the start to ensure any language tags are seen
457 if (InTagState(state
)) {
458 while ((startPos
> 0) && (InTagState(styler
.StyleAt(startPos
- 1)))) {
462 state
= SCE_H_DEFAULT
;
464 // String can be heredoc, must find a delimiter first
465 while (startPos
> 0 && isPHPStringState(state
) && state
!= SCE_HPHP_SIMPLESTRING
) {
468 state
= styler
.StyleAt(startPos
);
470 styler
.StartAt(startPos
, STYLE_MAX
);
472 int lineCurrent
= styler
.GetLine(startPos
);
474 if (lineCurrent
> 0) {
475 lineState
= styler
.GetLineState(lineCurrent
);
477 // Default client and ASP scripting language is JavaScript
478 lineState
= eScriptJS
<< 8;
479 lineState
|= styler
.GetPropertyInt("asp.default.language", eScriptJS
) << 4;
481 script_mode inScriptType
= script_mode((lineState
>> 0) & 0x03); // 2 bits of scripting mode
482 bool tagOpened
= (lineState
>> 2) & 0x01; // 1 bit to know if we are in an opened tag
483 bool tagClosing
= (lineState
>> 3) & 0x01; // 1 bit to know if we are in a closing tag
484 bool tagDontFold
= false; //some HTML tags should not be folded
485 script_type aspScript
= script_type((lineState
>> 4) & 0x0F); // 4 bits of script name
486 script_type clientScript
= script_type((lineState
>> 8) & 0x0F); // 4 bits of script name
487 int beforePreProc
= (lineState
>> 12) & 0xFF; // 8 bits of state
489 script_type scriptLanguage
= ScriptOfState(state
);
491 const bool foldHTML
= styler
.GetPropertyInt("fold.html", 0) != 0;
492 const bool fold
= foldHTML
&& styler
.GetPropertyInt("fold", 0);
493 const bool foldHTMLPreprocessor
= foldHTML
&& styler
.GetPropertyInt("fold.html.preprocessor", 1);
494 const bool foldCompact
= styler
.GetPropertyInt("fold.compact", 1) != 0;
495 const bool caseSensitive
= styler
.GetPropertyInt("html.tags.case.sensitive", 0) != 0;
497 int levelPrev
= styler
.LevelAt(lineCurrent
) & SC_FOLDLEVELNUMBERMASK
;
498 int levelCurrent
= levelPrev
;
499 int visibleChars
= 0;
503 char chPrevNonWhite
= ' ';
504 styler
.StartSegment(startPos
);
505 const int lengthDoc
= startPos
+ length
;
506 for (int i
= startPos
; i
< lengthDoc
; i
++) {
507 const char chPrev2
= chPrev
;
509 if (ch
!= ' ' && ch
!= '\t')
512 char chNext
= styler
.SafeGetCharAt(i
+ 1);
513 const char chNext2
= styler
.SafeGetCharAt(i
+ 2);
515 // Handle DBCS codepages
516 if (styler
.IsLeadByte(ch
)) {
522 if ((!isspacechar(ch
) || !foldCompact
) && fold
)
525 // decide what is the current state to print (depending of the script tag)
526 StateToPrint
= statePrintForState(state
, inScriptType
);
528 // handle script folding
530 switch (scriptLanguage
) {
533 //not currently supported case eScriptVBS:
535 if ((state
!= SCE_HPHP_COMMENT
) && (state
!= SCE_HPHP_COMMENTLINE
) && (state
!= SCE_HJ_COMMENT
) && (state
!= SCE_HJ_COMMENTLINE
) && (state
!= SCE_HJ_COMMENTDOC
) && (!isStringState(state
))) {
536 //Platform::DebugPrintf("state=%d, StateToPrint=%d, initStyle=%d\n", state, StateToPrint, initStyle);
537 //if ((state == SCE_HPHP_OPERATOR) || (state == SCE_HPHP_DEFAULT) || (state == SCE_HJ_SYMBOLS) || (state == SCE_HJ_START) || (state == SCE_HJ_DEFAULT)) {
538 if ((ch
== '{') || (ch
== '}')) {
539 levelCurrent
+= (ch
== '{') ? 1 : -1;
544 if (state
!= SCE_HP_COMMENTLINE
) {
545 if ((ch
== ':') && ((chNext
== '\n') || (chNext
== '\r' && chNext2
== '\n'))) {
547 } else if ((ch
== '\n') && !((chNext
== '\r') && (chNext2
== '\n')) && (chNext
!= '\n')) {
548 // check if the number of tabs is lower than the level
549 int Findlevel
= (levelCurrent
& ~SC_FOLDLEVELBASE
) * 8;
550 for (int j
= 0; Findlevel
> 0; j
++) {
551 char chTmp
= styler
.SafeGetCharAt(i
+ j
+ 1);
554 } else if (chTmp
== ' ') {
562 levelCurrent
-= Findlevel
/ 8;
574 if ((ch
== '\r' && chNext
!= '\n') || (ch
== '\n')) {
575 // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
576 // Avoid triggering two times on Dos/Win
577 // New line -> record any line state onto /next/ line
580 if (visibleChars
== 0)
581 lev
|= SC_FOLDLEVELWHITEFLAG
;
582 if ((levelCurrent
> levelPrev
) && (visibleChars
> 0))
583 lev
|= SC_FOLDLEVELHEADERFLAG
;
585 styler
.SetLevel(lineCurrent
, lev
);
587 levelPrev
= levelCurrent
;
590 styler
.SetLineState(lineCurrent
,
591 ((inScriptType
& 0x03) << 0) |
592 ((tagOpened
& 0x01) << 2) |
593 ((tagClosing
& 0x01) << 3) |
594 ((aspScript
& 0x0F) << 4) |
595 ((clientScript
& 0x0F) << 8) |
596 ((beforePreProc
& 0xFF) << 12));
599 // generic end of script processing
600 else if ((inScriptType
== eNonHtmlScript
) && (ch
== '<') && (chNext
== '/')) {
601 // Check if it's the end of the script tag (or any other HTML tag)
603 // in these cases, you can embed HTML tags (to confirm !!!!!!!!!!!!!!!!!!!!!!)
604 case SCE_H_DOUBLESTRING
:
605 case SCE_H_SINGLESTRING
:
607 case SCE_HJ_COMMENTDOC
:
608 // SCE_HJ_COMMENTLINE removed as this is a common thing done to hide
609 // the end of script marker from some JS interpreters.
610 //case SCE_HJ_COMMENTLINE:
611 case SCE_HJ_DOUBLESTRING
:
612 case SCE_HJ_SINGLESTRING
:
617 case SCE_HP_TRIPLEDOUBLE
:
620 // closing tag of the script (it's a closing HTML tag anyway)
621 styler
.ColourTo(i
- 1, StateToPrint
);
622 state
= SCE_H_TAGUNKNOWN
;
623 inScriptType
= eHtml
;
624 scriptLanguage
= eScriptNone
;
625 clientScript
= eScriptJS
;
633 /////////////////////////////////////
634 // handle the start of PHP pre-processor = Non-HTML
635 else if ((state
!= SCE_H_ASPAT
) &&
636 !isPHPStringState(state
) &&
637 (state
!= SCE_HPHP_COMMENT
) &&
640 styler
.ColourTo(i
- 1, StateToPrint
);
641 beforePreProc
= state
;
642 scriptLanguage
= segIsScriptingIndicator(styler
, styler
.GetStartSegment() + 2, i
+ 10, eScriptPHP
);
645 i
+= PrintScriptingIndicatorOffset(styler
, styler
.GetStartSegment() + 2, i
+ 10);
646 if (scriptLanguage
== eScriptXML
)
647 styler
.ColourTo(i
, SCE_H_XMLSTART
);
649 styler
.ColourTo(i
, SCE_H_QUESTION
);
650 state
= StateForScript(scriptLanguage
);
651 if (inScriptType
== eNonHtmlScript
)
652 inScriptType
= eNonHtmlScriptPreProc
;
654 inScriptType
= eNonHtmlPreProc
;
656 if (foldHTMLPreprocessor
){
658 if (scriptLanguage
== eScriptXML
)
659 levelCurrent
--; // no folding of the XML first tag (all XML-like tags in this case)
662 ch
= styler
.SafeGetCharAt(i
);
666 // handle the start of ASP pre-processor = Non-HTML
667 else if (!isCommentASPState(state
) && (ch
== '<') && (chNext
== '%')) {
668 styler
.ColourTo(i
- 1, StateToPrint
);
669 beforePreProc
= state
;
670 if (inScriptType
== eNonHtmlScript
)
671 inScriptType
= eNonHtmlScriptPreProc
;
673 inScriptType
= eNonHtmlPreProc
;
675 if (chNext2
== '@') {
676 i
+= 2; // place as if it was the second next char treated
679 } else if ((chNext2
== '-') && (styler
.SafeGetCharAt(i
+ 3) == '-')) {
680 styler
.ColourTo(i
+ 3, SCE_H_ASP
);
681 state
= SCE_H_XCCOMMENT
;
682 scriptLanguage
= eScriptVBS
;
685 if (chNext2
== '=') {
686 i
+= 2; // place as if it was the second next char treated
689 i
++; // place as if it was the next char treated
693 state
= StateForScript(aspScript
);
695 scriptLanguage
= eScriptVBS
;
696 styler
.ColourTo(i
, SCE_H_ASP
);
698 if (foldHTMLPreprocessor
)
701 ch
= styler
.SafeGetCharAt(i
);
705 /////////////////////////////////////
706 // handle the start of SGML language (DTD)
707 else if (((scriptLanguage
== eScriptNone
) || (scriptLanguage
== eScriptXML
)) &&
710 (StateToPrint
!= SCE_H_CDATA
) && (!IsCommentState(StateToPrint
))) {
711 beforePreProc
= state
;
712 styler
.ColourTo(i
- 2, StateToPrint
);
713 if ((chNext
== '-') && (chNext2
== '-')) {
714 state
= SCE_H_COMMENT
; // wait for a pending command
716 else if (isWordCdata(i
+ 1, i
+ 7, styler
)) {
719 styler
.ColourTo(i
, SCE_H_SGML_DEFAULT
); // <! is default
720 scriptLanguage
= eScriptSGML
;
721 state
= SCE_H_SGML_COMMAND
; // wait for a pending command
723 // fold whole tag (-- when closing the tag)
724 if (foldHTMLPreprocessor
)
729 // handle the end of a pre-processor = Non-HTML
731 ((inScriptType
== eNonHtmlPreProc
)
732 || (inScriptType
== eNonHtmlScriptPreProc
)) && (
733 ((scriptLanguage
== eScriptPHP
) && (ch
== '?') && !isPHPStringState(state
) && (state
!= SCE_HPHP_COMMENT
)) ||
734 ((scriptLanguage
!= eScriptNone
) && !isStringState(state
) &&
736 ) && (chNext
== '>')) ||
737 ((scriptLanguage
== eScriptSGML
) && (ch
== '>') && (state
!= SCE_H_SGML_COMMENT
))) {
738 if (state
== SCE_H_ASPAT
) {
739 aspScript
= segIsScriptingIndicator(styler
,
740 styler
.GetStartSegment(), i
- 1, aspScript
);
742 // Bounce out of any ASP mode
745 classifyWordHTJS(styler
.GetStartSegment(), i
- 1, keywords2
, styler
, inScriptType
);
748 classifyWordHTVB(styler
.GetStartSegment(), i
- 1, keywords3
, styler
, inScriptType
);
751 classifyWordHTPy(styler
.GetStartSegment(), i
- 1, keywords4
, styler
, prevWord
, inScriptType
);
754 classifyWordHTPHP(styler
.GetStartSegment(), i
- 1, keywords5
, styler
);
756 case SCE_H_XCCOMMENT
:
757 styler
.ColourTo(i
- 1, state
);
760 styler
.ColourTo(i
- 1, StateToPrint
);
763 if (scriptLanguage
!= eScriptSGML
) {
768 styler
.ColourTo(i
, SCE_H_ASP
);
769 else if (scriptLanguage
== eScriptXML
)
770 styler
.ColourTo(i
, SCE_H_XMLEND
);
771 else if (scriptLanguage
== eScriptSGML
)
772 styler
.ColourTo(i
, SCE_H_SGML_DEFAULT
);
774 styler
.ColourTo(i
, SCE_H_QUESTION
);
775 state
= beforePreProc
;
776 if (inScriptType
== eNonHtmlScriptPreProc
)
777 inScriptType
= eNonHtmlScript
;
779 inScriptType
= eHtml
;
780 scriptLanguage
= eScriptNone
;
781 // unfold all scripting languages
782 if (foldHTMLPreprocessor
)
786 /////////////////////////////////////
791 // in HTML, fold on tag open and unfold on tag close
793 tagClosing
= (chNext
== '/');
794 styler
.ColourTo(i
- 1, StateToPrint
);
796 state
= SCE_H_TAGUNKNOWN
;
797 } else if (ch
== '&') {
798 styler
.ColourTo(i
- 1, SCE_H_DEFAULT
);
799 state
= SCE_H_ENTITY
;
802 case SCE_H_SGML_DEFAULT
:
803 case SCE_H_SGML_BLOCK_DEFAULT
:
804 // if (scriptLanguage == eScriptSGMLblock)
805 // StateToPrint = SCE_H_SGML_BLOCK_DEFAULT;
808 styler
.ColourTo(i
- 1, StateToPrint
);
809 state
= SCE_H_SGML_DOUBLESTRING
;
810 } else if (ch
== '\'') {
811 styler
.ColourTo(i
- 1, StateToPrint
);
812 state
= SCE_H_SGML_SIMPLESTRING
;
813 } else if ((ch
== '-') && (chPrev
== '-')) {
814 styler
.ColourTo(i
- 2, StateToPrint
);
815 state
= SCE_H_SGML_COMMENT
;
816 } else if (isascii(ch
) && isalpha(ch
) && (chPrev
== '%')) {
817 styler
.ColourTo(i
- 2, StateToPrint
);
818 state
= SCE_H_SGML_ENTITY
;
819 } else if (ch
== '#') {
820 styler
.ColourTo(i
- 1, StateToPrint
);
821 state
= SCE_H_SGML_SPECIAL
;
822 } else if (ch
== '[') {
823 styler
.ColourTo(i
- 1, StateToPrint
);
824 scriptLanguage
= eScriptSGMLblock
;
825 state
= SCE_H_SGML_BLOCK_DEFAULT
;
826 } else if (ch
== ']') {
827 if (scriptLanguage
== eScriptSGMLblock
) {
828 styler
.ColourTo(i
, StateToPrint
);
829 scriptLanguage
= eScriptSGML
;
831 styler
.ColourTo(i
- 1, StateToPrint
);
832 styler
.ColourTo(i
, SCE_H_SGML_ERROR
);
834 state
= SCE_H_SGML_DEFAULT
;
835 } else if (scriptLanguage
== eScriptSGMLblock
) {
836 if ((ch
== '!') && (chPrev
== '<')) {
837 styler
.ColourTo(i
- 2, StateToPrint
);
838 styler
.ColourTo(i
, SCE_H_SGML_DEFAULT
);
839 state
= SCE_H_SGML_COMMAND
;
840 } else if (ch
== '>') {
841 styler
.ColourTo(i
- 1, StateToPrint
);
842 styler
.ColourTo(i
, SCE_H_SGML_DEFAULT
);
846 case SCE_H_SGML_COMMAND
:
847 if ((ch
== '-') && (chPrev
== '-')) {
848 styler
.ColourTo(i
- 2, StateToPrint
);
849 state
= SCE_H_SGML_COMMENT
;
850 } else if (!issgmlwordchar(ch
)) {
851 if (isWordHSGML(styler
.GetStartSegment(), i
- 1, keywords6
, styler
)) {
852 styler
.ColourTo(i
- 1, StateToPrint
);
853 state
= SCE_H_SGML_1ST_PARAM
;
855 state
= SCE_H_SGML_ERROR
;
859 case SCE_H_SGML_1ST_PARAM
:
860 // wait for the beginning of the word
861 if ((ch
== '-') && (chPrev
== '-')) {
862 if (scriptLanguage
== eScriptSGMLblock
) {
863 styler
.ColourTo(i
- 2, SCE_H_SGML_BLOCK_DEFAULT
);
865 styler
.ColourTo(i
- 2, SCE_H_SGML_DEFAULT
);
867 state
= SCE_H_SGML_1ST_PARAM_COMMENT
;
868 } else if (issgmlwordchar(ch
)) {
869 if (scriptLanguage
== eScriptSGMLblock
) {
870 styler
.ColourTo(i
- 1, SCE_H_SGML_BLOCK_DEFAULT
);
872 styler
.ColourTo(i
- 1, SCE_H_SGML_DEFAULT
);
874 // find the length of the word
876 while (ishtmlwordchar(styler
.SafeGetCharAt(i
+ size
)))
878 styler
.ColourTo(i
+ size
- 1, StateToPrint
);
880 visibleChars
+= size
- 1;
881 ch
= styler
.SafeGetCharAt(i
);
882 if (scriptLanguage
== eScriptSGMLblock
) {
883 state
= SCE_H_SGML_BLOCK_DEFAULT
;
885 state
= SCE_H_SGML_DEFAULT
;
890 case SCE_H_SGML_ERROR
:
891 if ((ch
== '-') && (chPrev
== '-')) {
892 styler
.ColourTo(i
- 2, StateToPrint
);
893 state
= SCE_H_SGML_COMMENT
;
895 case SCE_H_SGML_DOUBLESTRING
:
897 styler
.ColourTo(i
, StateToPrint
);
898 state
= SCE_H_SGML_DEFAULT
;
901 case SCE_H_SGML_SIMPLESTRING
:
903 styler
.ColourTo(i
, StateToPrint
);
904 state
= SCE_H_SGML_DEFAULT
;
907 case SCE_H_SGML_COMMENT
:
908 if ((ch
== '-') && (chPrev
== '-')) {
909 styler
.ColourTo(i
, StateToPrint
);
910 state
= SCE_H_SGML_DEFAULT
;
914 if ((chPrev2
== ']') && (chPrev
== ']') && (ch
== '>')) {
915 styler
.ColourTo(i
, StateToPrint
);
916 state
= SCE_H_DEFAULT
;
921 if ((chPrev2
== '-') && (chPrev
== '-') && (ch
== '>')) {
922 styler
.ColourTo(i
, StateToPrint
);
923 state
= SCE_H_DEFAULT
;
927 case SCE_H_SGML_1ST_PARAM_COMMENT
:
928 if ((ch
== '-') && (chPrev
== '-')) {
929 styler
.ColourTo(i
, SCE_H_SGML_COMMENT
);
930 state
= SCE_H_SGML_1ST_PARAM
;
933 case SCE_H_SGML_SPECIAL
:
934 if (!(isascii(ch
) && isupper(ch
))) {
935 styler
.ColourTo(i
- 1, StateToPrint
);
937 state
= SCE_H_SGML_ERROR
;
939 state
= SCE_H_SGML_DEFAULT
;
943 case SCE_H_SGML_ENTITY
:
945 styler
.ColourTo(i
, StateToPrint
);
946 state
= SCE_H_SGML_DEFAULT
;
947 } else if (!(isascii(ch
) && isalnum(ch
)) && ch
!= '-' && ch
!= '.') {
948 styler
.ColourTo(i
, SCE_H_SGML_ERROR
);
949 state
= SCE_H_SGML_DEFAULT
;
954 styler
.ColourTo(i
, StateToPrint
);
955 state
= SCE_H_DEFAULT
;
957 if (ch
!= '#' && !(isascii(ch
) && isalnum(ch
)) // Should check that '#' follows '&', but it is unlikely anyway...
958 && ch
!= '.' && ch
!= '-' && ch
!= '_' && ch
!= ':') { // valid in XML
959 styler
.ColourTo(i
, SCE_H_TAGUNKNOWN
);
960 state
= SCE_H_DEFAULT
;
963 case SCE_H_TAGUNKNOWN
:
964 if (!ishtmlwordchar(ch
) && !((ch
== '/') && (chPrev
== '<')) && ch
!= '[') {
965 int eClass
= classifyTagHTML(styler
.GetStartSegment(),
966 i
- 1, keywords
, styler
, tagDontFold
, caseSensitive
);
967 if (eClass
== SCE_H_SCRIPT
) {
969 inScriptType
= eNonHtmlScript
;
970 scriptLanguage
= clientScript
;
973 scriptLanguage
= eScriptNone
;
978 styler
.ColourTo(i
, eClass
);
979 if (inScriptType
== eNonHtmlScript
) {
980 state
= StateForScript(scriptLanguage
);
982 state
= SCE_H_DEFAULT
;
993 } else if (ch
== '/' && chNext
== '>') {
994 if (eClass
== SCE_H_TAGUNKNOWN
) {
995 styler
.ColourTo(i
+ 1, SCE_H_TAGUNKNOWN
);
997 styler
.ColourTo(i
- 1, StateToPrint
);
998 styler
.ColourTo(i
+ 1, SCE_H_TAGEND
);
1002 state
= SCE_H_DEFAULT
;
1005 if (eClass
!= SCE_H_TAGUNKNOWN
) {
1006 if (eClass
== SCE_H_SGML_DEFAULT
) {
1007 state
= SCE_H_SGML_DEFAULT
;
1009 state
= SCE_H_OTHER
;
1015 case SCE_H_ATTRIBUTE
:
1016 if (!ishtmlwordchar(ch
) && ch
!= '/' && ch
!= '-') {
1017 if (inScriptType
== eNonHtmlScript
) {
1018 int scriptLanguagePrev
= scriptLanguage
;
1019 clientScript
= segIsScriptingIndicator(styler
, styler
.GetStartSegment(), i
- 1, scriptLanguage
);
1020 scriptLanguage
= clientScript
;
1021 if ((scriptLanguagePrev
!= scriptLanguage
) && (scriptLanguage
== eScriptNone
))
1022 inScriptType
= eHtml
;
1024 classifyAttribHTML(styler
.GetStartSegment(), i
- 1, keywords
, styler
);
1026 styler
.ColourTo(i
, SCE_H_TAG
);
1027 if (inScriptType
== eNonHtmlScript
) {
1028 state
= StateForScript(scriptLanguage
);
1030 state
= SCE_H_DEFAULT
;
1041 } else if (ch
== '=') {
1042 styler
.ColourTo(i
, SCE_H_OTHER
);
1043 state
= SCE_H_VALUE
;
1045 state
= SCE_H_OTHER
;
1051 styler
.ColourTo(i
- 1, StateToPrint
);
1052 styler
.ColourTo(i
, SCE_H_TAG
);
1053 if (inScriptType
== eNonHtmlScript
) {
1054 state
= StateForScript(scriptLanguage
);
1056 state
= SCE_H_DEFAULT
;
1067 } else if (ch
== '\"') {
1068 styler
.ColourTo(i
- 1, StateToPrint
);
1069 state
= SCE_H_DOUBLESTRING
;
1070 } else if (ch
== '\'') {
1071 styler
.ColourTo(i
- 1, StateToPrint
);
1072 state
= SCE_H_SINGLESTRING
;
1073 } else if (ch
== '=') {
1074 styler
.ColourTo(i
, StateToPrint
);
1075 state
= SCE_H_VALUE
;
1076 } else if (ch
== '/' && chNext
== '>') {
1077 styler
.ColourTo(i
- 1, StateToPrint
);
1078 styler
.ColourTo(i
+ 1, SCE_H_TAGEND
);
1081 state
= SCE_H_DEFAULT
;
1083 } else if (ch
== '?' && chNext
== '>') {
1084 styler
.ColourTo(i
- 1, StateToPrint
);
1085 styler
.ColourTo(i
+ 1, SCE_H_XMLEND
);
1088 state
= SCE_H_DEFAULT
;
1089 } else if (ishtmlwordchar(ch
)) {
1090 styler
.ColourTo(i
- 1, StateToPrint
);
1091 state
= SCE_H_ATTRIBUTE
;
1094 case SCE_H_DOUBLESTRING
:
1096 if (inScriptType
== eNonHtmlScript
) {
1097 scriptLanguage
= segIsScriptingIndicator(styler
, styler
.GetStartSegment(), i
, scriptLanguage
);
1099 styler
.ColourTo(i
, SCE_H_DOUBLESTRING
);
1100 state
= SCE_H_OTHER
;
1103 case SCE_H_SINGLESTRING
:
1105 if (inScriptType
== eNonHtmlScript
) {
1106 scriptLanguage
= segIsScriptingIndicator(styler
, styler
.GetStartSegment(), i
, scriptLanguage
);
1108 styler
.ColourTo(i
, SCE_H_SINGLESTRING
);
1109 state
= SCE_H_OTHER
;
1113 if (!ishtmlwordchar(ch
)) {
1114 if (ch
== '\"' && chPrev
== '=') {
1115 // Should really test for being first character
1116 state
= SCE_H_DOUBLESTRING
;
1117 } else if (ch
== '\'' && chPrev
== '=') {
1118 state
= SCE_H_SINGLESTRING
;
1120 if (IsNumber(styler
.GetStartSegment(), styler
)) {
1121 styler
.ColourTo(i
- 1, SCE_H_NUMBER
);
1123 styler
.ColourTo(i
- 1, StateToPrint
);
1126 styler
.ColourTo(i
, SCE_H_TAG
);
1127 if (inScriptType
== eNonHtmlScript
) {
1128 state
= StateForScript(scriptLanguage
);
1130 state
= SCE_H_DEFAULT
;
1142 state
= SCE_H_OTHER
;
1147 case SCE_HJ_DEFAULT
:
1149 case SCE_HJ_SYMBOLS
:
1150 if (iswordstart(ch
)) {
1151 styler
.ColourTo(i
- 1, StateToPrint
);
1152 state
= SCE_HJ_WORD
;
1153 } else if (ch
== '/' && chNext
== '*') {
1154 styler
.ColourTo(i
- 1, StateToPrint
);
1156 state
= SCE_HJ_COMMENTDOC
;
1158 state
= SCE_HJ_COMMENT
;
1159 } else if (ch
== '/' && chNext
== '/') {
1160 styler
.ColourTo(i
- 1, StateToPrint
);
1161 state
= SCE_HJ_COMMENTLINE
;
1162 } else if (ch
== '/' && isOKBeforeRE(chPrevNonWhite
)) {
1163 styler
.ColourTo(i
- 1, StateToPrint
);
1164 state
= SCE_HJ_REGEX
;
1165 } else if (ch
== '\"') {
1166 styler
.ColourTo(i
- 1, StateToPrint
);
1167 state
= SCE_HJ_DOUBLESTRING
;
1168 } else if (ch
== '\'') {
1169 styler
.ColourTo(i
- 1, StateToPrint
);
1170 state
= SCE_HJ_SINGLESTRING
;
1171 } else if ((ch
== '<') && (chNext
== '!') && (chNext2
== '-') &&
1172 styler
.SafeGetCharAt(i
+ 3) == '-') {
1173 styler
.ColourTo(i
- 1, StateToPrint
);
1174 state
= SCE_HJ_COMMENTLINE
;
1175 } else if ((ch
== '-') && (chNext
== '-') && (chNext2
== '>')) {
1176 styler
.ColourTo(i
- 1, StateToPrint
);
1177 state
= SCE_HJ_COMMENTLINE
;
1179 } else if (isoperator(ch
)) {
1180 styler
.ColourTo(i
- 1, StateToPrint
);
1181 styler
.ColourTo(i
, statePrintForState(SCE_HJ_SYMBOLS
, inScriptType
));
1182 state
= SCE_HJ_DEFAULT
;
1183 } else if ((ch
== ' ') || (ch
== '\t')) {
1184 if (state
== SCE_HJ_START
) {
1185 styler
.ColourTo(i
- 1, StateToPrint
);
1186 state
= SCE_HJ_DEFAULT
;
1191 if (!iswordchar(ch
)) {
1192 classifyWordHTJS(styler
.GetStartSegment(), i
- 1, keywords2
, styler
, inScriptType
);
1193 //styler.ColourTo(i - 1, eHTJSKeyword);
1194 state
= SCE_HJ_DEFAULT
;
1195 if (ch
== '/' && chNext
== '*') {
1197 state
= SCE_HJ_COMMENTDOC
;
1199 state
= SCE_HJ_COMMENT
;
1200 } else if (ch
== '/' && chNext
== '/') {
1201 state
= SCE_HJ_COMMENTLINE
;
1202 } else if (ch
== '\"') {
1203 state
= SCE_HJ_DOUBLESTRING
;
1204 } else if (ch
== '\'') {
1205 state
= SCE_HJ_SINGLESTRING
;
1206 } else if ((ch
== '-') && (chNext
== '-') && (chNext2
== '>')) {
1207 styler
.ColourTo(i
- 1, StateToPrint
);
1208 state
= SCE_HJ_COMMENTLINE
;
1210 } else if (isoperator(ch
)) {
1211 styler
.ColourTo(i
, statePrintForState(SCE_HJ_SYMBOLS
, inScriptType
));
1212 state
= SCE_HJ_DEFAULT
;
1216 case SCE_HJ_COMMENT
:
1217 case SCE_HJ_COMMENTDOC
:
1218 if (ch
== '/' && chPrev
== '*') {
1219 styler
.ColourTo(i
, StateToPrint
);
1220 state
= SCE_HJ_DEFAULT
;
1223 case SCE_HJ_COMMENTLINE
:
1224 if (ch
== '\r' || ch
== '\n') {
1225 styler
.ColourTo(i
- 1, statePrintForState(SCE_HJ_COMMENTLINE
, inScriptType
));
1226 state
= SCE_HJ_DEFAULT
;
1229 case SCE_HJ_DOUBLESTRING
:
1231 if (chNext
== '\"' || chNext
== '\'' || chNext
== '\\') {
1234 } else if (ch
== '\"') {
1235 styler
.ColourTo(i
, statePrintForState(SCE_HJ_DOUBLESTRING
, inScriptType
));
1236 state
= SCE_HJ_DEFAULT
;
1237 } else if ((inScriptType
== eNonHtmlScript
) && (ch
== '-') && (chNext
== '-') && (chNext2
== '>')) {
1238 styler
.ColourTo(i
- 1, StateToPrint
);
1239 state
= SCE_HJ_COMMENTLINE
;
1241 } else if (isLineEnd(ch
)) {
1242 styler
.ColourTo(i
- 1, StateToPrint
);
1243 state
= SCE_HJ_STRINGEOL
;
1246 case SCE_HJ_SINGLESTRING
:
1248 if (chNext
== '\"' || chNext
== '\'' || chNext
== '\\') {
1251 } else if (ch
== '\'') {
1252 styler
.ColourTo(i
, statePrintForState(SCE_HJ_SINGLESTRING
, inScriptType
));
1253 state
= SCE_HJ_DEFAULT
;
1254 } else if ((inScriptType
== eNonHtmlScript
) && (ch
== '-') && (chNext
== '-') && (chNext2
== '>')) {
1255 styler
.ColourTo(i
- 1, StateToPrint
);
1256 state
= SCE_HJ_COMMENTLINE
;
1258 } else if (isLineEnd(ch
)) {
1259 styler
.ColourTo(i
- 1, StateToPrint
);
1260 state
= SCE_HJ_STRINGEOL
;
1263 case SCE_HJ_STRINGEOL
:
1264 if (!isLineEnd(ch
)) {
1265 styler
.ColourTo(i
- 1, StateToPrint
);
1266 state
= SCE_HJ_DEFAULT
;
1267 } else if (!isLineEnd(chNext
)) {
1268 styler
.ColourTo(i
, StateToPrint
);
1269 state
= SCE_HJ_DEFAULT
;
1273 if (ch
== '\r' || ch
== '\n' || ch
== '/') {
1274 styler
.ColourTo(i
, StateToPrint
);
1275 state
= SCE_HJ_DEFAULT
;
1276 } else if (ch
== '\\') {
1277 // Gobble up the quoted character
1278 if (chNext
== '\\' || chNext
== '/') {
1281 chNext
= styler
.SafeGetCharAt(i
+ 1);
1285 case SCE_HB_DEFAULT
:
1287 if (iswordstart(ch
)) {
1288 styler
.ColourTo(i
- 1, StateToPrint
);
1289 state
= SCE_HB_WORD
;
1290 } else if (ch
== '\'') {
1291 styler
.ColourTo(i
- 1, StateToPrint
);
1292 state
= SCE_HB_COMMENTLINE
;
1293 } else if (ch
== '\"') {
1294 styler
.ColourTo(i
- 1, StateToPrint
);
1295 state
= SCE_HB_STRING
;
1296 } else if ((ch
== '<') && (chNext
== '!') && (chNext2
== '-') &&
1297 styler
.SafeGetCharAt(i
+ 3) == '-') {
1298 styler
.ColourTo(i
- 1, StateToPrint
);
1299 state
= SCE_HB_COMMENTLINE
;
1300 } else if (isoperator(ch
)) {
1301 styler
.ColourTo(i
- 1, StateToPrint
);
1302 styler
.ColourTo(i
, statePrintForState(SCE_HB_DEFAULT
, inScriptType
));
1303 state
= SCE_HB_DEFAULT
;
1304 } else if ((ch
== ' ') || (ch
== '\t')) {
1305 if (state
== SCE_HB_START
) {
1306 styler
.ColourTo(i
- 1, StateToPrint
);
1307 state
= SCE_HB_DEFAULT
;
1312 if (!iswordchar(ch
)) {
1313 state
= classifyWordHTVB(styler
.GetStartSegment(), i
- 1, keywords3
, styler
, inScriptType
);
1314 if (state
== SCE_HB_DEFAULT
) {
1316 state
= SCE_HB_STRING
;
1317 } else if (ch
== '\'') {
1318 state
= SCE_HB_COMMENTLINE
;
1319 } else if (isoperator(ch
)) {
1320 styler
.ColourTo(i
, statePrintForState(SCE_HB_DEFAULT
, inScriptType
));
1321 state
= SCE_HB_DEFAULT
;
1328 styler
.ColourTo(i
, StateToPrint
);
1329 state
= SCE_HB_DEFAULT
;
1330 } else if (ch
== '\r' || ch
== '\n') {
1331 styler
.ColourTo(i
- 1, StateToPrint
);
1332 state
= SCE_HB_STRINGEOL
;
1335 case SCE_HB_COMMENTLINE
:
1336 if (ch
== '\r' || ch
== '\n') {
1337 styler
.ColourTo(i
- 1, StateToPrint
);
1338 state
= SCE_HB_DEFAULT
;
1341 case SCE_HB_STRINGEOL
:
1342 if (!isLineEnd(ch
)) {
1343 styler
.ColourTo(i
- 1, StateToPrint
);
1344 state
= SCE_HB_DEFAULT
;
1345 } else if (!isLineEnd(chNext
)) {
1346 styler
.ColourTo(i
, StateToPrint
);
1347 state
= SCE_HB_DEFAULT
;
1350 case SCE_HP_DEFAULT
:
1352 if (iswordstart(ch
)) {
1353 styler
.ColourTo(i
- 1, StateToPrint
);
1354 state
= SCE_HP_WORD
;
1355 } else if ((ch
== '<') && (chNext
== '!') && (chNext2
== '-') &&
1356 styler
.SafeGetCharAt(i
+ 3) == '-') {
1357 styler
.ColourTo(i
- 1, StateToPrint
);
1358 state
= SCE_HP_COMMENTLINE
;
1359 } else if (ch
== '#') {
1360 styler
.ColourTo(i
- 1, StateToPrint
);
1361 state
= SCE_HP_COMMENTLINE
;
1362 } else if (ch
== '\"') {
1363 styler
.ColourTo(i
- 1, StateToPrint
);
1364 if (chNext
== '\"' && chNext2
== '\"') {
1366 state
= SCE_HP_TRIPLEDOUBLE
;
1369 chNext
= styler
.SafeGetCharAt(i
+ 1);
1371 // state = statePrintForState(SCE_HP_STRING,inScriptType);
1372 state
= SCE_HP_STRING
;
1374 } else if (ch
== '\'') {
1375 styler
.ColourTo(i
- 1, StateToPrint
);
1376 if (chNext
== '\'' && chNext2
== '\'') {
1378 state
= SCE_HP_TRIPLE
;
1381 chNext
= styler
.SafeGetCharAt(i
+ 1);
1383 state
= SCE_HP_CHARACTER
;
1385 } else if (isoperator(ch
)) {
1386 styler
.ColourTo(i
- 1, StateToPrint
);
1387 styler
.ColourTo(i
, statePrintForState(SCE_HP_OPERATOR
, inScriptType
));
1388 } else if ((ch
== ' ') || (ch
== '\t')) {
1389 if (state
== SCE_HP_START
) {
1390 styler
.ColourTo(i
- 1, StateToPrint
);
1391 state
= SCE_HP_DEFAULT
;
1396 if (!iswordchar(ch
)) {
1397 classifyWordHTPy(styler
.GetStartSegment(), i
- 1, keywords4
, styler
, prevWord
, inScriptType
);
1398 state
= SCE_HP_DEFAULT
;
1400 state
= SCE_HP_COMMENTLINE
;
1401 } else if (ch
== '\"') {
1402 if (chNext
== '\"' && chNext2
== '\"') {
1404 state
= SCE_HP_TRIPLEDOUBLE
;
1407 chNext
= styler
.SafeGetCharAt(i
+ 1);
1409 state
= SCE_HP_STRING
;
1411 } else if (ch
== '\'') {
1412 if (chNext
== '\'' && chNext2
== '\'') {
1414 state
= SCE_HP_TRIPLE
;
1417 chNext
= styler
.SafeGetCharAt(i
+ 1);
1419 state
= SCE_HP_CHARACTER
;
1421 } else if (isoperator(ch
)) {
1422 styler
.ColourTo(i
, statePrintForState(SCE_HP_OPERATOR
, inScriptType
));
1426 case SCE_HP_COMMENTLINE
:
1427 if (ch
== '\r' || ch
== '\n') {
1428 styler
.ColourTo(i
- 1, StateToPrint
);
1429 state
= SCE_HP_DEFAULT
;
1434 if (chNext
== '\"' || chNext
== '\'' || chNext
== '\\') {
1437 chNext
= styler
.SafeGetCharAt(i
+ 1);
1439 } else if (ch
== '\"') {
1440 styler
.ColourTo(i
, StateToPrint
);
1441 state
= SCE_HP_DEFAULT
;
1444 case SCE_HP_CHARACTER
:
1446 if (chNext
== '\"' || chNext
== '\'' || chNext
== '\\') {
1449 chNext
= styler
.SafeGetCharAt(i
+ 1);
1451 } else if (ch
== '\'') {
1452 styler
.ColourTo(i
, StateToPrint
);
1453 state
= SCE_HP_DEFAULT
;
1457 if (ch
== '\'' && chPrev
== '\'' && chPrev2
== '\'') {
1458 styler
.ColourTo(i
, StateToPrint
);
1459 state
= SCE_HP_DEFAULT
;
1462 case SCE_HP_TRIPLEDOUBLE
:
1463 if (ch
== '\"' && chPrev
== '\"' && chPrev2
== '\"') {
1464 styler
.ColourTo(i
, StateToPrint
);
1465 state
= SCE_HP_DEFAULT
;
1468 ///////////// start - PHP state handling
1470 if (!iswordchar(ch
)) {
1471 classifyWordHTPHP(styler
.GetStartSegment(), i
- 1, keywords5
, styler
);
1472 if (ch
== '/' && chNext
== '*') {
1474 state
= SCE_HPHP_COMMENT
;
1475 } else if (ch
== '/' && chNext
== '/') {
1477 state
= SCE_HPHP_COMMENTLINE
;
1478 } else if (ch
== '#') {
1479 state
= SCE_HPHP_COMMENTLINE
;
1480 } else if (ch
== '\"') {
1481 state
= SCE_HPHP_HSTRING
;
1482 strcpy(phpStringDelimiter
, "\"");
1483 } else if (styler
.Match(i
, "<<<")) {
1484 state
= SCE_HPHP_HSTRING
;
1485 i
= FindPhpStringDelimiter(phpStringDelimiter
, sizeof(phpStringDelimiter
), i
+ 3, lengthDoc
, styler
);
1486 } else if (ch
== '\'') {
1487 state
= SCE_HPHP_SIMPLESTRING
;
1488 } else if (ch
== '$' && IsPhpWordStart(chNext
)) {
1489 state
= SCE_HPHP_VARIABLE
;
1490 } else if (isoperator(ch
)) {
1491 state
= SCE_HPHP_OPERATOR
;
1493 state
= SCE_HPHP_DEFAULT
;
1497 case SCE_HPHP_NUMBER
:
1498 if (!IsADigit(ch
)) {
1499 styler
.ColourTo(i
- 1, SCE_HPHP_NUMBER
);
1501 state
= SCE_HPHP_OPERATOR
;
1503 state
= SCE_HPHP_DEFAULT
;
1506 case SCE_HPHP_VARIABLE
:
1507 if (!IsPhpWordChar(ch
)) {
1508 styler
.ColourTo(i
- 1, SCE_HPHP_VARIABLE
);
1510 state
= SCE_HPHP_OPERATOR
;
1512 state
= SCE_HPHP_DEFAULT
;
1515 case SCE_HPHP_COMMENT
:
1516 if (ch
== '/' && chPrev
== '*') {
1517 styler
.ColourTo(i
, StateToPrint
);
1518 state
= SCE_HPHP_DEFAULT
;
1521 case SCE_HPHP_COMMENTLINE
:
1522 if (ch
== '\r' || ch
== '\n') {
1523 styler
.ColourTo(i
- 1, StateToPrint
);
1524 state
= SCE_HPHP_DEFAULT
;
1527 case SCE_HPHP_HSTRING
:
1528 if (ch
== '\\' && (phpStringDelimiter
[0] == '\"' || chNext
== '$' || chNext
== '{')) {
1529 // skip the next char
1531 } else if (((ch
== '{' && chNext
== '$') || (ch
== '$' && chNext
== '{'))
1532 && IsPhpWordStart(chNext2
)) {
1533 styler
.ColourTo(i
- 1, StateToPrint
);
1534 state
= SCE_HPHP_COMPLEX_VARIABLE
;
1535 } else if (ch
== '$' && IsPhpWordStart(chNext
)) {
1536 styler
.ColourTo(i
- 1, StateToPrint
);
1537 state
= SCE_HPHP_HSTRING_VARIABLE
;
1538 } else if (styler
.Match(i
, phpStringDelimiter
)) {
1539 if (strlen(phpStringDelimiter
) > 1)
1540 i
+= strlen(phpStringDelimiter
) - 1;
1541 styler
.ColourTo(i
, StateToPrint
);
1542 state
= SCE_HPHP_DEFAULT
;
1545 case SCE_HPHP_SIMPLESTRING
:
1547 // skip the next char
1549 } else if (ch
== '\'') {
1550 styler
.ColourTo(i
, StateToPrint
);
1551 state
= SCE_HPHP_DEFAULT
;
1554 case SCE_HPHP_HSTRING_VARIABLE
:
1555 if (!IsPhpWordChar(ch
)) {
1556 styler
.ColourTo(i
- 1, StateToPrint
);
1557 i
--; // strange but it works
1558 state
= SCE_HPHP_HSTRING
;
1561 case SCE_HPHP_COMPLEX_VARIABLE
:
1563 styler
.ColourTo(i
, StateToPrint
);
1564 state
= SCE_HPHP_HSTRING
;
1567 case SCE_HPHP_OPERATOR
:
1568 case SCE_HPHP_DEFAULT
:
1569 styler
.ColourTo(i
- 1, StateToPrint
);
1571 state
= SCE_HPHP_NUMBER
;
1572 } else if (iswordstart(ch
)) {
1573 state
= SCE_HPHP_WORD
;
1574 } else if (ch
== '/' && chNext
== '*') {
1576 state
= SCE_HPHP_COMMENT
;
1577 } else if (ch
== '/' && chNext
== '/') {
1579 state
= SCE_HPHP_COMMENTLINE
;
1580 } else if (ch
== '#') {
1581 state
= SCE_HPHP_COMMENTLINE
;
1582 } else if (ch
== '\"') {
1583 state
= SCE_HPHP_HSTRING
;
1584 strcpy(phpStringDelimiter
, "\"");
1585 } else if (styler
.Match(i
, "<<<")) {
1586 state
= SCE_HPHP_HSTRING
;
1587 i
= FindPhpStringDelimiter(phpStringDelimiter
, sizeof(phpStringDelimiter
), i
+ 3, lengthDoc
, styler
);
1588 } else if (ch
== '\'') {
1589 state
= SCE_HPHP_SIMPLESTRING
;
1590 } else if (ch
== '$' && IsPhpWordStart(chNext
)) {
1591 state
= SCE_HPHP_VARIABLE
;
1592 } else if (isoperator(ch
)) {
1593 state
= SCE_HPHP_OPERATOR
;
1594 } else if ((state
== SCE_HPHP_OPERATOR
) && (isspacechar(ch
))) {
1595 state
= SCE_HPHP_DEFAULT
;
1598 ///////////// end - PHP state handling
1601 // Some of the above terminated their lexeme but since the same character starts
1602 // the same class again, only reenter if non empty segment.
1604 bool nonEmptySegment
= i
>= static_cast<int>(styler
.GetStartSegment());
1605 if (state
== SCE_HB_DEFAULT
) { // One of the above succeeded
1606 if ((ch
== '\"') && (nonEmptySegment
)) {
1607 state
= SCE_HB_STRING
;
1608 } else if (ch
== '\'') {
1609 state
= SCE_HB_COMMENTLINE
;
1610 } else if (iswordstart(ch
)) {
1611 state
= SCE_HB_WORD
;
1612 } else if (isoperator(ch
)) {
1613 styler
.ColourTo(i
, SCE_HB_DEFAULT
);
1615 } else if (state
== SCE_HBA_DEFAULT
) { // One of the above succeeded
1616 if ((ch
== '\"') && (nonEmptySegment
)) {
1617 state
= SCE_HBA_STRING
;
1618 } else if (ch
== '\'') {
1619 state
= SCE_HBA_COMMENTLINE
;
1620 } else if (iswordstart(ch
)) {
1621 state
= SCE_HBA_WORD
;
1622 } else if (isoperator(ch
)) {
1623 styler
.ColourTo(i
, SCE_HBA_DEFAULT
);
1625 } else if (state
== SCE_HJ_DEFAULT
) { // One of the above succeeded
1626 if (ch
== '/' && chNext
== '*') {
1627 if (styler
.SafeGetCharAt(i
+ 2) == '*')
1628 state
= SCE_HJ_COMMENTDOC
;
1630 state
= SCE_HJ_COMMENT
;
1631 } else if (ch
== '/' && chNext
== '/') {
1632 state
= SCE_HJ_COMMENTLINE
;
1633 } else if ((ch
== '\"') && (nonEmptySegment
)) {
1634 state
= SCE_HJ_DOUBLESTRING
;
1635 } else if ((ch
== '\'') && (nonEmptySegment
)) {
1636 state
= SCE_HJ_SINGLESTRING
;
1637 } else if (iswordstart(ch
)) {
1638 state
= SCE_HJ_WORD
;
1639 } else if (isoperator(ch
)) {
1640 styler
.ColourTo(i
, statePrintForState(SCE_HJ_SYMBOLS
, inScriptType
));
1645 StateToPrint
= statePrintForState(state
, inScriptType
);
1646 styler
.ColourTo(lengthDoc
- 1, StateToPrint
);
1648 // Fill in the real level of the next line, keeping the current flags as they will be filled in later
1650 int flagsNext
= styler
.LevelAt(lineCurrent
) & ~SC_FOLDLEVELNUMBERMASK
;
1651 styler
.SetLevel(lineCurrent
, levelPrev
| flagsNext
);
1655 static bool isASPScript(int state
) {
1657 (state
>= SCE_HJA_START
&& state
<= SCE_HJA_REGEX
) ||
1658 (state
>= SCE_HBA_START
&& state
<= SCE_HBA_STRINGEOL
) ||
1659 (state
>= SCE_HPA_DEFAULT
&& state
<= SCE_HPA_IDENTIFIER
);
1662 static void ColouriseHBAPiece(StyleContext
&sc
, WordList
*keywordlists
[]) {
1663 WordList
&keywordsVBS
= *keywordlists
[2];
1664 if (sc
.state
== SCE_HBA_WORD
) {
1665 if (!IsAWordChar(sc
.ch
)) {
1667 sc
.GetCurrentLowered(s
, sizeof(s
));
1668 if (keywordsVBS
.InList(s
)) {
1669 if (strcmp(s
, "rem") == 0) {
1670 sc
.ChangeState(SCE_HBA_COMMENTLINE
);
1672 sc
.SetState(SCE_HBA_DEFAULT
);
1675 sc
.SetState(SCE_HBA_DEFAULT
);
1678 sc
.ChangeState(SCE_HBA_IDENTIFIER
);
1679 sc
.SetState(SCE_HBA_DEFAULT
);
1682 } else if (sc
.state
== SCE_HBA_NUMBER
) {
1683 if (!IsAWordChar(sc
.ch
)) {
1684 sc
.SetState(SCE_HBA_DEFAULT
);
1686 } else if (sc
.state
== SCE_HBA_STRING
) {
1687 if (sc
.ch
== '\"') {
1688 sc
.ForwardSetState(SCE_HBA_DEFAULT
);
1689 } else if (sc
.ch
== '\r' || sc
.ch
== '\n') {
1690 sc
.ChangeState(SCE_HBA_STRINGEOL
);
1691 sc
.ForwardSetState(SCE_HBA_DEFAULT
);
1693 } else if (sc
.state
== SCE_HBA_COMMENTLINE
) {
1694 if (sc
.ch
== '\r' || sc
.ch
== '\n') {
1695 sc
.SetState(SCE_HBA_DEFAULT
);
1699 if (sc
.state
== SCE_HBA_DEFAULT
) {
1700 if (IsADigit(sc
.ch
) || (sc
.ch
== '.' && IsADigit(sc
.chNext
))) {
1701 sc
.SetState(SCE_HBA_NUMBER
);
1702 } else if (IsAWordStart(sc
.ch
)) {
1703 sc
.SetState(SCE_HBA_WORD
);
1704 } else if (sc
.ch
== '\'') {
1705 sc
.SetState(SCE_HBA_COMMENTLINE
);
1706 } else if (sc
.ch
== '\"') {
1707 sc
.SetState(SCE_HBA_STRING
);
1712 static void ColouriseHTMLPiece(StyleContext
&sc
, WordList
*keywordlists
[]) {
1713 WordList
&keywordsTags
= *keywordlists
[0];
1714 if (sc
.state
== SCE_H_COMMENT
) {
1715 if (sc
.Match("-->")) {
1718 sc
.ForwardSetState(SCE_H_DEFAULT
);
1720 } else if (sc
.state
== SCE_H_ENTITY
) {
1722 sc
.ForwardSetState(SCE_H_DEFAULT
);
1723 } else if (sc
.ch
!= '#' && (sc
.ch
< 0x80) && !isalnum(sc
.ch
) // Should check that '#' follows '&', but it is unlikely anyway...
1724 && sc
.ch
!= '.' && sc
.ch
!= '-' && sc
.ch
!= '_' && sc
.ch
!= ':') { // valid in XML
1725 sc
.ChangeState(SCE_H_TAGUNKNOWN
);
1726 sc
.SetState(SCE_H_DEFAULT
);
1728 } else if (sc
.state
== SCE_H_TAGUNKNOWN
) {
1729 if (!ishtmlwordchar(static_cast<char>(sc
.ch
)) && !((sc
.ch
== '/') && (sc
.chPrev
== '<')) && sc
.ch
!= '[') {
1731 sc
.GetCurrentLowered(s
, sizeof(s
));
1733 if (keywordsTags
.InList(s
+ 2)) {
1734 sc
.ChangeState(SCE_H_TAG
);
1737 if (keywordsTags
.InList(s
+ 1)) {
1738 sc
.ChangeState(SCE_H_TAG
);
1742 sc
.ForwardSetState(SCE_H_DEFAULT
);
1743 } else if (sc
.Match('/', '>')) {
1744 sc
.SetState(SCE_H_TAGEND
);
1746 sc
.ForwardSetState(SCE_H_DEFAULT
);
1748 sc
.SetState(SCE_H_OTHER
);
1751 } else if (sc
.state
== SCE_H_ATTRIBUTE
) {
1752 if (!ishtmlwordchar(static_cast<char>(sc
.ch
))) {
1754 sc
.GetCurrentLowered(s
, sizeof(s
));
1755 if (!keywordsTags
.InList(s
)) {
1756 sc
.ChangeState(SCE_H_ATTRIBUTEUNKNOWN
);
1758 sc
.SetState(SCE_H_OTHER
);
1760 } else if (sc
.state
== SCE_H_OTHER
) {
1762 sc
.SetState(SCE_H_TAG
);
1763 sc
.ForwardSetState(SCE_H_DEFAULT
);
1764 } else if (sc
.Match('/', '>')) {
1765 sc
.SetState(SCE_H_TAG
);
1767 sc
.ForwardSetState(SCE_H_DEFAULT
);
1768 } else if (sc
.chPrev
== '=') {
1769 sc
.SetState(SCE_H_VALUE
);
1771 } else if (sc
.state
== SCE_H_DOUBLESTRING
) {
1772 if (sc
.ch
== '\"') {
1773 sc
.ForwardSetState(SCE_H_OTHER
);
1775 } else if (sc
.state
== SCE_H_SINGLESTRING
) {
1776 if (sc
.ch
== '\'') {
1777 sc
.ForwardSetState(SCE_H_OTHER
);
1779 } else if (sc
.state
== SCE_H_NUMBER
) {
1780 if (!IsADigit(sc
.ch
)) {
1781 sc
.SetState(SCE_H_OTHER
);
1785 if (sc
.state
== SCE_H_DEFAULT
) {
1787 if (sc
.Match("<!--"))
1788 sc
.SetState(SCE_H_COMMENT
);
1790 sc
.SetState(SCE_H_TAGUNKNOWN
);
1791 } else if (sc
.ch
== '&') {
1792 sc
.SetState(SCE_H_ENTITY
);
1794 } else if ((sc
.state
== SCE_H_OTHER
) || (sc
.state
== SCE_H_VALUE
)) {
1795 if (sc
.ch
== '\"' && sc
.chPrev
== '=') {
1796 sc
.SetState(SCE_H_DOUBLESTRING
);
1797 } else if (sc
.ch
== '\'' && sc
.chPrev
== '=') {
1798 sc
.SetState(SCE_H_SINGLESTRING
);
1799 } else if (IsADigit(sc
.ch
)) {
1800 sc
.SetState(SCE_H_NUMBER
);
1801 } else if (sc
.ch
== '>') {
1802 sc
.SetState(SCE_H_TAG
);
1803 sc
.ForwardSetState(SCE_H_DEFAULT
);
1804 } else if (ishtmlwordchar(static_cast<char>(sc
.ch
))) {
1805 sc
.SetState(SCE_H_ATTRIBUTE
);
1810 static void ColouriseASPPiece(StyleContext
&sc
, WordList
*keywordlists
[]) {
1811 // Possibly exit current state to either SCE_H_DEFAULT or SCE_HBA_DEFAULT
1812 if ((sc
.state
== SCE_H_ASPAT
|| isASPScript(sc
.state
)) && sc
.Match('%', '>')) {
1813 sc
.SetState(SCE_H_ASP
);
1815 sc
.ForwardSetState(SCE_H_DEFAULT
);
1818 // Handle some ASP script
1819 if (sc
.state
>= SCE_HBA_START
&& sc
.state
<= SCE_HBA_STRINGEOL
) {
1820 ColouriseHBAPiece(sc
, keywordlists
);
1821 } else if (sc
.state
>= SCE_H_DEFAULT
&& sc
.state
<= SCE_H_SGML_BLOCK_DEFAULT
) {
1822 ColouriseHTMLPiece(sc
, keywordlists
);
1825 // Enter new sc.state
1826 if ((sc
.state
== SCE_H_DEFAULT
) || (sc
.state
== SCE_H_TAGUNKNOWN
)) {
1827 if (sc
.Match('<', '%')) {
1828 if (sc
.state
== SCE_H_TAGUNKNOWN
)
1829 sc
.ChangeState(SCE_H_ASP
);
1831 sc
.SetState(SCE_H_ASP
);
1835 sc
.ForwardSetState(SCE_H_ASPAT
);
1840 sc
.SetState(SCE_HBA_DEFAULT
);
1846 static void ColouriseASPDoc(unsigned int startPos
, int length
, int initStyle
, WordList
*keywordlists
[],
1848 // Lexer for HTML requires more lexical states (7 bits worth) than most lexers
1849 StyleContext
sc(startPos
, length
, initStyle
, styler
, 0x7f);
1850 for (; sc
.More(); sc
.Forward()) {
1851 ColouriseASPPiece(sc
, keywordlists
);
1856 static void ColourisePHPPiece(StyleContext
&sc
, WordList
*keywordlists
[]) {
1857 // Possibly exit current state to either SCE_H_DEFAULT or SCE_HBA_DEFAULT
1858 if (sc
.state
>= SCE_HPHP_DEFAULT
&& sc
.state
<= SCE_HPHP_OPERATOR
) {
1859 if (!isPHPStringState(sc
.state
) &&
1860 (sc
.state
!= SCE_HPHP_COMMENT
) &&
1861 (sc
.Match('?', '>'))) {
1862 sc
.SetState(SCE_H_QUESTION
);
1864 sc
.ForwardSetState(SCE_H_DEFAULT
);
1868 if (sc
.state
>= SCE_H_DEFAULT
&& sc
.state
<= SCE_H_SGML_BLOCK_DEFAULT
) {
1869 ColouriseHTMLPiece(sc
, keywordlists
);
1872 // Handle some PHP script
1873 if (sc
.state
== SCE_HPHP_WORD
) {
1874 if (!IsPhpWordChar(static_cast<char>(sc
.ch
))) {
1875 sc
.SetState(SCE_HPHP_DEFAULT
);
1877 } else if (sc
.state
== SCE_HPHP_COMMENTLINE
) {
1878 if (sc
.ch
== '\r' || sc
.ch
== '\n') {
1879 sc
.SetState(SCE_HPHP_DEFAULT
);
1881 } else if (sc
.state
== SCE_HPHP_COMMENT
) {
1882 if (sc
.Match('*', '/')) {
1885 sc
.SetState(SCE_HPHP_DEFAULT
);
1887 } else if (sc
.state
== SCE_HPHP_HSTRING
) {
1888 if (sc
.ch
== '\"') {
1889 sc
.ForwardSetState(SCE_HPHP_DEFAULT
);
1891 } else if (sc
.state
== SCE_HPHP_SIMPLESTRING
) {
1892 if (sc
.ch
== '\'') {
1893 sc
.ForwardSetState(SCE_HPHP_DEFAULT
);
1895 } else if (sc
.state
== SCE_HPHP_VARIABLE
) {
1896 if (!IsPhpWordChar(static_cast<char>(sc
.ch
))) {
1897 sc
.SetState(SCE_HPHP_DEFAULT
);
1899 } else if (sc
.state
== SCE_HPHP_OPERATOR
) {
1900 sc
.SetState(SCE_HPHP_DEFAULT
);
1903 // Enter new sc.state
1904 if ((sc
.state
== SCE_H_DEFAULT
) || (sc
.state
== SCE_H_TAGUNKNOWN
)) {
1905 if (sc
.Match("<?php")) {
1906 sc
.SetState(SCE_H_QUESTION
);
1912 sc
.SetState(SCE_HPHP_DEFAULT
);
1915 if (sc
.state
== SCE_HPHP_DEFAULT
) {
1916 if (IsPhpWordStart(static_cast<char>(sc
.ch
))) {
1917 sc
.SetState(SCE_HPHP_WORD
);
1918 } else if (sc
.ch
== '#') {
1919 sc
.SetState(SCE_HPHP_COMMENTLINE
);
1920 } else if (sc
.Match("<!--")) {
1921 sc
.SetState(SCE_HPHP_COMMENTLINE
);
1922 } else if (sc
.Match('/', '/')) {
1923 sc
.SetState(SCE_HPHP_COMMENTLINE
);
1924 } else if (sc
.Match('/', '*')) {
1925 sc
.SetState(SCE_HPHP_COMMENT
);
1926 } else if (sc
.ch
== '\"') {
1927 sc
.SetState(SCE_HPHP_HSTRING
);
1928 } else if (sc
.ch
== '\'') {
1929 sc
.SetState(SCE_HPHP_SIMPLESTRING
);
1930 } else if (sc
.ch
== '$' && IsPhpWordStart(static_cast<char>(sc
.chNext
))) {
1931 sc
.SetState(SCE_HPHP_VARIABLE
);
1932 } else if (isoperator(static_cast<char>(sc
.ch
))) {
1933 sc
.SetState(SCE_HPHP_OPERATOR
);
1938 static void ColourisePHPDoc(unsigned int startPos
, int length
, int initStyle
, WordList
*keywordlists
[],
1940 // Lexer for HTML requires more lexical states (7 bits worth) than most lexers
1941 StyleContext
sc(startPos
, length
, initStyle
, styler
, 0x7f);
1942 for (; sc
.More(); sc
.Forward()) {
1943 ColourisePHPPiece(sc
, keywordlists
);
1948 static const char * const htmlWordListDesc
[] = {
1949 "HTML elements and attributes",
1950 "JavaScript keywords",
1951 "VBScript keywords",
1954 "SGML and DTD keywords",
1958 LexerModule
lmHTML(SCLEX_HTML
, ColouriseHyperTextDoc
, "hypertext", 0, htmlWordListDesc
);
1959 LexerModule
lmXML(SCLEX_XML
, ColouriseHyperTextDoc
, "xml", 0, htmlWordListDesc
);
1960 LexerModule
lmASP(SCLEX_ASP
, ColouriseASPDoc
, "asp", 0, htmlWordListDesc
);
1961 LexerModule
lmPHP(SCLEX_PHP
, ColourisePHPDoc
, "php", 0, htmlWordListDesc
);