using System; using System.Collections.Generic; using System.Drawing; using System.Globalization; using System.IO; using System.Text.RegularExpressions; using System.Xml; namespace FastColoredTextBoxNS { public class SyntaxHighlighter : IDisposable { //styles protected static readonly Platform platformType = PlatformType.GetOperationSystemPlatform(); public readonly Style BlueBoldStyle = new TextStyle(Brushes.Blue, null, FontStyle.Bold); public readonly Style BlueStyle = new TextStyle(Brushes.Blue, null, FontStyle.Regular); public readonly Style BoldStyle = new TextStyle(null, null, FontStyle.Bold | FontStyle.Underline); public readonly Style BrownStyle = new TextStyle(Brushes.Brown, null, FontStyle.Italic); public readonly Style GrayStyle = new TextStyle(Brushes.Gray, null, FontStyle.Regular); public readonly Style GreenStyle = new TextStyle(Brushes.Green, null, FontStyle.Italic); public readonly Style MagentaStyle = new TextStyle(Brushes.Magenta, null, FontStyle.Regular); public readonly Style MaroonStyle = new TextStyle(Brushes.Maroon, null, FontStyle.Regular); public readonly Style RedStyle = new TextStyle(Brushes.Red, null, FontStyle.Regular); public readonly Style BlackStyle = new TextStyle(Brushes.Black, null, FontStyle.Regular); // protected readonly Dictionary descByXMLfileNames = new Dictionary(); protected Regex CSharpAttributeRegex, CSharpClassNameRegex; protected Regex CSharpCommentRegex1, CSharpCommentRegex2, CSharpCommentRegex3; protected Regex CSharpKeywordRegex; protected Regex CSharpNumberRegex; protected Regex CSharpStringRegex; protected Regex HTMLAttrRegex, HTMLAttrValRegex, HTMLCommentRegex1, HTMLCommentRegex2; protected Regex HTMLEndTagRegex; protected Regex HTMLEntityRegex, HTMLTagContentRegex; protected Regex HTMLTagNameRegex; protected Regex HTMLTagRegex; protected Regex XMLAttrRegex, XMLAttrValRegex, XMLCommentRegex1, XMLCommentRegex2; protected Regex XMLEndTagRegex; protected Regex XMLEntityRegex, XMLTagContentRegex; protected Regex XMLTagNameRegex; protected Regex XMLTagRegex; protected Regex XMLCDataRegex; protected Regex XMLFoldingRegex; protected Regex JScriptCommentRegex1, JScriptCommentRegex2, JScriptCommentRegex3; protected Regex JScriptKeywordRegex; protected Regex JScriptNumberRegex; protected Regex JScriptStringRegex; protected Regex LuaCommentRegex1, LuaCommentRegex2, LuaCommentRegex3; protected Regex LuaKeywordRegex; protected Regex LuaNumberRegex; protected Regex LuaStringRegex; protected Regex LuaFunctionsRegex; protected Regex PHPCommentRegex1, PHPCommentRegex2, PHPCommentRegex3; protected Regex PHPKeywordRegex1, PHPKeywordRegex2, PHPKeywordRegex3; protected Regex PHPNumberRegex; protected Regex PHPStringRegex; protected Regex PHPVarRegex; protected Regex SQLCommentRegex1, SQLCommentRegex2, SQLCommentRegex3; protected Regex SQLFunctionsRegex; protected Regex SQLKeywordsRegex; protected Regex SQLNumberRegex; protected Regex SQLStatementsRegex; protected Regex SQLStringRegex; protected Regex SQLTypesRegex; protected Regex SQLVarRegex; protected Regex VBClassNameRegex; protected Regex VBCommentRegex; protected Regex VBKeywordRegex; protected Regex VBNumberRegex; protected Regex VBStringRegex; public static RegexOptions RegexCompiledOption { get { if (platformType == Platform.X86) return RegexOptions.Compiled; else return RegexOptions.None; } } #region IDisposable Members public void Dispose() { foreach (SyntaxDescriptor desc in descByXMLfileNames.Values) desc.Dispose(); } #endregion /// /// Highlights syntax for given language /// public virtual void HighlightSyntax(Language language, Range range) { switch (language) { case Language.CSharp: CSharpSyntaxHighlight(range); break; case Language.VB: VBSyntaxHighlight(range); break; case Language.HTML: HTMLSyntaxHighlight(range); break; case Language.XML: XMLSyntaxHighlight(range); break; case Language.SQL: SQLSyntaxHighlight(range); break; case Language.PHP: PHPSyntaxHighlight(range); break; case Language.JS: JScriptSyntaxHighlight(range); break; case Language.Lua: LuaSyntaxHighlight(range); break; default: break; } } public virtual void AutoIndentNeeded(object sender, AutoIndentEventArgs args) { var tb = (sender as FastColoredTextBox); Language language = tb.Language; switch (language) { case Language.CSharp: CSharpAutoIndentNeeded(sender, args); break; case Language.VB: VBAutoIndentNeeded(sender, args); break; case Language.HTML: HTMLAutoIndentNeeded(sender, args); break; case Language.XML: XMLAutoIndentNeeded(sender, args); break; case Language.SQL: SQLAutoIndentNeeded(sender, args); break; case Language.PHP: PHPAutoIndentNeeded(sender, args); break; case Language.JS: CSharpAutoIndentNeeded(sender, args); break; //JS like C# case Language.Lua: LuaAutoIndentNeeded(sender, args); break; default: break; } } protected void PHPAutoIndentNeeded(object sender, AutoIndentEventArgs args) { /* FastColoredTextBox tb = sender as FastColoredTextBox; tb.CalcAutoIndentShiftByCodeFolding(sender, args);*/ //block {} if (Regex.IsMatch(args.LineText, @"^[^""']*\{.*\}[^""']*$")) return; //start of block {} if (Regex.IsMatch(args.LineText, @"^[^""']*\{")) { args.ShiftNextLines = args.TabLength; return; } //end of block {} if (Regex.IsMatch(args.LineText, @"}[^""']*$")) { args.Shift = -args.TabLength; args.ShiftNextLines = -args.TabLength; return; } //is unclosed operator in previous line ? if (Regex.IsMatch(args.PrevLineText, @"^\s*(if|for|foreach|while|[\}\s]*else)\b[^{]*$")) if (!Regex.IsMatch(args.PrevLineText, @"(;\s*$)|(;\s*//)")) //operator is unclosed { args.Shift = args.TabLength; return; } } protected void SQLAutoIndentNeeded(object sender, AutoIndentEventArgs args) { var tb = sender as FastColoredTextBox; tb.CalcAutoIndentShiftByCodeFolding(sender, args); } protected void HTMLAutoIndentNeeded(object sender, AutoIndentEventArgs args) { var tb = sender as FastColoredTextBox; tb.CalcAutoIndentShiftByCodeFolding(sender, args); } protected void XMLAutoIndentNeeded(object sender, AutoIndentEventArgs args) { var tb = sender as FastColoredTextBox; tb.CalcAutoIndentShiftByCodeFolding(sender, args); } protected void VBAutoIndentNeeded(object sender, AutoIndentEventArgs args) { //end of block if (Regex.IsMatch(args.LineText, @"^\s*(End|EndIf|Next|Loop)\b", RegexOptions.IgnoreCase)) { args.Shift = -args.TabLength; args.ShiftNextLines = -args.TabLength; return; } //start of declaration if (Regex.IsMatch(args.LineText, @"\b(Class|Property|Enum|Structure|Sub|Function|Namespace|Interface|Get)\b|(Set\s*\()", RegexOptions.IgnoreCase)) { args.ShiftNextLines = args.TabLength; return; } // then ... if (Regex.IsMatch(args.LineText, @"\b(Then)\s*\S+", RegexOptions.IgnoreCase)) return; //start of operator block if (Regex.IsMatch(args.LineText, @"^\s*(If|While|For|Do|Try|With|Using|Select)\b", RegexOptions.IgnoreCase)) { args.ShiftNextLines = args.TabLength; return; } //Statements else, elseif, case etc if (Regex.IsMatch(args.LineText, @"^\s*(Else|ElseIf|Case|Catch|Finally)\b", RegexOptions.IgnoreCase)) { args.Shift = -args.TabLength; return; } //Char _ if (args.PrevLineText.TrimEnd().EndsWith("_")) { args.Shift = args.TabLength; return; } } protected void CSharpAutoIndentNeeded(object sender, AutoIndentEventArgs args) { //block {} if (Regex.IsMatch(args.LineText, @"^[^""']*\{.*\}[^""']*$")) return; //start of block {} if (Regex.IsMatch(args.LineText, @"^[^""']*\{")) { args.ShiftNextLines = args.TabLength; return; } //end of block {} if (Regex.IsMatch(args.LineText, @"}[^""']*$")) { args.Shift = -args.TabLength; args.ShiftNextLines = -args.TabLength; return; } //label if (Regex.IsMatch(args.LineText, @"^\s*\w+\s*:\s*($|//)") && !Regex.IsMatch(args.LineText, @"^\s*default\s*:")) { args.Shift = -args.TabLength; return; } //some statements: case, default if (Regex.IsMatch(args.LineText, @"^\s*(case|default)\b.*:\s*($|//)")) { args.Shift = -args.TabLength / 2; return; } //is unclosed operator in previous line ? if (Regex.IsMatch(args.PrevLineText, @"^\s*(if|for|foreach|while|[\}\s]*else)\b[^{]*$")) if (!Regex.IsMatch(args.PrevLineText, @"(;\s*$)|(;\s*//)")) //operator is unclosed { args.Shift = args.TabLength; return; } } public static SyntaxDescriptor ParseXmlDescription(XmlDocument doc) { var desc = new SyntaxDescriptor(); XmlNode brackets = doc.SelectSingleNode("doc/brackets"); if (brackets != null) { if (brackets.Attributes["left"] == null || brackets.Attributes["right"] == null || brackets.Attributes["left"].Value == "" || brackets.Attributes["right"].Value == "") { desc.leftBracket = '\x0'; desc.rightBracket = '\x0'; } else { desc.leftBracket = brackets.Attributes["left"].Value[0]; desc.rightBracket = brackets.Attributes["right"].Value[0]; } if (brackets.Attributes["left2"] == null || brackets.Attributes["right2"] == null || brackets.Attributes["left2"].Value == "" || brackets.Attributes["right2"].Value == "") { desc.leftBracket2 = '\x0'; desc.rightBracket2 = '\x0'; } else { desc.leftBracket2 = brackets.Attributes["left2"].Value[0]; desc.rightBracket2 = brackets.Attributes["right2"].Value[0]; } if (brackets.Attributes["strategy"] == null || brackets.Attributes["strategy"].Value == "") desc.bracketsHighlightStrategy = BracketsHighlightStrategy.Strategy2; else desc.bracketsHighlightStrategy = (BracketsHighlightStrategy)Enum.Parse(typeof(BracketsHighlightStrategy), brackets.Attributes["strategy"].Value); } var styleByName = new Dictionary(); foreach (XmlNode style in doc.SelectNodes("doc/style")) { Style s = ParseStyle(style); styleByName[style.Attributes["name"].Value] = s; desc.styles.Add(s); } foreach (XmlNode rule in doc.SelectNodes("doc/rule")) desc.rules.Add(ParseRule(rule, styleByName)); foreach (XmlNode folding in doc.SelectNodes("doc/folding")) desc.foldings.Add(ParseFolding(folding)); return desc; } protected static FoldingDesc ParseFolding(XmlNode foldingNode) { var folding = new FoldingDesc(); //regex folding.startMarkerRegex = foldingNode.Attributes["start"].Value; folding.finishMarkerRegex = foldingNode.Attributes["finish"].Value; //options XmlAttribute optionsA = foldingNode.Attributes["options"]; if (optionsA != null) folding.options = (RegexOptions)Enum.Parse(typeof(RegexOptions), optionsA.Value); return folding; } protected static RuleDesc ParseRule(XmlNode ruleNode, Dictionary styles) { var rule = new RuleDesc(); rule.pattern = ruleNode.InnerText; // XmlAttribute styleA = ruleNode.Attributes["style"]; XmlAttribute optionsA = ruleNode.Attributes["options"]; //Style if (styleA == null) throw new Exception("Rule must contain style name."); if (!styles.ContainsKey(styleA.Value)) throw new Exception("Style '" + styleA.Value + "' is not found."); rule.style = styles[styleA.Value]; //options if (optionsA != null) rule.options = (RegexOptions)Enum.Parse(typeof(RegexOptions), optionsA.Value); return rule; } protected static Style ParseStyle(XmlNode styleNode) { XmlAttribute typeA = styleNode.Attributes["type"]; XmlAttribute colorA = styleNode.Attributes["color"]; XmlAttribute backColorA = styleNode.Attributes["backColor"]; XmlAttribute fontStyleA = styleNode.Attributes["fontStyle"]; XmlAttribute nameA = styleNode.Attributes["name"]; //colors SolidBrush foreBrush = null; if (colorA != null) foreBrush = new SolidBrush(ParseColor(colorA.Value)); SolidBrush backBrush = null; if (backColorA != null) backBrush = new SolidBrush(ParseColor(backColorA.Value)); //fontStyle FontStyle fontStyle = FontStyle.Regular; if (fontStyleA != null) fontStyle = (FontStyle)Enum.Parse(typeof(FontStyle), fontStyleA.Value); return new TextStyle(foreBrush, backBrush, fontStyle); } protected static Color ParseColor(string s) { if (s.StartsWith("#")) { if (s.Length <= 7) return Color.FromArgb(255, Color.FromArgb(Int32.Parse(s.Substring(1), NumberStyles.AllowHexSpecifier))); else return Color.FromArgb(Int32.Parse(s.Substring(1), NumberStyles.AllowHexSpecifier)); } else return Color.FromName(s); } public void HighlightSyntax(SyntaxDescriptor desc, Range range) { //set style order range.tb.ClearStylesBuffer(); for (int i = 0; i < desc.styles.Count; i++) range.tb.Styles[i] = desc.styles[i]; //brackets char[] oldBrackets = RememberBrackets(range.tb); range.tb.LeftBracket = desc.leftBracket; range.tb.RightBracket = desc.rightBracket; range.tb.LeftBracket2 = desc.leftBracket2; range.tb.RightBracket2 = desc.rightBracket2; //clear styles of range range.ClearStyle(desc.styles.ToArray()); //highlight syntax foreach (RuleDesc rule in desc.rules) range.SetStyle(rule.style, rule.Regex); //clear folding range.ClearFoldingMarkers(); //folding markers foreach (FoldingDesc folding in desc.foldings) range.SetFoldingMarkers(folding.startMarkerRegex, folding.finishMarkerRegex, folding.options); // RestoreBrackets(range.tb, oldBrackets); } protected void RestoreBrackets(FastColoredTextBox tb, char[] oldBrackets) { tb.LeftBracket = oldBrackets[0]; tb.RightBracket = oldBrackets[1]; tb.LeftBracket2 = oldBrackets[2]; tb.RightBracket2 = oldBrackets[3]; } protected char[] RememberBrackets(FastColoredTextBox tb) { return new[] { tb.LeftBracket, tb.RightBracket, tb.LeftBracket2, tb.RightBracket2 }; } protected void InitCShaprRegex() { //CSharpStringRegex = new Regex( @"""""|@""""|''|@"".*?""|(?"".*?[^\\]"")|'.*?[^\\]'", RegexCompiledOption); CSharpStringRegex = new Regex( @" # Character definitions: ' (?> # disable backtracking (?: \\[^\r\n]| # escaped meta char [^'\r\n] # any character except ' )* ) '? | # Normal string & verbatim strings definitions: (?@)? # this group matches if it is an verbatim string "" (?> # disable backtracking (?: # match and consume an escaped character including escaped double quote ("") char (?(verbatimIdentifier) # if it is a verbatim string ... """"| # then: only match an escaped double quote ("") char \\. # else: match an escaped sequence ) | # OR # match any char except double quote char ("") [^""] )* ) "" ", RegexOptions.ExplicitCapture | RegexOptions.Singleline | RegexOptions.IgnorePatternWhitespace | RegexCompiledOption ); //thanks to rittergig for this regex CSharpCommentRegex1 = new Regex(@"//.*$", RegexOptions.Multiline | RegexCompiledOption); CSharpCommentRegex2 = new Regex(@"(/\*.*?\*/)|(/\*.*)", RegexOptions.Singleline | RegexCompiledOption); CSharpCommentRegex3 = new Regex(@"(/\*.*?\*/)|(.*\*/)", RegexOptions.Singleline | RegexOptions.RightToLeft | RegexCompiledOption); CSharpNumberRegex = new Regex(@"\b\d+[\.]?\d*([eE]\-?\d+)?[lLdDfF]?\b|\b0x[a-fA-F\d]+\b", RegexCompiledOption); CSharpAttributeRegex = new Regex(@"^\s*(?\[.+?\])\s*$", RegexOptions.Multiline | RegexCompiledOption); CSharpClassNameRegex = new Regex(@"\b(class|struct|enum|interface)\s+(?\w+?)\b", RegexCompiledOption); CSharpKeywordRegex = new Regex( @"\b(abstract|as|base|bool|break|byte|case|catch|char|checked|class|const|continue|decimal|default|delegate|do|double|else|enum|event|explicit|extern|false|finally|fixed|float|for|foreach|goto|if|implicit|in|int|interface|internal|is|lock|long|namespace|new|null|object|operator|out|override|params|private|protected|public|readonly|ref|return|sbyte|sealed|short|sizeof|stackalloc|static|string|struct|switch|this|throw|true|try|typeof|uint|ulong|unchecked|unsafe|ushort|using|virtual|void|volatile|while|add|alias|ascending|descending|dynamic|from|get|global|group|into|join|let|orderby|partial|remove|select|set|value|var|where|yield)\b|#region\b|#endregion\b", RegexCompiledOption); } public void InitStyleSchema(Language lang) { switch (lang) { case Language.CSharp: StringStyle = BrownStyle; CommentStyle = GreenStyle; NumberStyle = MagentaStyle; AttributeStyle = GreenStyle; ClassNameStyle = BoldStyle; KeywordStyle = BlueStyle; CommentTagStyle = GrayStyle; break; case Language.VB: StringStyle = BrownStyle; CommentStyle = GreenStyle; NumberStyle = MagentaStyle; ClassNameStyle = BoldStyle; KeywordStyle = BlueStyle; break; case Language.HTML: CommentStyle = GreenStyle; TagBracketStyle = BlueStyle; TagNameStyle = MaroonStyle; AttributeStyle = RedStyle; AttributeValueStyle = BlueStyle; HtmlEntityStyle = RedStyle; break; case Language.XML: CommentStyle = GreenStyle; XmlTagBracketStyle = BlueStyle; XmlTagNameStyle = MaroonStyle; XmlAttributeStyle = RedStyle; XmlAttributeValueStyle = BlueStyle; XmlEntityStyle = RedStyle; XmlCDataStyle = BlackStyle; break; case Language.JS: StringStyle = BrownStyle; CommentStyle = GreenStyle; NumberStyle = MagentaStyle; KeywordStyle = BlueStyle; break; case Language.Lua: StringStyle = BrownStyle; CommentStyle = GreenStyle; NumberStyle = MagentaStyle; KeywordStyle = BlueBoldStyle; FunctionsStyle = MaroonStyle; break; case Language.PHP: StringStyle = RedStyle; CommentStyle = GreenStyle; NumberStyle = RedStyle; VariableStyle = MaroonStyle; KeywordStyle = MagentaStyle; KeywordStyle2 = BlueStyle; KeywordStyle3 = GrayStyle; break; case Language.SQL: StringStyle = RedStyle; CommentStyle = GreenStyle; NumberStyle = MagentaStyle; KeywordStyle = BlueBoldStyle; StatementsStyle = BlueBoldStyle; FunctionsStyle = MaroonStyle; VariableStyle = MaroonStyle; TypesStyle = BrownStyle; break; } } /// /// Highlights C# code /// /// public virtual void CSharpSyntaxHighlight(Range range) { range.tb.CommentPrefix = "//"; range.tb.LeftBracket = '('; range.tb.RightBracket = ')'; range.tb.LeftBracket2 = '{'; range.tb.RightBracket2 = '}'; range.tb.BracketsHighlightStrategy = BracketsHighlightStrategy.Strategy2; range.tb.AutoIndentCharsPatterns = @" ^\s*[\w\.]+(\s\w+)?\s*(?=)\s*(?[^;]+); ^\s*(case|default)\s*[^:]*(?:)\s*(?[^;]+); "; //clear style of changed range range.ClearStyle(StringStyle, CommentStyle, NumberStyle, AttributeStyle, ClassNameStyle, KeywordStyle); // if (CSharpStringRegex == null) InitCShaprRegex(); //string highlighting range.SetStyle(StringStyle, CSharpStringRegex); //comment highlighting range.SetStyle(CommentStyle, CSharpCommentRegex1); range.SetStyle(CommentStyle, CSharpCommentRegex2); range.SetStyle(CommentStyle, CSharpCommentRegex3); //number highlighting range.SetStyle(NumberStyle, CSharpNumberRegex); //attribute highlighting range.SetStyle(AttributeStyle, CSharpAttributeRegex); //class name highlighting range.SetStyle(ClassNameStyle, CSharpClassNameRegex); //keyword highlighting range.SetStyle(KeywordStyle, CSharpKeywordRegex); //find document comments foreach (Range r in range.GetRanges(@"^\s*///.*$", RegexOptions.Multiline)) { //remove C# highlighting from this fragment r.ClearStyle(StyleIndex.All); //do XML highlighting if (HTMLTagRegex == null) InitHTMLRegex(); // r.SetStyle(CommentStyle); //tags foreach (Range rr in r.GetRanges(HTMLTagContentRegex)) { rr.ClearStyle(StyleIndex.All); rr.SetStyle(CommentTagStyle); } //prefix '///' foreach (Range rr in r.GetRanges(@"^\s*///", RegexOptions.Multiline)) { rr.ClearStyle(StyleIndex.All); rr.SetStyle(CommentTagStyle); } } //clear folding markers range.ClearFoldingMarkers(); //set folding markers range.SetFoldingMarkers("{", "}"); //allow to collapse brackets block range.SetFoldingMarkers(@"#region\b", @"#endregion\b"); //allow to collapse #region blocks range.SetFoldingMarkers(@"/\*", @"\*/"); //allow to collapse comment block } protected void InitVBRegex() { VBStringRegex = new Regex(@"""""|"".*?[^\\]""", RegexCompiledOption); VBCommentRegex = new Regex(@"'.*$", RegexOptions.Multiline | RegexCompiledOption); VBNumberRegex = new Regex(@"\b\d+[\.]?\d*([eE]\-?\d+)?\b", RegexCompiledOption); VBClassNameRegex = new Regex(@"\b(Class|Structure|Enum|Interface)[ ]+(?\w+?)\b", RegexOptions.IgnoreCase | RegexCompiledOption); VBKeywordRegex = new Regex( @"\b(AddHandler|AddressOf|Alias|And|AndAlso|As|Boolean|ByRef|Byte|ByVal|Call|Case|Catch|CBool|CByte|CChar|CDate|CDbl|CDec|Char|CInt|Class|CLng|CObj|Const|Continue|CSByte|CShort|CSng|CStr|CType|CUInt|CULng|CUShort|Date|Decimal|Declare|Default|Delegate|Dim|DirectCast|Do|Double|Each|Else|ElseIf|End|EndIf|Enum|Erase|Error|Event|Exit|False|Finally|For|Friend|Function|Get|GetType|GetXMLNamespace|Global|GoSub|GoTo|Handles|If|Implements|Imports|In|Inherits|Integer|Interface|Is|IsNot|Let|Lib|Like|Long|Loop|Me|Mod|Module|MustInherit|MustOverride|MyBase|MyClass|Namespace|Narrowing|New|Next|Not|Nothing|NotInheritable|NotOverridable|Object|Of|On|Operator|Option|Optional|Or|OrElse|Overloads|Overridable|Overrides|ParamArray|Partial|Private|Property|Protected|Public|RaiseEvent|ReadOnly|ReDim|REM|RemoveHandler|Resume|Return|SByte|Select|Set|Shadows|Shared|Short|Single|Static|Step|Stop|String|Structure|Sub|SyncLock|Then|Throw|To|True|Try|TryCast|TypeOf|UInteger|ULong|UShort|Using|Variant|Wend|When|While|Widening|With|WithEvents|WriteOnly|Xor|Region)\b|(#Const|#Else|#ElseIf|#End|#If|#Region)\b", RegexOptions.IgnoreCase | RegexCompiledOption); } /// /// Highlights VB code /// /// public virtual void VBSyntaxHighlight(Range range) { range.tb.CommentPrefix = "'"; range.tb.LeftBracket = '('; range.tb.RightBracket = ')'; range.tb.LeftBracket2 = '\x0'; range.tb.RightBracket2 = '\x0'; range.tb.AutoIndentCharsPatterns = @" ^\s*[\w\.\(\)]+\s*(?=)\s*(?.+) "; //clear style of changed range range.ClearStyle(StringStyle, CommentStyle, NumberStyle, ClassNameStyle, KeywordStyle); // if (VBStringRegex == null) InitVBRegex(); //string highlighting range.SetStyle(StringStyle, VBStringRegex); //comment highlighting range.SetStyle(CommentStyle, VBCommentRegex); //number highlighting range.SetStyle(NumberStyle, VBNumberRegex); //class name highlighting range.SetStyle(ClassNameStyle, VBClassNameRegex); //keyword highlighting range.SetStyle(KeywordStyle, VBKeywordRegex); //clear folding markers range.ClearFoldingMarkers(); //set folding markers range.SetFoldingMarkers(@"#Region\b", @"#End\s+Region\b", RegexOptions.IgnoreCase); range.SetFoldingMarkers(@"\b(Class|Property|Enum|Structure|Interface)[ \t]+\S+", @"\bEnd (Class|Property|Enum|Structure|Interface)\b", RegexOptions.IgnoreCase); range.SetFoldingMarkers(@"^\s*(?While)[ \t]+\S+", @"^\s*(?End While)\b", RegexOptions.Multiline | RegexOptions.IgnoreCase); range.SetFoldingMarkers(@"\b(Sub|Function)[ \t]+[^\s']+", @"\bEnd (Sub|Function)\b", RegexOptions.IgnoreCase); //this declared separately because Sub and Function can be unclosed range.SetFoldingMarkers(@"(\r|\n|^)[ \t]*(?Get|Set)[ \t]*(\r|\n|$)", @"\bEnd (Get|Set)\b", RegexOptions.IgnoreCase); range.SetFoldingMarkers(@"^\s*(?For|For\s+Each)\b", @"^\s*(?Next)\b", RegexOptions.Multiline | RegexOptions.IgnoreCase); range.SetFoldingMarkers(@"^\s*(?Do)\b", @"^\s*(?Loop)\b", RegexOptions.Multiline | RegexOptions.IgnoreCase); } protected void InitHTMLRegex() { HTMLCommentRegex1 = new Regex(@"()|()|(.*-->)", RegexOptions.Singleline | RegexOptions.RightToLeft | RegexCompiledOption); HTMLTagRegex = new Regex(@"<|/>|", RegexCompiledOption); HTMLTagNameRegex = new Regex(@"<(?[!\w:]+)", RegexCompiledOption); HTMLEndTagRegex = new Regex(@"[\w:]+)>", RegexCompiledOption); HTMLTagContentRegex = new Regex(@"<[^>]+>", RegexCompiledOption); HTMLAttrRegex = new Regex( @"(?[\w\d\-]{1,20}?)='[^']*'|(?[\w\d\-]{1,20})=""[^""]*""|(?[\w\d\-]{1,20})=[\w\d\-]{1,20}", RegexCompiledOption); HTMLAttrValRegex = new Regex( @"[\w\d\-]{1,20}?=(?'[^']*')|[\w\d\-]{1,20}=(?""[^""]*"")|[\w\d\-]{1,20}=(?[\w\d\-]{1,20})", RegexCompiledOption); HTMLEntityRegex = new Regex(@"\&(amp|gt|lt|nbsp|quot|apos|copy|reg|#[0-9]{1,8}|#x[0-9a-f]{1,8});", RegexCompiledOption | RegexOptions.IgnoreCase); } /// /// Highlights HTML code /// /// public virtual void HTMLSyntaxHighlight(Range range) { range.tb.CommentPrefix = null; range.tb.LeftBracket = '<'; range.tb.RightBracket = '>'; range.tb.LeftBracket2 = '('; range.tb.RightBracket2 = ')'; range.tb.AutoIndentCharsPatterns = @""; //clear style of changed range range.ClearStyle(CommentStyle, TagBracketStyle, TagNameStyle, AttributeStyle, AttributeValueStyle, HtmlEntityStyle); // if (HTMLTagRegex == null) InitHTMLRegex(); //comment highlighting range.SetStyle(CommentStyle, HTMLCommentRegex1); range.SetStyle(CommentStyle, HTMLCommentRegex2); //tag brackets highlighting range.SetStyle(TagBracketStyle, HTMLTagRegex); //tag name range.SetStyle(TagNameStyle, HTMLTagNameRegex); //end of tag range.SetStyle(TagNameStyle, HTMLEndTagRegex); //attributes range.SetStyle(AttributeStyle, HTMLAttrRegex); //attribute values range.SetStyle(AttributeValueStyle, HTMLAttrValRegex); //html entity range.SetStyle(HtmlEntityStyle, HTMLEntityRegex); //clear folding markers range.ClearFoldingMarkers(); //set folding markers range.SetFoldingMarkers("", RegexOptions.IgnoreCase); range.SetFoldingMarkers("", RegexOptions.IgnoreCase); range.SetFoldingMarkers("", RegexOptions.IgnoreCase); range.SetFoldingMarkers("", RegexOptions.IgnoreCase); range.SetFoldingMarkers("", RegexOptions.IgnoreCase); range.SetFoldingMarkers("", RegexOptions.IgnoreCase); range.SetFoldingMarkers("", RegexOptions.IgnoreCase); } protected void InitXMLRegex() { XMLCommentRegex1 = new Regex(@"()|()|(.*-->)", RegexOptions.Singleline | RegexOptions.RightToLeft | RegexCompiledOption); XMLTagRegex = new Regex(@"<\?|<|/>||\?>", RegexCompiledOption); XMLTagNameRegex = new Regex(@"<[?](?[x][m][l]{1})|<(?[!\w:]+)", RegexCompiledOption); XMLEndTagRegex = new Regex(@"[\w:]+)>", RegexCompiledOption); XMLTagContentRegex = new Regex(@"<[^>]+>", RegexCompiledOption); XMLAttrRegex = new Regex( @"(?[\w\d\-\:]+)[ ]*=[ ]*'[^']*'|(?[\w\d\-\:]+)[ ]*=[ ]*""[^""]*""|(?[\w\d\-\:]+)[ ]*=[ ]*[\w\d\-\:]+", RegexCompiledOption); XMLAttrValRegex = new Regex( @"[\w\d\-]+?=(?'[^']*')|[\w\d\-]+[ ]*=[ ]*(?""[^""]*"")|[\w\d\-]+[ ]*=[ ]*(?[\w\d\-]+)", RegexCompiledOption); XMLEntityRegex = new Regex(@"\&(amp|gt|lt|nbsp|quot|apos|copy|reg|#[0-9]{1,8}|#x[0-9a-f]{1,8});", RegexCompiledOption | RegexOptions.IgnoreCase); XMLCDataRegex = new Regex(@"(?>[^]]+|](?!]>))*)]]>", RegexCompiledOption | RegexOptions.IgnoreCase); // http://stackoverflow.com/questions/21681861/i-need-a-regex-that-matches-cdata-elements-in-html XMLFoldingRegex = new Regex(@"<(?/?\w+)\s[^>]*?[^/]>|<(?/?\w+)\s*>", RegexOptions.Singleline | RegexCompiledOption); } /// /// Highlights XML code /// /// public virtual void XMLSyntaxHighlight(Range range) { range.tb.CommentPrefix = null; range.tb.LeftBracket = '<'; range.tb.RightBracket = '>'; range.tb.LeftBracket2 = '('; range.tb.RightBracket2 = ')'; range.tb.AutoIndentCharsPatterns = @""; //clear style of changed range range.ClearStyle(CommentStyle, XmlTagBracketStyle, XmlTagNameStyle, XmlAttributeStyle, XmlAttributeValueStyle, XmlEntityStyle, XmlCDataStyle); // if (XMLTagRegex == null) { InitXMLRegex(); } //xml CData range.SetStyle(XmlCDataStyle, XMLCDataRegex); //comment highlighting range.SetStyle(CommentStyle, XMLCommentRegex1); range.SetStyle(CommentStyle, XMLCommentRegex2); //tag brackets highlighting range.SetStyle(XmlTagBracketStyle, XMLTagRegex); //tag name range.SetStyle(XmlTagNameStyle, XMLTagNameRegex); //end of tag range.SetStyle(XmlTagNameStyle, XMLEndTagRegex); //attributes range.SetStyle(XmlAttributeStyle, XMLAttrRegex); //attribute values range.SetStyle(XmlAttributeValueStyle, XMLAttrValRegex); //xml entity range.SetStyle(XmlEntityStyle, XMLEntityRegex); //clear folding markers range.ClearFoldingMarkers(); //set folding markers XmlFolding(range); } private void XmlFolding(Range range) { var stack = new Stack(); var id = 0; var fctb = range.tb; //extract opening and closing tags (exclude open-close tags: ) foreach (var r in range.GetRanges(XMLFoldingRegex)) { var tagName = r.Text; var iLine = r.Start.iLine; //if it is opening tag... if (tagName[0] != '/') { // ...push into stack var tag = new XmlFoldingTag {Name = tagName, id = id++, startLine = r.Start.iLine}; stack.Push(tag); // if this line has no markers - set marker if (string.IsNullOrEmpty(fctb[iLine].FoldingStartMarker)) fctb[iLine].FoldingStartMarker = tag.Marker; } else { //if it is closing tag - pop from stack if (stack.Count > 0) { var tag = stack.Pop(); //compare line number if (iLine == tag.startLine) { //remove marker, because same line can not be folding if (fctb[iLine].FoldingStartMarker == tag.Marker) //was it our marker? fctb[iLine].FoldingStartMarker = null; } else { //set end folding marker if (string.IsNullOrEmpty(fctb[iLine].FoldingEndMarker)) fctb[iLine].FoldingEndMarker = tag.Marker; } } } } } class XmlFoldingTag { public string Name; public int id; public int startLine; public string Marker { get { return Name + id; } } } protected void InitSQLRegex() { SQLStringRegex = new Regex(@"""""|''|"".*?[^\\]""|'.*?[^\\]'", RegexCompiledOption); SQLNumberRegex = new Regex(@"\b\d+[\.]?\d*([eE]\-?\d+)?\b", RegexCompiledOption); SQLCommentRegex1 = new Regex(@"--.*$", RegexOptions.Multiline | RegexCompiledOption); SQLCommentRegex2 = new Regex(@"(/\*.*?\*/)|(/\*.*)", RegexOptions.Singleline | RegexCompiledOption); SQLCommentRegex3 = new Regex(@"(/\*.*?\*/)|(.*\*/)", RegexOptions.Singleline | RegexOptions.RightToLeft | RegexCompiledOption); SQLVarRegex = new Regex(@"@[a-zA-Z_\d]*\b", RegexCompiledOption); SQLStatementsRegex = new Regex(@"\b(ALTER APPLICATION ROLE|ALTER ASSEMBLY|ALTER ASYMMETRIC KEY|ALTER AUTHORIZATION|ALTER BROKER PRIORITY|ALTER CERTIFICATE|ALTER CREDENTIAL|ALTER CRYPTOGRAPHIC PROVIDER|ALTER DATABASE|ALTER DATABASE AUDIT SPECIFICATION|ALTER DATABASE ENCRYPTION KEY|ALTER ENDPOINT|ALTER EVENT SESSION|ALTER FULLTEXT CATALOG|ALTER FULLTEXT INDEX|ALTER FULLTEXT STOPLIST|ALTER FUNCTION|ALTER INDEX|ALTER LOGIN|ALTER MASTER KEY|ALTER MESSAGE TYPE|ALTER PARTITION FUNCTION|ALTER PARTITION SCHEME|ALTER PROCEDURE|ALTER QUEUE|ALTER REMOTE SERVICE BINDING|ALTER RESOURCE GOVERNOR|ALTER RESOURCE POOL|ALTER ROLE|ALTER ROUTE|ALTER SCHEMA|ALTER SERVER AUDIT|ALTER SERVER AUDIT SPECIFICATION|ALTER SERVICE|ALTER SERVICE MASTER KEY|ALTER SYMMETRIC KEY|ALTER TABLE|ALTER TRIGGER|ALTER USER|ALTER VIEW|ALTER WORKLOAD GROUP|ALTER XML SCHEMA COLLECTION|BULK INSERT|CREATE AGGREGATE|CREATE APPLICATION ROLE|CREATE ASSEMBLY|CREATE ASYMMETRIC KEY|CREATE BROKER PRIORITY|CREATE CERTIFICATE|CREATE CONTRACT|CREATE CREDENTIAL|CREATE CRYPTOGRAPHIC PROVIDER|CREATE DATABASE|CREATE DATABASE AUDIT SPECIFICATION|CREATE DATABASE ENCRYPTION KEY|CREATE DEFAULT|CREATE ENDPOINT|CREATE EVENT NOTIFICATION|CREATE EVENT SESSION|CREATE FULLTEXT CATALOG|CREATE FULLTEXT INDEX|CREATE FULLTEXT STOPLIST|CREATE FUNCTION|CREATE INDEX|CREATE LOGIN|CREATE MASTER KEY|CREATE MESSAGE TYPE|CREATE PARTITION FUNCTION|CREATE PARTITION SCHEME|CREATE PROCEDURE|CREATE QUEUE|CREATE REMOTE SERVICE BINDING|CREATE RESOURCE POOL|CREATE ROLE|CREATE ROUTE|CREATE RULE|CREATE SCHEMA|CREATE SERVER AUDIT|CREATE SERVER AUDIT SPECIFICATION|CREATE SERVICE|CREATE SPATIAL INDEX|CREATE STATISTICS|CREATE SYMMETRIC KEY|CREATE SYNONYM|CREATE TABLE|CREATE TRIGGER|CREATE TYPE|CREATE USER|CREATE VIEW|CREATE WORKLOAD GROUP|CREATE XML INDEX|CREATE XML SCHEMA COLLECTION|DELETE|DISABLE TRIGGER|DROP AGGREGATE|DROP APPLICATION ROLE|DROP ASSEMBLY|DROP ASYMMETRIC KEY|DROP BROKER PRIORITY|DROP CERTIFICATE|DROP CONTRACT|DROP CREDENTIAL|DROP CRYPTOGRAPHIC PROVIDER|DROP DATABASE|DROP DATABASE AUDIT SPECIFICATION|DROP DATABASE ENCRYPTION KEY|DROP DEFAULT|DROP ENDPOINT|DROP EVENT NOTIFICATION|DROP EVENT SESSION|DROP FULLTEXT CATALOG|DROP FULLTEXT INDEX|DROP FULLTEXT STOPLIST|DROP FUNCTION|DROP INDEX|DROP LOGIN|DROP MASTER KEY|DROP MESSAGE TYPE|DROP PARTITION FUNCTION|DROP PARTITION SCHEME|DROP PROCEDURE|DROP QUEUE|DROP REMOTE SERVICE BINDING|DROP RESOURCE POOL|DROP ROLE|DROP ROUTE|DROP RULE|DROP SCHEMA|DROP SERVER AUDIT|DROP SERVER AUDIT SPECIFICATION|DROP SERVICE|DROP SIGNATURE|DROP STATISTICS|DROP SYMMETRIC KEY|DROP SYNONYM|DROP TABLE|DROP TRIGGER|DROP TYPE|DROP USER|DROP VIEW|DROP WORKLOAD GROUP|DROP XML SCHEMA COLLECTION|ENABLE TRIGGER|EXEC|EXECUTE|REPLACE|FROM|INSERT|MERGE|OPTION|OUTPUT|SELECT|TOP|TRUNCATE TABLE|UPDATE|UPDATE STATISTICS|WHERE|WITH|INTO|IN|SET)\b", RegexOptions.IgnoreCase | RegexCompiledOption); SQLKeywordsRegex = new Regex(@"\b(ADD|ALL|AND|ANY|AS|ASC|AUTHORIZATION|BACKUP|BEGIN|BETWEEN|BREAK|BROWSE|BY|CASCADE|CHECK|CHECKPOINT|CLOSE|CLUSTERED|COLLATE|COLUMN|COMMIT|COMPUTE|CONSTRAINT|CONTAINS|CONTINUE|CROSS|CURRENT|CURRENT_DATE|CURRENT_TIME|CURSOR|DATABASE|DBCC|DEALLOCATE|DECLARE|DEFAULT|DENY|DESC|DISK|DISTINCT|DISTRIBUTED|DOUBLE|DUMP|ELSE|END|ERRLVL|ESCAPE|EXCEPT|EXISTS|EXIT|EXTERNAL|FETCH|FILE|FILLFACTOR|FOR|FOREIGN|FREETEXT|FULL|FUNCTION|GOTO|GRANT|GROUP|HAVING|HOLDLOCK|IDENTITY|IDENTITY_INSERT|IDENTITYCOL|IF|INDEX|INNER|INTERSECT|IS|JOIN|KEY|KILL|LIKE|LINENO|LOAD|NATIONAL|NOCHECK|NONCLUSTERED|NOT|NULL|OF|OFF|OFFSETS|ON|OPEN|OR|ORDER|OUTER|OVER|PERCENT|PIVOT|PLAN|PRECISION|PRIMARY|PRINT|PROC|PROCEDURE|PUBLIC|RAISERROR|READ|READTEXT|RECONFIGURE|REFERENCES|REPLICATION|RESTORE|RESTRICT|RETURN|REVERT|REVOKE|ROLLBACK|ROWCOUNT|ROWGUIDCOL|RULE|SAVE|SCHEMA|SECURITYAUDIT|SHUTDOWN|SOME|STATISTICS|TABLE|TABLESAMPLE|TEXTSIZE|THEN|TO|TRAN|TRANSACTION|TRIGGER|TSEQUAL|UNION|UNIQUE|UNPIVOT|UPDATETEXT|USE|USER|VALUES|VARYING|VIEW|WAITFOR|WHEN|WHILE|WRITETEXT)\b", RegexOptions.IgnoreCase | RegexCompiledOption); SQLFunctionsRegex = new Regex(@"(@@CONNECTIONS|@@CPU_BUSY|@@CURSOR_ROWS|@@DATEFIRST|@@DATEFIRST|@@DBTS|@@ERROR|@@FETCH_STATUS|@@IDENTITY|@@IDLE|@@IO_BUSY|@@LANGID|@@LANGUAGE|@@LOCK_TIMEOUT|@@MAX_CONNECTIONS|@@MAX_PRECISION|@@NESTLEVEL|@@OPTIONS|@@PACKET_ERRORS|@@PROCID|@@REMSERVER|@@ROWCOUNT|@@SERVERNAME|@@SERVICENAME|@@SPID|@@TEXTSIZE|@@TRANCOUNT|@@VERSION)\b|\b(ABS|ACOS|APP_NAME|ASCII|ASIN|ASSEMBLYPROPERTY|AsymKey_ID|ASYMKEY_ID|asymkeyproperty|ASYMKEYPROPERTY|ATAN|ATN2|AVG|CASE|CAST|CEILING|Cert_ID|Cert_ID|CertProperty|CHAR|CHARINDEX|CHECKSUM_AGG|COALESCE|COL_LENGTH|COL_NAME|COLLATIONPROPERTY|COLLATIONPROPERTY|COLUMNPROPERTY|COLUMNS_UPDATED|COLUMNS_UPDATED|CONTAINSTABLE|CONVERT|COS|COT|COUNT|COUNT_BIG|CRYPT_GEN_RANDOM|CURRENT_TIMESTAMP|CURRENT_TIMESTAMP|CURRENT_USER|CURRENT_USER|CURSOR_STATUS|DATABASE_PRINCIPAL_ID|DATABASE_PRINCIPAL_ID|DATABASEPROPERTY|DATABASEPROPERTYEX|DATALENGTH|DATALENGTH|DATEADD|DATEDIFF|DATENAME|DATEPART|DAY|DB_ID|DB_NAME|DECRYPTBYASYMKEY|DECRYPTBYCERT|DECRYPTBYKEY|DECRYPTBYKEYAUTOASYMKEY|DECRYPTBYKEYAUTOCERT|DECRYPTBYPASSPHRASE|DEGREES|DENSE_RANK|DIFFERENCE|ENCRYPTBYASYMKEY|ENCRYPTBYCERT|ENCRYPTBYKEY|ENCRYPTBYPASSPHRASE|ERROR_LINE|ERROR_MESSAGE|ERROR_NUMBER|ERROR_PROCEDURE|ERROR_SEVERITY|ERROR_STATE|EVENTDATA|EXP|FILE_ID|FILE_IDEX|FILE_NAME|FILEGROUP_ID|FILEGROUP_NAME|FILEGROUPPROPERTY|FILEPROPERTY|FLOOR|fn_helpcollations|fn_listextendedproperty|fn_servershareddrives|fn_virtualfilestats|fn_virtualfilestats|FORMATMESSAGE|FREETEXTTABLE|FULLTEXTCATALOGPROPERTY|FULLTEXTSERVICEPROPERTY|GETANSINULL|GETDATE|GETUTCDATE|GROUPING|HAS_PERMS_BY_NAME|HOST_ID|HOST_NAME|IDENT_CURRENT|IDENT_CURRENT|IDENT_INCR|IDENT_INCR|IDENT_SEED|IDENTITY\(|INDEX_COL|INDEXKEY_PROPERTY|INDEXPROPERTY|IS_MEMBER|IS_OBJECTSIGNED|IS_SRVROLEMEMBER|ISDATE|ISDATE|ISNULL|ISNUMERIC|Key_GUID|Key_GUID|Key_ID|Key_ID|KEY_NAME|KEY_NAME|LEFT|LEN|LOG|LOG10|LOWER|LTRIM|MAX|MIN|MONTH|NCHAR|NEWID|NTILE|NULLIF|OBJECT_DEFINITION|OBJECT_ID|OBJECT_NAME|OBJECT_SCHEMA_NAME|OBJECTPROPERTY|OBJECTPROPERTYEX|OPENDATASOURCE|OPENQUERY|OPENROWSET|OPENXML|ORIGINAL_LOGIN|ORIGINAL_LOGIN|PARSENAME|PATINDEX|PATINDEX|PERMISSIONS|PI|POWER|PUBLISHINGSERVERNAME|PWDCOMPARE|PWDENCRYPT|QUOTENAME|RADIANS|RAND|RANK|REPLICATE|REVERSE|RIGHT|ROUND|ROW_NUMBER|ROWCOUNT_BIG|RTRIM|SCHEMA_ID|SCHEMA_ID|SCHEMA_NAME|SCHEMA_NAME|SCOPE_IDENTITY|SERVERPROPERTY|SESSION_USER|SESSION_USER|SESSIONPROPERTY|SETUSER|SIGN|SignByAsymKey|SignByCert|SIN|SOUNDEX|SPACE|SQL_VARIANT_PROPERTY|SQRT|SQUARE|STATS_DATE|STDEV|STDEVP|STR|STUFF|SUBSTRING|SUM|SUSER_ID|SUSER_NAME|SUSER_SID|SUSER_SNAME|SWITCHOFFSET|SYMKEYPROPERTY|symkeyproperty|sys\.dm_db_index_physical_stats|sys\.fn_builtin_permissions|sys\.fn_my_permissions|SYSDATETIME|SYSDATETIMEOFFSET|SYSTEM_USER|SYSTEM_USER|SYSUTCDATETIME|TAN|TERTIARY_WEIGHTS|TEXTPTR|TODATETIMEOFFSET|TRIGGER_NESTLEVEL|TYPE_ID|TYPE_NAME|TYPEPROPERTY|UNICODE|UPDATE\(|UPPER|USER_ID|USER_NAME|USER_NAME|VAR|VARP|VerifySignedByAsymKey|VerifySignedByCert|XACT_STATE|YEAR)\b", RegexOptions.IgnoreCase | RegexCompiledOption); SQLTypesRegex = new Regex( @"\b(BIGINT|NUMERIC|BIT|SMALLINT|DECIMAL|SMALLMONEY|INT|TINYINT|MONEY|FLOAT|REAL|DATE|DATETIMEOFFSET|DATETIME2|SMALLDATETIME|DATETIME|TIME|CHAR|VARCHAR|TEXT|NCHAR|NVARCHAR|NTEXT|BINARY|VARBINARY|IMAGE|TIMESTAMP|HIERARCHYID|TABLE|UNIQUEIDENTIFIER|SQL_VARIANT|XML)\b", RegexOptions.IgnoreCase | RegexCompiledOption); } /// /// Highlights SQL code /// /// public virtual void SQLSyntaxHighlight(Range range) { range.tb.CommentPrefix = "--"; range.tb.LeftBracket = '('; range.tb.RightBracket = ')'; range.tb.LeftBracket2 = '\x0'; range.tb.RightBracket2 = '\x0'; range.tb.AutoIndentCharsPatterns = @""; //clear style of changed range range.ClearStyle(CommentStyle, StringStyle, NumberStyle, VariableStyle, StatementsStyle, KeywordStyle, FunctionsStyle, TypesStyle); // if (SQLStringRegex == null) InitSQLRegex(); //comment highlighting range.SetStyle(CommentStyle, SQLCommentRegex1); range.SetStyle(CommentStyle, SQLCommentRegex2); range.SetStyle(CommentStyle, SQLCommentRegex3); //string highlighting range.SetStyle(StringStyle, SQLStringRegex); //number highlighting range.SetStyle(NumberStyle, SQLNumberRegex); //types highlighting range.SetStyle(TypesStyle, SQLTypesRegex); //var highlighting range.SetStyle(VariableStyle, SQLVarRegex); //statements range.SetStyle(StatementsStyle, SQLStatementsRegex); //keywords range.SetStyle(KeywordStyle, SQLKeywordsRegex); //functions range.SetStyle(FunctionsStyle, SQLFunctionsRegex); //clear folding markers range.ClearFoldingMarkers(); //set folding markers range.SetFoldingMarkers(@"\bBEGIN\b", @"\bEND\b", RegexOptions.IgnoreCase); //allow to collapse BEGIN..END blocks range.SetFoldingMarkers(@"/\*", @"\*/"); //allow to collapse comment block } protected void InitPHPRegex() { PHPStringRegex = new Regex(@"""""|''|"".*?[^\\]""|'.*?[^\\]'", RegexCompiledOption); PHPNumberRegex = new Regex(@"\b\d+[\.]?\d*\b", RegexCompiledOption); PHPCommentRegex1 = new Regex(@"(//|#).*$", RegexOptions.Multiline | RegexCompiledOption); PHPCommentRegex2 = new Regex(@"(/\*.*?\*/)|(/\*.*)", RegexOptions.Singleline | RegexCompiledOption); PHPCommentRegex3 = new Regex(@"(/\*.*?\*/)|(.*\*/)", RegexOptions.Singleline | RegexOptions.RightToLeft | RegexCompiledOption); PHPVarRegex = new Regex(@"\$[a-zA-Z_\d]*\b", RegexCompiledOption); PHPKeywordRegex1 = new Regex( @"\b(die|echo|empty|exit|eval|include|include_once|isset|list|require|require_once|return|print|unset)\b", RegexCompiledOption); PHPKeywordRegex2 = new Regex( @"\b(abstract|and|array|as|break|case|catch|cfunction|class|clone|const|continue|declare|default|do|else|elseif|enddeclare|endfor|endforeach|endif|endswitch|endwhile|extends|final|for|foreach|function|global|goto|if|implements|instanceof|interface|namespace|new|or|private|protected|public|static|switch|throw|try|use|var|while|xor)\b", RegexCompiledOption); PHPKeywordRegex3 = new Regex(@"__CLASS__|__DIR__|__FILE__|__LINE__|__FUNCTION__|__METHOD__|__NAMESPACE__", RegexCompiledOption); } /// /// Highlights PHP code /// /// public virtual void PHPSyntaxHighlight(Range range) { range.tb.CommentPrefix = "//"; range.tb.LeftBracket = '('; range.tb.RightBracket = ')'; range.tb.LeftBracket2 = '{'; range.tb.RightBracket2 = '}'; range.tb.BracketsHighlightStrategy = BracketsHighlightStrategy.Strategy2; //clear style of changed range range.ClearStyle(StringStyle, CommentStyle, NumberStyle, VariableStyle, KeywordStyle, KeywordStyle2, KeywordStyle3); range.tb.AutoIndentCharsPatterns = @" ^\s*\$[\w\.\[\]\'\""]+\s*(?=)\s*(?[^;]+); "; // if (PHPStringRegex == null) InitPHPRegex(); //string highlighting range.SetStyle(StringStyle, PHPStringRegex); //comment highlighting range.SetStyle(CommentStyle, PHPCommentRegex1); range.SetStyle(CommentStyle, PHPCommentRegex2); range.SetStyle(CommentStyle, PHPCommentRegex3); //number highlighting range.SetStyle(NumberStyle, PHPNumberRegex); //var highlighting range.SetStyle(VariableStyle, PHPVarRegex); //keyword highlighting range.SetStyle(KeywordStyle, PHPKeywordRegex1); range.SetStyle(KeywordStyle2, PHPKeywordRegex2); range.SetStyle(KeywordStyle3, PHPKeywordRegex3); //clear folding markers range.ClearFoldingMarkers(); //set folding markers range.SetFoldingMarkers("{", "}"); //allow to collapse brackets block range.SetFoldingMarkers(@"/\*", @"\*/"); //allow to collapse comment block } protected void InitJScriptRegex() { JScriptStringRegex = new Regex(@"""""|''|"".*?[^\\]""|'.*?[^\\]'", RegexCompiledOption); JScriptCommentRegex1 = new Regex(@"//.*$", RegexOptions.Multiline | RegexCompiledOption); JScriptCommentRegex2 = new Regex(@"(/\*.*?\*/)|(/\*.*)", RegexOptions.Singleline | RegexCompiledOption); JScriptCommentRegex3 = new Regex(@"(/\*.*?\*/)|(.*\*/)", RegexOptions.Singleline | RegexOptions.RightToLeft | RegexCompiledOption); JScriptNumberRegex = new Regex(@"\b\d+[\.]?\d*([eE]\-?\d+)?[lLdDfF]?\b|\b0x[a-fA-F\d]+\b", RegexCompiledOption); JScriptKeywordRegex = new Regex( @"\b(true|false|break|case|catch|const|continue|default|delete|do|else|export|for|function|if|in|instanceof|new|null|return|switch|this|throw|try|var|void|while|with|typeof)\b", RegexCompiledOption); } /// /// Highlights JavaScript code /// /// public virtual void JScriptSyntaxHighlight(Range range) { range.tb.CommentPrefix = "//"; range.tb.LeftBracket = '('; range.tb.RightBracket = ')'; range.tb.LeftBracket2 = '{'; range.tb.RightBracket2 = '}'; range.tb.BracketsHighlightStrategy = BracketsHighlightStrategy.Strategy2; range.tb.AutoIndentCharsPatterns = @" ^\s*[\w\.]+(\s\w+)?\s*(?=)\s*(?[^;]+); "; //clear style of changed range range.ClearStyle(StringStyle, CommentStyle, NumberStyle, KeywordStyle); // if (JScriptStringRegex == null) InitJScriptRegex(); //string highlighting range.SetStyle(StringStyle, JScriptStringRegex); //comment highlighting range.SetStyle(CommentStyle, JScriptCommentRegex1); range.SetStyle(CommentStyle, JScriptCommentRegex2); range.SetStyle(CommentStyle, JScriptCommentRegex3); //number highlighting range.SetStyle(NumberStyle, JScriptNumberRegex); //keyword highlighting range.SetStyle(KeywordStyle, JScriptKeywordRegex); //clear folding markers range.ClearFoldingMarkers(); //set folding markers range.SetFoldingMarkers("{", "}"); //allow to collapse brackets block range.SetFoldingMarkers(@"/\*", @"\*/"); //allow to collapse comment block } protected void InitLuaRegex() { LuaStringRegex = new Regex(@"""""|''|"".*?[^\\]""|'.*?[^\\]'", RegexCompiledOption); LuaCommentRegex1 = new Regex(@"--.*$", RegexOptions.Multiline | RegexCompiledOption); LuaCommentRegex2 = new Regex(@"(--\[\[.*?\]\])|(--\[\[.*)", RegexOptions.Singleline | RegexCompiledOption); LuaCommentRegex3 = new Regex(@"(--\[\[.*?\]\])|(.*\]\])", RegexOptions.Singleline | RegexOptions.RightToLeft | RegexCompiledOption); LuaNumberRegex = new Regex(@"\b\d+[\.]?\d*([eE]\-?\d+)?[lLdDfF]?\b|\b0x[a-fA-F\d]+\b", RegexCompiledOption); LuaKeywordRegex = new Regex( @"\b(and|break|do|else|elseif|end|false|for|function|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b", RegexCompiledOption); LuaFunctionsRegex = new Regex( @"\b(assert|collectgarbage|dofile|error|getfenv|getmetatable|ipairs|load|loadfile|loadstring|module|next|pairs|pcall|print|rawequal|rawget|rawset|require|select|setfenv|setmetatable|tonumber|tostring|type|unpack|xpcall)\b", RegexCompiledOption); } /// /// Highlights Lua code /// /// public virtual void LuaSyntaxHighlight(Range range) { range.tb.CommentPrefix = "--"; range.tb.LeftBracket = '('; range.tb.RightBracket = ')'; range.tb.LeftBracket2 = '{'; range.tb.RightBracket2 = '}'; range.tb.BracketsHighlightStrategy = BracketsHighlightStrategy.Strategy2; range.tb.AutoIndentCharsPatterns = @" ^\s*[\w\.]+(\s\w+)?\s*(?=)\s*(?.+) "; //clear style of changed range range.ClearStyle(StringStyle, CommentStyle, NumberStyle, KeywordStyle, FunctionsStyle); // if (LuaStringRegex == null) InitLuaRegex(); //string highlighting range.SetStyle(StringStyle, LuaStringRegex); //comment highlighting range.SetStyle(CommentStyle, LuaCommentRegex1); range.SetStyle(CommentStyle, LuaCommentRegex2); range.SetStyle(CommentStyle, LuaCommentRegex3); //number highlighting range.SetStyle(NumberStyle, LuaNumberRegex); //keyword highlighting range.SetStyle(KeywordStyle, LuaKeywordRegex); //functions highlighting range.SetStyle(FunctionsStyle, LuaFunctionsRegex); //clear folding markers range.ClearFoldingMarkers(); //set folding markers range.SetFoldingMarkers("{", "}"); //allow to collapse brackets block range.SetFoldingMarkers(@"--\[\[", @"\]\]"); //allow to collapse comment block } protected void LuaAutoIndentNeeded(object sender, AutoIndentEventArgs args) { //end of block if (Regex.IsMatch(args.LineText, @"^\s*(end|until)\b")) { args.Shift = -args.TabLength; args.ShiftNextLines = -args.TabLength; return; } // then ... if (Regex.IsMatch(args.LineText, @"\b(then)\s*\S+")) return; //start of operator block if (Regex.IsMatch(args.LineText, @"^\s*(function|do|for|while|repeat|if)\b")) { args.ShiftNextLines = args.TabLength; return; } //Statements else, elseif, case etc if (Regex.IsMatch(args.LineText, @"^\s*(else|elseif)\b", RegexOptions.IgnoreCase)) { args.Shift = -args.TabLength; return; } } #region Styles /// /// String style /// public Style StringStyle { get; set; } /// /// Comment style /// public Style CommentStyle { get; set; } /// /// Number style /// public Style NumberStyle { get; set; } /// /// C# attribute style /// public Style AttributeStyle { get; set; } /// /// Class name style /// public Style ClassNameStyle { get; set; } /// /// Keyword style /// public Style KeywordStyle { get; set; } /// /// Style of tags in comments of C# /// public Style CommentTagStyle { get; set; } /// /// HTML attribute value style /// public Style AttributeValueStyle { get; set; } /// /// HTML tag brackets style /// public Style TagBracketStyle { get; set; } /// /// HTML tag name style /// public Style TagNameStyle { get; set; } /// /// HTML Entity style /// public Style HtmlEntityStyle { get; set; } /// /// XML attribute style /// public Style XmlAttributeStyle { get; set; } /// /// XML attribute value style /// public Style XmlAttributeValueStyle { get; set; } /// /// XML tag brackets style /// public Style XmlTagBracketStyle { get; set; } /// /// XML tag name style /// public Style XmlTagNameStyle { get; set; } /// /// XML Entity style /// public Style XmlEntityStyle { get; set; } /// /// XML CData style /// public Style XmlCDataStyle { get; set; } /// /// Variable style /// public Style VariableStyle { get; set; } /// /// Specific PHP keyword style /// public Style KeywordStyle2 { get; set; } /// /// Specific PHP keyword style /// public Style KeywordStyle3 { get; set; } /// /// SQL Statements style /// public Style StatementsStyle { get; set; } /// /// SQL Functions style /// public Style FunctionsStyle { get; set; } /// /// SQL Types style /// public Style TypesStyle { get; set; } #endregion } /// /// Language /// public enum Language { Custom, CSharp, VB, HTML, XML, SQL, PHP, JS, Lua } }