Syntax highlighting for a Hugo data science blog


NOTE: I believe this requires the post to be in .Rmarkdown format, and that an .Rmd post will not have the syntax highlighting.

This post explains how I set up my Hugo blog (with the Whiteplain theme) to get the type of syntax highlighting I want for data science / statistics purposes. I relied heavily on this post from Amber Thomas. Thanks a lot Amber! If I were you, I’d probably use Amber’s more thorough post as a guide. It stands alone better than my post here.

Background

Hugo comes with a built-in, default syntax highlighting system called Chroma. There is an older, non-default option called Pygments which can still be used. To help with compatibility, Chroma retains lots of Pygments’ configuration options, e.g. you can have lines like pygmentsUseClasses = true in your blog’s config.toml file, even if you’re using the default Chroma instead of Pygments. See Hugo’s page on syntax highlighting for more info.

The default Chroma setup didn’t look good. For one, inline code blocks (as well as larger code chunks) showed as black font on a grey background, but I wanted something more like Github inline code like this.

One can also use a javascript library called highlight.js, which is ultimately what I went with. This library is described here in Yihui Xie’s blogdown book.

The exact procedure to modify default syntax highlighting to suit your needs will depend on the theme you’re using. This post relates to Whiteplain.

The problem

I wanted inline code chunks like this to look as they do here. By default they were in black text on a gray background. Other code chunks had the same problem, but now they look much better, like this R chunk:

myFunction <- function(f,g,h){
    print('Hi Mom')
    return (f*g*h^2)
}

What I did to solve the problem

My problem is basically the same as Amber’s, and I solved it with only minor differences to her solution.

So I went with highlight.js, not Chroma. I followed Amber’s Step One section exactly. Here’s the relevant code in my config.toml:

[params]
  ### SYNTAX HIGHLIGHTING using highlight.js
      description = "A website built through Hugo and blogdown."

      highlightjsVersion = "9.11.0"
      highlightjsCDN = "//cdn.bootcss.com"
      highlightjsLang = ["r", "yaml", "tex"]
      highlightjsTheme = "github"

      MathJaxCDN = "//cdn.bootcss.com"
      MathJaxVersion = "2.7.1"

I followed her Step Two exactly as well, except where she states that

In the partials folder for your theme (themes/name-of-your-theme/layouts/partials), you should see a file called head.html or header.html. Add the following code…

I actually had both files, so I added the specified code to both files, and that seemed to be fine. Now I’m up to her Step Three, and I ignored some of her steps there. At this point my syntax highlighting for code chunks was good, but the font size was a little small and inline code like this still was black on a grey background. To remedy this, I right clicked on my page and clicked “Inspect” (using Google Chrome here) to open Developer Tools. Then I clicked the little mouse-cursor-in-a-box icon towards the left of the screen, and then found a black-on-gray inline code bit on the page and clicked on that. I followed Amber’s advice about removing pre and code:

Search that doc for any instances of pre or code and find the chunk that has the background-color and text color that your theme is currently generating displaying.

Inline code formatting still wasn’t working

I can’t fully remember, but at this point I believe the syntax highlighting for inline still didn’t work. I wanted mine to look like Amber’s - so how was Amber’s formatted? To find out, I simply used the Inspector on Amber’s own page, Inspecting an inline code chunk of hers. Here the Inspector is showing how the word bootstrap gets its syntax highlighting:

I copied the block in the lower right pane which begins with code { and pasted that into themes/whiteplain/static/css/style.css, which is apparently the .css file that controls inline-code syntax highlighting in the Whiteplain theme. Finally I modified font-size: 90% to 120% to get the code to pop a little more.

Regarding Hugo’s lookup order

When Hugo builds your site, it looks for necessary files by searching directories in a certain order. Just above, I said I pasted code needed for inline formatting into themes/whiteplain/static/css/style.css. My understanding is that you ought to be able to copy the theme’s original style.css file into static/css/ and then modify that copy by pasting the formatting info in. In other words, my understanding is it’s possible to leave the themes/ directory itself alone, and effectively modify the theme via other files which override the default theme elements. Practically speaking this doesn’t matter a ton. But the advantage (if I had done that, and if it had worked) would be that if I wanted to know if any parts of the theme are modified, I could just look in the relevant non-themes/ directories of my site’s folder, to see where I’d placed overriding files. Oh well, for now, I’ve just modified the theme’s files in place, and it got me what I wanted, so I’m done.

Final thoughts

It’s not described above, but initially I was using Chroma and getting things almost right. I had two main problems. First, code chunks had zero indentation, so when they were on a colored background, the actual code was pushed all the way to the left of that colored background. This looked weird. I probably could have solved this using the Developer Tools, but I hadn’t yet found Amber’s blog so Chrome’s Developer Tools wasn’t on my mind yet. The second problem kind of fixed the first: I added line numbers. This made for nice indentation in multi-line chunks, but for single-line chunks, I got a line number of 1 at left, which looked like clutter to me, and no space appeared between the 1 and the code. Inline formatting was also that ugly black on gray, but I now believe that was sort of independent of the choice of Chroma over highlight.js – I probably could have solved the inline problem the same way I did above.

Anyway, switching to highlight.js from the default Chroma syntax highlighter solved my code chunk problems, and Chrome’s Developer Tools helped me quickly fix the inline code formatting. Thanks a lot Amber Thomas!

comments powered by Disqus