fd Blog

Daniel Hilgarth on software development

Automatic Syntax Highlighting

In my last post about the syntax highlighting of this blog I explained how to get Google’s code prettify to work.

Both options presented require me to add some kind of marker to the code blocks. That quickly started to annoy me. What I really wanted is the highlighting to happen without any markers, just like on Stack Overflow.

It is actually pretty simple to get this to work. From the prettify documentation we know that we simply have to add the class prettyprint to the tag we want highlighted.
From examining the source code of the generated HTML files I knew that the markdown code blocks get converted into <pre><code>The content of the code block</code></pre>. So, getting prettify to work automatically is as easy as running a simple jQuery statement:

<script type="text/javascript">
  $(document).ready(function() {
    $("article pre:has(> code):not(.nohl)").addClass("prettyprint");
  });
</script>

This looks for pre tags that are somewhere beneath an article tag and that have a direct code child. Additionally, the pre tag must not have the nohl class.
To all the matching pre tags the prettyprint class is then added.

But a little bit more work was necessary. Originally, I was using run_prettify.js to load the prettify JavaScript and CSS and to run the actual prettification (Yes, that noun exists!).
Especially the last point interfered with my jQuery statement, because apparently my code ran after the prettify code.

The fix was easy:
I downloaded the current version of prettify and extracted its .js files to source/javascripts/prettify and the CSS file to source/stylesheets/prettify.
I had to adjust the script tag:

<script src="{{ root_url }}/javascripts/prettify/prettify.js" type="text/javascript"></script>

and add a new link tag for the stylesheet:

<link href="{{ root_url }}/stylesheets/prettify/sons-of-obsidian.css" type="text/css" rel="stylesheet" />

sons-of-obsidian.css is not part of the normal package, I downloaded it from the style gallery.

Finally, I had to actually start the prettification by calling prettyPrint();. In the end, my source/_includes/custom/head.html has this new content:

<link href="{{ root_url }}/stylesheets/prettify/sons-of-obsidian.css" type="text/css" rel="stylesheet" />
<script src="{{ root_url }}/javascripts/prettify/prettify.js" type="text/javascript"></script>
<script src="{{ root_url }}/javascripts/jquery-1.9.1.min.js" type="text/javascript"></script>
<script type="text/javascript">
  $(document).ready(function() {
    $("article pre:has(> code):not(.nohl)").addClass("prettyprint");
    prettyPrint();
  });
</script>

That enabled the syntax highlighting you see on this blog.

Advanced features

No highlighting

You might have wondered what the part with :not(.nohl) was about in the jQuery statement.
nohl stands for “No Highlighting[, please]”. If I want to have a code block that is not prettified, I can add this class by using {:.nohl} right after the code block.
That’s actually, how I was able to get the first code in the original post to not be prettified.

Different language

If you don’t want to use the language prettify automatically inferred, you can add {:.lang-<extension>} right after the code block.
See the section “How do I specify the language of my code?” in the readme for a list of extensions.

Comments