/// <summary> /// Register custom highlighting patterns for usage in the editor /// </summary> public static void RegisterCustomHighlightingPatterns(HighlightingThemes hlThemes = null) { try { HighlightingManager.Instance.InitializeDefinitions(hlThemes); string path = Path.GetDirectoryName(Application.ResourceAssembly.Location); path = Path.Combine(path , "AvalonEdit\\Highlighting"); if (Directory.Exists(path)) { // Some HighlightingDefinitions contain 'import' statements which means that some // XSHDs have to be loaded before others (an exception is thrown otherwise) // Therefore, we use filenames to indicate sequence for loading xshds SortedSet<string> files = new SortedSet<string>(Directory.GetFiles(path).Where(x => { var extension = Path.GetExtension(x); return extension != null && extension.Contains("xshd"); })); foreach (var file in files) { try { var definition = LoadXshdDefinition(file); var hightlight = LoadHighlightingDefinition(file); HighlightingManager.Instance.RegisterHighlighting(definition.Name, definition.Extensions.ToArray(), hightlight); } catch{ throw; } } } } catch{ throw; } }
/// <summary> /// Constructor /// </summary> public HighlightingManager() { sortedHighlightingsByName = new SortedList<string, IHighlightingDefinition>(); listHighlightingsByName = new ObservableCollection<IHighlightingDefinition>(); highlightingsByExtension = new SortedDictionary<string, IHighlightingDefinition>(StringComparer.OrdinalIgnoreCase); allHighlightings = new List<IHighlightingDefinition>(); this.mHlThemes = null; this.BackupDynResources = null; }
/// <summary> /// Print highlighting theme color codes in HTML into the console output /// </summary> /// <param name="hdef"></param> /// <param name="hlThemes"></param> public static void PrintThemeToHTML(IHighlightingDefinition hdef, HighlightingThemes hlThemes) { if (hdef == null || hlThemes == null) { return; } IHighlightingTheme theme = hlThemes.FindTheme(hdef.Name); // Is the current highlighting (eg.: HTML) themable? if (theme != null) { if (hdef.NamedHighlightingColors != null) { Console.WriteLine("<h2>{0}</h2>\n", theme.HlName); Console.WriteLine("<table>"); Console.WriteLine("<tr>"); Console.WriteLine("<td>Code</td>"); Console.WriteLine("<td width=\"100\">Color</td>"); Console.WriteLine("<td>Description</td>"); Console.WriteLine("</tr>"); // Go through each color definition in the highlighting and apply the theme on each match foreach (HighlightingColor c in hdef.NamedHighlightingColors) { IWordsStyle s = theme.GetWordsStyle(c.Name); if (s != null) { if (s.fgColor != null) { Console.WriteLine(string.Format("<tr><td>#{0:x2}{1:x2}{2:x2}</td><td bgColor=\"#{0:x2}{1:x2}{2:x2}\"></td><td>{3}</td></tr>", s.fgColor.Color.R, s.fgColor.Color.G, s.fgColor.Color.B, s.Name)); } } } Console.WriteLine("</table>"); } } }
/// <summary> /// Apply highlighting theme to highlighting pattern definition. /// This results in re-defined highlighting colors while keeping /// rules for regular expression matching. /// </summary> /// <param name="hdef">Current highlighting pattern</param> /// <param name="hlThemes">Collection of highlighting styles to be applied on current highlighting patterns</param> public static void ApplyHighlightingTheme(IHighlightingDefinition hdef, HighlightingThemes hlThemes) { if (hdef == null || hlThemes == null) { return; } HighlightingTheme theme = hlThemes.FindTheme(hdef.Name); // Is the current highlighting (eg.: HTML) themable? if (theme != null) { if (hdef.NamedHighlightingColors != null) { // Go through each color definition in the highlighting and apply the theme on each match foreach (HighlightingColor c in hdef.NamedHighlightingColors) { WordsStyle s = theme.GetWordsStyle(c.Name); if (s != null) { if (s.bgColor != null) { c.Background = new SimpleHighlightingBrush(s.bgColor); } else { c.Background = null; } if (s.fgColor != null) { c.Foreground = new SimpleHighlightingBrush(s.fgColor); } else { c.Foreground = null; } if (s.fontStyle != null) { c.FontStyle = s.fontStyle; } else { c.FontStyle = null; } if (s.fontWeight != null) { c.FontWeight = s.fontWeight; } else { c.FontStyle = null; } } else { logger.WarnFormat("Named Color: '{0}'in '{1}' does not exist in '{2}'.", c.Name, hdef.Name, hlThemes.FileNamePath); } } } } else { logger.WarnFormat("highlighting definition: '{0}' does not have a style in '{1}'.", hdef.Name, hlThemes.FileNamePath); } }
/// <summary> /// Apply highlighting theme to highlighting pattern definition. /// This results in re-defined highlighting colors while keeping /// rules for regular expression matching. /// </summary> /// <param name="hdef">Current highlighting pattern</param> /// <param name="hlThemes">Collection of highlighting styles to be applied on current highlighting patterns</param> public static void ApplyHighlightingTheme(IHighlightingDefinition hdef, HighlightingThemes hlThemes) { if (hdef == null || hlThemes == null) return; HighlightingTheme theme = hlThemes.FindTheme(hdef.Name); // Is the current highlighting (eg.: HTML) themable? if (theme != null) { if (hdef.NamedHighlightingColors != null) { // Go through each color definition in the highlighting and apply the theme on each match foreach (HighlightingColor c in hdef.NamedHighlightingColors) { WordsStyle s = theme.GetWordsStyle(c.Name); if (s != null) { if (s.bgColor != null) c.Background = new SimpleHighlightingBrush(s.bgColor); else c.Background = null; if (s.fgColor != null) c.Foreground = new SimpleHighlightingBrush(s.fgColor); else c.Foreground = null; if (s.fontStyle != null) c.FontStyle = s.fontStyle; else c.FontStyle = null; if (s.fontWeight != null) c.FontWeight = s.fontWeight; else c.FontStyle = null; } else logger.WarnFormat("Named Color: '{0}'in '{1}' does not exist in '{2}'.", c.Name, hdef.Name, hlThemes.FileNamePath); } } } else logger.WarnFormat("highlighting definition: '{0}' does not have a style in '{1}'.", hdef.Name, hlThemes.FileNamePath); }
/// <summary> /// Print highlighting theme color codes in HTML into the console output /// </summary> /// <param name="hdef"></param> /// <param name="hlThemes"></param> public static void PrintThemeToHTML(IHighlightingDefinition hdef, HighlightingThemes hlThemes) { if (hdef == null || hlThemes == null) return; HighlightingTheme theme = hlThemes.FindTheme(hdef.Name); // Is the current highlighting (eg.: HTML) themable? if (theme != null) { if (hdef.NamedHighlightingColors != null) { Console.WriteLine("<h2>{0}</h2>\n", theme.HlName); Console.WriteLine("<table>"); Console.WriteLine("<tr>"); Console.WriteLine("<td>Code</td>"); Console.WriteLine("<td width=\"100\">Color</td>"); Console.WriteLine("<td>Description</td>"); Console.WriteLine("</tr>"); // Go through each color definition in the highlighting and apply the theme on each match foreach (HighlightingColor c in hdef.NamedHighlightingColors) { WordsStyle s = theme.GetWordsStyle(c.Name); if (s != null) { if (s.fgColor != null) Console.WriteLine(string.Format("<tr><td>#{0:x2}{1:x2}{2:x2}</td><td bgColor=\"#{0:x2}{1:x2}{2:x2}\"></td><td>{3}</td></tr>", s.fgColor.Color.R, s.fgColor.Color.G, s.fgColor.Color.B, s.Name)); } } Console.WriteLine("</table>"); } } }
/// <summary> /// Dirkster99 /// Initialize the highlighting definitions to force re-load of definitions /// </summary> public void InitializeDefinitions(HighlightingThemes hlThemes = null ) { lock (lockObj) { this.sortedHighlightingsByName.Clear(); this.listHighlightingsByName.Clear(); this.highlightingsByExtension.Clear(); this.allHighlightings.Clear(); this.mHlThemes = hlThemes; } }
/// <summary> /// Read the LexerStyles XML tag with its attributes (if any) and insert /// a resulting <seealso cref="HighlightingTheme"/> object into the <seealso cref="HighlightingThemes"/> root object. /// </summary> internal static void ReadNode(XmlReader reader, HighlightingThemes HlThemeRoot) { reader.ReadToNextSibling(ReadLexerStyles.XMLName); while (reader.Read()) { if (reader.IsStartElement() == true) { switch (reader.Name) { case ReadLexerType.XMLName: HighlightingTheme t = ReadLexerType.ReadNode(reader.ReadSubtree()); try { HlThemeRoot.AddTheme(t.HlName, t); } catch (Exception e) // Reading one errornous style node should not crash the whole process { logger.Error("Error reading LexerType node", e); } break; case XMLNameSpace: break; default: if (reader.Name.Trim().Length > 0 && reader.Name != XMLComment) logger.Warn("Parsing the XML child:'" + reader.Name + "' of '" + ReadLexerStyles.XMLName + "' is not implemented."); break; } } } }
/// <summary> /// Read the GlobalStyles XML tag with its attributes (if any) and insert /// a resulting <seealso cref="HighlightingTheme"/> object into the <seealso cref="HighlightingThemes"/> root object. /// </summary> internal static void ReadNode(XmlReader reader, HighlightingThemes HlThemeRoot) { reader.ReadToNextSibling(ReadGlobalStyles.XMLName); while (reader.Read()) { if (reader.IsStartElement() == true) { switch (reader.Name) { case ReadWidgetStyle.XMLName_Hyperlink: case ReadWidgetStyle.XMLName_DefaultStyle: WidgetStyle t = ReadWidgetStyle.ReadForegroundBackgroundColorNode(reader.ReadSubtree(), reader.Name); try { HlThemeRoot.AddWidgetStyle(t.Name, t); } catch (Exception e) // Reading one errornous style node should not crash the whole process { logger.Error("Error reading DefaultStyle node", e); } break; case ReadWidgetStyle.XMLName_CurrentLineBackground: t = ReadWidgetStyle.ReadCurrentLineBackgroundNode(reader.ReadSubtree()); try { HlThemeRoot.AddWidgetStyle(t.Name, t); } catch (Exception e) // Reading one errornous style node should not crash the whole process { logger.Error("Error reading CurrentLineBackground node", e); } break; case ReadWidgetStyle.XMLName_LineNumbersForeground: case ReadWidgetStyle.XMLName_NonPrintableCharacter: t = ReadWidgetStyle.ReadForegroundColorNode(reader.ReadSubtree(), reader.Name); try { HlThemeRoot.AddWidgetStyle(t.Name, t); } catch (Exception e) // Reading one errornous style node should not crash the whole process { logger.Error("Error reading LineNumbersForeground node", e); } break; case ReadWidgetStyle.XMLName_Selection: t = ReadWidgetStyle.ReadSelectionNode(reader.ReadSubtree()); try { HlThemeRoot.AddWidgetStyle(t.Name, t); } catch (Exception e) // Reading one errornous style node should not crash the whole process { logger.Error("Error reading Selection node", e); } break; case XMLNameSpace: break; default: if (reader.Name.Trim().Length > 0 && reader.Name != XMLComment) logger.Warn("Parsing the XML child:'" + reader.Name + "' of '" + ReadGlobalStyles.XMLName + "' is not implemented."); break; } } } }
/// <summary> /// Load custom highlighting theme definition from XML file. /// </summary> /// <param name="path"></param> /// <param name="fileName"></param> /// <param name="VerifySchema"></param> /// <returns></returns> public static HighlightingThemes ReadXML(String path = "", String fileName = @"AvalonEdit\HighLighting_Themes\DeepBlack.xshd", bool VerifySchema = true) { if (string.IsNullOrEmpty(path) == true && string.IsNullOrEmpty(fileName) == true) return null; HighlightingThemes HlThemeRoot = null; try { string sPathfileName = fileName; if (string.IsNullOrEmpty( path ) == false) sPathfileName = System.IO.Path.Combine(path, fileName); if (System.IO.File.Exists(sPathfileName) == false) { logger.Error(string.Format(CultureInfo.InvariantCulture, "File '{0}' does not exist at '{1}' or cannot be accessed.", fileName, path)); return null; } if (VerifySchema == true) // Test whether XSD schema is valid or not { List<string> errorMsgs; if ((errorMsgs = TestXML(sPathfileName)) != null) { // log error (if any) and return null foreach(string s in errorMsgs) logger.Error(s); return null; } } using (XmlReader reader = XmlReader.Create(sPathfileName)) { string rootTagName = Read.XMLName; string name = string.Empty; reader.ReadToNextSibling(Read.XMLName); while (reader.MoveToNextAttribute()) { switch (reader.Name) { case Read.attr_name: name = reader.Value; break; case XMLNameSpace: string s = reader.Value; break; } } HlThemeRoot = new HighlightingThemes(name); HlThemeRoot.FileNamePath = sPathfileName; // Find all children that belong into the second level right below the XML root tag while (reader.Read()) { if (reader.NodeType == XmlNodeType.Element) { switch (reader.Name) { case ReadLexerStyles.XMLName: ReadLexerStyles.ReadNode(reader.ReadSubtree(), HlThemeRoot); break; case ReadGlobalStyles.XMLName: ReadGlobalStyles.ReadNode(reader.ReadSubtree(), HlThemeRoot); break; default: if (reader.Name.Trim().Length > 0 && reader.Name != XMLComment) logger.Warn("Parsing the XML child:'" + reader.Name + "' of '" + rootTagName + "' is not implemented."); break; } } } } } catch (Exception e) { logger.Error(string.Format("An error occurred while reading a highlighting theme file at path '{0}', filename '{1}':\n\n", (path == null ? "(null)" : path), (fileName == null ? "(null)" : fileName)) + "Details:" + e.ToString()); return null; } return HlThemeRoot; }