Joe Maller.com

Web Syntax Coloring

February 2011 Update: This post was originally published in 2007 and hasn’t aged well. For code snippet syntax coloring, I currently use Google’s Prettify script (prettify.js). The script is dynamically inserted by jQuery if there are code elements to style.

Recently I’ve been experimenting with two very different methods of syntax coloring source code in web pages. The first method uses a Dan Webb’s CodeHighlighter JavaScript library to convert appropriately tagged content into syntax colored code. It’s necessarily simple, but easily extensible. As an example, here are the CSS rules I’m using to style CodeHighlighter’s conversions:

code.html span.comment         { color: #999;}
code.html span.tag             { color: #07f;}
code.html span.string         { color: #080;}
code.html span.attribute     { color: #07f;}
code.html span.doctype         { color: #07f;}

code.css span.comment          {color: #999;}
code.css span.keywords         {color: #fd2;}
code.css span.selectors        {color: #0b0;}
code.css span.properties    {color: #66f;}
code.css span.units            {color: #33c;}
code.css span.urls            {color: #4a0;}

code.javascript span.comment     { color: #999; }
code.javascript span.brackets     { color: #07f; }
code.javascript span.string     { color: #4a0; }
code.javascript span.keywords     { color: #07f; }
code.javascript span.exp         { color: #808; }
code.javascript span.global     { color: #06e; }

The second method uses two more fantastic TextMate features, Create HTML From Selection and Create CSS from Current Theme. What these two commands do is translate exactly what I’m seeing in TextMate into very precise and valid XHTML with accompanying CSS rules. The main disadvantage of this is the weight of the code, the above 721 bytes of CSS converts to nearly 36k of HTML and CSS rules. It’s a seriously heavy pile of span tags, but the cost is immediately outweighed by 148 very specific reasons. And that’s just bundles, there are dozens of great themes too.

Aaron Quint also deservingly gushes over these two commands.

What these do is convert exactly what I’m seeing in TextMate into very precise and valid XHTML. Here’s the same CSS as above translated by TextMate:

code.html span.comment      { color: #999;}
code.html span.tag          { color: #07f;}
code.html span.string       { color: #080;}
code.html span.attribute    { color: #07f;}
code.html span.doctype      { color: #07f;}

code.css span.comment       { color: #999;}
code.css span.keywords      { color: #fd2;} 
code.css span.selectors     { color: #0b0;} 
code.css span.properties    { color: #66f;} 
code.css span.units         { color: #33c;} 
code.css span.urls          { color: #4a0;} 

code.javascript span.comment    { color: #999;}
code.javascript span.brackets   { color: #07f;}
code.javascript span.string     { color: #4a0;}
code.javascript span.keywords   { color: #07f;}
code.javascript span.exp        { color: #808;}
code.javascript span.global     { color: #06e;}

Just for the sake of comparison, below is a screenshot of how my code looks in TextMate. It’s not a perfect translation, but it’s a very good start:

Syntax Coloring CSS in TextMate

One of the purported advantages of the JavaScript method is that the source code remains unchanged. That’s sort of true, but not really. The JavaScript functions work by inserting a bunch of spans, so by the time the user sees it the main difference between JavaScript converted code and pre-processed code from TextMate is the detail (and weight) of the TextMate result. Also, any HTML would need to have entities escaped which is another step and a further degradation of the original code.

The main advantage then becomes convenience. A simple block of code doesn’t need to be run through TextMate (on the off-chance I’m writing somewhere else), it can be entered directly and tagged for styling without breaking focus.


AppleScript source links from TextMate

AppleScript’s URL Protocol Support allows the full source code of an AppleScript to be shared through an encoded URL. Here’s a short little TextMate Command for converting AppleScripts to encoded URLs.

Create a new command in TextMate’s AppleScript bundle with the following code:

#!/usr/bin/env ruby -KA -rcgi
src = CGI.escape(STDIN.read)
src = src.gsub('+', '%20')
src = 'applescript://com.apple.scripteditor?action=new&script=' + src
`echo -n "#{src}" | pbcopy`
print "The URL encoded AppleScript was copied to the clipboard"

There’s no reason this idea can’t be used for all sorts of stuff. So why not make it easier, it’s not AppleScript, but here’s that code in Script Editor for easier copying.

This is exceptionally fast, much faster than Apple’s provided encoding script. As an extreme example, converting the 558 lines of my iPhoto Date Reset script took just under a minute using Apple’s script. The little Ruby script in TextMate does it instantly. (running the AppleScript in Script Editor with the Event Log Window open took nearly 7 minutes.)

Update: I committed this command to the TextMate Bundles repository and it’s now included in the default set of Bundles shipping with TextMate. (And slightly improved by other TextMate bundle developers)