Lady’s Computer: MY computer over YOUR internets

Lady’s Weblog

Adding syntax highlighting to Lady’s Weblog

Lady

Published: .

As I mentioned previously, this blog is generated using a hacky Ecmascript+Deno static site generator I wrote called Bjørn. I originally wrote Bjørn for a different blog, on a different site, and I published the source code with the intention that anyone who used it would use it as a template and hack on it as they saw fit. But, when I started this blog, I decided to not do that (it sounded like a lot of work t·b·h) and instead just pulled in the latest version from the git repository with no changes :⁠—

build:
	deno run --allow-read=. --allow-write=. $(BEORN)
The original Makefile rule for building this blog.

…Look, mostly I just did not want to have to maintain a fork of my own software just to have a blog. However, that has made it difficult to provide any meaningful customization to the compiled output, including things like the syntax highlighting seen on this page.

Bjørn was written and designed to be run as a shell script—not as a library. It processes the current directory immediately when it runs. So in order to add configurability, I had to define “hooks” on the global object, which Bjørn can check for at runtime and execute if they exist. (I made those changes in 7bea148.) Then, in what is sure to give any respectable Javascript dev nightmares, I set up the build script for this blog as follows :⁠—

#!/usr/bin/env -S deno run --allow-read --allow-write

// Copyright © 2023 Lady [@ Lady’s Computer].
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at <https://mozilla.org/MPL/2.0/>.

import hljs from "npm:highlight.js@11.8.0";

// [Redacted for brevity: function definitions for `processContent` and
// `applyHighlighting`.]

globalThis.bjørnTransformMetadata = (metadata, _type) => {
  processContent(metadata.content);
  processContent(metadata.summary);
};

await import(
  "https://git.ladys.computer/Beorn/blob_plain/0.2.1:/build.js"
);
Excerpt of this blog’s current build script.

Or, to summarize, I used a dynamic import() to defer running of the Bjørn script until after my globalThis.bjørnTransformMetadata hook had had a chance to be defined. (It still just processes the whole directory the second it runs.)

This is very dirty and hacky and also works very well. I’m satisfied with the result! The actual code is a bit horrible, because of course this is executing in an environment without a real D·O·M and the polyfill I am using is extremely minimal. I chose to use Shades of Purple as my interim syntax highlighting theme as it seemed more healthy and less bullshit than a lot of the other themes on the highlight.js website; ideally at some point I will replace it with a theme of my own.