Mastodon

Enabling Code Syntax Highlighting in Jekyll

May 09, 2021 by Kolappan N

TLDR: You need to add some CSS.

Sometime ago I switched from embedding code form GitHub on my blogs to have the code directly in HTML. I did for performance reasons and cutting out some JavaScript. And the change helped in increasing the performance of the page for sure. But the first thing I noticed on my native code blocks created in markdown is that there was no syntax highlighting.

Surely, Jekyll has support for Syntax highlighting? Yes, it does. The Jekyll website tells us that Jekyll uses Rouge to highlight more than 100 languages. So, why is my code all black without any syntax highlight?

First let us understand how Rouge works. It analyses your code and identifies the keywords, operators, strings, comments, etc… based on the language details you have given. It splits your code into various span tags and adds classes to each span tag like <span class="k">new</span>, where the class k stands for keywords. In order for Jekyll to recognise a code block you can use a markdown code block.

You will need a CSS rule that colours the code based on the class. Just add a suitable CSS and ta da you have syntax highlighting. I wish Jekyll included some sort of theme by default though. Unfortunately Jekyll doesn’t have one by default. Here is the SCSS one I use,

/* 
* Jekyll uses Rougue for syntax highlighting - https://jekyllrb.com/docs/liquid/tags/#code-snippet-highlighting
* List of tokens used in Rougue - https://github.com/rouge-ruby/rouge/wiki/List-of-tokens
* 
* Any rougue or pygments theme can be used here.
* The below code is modified from: https://github.com/microsoft/SandDance/blob/master/docs/_sass/generic/_generic.syntax-highlight.scss
*/

.highlight {
  color: #b4b1a2; /* For anything that is not covered below */

  .hll { background-color: #272822; }
  .c { color: #979381 } /* Comment */
  .err { color: #960050; background-color: #1e0010 } /* Error */
  .k { color: #66d9ef } /* Keyword */
  .l { color: #ae81ff } /* Literal */
  .n { color: #f8f8f2 } /* Name */
  .o { color: #f92672 } /* Operator */
  .p { color: #f8f8f2 } /* Punctuation */
  .cm { color: #979381 } /* Comment.Multiline */
  .cp { color: #979381 } /* Comment.Preproc */
  .c1 { color: #979381 } /* Comment.Single */
  .cs { color: #979381 } /* Comment.Special */
  .ge { font-style: italic } /* Generic.Emph */
  .gs { font-weight: bold } /* Generic.Strong */
  .kc { color: #66d9ef } /* Keyword.Constant */
  .kd { color: #66d9ef } /* Keyword.Declaration */
  .kn { color: #f92672 } /* Keyword.Namespace */
  .kp { color: #66d9ef } /* Keyword.Pseudo */
  .kr { color: #66d9ef } /* Keyword.Reserved */
  .kt { color: #66d9ef } /* Keyword.Type */
  .ld { color: #e6db74 } /* Literal.Date */
  .m { color: #ae81ff } /* Literal.Number */
  .s { color: #e6db74 } /* Literal.String */
  .na { color: #a6e22e } /* Name.Attribute */
  .nb { color: #f8f8f2 } /* Name.Builtin */
  .nc { color: #a6e22e } /* Name.Class */
  .no { color: #66d9ef } /* Name.Constant */
  .nd { color: #a6e22e } /* Name.Decorator */
  .ni { color: #f8f8f2 } /* Name.Entity */
  .ne { color: #a6e22e } /* Name.Exception */
  .nf { color: #a6e22e } /* Name.Function */
  .nl { color: #f8f8f2 } /* Name.Label */
  .nn { color: #f8f8f2 } /* Name.Namespace */
  .nx { color: #a6e22e } /* Name.Other */
  .py { color: #f8f8f2 } /* Name.Property */
  .nt { color: #f92672 } /* Name.Tag */
  .nv { color: #f8f8f2 } /* Name.Variable */
  .ow { color: #f92672 } /* Operator.Word */
  .w { color: #f8f8f2 } /* Text.Whitespace */
  .mf { color: #ae81ff } /* Literal.Number.Float */
  .mh { color: #ae81ff } /* Literal.Number.Hex */
  .mi { color: #ae81ff } /* Literal.Number.Integer */
  .mo { color: #ae81ff } /* Literal.Number.Oct */
  .sb { color: #e6db74 } /* Literal.String.Backtick */
  .sc { color: #e6db74 } /* Literal.String.Char */
  .sd { color: #e6db74 } /* Literal.String.Doc */
  .s2 { color: #e6db74 } /* Literal.String.Double */
  .se { color: #ae81ff } /* Literal.String.Escape */
  .sh { color: #e6db74 } /* Literal.String.Heredoc */
  .si { color: #e6db74 } /* Literal.String.Interpol */
  .sx { color: #e6db74 } /* Literal.String.Other */
  .sr { color: #e6db74 } /* Literal.String.Regex */
  .s1 { color: #e6db74 } /* Literal.String.Single */
  .ss { color: #e6db74 } /* Literal.String.Symbol */
  .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */
  .vc { color: #f8f8f2 } /* Name.Variable.Class */
  .vg { color: #f8f8f2 } /* Name.Variable.Global */
  .vi { color: #f8f8f2 } /* Name.Variable.Instance */
  .il { color: #ae81ff } /* Literal.Number.Integer.Long */

  .gh { } /* Generic Heading & Diff Header */
  .gu { color: #979381; } /* Generic.Subheading & Diff Unified/Comment? */
  .gd { color: #f92672; } /* Generic.Deleted & Diff Deleted */
  .gi { color: #a6e22e; } /* Generic.Inserted & Diff Inserted */
}