1 ///////////////////////////////////////////////////////////////////////////
4 // Created: 22-Oct-2006
6 // Copyright: Stcherbatchenko Andrei, portions by Tim Gerundt
7 // E-mail: windfall@gmx.de
9 // CSS (Cascading Stylesheets) 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 "string_util.h"
26 static LPTSTR s_apszCss1KeywordList[] =
30 _T ("background-attachment"),
31 _T ("background-color"),
32 _T ("background-image"),
33 _T ("background-position"),
34 _T ("background-repeat"),
37 _T ("border-bottom-width"),
40 _T ("border-left-width"),
42 _T ("border-right-width"),
45 _T ("border-top-width"),
58 _T ("letter-spacing"),
61 _T ("list-style-image"),
62 _T ("list-style-position"),
63 _T ("list-style-type"),
70 _T ("padding-bottom"),
75 _T ("text-decoration"),
77 _T ("text-transform"),
78 _T ("vertical-align"),
85 static LPTSTR s_apszCss2KeywordList[] =
92 _T ("border-bottom-color"),
93 _T ("border-bottom-style"),
94 _T ("border-collapse"),
96 _T ("border-left-color"),
97 _T ("border-left-style"),
98 _T ("border-right-color"),
99 _T ("border-right-style"),
100 _T ("border-spacing"),
102 _T ("border-top-color"),
103 _T ("border-top-style"),
110 _T ("counter-increment"),
111 _T ("counter-reset"),
116 _T ("definition-src"),
121 _T ("font-size-adjust"),
124 _T ("marker-offset"),
133 _T ("outline-color"),
134 _T ("outline-style"),
135 _T ("outline-width"),
138 _T ("page-break-after"),
139 _T ("page-break-before"),
140 _T ("page-break-inside"),
156 _T ("speak-numeral"),
157 _T ("speak-punctuation"),
168 _T ("unicode-range"),
181 IsXKeyword (LPTSTR apszKeywords[], LPCTSTR pszChars, int nLength)
183 for (int L = 0; apszKeywords[L] != nullptr; L++)
185 if (_tcsnicmp (apszKeywords[L], pszChars, nLength) == 0
186 && apszKeywords[L][nLength] == 0)
193 IsCss1Keyword (LPCTSTR pszChars, int nLength)
195 return IsXKeyword (s_apszCss1KeywordList, pszChars, nLength);
199 IsCss2Keyword (LPCTSTR pszChars, int nLength)
201 return IsXKeyword (s_apszCss2KeywordList, pszChars, nLength);
205 CrystalLineParser::ParseLineCss (DWORD dwCookie, const TCHAR *pszChars, int nLength, TEXTBLOCK * pBuf, int &nActualItems)
208 return dwCookie & (COOKIE_EXT_COMMENT|COOKIE_EXT_DEFINITION|COOKIE_EXT_VALUE);
210 bool bFirstChar = (dwCookie & ~(COOKIE_EXT_COMMENT|COOKIE_EXT_DEFINITION|COOKIE_EXT_VALUE)) == 0;
211 bool bRedefineBlock = true;
212 bool bWasCommentStart = false;
213 bool bDecIndex = false;
214 int nIdentBegin = -1;
217 for (I = 0;; nPrevI = I, I = static_cast<int>(::CharNext(pszChars+I) - pszChars))
221 // CharNext did not advance, so we're at the end of the string
222 // and we already handled this character, so stop
231 if (dwCookie & COOKIE_EXT_COMMENT)
233 DEFINE_BLOCK (nPos, COLORINDEX_COMMENT);
237 if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.' || pszChars[nPos] == '-' || pszChars[nPos] == '%')
239 if (dwCookie & COOKIE_EXT_VALUE)
241 DEFINE_BLOCK (nPos, COLORINDEX_STRING);
245 DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT);
250 DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR);
251 bRedefineBlock = true;
256 bRedefineBlock = false;
261 // Can be bigger than length if there is binary data
262 // See bug #1474782 Crash when comparing SQL with with binary data
266 // Extended definition {....}
267 if (dwCookie & COOKIE_EXT_DEFINITION)
269 if (pszChars[I] == ':') //Value start...
271 dwCookie |= COOKIE_EXT_VALUE;
273 else if (pszChars[I] == ';') //Value end...
275 dwCookie &= ~COOKIE_EXT_VALUE;
277 else if (pszChars[I] == '}') //Definition end...
279 dwCookie &= ~COOKIE_EXT_DEFINITION;
280 dwCookie &= ~COOKIE_EXT_VALUE;
284 // Extended comment /*....*/
285 if (dwCookie & COOKIE_EXT_COMMENT)
287 if ((I > 1 && pszChars[I] == '/' && pszChars[nPrevI] == '*' && !bWasCommentStart) || (I == 1 && pszChars[I] == '/' && pszChars[nPrevI] == '*'))
289 dwCookie &= ~COOKIE_EXT_COMMENT;
290 bRedefineBlock = true;
292 bWasCommentStart = false;
297 if (pszChars[I] == '{')
299 dwCookie |= COOKIE_EXT_DEFINITION;
301 if (I > 0 && pszChars[I] == '*' && pszChars[nPrevI] == '/')
303 DEFINE_BLOCK (nPrevI, COLORINDEX_COMMENT);
304 dwCookie |= COOKIE_EXT_COMMENT;
305 bWasCommentStart = true;
309 bWasCommentStart = false;
313 if (!xisspace (pszChars[I]))
318 continue; // We don't need to extract keywords,
319 // for faster parsing skip the rest of loop
321 if (xisalnum (pszChars[I]) || pszChars[I] == '.' || pszChars[I] == '-' || pszChars[I] == '%')
323 if (nIdentBegin == -1)
328 if (nIdentBegin >= 0)
330 if (dwCookie & COOKIE_EXT_VALUE)
332 if (IsCss1Keyword (pszChars + nIdentBegin, I - nIdentBegin))
334 DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1);
336 else if (IsCss2Keyword (pszChars + nIdentBegin, I - nIdentBegin))
338 DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER2);
345 bRedefineBlock = true;
354 if ((nIdentBegin >= 0) && (dwCookie & COOKIE_EXT_VALUE))
356 if (IsCss1Keyword (pszChars + nIdentBegin, I - nIdentBegin))
358 DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1);
360 else if (IsCss2Keyword (pszChars + nIdentBegin, I - nIdentBegin))
362 DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER2);
366 dwCookie &= (COOKIE_EXT_COMMENT|COOKIE_EXT_DEFINITION|COOKIE_EXT_VALUE);