Until today, I was using highlight.js to highlight code snippets on this site. It’s a very nice plugin but the problem is that it’s yet another JavaScript resource that has to load before the page can completely resolve. Either you can put it in the header and make it a blocking script (more on that in a future article), or you can put it in the footer and watch your code “blink” as it goes from its default state to its fancy now-modified-by-the-plugin state.

Pick your poison.

A more elegant solution is to modify the markup on the server, before ever sending it to the client. This is functionality that Jekyll will readily give to you, in fact. The only reason I didn’t start this way from the get-go was because I was approaching the problem from the assumptions that my WordPress background gave me (thank you WordPress) where this idea of highlighting code server-side would be a serious hassle involving some sort of filter or shortcode nonsense that would have to get applied on every page load.1 Instead, with Jekyll you have clean .markdown files in your IDE of choice, which in turn get compiled once per deploy, not per page load, into static .html files that load lightning fast.

When that’s the paradigm, what’s not to love about Rouge? Rouge was already installed since it’s bundled with the github-pages gem, but if it hadn’t been, I could have run sudo gem install rouge.

With the drop-dead simple documentation on how to get Rouge working with Jekyll, all I had to do was add a stylesheet. I went with the suggested syntax.css and added the following additions in my own custom stylesheet, so as to make it to look even more like GitHub’s code highlighter:

.highlight {
    > pre {
        border: 1px solid #ddd;
        padding: 0;

        pre {
            margin: 0;
            font-size: 12px;
            line-height: 17px;
            font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
            border: none;
            word-wrap: normal;
    td.gutter {
        min-width: 40px;
        pre {
            color: #aaa;
            border-right: 1px solid #eee;
            border-radius: 0;
            -webkit-user-select: none;
            -moz-user-select: none;
            -ms-user-select: none;
            user-select: none;

As an aside, the word-wrap: normal; line up there took me half an hour to write. You only need it if you’re also including Bootstrap CSS and you’re viewing your handiwork in Safari, at which point you’ll start wondering why the line numbers don’t line up correctly with the code lines.2

You’d be hard pressed to find a language that Rouge does not support – they have about 60. I’m quite pleased at how good the code on this site is now appearing.

  1. You can cache WordPress pages, of course, but you get the idea. ↩︎
  2. GitHub’s DOM structure is more elegant. It has a dedicated <td> for each line number and a dedicated <td> for each corresponding code line. This means that no matter what it’s impossible for these two columns to get out of sync. Not following this intuitive approach is my only complaint about Rouge. ↩︎