+static bool isASPScript(int state) {
+ return
+ (state >= SCE_HJA_START && state <= SCE_HJA_REGEX) ||
+ (state >= SCE_HBA_START && state <= SCE_HBA_STRINGEOL) ||
+ (state >= SCE_HPA_DEFAULT && state <= SCE_HPA_IDENTIFIER);
+}
+
+static void ColouriseHBAPiece(StyleContext &sc, WordList *keywordlists[]) {
+ WordList &keywordsVBS = *keywordlists[2];
+ if (sc.state == SCE_HBA_WORD) {
+ if (!IsAWordChar(sc.ch)) {
+ char s[100];
+ sc.GetCurrentLowered(s, sizeof(s));
+ if (keywordsVBS.InList(s)) {
+ if (strcmp(s, "rem") == 0) {
+ sc.ChangeState(SCE_HBA_COMMENTLINE);
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_HBA_DEFAULT);
+ }
+ } else {
+ sc.SetState(SCE_HBA_DEFAULT);
+ }
+ } else {
+ sc.ChangeState(SCE_HBA_IDENTIFIER);
+ sc.SetState(SCE_HBA_DEFAULT);
+ }
+ }
+ } else if (sc.state == SCE_HBA_NUMBER) {
+ if (!IsAWordChar(sc.ch)) {
+ sc.SetState(SCE_HBA_DEFAULT);
+ }
+ } else if (sc.state == SCE_HBA_STRING) {
+ if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_HBA_DEFAULT);
+ } else if (sc.ch == '\r' || sc.ch == '\n') {
+ sc.ChangeState(SCE_HBA_STRINGEOL);
+ sc.ForwardSetState(SCE_HBA_DEFAULT);
+ }
+ } else if (sc.state == SCE_HBA_COMMENTLINE) {
+ if (sc.ch == '\r' || sc.ch == '\n') {
+ sc.SetState(SCE_HBA_DEFAULT);
+ }
+ }
+
+ if (sc.state == SCE_HBA_DEFAULT) {
+ if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+ sc.SetState(SCE_HBA_NUMBER);
+ } else if (IsAWordStart(sc.ch)) {
+ sc.SetState(SCE_HBA_WORD);
+ } else if (sc.ch == '\'') {
+ sc.SetState(SCE_HBA_COMMENTLINE);
+ } else if (sc.ch == '\"') {
+ sc.SetState(SCE_HBA_STRING);
+ }
+ }
+}
+
+static void ColouriseHTMLPiece(StyleContext &sc, WordList *keywordlists[]) {
+ WordList &keywordsTags = *keywordlists[0];
+ if (sc.state == SCE_H_COMMENT) {
+ if (sc.Match("-->")) {
+ sc.Forward();
+ sc.Forward();
+ sc.ForwardSetState(SCE_H_DEFAULT);
+ }
+ } else if (sc.state == SCE_H_ENTITY) {
+ if (sc.ch == ';') {
+ sc.ForwardSetState(SCE_H_DEFAULT);
+ } else if (sc.ch != '#' && (sc.ch < 0x80) && !isalnum(sc.ch)) { // Should check that '#' follows '&', but it is unlikely anyway...
+ sc.ChangeState(SCE_H_TAGUNKNOWN);
+ sc.SetState(SCE_H_DEFAULT);
+ }
+ } else if (sc.state == SCE_H_TAGUNKNOWN) {
+ if (!ishtmlwordchar(static_cast<char>(sc.ch)) && !((sc.ch == '/') && (sc.chPrev == '<')) && sc.ch != '[') {
+ char s[100];
+ sc.GetCurrentLowered(s, sizeof(s));
+ if (s[1] == '/') {
+ if (keywordsTags.InList(s + 2)) {
+ sc.ChangeState(SCE_H_TAG);
+ }
+ } else {
+ if (keywordsTags.InList(s + 1)) {
+ sc.ChangeState(SCE_H_TAG);
+ }
+ }
+ if (sc.ch == '>') {
+ sc.ForwardSetState(SCE_H_DEFAULT);
+ } else if (sc.Match('/', '>')) {
+ sc.SetState(SCE_H_TAGEND);
+ sc.Forward();
+ sc.ForwardSetState(SCE_H_DEFAULT);
+ } else {
+ sc.SetState(SCE_H_OTHER);
+ }
+ }
+ } else if (sc.state == SCE_H_ATTRIBUTE) {
+ if (!ishtmlwordchar(static_cast<char>(sc.ch))) {
+ char s[100];
+ sc.GetCurrentLowered(s, sizeof(s));
+ if (!keywordsTags.InList(s)) {
+ sc.ChangeState(SCE_H_ATTRIBUTEUNKNOWN);
+ }
+ sc.SetState(SCE_H_OTHER);
+ }
+ } else if (sc.state == SCE_H_OTHER) {
+ if (sc.ch == '>') {
+ sc.SetState(SCE_H_TAG);
+ sc.ForwardSetState(SCE_H_DEFAULT);
+ } else if (sc.Match('/', '>')) {
+ sc.SetState(SCE_H_TAG);
+ sc.Forward();
+ sc.ForwardSetState(SCE_H_DEFAULT);
+ } else if (sc.chPrev == '=') {
+ sc.SetState(SCE_H_VALUE);
+ }
+ } else if (sc.state == SCE_H_DOUBLESTRING) {
+ if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_H_OTHER);
+ }
+ } else if (sc.state == SCE_H_SINGLESTRING) {
+ if (sc.ch == '\'') {
+ sc.ForwardSetState(SCE_H_OTHER);
+ }
+ } else if (sc.state == SCE_H_NUMBER) {
+ if (!IsADigit(sc.ch)) {
+ sc.SetState(SCE_H_OTHER);
+ }
+ }
+
+ if (sc.state == SCE_H_DEFAULT) {
+ if (sc.ch == '<') {
+ if (sc.Match("<!--"))
+ sc.SetState(SCE_H_COMMENT);
+ else
+ sc.SetState(SCE_H_TAGUNKNOWN);
+ } else if (sc.ch == '&') {
+ sc.SetState(SCE_H_ENTITY);
+ }
+ } else if ((sc.state == SCE_H_OTHER) || (sc.state == SCE_H_VALUE)) {
+ if (sc.ch == '\"') {
+ sc.SetState(SCE_H_DOUBLESTRING);
+ } else if (sc.ch == '\'') {
+ sc.SetState(SCE_H_SINGLESTRING);
+ } else if (IsADigit(sc.ch)) {
+ sc.SetState(SCE_H_NUMBER);
+ } else if (sc.ch == '>') {
+ sc.SetState(SCE_H_TAG);
+ sc.ForwardSetState(SCE_H_DEFAULT);
+ } else if (ishtmlwordchar(static_cast<char>(sc.ch))) {
+ sc.SetState(SCE_H_ATTRIBUTE);
+ }
+ }
+}
+
+static void ColouriseASPPiece(StyleContext &sc, WordList *keywordlists[]) {
+ // Possibly exit current state to either SCE_H_DEFAULT or SCE_HBA_DEFAULT
+ if ((sc.state == SCE_H_ASPAT || isASPScript(sc.state)) && sc.Match('%', '>')) {
+ sc.SetState(SCE_H_ASP);
+ sc.Forward();
+ sc.ForwardSetState(SCE_H_DEFAULT);
+ }
+
+ // Handle some ASP script
+ if (sc.state >= SCE_HBA_START && sc.state <= SCE_HBA_STRINGEOL) {
+ ColouriseHBAPiece(sc, keywordlists);
+ } else if (sc.state >= SCE_H_DEFAULT && sc.state <= SCE_H_SGML_BLOCK_DEFAULT) {
+ ColouriseHTMLPiece(sc, keywordlists);
+ }
+
+ // Enter new sc.state
+ if ((sc.state == SCE_H_DEFAULT) || (sc.state == SCE_H_TAGUNKNOWN)) {
+ if (sc.Match('<', '%')) {
+ if (sc.state == SCE_H_TAGUNKNOWN)
+ sc.ChangeState(SCE_H_ASP);
+ else
+ sc.SetState(SCE_H_ASP);
+ sc.Forward();
+ sc.Forward();
+ if (sc.ch == '@') {
+ sc.ForwardSetState(SCE_H_ASPAT);
+ } else {
+ if (sc.ch == '=') {
+ sc.Forward();
+ }
+ sc.SetState(SCE_HBA_DEFAULT);
+ }
+ }
+ }
+}
+
+static void ColouriseASPDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+ // Lexer for HTML requires more lexical states (7 bits worth) than most lexers
+ StyleContext sc(startPos, length, initStyle, styler, 0x7f);
+ for (; sc.More(); sc.Forward()) {
+ ColouriseASPPiece(sc, keywordlists);
+ }
+ sc.Complete();
+}
+
+static void ColourisePHPPiece(StyleContext &sc, WordList *keywordlists[]) {
+ // Possibly exit current state to either SCE_H_DEFAULT or SCE_HBA_DEFAULT
+ if (sc.state >= SCE_HPHP_DEFAULT && sc.state <= SCE_HPHP_OPERATOR) {
+ if (!isPHPStringState(sc.state) &&
+ (sc.state != SCE_HPHP_COMMENT) &&
+ (sc.Match('?', '>'))) {
+ sc.SetState(SCE_H_QUESTION);
+ sc.Forward();
+ sc.ForwardSetState(SCE_H_DEFAULT);
+ }
+ }
+
+ if (sc.state >= SCE_H_DEFAULT && sc.state <= SCE_H_SGML_BLOCK_DEFAULT) {
+ ColouriseHTMLPiece(sc, keywordlists);
+ }
+
+ // Handle some PHP script
+ if (sc.state == SCE_HPHP_WORD) {
+ if (!IsAWordStart(sc.ch)) {
+ sc.SetState(SCE_HPHP_DEFAULT);
+ }
+ } else if (sc.state == SCE_HPHP_COMMENTLINE) {
+ if (sc.ch == '\r' || sc.ch == '\n') {
+ sc.SetState(SCE_HPHP_DEFAULT);
+ }
+ } else if (sc.state == SCE_HPHP_COMMENT) {
+ if (sc.Match('*', '/')) {
+ sc.Forward();
+ sc.Forward();
+ sc.SetState(SCE_HPHP_DEFAULT);
+ }
+ } else if (sc.state == SCE_HPHP_HSTRING) {
+ if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_HPHP_DEFAULT);
+ }
+ } else if (sc.state == SCE_HPHP_SIMPLESTRING) {
+ if (sc.ch == '\'') {
+ sc.ForwardSetState(SCE_HPHP_DEFAULT);
+ }
+ } else if (sc.state == SCE_HPHP_VARIABLE) {
+ if (!IsAWordStart(sc.ch)) {
+ sc.SetState(SCE_HPHP_DEFAULT);
+ }
+ } else if (sc.state == SCE_HPHP_OPERATOR) {
+ sc.SetState(SCE_HPHP_DEFAULT);
+ }
+
+ // Enter new sc.state
+ if ((sc.state == SCE_H_DEFAULT) || (sc.state == SCE_H_TAGUNKNOWN)) {
+ if (sc.Match("<?php")) {
+ sc.SetState(SCE_H_QUESTION);
+ sc.Forward();
+ sc.Forward();
+ sc.Forward();
+ sc.Forward();
+ sc.Forward();
+ sc.SetState(SCE_HPHP_DEFAULT);
+ }
+ }
+ if (sc.state == SCE_HPHP_DEFAULT) {
+ if (IsAWordStart(sc.ch)) {
+ sc.SetState(SCE_HPHP_WORD);
+ } else if (sc.ch == '#') {
+ sc.SetState(SCE_HPHP_COMMENTLINE);
+ } else if (sc.Match("<!--")) {
+ sc.SetState(SCE_HPHP_COMMENTLINE);
+ } else if (sc.Match('/', '/')) {
+ sc.SetState(SCE_HPHP_COMMENTLINE);
+ } else if (sc.Match('/', '*')) {
+ sc.SetState(SCE_HPHP_COMMENT);
+ } else if (sc.ch == '\"') {
+ sc.SetState(SCE_HPHP_HSTRING);
+ } else if (sc.ch == '\'') {
+ sc.SetState(SCE_HPHP_SIMPLESTRING);
+ } else if (sc.ch == '$') {
+ sc.SetState(SCE_HPHP_VARIABLE);
+ } else if (isoperator(static_cast<char>(sc.ch))) {
+ sc.SetState(SCE_HPHP_OPERATOR);
+ }
+ }
+}
+
+static void ColourisePHPDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+ // Lexer for HTML requires more lexical states (7 bits worth) than most lexers
+ StyleContext sc(startPos, length, initStyle, styler, 0x7f);
+ for (; sc.More(); sc.Forward()) {
+ ColourisePHPPiece(sc, keywordlists);
+ }
+ sc.Complete();
+}
+