Syntax Highlighting in WordPress.com hosted blogs and how to create a Windows Live Writer Plug-in

There are various ways of displaying code in a blog entry. Some authors insert images which enable them to ensure that the code is readable and in the required format, however the code can’t then be as easily viewed inside some feed readers, and the text is not searchable or easy to copy/paste. Alternatively an author can just type the text in and use indentation and font styles to distinguish it from the body of the text. By far the best solution however is use a Code Highlighter of some sort that will render the code into a readable format with additional benefits of copy to clipboard, line numbers and colour coding. One popular tool for this job is Syntax Highlighter by Alex Gorbatchev. This uses JavaScript to render the code on the client in a very readable format (see below). It integrates well with the WordPress blog engine and there are several Windows Live Writer Plug-ins for it making it easy to add code snippets to your posts.

Having decided on using Syntax Highlighter for my blog I hit a problem. I’m hosting on WordPress.com and therefore do not have the access required to add it to my site. I found a lot of posts on the web discussing how to integrate it with WordPress but these are for self hosted WordPress.org blogs. Eventually however, to much delight, I found that the WordPress.com developers themselves have already integrated Syntax Highlighter. There is a list of supported languages and details on how to use it here. To activate it you just add a wrap your code inside special tags. Excellent!

Writing a Windows Live Writer Plug-in (Part One)

My next thought though was that I needed to integrate into Windows Live Writer via a plug-in. I couldn’t find a WordPress.com specific plug-in so I fired up MSDN and looked at coding one. All the information you need is on MSDN here

There are two types of plugins. Simple and Smart. As I just needed to add a block of code text surrounded by special tags I figured I would implement the simple type. Simple’s good! Right?

To start with I needed to create a new class library project, reference the Live Writer API (windowslive.writer.api.dll), and add a new class which derived from ‘ContentSource’ and has a ‘InsertableContentSourceAttribute’ attribute.

InsertableContentSourceAttribute("Highlighted Source Code")]
public class MyPlugin : ContentSource
{
}


Next override the CreateContent method on the base class. This is the method that gets called when the user clicks to activate our plug-in to insert some content. It returns a DialogResult and has a string parameter passed by-reference called ‘newContent’. This string parameter is how you set the text to be inserted into the blog post.  In the code example shown below I am displaying a form for the user to enter the code block to insert. The form adds the required WordPress.com wrapper text and then the ‘newContent’ string is set to be the whole text content (code plus wrapper text):

public override System.Windows.Forms.DialogResult CreateContent(System.Windows.Forms.IWin32Window dialogOwner, ref string newContent)
{
    using (codeEntryForm entryform = new codeEntryForm())
    {
        entryform.StartPosition = FormStartPosition.CenterParent;
        DialogResult result = entryform.ShowDialog(dialogOwner); 
        if (result == DialogResult.OK)
        {
            newContent = entryform.GetData();
        }                
        return result;
    }
} 


In addition to overriding the CreateContent method the WriterPluginAttribute needs to be set on the class. This basically provides Live Writer with information about your plug-in. For an explanation of the properties see here.

[WriterPlugin (
        "BF15A85A-9668-480d-9FC2-EC5C16FC140D",
        "Wordpress.com Syntax Highliter Plugin",
        ImagePath = "Images.image.bmp",
        PublisherUrl = "http://www.richhewlett.com/",
        Description = "Inserts WordPress.com code highlight tags around code snippets",
        HasEditableOptions=false)
] 

Once done compile it up and copy the assembly to the Plugins folder of your Windows Live writer installation (e.g. C:\Program Files\Windows Live\Writer). When the application starts all the plug-ins in that folder get loaded too. I now had my Syntax Highlighter plug-in, and it worked. I could insert code into my blog post and upload it to the server for WordPress to display using Syntax Highlighter.

Job done then hey? Well not quite. As I had coded this as a SimpleContentSource plug-in once the code snippet had been inserted into the post editor it was treated as plain text (just as if I had written it by hand into the editor). This meant that if I flipped between the Editor and Source windows Live Writer converted my code text to use escape characters. This meant that my code snippet’s quotes and ampersands etc were converted to their friendly alternatives, and WordPress.com would display them without converting them back.

Writing a Windows Live Writer Plug-in (Part Two)

In order to resolve the issue of Live Writer treating my code snippets as regular text I went back to MSDN and found that the SmartContentSource plug-in type provides more control over the HTML that gets sent for publishing. SmartContentSource plug-ins are not treated as regular text and provide more control. Building this type of plug-in is only slightly more work than the less smart plain ContentSource type.

Firstly I needed to change the plug-in class (from above) to override SmartContentSource instead of ContentSource.

[InsertableContentSourceAttribute("Highlighted Source Code")]
public class Plugin : SmartContentSource
{
}    

Then we override the CreateContent method as we did before. Live Writer creates a ISmartContent object and passes it in for us to update with the content the user creates. Again as before this example has a dialog box being shown to the user for them to key the code snippet but this time the data is set within the ISmartContent properties.

