Search This Blog

A Barely Adequate Guide to Syntax Highlighting Code in a Web Page

Since I talk about programming somewhat frequently, I figured it was about time that I add syntax highlighting to my code examples. This post will be an interesting experiment because I only have a vague idea of how to do it, but I think I can figure it out quickly enough while writing an article about it at the same time. I'll set out three goals for this post:
  1. Figure out how to add syntax highlighting to my posts on Blogger as quickly as possible.
  2. Do a little survey of different ways to do syntax highlighting. This won't be comprehensive, but hopefully will give a few reasonable alternatives.
  3. Write fairly continuously. I've wanted to do a little writing exercise to work on writing faster, and here's a good opportunity to do it.
Okay, with that settled, are you ready? Let's see how this turns out.

 A Brute Force Attempt


I'll focus on highlighting Ruby code in this post, and I normally do my Ruby coding in Vim. I know Vim has a way to convert syntax highlighted code to HTML with the command :TOhtml. I'll make a little code snippet that has a decent variety of Ruby elements and run the converter on it to see what it looks like. Here it is:
class Speaker
  # Greet someone
  def self.say_hello(params)
    @name = params[:name]
    puts "#{params[:greeting]}, #{@name}"
  end
end

Speaker.say_hello({greeting: "Hello", name: "Sam"})
That looks pretty good right off the bat. I could tweak the CSS a bit to change colors, but other than that, it's straightforward. The problem with this method is that it's not too easy to go back and convert all of my old code samples to add syntax highlighting. I have to copy each one into Vim, run the converter, and then copy the HTML back into Blogger. I'm not looking forward to that. Also, I had to remove some of the generated HTML because Vim produces HTML for an entire web page, and I just need the <style> and <pre> tags and related content. I don't want to have to nip and tuck the HTML for every code snippet on my blog.

There Must Be a Better Way


There must be a way to use a JavaScript library to do the highlighting for me. It's time to pull out the programmer's most essential tool - Google. If I do a search for "syntax highlighting javascript," I get the following top 10 list:
  1. highlightjs.org
  2. prismjs.com 
  3. stackoverflow.com/questions/160694/syntax-highlighting-code-with-javascript
  4. shjs.sourceforge.net
  5. craig.is/making/rainbows
  6. alexgorbatchev.com/SyntaxHighlighter/
  7. code.google.com/p/google-code-prettify/
  8. softwaremaniacs.org/playground/showdown-highlight/ 
  9. softwaremaniacs.org/blog/2011/05/22/highlighters-comparison/
  10. github.com/LeaVerou/prism 
That looks mighty promising. We've got a number of JavaScript syntax highlighters, another list of them on Stackoverflow, and a comparison down at #9 that may prove useful for my second goal. Let's take the first one off the top of the list.

Highlight.js


Highlight.js looks really easy to use. All I have to do is add three lines to my template header in Blogger as described in the basic usage instructions, wrap my code in <pre><code>...</code></pre> tags, and format the code in HTML with the exact tab spacing that I want. Really, I can just copy the code out of Vim and into the HTML, and it should work. The script is even hosted so I don't have to figure out how to add it to my Blogger template, although I'm sure that's easy, too. Here's what the result of all that looks like:
class Speaker
  # Greet someone
  def self.say_hello(params)
    @name = params[:name]
    puts "#{params[:greeting]}, #{@name}"
  end
end

Speaker.say_hello({greeting: "Hello", name: "Sam"})
Nice! To change the theme, you can change the default.min.css to a number of different CSS templates. There's even a live demo at highlightjs.org so you can easily pick a theme that you like. I like to light up my code like a Christmas tree because it's easier for me to recognize different code elements. I also want a theme with a black background and good contrast so it doesn't seem like I'm looking through a dense fog at the code. Finally, I like my keywords to be blue or purple, just because. I thought the Tomorrow Night Bright theme was okay, so I went with that one. I might change it in the future, though, so no guarantees that what you see here is that theme.

Wait, We're Done Already?


Yup, that was actually easier than I thought it would be, and I'm happy with how easy it is to go back and convert my other code samples to be highlighted. But not today. Actually, we're not quite done, yet because I only showed two highlighting options. I'll spend a few minutes looking into the other options that turned up in Google.

Prism.js: Prism.js seems pretty nice. The website is straightforward, there's some good API documentation, and there's a test drive page where you can see what code for your favorite language will look like in one of their six prepackaged themes. There aren't as many themes or supported languages as Highlight.js, but it already supports Swift, which is pretty impressive and means it's definitely in active development. Prism.js does support line numbers, which is nice for long code listings or if you want to reference specific lines in your text. There's no hosted JavaScript as far as I could tell, so you'll have to download it for your own use. Most people will probably do this anyway. It's so much easier to do a quick-and-dirty setup with a hosted instance of the plug-in.

SHJS: SHJS doesn't look like it's been updated since the end of 2008. That's not necessarily a problem, but the other syntax highlighters have probably advanced beyond it. It does support a decent selection of languages, although not as many as Highlight.js, and a decent set of themes, including many of the default themes from popular editors such as Emacs, Eclipse, and Vim. You can test out how they look with a snippet of C++ code on the website. As with Prism.js, there is no hosted JavaScript available.

Rainbow.js: Rainbow.js looks to be a more basic option, with a bare-bones, although probably sufficient, single-page website. It supports 18 languages, which is on the low side of all of these options, but they're all the most popular ones so it should work for most people. The minified JS file is tiny at only 1.4kB (no hosted instance again), and it includes a decent set of predefined themes. You can't preview the themes on the website, though.

SyntaxHighlighter: The language support is also on the low side with 23 different language 'brushes' included. As far as I could tell, there was only one default theme available, so if it's not to your liking, you'll have to tweak the CSS yourself. It does support line numbering, and the styling of the line numbers looks especially nice. Once again, there was no hosted instance of the JavaScript.

Prettify: Prettify supports a nice variety of languages, and it's the only one of these highlighters, other than Highlighter.js, that auto-detects which language it's highlighting. It only has a few prepackaged themes, and they are shown as previews on the website. It does support line numbering, but only labels every fifth line by default. Getting it to number every line takes a bit a bit of extra CSS code.

Syntax highlighting code with JavaScript - Stack Overflow: The answers to this Stack Overflow question had most of the JavaScript syntax highlighters from the first page of Google search results and a few more. Since the search results already turned up enough, I won't go into the few additional ones listed here.

Completely unfair comparison of Javascript syntax highlighters: The guy that did Highlighter.js wrote up a nice comparison of Highlight.js, SHJS, SyntaxHighlighter, and Prettify. It's now three years old, so things could have changed from when it was written, but it's a nice read for understanding what to look for in a Javascript syntax highlighter. It is admittedly biased, but it convinced me that my original choice of using Highlight.js was adequate.

In the future I'll probably figure out how to include the Highlight.js code in my Blogger template instead of linking to the hosted instance of the code, and I'll tweak the colors and code block decorations a bit. Overall, I was quite pleased with how quickly I could get the syntax highlighting working. I should have tried it out sooner! It's nice to have some colorful code now.