Monday, 2 April 2012

SyntaxHighlighter - a syntax highlighter for blog posts

I usually use Windows Live Writer to do my blogs. I also have some add-ins to support the syntax highlight, which embeds the CSS into the page.

Today, I viewed the source on my own page, and here is an example of what the "Insert Code Snippet" generated:

// Original formatting with no CSS
Console.WriteLine("Hello World!");
Console.WriteLine("Hello World!");
Console.WriteLine("Hello World!");
Gets rendered to ....


<div id="codeSnippetWrapper">
<br>
<div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt;
background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%;
padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr;
border-top-style: none; color: black; border-right-style: none; font-size: 8pt;
overflow: visible; padding-top: 0px" id="codeSnippet">
<br />
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt;
background-color: white; margin: 0em; border-left-style: none; padding-left: 0px;
width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace;
direction: ltr; border-top-style: none; color: black; border-right-style: none;
font-size: 8pt; overflow: visible; padding-top: 0px"><br />
<span style="color: #606060" id="lnum1">1:</span><br />
Console.WriteLine(<span style="color: #006080">"Hello World!"</span>);</pre>
<br />
<!--CRLF-->
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt;
background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px;
width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace;
direction: ltr; border-top-style: none; color: black; border-right-style: none;
font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060"
id="lnum2">2:</span><br />
Console.WriteLine(<span style="color: #006080">"Hello World!"</span>);</pre>
<!--CRLF-->
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt;
background-color: white; margin: 0em; border-left-style: none; padding-left: 0px;
width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace;
direction: ltr; border-top-style: none; color: black; border-right-style: none;
font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060"
id="lnum3">3:</span> <br/>
Console.WriteLine(<span style="color: #006080">"Hello World!"</span>);</pre>
<!--CRLF-->
</div>
</div>
Okay, that is pretty horrific. Does the job, no doubt but when it comes to editing this in the application, it is a complete nightmare. It selects single rows, changes their width accidently. When you have a bit of luck actually selecting the outer div, the Code Snippet editor even warns you that it is going to attempt to read it. When viewing this on a mobile device, it looks even worse. Much worse trust me!

At the same time I was catching up with my Google Reader and was looking through posts I'd missed by Scott Hanselman. He was looking for a syntax highlighter for Windows Live Writer a few years ago. He also went to the trouble of writing a Windows Live Writer plug-in for it. But luckily, things have been made much easier.

How to add SyntaxHighlighter to your site

  1. Download the Javascript and CSS libraries from the SyntaxHighligter authors site. (Alternatively reference them as described)
  2. Add a few lines of script, referencing the code types you wish to use, including the core libraries.
    <script src="shCore.js" type="text/javascript"></script>
    <script src="shAutoloader.js" type="text/javascript"></script>
    <script type="text/javascript">SyntaxHighlighter.autoloader(
    'js jscript javascript /js/shBrushJScript.js',
    'csharp c-sharp /js/shBrushCSharp.js',
    'xml /js/shBrushXml.js'
    );


    SyntaxHighlighter.all();
              http://alexgorbatchev.com/SyntaxHighlighter/manual/api/autoloader.html
In your HTML of your blog post, or site, all you do is add the nice and friendly <pre> tag that we all know and love, applied with a 'class' attribute with your programming language - simples!.

So here is a code sample (from a previous post) and the newer way I will be blogging from now on:

Before


   1: # PowerShell script to modify the 'timeout' value in the specified web.config    
   2: # when no Sessions are in use.    
   3:  
   4: # Constants used throughout application    
   5: $webConfig = "d:\web.config"    
   6: $newTimeout = "20"    
   7: $sessionCount = 0    
   8:  
   9: ## BEGIN   
  10: write-host Getting performance counters ...   
  11:  
  12: $perfCounterString = "\asp.net applications(__total__)\sessions total"    
  13: $perfCounter = get-counter -counter $perfCounterString    
  14: $rawValue = $perfCounter .CounterSamples[0].CookedValue    
  15:  
  16: write-host Session Count is $rawValue   
  17:  
  18: if( $rawValue -gt $sessionCount)   
  19: {   
  20:    write-host Session Count = $rawValue - exiting   
  21:    exit   
  22: }   
  23:  
  24: write-host Stopping IIS   
  25: stop-service "IISAdmin"   
  26:  
  27: # Open file and change value   
  28: $doc = new-object System.Xml.XmlDocument   
  29: $doc.Load($webConfig)   
  30: $doc.SelectSingleNode("//sessionState").timeout = $newTimeout    
  31: $doc.Save($webConfig)   
  32:  
  33: write-host Starting IIS   
  34: start-service "IISAdmin"   
  35:  
  36: write-host Done!   
  37: ## END

After


# PowerShell script to modify the 'timeout' value in the specified web.config    
# when no Sessions are in use.

# Constants used throughout application
$webConfig = "d:\web.config"
$newTimeout = "20"
$sessionCount = 0

## BEGIN
write-host Getting performance counters ...
$perfCounterString = "\asp.net applications(__total__)\sessions total"
$perfCounter = get-counter -counter $perfCounterString
$rawValue = $perfCounter .CounterSamples[0].CookedValue

write-host Session Count is $rawValue

if( $rawValue -gt $sessionCount)
{
write-host Session Count = $rawValue - exiting
exit
}

write-host Stopping IIS
stop-service "IISAdmin"

# Open file and change value
$doc = new-object System.Xml.XmlDocument
$doc.Load($webConfig)
$doc.SelectSingleNode("//sessionState").timeout = $newTimeout
$doc.Save($webConfig)

write-host Starting IIS
start-service "IISAdmin"
write-host Done!
## END

Have a look at the source of this page to see how readable each section is.