Simplified server-side syntax highlighting in Jigsaw

18th Jan 2021

php

I currently use Jigsaw, a static site generator based on the Laravel framework, for my personal website. By default the blog template ships with Highlight.js which is a great package for providing syntax highlighting for code blocks.

However, Highlight.js runs in the visitor's browser, and therefore can be quite slow when there are a lot of code blocks. I recently ported over to using Highlight.php (a PHP-port of the Highlight.js package) by following Stefan Zweifel's great article on implementing this. However, I knew that this article was old (from March 2019), and I also knew that some Markdown parser changes had been made to Jigsaw since then.

I was looking for a way to cut down this code and make it as simple as possible to implement. Back in February 2020, after the Markdown parser was changed to PHP Markdown, a PR was opened to restore the broken language-* prefixes for code blocks (PR #426). This however also added support for the markdownParser object being bound to the container meaning that it is accessible from your project's bootstrap.php.

One of the configurations that can be set in the boostrap.php is adding a callback function for code_block_content_func which is what gets run to transform the contents of a Markdown code block to HTML. I ended up using this with the following code.

First, I installed Highlight.php into my Jigsaw project (although this was already installed following Stefan's article).

$ composer require scrivo/highlight.php

And then, you can just add the following to your bootstrap.php file:

$container['markdownParser']->code_block_content_func = function ($code, $language) {
    return (new \Highlight\Highlighter())->highlight($language ?? 'plaintext', $code)->value;
};

Any code blocks without a language specified will fall back to plaintext, and all others will use their specified languages.

Note, you'll also need to include a stylesheet from the Highlight.php styles directory in your CSS source code. I currently use the a11y-light theme for my site.