1 // Scintilla source code edit control
5 // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
6 // The License.txt file describes the conditions under which this software may be distributed.
19 #include "Scintilla.h"
22 #define SCE_HA_JS (SCE_HJA_START - SCE_HJ_START)
23 #define SCE_HA_VBS (SCE_HBA_START - SCE_HB_START)
24 #define SCE_HA_PYTHON (SCE_HPA_START - SCE_HP_START)
26 enum { eScriptNone
= 0, eScriptJS
, eScriptVBS
, eScriptPython
, eScriptPHP
, eScriptXML
, eScriptSGML
, eScriptSGMLblock
};
27 enum { eHtml
= 0, eNonHtmlScript
, eNonHtmlPreProc
, eNonHtmlScriptPreProc
};
29 static int segIsScriptingIndicator(Accessor
&styler
, unsigned int start
, unsigned int end
, int prevValue
) {
32 for (; i
< end
- start
+ 1 && i
< 30; i
++) {
33 s
[i
] = static_cast<char>(tolower(styler
[start
+ i
]));
36 //Platform::DebugPrintf("Scripting indicator [%s]\n", s);
37 if (strstr(s
, "src")) // External script
41 if (strstr(s
, "pyth"))
43 if (strstr(s
, "javas"))
45 if (strstr(s
, "jscr"))
55 static int PrintScriptingIndicatorOffset(Accessor
&styler
, unsigned int start
, unsigned int end
) {
59 for (; i
< end
- start
+ 1 && i
< 30; i
++) {
60 s
[i
] = static_cast<char>(tolower(styler
[start
+ i
]));
63 if (0 == strncmp(s
, "php", 3)) {
70 static int ScriptOfState(int state
) {
71 if ((state
>= SCE_HP_START
) && (state
<= SCE_HP_IDENTIFIER
)) {
73 } else if ((state
>= SCE_HB_START
) && (state
<= SCE_HB_STRINGEOL
)) {
75 } else if ((state
>= SCE_HJ_START
) && (state
<= SCE_HJ_REGEX
)) {
77 } else if ((state
>= SCE_HPHP_DEFAULT
) && (state
<= SCE_HPHP_COMMENTLINE
)) {
79 } else if ((state
>= SCE_H_SGML_DEFAULT
) && (state
<= SCE_H_SGML_BLOCK_DEFAULT
)) {
81 } else if (state
== SCE_H_SGML_BLOCK_DEFAULT
) {
82 return eScriptSGMLblock
;
88 static int statePrintForState(int state
, int inScriptType
) {
91 if ((state
>= SCE_HP_START
) && (state
<= SCE_HP_IDENTIFIER
)) {
92 StateToPrint
= state
+ ((inScriptType
== eNonHtmlScript
) ? 0 : SCE_HA_PYTHON
);
93 } else if ((state
>= SCE_HB_START
) && (state
<= SCE_HB_STRINGEOL
)) {
94 StateToPrint
= state
+ ((inScriptType
== eNonHtmlScript
) ? 0 : SCE_HA_VBS
);
95 } else if ((state
>= SCE_HJ_START
) && (state
<= SCE_HJ_REGEX
)) {
96 StateToPrint
= state
+ ((inScriptType
== eNonHtmlScript
) ? 0 : SCE_HA_JS
);
104 static int stateForPrintState(int StateToPrint
) {
107 if ((StateToPrint
>= SCE_HPA_START
) && (StateToPrint
<= SCE_HPA_IDENTIFIER
)) {
108 state
= StateToPrint
- SCE_HA_PYTHON
;
109 } else if ((StateToPrint
>= SCE_HBA_START
) && (StateToPrint
<= SCE_HBA_STRINGEOL
)) {
110 state
= StateToPrint
- SCE_HA_VBS
;
111 } else if ((StateToPrint
>= SCE_HJA_START
) && (StateToPrint
<= SCE_HJA_REGEX
)) {
112 state
= StateToPrint
- SCE_HA_JS
;
114 state
= StateToPrint
;
120 static inline bool IsNumber(unsigned int start
, Accessor
&styler
) {
121 return isdigit(styler
[start
]) || (styler
[start
] == '.') ||
122 (styler
[start
] == '-') || (styler
[start
] == '#');
125 static inline bool isStringState(int state
) {
129 case SCE_HJ_DOUBLESTRING
:
130 case SCE_HJ_SINGLESTRING
:
131 case SCE_HJA_DOUBLESTRING
:
132 case SCE_HJA_SINGLESTRING
:
137 case SCE_HPHP_HSTRING
:
138 case SCE_HPHP_SIMPLESTRING
:
148 // not really well done, since it's only comments that should lex the %> and <%
149 static inline bool isCommentASPState(int state
) {
154 case SCE_HJ_COMMENTLINE
:
155 case SCE_HJ_COMMENTDOC
:
156 case SCE_HB_COMMENTLINE
:
157 case SCE_HP_COMMENTLINE
:
158 case SCE_HPHP_COMMENT
:
159 case SCE_HPHP_COMMENTLINE
:
169 static void classifyAttribHTML(unsigned int start
, unsigned int end
, WordList
&keywords
, Accessor
&styler
) {
170 bool wordIsNumber
= IsNumber(start
, styler
);
171 char chAttr
= SCE_H_ATTRIBUTEUNKNOWN
;
173 chAttr
= SCE_H_NUMBER
;
177 for (; i
< end
- start
+ 1 && i
< 30; i
++) {
178 s
[i
] = static_cast<char>(tolower(styler
[start
+ i
]));
181 if (keywords
.InList(s
))
182 chAttr
= SCE_H_ATTRIBUTE
;
184 if ((chAttr
== SCE_H_ATTRIBUTEUNKNOWN
) && !keywords
)
185 // No keywords -> all are known
186 chAttr
= SCE_H_ATTRIBUTE
;
187 styler
.ColourTo(end
, chAttr
);
190 static int classifyTagHTML(unsigned int start
, unsigned int end
,
191 WordList
&keywords
, Accessor
&styler
) {
193 // Copy after the '<'
195 for (unsigned int cPos
= start
; cPos
<= end
&& i
< 30; cPos
++) {
196 char ch
= styler
[cPos
];
197 if ((ch
!= '<') && (ch
!= '/'))
198 s
[i
++] = static_cast<char>(tolower(ch
));
201 bool isScript
= false;
202 char chAttr
= SCE_H_TAGUNKNOWN
;
204 chAttr
= SCE_H_SGML_DEFAULT
;
205 } else if (s
[0] == '/') { // Closing tag
206 if (keywords
.InList(s
+ 1))
209 if (keywords
.InList(s
)) {
211 isScript
= 0 == strcmp(s
, "script");
214 if ((chAttr
== SCE_H_TAGUNKNOWN
) && !keywords
)
215 // No keywords -> all are known
217 styler
.ColourTo(end
, chAttr
);
218 return isScript
? SCE_H_SCRIPT
: chAttr
;
221 static void classifyWordHTJS(unsigned int start
, unsigned int end
,
222 WordList
&keywords
, Accessor
&styler
, int inScriptType
) {
223 char chAttr
= SCE_HJ_WORD
;
224 bool wordIsNumber
= isdigit(styler
[start
]) || (styler
[start
] == '.');
226 chAttr
= SCE_HJ_NUMBER
;
230 for (; i
< end
- start
+ 1 && i
< 30; i
++) {
231 s
[i
] = styler
[start
+ i
];
234 if (keywords
.InList(s
))
235 chAttr
= SCE_HJ_KEYWORD
;
237 styler
.ColourTo(end
, statePrintForState(chAttr
, inScriptType
));
240 static int classifyWordHTVB(unsigned int start
, unsigned int end
, WordList
&keywords
, Accessor
&styler
, int inScriptType
) {
241 char chAttr
= SCE_HB_IDENTIFIER
;
242 bool wordIsNumber
= isdigit(styler
[start
]) || (styler
[start
] == '.');
244 chAttr
= SCE_HB_NUMBER
;
248 for (; i
< end
- start
+ 1 && i
< 30; i
++) {
249 s
[i
] = static_cast<char>(tolower(styler
[start
+ i
]));
252 if (keywords
.InList(s
)) {
253 chAttr
= SCE_HB_WORD
;
254 if (strcmp(s
, "rem") == 0)
255 chAttr
= SCE_HB_COMMENTLINE
;
258 styler
.ColourTo(end
, statePrintForState(chAttr
, inScriptType
));
259 if (chAttr
== SCE_HB_COMMENTLINE
)
260 return SCE_HB_COMMENTLINE
;
262 return SCE_HB_DEFAULT
;
265 static void classifyWordHTPy(unsigned int start
, unsigned int end
, WordList
&keywords
, Accessor
&styler
, char *prevWord
, int inScriptType
) {
266 bool wordIsNumber
= isdigit(styler
[start
]);
269 for (; i
< end
- start
+ 1 && i
< 30; i
++) {
270 s
[i
] = styler
[start
+ i
];
273 char chAttr
= SCE_HP_IDENTIFIER
;
274 if (0 == strcmp(prevWord
, "class"))
275 chAttr
= SCE_HP_CLASSNAME
;
276 else if (0 == strcmp(prevWord
, "def"))
277 chAttr
= SCE_HP_DEFNAME
;
278 else if (wordIsNumber
)
279 chAttr
= SCE_HP_NUMBER
;
280 else if (keywords
.InList(s
))
281 chAttr
= SCE_HP_WORD
;
282 styler
.ColourTo(end
, statePrintForState(chAttr
, inScriptType
));
286 // Update the word colour to default or keyword
287 // Called when in a PHP word
288 static void classifyWordHTPHP(unsigned int start
, unsigned int end
, WordList
&keywords
, Accessor
&styler
) {
289 char chAttr
= SCE_HPHP_DEFAULT
;
290 bool wordIsNumber
= isdigit(styler
[start
]);
292 chAttr
= SCE_HPHP_NUMBER
;
296 for (; i
< end
- start
+ 1 && i
< 30; i
++) {
297 s
[i
] = styler
[start
+ i
];
300 if (keywords
.InList(s
))
301 chAttr
= SCE_HPHP_WORD
;
303 styler
.ColourTo(end
, chAttr
);
306 static bool isWordHSGML(unsigned int start
, unsigned int end
, WordList
&keywords
, Accessor
&styler
) {
309 for (; i
< end
- start
+ 1 && i
< 30; i
++) {
310 s
[i
] = styler
[start
+ i
];
313 return keywords
.InList(s
);
316 static bool isWordCdata(unsigned int start
, unsigned int end
, Accessor
&styler
) {
319 for (; i
< end
- start
+ 1 && i
< 30; i
++) {
320 s
[i
] = styler
[start
+ i
];
323 return (0 == strcmp(s
, "[CDATA["));
326 // Return the first state to reach when entering a scripting language
327 static int StateForScript(int scriptLanguage
) {
329 switch (scriptLanguage
) {
331 Result
= SCE_HB_START
;
334 Result
= SCE_HP_START
;
337 Result
= SCE_HPHP_DEFAULT
;
340 Result
= SCE_H_TAGUNKNOWN
;
343 Result
= SCE_H_SGML_DEFAULT
;
346 Result
= SCE_HJ_START
;
352 inline bool ishtmlwordchar(char ch
) {
353 return isalnum(ch
) || ch
== '.' || ch
== '-' || ch
== '_' || ch
== ':' || ch
== '!' || ch
== '#';
356 inline bool issgmlwordchar(char ch
) {
357 return isalnum(ch
) || ch
== '.' || ch
== '_' || ch
== ':' || ch
== '!' || ch
== '#' || ch
== '[';
360 static bool InTagState(int state
) {
361 return state
== SCE_H_TAG
|| state
== SCE_H_TAGUNKNOWN
||
362 state
== SCE_H_SCRIPT
||
363 state
== SCE_H_ATTRIBUTE
|| state
== SCE_H_ATTRIBUTEUNKNOWN
||
364 state
== SCE_H_NUMBER
|| state
== SCE_H_OTHER
||
365 state
== SCE_H_DOUBLESTRING
|| state
== SCE_H_SINGLESTRING
;
368 static bool IsCommentState(const int state
) {
369 return state
== SCE_H_COMMENT
|| state
== SCE_H_SGML_COMMENT
;
372 static bool isLineEnd(char ch
) {
373 return ch
== '\r' || ch
== '\n';
376 static bool isOKBeforeRE(char ch
) {
377 return (ch
== '(') || (ch
== '=') || (ch
== ',');
380 static bool isPHPStringState(int state
) {
382 (state
== SCE_HPHP_HSTRING
) ||
383 (state
== SCE_HPHP_SIMPLESTRING
) ||
384 (state
== SCE_HPHP_HSTRING_VARIABLE
);
387 static void ColouriseHyperTextDoc(unsigned int startPos
, int length
, int initStyle
, WordList
*keywordlists
[],
389 WordList
&keywords
= *keywordlists
[0];
390 WordList
&keywords2
= *keywordlists
[1];
391 WordList
&keywords3
= *keywordlists
[2];
392 WordList
&keywords4
= *keywordlists
[3];
393 WordList
&keywords5
= *keywordlists
[4];
394 WordList
&keywords6
= *keywordlists
[5]; // SGML (DTD) keywords
396 // Lexer for HTML requires more lexical states (7 bits worth) than most lexers
397 styler
.StartAt(startPos
, STYLE_MAX
);
400 int StateToPrint
= initStyle
;
401 int state
= stateForPrintState(StateToPrint
);
403 // If inside a tag, it may be a script tag, so reread from the start to ensure any language tags are seen
404 if (InTagState(state
)) {
405 while ((startPos
> 0) && (InTagState(styler
.StyleAt(startPos
- 1)))) {
409 state
= SCE_H_DEFAULT
;
411 styler
.StartAt(startPos
, STYLE_MAX
);
413 int lineCurrent
= styler
.GetLine(startPos
);
415 if (lineCurrent
> 0) {
416 lineState
= styler
.GetLineState(lineCurrent
);
418 // Default client and ASP scripting language is JavaScript
419 lineState
= eScriptJS
<< 8;
420 lineState
|= styler
.GetPropertyInt("asp.default.language", eScriptJS
) << 4;
422 int inScriptType
= (lineState
>> 0) & 0x03; // 2 bits of scripting type
423 bool tagOpened
= (lineState
>> 2) & 0x01; // 1 bit to know if we are in an opened tag
424 bool tagClosing
= (lineState
>> 3) & 0x01; // 1 bit to know if we are in a closing tag
425 int aspScript
= (lineState
>> 4) & 0x0F; // 4 bits of script name
426 int clientScript
= (lineState
>> 8) & 0x0F; // 4 bits of script name
427 int beforePreProc
= (lineState
>> 12) & 0xFF; // 8 bits of state
429 int scriptLanguage
= ScriptOfState(state
);
431 const bool foldHTML
= styler
.GetPropertyInt("fold.html", 0);
432 const bool fold
= foldHTML
&& styler
.GetPropertyInt("fold");
433 const bool foldCompact
= styler
.GetPropertyInt("fold.compact", 1);
435 int levelPrev
= styler
.LevelAt(lineCurrent
) & SC_FOLDLEVELNUMBERMASK
;
436 int levelCurrent
= levelPrev
;
437 int visibleChars
= 0;
441 char chPrevNonWhite
= ' ';
442 styler
.StartSegment(startPos
);
443 const int lengthDoc
= startPos
+ length
;
444 for (int i
= startPos
; i
< lengthDoc
; i
++) {
445 const char chPrev2
= chPrev
;
447 if (ch
!= ' ' && ch
!= '\t')
450 char chNext
= styler
.SafeGetCharAt(i
+ 1);
451 const char chNext2
= styler
.SafeGetCharAt(i
+ 2);
453 // Handle DBCS codepages
454 if (styler
.IsLeadByte(ch
)) {
460 if ((!isspacechar(ch
) || !foldCompact
) && fold
)
463 // decide what is the current state to print (depending of the script tag)
464 StateToPrint
= statePrintForState(state
, inScriptType
);
466 // handle script folding
468 switch (scriptLanguage
) {
471 //not currently supported case eScriptVBS:
473 if ((state
!= SCE_HPHP_COMMENT
) && (state
!= SCE_HPHP_COMMENTLINE
) && (state
!= SCE_HJ_COMMENT
) && (state
!= SCE_HJ_COMMENTLINE
) && (state
!= SCE_HJ_COMMENTDOC
)) {
474 if ((ch
== '{') || (ch
== '}')) {
475 levelCurrent
+= (ch
== '{') ? 1 : -1;
480 if (state
!= SCE_HP_COMMENTLINE
) {
481 if ((ch
== ':') && ((chNext
== '\n') || (chNext
== '\r' && chNext2
== '\n'))) {
483 } else if ((ch
== '\n') && !((chNext
== '\r') && (chNext2
== '\n')) && (chNext
!= '\n')) {
484 // check if the number of tabs is lower than the level
485 int Findlevel
= (levelCurrent
& ~SC_FOLDLEVELBASE
) * 8;
486 for (int j
= 0; Findlevel
> 0; j
++) {
487 char chTmp
= styler
.SafeGetCharAt(i
+ j
+ 1);
490 } else if (chTmp
== ' ') {
498 levelCurrent
-= Findlevel
/ 8;
508 if ((ch
== '\r' && chNext
!= '\n') || (ch
== '\n')) {
509 // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
510 // Avoid triggering two times on Dos/Win
511 // New line -> record any line state onto /next/ line
514 if (visibleChars
== 0)
515 lev
|= SC_FOLDLEVELWHITEFLAG
;
516 if ((levelCurrent
> levelPrev
) && (visibleChars
> 0))
517 lev
|= SC_FOLDLEVELHEADERFLAG
;
519 styler
.SetLevel(lineCurrent
, lev
);
521 levelPrev
= levelCurrent
;
524 styler
.SetLineState(lineCurrent
,
525 ((inScriptType
& 0x03) << 0) |
526 ((tagOpened
& 0x01) << 2) |
527 ((tagClosing
& 0x01) << 3) |
528 ((aspScript
& 0x0F) << 4) |
529 ((clientScript
& 0x0F) << 8) |
530 ((beforePreProc
& 0xFF) << 12));
533 // generic end of script processing
534 else if ((inScriptType
== eNonHtmlScript
) && (ch
== '<') && (chNext
== '/')) {
535 // Check if it's the end of the script tag (or any other HTML tag)
537 // in these cases, you can embed HTML tags (to confirm !!!!!!!!!!!!!!!!!!!!!!)
538 case SCE_H_DOUBLESTRING
:
539 case SCE_H_SINGLESTRING
:
541 case SCE_HJ_COMMENTDOC
:
542 // SCE_HJ_COMMENTLINE removed as this is a common thing done to hide
543 // the end of script marker from some JS interpreters.
544 //case SCE_HJ_COMMENTLINE:
545 case SCE_HJ_DOUBLESTRING
:
546 case SCE_HJ_SINGLESTRING
:
550 case SCE_HP_TRIPLEDOUBLE
:
553 // closing tag of the script (it's a closing HTML tag anyway)
554 styler
.ColourTo(i
- 1, StateToPrint
);
555 state
= SCE_H_TAGUNKNOWN
;
556 inScriptType
= eHtml
;
557 scriptLanguage
= eScriptNone
;
558 clientScript
= eScriptJS
;
566 /////////////////////////////////////
567 // handle the start of PHP pre-processor = Non-HTML
568 else if ((state
!= SCE_H_ASPAT
) &&
569 !isPHPStringState(state
) &&
570 (state
!= SCE_HPHP_COMMENT
) &&
573 styler
.ColourTo(i
- 1, StateToPrint
);
574 beforePreProc
= state
;
575 scriptLanguage
= segIsScriptingIndicator(styler
, styler
.GetStartSegment() + 2, i
+ 10, eScriptPHP
);
578 i
+= PrintScriptingIndicatorOffset(styler
, styler
.GetStartSegment() + 2, i
+ 10);
579 if (scriptLanguage
== eScriptXML
)
580 styler
.ColourTo(i
, SCE_H_XMLSTART
);
582 styler
.ColourTo(i
, SCE_H_QUESTION
);
583 state
= StateForScript(scriptLanguage
);
584 if (inScriptType
== eNonHtmlScript
)
585 inScriptType
= eNonHtmlScriptPreProc
;
587 inScriptType
= eNonHtmlPreProc
;
590 if (scriptLanguage
== eScriptXML
)
591 levelCurrent
--; // no folding of the XML first tag (all XML-like tags in this case)
593 ch
= styler
.SafeGetCharAt(i
);
597 // handle the start of ASP pre-processor = Non-HTML
598 else if (!isCommentASPState(state
) && (ch
== '<') && (chNext
== '%')) {
599 styler
.ColourTo(i
- 1, StateToPrint
);
600 beforePreProc
= state
;
601 if (inScriptType
== eNonHtmlScript
)
602 inScriptType
= eNonHtmlScriptPreProc
;
604 inScriptType
= eNonHtmlPreProc
;
606 if (chNext2
== '@') {
607 i
+= 2; // place as if it was the second next char treated
610 } else if ((chNext2
== '-') && (styler
.SafeGetCharAt(i
+ 3) == '-')) {
611 styler
.ColourTo(i
+ 3, SCE_H_ASP
);
612 state
= SCE_H_XCCOMMENT
;
613 scriptLanguage
= eScriptVBS
;
616 if (chNext2
== '=') {
617 i
+= 2; // place as if it was the second next char treated
620 i
++; // place as if it was the next char treated
624 state
= StateForScript(aspScript
);
626 scriptLanguage
= eScriptVBS
;
627 styler
.ColourTo(i
, SCE_H_ASP
);
631 ch
= styler
.SafeGetCharAt(i
);
635 /////////////////////////////////////
636 // handle the start of SGML language (DTD)
637 else if (((scriptLanguage
== eScriptNone
) || (scriptLanguage
== eScriptXML
)) &&
640 (StateToPrint
!= SCE_H_CDATA
) && (!IsCommentState(StateToPrint
))) {
641 beforePreProc
= state
;
642 styler
.ColourTo(i
- 2, StateToPrint
);
643 if ((chNext
== '-') && (chNext2
== '-')) {
644 state
= SCE_H_COMMENT
; // wait for a pending command
646 else if (isWordCdata(i
+ 1, i
+ 7, styler
)) {
649 styler
.ColourTo(i
, SCE_H_SGML_DEFAULT
); // <! is default
650 scriptLanguage
= eScriptSGML
;
651 state
= SCE_H_SGML_COMMAND
; // wait for a pending command
653 // fold whole tag (-- when closing the tag)
659 // handle the end of a pre-processor = Non-HTML
661 ((inScriptType
== eNonHtmlPreProc
)
662 || (inScriptType
== eNonHtmlScriptPreProc
)) && (
663 ((scriptLanguage
== eScriptPHP
) && (ch
== '?') && !isPHPStringState(state
) && (state
!= SCE_HPHP_COMMENT
)) ||
664 ((scriptLanguage
!= eScriptNone
) && !isStringState(state
) &&
666 ) && (chNext
== '>')) ||
667 ((scriptLanguage
== eScriptSGML
) && (ch
== '>') && (state
!= SCE_H_SGML_COMMENT
))) {
668 if (state
== SCE_H_ASPAT
) {
669 aspScript
= segIsScriptingIndicator(styler
,
670 styler
.GetStartSegment(), i
- 1, aspScript
);
672 // Bounce out of any ASP mode
675 classifyWordHTJS(styler
.GetStartSegment(), i
- 1, keywords2
, styler
, inScriptType
);
678 classifyWordHTVB(styler
.GetStartSegment(), i
- 1, keywords3
, styler
, inScriptType
);
681 classifyWordHTPy(styler
.GetStartSegment(), i
- 1, keywords4
, styler
, prevWord
, inScriptType
);
684 classifyWordHTPHP(styler
.GetStartSegment(), i
- 1, keywords5
, styler
);
686 case SCE_H_XCCOMMENT
:
687 styler
.ColourTo(i
- 1, state
);
690 styler
.ColourTo(i
- 1, StateToPrint
);
693 if (scriptLanguage
!= eScriptSGML
) {
698 styler
.ColourTo(i
, SCE_H_ASP
);
699 else if (scriptLanguage
== eScriptXML
)
700 styler
.ColourTo(i
, SCE_H_XMLEND
);
701 else if (scriptLanguage
== eScriptSGML
)
702 styler
.ColourTo(i
, SCE_H_SGML_DEFAULT
);
704 styler
.ColourTo(i
, SCE_H_QUESTION
);
705 state
= beforePreProc
;
706 if (inScriptType
== eNonHtmlScriptPreProc
)
707 inScriptType
= eNonHtmlScript
;
709 inScriptType
= eHtml
;
710 scriptLanguage
= eScriptNone
;
711 // unfold all scripting languages
715 /////////////////////////////////////
720 // in HTML, fold on tag open and unfold on tag close
722 tagClosing
= (chNext
== '/');
723 styler
.ColourTo(i
- 1, StateToPrint
);
725 state
= SCE_H_TAGUNKNOWN
;
726 } else if (ch
== '&') {
727 styler
.ColourTo(i
- 1, SCE_H_DEFAULT
);
728 state
= SCE_H_ENTITY
;
731 case SCE_H_SGML_DEFAULT
:
732 if (scriptLanguage
== eScriptSGMLblock
)
733 StateToPrint
= SCE_H_SGML_BLOCK_DEFAULT
;
736 styler
.ColourTo(i
- 1, StateToPrint
);
737 state
= SCE_H_SGML_DOUBLESTRING
;
738 } else if (ch
== '\'') {
739 styler
.ColourTo(i
- 1, StateToPrint
);
740 state
= SCE_H_SGML_SIMPLESTRING
;
741 } else if ((ch
== '-') && (chPrev
== '-')) {
742 styler
.ColourTo(i
- 2, StateToPrint
);
743 state
= SCE_H_SGML_COMMENT
;
744 } else if (isalpha(ch
) && (chPrev
== '%')) {
745 styler
.ColourTo(i
- 2, StateToPrint
);
746 state
= SCE_H_SGML_ENTITY
;
747 } else if (ch
== '#') {
748 styler
.ColourTo(i
- 1, StateToPrint
);
749 state
= SCE_H_SGML_SPECIAL
;
750 } else if (ch
== '[') {
751 styler
.ColourTo(i
- 1, StateToPrint
);
752 scriptLanguage
= eScriptSGMLblock
;
753 } else if (ch
== ']') {
754 if (scriptLanguage
== eScriptSGMLblock
) {
755 styler
.ColourTo(i
, StateToPrint
);
756 scriptLanguage
= eScriptSGML
;
758 styler
.ColourTo(i
- 1, StateToPrint
);
759 styler
.ColourTo(i
, SCE_H_SGML_ERROR
);
761 } else if (scriptLanguage
== eScriptSGMLblock
) {
762 if ((ch
== '!') && (chPrev
== '<')) {
763 styler
.ColourTo(i
- 2, StateToPrint
);
764 styler
.ColourTo(i
, SCE_H_SGML_DEFAULT
);
765 state
= SCE_H_SGML_COMMAND
;
766 } else if (ch
== '>') {
767 styler
.ColourTo(i
- 1, StateToPrint
);
768 styler
.ColourTo(i
, SCE_H_SGML_DEFAULT
);
772 case SCE_H_SGML_COMMAND
:
773 if ((ch
== '-') && (chPrev
== '-')) {
774 styler
.ColourTo(i
- 2, StateToPrint
);
775 state
= SCE_H_SGML_COMMENT
;
776 } else if (!issgmlwordchar(ch
)) {
777 if (isWordHSGML(styler
.GetStartSegment(), i
- 1, keywords6
, styler
)) {
778 styler
.ColourTo(i
- 1, StateToPrint
);
779 state
= SCE_H_SGML_1ST_PARAM
;
781 state
= SCE_H_SGML_ERROR
;
785 case SCE_H_SGML_1ST_PARAM
:
786 // wait for the beginning of the word
787 if ((ch
== '-') && (chPrev
== '-')) {
788 if (scriptLanguage
== eScriptSGMLblock
) {
789 styler
.ColourTo(i
- 2, SCE_H_SGML_BLOCK_DEFAULT
);
791 styler
.ColourTo(i
- 2, SCE_H_SGML_DEFAULT
);
793 state
= SCE_H_SGML_1ST_PARAM_COMMENT
;
794 } else if (issgmlwordchar(ch
)) {
795 if (scriptLanguage
== eScriptSGMLblock
) {
796 styler
.ColourTo(i
- 1, SCE_H_SGML_BLOCK_DEFAULT
);
798 styler
.ColourTo(i
- 1, SCE_H_SGML_DEFAULT
);
800 // find the length of the word
802 while (ishtmlwordchar(styler
.SafeGetCharAt(i
+ size
)))
804 styler
.ColourTo(i
+ size
- 1, StateToPrint
);
806 visibleChars
+= size
- 1;
807 ch
= styler
.SafeGetCharAt(i
);
808 state
= SCE_H_SGML_DEFAULT
;
812 case SCE_H_SGML_ERROR
:
813 if ((ch
== '-') && (chPrev
== '-')) {
814 styler
.ColourTo(i
- 2, StateToPrint
);
815 state
= SCE_H_SGML_COMMENT
;
817 case SCE_H_SGML_DOUBLESTRING
:
819 styler
.ColourTo(i
, StateToPrint
);
820 state
= SCE_H_SGML_DEFAULT
;
823 case SCE_H_SGML_SIMPLESTRING
:
825 styler
.ColourTo(i
, StateToPrint
);
826 state
= SCE_H_SGML_DEFAULT
;
829 case SCE_H_SGML_COMMENT
:
830 if ((ch
== '-') && (chPrev
== '-')) {
831 styler
.ColourTo(i
, StateToPrint
);
832 state
= SCE_H_SGML_DEFAULT
;
836 if ((chPrev2
== ']') && (chPrev
== ']') && (ch
== '>')) {
837 styler
.ColourTo(i
, StateToPrint
);
838 state
= SCE_H_DEFAULT
;
843 if ((chPrev2
== '-') && (chPrev
== '-') && (ch
== '>')) {
844 styler
.ColourTo(i
, StateToPrint
);
845 state
= SCE_H_DEFAULT
;
849 case SCE_H_SGML_1ST_PARAM_COMMENT
:
850 if ((ch
== '-') && (chPrev
== '-')) {
851 styler
.ColourTo(i
, SCE_H_SGML_COMMENT
);
852 state
= SCE_H_SGML_1ST_PARAM
;
855 case SCE_H_SGML_SPECIAL
:
857 styler
.ColourTo(i
- 1, StateToPrint
);
859 state
= SCE_H_SGML_ERROR
;
861 state
= SCE_H_SGML_DEFAULT
;
865 case SCE_H_SGML_ENTITY
:
867 styler
.ColourTo(i
, StateToPrint
);
868 state
= SCE_H_SGML_DEFAULT
;
869 } else if (!isalnum(ch
) && ch
!= '-' && ch
!= '.') {
870 styler
.ColourTo(i
, SCE_H_SGML_ERROR
);
871 state
= SCE_H_SGML_DEFAULT
;
876 styler
.ColourTo(i
, StateToPrint
);
877 state
= SCE_H_DEFAULT
;
879 if (ch
!= '#' && !isalnum(ch
)) { // Should check that '#' follows '&', but it is unlikely anyway...
880 styler
.ColourTo(i
, SCE_H_TAGUNKNOWN
);
881 state
= SCE_H_DEFAULT
;
884 case SCE_H_TAGUNKNOWN
:
885 if (!ishtmlwordchar(ch
) && !((ch
== '/') && (chPrev
== '<')) && ch
!= '[') {
886 int eClass
= classifyTagHTML(styler
.GetStartSegment(), i
- 1, keywords
, styler
);
887 if (eClass
== SCE_H_SCRIPT
) {
889 inScriptType
= eNonHtmlScript
;
890 scriptLanguage
= clientScript
;
893 scriptLanguage
= eScriptNone
;
898 styler
.ColourTo(i
, eClass
);
899 if (inScriptType
== eNonHtmlScript
) {
900 state
= StateForScript(scriptLanguage
);
902 state
= SCE_H_DEFAULT
;
911 } else if (ch
== '/' && chNext
== '>') {
912 if (eClass
== SCE_H_TAGUNKNOWN
) {
913 styler
.ColourTo(i
+ 1, SCE_H_TAGUNKNOWN
);
915 styler
.ColourTo(i
- 1, StateToPrint
);
916 styler
.ColourTo(i
+ 1, SCE_H_TAGEND
);
920 state
= SCE_H_DEFAULT
;
923 if (eClass
!= SCE_H_TAGUNKNOWN
) {
924 if (eClass
== SCE_H_SGML_DEFAULT
) {
925 state
= SCE_H_SGML_DEFAULT
;
933 case SCE_H_ATTRIBUTE
:
934 if (!ishtmlwordchar(ch
) && ch
!= '/' && ch
!= '-') {
935 if (inScriptType
== eNonHtmlScript
) {
936 int scriptLanguagePrev
= scriptLanguage
;
937 clientScript
= segIsScriptingIndicator(styler
, styler
.GetStartSegment(), i
- 1, scriptLanguage
);
938 scriptLanguage
= clientScript
;
939 if ((scriptLanguagePrev
!= scriptLanguage
) && (scriptLanguage
== eScriptNone
))
940 inScriptType
= eHtml
;
942 classifyAttribHTML(styler
.GetStartSegment(), i
- 1, keywords
, styler
);
944 styler
.ColourTo(i
, SCE_H_TAG
);
945 if (inScriptType
== eNonHtmlScript
) {
946 state
= StateForScript(scriptLanguage
);
948 state
= SCE_H_DEFAULT
;
956 } else if (ch
== '=') {
957 styler
.ColourTo(i
, SCE_H_OTHER
);
966 styler
.ColourTo(i
- 1, StateToPrint
);
967 styler
.ColourTo(i
, SCE_H_TAG
);
968 if (inScriptType
== eNonHtmlScript
) {
969 state
= StateForScript(scriptLanguage
);
971 state
= SCE_H_DEFAULT
;
979 } else if (ch
== '\"') {
980 styler
.ColourTo(i
- 1, StateToPrint
);
981 state
= SCE_H_DOUBLESTRING
;
982 } else if (ch
== '\'') {
983 styler
.ColourTo(i
- 1, StateToPrint
);
984 state
= SCE_H_SINGLESTRING
;
985 } else if (ch
== '=') {
986 styler
.ColourTo(i
, StateToPrint
);
988 } else if (ch
== '/' && chNext
== '>') {
989 styler
.ColourTo(i
- 1, StateToPrint
);
990 styler
.ColourTo(i
+ 1, SCE_H_TAGEND
);
993 state
= SCE_H_DEFAULT
;
995 } else if (ch
== '?' && chNext
== '>') {
996 styler
.ColourTo(i
- 1, StateToPrint
);
997 styler
.ColourTo(i
+ 1, SCE_H_XMLEND
);
1000 state
= SCE_H_DEFAULT
;
1001 } else if (ishtmlwordchar(ch
)) {
1002 styler
.ColourTo(i
- 1, StateToPrint
);
1003 state
= SCE_H_ATTRIBUTE
;
1006 case SCE_H_DOUBLESTRING
:
1008 if (inScriptType
== eNonHtmlScript
) {
1009 scriptLanguage
= segIsScriptingIndicator(styler
, styler
.GetStartSegment(), i
, scriptLanguage
);
1011 styler
.ColourTo(i
, SCE_H_DOUBLESTRING
);
1012 state
= SCE_H_OTHER
;
1015 case SCE_H_SINGLESTRING
:
1017 if (inScriptType
== eNonHtmlScript
) {
1018 scriptLanguage
= segIsScriptingIndicator(styler
, styler
.GetStartSegment(), i
, scriptLanguage
);
1020 styler
.ColourTo(i
, SCE_H_SINGLESTRING
);
1021 state
= SCE_H_OTHER
;
1025 if (!ishtmlwordchar(ch
)) {
1027 // Should really test for being first character
1028 state
= SCE_H_DOUBLESTRING
;
1029 } else if (ch
== '\'') {
1030 state
= SCE_H_SINGLESTRING
;
1032 if (IsNumber(styler
.GetStartSegment(), styler
)) {
1033 styler
.ColourTo(i
- 1, SCE_H_NUMBER
);
1035 styler
.ColourTo(i
- 1, StateToPrint
);
1038 styler
.ColourTo(i
, SCE_H_TAG
);
1039 if (inScriptType
== eNonHtmlScript
) {
1040 state
= StateForScript(scriptLanguage
);
1042 state
= SCE_H_DEFAULT
;
1051 state
= SCE_H_OTHER
;
1056 case SCE_HJ_DEFAULT
:
1058 case SCE_HJ_SYMBOLS
:
1059 if (iswordstart(ch
)) {
1060 styler
.ColourTo(i
- 1, StateToPrint
);
1061 state
= SCE_HJ_WORD
;
1062 } else if (ch
== '/' && chNext
== '*') {
1063 styler
.ColourTo(i
- 1, StateToPrint
);
1065 state
= SCE_HJ_COMMENTDOC
;
1067 state
= SCE_HJ_COMMENT
;
1068 } else if (ch
== '/' && chNext
== '/') {
1069 styler
.ColourTo(i
- 1, StateToPrint
);
1070 state
= SCE_HJ_COMMENTLINE
;
1071 } else if (ch
== '/' && isOKBeforeRE(chPrevNonWhite
)) {
1072 styler
.ColourTo(i
- 1, StateToPrint
);
1073 state
= SCE_HJ_REGEX
;
1074 } else if (ch
== '\"') {
1075 styler
.ColourTo(i
- 1, StateToPrint
);
1076 state
= SCE_HJ_DOUBLESTRING
;
1077 } else if (ch
== '\'') {
1078 styler
.ColourTo(i
- 1, StateToPrint
);
1079 state
= SCE_HJ_SINGLESTRING
;
1080 } else if ((ch
== '<') && (chNext
== '!') && (chNext2
== '-') &&
1081 styler
.SafeGetCharAt(i
+ 3) == '-') {
1082 styler
.ColourTo(i
- 1, StateToPrint
);
1083 state
= SCE_HJ_COMMENTLINE
;
1084 } else if ((ch
== '-') && (chNext
== '-') && (chNext2
== '>')) {
1085 styler
.ColourTo(i
- 1, StateToPrint
);
1086 state
= SCE_HJ_COMMENTLINE
;
1088 } else if (isoperator(ch
)) {
1089 styler
.ColourTo(i
- 1, StateToPrint
);
1090 styler
.ColourTo(i
, statePrintForState(SCE_HJ_SYMBOLS
, inScriptType
));
1091 state
= SCE_HJ_DEFAULT
;
1092 } else if ((ch
== ' ') || (ch
== '\t')) {
1093 if (state
== SCE_HJ_START
) {
1094 styler
.ColourTo(i
- 1, StateToPrint
);
1095 state
= SCE_HJ_DEFAULT
;
1100 if (!iswordchar(ch
)) {
1101 classifyWordHTJS(styler
.GetStartSegment(), i
- 1, keywords2
, styler
, inScriptType
);
1102 //styler.ColourTo(i - 1, eHTJSKeyword);
1103 state
= SCE_HJ_DEFAULT
;
1104 if (ch
== '/' && chNext
== '*') {
1106 state
= SCE_HJ_COMMENTDOC
;
1108 state
= SCE_HJ_COMMENT
;
1109 } else if (ch
== '/' && chNext
== '/') {
1110 state
= SCE_HJ_COMMENTLINE
;
1111 } else if (ch
== '\"') {
1112 state
= SCE_HJ_DOUBLESTRING
;
1113 } else if (ch
== '\'') {
1114 state
= SCE_HJ_SINGLESTRING
;
1115 } else if ((ch
== '-') && (chNext
== '-') && (chNext2
== '>')) {
1116 styler
.ColourTo(i
- 1, StateToPrint
);
1117 state
= SCE_HJ_COMMENTLINE
;
1119 } else if (isoperator(ch
)) {
1120 styler
.ColourTo(i
, statePrintForState(SCE_HJ_SYMBOLS
, inScriptType
));
1121 state
= SCE_HJ_DEFAULT
;
1125 case SCE_HJ_COMMENT
:
1126 case SCE_HJ_COMMENTDOC
:
1127 if (ch
== '/' && chPrev
== '*') {
1128 styler
.ColourTo(i
, StateToPrint
);
1129 state
= SCE_HJ_DEFAULT
;
1132 case SCE_HJ_COMMENTLINE
:
1133 if (ch
== '\r' || ch
== '\n') {
1134 styler
.ColourTo(i
- 1, statePrintForState(SCE_HJ_COMMENTLINE
, inScriptType
));
1135 state
= SCE_HJ_DEFAULT
;
1138 case SCE_HJ_DOUBLESTRING
:
1140 if (chNext
== '\"' || chNext
== '\'' || chNext
== '\\') {
1143 } else if (ch
== '\"') {
1144 styler
.ColourTo(i
, statePrintForState(SCE_HJ_DOUBLESTRING
, inScriptType
));
1145 state
= SCE_HJ_DEFAULT
;
1146 } else if ((inScriptType
== eNonHtmlScript
) && (ch
== '-') && (chNext
== '-') && (chNext2
== '>')) {
1147 styler
.ColourTo(i
- 1, StateToPrint
);
1148 state
= SCE_HJ_COMMENTLINE
;
1150 } else if (isLineEnd(ch
)) {
1151 styler
.ColourTo(i
- 1, StateToPrint
);
1152 state
= SCE_HJ_STRINGEOL
;
1155 case SCE_HJ_SINGLESTRING
:
1157 if (chNext
== '\"' || chNext
== '\'' || chNext
== '\\') {
1160 } else if (ch
== '\'') {
1161 styler
.ColourTo(i
, statePrintForState(SCE_HJ_SINGLESTRING
, inScriptType
));
1162 state
= SCE_HJ_DEFAULT
;
1163 } else if ((inScriptType
== eNonHtmlScript
) && (ch
== '-') && (chNext
== '-') && (chNext2
== '>')) {
1164 styler
.ColourTo(i
- 1, StateToPrint
);
1165 state
= SCE_HJ_COMMENTLINE
;
1167 } else if (isLineEnd(ch
)) {
1168 styler
.ColourTo(i
- 1, StateToPrint
);
1169 state
= SCE_HJ_STRINGEOL
;
1172 case SCE_HJ_STRINGEOL
:
1173 if (!isLineEnd(ch
)) {
1174 styler
.ColourTo(i
- 1, StateToPrint
);
1175 state
= SCE_HJ_DEFAULT
;
1176 } else if (!isLineEnd(chNext
)) {
1177 styler
.ColourTo(i
, StateToPrint
);
1178 state
= SCE_HJ_DEFAULT
;
1182 if (ch
== '\r' || ch
== '\n' || ch
== '/') {
1183 styler
.ColourTo(i
, StateToPrint
);
1184 state
= SCE_HJ_DEFAULT
;
1185 } else if (ch
== '\\') {
1186 // Gobble up the quoted character
1187 if (chNext
== '\\' || chNext
== '/') {
1190 chNext
= styler
.SafeGetCharAt(i
+ 1);
1194 case SCE_HB_DEFAULT
:
1196 if (iswordstart(ch
)) {
1197 styler
.ColourTo(i
- 1, StateToPrint
);
1198 state
= SCE_HB_WORD
;
1199 } else if (ch
== '\'') {
1200 styler
.ColourTo(i
- 1, StateToPrint
);
1201 state
= SCE_HB_COMMENTLINE
;
1202 } else if (ch
== '\"') {
1203 styler
.ColourTo(i
- 1, StateToPrint
);
1204 state
= SCE_HB_STRING
;
1205 } else if ((ch
== '<') && (chNext
== '!') && (chNext2
== '-') &&
1206 styler
.SafeGetCharAt(i
+ 3) == '-') {
1207 styler
.ColourTo(i
- 1, StateToPrint
);
1208 state
= SCE_HB_COMMENTLINE
;
1209 } else if (isoperator(ch
)) {
1210 styler
.ColourTo(i
- 1, StateToPrint
);
1211 styler
.ColourTo(i
, statePrintForState(SCE_HB_DEFAULT
, inScriptType
));
1212 state
= SCE_HB_DEFAULT
;
1213 } else if ((ch
== ' ') || (ch
== '\t')) {
1214 if (state
== SCE_HB_START
) {
1215 styler
.ColourTo(i
- 1, StateToPrint
);
1216 state
= SCE_HB_DEFAULT
;
1221 if (!iswordchar(ch
)) {
1222 state
= classifyWordHTVB(styler
.GetStartSegment(), i
- 1, keywords3
, styler
, inScriptType
);
1223 if (state
== SCE_HB_DEFAULT
) {
1225 state
= SCE_HB_STRING
;
1226 } else if (ch
== '\'') {
1227 state
= SCE_HB_COMMENTLINE
;
1228 } else if (isoperator(ch
)) {
1229 styler
.ColourTo(i
, statePrintForState(SCE_HB_DEFAULT
, inScriptType
));
1230 state
= SCE_HB_DEFAULT
;
1237 styler
.ColourTo(i
, StateToPrint
);
1238 state
= SCE_HB_DEFAULT
;
1239 } else if (ch
== '\r' || ch
== '\n') {
1240 styler
.ColourTo(i
- 1, StateToPrint
);
1241 state
= SCE_HB_STRINGEOL
;
1244 case SCE_HB_COMMENTLINE
:
1245 if (ch
== '\r' || ch
== '\n') {
1246 styler
.ColourTo(i
- 1, StateToPrint
);
1247 state
= SCE_HB_DEFAULT
;
1250 case SCE_HB_STRINGEOL
:
1251 if (!isLineEnd(ch
)) {
1252 styler
.ColourTo(i
- 1, StateToPrint
);
1253 state
= SCE_HB_DEFAULT
;
1254 } else if (!isLineEnd(chNext
)) {
1255 styler
.ColourTo(i
, StateToPrint
);
1256 state
= SCE_HB_DEFAULT
;
1259 case SCE_HP_DEFAULT
:
1261 if (iswordstart(ch
)) {
1262 styler
.ColourTo(i
- 1, StateToPrint
);
1263 state
= SCE_HP_WORD
;
1264 } else if ((ch
== '<') && (chNext
== '!') && (chNext2
== '-') &&
1265 styler
.SafeGetCharAt(i
+ 3) == '-') {
1266 styler
.ColourTo(i
- 1, StateToPrint
);
1267 state
= SCE_HP_COMMENTLINE
;
1268 } else if (ch
== '#') {
1269 styler
.ColourTo(i
- 1, StateToPrint
);
1270 state
= SCE_HP_COMMENTLINE
;
1271 } else if (ch
== '\"') {
1272 styler
.ColourTo(i
- 1, StateToPrint
);
1273 if (chNext
== '\"' && chNext2
== '\"') {
1275 state
= SCE_HP_TRIPLEDOUBLE
;
1278 chNext
= styler
.SafeGetCharAt(i
+ 1);
1280 // state = statePrintForState(SCE_HP_STRING,inScriptType);
1281 state
= SCE_HP_STRING
;
1283 } else if (ch
== '\'') {
1284 styler
.ColourTo(i
- 1, StateToPrint
);
1285 if (chNext
== '\'' && chNext2
== '\'') {
1287 state
= SCE_HP_TRIPLE
;
1290 chNext
= styler
.SafeGetCharAt(i
+ 1);
1292 state
= SCE_HP_CHARACTER
;
1294 } else if (isoperator(ch
)) {
1295 styler
.ColourTo(i
- 1, StateToPrint
);
1296 styler
.ColourTo(i
, statePrintForState(SCE_HP_OPERATOR
, inScriptType
));
1297 } else if ((ch
== ' ') || (ch
== '\t')) {
1298 if (state
== SCE_HP_START
) {
1299 styler
.ColourTo(i
- 1, StateToPrint
);
1300 state
= SCE_HP_DEFAULT
;
1305 if (!iswordchar(ch
)) {
1306 classifyWordHTPy(styler
.GetStartSegment(), i
- 1, keywords4
, styler
, prevWord
, inScriptType
);
1307 state
= SCE_HP_DEFAULT
;
1309 state
= SCE_HP_COMMENTLINE
;
1310 } else if (ch
== '\"') {
1311 if (chNext
== '\"' && chNext2
== '\"') {
1313 state
= SCE_HP_TRIPLEDOUBLE
;
1316 chNext
= styler
.SafeGetCharAt(i
+ 1);
1318 state
= SCE_HP_STRING
;
1320 } else if (ch
== '\'') {
1321 if (chNext
== '\'' && chNext2
== '\'') {
1323 state
= SCE_HP_TRIPLE
;
1326 chNext
= styler
.SafeGetCharAt(i
+ 1);
1328 state
= SCE_HP_CHARACTER
;
1330 } else if (isoperator(ch
)) {
1331 styler
.ColourTo(i
, statePrintForState(SCE_HP_OPERATOR
, inScriptType
));
1335 case SCE_HP_COMMENTLINE
:
1336 if (ch
== '\r' || ch
== '\n') {
1337 styler
.ColourTo(i
- 1, StateToPrint
);
1338 state
= SCE_HP_DEFAULT
;
1343 if (chNext
== '\"' || chNext
== '\'' || chNext
== '\\') {
1346 chNext
= styler
.SafeGetCharAt(i
+ 1);
1348 } else if (ch
== '\"') {
1349 styler
.ColourTo(i
, StateToPrint
);
1350 state
= SCE_HP_DEFAULT
;
1353 case SCE_HP_CHARACTER
:
1355 if (chNext
== '\"' || chNext
== '\'' || chNext
== '\\') {
1358 chNext
= styler
.SafeGetCharAt(i
+ 1);
1360 } else if (ch
== '\'') {
1361 styler
.ColourTo(i
, StateToPrint
);
1362 state
= SCE_HP_DEFAULT
;
1366 if (ch
== '\'' && chPrev
== '\'' && chPrev2
== '\'') {
1367 styler
.ColourTo(i
, StateToPrint
);
1368 state
= SCE_HP_DEFAULT
;
1371 case SCE_HP_TRIPLEDOUBLE
:
1372 if (ch
== '\"' && chPrev
== '\"' && chPrev2
== '\"') {
1373 styler
.ColourTo(i
, StateToPrint
);
1374 state
= SCE_HP_DEFAULT
;
1377 ///////////// start - PHP state handling
1379 if (!iswordstart(ch
)) {
1380 classifyWordHTPHP(styler
.GetStartSegment(), i
- 1, keywords5
, styler
);
1381 if (ch
== '/' && chNext
== '*') {
1383 state
= SCE_HPHP_COMMENT
;
1384 } else if (ch
== '/' && chNext
== '/') {
1386 state
= SCE_HPHP_COMMENTLINE
;
1387 } else if (ch
== '#') {
1388 state
= SCE_HPHP_COMMENTLINE
;
1389 } else if (ch
== '\"') {
1390 state
= SCE_HPHP_HSTRING
;
1391 } else if (ch
== '\'') {
1392 state
= SCE_HPHP_SIMPLESTRING
;
1393 } else if (ch
== '$') {
1394 state
= SCE_HPHP_VARIABLE
;
1395 } else if (isoperator(ch
)) {
1396 state
= SCE_HPHP_OPERATOR
;
1398 state
= SCE_HPHP_DEFAULT
;
1402 case SCE_HPHP_NUMBER
:
1404 styler
.ColourTo(i
- 1, SCE_HPHP_NUMBER
);
1406 state
= SCE_HPHP_OPERATOR
;
1408 state
= SCE_HPHP_DEFAULT
;
1411 case SCE_HPHP_VARIABLE
:
1412 if (!iswordstart(ch
)) {
1413 styler
.ColourTo(i
- 1, SCE_HPHP_VARIABLE
);
1415 state
= SCE_HPHP_OPERATOR
;
1417 state
= SCE_HPHP_DEFAULT
;
1420 case SCE_HPHP_COMMENT
:
1421 if (ch
== '/' && chPrev
== '*') {
1422 styler
.ColourTo(i
, StateToPrint
);
1423 state
= SCE_HPHP_DEFAULT
;
1426 case SCE_HPHP_COMMENTLINE
:
1427 if (ch
== '\r' || ch
== '\n') {
1428 styler
.ColourTo(i
- 1, StateToPrint
);
1429 state
= SCE_HPHP_DEFAULT
;
1432 case SCE_HPHP_HSTRING
:
1434 // skip the next char
1436 } else if (ch
== '$') {
1437 styler
.ColourTo(i
- 1, StateToPrint
);
1438 state
= SCE_HPHP_HSTRING_VARIABLE
;
1439 } else if (ch
== '\"') {
1440 styler
.ColourTo(i
, StateToPrint
);
1441 state
= SCE_HPHP_DEFAULT
;
1444 case SCE_HPHP_SIMPLESTRING
:
1446 // skip the next char
1448 } else if (ch
== '\'') {
1449 styler
.ColourTo(i
, StateToPrint
);
1450 state
= SCE_HPHP_DEFAULT
;
1453 case SCE_HPHP_HSTRING_VARIABLE
:
1454 if (!iswordstart(ch
)) {
1455 styler
.ColourTo(i
- 1, StateToPrint
);
1456 i
--; // strange but it works
1457 state
= SCE_HPHP_HSTRING
;
1460 case SCE_HPHP_OPERATOR
:
1461 case SCE_HPHP_DEFAULT
:
1462 styler
.ColourTo(i
- 1, StateToPrint
);
1464 state
= SCE_HPHP_NUMBER
;
1465 } else if (iswordstart(ch
)) {
1466 state
= SCE_HPHP_WORD
;
1467 } else if (ch
== '/' && chNext
== '*') {
1469 state
= SCE_HPHP_COMMENT
;
1470 } else if (ch
== '/' && chNext
== '/') {
1472 state
= SCE_HPHP_COMMENTLINE
;
1473 } else if (ch
== '#') {
1474 state
= SCE_HPHP_COMMENTLINE
;
1475 } else if (ch
== '\"') {
1476 state
= SCE_HPHP_HSTRING
;
1477 } else if (ch
== '\'') {
1478 state
= SCE_HPHP_SIMPLESTRING
;
1479 } else if (ch
== '$') {
1480 state
= SCE_HPHP_VARIABLE
;
1481 } else if (isoperator(ch
)) {
1482 state
= SCE_HPHP_OPERATOR
;
1483 } else if ((state
== SCE_HPHP_OPERATOR
) && (isspacechar(ch
))) {
1484 state
= SCE_HPHP_DEFAULT
;
1487 ///////////// end - PHP state handling
1490 // Some of the above terminated their lexeme but since the same character starts
1491 // the same class again, only reenter if non empty segment.
1493 bool nonEmptySegment
= i
>= static_cast<int>(styler
.GetStartSegment());
1494 if (state
== SCE_HB_DEFAULT
) { // One of the above succeeded
1495 if ((ch
== '\"') && (nonEmptySegment
)) {
1496 state
= SCE_HB_STRING
;
1497 } else if (ch
== '\'') {
1498 state
= SCE_HB_COMMENTLINE
;
1499 } else if (iswordstart(ch
)) {
1500 state
= SCE_HB_WORD
;
1501 } else if (isoperator(ch
)) {
1502 styler
.ColourTo(i
, SCE_HB_DEFAULT
);
1504 } else if (state
== SCE_HBA_DEFAULT
) { // One of the above succeeded
1505 if ((ch
== '\"') && (nonEmptySegment
)) {
1506 state
= SCE_HBA_STRING
;
1507 } else if (ch
== '\'') {
1508 state
= SCE_HBA_COMMENTLINE
;
1509 } else if (iswordstart(ch
)) {
1510 state
= SCE_HBA_WORD
;
1511 } else if (isoperator(ch
)) {
1512 styler
.ColourTo(i
, SCE_HBA_DEFAULT
);
1514 } else if (state
== SCE_HJ_DEFAULT
) { // One of the above succeeded
1515 if (ch
== '/' && chNext
== '*') {
1516 if (styler
.SafeGetCharAt(i
+ 2) == '*')
1517 state
= SCE_HJ_COMMENTDOC
;
1519 state
= SCE_HJ_COMMENT
;
1520 } else if (ch
== '/' && chNext
== '/') {
1521 state
= SCE_HJ_COMMENTLINE
;
1522 } else if ((ch
== '\"') && (nonEmptySegment
)) {
1523 state
= SCE_HJ_DOUBLESTRING
;
1524 } else if ((ch
== '\'') && (nonEmptySegment
)) {
1525 state
= SCE_HJ_SINGLESTRING
;
1526 } else if (iswordstart(ch
)) {
1527 state
= SCE_HJ_WORD
;
1528 } else if (isoperator(ch
)) {
1529 styler
.ColourTo(i
, statePrintForState(SCE_HJ_SYMBOLS
, inScriptType
));
1534 StateToPrint
= statePrintForState(state
, inScriptType
);
1535 styler
.ColourTo(lengthDoc
- 1, StateToPrint
);
1537 // Fill in the real level of the next line, keeping the current flags as they will be filled in later
1539 int flagsNext
= styler
.LevelAt(lineCurrent
) & ~SC_FOLDLEVELNUMBERMASK
;
1540 styler
.SetLevel(lineCurrent
, levelPrev
| flagsNext
);
1544 LexerModule
lmHTML(SCLEX_HTML
, ColouriseHyperTextDoc
, "hypertext");
1545 LexerModule
lmXML(SCLEX_XML
, ColouriseHyperTextDoc
, "xml");