aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/LexHTML.cxx
diff options
context:
space:
mode:
authornyamatongwe <unknown>2009-10-09 02:12:33 +0000
committernyamatongwe <unknown>2009-10-09 02:12:33 +0000
commit310b2e88d1f4ded7dce3abd6b08b2f3b8fc2faeb (patch)
treebb2882814459aa5c0991d232e0fbbf1aa3268d7a /src/LexHTML.cxx
parent62b04a97428eb3ebe4ef094c6fb15d0b96c762d6 (diff)
downloadscintilla-mirror-310b2e88d1f4ded7dce3abd6b08b2f3b8fc2faeb.tar.gz
Support for the Mako template language implemented.
From Stephan Deibel at Wingware.
Diffstat (limited to 'src/LexHTML.cxx')
-rw-r--r--src/LexHTML.cxx139
1 files changed, 133 insertions, 6 deletions
diff --git a/src/LexHTML.cxx b/src/LexHTML.cxx
index a8d7e2711..6038326e3 100644
--- a/src/LexHTML.cxx
+++ b/src/LexHTML.cxx
@@ -69,6 +69,22 @@ static void GetTextSegment(Accessor &styler, unsigned int start, unsigned int en
s[i] = '\0';
}
+static const char *GetNextWord(Accessor &styler, unsigned int start, char *s, size_t sLen) {
+
+ size_t i = 0;
+ for (; i < sLen-1; i++) {
+ char ch = static_cast<char>(styler.SafeGetCharAt(start + i));
+ if ((i == 0) && !IsAWordStart(ch))
+ break;
+ if ((i > 0) && !IsAWordChar(ch))
+ break;
+ s[i] = ch;
+ }
+ s[i] = '\0';
+
+ return s;
+}
+
static script_type segIsScriptingIndicator(Accessor &styler, unsigned int start, unsigned int end, script_type prevValue) {
char s[100];
GetTextSegment(styler, start, end, s, sizeof(s));
@@ -474,6 +490,23 @@ static bool isOKBeforeRE(int ch) {
return (ch == '(') || (ch == '=') || (ch == ',');
}
+static bool isMakoBlockEnd(const int ch, const int chNext, const char *blockType) {
+ if (strlen(blockType) == 0) {
+ return ((ch == '%') && (chNext == '>'));
+ } else if ((0 == strcmp(blockType, "inherit")) ||
+ (0 == strcmp(blockType, "namespace")) ||
+ (0 == strcmp(blockType, "include")) ||
+ (0 == strcmp(blockType, "page"))) {
+ return ((ch == '/') && (chNext == '>'));
+ } else if (0 == strcmp(blockType, "%")) {
+ return isLineEnd(ch);
+ } else if (0 == strcmp(blockType, "{")) {
+ return ch == '}';
+ } else {
+ return (ch == '>');
+ }
+}
+
static bool isPHPStringState(int state) {
return
(state == SCE_HPHP_HSTRING) ||
@@ -542,10 +575,14 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
styler.StartAt(startPos, static_cast<char>(STYLE_MAX));
char prevWord[200];
prevWord[0] = '\0';
+ char nextWord[200];
+ nextWord[0] = '\0';
char phpStringDelimiter[200]; // PHP is not limited in length, we are
phpStringDelimiter[0] = '\0';
int StateToPrint = initStyle;
int state = stateForPrintState(StateToPrint);
+ char makoBlockType[200];
+ makoBlockType[0] = '\0';
// 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)) {
@@ -627,6 +664,10 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
// Set to 0 to disable scripts in XML.
const bool allowScripts = styler.GetPropertyInt("lexer.xml.allow.scripts", 1) != 0;
+ // property lexer.html.mako
+ // Set to 1 to enable the mako template language.
+ const bool isMako = styler.GetPropertyInt("lexer.html.mako", 0) != 0;
+
const CharacterSet setHTMLWord(CharacterSet::setAlphaNum, ".-_:!#", 0x80, true);
const CharacterSet setTagContinue(CharacterSet::setAlphaNum, ".-_:!#[", 0x80, true);
const CharacterSet setAttributeContinue(CharacterSet::setAlphaNum, ".-_:!#/", 0x80, true);
@@ -634,6 +675,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
int levelCurrent = levelPrev;
int visibleChars = 0;
+ int lineStartVisibleChars = 0;
int chPrev = ' ';
int ch = ' ';
@@ -674,6 +716,8 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
if ((!IsASpace(ch) || !foldCompact) && fold)
visibleChars++;
+ if (!IsASpace(ch))
+ lineStartVisibleChars++;
// decide what is the current state to print (depending of the script tag)
StateToPrint = statePrintForState(state, inScriptType);
@@ -742,6 +786,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
levelPrev = levelCurrent;
}
lineCurrent++;
+ lineStartVisibleChars = 0;
styler.SetLineState(lineCurrent,
((inScriptType & 0x03) << 0) |
((tagOpened & 0x01) << 2) |
@@ -751,6 +796,11 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
((beforePreProc & 0xFF) << 12));
}
+ // Allow falling through to mako handling code if newline is going to end a block
+ if (((ch == '\r' && chNext != '\n') || (ch == '\n')) &&
+ (!isMako || (0 != strcmp(makoBlockType, "%")))) {
+ }
+
// 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)
@@ -835,8 +885,54 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
continue;
}
+ // handle the start Mako template Python code
+ else if (isMako && scriptLanguage == eScriptNone && ((ch == '<' && chNext == '%') ||
+ (lineStartVisibleChars == 1 && ch == '%') ||
+ (ch == '$' && chNext == '{') ||
+ (ch == '<' && chNext == '/' && chNext2 == '%'))) {
+ if (ch == '%')
+ strcpy(makoBlockType, "%");
+ else if (ch == '$')
+ strcpy(makoBlockType, "{");
+ else if (chNext == '/')
+ GetNextWord(styler, i+3, makoBlockType, sizeof(makoBlockType));
+ else
+ GetNextWord(styler, i+2, makoBlockType, sizeof(makoBlockType));
+ styler.ColourTo(i - 1, StateToPrint);
+ beforePreProc = state;
+ if (inScriptType == eNonHtmlScript)
+ inScriptType = eNonHtmlScriptPreProc;
+ else
+ inScriptType = eNonHtmlPreProc;
+
+ if (chNext == '/') {
+ i += 2;
+ visibleChars += 2;
+ } else if (ch != '%') {
+ i++;
+ visibleChars++;
+ }
+ state = SCE_HP_START;
+ scriptLanguage = eScriptPython;
+ styler.ColourTo(i, SCE_H_ASP);
+ if (foldHTMLPreprocessor && ch == '<')
+ levelCurrent++;
+
+ if (ch != '%' && ch != '$') {
+ i += strlen(makoBlockType);
+ visibleChars += strlen(makoBlockType);
+ if (keywords4.InList(makoBlockType))
+ styler.ColourTo(i, SCE_HP_WORD);
+ else
+ styler.ColourTo(i, SCE_H_TAGUNKNOWN);
+ }
+
+ ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
+ continue;
+ }
+
// handle the start of ASP pre-processor = Non-HTML
- else if (!isCommentASPState(state) && (ch == '<') && (chNext == '%') && !isPHPStringState(state)) {
+ else if (!isMako && !isCommentASPState(state) && (ch == '<') && (chNext == '%') && !isPHPStringState(state)) {
styler.ColourTo(i - 1, StateToPrint);
beforePreProc = state;
if (inScriptType == eNonHtmlScript)
@@ -901,12 +997,43 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
continue;
}
+ // handle the end of Mako Python code
+ else if (isMako &&
+ ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) &&
+ (scriptLanguage != eScriptNone) && stateAllowsTermination(state) &&
+ isMakoBlockEnd(ch, chNext, makoBlockType)) {
+ if (state == SCE_H_ASPAT) {
+ aspScript = segIsScriptingIndicator(styler,
+ styler.GetStartSegment(), i - 1, aspScript);
+ }
+ if (state == SCE_HP_WORD) {
+ classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType);
+ } else {
+ styler.ColourTo(i - 1, StateToPrint);
+ }
+ if (0 != strcmp(makoBlockType, "%") && (0 != strcmp(makoBlockType, "{")) && ch != '>') {
+ i++;
+ visibleChars++;
+ }
+ if (0 != strcmp(makoBlockType, "%")) {
+ styler.ColourTo(i, SCE_H_ASP);
+ }
+ state = beforePreProc;
+ if (inScriptType == eNonHtmlScriptPreProc)
+ inScriptType = eNonHtmlScript;
+ else
+ inScriptType = eHtml;
+ if (foldHTMLPreprocessor && ch != '\n' && ch != '\r') {
+ levelCurrent--;
+ }
+ scriptLanguage = eScriptNone;
+ continue;
+ }
+
// handle the end of a pre-processor = Non-HTML
- else if ((
- ((inScriptType == eNonHtmlPreProc)
- || (inScriptType == eNonHtmlScriptPreProc)) && (
- ((scriptLanguage != eScriptNone) && stateAllowsTermination(state) && ((ch == '%') || (ch == '?')))
- ) && (chNext == '>')) ||
+ else if ((!isMako && ((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,