I'm in the process of rewriting my blog in ASP.NET MVC to move it from Google App Engine to AppHarbor. One of the important changes is that all my articles will be stored as Markdown instead of HTML.
I've blogged previously about the MarkdownHelper class I created and put on NuGet to make using Markdown in views as trivial as typing:
One thing that I didn't take care of was adding syntax highlighting to code blocks. On this blog I currently use Google Code's Prettify syntax highlighter, and this requires a CSS class be applied to code blocks:
By default, MarkdownDeep (which my MarkdownHelper uses) doesn't add these classes, so I had to make some changes to support it. I didn't want to build this into MarkdownHelper as it's fairly specific to using this particular syntax highlighter. Instead, I decided to take advantage of partial classes to allow the functionality to be customised without having to modify the MarkdownHelper.cs file added by MarkdownHelper/NuGet.
First I amended the MarkdownHelper class, adding "partial" to the declaration. This was pushed to NuGet as MarkdownHelper 1.2:
With this done, I loaded my blog in Visual Studio and opened the Library Package Manager, which showed the update and replaced the class with one click. With this done, I then created a new file named "MarkdownHelper.CodeFormatting.cs" alongside "MarkdownHelper.cs" in my Helpers folder. This is where my customisations should go, which will allow MarkdownHelper.cs to be updated by NuGet without affecting the customisations.
As it turned out, customising the code blocks with MarkdownDeep was pretty easy. The class has several extension points, the interesting one for me being:
If you set this property, when a code block is encountered, your code will be called instead of the default. To make sure I wasn't losing any functionality, I checked the source code of MarkdownDeep to see exactly what it did with a code block:
This seemed simple enough, and actually, the code path when you had a custom method was almost the same, it just didn't put the pre/code blocks in:
This meant the only thing I needed to do was surround the string with the pre/code tags. Adding class="prettyprint" was rather trivial:
Then in my partial class, I simply assigned this method to the FormatCodeBlock property of the Markdown transformer in a static constructor (since this is a partial class, it has direct access to the "markdownTransform" object):
With those changes, all my code blocks have the correct class and highlight correctly :-)