1 ///////////////////////////////////////////////////////////////////////////
4 // Updated: 19-Jul-1998
6 // Copyright: Ferdinand Prantl, portions by Stcherbatchenko Andrei
7 // E-mail: prantl@ff.cuni.cz
9 // HTML syntax highlighing definition
11 // You are free to use or modify this code to the following restrictions:
12 // - Acknowledge me somewhere in your about box, simple "Parts of code by.."
13 // will be enough. If you can't (or don't want to), contact me personally.
14 // - LEAVE THIS HEADER INTACT
15 ////////////////////////////////////////////////////////////////////////////
18 #include "crystallineparser.h"
19 #include "../SyntaxColors.h"
20 #include "../utils/string_util.h"
27 CrystalLineParser::ParseLineHtmlEx (unsigned dwCookie, const TCHAR *pszChars, int nLength, TEXTBLOCK * pBuf, int &nActualItems, int nEmbeddedLanguage)
30 return dwCookie & (COOKIE_EXT_COMMENT|COOKIE_EXT_USER1|COOKIE_ELEMENT|COOKIE_BLOCK_SCRIPT|COOKIE_BLOCK_STYLE|COOKIE_EXT_DEFINITION|COOKIE_EXT_VALUE);
32 bool bRedefineBlock = true;
33 if (!(dwCookie & COOKIE_ELEMENT))
34 bRedefineBlock = !(dwCookie & (COOKIE_EXT_USER1|COOKIE_BLOCK_SCRIPT|COOKIE_BLOCK_STYLE));
35 bool bDecIndex = false;
39 for (I = 0;; nPrevI = I, I = static_cast<int>(::CharNext(pszChars+I) - pszChars))
43 // CharNext did not advance, so we're at the end of the string
44 // and we already handled this character, so stop
53 if (dwCookie & COOKIE_EXT_COMMENT)
55 DEFINE_BLOCK (nPos, COLORINDEX_COMMENT);
57 else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING))
59 DEFINE_BLOCK (nPos, COLORINDEX_STRING);
61 else if (dwCookie & COOKIE_ELEMENT)
63 DEFINE_BLOCK (nPos, COLORINDEX_PREPROCESSOR);
67 if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.')
69 DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT);
73 DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR);
74 bRedefineBlock = true;
79 bRedefineBlock = false;
84 // Can be bigger than length if there is binary data
85 // See bug #1474782 Crash when comparing SQL with with binary data
86 if (I >= nLength || pszChars[I] == 0)
89 if (!(dwCookie & COOKIE_ELEMENT) && (dwCookie & (COOKIE_EXT_USER1|COOKIE_BLOCK_SCRIPT|COOKIE_BLOCK_STYLE)))
91 if (dwCookie & COOKIE_BLOCK_SCRIPT)
93 const TCHAR *pszEnd = _tcsstr(pszChars + I, _T("</script>"));
94 int nextI = pszEnd ? static_cast<int>(pszEnd - pszChars) : nLength;
95 dwCookie = ParseLineJavaScript(dwCookie & ~COOKIE_BLOCK_SCRIPT, pszChars + I, nextI - I, pBuf, nActualItems);
97 dwCookie |= COOKIE_BLOCK_SCRIPT;
101 bRedefineBlock = true;
105 else if (dwCookie & COOKIE_BLOCK_STYLE)
107 const TCHAR *pszEnd = _tcsstr(pszChars + I, _T("</style>"));
108 int nextI = pszEnd ? static_cast<int>(pszEnd - pszChars) : nLength;
109 dwCookie = ParseLineCss(dwCookie & ~COOKIE_BLOCK_STYLE, pszChars + I, nextI - I, pBuf, nActualItems);
111 dwCookie |= COOKIE_BLOCK_STYLE;
115 bRedefineBlock = true;
119 else if ((dwCookie & COOKIE_EXT_USER1))
121 const TCHAR *pszEnd = _tcsstr(pszChars + I, _T("?>"));
123 pszEnd = _tcsstr(pszChars + I, _T("%>"));
124 int nextI = pszEnd ? static_cast<int>(pszEnd - pszChars) : nLength;
125 unsigned (*pParseLineFunc)(unsigned, const TCHAR *, int, TEXTBLOCK *, int &);
126 switch (nEmbeddedLanguage)
128 case SRC_BASIC: pParseLineFunc = ParseLineBasic; break;
129 case SRC_PHP: pParseLineFunc = ParseLinePhpLanguage; break;
130 default: pParseLineFunc = ParseLineJavaScript; break;
132 dwCookie = pParseLineFunc(dwCookie & ~COOKIE_EXT_USER1, pszChars + I, nextI - I, pBuf, nActualItems);
134 dwCookie |= COOKIE_EXT_USER1;
138 bRedefineBlock = true;
145 // String constant "...."
146 if (dwCookie & COOKIE_STRING)
148 if (pszChars[I] == '"' && (I == 0 || I == 1 && pszChars[nPrevI] != '\\' || I >= 2 && (pszChars[nPrevI] != '\\' || *::CharPrev(pszChars, pszChars + nPrevI) == '\\')))
150 dwCookie &= ~COOKIE_STRING;
151 bRedefineBlock = true;
156 // Char constant '..'
157 if (dwCookie & COOKIE_CHAR)
159 if (pszChars[I] == '\'' && (I == 0 || I == 1 && pszChars[nPrevI] != '\\' || I >= 2 && (pszChars[nPrevI] != '\\' || *::CharPrev(pszChars, pszChars + nPrevI) == '\\')))
161 dwCookie &= ~COOKIE_CHAR;
162 bRedefineBlock = true;
167 // Extended comment <!--....-->
168 if (dwCookie & COOKIE_EXT_COMMENT)
170 if (I > 1 && pszChars[I] == '>' && pszChars[nPrevI] == '-' && *::CharPrev(pszChars, pszChars + nPrevI) == '-')
172 dwCookie &= ~COOKIE_EXT_COMMENT;
173 bRedefineBlock = true;
179 if ((dwCookie & COOKIE_ELEMENT) && pszChars[I] == '"')
181 DEFINE_BLOCK (I, COLORINDEX_STRING);
182 dwCookie |= COOKIE_STRING;
186 if ((dwCookie & COOKIE_ELEMENT) && pszChars[I] == '\'')
188 // if (I + 1 < nLength && pszChars[I + 1] == '\'' || I + 2 < nLength && pszChars[I + 1] != '\\' && pszChars[I + 2] == '\'' || I + 3 < nLength && pszChars[I + 1] == '\\' && pszChars[I + 3] == '\'')
189 if (!I || !xisalnum (pszChars[nPrevI]))
191 DEFINE_BLOCK (I, COLORINDEX_STRING);
192 dwCookie |= COOKIE_CHAR;
197 if (I < nLength - 3 && pszChars[I] == '<' && pszChars[I + 1] == '!' && pszChars[I + 2] == '-' && pszChars[I + 3] == '-')
199 DEFINE_BLOCK (I, COLORINDEX_COMMENT);
201 dwCookie |= COOKIE_EXT_COMMENT;
202 dwCookie &= ~COOKIE_ELEMENT;
207 if (I < nLength && pszChars[I] == '<' && I < nLength - 1 && (pszChars[I + 1] == '?' || pszChars[I + 1] == '%'))
209 DEFINE_BLOCK (I, COLORINDEX_NORMALTEXT);
210 dwCookie |= COOKIE_EXT_USER1;
216 continue; // We don't need to extract keywords,
217 // for faster parsing skip the rest of loop
219 if (xisalnum (pszChars[I]) || pszChars[I] == '.')
221 if (nIdentBegin == -1)
226 if (nIdentBegin >= 0)
228 if (dwCookie & COOKIE_ELEMENT)
230 if (IsHtmlKeyword (pszChars + nIdentBegin, I - nIdentBegin) && (pszChars[nIdentBegin - 1] == _T ('<') || pszChars[nIdentBegin - 1] == _T ('/')))
232 DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD);
233 if (nIdentBegin > 0 && _tcsnicmp(pszChars + nIdentBegin - 1, _T("<script"), sizeof("<script") - 1) == 0)
234 dwCookie |= COOKIE_BLOCK_SCRIPT;
235 else if (nIdentBegin > 0 && _tcsnicmp(pszChars + nIdentBegin - 1, _T("<style"), sizeof("<style") - 1) == 0)
236 dwCookie |= COOKIE_BLOCK_STYLE;
238 else if (IsHtmlUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin))
240 DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1);
242 else if (IsXNumber (pszChars + nIdentBegin, I - nIdentBegin))
244 DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER);
251 else if (dwCookie & COOKIE_USER1)
253 if (IsHtmlUser2Keyword (pszChars + nIdentBegin, I - nIdentBegin))
255 DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER2);
262 bRedefineBlock = true;
269 // Preprocessor start: < or bracket
270 if (I < nLength && pszChars[I] == '<' && !(I < nLength - 3 && pszChars[I + 1] == '!' && pszChars[I + 2] == '-' && pszChars[I + 3] == '-'))
272 DEFINE_BLOCK (I, COLORINDEX_OPERATOR);
273 DEFINE_BLOCK (I + 1, COLORINDEX_PREPROCESSOR);
274 dwCookie |= COOKIE_ELEMENT;
279 // Preprocessor end: > or bracket
280 if (dwCookie & COOKIE_ELEMENT)
282 if (pszChars[I] == '>')
284 dwCookie &= ~COOKIE_ELEMENT;
286 bRedefineBlock = true;
292 // Preprocessor start: &
293 if (pszChars[I] == '&')
295 dwCookie |= COOKIE_USER1;
300 // Preprocessor end: ;
301 if (dwCookie & COOKIE_USER1)
303 if (pszChars[I] == ';')
305 dwCookie &= ~COOKIE_USER1;
313 if (nIdentBegin >= 0 && (dwCookie & COOKIE_ELEMENT))
315 if (IsHtmlKeyword (pszChars + nIdentBegin, I - nIdentBegin) && (pszChars[nIdentBegin - 1] == _T ('<') || pszChars[nIdentBegin - 1] == _T ('/')))
317 DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD);
318 if (nIdentBegin > 0 && _tcsnicmp(pszChars + nIdentBegin - 1, _T("<script"), sizeof("<script") - 1) == 0)
319 dwCookie |= COOKIE_BLOCK_SCRIPT;
320 else if (nIdentBegin > 0 && _tcsnicmp(pszChars + nIdentBegin - 1, _T("<style"), sizeof("<style") - 1) == 0)
321 dwCookie |= COOKIE_BLOCK_STYLE;
323 else if (IsHtmlUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin))
325 DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1);
327 else if (IsHtmlUser2Keyword (pszChars + nIdentBegin, I - nIdentBegin))
329 DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER2);
331 else if (IsXNumber (pszChars + nIdentBegin, I - nIdentBegin))
333 DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER);
337 dwCookie &= (COOKIE_EXT_COMMENT | COOKIE_STRING | COOKIE_ELEMENT | COOKIE_EXT_USER1 | COOKIE_BLOCK_SCRIPT | COOKIE_BLOCK_STYLE | COOKIE_EXT_DEFINITION | COOKIE_EXT_VALUE);
342 CrystalLineParser::ParseLineHtml (unsigned dwCookie, const TCHAR *pszChars, int nLength, TEXTBLOCK * pBuf, int &nActualItems)
344 return ParseLineHtmlEx(dwCookie, pszChars, nLength, pBuf, nActualItems, SRC_JAVA);