Done

Syntax Highlighting for Blogdown Posts

R

blogdown

Syntax highlighting makes things fun and colorful and provides some additional information about your code. The bootstrap dependency of my blogdown theme code was ultimately the culprit but I detailed my investigative process to solving the problem in this post.

The Backstory

I’ve been playing with Yihui Xie ’s blogdown package for almost a year now, and I’m constantly amazed by all of the things that it can do. Maybe I’ll get around to turning this post into a series, with each addition explaining one more cool thing that you can now add to your blog posts from R. But, for now, there’s just one I’d like to touch on: syntax highlighting.

When I first began my blogdown journey, I didn’t think syntax highlighting was possible. I had started with this theme and any code I added to posts was just a solid color.

For example, when I typed code into an RMarkdown document in RStudio, it would look like this:

Screen shot of a code block within the R environment. The text is either black or green, depending on the purpose of each text string in the code.

See how there are colors? But rendered on my website, it looked like this:

A screenshot of the same code from the previous image, but all of the text is black. Comments and code are visually indistinguishable except that comments are preceded by a # symbol. Boo, no colors!

Ok, so, I recognize that this is mostly text decoration, but when you have very long chunks of code it is a little bit helpful to have certain parts colored. It also helps me quickly notice if I’ve made a typo.

Anyway, I thought this was just a blogging dream of mine until I was reviewing the blogdown book and stumbled upon this section which mentions the use of highlight.js, a javascript library that highlights the syntax of different programming languages. The blogdown book goes into more detail about syntax highlighting here , but I hadn’t given it a try until Mara Averick shared some tips for R blogging and this was included:

A screenshot from Mara Averick's blog. The text reads: Syntax highlighting! Just do it. Life is better when things are colorful. Plus, but it's really not hard — I didn't even have to do anything special with my blogdown theme to get it working. This is covered in the blogdown book as both a theme parameter and a custom template. Below the text is a screenshot of an R console with a colorful tidyverse logo.

I finally decided to take the dive and after lots of code-tweaking and googling I got it working.

Here’s that same piece of code on my website now:

Yay, colors!

Alright, so how did I do it?

Step One: Check Your Theme

As it so happens, some Hugo themes already have highlight.js functionality built in. For instance, if you use the default theme within blogdown, you’re all set.

All you’d need to do is go to your config.toml file, and update this section:

config.toml

[params]
    description = "A website built through Hugo and blogdown."
    highlightjsVersion = "9.11.0"
    highlightjsCDN = "//cdn.bootcss.com"
    highlightjsLang = ["r", "yaml"]
    highlightjsTheme = "github"
    MathJaxCDN = "//cdn.bootcss.com"
    MathJaxVersion = "2.7.1"

The highlightjsLang argument allows you to specify which languages you want to highlight, and the highlightjsTheme controls what colors are used to highlight (more options available here ).

If, like me, your theme does not allow for highlighting out-of-the-box, keep reading.

Step Two: Add Highlight.js

There are several ways to add highlight.js to your blogdown site, but here’s the way that I did it.

head.css

<link rel="stylesheet" 
	href="{{"css/github-gist.css" | absURL}}" 
	rel="stylesheet" id="theme-stylesheet">

<script src="{{ "js/highlight.pack.js" | absURL }}"></script>
<script>hljs.initHighlightingOnLoad();</script>

Hopefully that will work for some of you! In my case though, there was more to be done.

Step Three: Blame Bootstrap

I had done the steps above, and my syntax highlighting still wasn’t working. I figured the next logical step was to figure out if there was some CSS leftover somewhere that was being used over my new highlight.js css file.

Here’s how I checked:

When I do that, this is what I see:

A screenshot of my blogdown blog with Google dev tool panel open on the right hand side. A code block is currently highlighted, displaying a code element with a class of hljs alongside CSS styles for the element.

There’s a lot going on there, but focus on this part:

A zoomed in screen shot highlighting the CSS code for the hljs class and for pre and code elements. In the screenshot, the CSS indicates that styles for the hljs class are being derived from the file github-gist.css, while the styles from pre and code are coming from bootstrap.css

I accidentally forgot to take screenshots when I was having this problem, so these screenshots show what it should look like.

Notice how items in the class hljs (written as .hljs) are being styled by github-gist.css and the elements pre and code (written as pre code) are being styled by bootstrap.css? Well, when I originally ran into this issue, there was no hljs class items, and all pre and code items were being styled by a file called code.less.

I spent forever searching for a file (both visible and hidden) named code.less that was messing up my syntax highlighting, but it was nowhere to be found. After much googling, I discovered that it is bundled in bootstrap.css which has been minified (i.e., all excess white-space and formatting has been removed, making it not very human-readable). This made it really hard to pin-point the issue, but luckily someone on StackOverflow had asked this question already. Essentially, the top-respondent suggested I had 3 choices:

  • Option 1: Download the bootstrap source code less.css. modify the file and use it.

  • Option 2: Place !important beside the css that you want to override in your custom.css

  • Option 3: Go to developer tools identify the portions of less.css which you want to override and use your own id with those elements. After that style them in your own css file.

After lots of playing around, Option 1 seemed like my best bet…sorta. I decided to download a new bootstrap.js and bootstrap.css file without the code.less file bundled in.

  • You can do that by going here and under “Common CSS”, uncheck the box that says “Code”. I had no idea what other files had been changed between this version of bootstrap and the one used in my theme, so I left everything else untouched.

  • Click “Compile & Download”.

you are about to replace some of your theme’s js and css files, I’d recommend copying these to a safe location until you see if you will need to undo this step

  • Unzip the folder, and move the bootstrap.min.js file to the js file of your site (themes/name-of-your-theme/static/js) and the bootstrap.min.css file to the css folder of your site (themes/name-of-your-theme/static/css).

  • Serve your site using blogdown::serve_site() and see if your syntax is working (For some of you, I assume, it should be).

At this point, my syntax highlighting was, indeed, working (🙌 🎉), but the layout of my page was a little messed up. That makes sense, as I had replaced the CSS file that ran my site. I decided to put my original bootstrap.min.js and bootstrap.min.css files back in their original locations which fixed the layout but my syntax highlighting was gone again. Here’s what finally got it working with my theme:

css

pre, code, pre code,  {    
	padding: 2px 4px;    
	font-size: 90%;    
	color: #c7254e;    
	background-color: #f9f2f4;    
	border-radius: 4px
}

All I needed to do was remove any instances of pre from this. So it now looks like this:

css

code {    
	padding: 2px 4px;    
	font-size: 90%;    
	color: #c7254e;    
	background-color: #f9f2f4;    
	border-radius: 4px
}

header.html

<link rel="stylesheet" href="{{ "css/bootstrap.min.css" | absURL }}">

just remove the call to the minified version and save

header.html

<link rel="stylesheet" href="{{ "css/bootstrap.css" | absURL }}">

And that’s it! This may not work for every theme, but hopefully I hit walls frequently enough to keep you clear of them. Now go enjoy your colorful code 😄