From: Lady Date: Wed, 3 May 2023 01:33:34 +0000 (-0700) Subject: Add highlighting support for code blocks X-Git-Url: https://git.ladys.computer/Blog/commitdiff_plain/bb0407b1891330f2f759528154c98d3420a285f5 Add highlighting support for code blocks This code is somewhat messy because it has to work around the extreme limitations of the xmldom window polyfill provided by Lemon. - Updates the dependency on Beorn to 0.2.1 and adds a new one for highlight.js at 11.8.0. - Defines a wrapper build script to set up a transformation hook and then dynamically run Beorn through an import. - Updates .rsync-filter to exclude these new files. --- diff --git a/.rsync-filter b/.rsync-filter index b238190..01b3406 100644 --- a/.rsync-filter +++ b/.rsync-filter @@ -1,6 +1,8 @@ -s .DS_Store -s .git -s .gitignore +-s deno.json +-s /build.js -s /GNUmakefile -s /.grass - /.rsync-filter diff --git a/GNUmakefile b/GNUmakefile index 3095070..5491636 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -6,9 +6,6 @@ SHELL = /bin/sh # 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/. -BEORN_VERSION = 0.1.0 -BEORN = https://git.ladys.computer/Beorn/blob_plain/$(BEORN_VERSION):/build.js - # This Makefile requires rsync 3 or newer. RSYNC = rsync RSYNC_FLAGS = -Oclmrtvz @@ -32,7 +29,7 @@ DESTINATION = $(DESTINATION_HOST):$(DESTINATION_PATH) GIT_FORCE = build: - deno run --allow-read=. --allow-write=. $(BEORN) + deno run --allow-read=. --allow-write=. ./build.js touch .grass ensure-build: @@ -45,7 +42,6 @@ ensure-branch-up-to-date: ensure-clean: @if output=$$(git status --porcelain) && [ ! -z "$$output" ]; then echo 'Error: There are uncommitted changes!' >&2; echo 'Commit changes and run `make` before syncing.' >&2; exit 1; fi - @if output=$$(git status --porcelain) && [ ! -z "$$output" ]; then echo 'Error: There are uncommitted changes!' >&2; echo 'Commit changes and run `make` before syncing.' >&2; exit 1; fi dry-sync: ensure-clean$(if $(GIT_FORCE),, ensure-branch-up-to-date) ensure-build $(RSYNC) $(RSYNC_FLAGS) --del --dry-run --filter=". $(RSYNC_FILTER)" --iconv=$(SOURCE_CHARSET),$(DESTINATION_CHARSET) $(RSYNC_OPTIONS) . $(DESTINATION) diff --git a/build.js b/build.js new file mode 100755 index 0000000..641bd94 --- /dev/null +++ b/build.js @@ -0,0 +1,62 @@ +#!/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 . + +import hljs from "npm:highlight.js@11.8.0"; + +const processContent = (content) => { + if (content == null || Object(content) instanceof String) { + /* do nothing */ + } else if (Array.isArray(content)) { + // The provided content is an array. + content.forEach(processContent); + } else { + for (const child of Array.from(content)) { + applyHighlighting(child); + } + } +}; + +const applyHighlighting = (node) => { + if ( + node.localName == "pre" && node.childNodes.length == 1 && + node.firstChild.localName == "code" + ) { + const code = node.firstChild; + const language = /language-(.*)/u.exec(code.getAttribute("class")) + ?.[1]; + if (language) { + try { + const { value: highlight } = hljs.highlight( + node.firstChild.textContent, + { language }, + ); + const nodes = new DOMParser().parseFromString( + `${highlight}`, + "text/html", + ).documentElement.lastChild.childNodes; + code.textContent = ""; + for (const node of Array.from(nodes)) { + code.appendChild(code.ownerDocument.importNode(node, true)); + } + } catch (e) { + console.warn(e); + } + } + } else if (node.nodeType == 1) { + Array.from(node.childNodes).forEach(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" +); diff --git a/deno.json b/deno.json new file mode 100644 index 0000000..05375a3 --- /dev/null +++ b/deno.json @@ -0,0 +1 @@ +{ "fmt": { "lineWidth": 71 }, "lock": false }