📄 lexhtml.cxx.svn-base
字号:
}
static inline bool IsPhpWordStart(const unsigned char ch) {
return (isascii(ch) && (isalpha(ch) || (ch == '_'))) || (ch >= 0x7f);
}
static inline bool IsPhpWordChar(char ch) {
return IsADigit(ch) || IsPhpWordStart(ch);
}
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;
// Don
//lineState |= styler.GetPropertyInt("asp.default.language", eScriptJS) << 4;
lineState |= styler.GetPropertyInt("asp.default.language", eScriptVBS) << 4;
//nod
}
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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -