blog

lame subtitle

This is my blog. Do not expect frequent content.

Previous
Next

Adding syntax highlighting to simple_blog

13 April 2019 12:04 -04:00 / Permalink

After publishing my first post, which had a YAML code block in it, I decided that syntax highlighting would be nice to have. As much as YAML is fine to read without highlighting, the added colours make it even easier to read.

To add highlighting, I had to first figure out where to best insert a highlighter. I considered using highlight.js, since comrak is already set up to work easily with it, but I didn't really want a) highlighting to be dependent upon JavaScript and b) any JavaScript on my blog. I really just don't need it for a static site.

So, I decided I'd need to add highlighting during the generation flow. The way simple_blog worked before highlighting was as follows:

  1. The templates path is parsed by Tera.
  2. The posts path is crawled for *.md files, and each file has its front matter For example:
    ---
    title: Post title
    date: 2019-04-13T12:04:21-0400
    custom: anything else you want
    ---
    
    ...
    
    parsed.
  3. The front matters are sorted by date in ascending order.
  4. The rest of each file is read, and the markdown is parsed.
  5. The post template is rendered using the front matter, configuration, and parsed markdown.
  6. The index template is rendered using the last post.

In the end, I decided to go the route of adding highlighting as the markdown is being parsed. This meant I would have to fork comrak to add the feature, since comrak has no way of adding an extension programmatically.

I chose syntect as my highlighter, and I injected some logic into comrak's HTML output code for code blocks. This produced a <pre><code> with several <span>s inside, all with classes describing the token inside. That was actually pretty painless, besides clippy warning me that the cognitive complexity of the HTML emitter was too high.

The hard part was actually creating styles to use to make the spans have colour. syntect uses Sublime Text themes and syntax sets to highlight code, so I found a Sublime Text theme I wanted (Atom One Dark), I don't actually use Atom; I don't like it. The Atom One Dark theme, though, is my absolute favourite code theme. and I downloaded it.

Sublime Text themes are plist files, and I really didn't want to go through the hassle of deserialising them and picking out the colours and font styles. Luckily, syntect exposes all the necessary code it uses to do so, so I loaded my chosen theme into syntect and I generated CSS from the theme. Highlighting actually uses Sublime Text scopes as classes, so the punctuation.separator scope would turn into <span class="punctuation separator">, which made generating the CSS very easy.

Finally, I updated simple_blog to allow custom keys into front matter, and I made my template look for post.fm.highlight. If set to true, /style/highlight.css is included in the page. Then highlighting just worked. I have to say, it was simpler than I thought it was going to be, and it requires no JavaScript!