📄 lexhtml.cxx
字号:
static bool InTagState(int state) { return state == SCE_H_TAG || state == SCE_H_TAGUNKNOWN || state == SCE_H_SCRIPT || state == SCE_H_ATTRIBUTE || state == SCE_H_ATTRIBUTEUNKNOWN || state == SCE_H_NUMBER || state == SCE_H_OTHER || state == SCE_H_DOUBLESTRING || state == SCE_H_SINGLESTRING;}static bool IsCommentState(const int state) { return state == SCE_H_COMMENT || state == SCE_H_SGML_COMMENT;}static bool IsScriptCommentState(const int state) { return state == SCE_HJ_COMMENT || state == SCE_HJ_COMMENTLINE || state == SCE_HJA_COMMENT || state == SCE_HJA_COMMENTLINE || state == SCE_HB_COMMENTLINE || state == SCE_HBA_COMMENTLINE;}static bool isLineEnd(char ch) { return ch == '\r' || ch == '\n';}static bool isOKBeforeRE(char ch) { return (ch == '(') || (ch == '=') || (ch == ',');}static bool isPHPStringState(int state) { return (state == SCE_HPHP_HSTRING) || (state == SCE_HPHP_SIMPLESTRING) || (state == SCE_HPHP_HSTRING_VARIABLE) || (state == SCE_HPHP_COMPLEX_VARIABLE);}static int FindPhpStringDelimiter(char *phpStringDelimiter, const int phpStringDelimiterSize, int i, const int lengthDoc, Accessor &styler) { int j; while (i < lengthDoc && (styler[i] == ' ' || styler[i] == '\t')) i++; phpStringDelimiter[0] = '\n'; for (j = i; j < lengthDoc && styler[j] != '\n' && styler[j] != '\r'; j++) { if (j - i < phpStringDelimiterSize - 2) phpStringDelimiter[j-i+1] = styler[j]; else i++; } phpStringDelimiter[j-i+1] = '\0'; return j;}static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; WordList &keywords4 = *keywordlists[3]; WordList &keywords5 = *keywordlists[4]; WordList &keywords6 = *keywordlists[5]; // SGML (DTD) keywords // Lexer for HTML requires more lexical states (7 bits worth) than most lexers styler.StartAt(startPos, STYLE_MAX); char prevWord[200]; prevWord[0] = '\0'; char phpStringDelimiter[200]; // PHP is not limited in length, we are phpStringDelimiter[0] = '\0'; int StateToPrint = initStyle; int state = stateForPrintState(StateToPrint); // If inside a tag, it may be a script tag, so reread from the start to ensure any language tags are seen if (InTagState(state)) { while ((startPos > 0) && (InTagState(styler.StyleAt(startPos - 1)))) { startPos--; length++; } state = SCE_H_DEFAULT; } // String can be heredoc, must find a delimiter first while (startPos > 0 && isPHPStringState(state) && state != SCE_HPHP_SIMPLESTRING) { startPos--; length++; state = styler.StyleAt(startPos); } styler.StartAt(startPos, STYLE_MAX); int lineCurrent = styler.GetLine(startPos); int lineState; if (lineCurrent > 0) { lineState = styler.GetLineState(lineCurrent); } else { // Default client and ASP scripting language is JavaScript lineState = eScriptJS << 8; lineState |= styler.GetPropertyInt("asp.default.language", eScriptJS) << 4; } script_mode inScriptType = script_mode((lineState >> 0) & 0x03); // 2 bits of scripting mode bool tagOpened = (lineState >> 2) & 0x01; // 1 bit to know if we are in an opened tag bool tagClosing = (lineState >> 3) & 0x01; // 1 bit to know if we are in a closing tag bool tagDontFold = false; //some HTML tags should not be folded script_type aspScript = script_type((lineState >> 4) & 0x0F); // 4 bits of script name script_type clientScript = script_type((lineState >> 8) & 0x0F); // 4 bits of script name int beforePreProc = (lineState >> 12) & 0xFF; // 8 bits of state script_type scriptLanguage = ScriptOfState(state); const bool foldHTML = styler.GetPropertyInt("fold.html", 0) != 0; const bool fold = foldHTML && styler.GetPropertyInt("fold", 0); const bool foldHTMLPreprocessor = foldHTML && styler.GetPropertyInt("fold.html.preprocessor", 1); const bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; const bool caseSensitive = styler.GetPropertyInt("html.tags.case.sensitive", 0) != 0; int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; int visibleChars = 0; char chPrev = ' '; char ch = ' '; char chPrevNonWhite = ' '; // look back to set chPrevNonWhite properly for better regex colouring if (scriptLanguage == eScriptJS && startPos > 0) { int back = startPos; int style = 0; while (--back) { style = styler.StyleAt(back); if (style < SCE_HJ_DEFAULT || style > SCE_HJ_COMMENTDOC) // includes SCE_HJ_COMMENT & SCE_HJ_COMMENTLINE break; } if (style == SCE_HJ_SYMBOLS) { chPrevNonWhite = styler.SafeGetCharAt(back); } } styler.StartSegment(startPos); const int lengthDoc = startPos + length; for (int i = startPos; i < lengthDoc; i++) { const char chPrev2 = chPrev; chPrev = ch; if (!isspacechar(ch) && state != SCE_HJ_COMMENT && state != SCE_HJ_COMMENTLINE && state != SCE_HJ_COMMENTDOC) chPrevNonWhite = ch; ch = styler[i]; char chNext = styler.SafeGetCharAt(i + 1); const char chNext2 = styler.SafeGetCharAt(i + 2); // Handle DBCS codepages if (styler.IsLeadByte(ch)) { chPrev = ' '; i += 1; continue; } if ((!isspacechar(ch) || !foldCompact) && fold) visibleChars++; // decide what is the current state to print (depending of the script tag) StateToPrint = statePrintForState(state, inScriptType); // handle script folding if (fold) { switch (scriptLanguage) { case eScriptJS: case eScriptPHP: //not currently supported case eScriptVBS: if ((state != SCE_HPHP_COMMENT) && (state != SCE_HPHP_COMMENTLINE) && (state != SCE_HJ_COMMENT) && (state != SCE_HJ_COMMENTLINE) && (state != SCE_HJ_COMMENTDOC) && (!isStringState(state))) { //Platform::DebugPrintf("state=%d, StateToPrint=%d, initStyle=%d\n", state, StateToPrint, initStyle); //if ((state == SCE_HPHP_OPERATOR) || (state == SCE_HPHP_DEFAULT) || (state == SCE_HJ_SYMBOLS) || (state == SCE_HJ_START) || (state == SCE_HJ_DEFAULT)) { if ((ch == '{') || (ch == '}')) { levelCurrent += (ch == '{') ? 1 : -1; } } break; case eScriptPython: if (state != SCE_HP_COMMENTLINE) { if ((ch == ':') && ((chNext == '\n') || (chNext == '\r' && chNext2 == '\n'))) { levelCurrent++; } else if ((ch == '\n') && !((chNext == '\r') && (chNext2 == '\n')) && (chNext != '\n')) { // check if the number of tabs is lower than the level int Findlevel = (levelCurrent & ~SC_FOLDLEVELBASE) * 8; for (int j = 0; Findlevel > 0; j++) { char chTmp = styler.SafeGetCharAt(i + j + 1); if (chTmp == '\t') { Findlevel -= 8; } else if (chTmp == ' ') { Findlevel--; } else { break; } } if (Findlevel > 0) { levelCurrent -= Findlevel / 8; if (Findlevel % 8) levelCurrent--; } } } break; default: break; } } if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix) // Avoid triggering two times on Dos/Win // New line -> record any line state onto /next/ line if (fold) { int lev = levelPrev; if (visibleChars == 0) lev |= SC_FOLDLEVELWHITEFLAG; if ((levelCurrent > levelPrev) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; styler.SetLevel(lineCurrent, lev); visibleChars = 0; levelPrev = levelCurrent; } lineCurrent++; styler.SetLineState(lineCurrent, ((inScriptType & 0x03) << 0) | ((tagOpened & 0x01) << 2) | ((tagClosing & 0x01) << 3) | ((aspScript & 0x0F) << 4) | ((clientScript & 0x0F) << 8) | ((beforePreProc & 0xFF) << 12)); } // generic end of script processing else if ((inScriptType == eNonHtmlScript) && (ch == '<') && (chNext == '/')) { // Check if it's the end of the script tag (or any other HTML tag) switch (state) { // in these cases, you can embed HTML tags (to confirm !!!!!!!!!!!!!!!!!!!!!!) case SCE_H_DOUBLESTRING: case SCE_H_SINGLESTRING: case SCE_HJ_COMMENT: case SCE_HJ_COMMENTDOC: //case SCE_HJ_COMMENTLINE: // removed as this is a common thing done to hide // the end of script marker from some JS interpreters. case SCE_HJ_DOUBLESTRING: case SCE_HJ_SINGLESTRING: case SCE_HJ_REGEX: case SCE_HB_STRING: case SCE_HP_STRING: case SCE_HP_TRIPLE: case SCE_HP_TRIPLEDOUBLE: break; default : // check if the closing tag is a script tag if (state == SCE_HJ_COMMENTLINE) { char tag[7]; // room for the <script> tag char chr; // current char int j=0; chr = styler.SafeGetCharAt(i+2); while (j < 6 && !isspacechar(chr)) { tag[j++] = static_cast<char>(MakeLowerCase(chr)); chr = styler.SafeGetCharAt(i+2+j); } tag[j] = '\0'; if (strcmp(tag, "script") != 0) break; } // closing tag of the script (it's a closing HTML tag anyway) styler.ColourTo(i - 1, StateToPrint); state = SCE_H_TAGUNKNOWN; inScriptType = eHtml; scriptLanguage = eScriptNone; clientScript = eScriptJS; i += 2; visibleChars += 2; tagClosing = true; continue; } } ///////////////////////////////////// // handle the start of PHP pre-processor = Non-HTML else if ((state != SCE_H_ASPAT) && !isPHPStringState(state) && (state != SCE_HPHP_COMMENT) && (ch == '<') && (chNext == '?') && !IsScriptCommentState(state) ) { scriptLanguage = segIsScriptingIndicator(styler, i + 2, i + 10, eScriptPHP); if (scriptLanguage != eScriptPHP && isStringState(state)) continue; styler.ColourTo(i - 1, StateToPrint); beforePreProc = state; i++; visibleChars++; i += PrintScriptingIndicatorOffset(styler, styler.GetStartSegment() + 2, i + 10); if (scriptLanguage == eScriptXML) styler.ColourTo(i, SCE_H_XMLSTART); else styler.ColourTo(i, SCE_H_QUESTION); state = StateForScript(scriptLanguage); if (inScriptType == eNonHtmlScript) inScriptType = eNonHtmlScriptPreProc; else inScriptType = eNonHtmlPreProc; // Fold whole script, but not if the XML first tag (all XML-like tags in this case) if (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) { levelCurrent++; } // should be better ch = styler.SafeGetCharAt(i); continue; } // handle the start of ASP pre-processor = Non-HTML else if (!isCommentASPState(state) && (ch == '<') && (chNext == '%') && !isPHPStringState(state)) { styler.ColourTo(i - 1, StateToPrint); beforePreProc = state; if (inScriptType == eNonHtmlScript) inScriptType = eNonHtmlScriptPreProc; else inScriptType = eNonHtmlPreProc; if (chNext2 == '@') { i += 2; // place as if it was the second next char treated visibleChars += 2; state = SCE_H_ASPAT; } else if ((chNext2 == '-') && (styler.SafeGetCharAt(i + 3) == '-')) { styler.ColourTo(i + 3, SCE_H_ASP); state = SCE_H_XCCOMMENT; scriptLanguage = eScriptVBS; continue; } else { if (chNext2 == '=') { i += 2; // place as if it was the second next char treated visibleChars += 2; } else { i++; // place as if it was the next char treated visibleChars++; } state = StateForScript(aspScript); } scriptLanguage = eScriptVBS; styler.ColourTo(i, SCE_H_ASP); // fold whole script if (foldHTMLPreprocessor) levelCurrent++; // should be better ch = styler.SafeGetCharAt(i); continue; } ///////////////////////////////////// // handle the start of SGML language (DTD) else if (((scriptLanguage == eScriptNone) || (scriptLanguage == eScriptXML)) && (chPrev == '<') && (ch == '!') && (StateToPrint != SCE_H_CDATA) && (!IsCommentState(StateToPrint)) && (!IsScriptCommentState(StateToPrint)) ) { beforePreProc = state; styler.ColourTo(i - 2, StateToPrint); if ((chNext == '-') && (chNext2 == '-')) { state = SCE_H_COMMENT; // wait for a pending command styler.ColourTo(i + 2, SCE_H_COMMENT); i += 2; // follow styling after the -- } else if (isWordCdata(i + 1, i + 7, styler)) { state = SCE_H_CDATA; } else { styler.ColourTo(i, SCE_H_SGML_DEFAULT); // <! is default scriptLanguage = eScriptSGML; state = SCE_H_SGML_COMMAND; // wait for a pending command } // fold whole tag (-- when closing the tag) if (foldHTMLPreprocessor) levelCurrent++; continue; } // handle the end of a pre-processor = Non-HTML else if (( ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) && ( ((scriptLanguage != eScriptNone) && stateAllowsTermination(state) && ((ch == '%') || (ch == '?'))) ) && (chNext == '>')) || ((scriptLanguage == eScriptSGML) && (ch == '>') && (state != SCE_H_SGML_COMMENT))) { if (state == SCE_H_ASPAT) { aspScript = segIsScriptingIndicator(styler, styler.GetStartSegment(), i - 1, aspScript); } // Bounce out of any ASP mode switch (state) { case SCE_HJ_WORD: classifyWordHTJS(styler.GetStartSegment(), i - 1, keywords2, styler, inScriptType); break; case SCE_HB_WORD: classifyWordHTVB(styler.GetStartSegment(), i - 1, keywords3, styler, inScriptType); break; case SCE_HP_WORD: classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType); break; case SCE_HPHP_WORD: classifyWordHTPHP(styler.GetStartSegment(), i - 1, keywords5, styler); break; case SCE_H_XCCOMMENT: styler.ColourTo(i - 1, state); break; default : styler.ColourTo(i - 1, StateToPrint); break; } if (scriptLanguage != eScriptSGML) { i++; visibleChars++; } if (ch == '%') styler.ColourTo(i, SCE_H_ASP);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -