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 isdigit(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
:
157 // not really well done, since it's only comments that should lex the %> and <%
158 static inline bool isCommentASPState(int state
) {
163 case SCE_HJ_COMMENTLINE
:
164 case SCE_HJ_COMMENTDOC
:
165 case SCE_HB_COMMENTLINE
:
166 case SCE_HP_COMMENTLINE
:
167 case SCE_HPHP_COMMENT
:
168 case SCE_HPHP_COMMENTLINE
:
178 static void classifyAttribHTML(unsigned int start
, unsigned int end
, WordList
&keywords
, Accessor
&styler
) {
179 bool wordIsNumber
= IsNumber(start
, styler
);
180 char chAttr
= SCE_H_ATTRIBUTEUNKNOWN
;
182 chAttr
= SCE_H_NUMBER
;
186 for (; i
< end
- start
+ 1 && i
< 30; i
++) {
187 s
[i
] = static_cast<char>(tolower(styler
[start
+ i
]));
190 if (keywords
.InList(s
))
191 chAttr
= SCE_H_ATTRIBUTE
;
193 if ((chAttr
== SCE_H_ATTRIBUTEUNKNOWN
) && !keywords
)
194 // No keywords -> all are known
195 chAttr
= SCE_H_ATTRIBUTE
;
196 styler
.ColourTo(end
, chAttr
);
199 static int classifyTagHTML(unsigned int start
, unsigned int end
,
200 WordList
&keywords
, Accessor
&styler
, bool &tagDontFold
,
201 bool caseSensitive
) {
203 // Copy after the '<'
205 for (unsigned int cPos
= start
; cPos
<= end
&& i
< 30; cPos
++) {
206 char ch
= styler
[cPos
];
207 if ((ch
!= '<') && (ch
!= '/')) {
208 s
[i
++] = caseSensitive
? ch
: static_cast<char>(tolower(ch
));
212 //The following is only a quick hack, to see if this whole thing would work
213 //we first need the tagname with a trailing space...
217 //...to find it in the list of no-container-tags
218 // (There are many more. We will need a keywordlist in the property file for this)
219 tagDontFold
= (NULL
!= strstr("meta link img area br hr input ",s
));
221 //now we can remove the trailing space
224 bool isScript
= false;
225 char chAttr
= SCE_H_TAGUNKNOWN
;
227 chAttr
= SCE_H_SGML_DEFAULT
;
228 } else if (s
[0] == '/') { // Closing tag
229 if (keywords
.InList(s
+ 1))
232 if (keywords
.InList(s
)) {
234 isScript
= 0 == strcmp(s
, "script");
237 if ((chAttr
== SCE_H_TAGUNKNOWN
) && !keywords
) {
238 // No keywords -> all are known
240 isScript
= 0 == strcmp(s
, "script");
242 styler
.ColourTo(end
, chAttr
);
243 return isScript
? SCE_H_SCRIPT
: chAttr
;
246 static void classifyWordHTJS(unsigned int start
, unsigned int end
,
247 WordList
&keywords
, Accessor
&styler
, script_mode inScriptType
) {
248 char chAttr
= SCE_HJ_WORD
;
249 bool wordIsNumber
= isdigit(styler
[start
]) || (styler
[start
] == '.');
251 chAttr
= SCE_HJ_NUMBER
;
255 for (; i
< end
- start
+ 1 && i
< 30; i
++) {
256 s
[i
] = styler
[start
+ i
];
259 if (keywords
.InList(s
))
260 chAttr
= SCE_HJ_KEYWORD
;
262 styler
.ColourTo(end
, statePrintForState(chAttr
, inScriptType
));
265 static int classifyWordHTVB(unsigned int start
, unsigned int end
, WordList
&keywords
, Accessor
&styler
, script_mode inScriptType
) {
266 char chAttr
= SCE_HB_IDENTIFIER
;
267 bool wordIsNumber
= isdigit(styler
[start
]) || (styler
[start
] == '.');
269 chAttr
= SCE_HB_NUMBER
;
273 for (; i
< end
- start
+ 1 && i
< 30; i
++) {
274 s
[i
] = static_cast<char>(tolower(styler
[start
+ i
]));
277 if (keywords
.InList(s
)) {
278 chAttr
= SCE_HB_WORD
;
279 if (strcmp(s
, "rem") == 0)
280 chAttr
= SCE_HB_COMMENTLINE
;
283 styler
.ColourTo(end
, statePrintForState(chAttr
, inScriptType
));
284 if (chAttr
== SCE_HB_COMMENTLINE
)
285 return SCE_HB_COMMENTLINE
;
287 return SCE_HB_DEFAULT
;
290 static void classifyWordHTPy(unsigned int start
, unsigned int end
, WordList
&keywords
, Accessor
&styler
, char *prevWord
, script_mode inScriptType
) {
291 bool wordIsNumber
= isdigit(styler
[start
]) != 0;
294 for (; i
< end
- start
+ 1 && i
< 30; i
++) {
295 s
[i
] = styler
[start
+ i
];
298 char chAttr
= SCE_HP_IDENTIFIER
;
299 if (0 == strcmp(prevWord
, "class"))
300 chAttr
= SCE_HP_CLASSNAME
;
301 else if (0 == strcmp(prevWord
, "def"))
302 chAttr
= SCE_HP_DEFNAME
;
303 else if (wordIsNumber
)
304 chAttr
= SCE_HP_NUMBER
;
305 else if (keywords
.InList(s
))
306 chAttr
= SCE_HP_WORD
;
307 styler
.ColourTo(end
, statePrintForState(chAttr
, inScriptType
));
311 // Update the word colour to default or keyword
312 // Called when in a PHP word
313 static void classifyWordHTPHP(unsigned int start
, unsigned int end
, WordList
&keywords
, Accessor
&styler
) {
314 char chAttr
= SCE_HPHP_DEFAULT
;
315 bool wordIsNumber
= isdigit(styler
[start
]) != 0;
317 chAttr
= SCE_HPHP_NUMBER
;
321 for (; i
< end
- start
+ 1 && i
< 100; i
++) {
322 s
[i
] = static_cast<char>(tolower(styler
[start
+ i
]));
325 if (keywords
.InList(s
))
326 chAttr
= SCE_HPHP_WORD
;
328 styler
.ColourTo(end
, chAttr
);
331 static bool isWordHSGML(unsigned int start
, unsigned int end
, WordList
&keywords
, Accessor
&styler
) {
334 for (; i
< end
- start
+ 1 && i
< 30; i
++) {
335 s
[i
] = styler
[start
+ i
];
338 return keywords
.InList(s
);
341 static bool isWordCdata(unsigned int start
, unsigned int end
, Accessor
&styler
) {
344 for (; i
< end
- start
+ 1 && i
< 30; i
++) {
345 s
[i
] = styler
[start
+ i
];
348 return (0 == strcmp(s
, "[CDATA["));
351 // Return the first state to reach when entering a scripting language
352 static int StateForScript(script_type scriptLanguage
) {
354 switch (scriptLanguage
) {
356 Result
= SCE_HB_START
;
359 Result
= SCE_HP_START
;
362 Result
= SCE_HPHP_DEFAULT
;
365 Result
= SCE_H_TAGUNKNOWN
;
368 Result
= SCE_H_SGML_DEFAULT
;
371 Result
= SCE_HJ_START
;
377 static inline bool ishtmlwordchar(char ch
) {
378 return isalnum(ch
) || ch
== '.' || ch
== '-' || ch
== '_' || ch
== ':' || ch
== '!' || ch
== '#';
381 static inline bool issgmlwordchar(char ch
) {
382 return isalnum(ch
) || ch
== '.' || ch
== '_' || ch
== ':' || ch
== '!' || ch
== '#' || ch
== '[';
385 static inline bool IsPhpWordStart(const unsigned char ch
) {
386 return isalpha(ch
) || (ch
== '_') || (ch
>= 0x7f);
389 static inline bool IsPhpWordChar(char ch
) {
390 return isdigit(ch
) || IsPhpWordStart(ch
);
393 static bool InTagState(int state
) {
394 return state
== SCE_H_TAG
|| state
== SCE_H_TAGUNKNOWN
||
395 state
== SCE_H_SCRIPT
||
396 state
== SCE_H_ATTRIBUTE
|| state
== SCE_H_ATTRIBUTEUNKNOWN
||
397 state
== SCE_H_NUMBER
|| state
== SCE_H_OTHER
||
398 state
== SCE_H_DOUBLESTRING
|| state
== SCE_H_SINGLESTRING
;
401 static bool IsCommentState(const int state
) {
402 return state
== SCE_H_COMMENT
|| state
== SCE_H_SGML_COMMENT
;
405 static bool isLineEnd(char ch
) {
406 return ch
== '\r' || ch
== '\n';
409 static bool isOKBeforeRE(char ch
) {
410 return (ch
== '(') || (ch
== '=') || (ch
== ',');
413 static bool isPHPStringState(int state
) {
415 (state
== SCE_HPHP_HSTRING
) ||
416 (state
== SCE_HPHP_SIMPLESTRING
) ||
417 (state
== SCE_HPHP_HSTRING_VARIABLE
);
420 static void ColouriseHyperTextDoc(unsigned int startPos
, int length
, int initStyle
, WordList
*keywordlists
[],
422 WordList
&keywords
= *keywordlists
[0];
423 WordList
&keywords2
= *keywordlists
[1];
424 WordList
&keywords3
= *keywordlists
[2];
425 WordList
&keywords4
= *keywordlists
[3];
426 WordList
&keywords5
= *keywordlists
[4];
427 WordList
&keywords6
= *keywordlists
[5]; // SGML (DTD) keywords
429 // Lexer for HTML requires more lexical states (7 bits worth) than most lexers
430 styler
.StartAt(startPos
, STYLE_MAX
);
433 int StateToPrint
= initStyle
;
434 int state
= stateForPrintState(StateToPrint
);
436 // If inside a tag, it may be a script tag, so reread from the start to ensure any language tags are seen
437 if (InTagState(state
)) {
438 while ((startPos
> 0) && (InTagState(styler
.StyleAt(startPos
- 1)))) {
442 state
= SCE_H_DEFAULT
;
444 styler
.StartAt(startPos
, STYLE_MAX
);
446 int lineCurrent
= styler
.GetLine(startPos
);
448 if (lineCurrent
> 0) {
449 lineState
= styler
.GetLineState(lineCurrent
);
451 // Default client and ASP scripting language is JavaScript
452 lineState
= eScriptJS
<< 8;
453 lineState
|= styler
.GetPropertyInt("asp.default.language", eScriptJS
) << 4;
455 script_mode inScriptType
= script_mode((lineState
>> 0) & 0x03); // 2 bits of scripting mode
456 bool tagOpened
= (lineState
>> 2) & 0x01; // 1 bit to know if we are in an opened tag
457 bool tagClosing
= (lineState
>> 3) & 0x01; // 1 bit to know if we are in a closing tag
458 bool tagDontFold
= false; //some HTML tags should not be folded
459 script_type aspScript
= script_type((lineState
>> 4) & 0x0F); // 4 bits of script name
460 script_type clientScript
= script_type((lineState
>> 8) & 0x0F); // 4 bits of script name
461 int beforePreProc
= (lineState
>> 12) & 0xFF; // 8 bits of state
463 script_type scriptLanguage
= ScriptOfState(state
);
465 const bool foldHTML
= styler
.GetPropertyInt("fold.html", 0) != 0;
466 const bool fold
= foldHTML
&& styler
.GetPropertyInt("fold", 0);
467 const bool foldHTMLPreprocessor
= foldHTML
&& styler
.GetPropertyInt("fold.html.preprocessor", 1);
468 const bool foldCompact
= styler
.GetPropertyInt("fold.compact", 1) != 0;
469 const bool caseSensitive
= styler
.GetPropertyInt("html.tags.case.sensitive", 0) != 0;
471 int levelPrev
= styler
.LevelAt(lineCurrent
) & SC_FOLDLEVELNUMBERMASK
;
472 int levelCurrent
= levelPrev
;
473 int visibleChars
= 0;
477 char chPrevNonWhite
= ' ';
478 styler
.StartSegment(startPos
);
479 const int lengthDoc
= startPos
+ length
;
480 for (int i
= startPos
; i
< lengthDoc
; i
++) {
481 const char chPrev2
= chPrev
;
483 if (ch
!= ' ' && ch
!= '\t')
486 char chNext
= styler
.SafeGetCharAt(i
+ 1);
487 const char chNext2
= styler
.SafeGetCharAt(i
+ 2);
489 // Handle DBCS codepages
490 if (styler
.IsLeadByte(ch
)) {
496 if ((!isspacechar(ch
) || !foldCompact
) && fold
)
499 // decide what is the current state to print (depending of the script tag)
500 StateToPrint
= statePrintForState(state
, inScriptType
);
502 // handle script folding
504 switch (scriptLanguage
) {
507 //not currently supported case eScriptVBS:
509 if ((state
!= SCE_HPHP_COMMENT
) && (state
!= SCE_HPHP_COMMENTLINE
) && (state
!= SCE_HJ_COMMENT
) && (state
!= SCE_HJ_COMMENTLINE
) && (state
!= SCE_HJ_COMMENTDOC
) && (!isStringState(state
))) {
510 //Platform::DebugPrintf("state=%d, StateToPrint=%d, initStyle=%d\n", state, StateToPrint, initStyle);
511 //if ((state == SCE_HPHP_OPERATOR) || (state == SCE_HPHP_DEFAULT) || (state == SCE_HJ_SYMBOLS) || (state == SCE_HJ_START) || (state == SCE_HJ_DEFAULT)) {
512 if ((ch
== '{') || (ch
== '}')) {
513 levelCurrent
+= (ch
== '{') ? 1 : -1;
518 if (state
!= SCE_HP_COMMENTLINE
) {
519 if ((ch
== ':') && ((chNext
== '\n') || (chNext
== '\r' && chNext2
== '\n'))) {
521 } else if ((ch
== '\n') && !((chNext
== '\r') && (chNext2
== '\n')) && (chNext
!= '\n')) {
522 // check if the number of tabs is lower than the level
523 int Findlevel
= (levelCurrent
& ~SC_FOLDLEVELBASE
) * 8;
524 for (int j
= 0; Findlevel
> 0; j
++) {
525 char chTmp
= styler
.SafeGetCharAt(i
+ j
+ 1);
528 } else if (chTmp
== ' ') {
536 levelCurrent
-= Findlevel
/ 8;
548 if ((ch
== '\r' && chNext
!= '\n') || (ch
== '\n')) {
549 // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
550 // Avoid triggering two times on Dos/Win
551 // New line -> record any line state onto /next/ line
554 if (visibleChars
== 0)
555 lev
|= SC_FOLDLEVELWHITEFLAG
;
556 if ((levelCurrent
> levelPrev
) && (visibleChars
> 0))
557 lev
|= SC_FOLDLEVELHEADERFLAG
;
559 styler
.SetLevel(lineCurrent
, lev
);
561 levelPrev
= levelCurrent
;
564 styler
.SetLineState(lineCurrent
,
565 ((inScriptType
& 0x03) << 0) |
566 ((tagOpened
& 0x01) << 2) |
567 ((tagClosing
& 0x01) << 3) |
568 ((aspScript
& 0x0F) << 4) |
569 ((clientScript
& 0x0F) << 8) |
570 ((beforePreProc
& 0xFF) << 12));
573 // generic end of script processing
574 else if ((inScriptType
== eNonHtmlScript
) && (ch
== '<') && (chNext
== '/')) {
575 // Check if it's the end of the script tag (or any other HTML tag)
577 // in these cases, you can embed HTML tags (to confirm !!!!!!!!!!!!!!!!!!!!!!)
578 case SCE_H_DOUBLESTRING
:
579 case SCE_H_SINGLESTRING
:
581 case SCE_HJ_COMMENTDOC
:
582 // SCE_HJ_COMMENTLINE removed as this is a common thing done to hide
583 // the end of script marker from some JS interpreters.
584 //case SCE_HJ_COMMENTLINE:
585 case SCE_HJ_DOUBLESTRING
:
586 case SCE_HJ_SINGLESTRING
:
591 case SCE_HP_TRIPLEDOUBLE
:
594 // closing tag of the script (it's a closing HTML tag anyway)
595 styler
.ColourTo(i
- 1, StateToPrint
);
596 state
= SCE_H_TAGUNKNOWN
;
597 inScriptType
= eHtml
;
598 scriptLanguage
= eScriptNone
;
599 clientScript
= eScriptJS
;
607 /////////////////////////////////////
608 // handle the start of PHP pre-processor = Non-HTML
609 else if ((state
!= SCE_H_ASPAT
) &&
610 !isPHPStringState(state
) &&
611 (state
!= SCE_HPHP_COMMENT
) &&
614 styler
.ColourTo(i
- 1, StateToPrint
);
615 beforePreProc
= state
;
616 scriptLanguage
= segIsScriptingIndicator(styler
, styler
.GetStartSegment() + 2, i
+ 10, eScriptPHP
);
619 i
+= PrintScriptingIndicatorOffset(styler
, styler
.GetStartSegment() + 2, i
+ 10);
620 if (scriptLanguage
== eScriptXML
)
621 styler
.ColourTo(i
, SCE_H_XMLSTART
);
623 styler
.ColourTo(i
, SCE_H_QUESTION
);
624 state
= StateForScript(scriptLanguage
);
625 if (inScriptType
== eNonHtmlScript
)
626 inScriptType
= eNonHtmlScriptPreProc
;
628 inScriptType
= eNonHtmlPreProc
;
630 if (foldHTMLPreprocessor
){
632 if (scriptLanguage
== eScriptXML
)
633 levelCurrent
--; // no folding of the XML first tag (all XML-like tags in this case)
636 ch
= styler
.SafeGetCharAt(i
);
640 // handle the start of ASP pre-processor = Non-HTML
641 else if (!isCommentASPState(state
) && (ch
== '<') && (chNext
== '%')) {
642 styler
.ColourTo(i
- 1, StateToPrint
);
643 beforePreProc
= state
;
644 if (inScriptType
== eNonHtmlScript
)
645 inScriptType
= eNonHtmlScriptPreProc
;
647 inScriptType
= eNonHtmlPreProc
;
649 if (chNext2
== '@') {
650 i
+= 2; // place as if it was the second next char treated
653 } else if ((chNext2
== '-') && (styler
.SafeGetCharAt(i
+ 3) == '-')) {
654 styler
.ColourTo(i
+ 3, SCE_H_ASP
);
655 state
= SCE_H_XCCOMMENT
;
656 scriptLanguage
= eScriptVBS
;
659 if (chNext2
== '=') {
660 i
+= 2; // place as if it was the second next char treated
663 i
++; // place as if it was the next char treated
667 state
= StateForScript(aspScript
);
669 scriptLanguage
= eScriptVBS
;
670 styler
.ColourTo(i
, SCE_H_ASP
);
672 if (foldHTMLPreprocessor
)
675 ch
= styler
.SafeGetCharAt(i
);
679 /////////////////////////////////////
680 // handle the start of SGML language (DTD)
681 else if (((scriptLanguage
== eScriptNone
) || (scriptLanguage
== eScriptXML
)) &&
684 (StateToPrint
!= SCE_H_CDATA
) && (!IsCommentState(StateToPrint
))) {
685 beforePreProc
= state
;
686 styler
.ColourTo(i
- 2, StateToPrint
);
687 if ((chNext
== '-') && (chNext2
== '-')) {
688 state
= SCE_H_COMMENT
; // wait for a pending command
690 else if (isWordCdata(i
+ 1, i
+ 7, styler
)) {
693 styler
.ColourTo(i
, SCE_H_SGML_DEFAULT
); // <! is default
694 scriptLanguage
= eScriptSGML
;
695 state
= SCE_H_SGML_COMMAND
; // wait for a pending command
697 // fold whole tag (-- when closing the tag)
698 if (foldHTMLPreprocessor
)
703 // handle the end of a pre-processor = Non-HTML
705 ((inScriptType
== eNonHtmlPreProc
)
706 || (inScriptType
== eNonHtmlScriptPreProc
)) && (
707 ((scriptLanguage
== eScriptPHP
) && (ch
== '?') && !isPHPStringState(state
) && (state
!= SCE_HPHP_COMMENT
)) ||
708 ((scriptLanguage
!= eScriptNone
) && !isStringState(state
) &&
710 ) && (chNext
== '>')) ||
711 ((scriptLanguage
== eScriptSGML
) && (ch
== '>') && (state
!= SCE_H_SGML_COMMENT
))) {
712 if (state
== SCE_H_ASPAT
) {
713 aspScript
= segIsScriptingIndicator(styler
,
714 styler
.GetStartSegment(), i
- 1, aspScript
);
716 // Bounce out of any ASP mode
719 classifyWordHTJS(styler
.GetStartSegment(), i
- 1, keywords2
, styler
, inScriptType
);
722 classifyWordHTVB(styler
.GetStartSegment(), i
- 1, keywords3
, styler
, inScriptType
);
725 classifyWordHTPy(styler
.GetStartSegment(), i
- 1, keywords4
, styler
, prevWord
, inScriptType
);
728 classifyWordHTPHP(styler
.GetStartSegment(), i
- 1, keywords5
, styler
);
730 case SCE_H_XCCOMMENT
:
731 styler
.ColourTo(i
- 1, state
);
734 styler
.ColourTo(i
- 1, StateToPrint
);
737 if (scriptLanguage
!= eScriptSGML
) {
742 styler
.ColourTo(i
, SCE_H_ASP
);
743 else if (scriptLanguage
== eScriptXML
)
744 styler
.ColourTo(i
, SCE_H_XMLEND
);
745 else if (scriptLanguage
== eScriptSGML
)
746 styler
.ColourTo(i
, SCE_H_SGML_DEFAULT
);
748 styler
.ColourTo(i
, SCE_H_QUESTION
);
749 state
= beforePreProc
;
750 if (inScriptType
== eNonHtmlScriptPreProc
)
751 inScriptType
= eNonHtmlScript
;
753 inScriptType
= eHtml
;
754 scriptLanguage
= eScriptNone
;
755 // unfold all scripting languages
756 if (foldHTMLPreprocessor
)
760 /////////////////////////////////////
765 // in HTML, fold on tag open and unfold on tag close
767 tagClosing
= (chNext
== '/');
768 styler
.ColourTo(i
- 1, StateToPrint
);
770 state
= SCE_H_TAGUNKNOWN
;
771 } else if (ch
== '&') {
772 styler
.ColourTo(i
- 1, SCE_H_DEFAULT
);
773 state
= SCE_H_ENTITY
;
776 case SCE_H_SGML_DEFAULT
:
777 case SCE_H_SGML_BLOCK_DEFAULT
:
778 // if (scriptLanguage == eScriptSGMLblock)
779 // StateToPrint = SCE_H_SGML_BLOCK_DEFAULT;
782 styler
.ColourTo(i
- 1, StateToPrint
);
783 state
= SCE_H_SGML_DOUBLESTRING
;
784 } else if (ch
== '\'') {
785 styler
.ColourTo(i
- 1, StateToPrint
);
786 state
= SCE_H_SGML_SIMPLESTRING
;
787 } else if ((ch
== '-') && (chPrev
== '-')) {
788 styler
.ColourTo(i
- 2, StateToPrint
);
789 state
= SCE_H_SGML_COMMENT
;
790 } else if (isalpha(ch
) && (chPrev
== '%')) {
791 styler
.ColourTo(i
- 2, StateToPrint
);
792 state
= SCE_H_SGML_ENTITY
;
793 } else if (ch
== '#') {
794 styler
.ColourTo(i
- 1, StateToPrint
);
795 state
= SCE_H_SGML_SPECIAL
;
796 } else if (ch
== '[') {
797 styler
.ColourTo(i
- 1, StateToPrint
);
798 scriptLanguage
= eScriptSGMLblock
;
799 state
= SCE_H_SGML_BLOCK_DEFAULT
;
800 } else if (ch
== ']') {
801 if (scriptLanguage
== eScriptSGMLblock
) {
802 styler
.ColourTo(i
, StateToPrint
);
803 scriptLanguage
= eScriptSGML
;
805 styler
.ColourTo(i
- 1, StateToPrint
);
806 styler
.ColourTo(i
, SCE_H_SGML_ERROR
);
808 state
= SCE_H_SGML_DEFAULT
;
809 } else if (scriptLanguage
== eScriptSGMLblock
) {
810 if ((ch
== '!') && (chPrev
== '<')) {
811 styler
.ColourTo(i
- 2, StateToPrint
);
812 styler
.ColourTo(i
, SCE_H_SGML_DEFAULT
);
813 state
= SCE_H_SGML_COMMAND
;
814 } else if (ch
== '>') {
815 styler
.ColourTo(i
- 1, StateToPrint
);
816 styler
.ColourTo(i
, SCE_H_SGML_DEFAULT
);
820 case SCE_H_SGML_COMMAND
:
821 if ((ch
== '-') && (chPrev
== '-')) {
822 styler
.ColourTo(i
- 2, StateToPrint
);
823 state
= SCE_H_SGML_COMMENT
;
824 } else if (!issgmlwordchar(ch
)) {
825 if (isWordHSGML(styler
.GetStartSegment(), i
- 1, keywords6
, styler
)) {
826 styler
.ColourTo(i
- 1, StateToPrint
);
827 state
= SCE_H_SGML_1ST_PARAM
;
829 state
= SCE_H_SGML_ERROR
;
833 case SCE_H_SGML_1ST_PARAM
:
834 // wait for the beginning of the word
835 if ((ch
== '-') && (chPrev
== '-')) {
836 if (scriptLanguage
== eScriptSGMLblock
) {
837 styler
.ColourTo(i
- 2, SCE_H_SGML_BLOCK_DEFAULT
);
839 styler
.ColourTo(i
- 2, SCE_H_SGML_DEFAULT
);
841 state
= SCE_H_SGML_1ST_PARAM_COMMENT
;
842 } else if (issgmlwordchar(ch
)) {
843 if (scriptLanguage
== eScriptSGMLblock
) {
844 styler
.ColourTo(i
- 1, SCE_H_SGML_BLOCK_DEFAULT
);
846 styler
.ColourTo(i
- 1, SCE_H_SGML_DEFAULT
);
848 // find the length of the word
850 while (ishtmlwordchar(styler
.SafeGetCharAt(i
+ size
)))
852 styler
.ColourTo(i
+ size
- 1, StateToPrint
);
854 visibleChars
+= size
- 1;
855 ch
= styler
.SafeGetCharAt(i
);
856 if (scriptLanguage
== eScriptSGMLblock
) {
857 state
= SCE_H_SGML_BLOCK_DEFAULT
;
859 state
= SCE_H_SGML_DEFAULT
;
864 case SCE_H_SGML_ERROR
:
865 if ((ch
== '-') && (chPrev
== '-')) {
866 styler
.ColourTo(i
- 2, StateToPrint
);
867 state
= SCE_H_SGML_COMMENT
;
869 case SCE_H_SGML_DOUBLESTRING
:
871 styler
.ColourTo(i
, StateToPrint
);
872 state
= SCE_H_SGML_DEFAULT
;
875 case SCE_H_SGML_SIMPLESTRING
:
877 styler
.ColourTo(i
, StateToPrint
);
878 state
= SCE_H_SGML_DEFAULT
;
881 case SCE_H_SGML_COMMENT
:
882 if ((ch
== '-') && (chPrev
== '-')) {
883 styler
.ColourTo(i
, StateToPrint
);
884 state
= SCE_H_SGML_DEFAULT
;
888 if ((chPrev2
== ']') && (chPrev
== ']') && (ch
== '>')) {
889 styler
.ColourTo(i
, StateToPrint
);
890 state
= SCE_H_DEFAULT
;
895 if ((chPrev2
== '-') && (chPrev
== '-') && (ch
== '>')) {
896 styler
.ColourTo(i
, StateToPrint
);
897 state
= SCE_H_DEFAULT
;
901 case SCE_H_SGML_1ST_PARAM_COMMENT
:
902 if ((ch
== '-') && (chPrev
== '-')) {
903 styler
.ColourTo(i
, SCE_H_SGML_COMMENT
);
904 state
= SCE_H_SGML_1ST_PARAM
;
907 case SCE_H_SGML_SPECIAL
:
909 styler
.ColourTo(i
- 1, StateToPrint
);
911 state
= SCE_H_SGML_ERROR
;
913 state
= SCE_H_SGML_DEFAULT
;
917 case SCE_H_SGML_ENTITY
:
919 styler
.ColourTo(i
, StateToPrint
);
920 state
= SCE_H_SGML_DEFAULT
;
921 } else if (!isalnum(ch
) && ch
!= '-' && ch
!= '.') {
922 styler
.ColourTo(i
, SCE_H_SGML_ERROR
);
923 state
= SCE_H_SGML_DEFAULT
;
928 styler
.ColourTo(i
, StateToPrint
);
929 state
= SCE_H_DEFAULT
;
931 if (ch
!= '#' && !isalnum(ch
)) { // Should check that '#' follows '&', but it is unlikely anyway...
932 styler
.ColourTo(i
, SCE_H_TAGUNKNOWN
);
933 state
= SCE_H_DEFAULT
;
936 case SCE_H_TAGUNKNOWN
:
937 if (!ishtmlwordchar(ch
) && !((ch
== '/') && (chPrev
== '<')) && ch
!= '[') {
938 int eClass
= classifyTagHTML(styler
.GetStartSegment(),
939 i
- 1, keywords
, styler
, tagDontFold
, caseSensitive
);
940 if (eClass
== SCE_H_SCRIPT
) {
942 inScriptType
= eNonHtmlScript
;
943 scriptLanguage
= clientScript
;
946 scriptLanguage
= eScriptNone
;
951 styler
.ColourTo(i
, eClass
);
952 if (inScriptType
== eNonHtmlScript
) {
953 state
= StateForScript(scriptLanguage
);
955 state
= SCE_H_DEFAULT
;
966 } else if (ch
== '/' && chNext
== '>') {
967 if (eClass
== SCE_H_TAGUNKNOWN
) {
968 styler
.ColourTo(i
+ 1, SCE_H_TAGUNKNOWN
);
970 styler
.ColourTo(i
- 1, StateToPrint
);
971 styler
.ColourTo(i
+ 1, SCE_H_TAGEND
);
975 state
= SCE_H_DEFAULT
;
978 if (eClass
!= SCE_H_TAGUNKNOWN
) {
979 if (eClass
== SCE_H_SGML_DEFAULT
) {
980 state
= SCE_H_SGML_DEFAULT
;
988 case SCE_H_ATTRIBUTE
:
989 if (!ishtmlwordchar(ch
) && ch
!= '/' && ch
!= '-') {
990 if (inScriptType
== eNonHtmlScript
) {
991 int scriptLanguagePrev
= scriptLanguage
;
992 clientScript
= segIsScriptingIndicator(styler
, styler
.GetStartSegment(), i
- 1, scriptLanguage
);
993 scriptLanguage
= clientScript
;
994 if ((scriptLanguagePrev
!= scriptLanguage
) && (scriptLanguage
== eScriptNone
))
995 inScriptType
= eHtml
;
997 classifyAttribHTML(styler
.GetStartSegment(), i
- 1, keywords
, styler
);
999 styler
.ColourTo(i
, SCE_H_TAG
);
1000 if (inScriptType
== eNonHtmlScript
) {
1001 state
= StateForScript(scriptLanguage
);
1003 state
= SCE_H_DEFAULT
;
1014 } else if (ch
== '=') {
1015 styler
.ColourTo(i
, SCE_H_OTHER
);
1016 state
= SCE_H_VALUE
;
1018 state
= SCE_H_OTHER
;
1024 styler
.ColourTo(i
- 1, StateToPrint
);
1025 styler
.ColourTo(i
, SCE_H_TAG
);
1026 if (inScriptType
== eNonHtmlScript
) {
1027 state
= StateForScript(scriptLanguage
);
1029 state
= SCE_H_DEFAULT
;
1040 } else if (ch
== '\"') {
1041 styler
.ColourTo(i
- 1, StateToPrint
);
1042 state
= SCE_H_DOUBLESTRING
;
1043 } else if (ch
== '\'') {
1044 styler
.ColourTo(i
- 1, StateToPrint
);
1045 state
= SCE_H_SINGLESTRING
;
1046 } else if (ch
== '=') {
1047 styler
.ColourTo(i
, StateToPrint
);
1048 state
= SCE_H_VALUE
;
1049 } else if (ch
== '/' && chNext
== '>') {
1050 styler
.ColourTo(i
- 1, StateToPrint
);
1051 styler
.ColourTo(i
+ 1, SCE_H_TAGEND
);
1054 state
= SCE_H_DEFAULT
;
1056 } else if (ch
== '?' && chNext
== '>') {
1057 styler
.ColourTo(i
- 1, StateToPrint
);
1058 styler
.ColourTo(i
+ 1, SCE_H_XMLEND
);
1061 state
= SCE_H_DEFAULT
;
1062 } else if (ishtmlwordchar(ch
)) {
1063 styler
.ColourTo(i
- 1, StateToPrint
);
1064 state
= SCE_H_ATTRIBUTE
;
1067 case SCE_H_DOUBLESTRING
:
1069 if (inScriptType
== eNonHtmlScript
) {
1070 scriptLanguage
= segIsScriptingIndicator(styler
, styler
.GetStartSegment(), i
, scriptLanguage
);
1072 styler
.ColourTo(i
, SCE_H_DOUBLESTRING
);
1073 state
= SCE_H_OTHER
;
1076 case SCE_H_SINGLESTRING
:
1078 if (inScriptType
== eNonHtmlScript
) {
1079 scriptLanguage
= segIsScriptingIndicator(styler
, styler
.GetStartSegment(), i
, scriptLanguage
);
1081 styler
.ColourTo(i
, SCE_H_SINGLESTRING
);
1082 state
= SCE_H_OTHER
;
1086 if (!ishtmlwordchar(ch
)) {
1087 if (ch
== '\"' && chPrev
== '=') {
1088 // Should really test for being first character
1089 state
= SCE_H_DOUBLESTRING
;
1090 } else if (ch
== '\'' && chPrev
== '=') {
1091 state
= SCE_H_SINGLESTRING
;
1093 if (IsNumber(styler
.GetStartSegment(), styler
)) {
1094 styler
.ColourTo(i
- 1, SCE_H_NUMBER
);
1096 styler
.ColourTo(i
- 1, StateToPrint
);
1099 styler
.ColourTo(i
, SCE_H_TAG
);
1100 if (inScriptType
== eNonHtmlScript
) {
1101 state
= StateForScript(scriptLanguage
);
1103 state
= SCE_H_DEFAULT
;
1115 state
= SCE_H_OTHER
;
1120 case SCE_HJ_DEFAULT
:
1122 case SCE_HJ_SYMBOLS
:
1123 if (iswordstart(ch
)) {
1124 styler
.ColourTo(i
- 1, StateToPrint
);
1125 state
= SCE_HJ_WORD
;
1126 } else if (ch
== '/' && chNext
== '*') {
1127 styler
.ColourTo(i
- 1, StateToPrint
);
1129 state
= SCE_HJ_COMMENTDOC
;
1131 state
= SCE_HJ_COMMENT
;
1132 } else if (ch
== '/' && chNext
== '/') {
1133 styler
.ColourTo(i
- 1, StateToPrint
);
1134 state
= SCE_HJ_COMMENTLINE
;
1135 } else if (ch
== '/' && isOKBeforeRE(chPrevNonWhite
)) {
1136 styler
.ColourTo(i
- 1, StateToPrint
);
1137 state
= SCE_HJ_REGEX
;
1138 } else if (ch
== '\"') {
1139 styler
.ColourTo(i
- 1, StateToPrint
);
1140 state
= SCE_HJ_DOUBLESTRING
;
1141 } else if (ch
== '\'') {
1142 styler
.ColourTo(i
- 1, StateToPrint
);
1143 state
= SCE_HJ_SINGLESTRING
;
1144 } else if ((ch
== '<') && (chNext
== '!') && (chNext2
== '-') &&
1145 styler
.SafeGetCharAt(i
+ 3) == '-') {
1146 styler
.ColourTo(i
- 1, StateToPrint
);
1147 state
= SCE_HJ_COMMENTLINE
;
1148 } else if ((ch
== '-') && (chNext
== '-') && (chNext2
== '>')) {
1149 styler
.ColourTo(i
- 1, StateToPrint
);
1150 state
= SCE_HJ_COMMENTLINE
;
1152 } else if (isoperator(ch
)) {
1153 styler
.ColourTo(i
- 1, StateToPrint
);
1154 styler
.ColourTo(i
, statePrintForState(SCE_HJ_SYMBOLS
, inScriptType
));
1155 state
= SCE_HJ_DEFAULT
;
1156 } else if ((ch
== ' ') || (ch
== '\t')) {
1157 if (state
== SCE_HJ_START
) {
1158 styler
.ColourTo(i
- 1, StateToPrint
);
1159 state
= SCE_HJ_DEFAULT
;
1164 if (!iswordchar(ch
)) {
1165 classifyWordHTJS(styler
.GetStartSegment(), i
- 1, keywords2
, styler
, inScriptType
);
1166 //styler.ColourTo(i - 1, eHTJSKeyword);
1167 state
= SCE_HJ_DEFAULT
;
1168 if (ch
== '/' && chNext
== '*') {
1170 state
= SCE_HJ_COMMENTDOC
;
1172 state
= SCE_HJ_COMMENT
;
1173 } else if (ch
== '/' && chNext
== '/') {
1174 state
= SCE_HJ_COMMENTLINE
;
1175 } else if (ch
== '\"') {
1176 state
= SCE_HJ_DOUBLESTRING
;
1177 } else if (ch
== '\'') {
1178 state
= SCE_HJ_SINGLESTRING
;
1179 } else if ((ch
== '-') && (chNext
== '-') && (chNext2
== '>')) {
1180 styler
.ColourTo(i
- 1, StateToPrint
);
1181 state
= SCE_HJ_COMMENTLINE
;
1183 } else if (isoperator(ch
)) {
1184 styler
.ColourTo(i
, statePrintForState(SCE_HJ_SYMBOLS
, inScriptType
));
1185 state
= SCE_HJ_DEFAULT
;
1189 case SCE_HJ_COMMENT
:
1190 case SCE_HJ_COMMENTDOC
:
1191 if (ch
== '/' && chPrev
== '*') {
1192 styler
.ColourTo(i
, StateToPrint
);
1193 state
= SCE_HJ_DEFAULT
;
1196 case SCE_HJ_COMMENTLINE
:
1197 if (ch
== '\r' || ch
== '\n') {
1198 styler
.ColourTo(i
- 1, statePrintForState(SCE_HJ_COMMENTLINE
, inScriptType
));
1199 state
= SCE_HJ_DEFAULT
;
1202 case SCE_HJ_DOUBLESTRING
:
1204 if (chNext
== '\"' || chNext
== '\'' || chNext
== '\\') {
1207 } else if (ch
== '\"') {
1208 styler
.ColourTo(i
, statePrintForState(SCE_HJ_DOUBLESTRING
, inScriptType
));
1209 state
= SCE_HJ_DEFAULT
;
1210 } else if ((inScriptType
== eNonHtmlScript
) && (ch
== '-') && (chNext
== '-') && (chNext2
== '>')) {
1211 styler
.ColourTo(i
- 1, StateToPrint
);
1212 state
= SCE_HJ_COMMENTLINE
;
1214 } else if (isLineEnd(ch
)) {
1215 styler
.ColourTo(i
- 1, StateToPrint
);
1216 state
= SCE_HJ_STRINGEOL
;
1219 case SCE_HJ_SINGLESTRING
:
1221 if (chNext
== '\"' || chNext
== '\'' || chNext
== '\\') {
1224 } else if (ch
== '\'') {
1225 styler
.ColourTo(i
, statePrintForState(SCE_HJ_SINGLESTRING
, inScriptType
));
1226 state
= SCE_HJ_DEFAULT
;
1227 } else if ((inScriptType
== eNonHtmlScript
) && (ch
== '-') && (chNext
== '-') && (chNext2
== '>')) {
1228 styler
.ColourTo(i
- 1, StateToPrint
);
1229 state
= SCE_HJ_COMMENTLINE
;
1231 } else if (isLineEnd(ch
)) {
1232 styler
.ColourTo(i
- 1, StateToPrint
);
1233 state
= SCE_HJ_STRINGEOL
;
1236 case SCE_HJ_STRINGEOL
:
1237 if (!isLineEnd(ch
)) {
1238 styler
.ColourTo(i
- 1, StateToPrint
);
1239 state
= SCE_HJ_DEFAULT
;
1240 } else if (!isLineEnd(chNext
)) {
1241 styler
.ColourTo(i
, StateToPrint
);
1242 state
= SCE_HJ_DEFAULT
;
1246 if (ch
== '\r' || ch
== '\n' || ch
== '/') {
1247 styler
.ColourTo(i
, StateToPrint
);
1248 state
= SCE_HJ_DEFAULT
;
1249 } else if (ch
== '\\') {
1250 // Gobble up the quoted character
1251 if (chNext
== '\\' || chNext
== '/') {
1254 chNext
= styler
.SafeGetCharAt(i
+ 1);
1258 case SCE_HB_DEFAULT
:
1260 if (iswordstart(ch
)) {
1261 styler
.ColourTo(i
- 1, StateToPrint
);
1262 state
= SCE_HB_WORD
;
1263 } else if (ch
== '\'') {
1264 styler
.ColourTo(i
- 1, StateToPrint
);
1265 state
= SCE_HB_COMMENTLINE
;
1266 } else if (ch
== '\"') {
1267 styler
.ColourTo(i
- 1, StateToPrint
);
1268 state
= SCE_HB_STRING
;
1269 } else if ((ch
== '<') && (chNext
== '!') && (chNext2
== '-') &&
1270 styler
.SafeGetCharAt(i
+ 3) == '-') {
1271 styler
.ColourTo(i
- 1, StateToPrint
);
1272 state
= SCE_HB_COMMENTLINE
;
1273 } else if (isoperator(ch
)) {
1274 styler
.ColourTo(i
- 1, StateToPrint
);
1275 styler
.ColourTo(i
, statePrintForState(SCE_HB_DEFAULT
, inScriptType
));
1276 state
= SCE_HB_DEFAULT
;
1277 } else if ((ch
== ' ') || (ch
== '\t')) {
1278 if (state
== SCE_HB_START
) {
1279 styler
.ColourTo(i
- 1, StateToPrint
);
1280 state
= SCE_HB_DEFAULT
;
1285 if (!iswordchar(ch
)) {
1286 state
= classifyWordHTVB(styler
.GetStartSegment(), i
- 1, keywords3
, styler
, inScriptType
);
1287 if (state
== SCE_HB_DEFAULT
) {
1289 state
= SCE_HB_STRING
;
1290 } else if (ch
== '\'') {
1291 state
= SCE_HB_COMMENTLINE
;
1292 } else if (isoperator(ch
)) {
1293 styler
.ColourTo(i
, statePrintForState(SCE_HB_DEFAULT
, inScriptType
));
1294 state
= SCE_HB_DEFAULT
;
1301 styler
.ColourTo(i
, StateToPrint
);
1302 state
= SCE_HB_DEFAULT
;
1303 } else if (ch
== '\r' || ch
== '\n') {
1304 styler
.ColourTo(i
- 1, StateToPrint
);
1305 state
= SCE_HB_STRINGEOL
;
1308 case SCE_HB_COMMENTLINE
:
1309 if (ch
== '\r' || ch
== '\n') {
1310 styler
.ColourTo(i
- 1, StateToPrint
);
1311 state
= SCE_HB_DEFAULT
;
1314 case SCE_HB_STRINGEOL
:
1315 if (!isLineEnd(ch
)) {
1316 styler
.ColourTo(i
- 1, StateToPrint
);
1317 state
= SCE_HB_DEFAULT
;
1318 } else if (!isLineEnd(chNext
)) {
1319 styler
.ColourTo(i
, StateToPrint
);
1320 state
= SCE_HB_DEFAULT
;
1323 case SCE_HP_DEFAULT
:
1325 if (iswordstart(ch
)) {
1326 styler
.ColourTo(i
- 1, StateToPrint
);
1327 state
= SCE_HP_WORD
;
1328 } else if ((ch
== '<') && (chNext
== '!') && (chNext2
== '-') &&
1329 styler
.SafeGetCharAt(i
+ 3) == '-') {
1330 styler
.ColourTo(i
- 1, StateToPrint
);
1331 state
= SCE_HP_COMMENTLINE
;
1332 } else if (ch
== '#') {
1333 styler
.ColourTo(i
- 1, StateToPrint
);
1334 state
= SCE_HP_COMMENTLINE
;
1335 } else if (ch
== '\"') {
1336 styler
.ColourTo(i
- 1, StateToPrint
);
1337 if (chNext
== '\"' && chNext2
== '\"') {
1339 state
= SCE_HP_TRIPLEDOUBLE
;
1342 chNext
= styler
.SafeGetCharAt(i
+ 1);
1344 // state = statePrintForState(SCE_HP_STRING,inScriptType);
1345 state
= SCE_HP_STRING
;
1347 } else if (ch
== '\'') {
1348 styler
.ColourTo(i
- 1, StateToPrint
);
1349 if (chNext
== '\'' && chNext2
== '\'') {
1351 state
= SCE_HP_TRIPLE
;
1354 chNext
= styler
.SafeGetCharAt(i
+ 1);
1356 state
= SCE_HP_CHARACTER
;
1358 } else if (isoperator(ch
)) {
1359 styler
.ColourTo(i
- 1, StateToPrint
);
1360 styler
.ColourTo(i
, statePrintForState(SCE_HP_OPERATOR
, inScriptType
));
1361 } else if ((ch
== ' ') || (ch
== '\t')) {
1362 if (state
== SCE_HP_START
) {
1363 styler
.ColourTo(i
- 1, StateToPrint
);
1364 state
= SCE_HP_DEFAULT
;
1369 if (!iswordchar(ch
)) {
1370 classifyWordHTPy(styler
.GetStartSegment(), i
- 1, keywords4
, styler
, prevWord
, inScriptType
);
1371 state
= SCE_HP_DEFAULT
;
1373 state
= SCE_HP_COMMENTLINE
;
1374 } else if (ch
== '\"') {
1375 if (chNext
== '\"' && chNext2
== '\"') {
1377 state
= SCE_HP_TRIPLEDOUBLE
;
1380 chNext
= styler
.SafeGetCharAt(i
+ 1);
1382 state
= SCE_HP_STRING
;
1384 } else if (ch
== '\'') {
1385 if (chNext
== '\'' && chNext2
== '\'') {
1387 state
= SCE_HP_TRIPLE
;
1390 chNext
= styler
.SafeGetCharAt(i
+ 1);
1392 state
= SCE_HP_CHARACTER
;
1394 } else if (isoperator(ch
)) {
1395 styler
.ColourTo(i
, statePrintForState(SCE_HP_OPERATOR
, inScriptType
));
1399 case SCE_HP_COMMENTLINE
:
1400 if (ch
== '\r' || ch
== '\n') {
1401 styler
.ColourTo(i
- 1, StateToPrint
);
1402 state
= SCE_HP_DEFAULT
;
1407 if (chNext
== '\"' || chNext
== '\'' || chNext
== '\\') {
1410 chNext
= styler
.SafeGetCharAt(i
+ 1);
1412 } else if (ch
== '\"') {
1413 styler
.ColourTo(i
, StateToPrint
);
1414 state
= SCE_HP_DEFAULT
;
1417 case SCE_HP_CHARACTER
:
1419 if (chNext
== '\"' || chNext
== '\'' || chNext
== '\\') {
1422 chNext
= styler
.SafeGetCharAt(i
+ 1);
1424 } else if (ch
== '\'') {
1425 styler
.ColourTo(i
, StateToPrint
);
1426 state
= SCE_HP_DEFAULT
;
1430 if (ch
== '\'' && chPrev
== '\'' && chPrev2
== '\'') {
1431 styler
.ColourTo(i
, StateToPrint
);
1432 state
= SCE_HP_DEFAULT
;
1435 case SCE_HP_TRIPLEDOUBLE
:
1436 if (ch
== '\"' && chPrev
== '\"' && chPrev2
== '\"') {
1437 styler
.ColourTo(i
, StateToPrint
);
1438 state
= SCE_HP_DEFAULT
;
1441 ///////////// start - PHP state handling
1443 if (!iswordchar(ch
)) {
1444 classifyWordHTPHP(styler
.GetStartSegment(), i
- 1, keywords5
, styler
);
1445 if (ch
== '/' && chNext
== '*') {
1447 state
= SCE_HPHP_COMMENT
;
1448 } else if (ch
== '/' && chNext
== '/') {
1450 state
= SCE_HPHP_COMMENTLINE
;
1451 } else if (ch
== '#') {
1452 state
= SCE_HPHP_COMMENTLINE
;
1453 } else if (ch
== '\"') {
1454 state
= SCE_HPHP_HSTRING
;
1455 } else if (ch
== '\'') {
1456 state
= SCE_HPHP_SIMPLESTRING
;
1457 } else if (ch
== '$' && IsPhpWordStart(chNext
)) {
1458 state
= SCE_HPHP_VARIABLE
;
1459 } else if (isoperator(ch
)) {
1460 state
= SCE_HPHP_OPERATOR
;
1462 state
= SCE_HPHP_DEFAULT
;
1466 case SCE_HPHP_NUMBER
:
1468 styler
.ColourTo(i
- 1, SCE_HPHP_NUMBER
);
1470 state
= SCE_HPHP_OPERATOR
;
1472 state
= SCE_HPHP_DEFAULT
;
1475 case SCE_HPHP_VARIABLE
:
1476 if (!IsPhpWordChar(ch
)) {
1477 styler
.ColourTo(i
- 1, SCE_HPHP_VARIABLE
);
1479 state
= SCE_HPHP_OPERATOR
;
1481 state
= SCE_HPHP_DEFAULT
;
1484 case SCE_HPHP_COMMENT
:
1485 if (ch
== '/' && chPrev
== '*') {
1486 styler
.ColourTo(i
, StateToPrint
);
1487 state
= SCE_HPHP_DEFAULT
;
1490 case SCE_HPHP_COMMENTLINE
:
1491 if (ch
== '\r' || ch
== '\n') {
1492 styler
.ColourTo(i
- 1, StateToPrint
);
1493 state
= SCE_HPHP_DEFAULT
;
1496 case SCE_HPHP_HSTRING
:
1498 // skip the next char
1500 } else if (ch
== '$' && IsPhpWordStart(chNext
)) {
1501 styler
.ColourTo(i
- 1, StateToPrint
);
1502 state
= SCE_HPHP_HSTRING_VARIABLE
;
1503 } else if (ch
== '\"') {
1504 styler
.ColourTo(i
, StateToPrint
);
1505 state
= SCE_HPHP_DEFAULT
;
1508 case SCE_HPHP_SIMPLESTRING
:
1510 // skip the next char
1512 } else if (ch
== '\'') {
1513 styler
.ColourTo(i
, StateToPrint
);
1514 state
= SCE_HPHP_DEFAULT
;
1517 case SCE_HPHP_HSTRING_VARIABLE
:
1518 if (!IsPhpWordChar(ch
)) {
1519 styler
.ColourTo(i
- 1, StateToPrint
);
1520 i
--; // strange but it works
1521 state
= SCE_HPHP_HSTRING
;
1524 case SCE_HPHP_OPERATOR
:
1525 case SCE_HPHP_DEFAULT
:
1526 styler
.ColourTo(i
- 1, StateToPrint
);
1528 state
= SCE_HPHP_NUMBER
;
1529 } else if (iswordstart(ch
)) {
1530 state
= SCE_HPHP_WORD
;
1531 } else if (ch
== '/' && chNext
== '*') {
1533 state
= SCE_HPHP_COMMENT
;
1534 } else if (ch
== '/' && chNext
== '/') {
1536 state
= SCE_HPHP_COMMENTLINE
;
1537 } else if (ch
== '#') {
1538 state
= SCE_HPHP_COMMENTLINE
;
1539 } else if (ch
== '\"') {
1540 state
= SCE_HPHP_HSTRING
;
1541 } else if (ch
== '\'') {
1542 state
= SCE_HPHP_SIMPLESTRING
;
1543 } else if (ch
== '$' && IsPhpWordStart(chNext
)) {
1544 state
= SCE_HPHP_VARIABLE
;
1545 } else if (isoperator(ch
)) {
1546 state
= SCE_HPHP_OPERATOR
;
1547 } else if ((state
== SCE_HPHP_OPERATOR
) && (isspacechar(ch
))) {
1548 state
= SCE_HPHP_DEFAULT
;
1551 ///////////// end - PHP state handling
1554 // Some of the above terminated their lexeme but since the same character starts
1555 // the same class again, only reenter if non empty segment.
1557 bool nonEmptySegment
= i
>= static_cast<int>(styler
.GetStartSegment());
1558 if (state
== SCE_HB_DEFAULT
) { // One of the above succeeded
1559 if ((ch
== '\"') && (nonEmptySegment
)) {
1560 state
= SCE_HB_STRING
;
1561 } else if (ch
== '\'') {
1562 state
= SCE_HB_COMMENTLINE
;
1563 } else if (iswordstart(ch
)) {
1564 state
= SCE_HB_WORD
;
1565 } else if (isoperator(ch
)) {
1566 styler
.ColourTo(i
, SCE_HB_DEFAULT
);
1568 } else if (state
== SCE_HBA_DEFAULT
) { // One of the above succeeded
1569 if ((ch
== '\"') && (nonEmptySegment
)) {
1570 state
= SCE_HBA_STRING
;
1571 } else if (ch
== '\'') {
1572 state
= SCE_HBA_COMMENTLINE
;
1573 } else if (iswordstart(ch
)) {
1574 state
= SCE_HBA_WORD
;
1575 } else if (isoperator(ch
)) {
1576 styler
.ColourTo(i
, SCE_HBA_DEFAULT
);
1578 } else if (state
== SCE_HJ_DEFAULT
) { // One of the above succeeded
1579 if (ch
== '/' && chNext
== '*') {
1580 if (styler
.SafeGetCharAt(i
+ 2) == '*')
1581 state
= SCE_HJ_COMMENTDOC
;
1583 state
= SCE_HJ_COMMENT
;
1584 } else if (ch
== '/' && chNext
== '/') {
1585 state
= SCE_HJ_COMMENTLINE
;
1586 } else if ((ch
== '\"') && (nonEmptySegment
)) {
1587 state
= SCE_HJ_DOUBLESTRING
;
1588 } else if ((ch
== '\'') && (nonEmptySegment
)) {
1589 state
= SCE_HJ_SINGLESTRING
;
1590 } else if (iswordstart(ch
)) {
1591 state
= SCE_HJ_WORD
;
1592 } else if (isoperator(ch
)) {
1593 styler
.ColourTo(i
, statePrintForState(SCE_HJ_SYMBOLS
, inScriptType
));
1598 StateToPrint
= statePrintForState(state
, inScriptType
);
1599 styler
.ColourTo(lengthDoc
- 1, StateToPrint
);
1601 // Fill in the real level of the next line, keeping the current flags as they will be filled in later
1603 int flagsNext
= styler
.LevelAt(lineCurrent
) & ~SC_FOLDLEVELNUMBERMASK
;
1604 styler
.SetLevel(lineCurrent
, levelPrev
| flagsNext
);
1608 static bool isASPScript(int state
) {
1610 (state
>= SCE_HJA_START
&& state
<= SCE_HJA_REGEX
) ||
1611 (state
>= SCE_HBA_START
&& state
<= SCE_HBA_STRINGEOL
) ||
1612 (state
>= SCE_HPA_DEFAULT
&& state
<= SCE_HPA_IDENTIFIER
);
1615 static void ColouriseHBAPiece(StyleContext
&sc
, WordList
*keywordlists
[]) {
1616 WordList
&keywordsVBS
= *keywordlists
[2];
1617 if (sc
.state
== SCE_HBA_WORD
) {
1618 if (!IsAWordChar(sc
.ch
)) {
1620 sc
.GetCurrentLowered(s
, sizeof(s
));
1621 if (keywordsVBS
.InList(s
)) {
1622 if (strcmp(s
, "rem") == 0) {
1623 sc
.ChangeState(SCE_HBA_COMMENTLINE
);
1625 sc
.SetState(SCE_HBA_DEFAULT
);
1628 sc
.SetState(SCE_HBA_DEFAULT
);
1631 sc
.ChangeState(SCE_HBA_IDENTIFIER
);
1632 sc
.SetState(SCE_HBA_DEFAULT
);
1635 } else if (sc
.state
== SCE_HBA_NUMBER
) {
1636 if (!IsAWordChar(sc
.ch
)) {
1637 sc
.SetState(SCE_HBA_DEFAULT
);
1639 } else if (sc
.state
== SCE_HBA_STRING
) {
1640 if (sc
.ch
== '\"') {
1641 sc
.ForwardSetState(SCE_HBA_DEFAULT
);
1642 } else if (sc
.ch
== '\r' || sc
.ch
== '\n') {
1643 sc
.ChangeState(SCE_HBA_STRINGEOL
);
1644 sc
.ForwardSetState(SCE_HBA_DEFAULT
);
1646 } else if (sc
.state
== SCE_HBA_COMMENTLINE
) {
1647 if (sc
.ch
== '\r' || sc
.ch
== '\n') {
1648 sc
.SetState(SCE_HBA_DEFAULT
);
1652 if (sc
.state
== SCE_HBA_DEFAULT
) {
1653 if (IsADigit(sc
.ch
) || (sc
.ch
== '.' && IsADigit(sc
.chNext
))) {
1654 sc
.SetState(SCE_HBA_NUMBER
);
1655 } else if (IsAWordStart(sc
.ch
)) {
1656 sc
.SetState(SCE_HBA_WORD
);
1657 } else if (sc
.ch
== '\'') {
1658 sc
.SetState(SCE_HBA_COMMENTLINE
);
1659 } else if (sc
.ch
== '\"') {
1660 sc
.SetState(SCE_HBA_STRING
);
1665 static void ColouriseHTMLPiece(StyleContext
&sc
, WordList
*keywordlists
[]) {
1666 WordList
&keywordsTags
= *keywordlists
[0];
1667 if (sc
.state
== SCE_H_COMMENT
) {
1668 if (sc
.Match("-->")) {
1671 sc
.ForwardSetState(SCE_H_DEFAULT
);
1673 } else if (sc
.state
== SCE_H_ENTITY
) {
1675 sc
.ForwardSetState(SCE_H_DEFAULT
);
1676 } else if (sc
.ch
!= '#' && (sc
.ch
< 0x80) && !isalnum(sc
.ch
)) { // Should check that '#' follows '&', but it is unlikely anyway...
1677 sc
.ChangeState(SCE_H_TAGUNKNOWN
);
1678 sc
.SetState(SCE_H_DEFAULT
);
1680 } else if (sc
.state
== SCE_H_TAGUNKNOWN
) {
1681 if (!ishtmlwordchar(static_cast<char>(sc
.ch
)) && !((sc
.ch
== '/') && (sc
.chPrev
== '<')) && sc
.ch
!= '[') {
1683 sc
.GetCurrentLowered(s
, sizeof(s
));
1685 if (keywordsTags
.InList(s
+ 2)) {
1686 sc
.ChangeState(SCE_H_TAG
);
1689 if (keywordsTags
.InList(s
+ 1)) {
1690 sc
.ChangeState(SCE_H_TAG
);
1694 sc
.ForwardSetState(SCE_H_DEFAULT
);
1695 } else if (sc
.Match('/', '>')) {
1696 sc
.SetState(SCE_H_TAGEND
);
1698 sc
.ForwardSetState(SCE_H_DEFAULT
);
1700 sc
.SetState(SCE_H_OTHER
);
1703 } else if (sc
.state
== SCE_H_ATTRIBUTE
) {
1704 if (!ishtmlwordchar(static_cast<char>(sc
.ch
))) {
1706 sc
.GetCurrentLowered(s
, sizeof(s
));
1707 if (!keywordsTags
.InList(s
)) {
1708 sc
.ChangeState(SCE_H_ATTRIBUTEUNKNOWN
);
1710 sc
.SetState(SCE_H_OTHER
);
1712 } else if (sc
.state
== SCE_H_OTHER
) {
1714 sc
.SetState(SCE_H_TAG
);
1715 sc
.ForwardSetState(SCE_H_DEFAULT
);
1716 } else if (sc
.Match('/', '>')) {
1717 sc
.SetState(SCE_H_TAG
);
1719 sc
.ForwardSetState(SCE_H_DEFAULT
);
1720 } else if (sc
.chPrev
== '=') {
1721 sc
.SetState(SCE_H_VALUE
);
1723 } else if (sc
.state
== SCE_H_DOUBLESTRING
) {
1724 if (sc
.ch
== '\"') {
1725 sc
.ForwardSetState(SCE_H_OTHER
);
1727 } else if (sc
.state
== SCE_H_SINGLESTRING
) {
1728 if (sc
.ch
== '\'') {
1729 sc
.ForwardSetState(SCE_H_OTHER
);
1731 } else if (sc
.state
== SCE_H_NUMBER
) {
1732 if (!IsADigit(sc
.ch
)) {
1733 sc
.SetState(SCE_H_OTHER
);
1737 if (sc
.state
== SCE_H_DEFAULT
) {
1739 if (sc
.Match("<!--"))
1740 sc
.SetState(SCE_H_COMMENT
);
1742 sc
.SetState(SCE_H_TAGUNKNOWN
);
1743 } else if (sc
.ch
== '&') {
1744 sc
.SetState(SCE_H_ENTITY
);
1746 } else if ((sc
.state
== SCE_H_OTHER
) || (sc
.state
== SCE_H_VALUE
)) {
1747 if (sc
.ch
== '\"' && sc
.chPrev
== '=') {
1748 sc
.SetState(SCE_H_DOUBLESTRING
);
1749 } else if (sc
.ch
== '\'' && sc
.chPrev
== '=') {
1750 sc
.SetState(SCE_H_SINGLESTRING
);
1751 } else if (IsADigit(sc
.ch
)) {
1752 sc
.SetState(SCE_H_NUMBER
);
1753 } else if (sc
.ch
== '>') {
1754 sc
.SetState(SCE_H_TAG
);
1755 sc
.ForwardSetState(SCE_H_DEFAULT
);
1756 } else if (ishtmlwordchar(static_cast<char>(sc
.ch
))) {
1757 sc
.SetState(SCE_H_ATTRIBUTE
);
1762 static void ColouriseASPPiece(StyleContext
&sc
, WordList
*keywordlists
[]) {
1763 // Possibly exit current state to either SCE_H_DEFAULT or SCE_HBA_DEFAULT
1764 if ((sc
.state
== SCE_H_ASPAT
|| isASPScript(sc
.state
)) && sc
.Match('%', '>')) {
1765 sc
.SetState(SCE_H_ASP
);
1767 sc
.ForwardSetState(SCE_H_DEFAULT
);
1770 // Handle some ASP script
1771 if (sc
.state
>= SCE_HBA_START
&& sc
.state
<= SCE_HBA_STRINGEOL
) {
1772 ColouriseHBAPiece(sc
, keywordlists
);
1773 } else if (sc
.state
>= SCE_H_DEFAULT
&& sc
.state
<= SCE_H_SGML_BLOCK_DEFAULT
) {
1774 ColouriseHTMLPiece(sc
, keywordlists
);
1777 // Enter new sc.state
1778 if ((sc
.state
== SCE_H_DEFAULT
) || (sc
.state
== SCE_H_TAGUNKNOWN
)) {
1779 if (sc
.Match('<', '%')) {
1780 if (sc
.state
== SCE_H_TAGUNKNOWN
)
1781 sc
.ChangeState(SCE_H_ASP
);
1783 sc
.SetState(SCE_H_ASP
);
1787 sc
.ForwardSetState(SCE_H_ASPAT
);
1792 sc
.SetState(SCE_HBA_DEFAULT
);
1798 static void ColouriseASPDoc(unsigned int startPos
, int length
, int initStyle
, WordList
*keywordlists
[],
1800 // Lexer for HTML requires more lexical states (7 bits worth) than most lexers
1801 StyleContext
sc(startPos
, length
, initStyle
, styler
, 0x7f);
1802 for (; sc
.More(); sc
.Forward()) {
1803 ColouriseASPPiece(sc
, keywordlists
);
1808 static void ColourisePHPPiece(StyleContext
&sc
, WordList
*keywordlists
[]) {
1809 // Possibly exit current state to either SCE_H_DEFAULT or SCE_HBA_DEFAULT
1810 if (sc
.state
>= SCE_HPHP_DEFAULT
&& sc
.state
<= SCE_HPHP_OPERATOR
) {
1811 if (!isPHPStringState(sc
.state
) &&
1812 (sc
.state
!= SCE_HPHP_COMMENT
) &&
1813 (sc
.Match('?', '>'))) {
1814 sc
.SetState(SCE_H_QUESTION
);
1816 sc
.ForwardSetState(SCE_H_DEFAULT
);
1820 if (sc
.state
>= SCE_H_DEFAULT
&& sc
.state
<= SCE_H_SGML_BLOCK_DEFAULT
) {
1821 ColouriseHTMLPiece(sc
, keywordlists
);
1824 // Handle some PHP script
1825 if (sc
.state
== SCE_HPHP_WORD
) {
1826 if (!IsPhpWordChar(static_cast<char>(sc
.ch
))) {
1827 sc
.SetState(SCE_HPHP_DEFAULT
);
1829 } else if (sc
.state
== SCE_HPHP_COMMENTLINE
) {
1830 if (sc
.ch
== '\r' || sc
.ch
== '\n') {
1831 sc
.SetState(SCE_HPHP_DEFAULT
);
1833 } else if (sc
.state
== SCE_HPHP_COMMENT
) {
1834 if (sc
.Match('*', '/')) {
1837 sc
.SetState(SCE_HPHP_DEFAULT
);
1839 } else if (sc
.state
== SCE_HPHP_HSTRING
) {
1840 if (sc
.ch
== '\"') {
1841 sc
.ForwardSetState(SCE_HPHP_DEFAULT
);
1843 } else if (sc
.state
== SCE_HPHP_SIMPLESTRING
) {
1844 if (sc
.ch
== '\'') {
1845 sc
.ForwardSetState(SCE_HPHP_DEFAULT
);
1847 } else if (sc
.state
== SCE_HPHP_VARIABLE
) {
1848 if (!IsPhpWordChar(static_cast<char>(sc
.ch
))) {
1849 sc
.SetState(SCE_HPHP_DEFAULT
);
1851 } else if (sc
.state
== SCE_HPHP_OPERATOR
) {
1852 sc
.SetState(SCE_HPHP_DEFAULT
);
1855 // Enter new sc.state
1856 if ((sc
.state
== SCE_H_DEFAULT
) || (sc
.state
== SCE_H_TAGUNKNOWN
)) {
1857 if (sc
.Match("<?php")) {
1858 sc
.SetState(SCE_H_QUESTION
);
1864 sc
.SetState(SCE_HPHP_DEFAULT
);
1867 if (sc
.state
== SCE_HPHP_DEFAULT
) {
1868 if (IsPhpWordStart(static_cast<char>(sc
.ch
))) {
1869 sc
.SetState(SCE_HPHP_WORD
);
1870 } else if (sc
.ch
== '#') {
1871 sc
.SetState(SCE_HPHP_COMMENTLINE
);
1872 } else if (sc
.Match("<!--")) {
1873 sc
.SetState(SCE_HPHP_COMMENTLINE
);
1874 } else if (sc
.Match('/', '/')) {
1875 sc
.SetState(SCE_HPHP_COMMENTLINE
);
1876 } else if (sc
.Match('/', '*')) {
1877 sc
.SetState(SCE_HPHP_COMMENT
);
1878 } else if (sc
.ch
== '\"') {
1879 sc
.SetState(SCE_HPHP_HSTRING
);
1880 } else if (sc
.ch
== '\'') {
1881 sc
.SetState(SCE_HPHP_SIMPLESTRING
);
1882 } else if (sc
.ch
== '$' && IsPhpWordStart(static_cast<char>(sc
.chNext
))) {
1883 sc
.SetState(SCE_HPHP_VARIABLE
);
1884 } else if (isoperator(static_cast<char>(sc
.ch
))) {
1885 sc
.SetState(SCE_HPHP_OPERATOR
);
1890 static void ColourisePHPDoc(unsigned int startPos
, int length
, int initStyle
, WordList
*keywordlists
[],
1892 // Lexer for HTML requires more lexical states (7 bits worth) than most lexers
1893 StyleContext
sc(startPos
, length
, initStyle
, styler
, 0x7f);
1894 for (; sc
.More(); sc
.Forward()) {
1895 ColourisePHPPiece(sc
, keywordlists
);
1900 static const char * const htmlWordListDesc
[] = {
1901 "HTML elements and attributes",
1902 "JavaScript keywords",
1903 "VBScript keywords",
1906 "SGML and DTD keywords",
1910 LexerModule
lmHTML(SCLEX_HTML
, ColouriseHyperTextDoc
, "hypertext", 0, htmlWordListDesc
);
1911 LexerModule
lmXML(SCLEX_XML
, ColouriseHyperTextDoc
, "xml", 0, htmlWordListDesc
);
1912 LexerModule
lmASP(SCLEX_ASP
, ColouriseASPDoc
, "asp", 0, htmlWordListDesc
);
1913 LexerModule
lmPHP(SCLEX_PHP
, ColourisePHPDoc
, "php", 0, htmlWordListDesc
);