My Profile Photo

Rich Werden

A simple site for Rich to write about code and archive some completed projects for future reference...

Line Numbers in Jekyll Code Blocks

I’ve been a little annoyed that Markdown doesn’t allow for line-numbers in its code blocks. It’s just not a part of the basic system1 though some engines do add line numbers when putting together the final HTML that gets displayed. Usually, I think of these posts in terms of Markdown syntax, but I’m really writing Markdown inside of liquid and so it turns out that in jekyll, there is a way to add line numbers to code blocks. (Scroll to the bottom if you want to cut to the chase)

In Markdown, there are two ‘normal’ / official ways of writing code-blocks:

1. Using Three ` Backticks

This is my normal go-to when I’m writing my posts and notes. If I want a code block I’ll use the GFM (Github Flavored Markdown) approach which is to start and end a block with three backticks2 in a line. If you want a language-specific color-theme rendered, just include the name of that syntax attached to the first line of the code block’s ```’s like so:

  function some(code) { /* goes here */ }
  var x = 21;

Which actually renders on the page as…

  function some(code) { /* goes here */ }
  let x = 21;

2. Indenting Four Spaces

I don’t think this is such a great idea in that while it is cool in that it is automagical, and just happens when you put an empty line and then four spaces before the start of your line, I feel that it doesn’t ‘read’ most easily in a raw .md file

A couple of spaces of indenting can make or break formatting things.
And if you care enough about line numbers to read this, you care about formatting.  

Also, I don’t think you can get any sort of language specific syntax with it.

3. ANSWER: liquid ‘linenos’

The answer amounts to RTFM: It’s right in the jekyll docs, though it is jekyll/liquid specific and won’t work in, say, a github readme. The trick is to use liquid’s {% highlight %}function…
Ya might recall that anything you type between an opening {% highlight someLanguage %} tag, and an ending {% endhighlight %} tag will be code block-formatted into whatever language you put in the first tag just like the ```ruby approach in #2. So, to get the exact same output as the JS example above, you’d write:

{% highlight javascript %}
    function some(code) { /*goes here*/ }
    let x = 21;
{% endhighlight %}

However, if I include the word linenos in the opening tag, guess what happens?

{% highlight javascript linenos %}
    function some(code) { /*goes here*/ }
    let x = 21;
{% endhighlight %}


    function some(code) { /*goes here*/ }
    let x = 21;
    // Neatorific!

You can actually set this as a default behavior in your config.yml, but I’m not gonna on this theme for the moment… (Oh, and good guess, btw.)
If you want to style the numbers in particular, you can make changes to the .lineno {} class in your CSS. See this post for details, but I gotta wonder WHY WOULD A linenos [plural] ARGUMENT BE MODIFIED BY A CLASS NAME .lineno [singular]?? <sigh>

TIL next time…Cheers!


Saw (this post from 2015 by Tobias Lohse)[] that says you can put the following code in your _config.yml:

markdown: kramdown
    highlighter: rouge
            line_numbers: true

  1. The argument I’ve seen about leaving line-#s out of GFM is that one ends up copying line numbers when copying and pasting code. Makes enough sense. 

  2. The Backtick is the small ` thing on the top left of your keyboard that shares a key with the tilde/~/squiggle symbol. Basically, just realize that the Backtick is NOT the same as a single quote . It is technically called a ‘grave’, but in the same way that whatever you want to call this thing: #, which is really an octothorp, nowsadays coders just call the ` a backtick. See Wikipedia for deets.