Syntax highlighting with prism.js

Published on Saturday 16 April 2016. Tagged as CSSJavaScript.

Finding and implementing a nice and performant syntax highlighting tool. Loading an extra CSS file after the page has loaded, but only when needed.

Prism.js

Although I've built a syntax highlighter in JavaScript myself, that was in the days I still used Lotus Notes/Domino, so my tool supported only Lotus Formula Language and Lotusscript as backend coding languages. Now I want to support PHP. Luckily I stumbled upon a very nice tool that fits my purpose: prism.js, a hand-crafted tool written in JavaScript by Lea Verou e.a.

The tool is written in plain vanilla JavaScript, adding <span>s with CSS classes to do the colour coding. To use it real-time on your own pages, you only have to include one CSS and one JavaScript file. No need for any frameworks. There is also a test-drive page where you paste your code and convert it to a syntax highlighted version online. I decided to use the online tool to convert te code fragments I want and then grab the highlighted versions directly from there and paste them in my own pages. I then only have to add the prism.css file to the page.

Adding CSS on Demand with JavaScript

To keep my pages as slim as possible, avoiding any extra HTTP request I can, I decided to wait until the page is loaded (and rendered), see if there are code blocks on them and add the prism.css only when necessary. This has to be done with JavaScript, but the effort is so small that any JavaScript framework would be complete overkill.

Since most browsers now are almost completely standards compliant, the vanilla JavaScript is only a few lines. You can find a lot of examples elsewhere on the internet, but all make a DOM object, use DOM methods to add attributes to it and appending it to the <head> tag. My method is cleaner and faster, but some might be a bit shocked: I just append it as a string to the <head>'s innerHtml. That works as a charm:

document.addEventListener('DOMContentLoaded', function(){
	var D=document;
	if(D.querySelectorAll('pre code').length){
		var link='<link rel="stylesheet" href="/webdev/inc/prism.css">';
		D.querySelector('head').innerHTML+=link;
	}
} , false );

What next?

I continued working on the backend of this blog, and I now made a complete separation of the admin interface and the static pages. Now all the pages are rendered directly in the root, and HTTP requests to pages no longer have to route through the index page to be rendered. They are handled by a rewrite role in the .htaccess file, merely adding .phpto the requests. In the process, I lost the custom 404 page I've made: the server can't find it anymore... but that's something I hope to fix later. Here's the complete .htaccess file. The file also contains the code to add caching to files:

Options -Indexes

RewriteEngine On
RewriteRule ^(/.*|)$ - [L]
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^(.+)$ ./$1.php

<IfModule mod_expires.c>
ExpiresActive On 
ExpiresDefault "access plus 1 hour"

ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"

ExpiresByType image/x-icon "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType image/svg+xml "access plus 1 month"
ExpiresByType application/javascript "access plus 1 year"
</IfModule>

Next, I'll explain some tricks with the publish date of the listed posts in the index...