Improved syntax highlighting on my website

Getting to know SHJS and GNU source-highlight
Published on June 12, 2022.
Last updated on November 10, 2022.

For another page on this site I wanted to enable syntax highlighting for .ini files. Looking at the language files included in my SHJS 'distribution' I didn't find an obvious file for 'ini'. I tried the 'desktop' language, because these seem similar to 'ini' files, but the resulting syntax highlighting didn't look good. The SHJS docs don't mention 'ini' at all.

I then took a little dive into how these files work. Turns out SHJS uses the language definition files from GNU source-highlight. These are then converted to the js files needed by SHJS. The source-highlight page mentions they support ini files, but I couldn't find a matching definition file in there. Looking at my Arch system, I saw that source-highlight is already installed, including the language definitions in /usr/share/source-highlight. So I ran source-highlight --lang-list which confirms that the desktop language is indeed the one to use for 'ini' files. I also downloaded the most recent SHJS source distribution from their Sourceforge.

Looking at the SHJS source, they include the source-highlight definitions as well, and they seem very similar, with one important difference.

--- /home/thomas/Projekte/extern/shjs-0.6-src/source-highlight-lang/desktop.lang        2022-06-12 10:37:47.468000842 +0200
+++ /usr/share/source-highlight/desktop.lang    2021-12-17 06:57:29.000000000 +0100
@@ -5,3 +5,7 @@
 section start '\[.*\]'

 (type,paren,normal,symbol) = `([^="\[]+)((?:\[.+\])*)([[:blank:]]*)(=)`
+
+include "number.lang"
+include "symbols.lang"
+include "c_string.lang"

They removed the includes at the end for some reason. So I wanted to convert the language definition from my system distributed source-highlight to the format needed by SHJS, which is done with their sh2js.pl script.

It didn't run however.

Turns out some time ago Perl distributions disabled loading modules from the current directory. So I had to add this to the beginning of the script.

use FindBin 1.51 qw( $RealBin );
use lib $RealBin;

I also had to install some dependencies with CPAN.

$ perl -MCPAN -e shell

Namely Parse::RecDescent.

install Parse::RecDescent

Then I was able to convert the file.

$ perl sh2js.pl /usr/share/source-highlight/desktop.lang > desktop_test.lang.js

And minify it, like the SHJS devs are doing in their makefile. For this, I had to get yuicompressor first.

$ wget https://github.com/yui/yuicompressor/releases/download/v2.4.8/yuicompressor-2.4.8.jar
$ mv yuicompressor-2.4.8.jar ~/bin/

And run it on the generated js file.

$ java -jar ~/bin/yuicompressor-2.4.8.jar desktop_test.lang.js > desktop_test.lang.min.js

That's it, worked flawlessly! Now I have some nicer ini file syntax highlighting. And this was a fun little exercise for sunday morning!

Update from November 2022:

I also added YAML, for which I found a ready-made language definition file by AlexZeitler.

And I added support for G-Code by making my own language definition, based on this:

# highlighting for CNC G-Code
# based on https://github.com/PrismJS/prism/blob/master/components/prism-gcode.js

comment = `;.*|\B\(.*?\)\B`
string = `"(?:""|[^"])*"`
keyword = `\b[GM]\d+(?:\.\d+)?\b`
function = `\b[A-Z]`
number = `(\*)\d+`
label = `[:*]`