public override System.Windows.Forms.DialogResult CreateContent(IWin32Window dialogOwner, ISmartContent newContent)
{
    using (CodeEntryForm entryform = new CodeEntryForm())
    {
        entryform.StartPosition = FormStartPosition.CenterParent;
        DialogResult result = entryform.ShowDialog(dialogOwner); 
        if (result == DialogResult.OK)
        {
            newContent.Properties.SetString("OutputHTML", entryform.GetData());
            newContent.Properties.SetString("RawCode", entryform.GetRawCodeSnippet());
            newContent.Properties.SetString("SelectedLanguage", entryform.GetSelectedLanguage());                    
        }
        return result;
    }
} 


N,B: The reason I’m setting the ‘RawCode’ and the ‘SelectedLanguage’ properties as well as the combined total output is for use later when we want to display the dialog to the user again pre-populated.

In order to ensure that the correct text is being passed to the blog engine for publishing we override the GeneratePublishHtml method. The ISmartContent object passed in has the original data set as one of its properties so in this example I just return that.

public override string GeneratePublishHtml(ISmartContent content, IPublishingContext publishingContext)
{
    return content.Properties["OutputHTML"].ToString();
} 

This gets around the original problem that I experienced with the first ContentSource plug-in. Also SmartContentSource plug-ins benefit from being able to be edited via an editor view. This means that when an inserted code snippet is selected in the Editor in Live Writer we can display our own properties bar on the right hand side. To use this feature we need to add a UserControl to our project and make it derive from SmartContentEditor. We then add relevant controls to it to interact with our Content (i.e. code snippet). In my case I just added a link label control to re-launch the dialog box for the user to modify the code within the currently selected content (code snippet) in the editor. Once complete then override the CreateEditor method and return our own UserControl object as a SmartContentEditor object .

public override SmartContentEditor CreateEditor(ISmartContentEditorSite editorSite)
{
    return new MySmartContentEditor();
} 

An important point is that only one instance of the plug-in is used in Live Writer for all instances of content being inserted. For example you may add multiple code snippets into one blog post but only one instance of your plug-in will be created and reused, therefore you cannot store any state information specific to an individual content items (i.e. Code snippets) within the plug-in. That’s why the data is always passed in to these methods we have been overriding.

Compile it up and copy the assembly to the PlugIns folder of your Windows Live writer installation (e.g. C:\Program Files\Windows Live\Writer\Plugins) to test. This time the content added using SmartContentSource is treated as special and is not converted as you flip between the Editor and Source views.

To extend the plug-in further its possible to update the ‘WriterPlugin’ attribute property ‘HasEditableOptions’ to true and override the ‘EditOptions’ method to display an options dialog to the user. This means that you can let the user modify settings for your plug-in. 

As you can see the plug-in model for Windows Live Writer is very simple and productive. It is surprisingly easy to quickly produce useful plug-ins.

If you want to make use of this plug-in for making it easier to add highlighted code to your WordPress.com blog then feel free to download it here.

Advertisements

8 thoughts on “Syntax Highlighting in WordPress.com hosted blogs and how to create a Windows Live Writer Plug-in

  1. Hi,
    Do you have any idea in this method
    public override string GeneratePublishHtml(ISmartContent content, IPublishingContext publishingContext)
    {
    return content.Properties[“OutputHTML”].ToString();
    }

    when it return in windows live writer it add
    so we can remove it ? I need the same html content which i did pass from this method.

    1. shailesh I’m not quite clear on the question. The GeneratePublishHtml method is called on the plugin once the user has submitted the post in Live Writer. As the post doesn’t automatically close after posting it is possible to still retrieve the values from the content.Properties collection as normal. I have tried to find a way of updating the HTML server side after it is posted via the api but not with any luck.
      Rich

  2. Hi,Nice to see your answer … Here I am describing my problem.

    I am creating one photo album upload plug.So In that I am generating my own HTML tag but when I post that HTML then it is going to be converted in between one strange Tag.

    I mean how my own generated HTML has been changed in GeneratePublishHtml Method… ?

    I have a same problem as described in this blog so that you can get a clear idea…

    http://social.msdn.microsoft.com/Forums/en/wlwdev/thread/f555955a-b96d-4e13-a078-f12df240393d

    1. Hi shailesh, unfortunately on submitting a SmartContentSource Live Writer wraps the HTML output from the plugin in DIV tags. These DIV tags are very useful for a plugin as they indicate that an the area in the DIV tag is a plugin element and also which plugin it relates too. This allows you to update the element with the plugin even after it has been inserted. However the side effect of this DIV tag is that it is often not desirable on the server and causes various issues depending on CSS and templates used. Unfortunately I have tried to get around this problem and have not managed to find a way. It seems to be a flaw in the way that Live Writer handles SmartContentSources. If you use a Simple ContentSource then the DIV will not be added but this means that the insertion of your element into the editior will be a once only excercise and the HTML inserted will be subject to change (usually undesirable) by the editor.
      If you find a way to do this then please update this post as I’d know.

      Thanks,
      Rich

  3. My partner and i seriously like everything you post here. Really unusual and also brilliant. 1 problem though. I’m running Opera together with Debian and also pieces of one’s up-to-date page layout parts certainly are a tiny wonky. My partner and i notice it’s not just a standard create. Yet it’s something to be able to keep in mind. My partner and i hope which it will aid and also continue to keep up the top notch top quality creating.

Comments are closed.