Syntax Highlighting with Prism

May 20, 2017

After completing a minimal initial iteration of this web site, I began examining what features it still lacked. Among these was syntax highlighting for enhanced readability of code samples. I've evaluated several libraries for this purpose over the years: SyntaxHighlighter, highlight.js, Rainbow, and more recently Prism.

In this instance, I decided to use Prism, for a few reasons.

  1. At 2.4 KB, it has a fairly lean core.
  2. It has separate files for specific languages that are also fairly small. The one for PHP is a mere 968 bytes when minified.
  3. It supports display of line numbers via a plugin, a feature that is also supported in SyntaxHighlighter and Rainbow but not in highlight.js.
  4. It supports on-demand autoloading of syntax and stylesheet files for individual languages via a plugin that requires very little setup or configuration.
  5. It has a number of other useful plugins.
  6. It supports multiple color themes implemented using CSS.
  7. It is available on CDNJS, which removes the need for me to build or host it myself.

Implementing use of Prism involved making a few additions to my layout template.

First, I had to include two CSS files, one for the color theme and another for the line numbers plugin.

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.6.0/themes/prism-twilight.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.6.0/plugins/line-numbers/prism-line-numbers.min.css">

Second, I had to include three JS files: one for the Prism core, one for the line numbers plugin, and one for the autoloader plugin.

<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.6.0/components/prism-core.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.6.0/plugins/line-numbers/prism-line-numbers.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.6.0/plugins/autoloader/prism-autoloader.min.js"></script>

Finally, I had to provide a bit of JS to set a base path for autoloaded language files and to enable the line numbers plugin.

Prism.plugins.autoloader.languages_path = 'https://cdnjs.cloudflare.com/ajax/libs/prism/1.6.0/components/';
Prism.hooks.add('before-highlight', function(env) {
    env.element.className += ' line-numbers';
});

The CommonMark standard supports what it calls info strings in fenced code blocks, which can be used to (among other things) designate the language of the code within the block. The library I use to produce HTML from Markdown, league/commonmark, generates HTML for info strings in a way that is conveniently consistent with how the Prism autoloader searches for code samples to highlight.

Overall, Prism offered a fairly easily implemented solution to produce aesthetically pleasing and readable code samples as a progressive enhancement.