- Smarty delimiters can be changed, but for now only the default delimiters "{" and "}" are supported.
<ClCompile Include="$(MSBuildThisFileDirectory)parsers\sgml.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)parsers\sh.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)parsers\siod.cpp" />
+ <ClCompile Include="$(MSBuildThisFileDirectory)parsers\smarty.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)parsers\sql.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)parsers\tcl.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)parsers\tex.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)parsers\siod.cpp">
<Filter>Parsers\Source Files</Filter>
</ClCompile>
+ <ClCompile Include="$(MSBuildThisFileDirectory)parsers\smarty.cpp">
+ <Filter>Parsers\Source Files</Filter>
+ </ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)parsers\sql.cpp">
<Filter>Parsers\Source Files</Filter>
</ClCompile>
SRC_SGML, _T ("Sgml"), _T ("sgml"), &ParseLineSgml, SRCOPT_AUTOINDENT|SRCOPT_BRACEANSI, /*2,*/ _T ("<!--"), _T ("-->"), _T (""), (DWORD)-1,
SRC_SH, _T ("Shell"), _T ("sh;conf"), &ParseLineSh, SRCOPT_INSERTTABS|SRCOPT_AUTOINDENT|SRCOPT_EOLNUNIX, /*4,*/ _T (""), _T (""), _T ("#"), (DWORD)-1,
SRC_SIOD, _T ("SIOD"), _T ("scm"), &ParseLineSiod, SRCOPT_AUTOINDENT|SRCOPT_BRACEGNU, /*2,*/ _T (";|"), _T ("|;"), _T (";"), (DWORD)-1,
+ SRC_SMARTY, _T("Smarty"), _T("tpl"), &ParseLineSmarty, SRCOPT_AUTOINDENT | SRCOPT_BRACEGNU, /*2,*/ _T("{*"), _T("*}"), _T(""), (DWORD)-1,
SRC_SQL, _T ("SQL"), _T ("sql"), &ParseLineSql, SRCOPT_AUTOINDENT, /*4,*/ _T ("/*"), _T ("*/"), _T ("//"), (DWORD)-1,
SRC_TCL, _T ("TCL"), _T ("tcl"), &ParseLineTcl, SRCOPT_AUTOINDENT|SRCOPT_BRACEGNU|SRCOPT_EOLNUNIX, /*2,*/ _T (""), _T (""), _T ("#"), (DWORD)-1,
SRC_TEX, _T ("TEX"), _T ("tex;sty;clo;ltx;fd;dtx"), &ParseLineTex, SRCOPT_AUTOINDENT, /*4,*/ _T (""), _T (""), _T ("%"), (DWORD)-1,
SRC_SGML,\r
SRC_SH,\r
SRC_SIOD,\r
+ SRC_SMARTY,\r
SRC_SQL,\r
SRC_TCL,\r
SRC_TEX,\r
unsigned encoding;\r
};\r
\r
-extern TextDefinition m_SourceDefs[40];\r
+extern TextDefinition m_SourceDefs[41];\r
\r
bool IsXKeyword(const TCHAR *pszKey, size_t nKeyLen, const TCHAR *pszKeywordList[], size_t nKeywordListCount, int(*compare)(const TCHAR *, const TCHAR *, size_t));\r
bool IsXNumber(const TCHAR* pszChars, int nLength);\r
unsigned ParseLineSgml(unsigned dwCookie, const TCHAR *pszChars, int nLength, TEXTBLOCK * pBuf, int &nActualItems);\r
unsigned ParseLineSh(unsigned dwCookie, const TCHAR *pszChars, int nLength, TEXTBLOCK * pBuf, int &nActualItems);\r
unsigned ParseLineSiod(unsigned dwCookie, const TCHAR *pszChars, int nLength, TEXTBLOCK * pBuf, int &nActualItems);\r
+unsigned ParseLineSmarty(unsigned dwCookie, const TCHAR* pszChars, int nLength, TEXTBLOCK* pBuf, int& nActualItems);\r
+unsigned ParseLineSmartyLanguage(unsigned dwCookie, const TCHAR* pszChars, int nLength, TEXTBLOCK* pBuf, int& nActualItems);\r
unsigned ParseLineSql(unsigned dwCookie, const TCHAR *pszChars, int nLength, TEXTBLOCK * pBuf, int &nActualItems);\r
unsigned ParseLineTcl(unsigned dwCookie, const TCHAR *pszChars, int nLength, TEXTBLOCK * pBuf, int &nActualItems);\r
unsigned ParseLineTex(unsigned dwCookie, const TCHAR *pszChars, int nLength, TEXTBLOCK * pBuf, int &nActualItems);\r
{
if (nLength == 0)
{
- unsigned dwCookieStrChar = ((nEmbeddedLanguage == SRC_PHP) && (dwCookie & COOKIE_EXT_USER1)) ? (dwCookie & (COOKIE_STRING | COOKIE_CHAR)) : 0;
+ unsigned dwCookieStrChar = ((nEmbeddedLanguage == SRC_PHP || nEmbeddedLanguage == SRC_SMARTY) && (dwCookie & COOKIE_EXT_USER1)) ? (dwCookie & (COOKIE_STRING | COOKIE_CHAR)) : 0;
return dwCookie & (COOKIE_EXT_COMMENT|COOKIE_EXT_USER1|COOKIE_ELEMENT|COOKIE_BLOCK_SCRIPT|COOKIE_BLOCK_STYLE|COOKIE_EXT_DEFINITION|COOKIE_EXT_VALUE|dwCookieStrChar);
}
}
else if ((dwCookie & COOKIE_EXT_USER1))
{
- const TCHAR *pszEnd = _tcsstr(pszChars + I, _T("?>"));
- if (!pszEnd)
- pszEnd = _tcsstr(pszChars + I, _T("%>"));
- int nextI = pszEnd ? static_cast<int>(pszEnd - pszChars) : nLength;
- unsigned (*pParseLineFunc)(unsigned, const TCHAR *, int, TEXTBLOCK *, int &);
- switch (nEmbeddedLanguage)
- {
- case SRC_BASIC: pParseLineFunc = ParseLineBasic; break;
- case SRC_PHP: pParseLineFunc = ParseLinePhpLanguage; break;
- default: pParseLineFunc = ParseLineJavaScript; break;
- }
- int nActualItemsEmbedded = 0;
- dwCookie = pParseLineFunc(dwCookie & ~COOKIE_EXT_USER1, pszChars + I, nextI - I, pBuf + nActualItems, nActualItemsEmbedded);
- AdjustCharPosInTextBlocks(pBuf, nActualItems, nActualItems + nActualItemsEmbedded - 1, I);
- nActualItems += nActualItemsEmbedded;
- if (!pszEnd)
- dwCookie |= COOKIE_EXT_USER1;
- else if ((nEmbeddedLanguage == SRC_PHP) && (dwCookie & (COOKIE_EXT_COMMENT | COOKIE_STRING | COOKIE_CHAR)))
+ if (nEmbeddedLanguage != SRC_SMARTY)
{
- // A closing tag in a comment or string.
- if (dwCookie & COOKIE_EXT_COMMENT)
+ const TCHAR *pszEnd = _tcsstr(pszChars + I, _T("?>"));
+ if (!pszEnd)
+ pszEnd = _tcsstr(pszChars + I, _T("%>"));
+ int nextI = pszEnd ? static_cast<int>(pszEnd - pszChars) : nLength;
+ unsigned (*pParseLineFunc)(unsigned, const TCHAR *, int, TEXTBLOCK *, int &);
+ switch (nEmbeddedLanguage)
+ {
+ case SRC_BASIC: pParseLineFunc = ParseLineBasic; break;
+ case SRC_PHP: pParseLineFunc = ParseLinePhpLanguage; break;
+ default: pParseLineFunc = ParseLineJavaScript; break;
+ }
+ int nActualItemsEmbedded = 0;
+ dwCookie = pParseLineFunc(dwCookie & ~COOKIE_EXT_USER1, pszChars + I, nextI - I, pBuf + nActualItems, nActualItemsEmbedded);
+ AdjustCharPosInTextBlocks(pBuf, nActualItems, nActualItems + nActualItemsEmbedded - 1, I);
+ nActualItems += nActualItemsEmbedded;
+ if (!pszEnd)
+ dwCookie |= COOKIE_EXT_USER1;
+ else if ((nEmbeddedLanguage == SRC_PHP) && (dwCookie & (COOKIE_EXT_COMMENT | COOKIE_STRING | COOKIE_CHAR)))
{
- DEFINE_BLOCK(I, COLORINDEX_COMMENT);
+ // A closing tag in a comment or string.
+ if (dwCookie & COOKIE_EXT_COMMENT)
+ {
+ DEFINE_BLOCK(I, COLORINDEX_COMMENT);
+ }
+ else if (dwCookie & (COOKIE_STRING | COOKIE_CHAR))
+ {
+ DEFINE_BLOCK(I, COLORINDEX_STRING);
+ }
+ nextI += 2; // Length of "?>"
+ dwCookie |= COOKIE_EXT_USER1;
+ bRedefineBlock = true;
}
- else if (dwCookie & (COOKIE_STRING | COOKIE_CHAR))
+ else
{
- DEFINE_BLOCK(I, COLORINDEX_STRING);
+ dwCookie = 0;
+ bRedefineBlock = true;
}
- nextI += 2; // Length of "?>"
- dwCookie |= COOKIE_EXT_USER1;
- bRedefineBlock = true;
+ I = nextI - 1;
}
else
{
- dwCookie = 0;
- bRedefineBlock = true;
+ const TCHAR* pszEnd = _tcsstr(pszChars + I, _T("}"));
+ int nextI = pszEnd ? static_cast<int>(pszEnd - pszChars) : nLength;
+ int nActualItemsEmbedded = 0;
+ int nOffset = (I > 0 && pszChars[I - 1] == '{') ? (I - 1) : I;
+ dwCookie = ParseLineSmartyLanguage(dwCookie & ~COOKIE_EXT_USER1, pszChars + nOffset, nextI - nOffset + 1, pBuf + nActualItems, nActualItemsEmbedded);
+ AdjustCharPosInTextBlocks(pBuf, nActualItems, nActualItems + nActualItemsEmbedded - 1, nOffset);
+ nActualItems += nActualItemsEmbedded;
+ if (!pszEnd)
+ dwCookie |= COOKIE_EXT_USER1;
+ else if (dwCookie & (COOKIE_EXT_COMMENT | COOKIE_STRING))
+ {
+ // A closing tag in a comment or string.
+ if (dwCookie & COOKIE_EXT_COMMENT)
+ {
+ DEFINE_BLOCK(I, COLORINDEX_COMMENT);
+ }
+ else if (dwCookie & (COOKIE_STRING | COOKIE_CHAR))
+ {
+ DEFINE_BLOCK(I, COLORINDEX_STRING);
+ }
+ nextI += 1; // Length of "}"
+ dwCookie |= COOKIE_EXT_USER1;
+ bRedefineBlock = true;
+ }
+ else
+ {
+ nextI += 1; // Length of "}"
+ dwCookie = 0;
+ bRedefineBlock = true;
+ }
+ I = nextI - 1;
}
- I = nextI - 1;
}
continue;
}
continue;
}
+ if (nEmbeddedLanguage == SRC_SMARTY)
+ {
+ // In Smarty templates, the { and } braces will be ignored so long as they are surrounded by white space.
+ bool bLeftDelim = ((I < nLength&& pszChars[I] == '{') && ((I > 0 && (!xisspace(pszChars[I - 1]))) || (I + 1 < nLength && (!xisspace(pszChars[I + 1])))));
+ if (bLeftDelim)
+ {
+ dwCookie |= COOKIE_EXT_USER1;
+ nIdentBegin = -1;
+ continue;
+ }
+ }
+
if (pBuf == nullptr)
continue; // We don't need to extract keywords,
// for faster parsing skip the rest of loop
if (IsHtmlKeyword (pszChars + nIdentBegin, I - nIdentBegin) && (pszChars[nIdentBegin - 1] == _T ('<') || pszChars[nIdentBegin - 1] == _T ('/')))
{
DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD);
- if (nIdentBegin > 0 && _tcsnicmp(pszChars + nIdentBegin - 1, _T("<script"), sizeof("<script") - 1) == 0)
- dwCookie |= COOKIE_BLOCK_SCRIPT;
- else if (nIdentBegin > 0 && _tcsnicmp(pszChars + nIdentBegin - 1, _T("<style"), sizeof("<style") - 1) == 0)
- dwCookie |= COOKIE_BLOCK_STYLE;
+ if (nEmbeddedLanguage != SRC_SMARTY)
+ {
+ if (nIdentBegin > 0 && _tcsnicmp(pszChars + nIdentBegin - 1, _T("<script"), sizeof("<script") - 1) == 0)
+ dwCookie |= COOKIE_BLOCK_SCRIPT;
+ else if (nIdentBegin > 0 && _tcsnicmp(pszChars + nIdentBegin - 1, _T("<style"), sizeof("<style") - 1) == 0)
+ dwCookie |= COOKIE_BLOCK_STYLE;
+ }
}
else if (IsHtmlUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin))
{
if (IsHtmlKeyword (pszChars + nIdentBegin, I - nIdentBegin) && (pszChars[nIdentBegin - 1] == _T ('<') || pszChars[nIdentBegin - 1] == _T ('/')))
{
DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD);
- if (nIdentBegin > 0 && _tcsnicmp(pszChars + nIdentBegin - 1, _T("<script"), sizeof("<script") - 1) == 0)
- dwCookie |= COOKIE_BLOCK_SCRIPT;
- else if (nIdentBegin > 0 && _tcsnicmp(pszChars + nIdentBegin - 1, _T("<style"), sizeof("<style") - 1) == 0)
- dwCookie |= COOKIE_BLOCK_STYLE;
+ if (nEmbeddedLanguage != SRC_SMARTY)
+ {
+ if (nIdentBegin > 0 && _tcsnicmp(pszChars + nIdentBegin - 1, _T("<script"), sizeof("<script") - 1) == 0)
+ dwCookie |= COOKIE_BLOCK_SCRIPT;
+ else if (nIdentBegin > 0 && _tcsnicmp(pszChars + nIdentBegin - 1, _T("<style"), sizeof("<style") - 1) == 0)
+ dwCookie |= COOKIE_BLOCK_STYLE;
+ }
}
else if (IsHtmlUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin))
{
}
}
- unsigned dwCookieChar = ((nEmbeddedLanguage == SRC_PHP) && (dwCookie & COOKIE_EXT_USER1)) ? (dwCookie & COOKIE_CHAR) : 0;
+ unsigned dwCookieChar = ((nEmbeddedLanguage == SRC_PHP || nEmbeddedLanguage == SRC_SMARTY) && (dwCookie & COOKIE_EXT_USER1)) ? (dwCookie & COOKIE_CHAR) : 0;
dwCookie &= (COOKIE_EXT_COMMENT | COOKIE_STRING | COOKIE_ELEMENT | COOKIE_EXT_USER1 | COOKIE_BLOCK_SCRIPT | COOKIE_BLOCK_STYLE | COOKIE_EXT_DEFINITION | COOKIE_EXT_VALUE | dwCookieChar);
return dwCookie;
}
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// File: smarty.cpp
+// Version: 1.0.0.0
+// Updated: 11-Jun-2021
+//
+// Copyright: Ferdinand Prantl, portions by Stcherbatchenko Andrei
+// E-mail: prantl@ff.cuni.cz
+//
+// Smarty syntax highlighing definition
+//
+// You are free to use or modify this code to the following restrictions:
+// - Acknowledge me somewhere in your about box, simple "Parts of code by.."
+// will be enough. If you can't (or don't want to), contact me personally.
+// - LEAVE THIS HEADER INTACT
+////////////////////////////////////////////////////////////////////////////
+
+#include "StdAfx.h"
+#include "crystallineparser.h"
+#include "../SyntaxColors.h"
+#include "../utils/string_util.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+// See https://www.smarty.net/docs/en/
+
+// Chapter7
+// Built-in Functions
+static const TCHAR * s_apszBuiltInFunctionList[] =
+ {
+ _T ("append"),
+ _T ("as"), // This is used with "foreach".
+ _T ("assign"),
+ _T ("block"),
+ _T ("break"),
+ _T ("call"),
+ _T ("capture"),
+ _T ("config_load"),
+ _T ("continue"),
+ _T ("debug"),
+ _T ("else"),
+ _T ("elseif"),
+ _T ("extends"),
+ _T ("for"),
+ _T ("foreach"),
+ _T ("foreachelse"),
+ _T ("forelse"),
+ _T ("function"),
+ _T ("if"),
+ _T ("include"),
+ _T ("include_php"),
+ _T ("insert"),
+ _T ("ldelim"),
+ _T ("literal"),
+ _T ("nocache"),
+ _T ("php"),
+ _T ("rdelim"),
+ _T ("section"),
+ _T ("sectionelse"),
+ _T ("setfilter"),
+ _T ("step"), // This is used with "for".
+ _T ("strip"),
+ _T ("to"), // This is used with "for".
+ _T ("while"),
+ };
+
+// Operators
+static const TCHAR * s_apszOperatorList[] =
+ {
+ _T ("by"),
+ _T ("div"),
+ _T ("eq"),
+ _T ("even"),
+ _T ("ge"),
+ _T ("gt"),
+ _T ("gte"),
+ _T ("is"),
+ _T ("le"),
+ _T ("lt"),
+ _T ("lte"),
+ _T ("mod"),
+ _T ("ne"),
+ _T ("neq"),
+ _T ("not"),
+ _T ("odd"),
+ };
+
+// Chapter8
+// Custom Functions
+static const TCHAR * s_apszCustomFunctionList[] =
+ {
+ _T ("counter"),
+ _T ("cycle"),
+ _T ("eval"),
+ _T ("fetch"),
+ _T ("html_checkboxes"),
+ _T ("html_image"),
+ _T ("html_options"),
+ _T ("html_radios"),
+ _T ("html_select_date"),
+ _T ("html_select_time"),
+ _T ("html_table"),
+ _T ("mailto"),
+ _T ("math"),
+ _T ("textformat"),
+ };
+
+// Chapter5
+// Variable Modifiers
+static const TCHAR * s_apszVariableModifierList[] =
+ {
+ _T ("capitalize"),
+ _T ("cat"),
+ _T ("count_characters"),
+ _T ("count_paragraphs"),
+ _T ("count_sentences"),
+ _T ("count_words"),
+ _T ("date_format"),
+ _T ("default"),
+ _T ("escape"),
+ _T ("from_charset"),
+ _T ("indent"),
+ _T ("lower"),
+ _T ("nl2br"),
+ _T ("regex_replace"),
+ _T ("replace"),
+ _T ("spacify"),
+ _T ("string_format"),
+// _T ("strip"), // This is also defined as a build-in function, so comment it out.
+ _T ("strip_tags"),
+ _T ("to_charset"),
+ _T ("truncate"),
+ _T ("unescape"),
+ _T ("upper"),
+ _T ("wordwrap"),
+ };
+
+
+static bool
+IsSmartyKeyword (const TCHAR *pszChars, int nLength)
+{
+ return ISXKEYWORDI (s_apszBuiltInFunctionList, pszChars, nLength);
+}
+
+static bool
+IsOperatorKeyword(const TCHAR* pszChars, int nLength)
+{
+ return ISXKEYWORDI(s_apszOperatorList, pszChars, nLength);
+}
+
+static bool
+IsUser1Keyword (const TCHAR *pszChars, int nLength)
+{
+ return ISXKEYWORDI (s_apszCustomFunctionList, pszChars, nLength);
+}
+
+static bool
+IsUser2Keyword (const TCHAR *pszChars, int nLength)
+{
+ return ISXKEYWORDI (s_apszVariableModifierList, pszChars, nLength);
+}
+
+unsigned
+CrystalLineParser::ParseLineSmarty(unsigned dwCookie, const TCHAR* pszChars, int nLength, TEXTBLOCK* pBuf, int& nActualItems)
+{
+ return ParseLineHtmlEx(dwCookie, pszChars, nLength, pBuf, nActualItems, SRC_SMARTY);
+}
+
+unsigned
+CrystalLineParser::ParseLineSmartyLanguage (unsigned dwCookie, const TCHAR *pszChars, int nLength, TEXTBLOCK * pBuf, int &nActualItems)
+{
+ if (nLength == 0)
+ return dwCookie & (COOKIE_EXT_COMMENT | COOKIE_STRING | COOKIE_CHAR);
+
+ const TCHAR *pszCommentBegin = nullptr;
+ const TCHAR *pszCommentEnd = nullptr;
+ bool bRedefineBlock = true;
+ bool bDecIndex = false;
+ int nIdentBegin = -1;
+ int nPrevI = -1;
+ int I=0;
+ for (I = 0;; nPrevI = I, I = static_cast<int>(::CharNext(pszChars+I) - pszChars))
+ {
+ if (I == nPrevI)
+ {
+ // CharNext did not advance, so we're at the end of the string
+ // and we already handled this character, so stop
+ break;
+ }
+
+ if (bRedefineBlock)
+ {
+ int nPos = I;
+ if (bDecIndex)
+ nPos = nPrevI;
+ if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT))
+ {
+ DEFINE_BLOCK (nPos, COLORINDEX_COMMENT);
+ }
+ else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING))
+ {
+ DEFINE_BLOCK (nPos, COLORINDEX_STRING);
+ }
+ else if (dwCookie & COOKIE_USER1) // Config???
+ {
+ DEFINE_BLOCK(nPos, COLORINDEX_USER1);
+ }
+ else if (dwCookie & COOKIE_PREPROCESSOR)
+ {
+ DEFINE_BLOCK (nPos, COLORINDEX_PREPROCESSOR);
+ }
+ else
+ {
+ if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.')
+ {
+ DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT);
+ }
+ else
+ {
+ DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR);
+ bRedefineBlock = true;
+ bDecIndex = true;
+ goto out;
+ }
+ }
+ bRedefineBlock = false;
+ bDecIndex = false;
+ }
+out:
+
+ // Can be bigger than length if there is binary data
+ // See bug #1474782 Crash when comparing SQL with with binary data
+ if (I >= nLength || pszChars[I] == 0)
+ break;
+
+ if (dwCookie & COOKIE_COMMENT)
+ {
+ DEFINE_BLOCK (I, COLORINDEX_COMMENT);
+ dwCookie |= COOKIE_COMMENT;
+ break;
+ }
+
+ // String constant "...."
+ if (dwCookie & COOKIE_STRING)
+ {
+ if (pszChars[I] == '"' && (I == 0 || I == 1 && pszChars[nPrevI] != '\\' || I >= 2 && (pszChars[nPrevI] != '\\' || *::CharPrev(pszChars, pszChars + nPrevI) == '\\')))
+ {
+ dwCookie &= ~COOKIE_STRING;
+ bRedefineBlock = true;
+ }
+ continue;
+ }
+
+ // Char constant '..'
+ if (dwCookie & COOKIE_CHAR)
+ {
+ if (pszChars[I] == '\'' && (I == 0 || I == 1 && pszChars[nPrevI] != '\\' || I >= 2 && (pszChars[nPrevI] != '\\' || *::CharPrev(pszChars, pszChars + nPrevI) == '\\')))
+ {
+ dwCookie &= ~COOKIE_CHAR;
+ bRedefineBlock = true;
+ }
+ continue;
+ }
+
+ // Variables loaded from config files #....#
+ if (dwCookie & COOKIE_USER1)
+ {
+ if (pszChars[I] == '#' && (I == 0 || I == 1 && pszChars[nPrevI] != '\\' || I >= 2 && (pszChars[nPrevI] != '\\' || *::CharPrev(pszChars, pszChars + nPrevI) == '\\')))
+ {
+ dwCookie &= ~COOKIE_USER1;
+ bRedefineBlock = true;
+ }
+ continue;
+ }
+
+ // Comment
+ if (dwCookie & COOKIE_EXT_COMMENT)
+ {
+ if ((pszCommentBegin < pszChars + I) && (I > 0 && pszChars[I] == '}' && pszChars[nPrevI] == '*'))
+ {
+ dwCookie &= ~COOKIE_EXT_COMMENT;
+ bRedefineBlock = true;
+ pszCommentEnd = pszChars + I + 1;
+ }
+ continue;
+ }
+
+ // Normal text
+ if (pszChars[I] == '"')
+ {
+ DEFINE_BLOCK (I, COLORINDEX_STRING);
+ dwCookie |= COOKIE_STRING;
+ continue;
+ }
+
+ if (pszChars[I] == '\'')
+ {
+ // 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] == '\'')
+ if (!I || !xisalnum (pszChars[nPrevI]))
+ {
+ DEFINE_BLOCK (I, COLORINDEX_STRING);
+ dwCookie |= COOKIE_CHAR;
+ continue;
+ }
+ }
+
+ if (pszChars[I] == '#')
+ {
+ DEFINE_BLOCK(I, COLORINDEX_USER1);
+ dwCookie |= COOKIE_USER1;
+ continue;
+ }
+
+ if ((pszCommentEnd < pszChars + I) && (I > 0 && pszChars[I] == '*' && pszChars[nPrevI] == '{'))
+ {
+ DEFINE_BLOCK (nPrevI, COLORINDEX_COMMENT);
+ dwCookie |= COOKIE_EXT_COMMENT;
+ pszCommentBegin = pszChars + I + 1;
+ continue;
+ }
+
+ if (pBuf == nullptr)
+ continue; // We don't need to extract keywords,
+ // for faster parsing skip the rest of loop
+
+ if (xisalnum (pszChars[I]) || pszChars[I] == '.')
+ {
+ if (nIdentBegin == -1)
+ nIdentBegin = I;
+ }
+ else
+ {
+ if (nIdentBegin >= 0)
+ {
+ if (dwCookie & COOKIE_USER2)
+ {
+ DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1);
+ }
+ if (IsSmartyKeyword (pszChars + nIdentBegin, I - nIdentBegin))
+ {
+ DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD);
+ }
+ else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin))
+ {
+ DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME);
+ }
+ else if (IsUser2Keyword (pszChars + nIdentBegin, I - nIdentBegin))
+ {
+ DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER2);
+ }
+ else if (IsOperatorKeyword(pszChars + nIdentBegin, I - nIdentBegin))
+ {
+ DEFINE_BLOCK(nIdentBegin, COLORINDEX_OPERATOR);
+ }
+ else if (IsXNumber (pszChars + nIdentBegin, I - nIdentBegin))
+ {
+ DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER);
+ }
+ else
+ {
+ bool bFunction = false;
+
+ for (int j = I; j < nLength; j++)
+ {
+ if (!xisspace (pszChars[j]))
+ {
+ if (pszChars[j] == '(')
+ {
+ bFunction = true;
+ }
+ break;
+ }
+ }
+ if (bFunction)
+ {
+ DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME);
+ }
+ }
+ bRedefineBlock = true;
+ bDecIndex = true;
+ nIdentBegin = -1;
+ }
+
+ // Preprocessor start: $
+ if (pszChars[I] == '$')
+ {
+ dwCookie |= COOKIE_USER2;
+ nIdentBegin = -1;
+ continue;
+ }
+
+ // Preprocessor end: ...
+ if (dwCookie & COOKIE_USER2)
+ {
+ if (!xisalnum (pszChars[I]))
+ {
+ dwCookie &= ~COOKIE_USER2;
+ nIdentBegin = -1;
+ continue;
+ }
+ }
+ }
+ }
+
+ if (nIdentBegin >= 0)
+ {
+ if (IsSmartyKeyword (pszChars + nIdentBegin, I - nIdentBegin))
+ {
+ DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD);
+ }
+ else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin))
+ {
+ DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME);
+ }
+ else if (IsUser2Keyword (pszChars + nIdentBegin, I - nIdentBegin))
+ {
+ DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER2);
+ }
+ else if (IsOperatorKeyword(pszChars + nIdentBegin, I - nIdentBegin))
+ {
+ DEFINE_BLOCK(nIdentBegin, COLORINDEX_OPERATOR);
+ }
+ else if (IsXNumber (pszChars + nIdentBegin, I - nIdentBegin))
+ {
+ DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER);
+ }
+ else
+ {
+ bool bFunction = false;
+
+ for (int j = I; j < nLength; j++)
+ {
+ if (!xisspace (pszChars[j]))
+ {
+ if (pszChars[j] == '(')
+ {
+ bFunction = true;
+ }
+ break;
+ }
+ }
+ if (bFunction)
+ {
+ DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME);
+ }
+ }
+ }
+
+ dwCookie &= (COOKIE_EXT_COMMENT | COOKIE_STRING | COOKIE_CHAR);
+ return dwCookie;
+}
IDS_COLORSCHEME_SGML "SGML"\r
IDS_COLORSCHEME_SH "Shell"\r
IDS_COLORSCHEME_SIOD "SIOD"\r
+ IDS_COLORSCHEME_SMARTY "Smarty"\r
IDS_COLORSCHEME_SQL "SQL"\r
IDS_COLORSCHEME_TCL "TCL"\r
END\r
#define IDS_COLORSCHEME_SGML 33183\r
#define IDS_COLORSCHEME_SH 33184\r
#define IDS_COLORSCHEME_SIOD 33185\r
-#define IDS_COLORSCHEME_SQL 33186\r
-#define IDS_COLORSCHEME_TCL 33187\r
-#define IDS_COLORSCHEME_TEX 33188\r
-#define IDS_COLORSCHEME_VERILOG 33189\r
-#define IDS_COLORSCHEME_VHDL 33190\r
-#define IDS_COLORSCHEME_XML 33191\r
-#define ID_COLORSCHEME_LAST 33191 // = IDS_COLORSCHEME_XML\r
+#define IDS_COLORSCHEME_SMARTY 33186\r
+#define IDS_COLORSCHEME_SQL 33187\r
+#define IDS_COLORSCHEME_TCL 33188\r
+#define IDS_COLORSCHEME_TEX 33189\r
+#define IDS_COLORSCHEME_VERILOG 33190\r
+#define IDS_COLORSCHEME_VHDL 33191\r
+#define IDS_COLORSCHEME_XML 33192\r
+#define ID_COLORSCHEME_LAST 33192 // = IDS_COLORSCHEME_XML\r
#define ID_TOOLBAR_NONE 33194\r
#define ID_TOOLBAR_SMALL 33195\r
#define ID_TOOLBAR_BIG 33196\r
Rust
SGML
SIOD
+Smarty
SQL
TCL
TEX