How do I create an AvalonEdit syntax file (.xshd) and embed it into my assembly?

Joe White picture Joe White · Feb 20, 2011 · Viewed 13.4k times · Source

I'm trying to define some custom highlighting rules for AvalonEdit. There doesn't seem to be any documentation for this -- there's some documentation on the file format, but nothing on how to actually load and use the definition once you've created it.

The "Syntax highlighting" wiki page (for the old WinForms TextEditor) documents how to load highlighting definitions from a .xshd file on disk, but I'd rather embed it as a resource, the same way AvalonEdit does with its built-in definitions.

I've looked at the code in the ICSharpCode.AvalonEdit project that loads its built-in highlighters, but the actual "load from resource" code is done in DefaultHighlightingManager.LoadHighlighting, which is private -- and which, to make things weirder, is apparently only called in release builds.

I can keep fumbling around, copy/paste some of the code from the private methods, and try to cobble something together that might or might not work, but it seems worthwhile to ask: what is the standard way to do this? Is there a recommended way for third-party code to load a highlighting definition from a resource?


Daniel's answer gave me a good start, but you need to include the namespace name in the string you pass to GetManifestResourceStream -- if you don't, you'll get a NullReferenceException (because it returns a null stream).

I wound up adding a static class called ResourceLoader to the same project folder as the .xshd file, with this method:

public static IHighlightingDefinition LoadHighlightingDefinition(
    string resourceName)
{
    var type = typeof(ResourceLoader);
    var fullName = type.Namespace + "." + resourceName;
    using (var stream = type.Assembly.GetManifestResourceStream(fullName))
    using (var reader = new XmlTextReader(stream))
        return HighlightingLoader.Load(reader, HighlightingManager.Instance);
}

Then I can just call ResourceLoader.LoadHighlightingDefinition("Name.xshd").

For anyone following along at home, the .xshd file needs to have its Build Action set to Embedded Resource.

Answer

Daniel picture Daniel · Feb 20, 2011

You can use the static methods in the class ICSharpCode.AvalonEdit.Highlighting.Xshd.HighlightingLoader to load .xshd files. For example:

using (Stream s = myAssembly.GetManifestResourceStream("MyHighlighting.xshd")) {
    using (XmlTextReader reader = new XmlTextReader(s)) {
        textEditor.SyntaxHighlighting = HighlightingLoader.Load(reader, HighlightingManager.Instance);
    }
}

The loading code in AvalonEdit itself is weird because it eagerly loads the xshds in debug builds (so that errors in them are noticed immediately), but delay-loads them in release builds.