From: Lady Date: Tue, 2 May 2023 23:51:17 +0000 (-0700) Subject: Support hooks for transforming build script output X-Git-Tag: 0.2.0^0 X-Git-Url: https://git.ladys.computer/Beorn/commitdiff_plain/7bea148d7f7b13878c590a9105af1829870fa7e7?hp=203c5e4c4b5ea796aa24e90f11b80c8c887d2059 Support hooks for transforming build script output See README changes for a more in‐depth explanation, but the idea here is that users should have an opportunity to make adjustments to the build output before it is saved. This relies on defining hooks on the global object and then using a dynamic import to get the build script to run. --- diff --git a/README.markdown b/README.markdown index a0f3043..6a72afb 100644 --- a/README.markdown +++ b/README.markdown @@ -123,7 +123,48 @@ file extension. A sample `.rsync-filter` might be as follows :— Feel free to add styles, additional content, and whatever else you like to the template files (as well as the rest of the website). -To modify what content is generated, simply edit `build.js` :) . +### Hooks + +🧸📔 Bjørn recognizes the following hooks (defined on the global +object) when it runs :— + +- **`globalThis.bjørnTransformEntryHTML(document, metadata)`:** + Receives a document and a metadata object for each generated HTML + entry. + +- **`globalThis.bjørnTransformFeedAtom(document, metadata)`:** Receives + a document and a metadata object for each generated Atom feed index. + +- **`globalThis.bjørnTransformFeedHTML(document, metadata)`:** Receives + a document and a metadata object for each generated HTML feed index. + +- **`globalThis.bjørnTransformHead(headElement, metadata, type)`:** + Receives a `` element, a metadata object, and a type value of + either `"entry"` or `"feed"`. + +- **`globalThis.bjørnTransformMetadata(metadata, type)`:** Receives a + metadata object, and a type value of either `"entry"` or `"feed"`. + Use this to provide any initial transformations to the metadata prior + to document generation. + +Naturally, when running 🧸📔 Bjørn normally from the command line, all +of these hooks are undefined. You can write your own small build script +to define them, and run that instead :— + +```js +#!/usr/bin/env -S deno run --allow-read --allow-write +// custom_build.js + +// Define your hooks first… +globalThis.bjørnTransformHead = (headElement, metadata, type) => { + Array.from(headElement.children) + .find(($) => $.localName == "title") + .textContent += " | My Cool Site"; +}; + +// Then run the script… +await import("./build.js"); +``` [CommonMark]: [Deno]: diff --git a/build.js b/build.js index 024698a..4c26518 100755 --- a/build.js +++ b/build.js @@ -2,7 +2,7 @@ // 🧸📔 Bjørn ∷ build.js // ==================================================================== // -// Copyright © 2022 Lady [@ Lady’s Computer]. +// Copyright © 2022‐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 @@ -344,6 +344,7 @@ const applyMetadata = (node, metadata) => { // There is no content placeholder. /* do nothing */ } + globalThis.bjørnTransformEntryHTML?.(document, metadata); } else { // This is not an XHTML template. /* do nothing */ @@ -639,6 +640,7 @@ const fillOutHead = (document, metadata, type) => { .href("./feed.atom")``, ); } + globalThis.bjørnTransformHead?.(head, metadata, type); }; /** @@ -866,6 +868,7 @@ const metadataFromDocument = ( /* do nothing */ } } + globalThis.bjørnTransformMetadata?.(result, documentType); return validateMetadata(result, documentType); }; @@ -906,6 +909,31 @@ const validateMetadata = (metadata, type) => { } }; +{ // Set up global variables for use in hooks. + // + // Bjørn is principally built to be run from the command line (as a + // shell script) rather than conforming to typical Ecmascript module + // patterns. However, it recognizes hooks through various + // specially‐named properties on `globalThis`. After defining these + // hooks, a script can use a *dynamic* `import("./path/to/build.js")` + // to run the Bjørn build steps. + // + // To make writing scripts which make use of these hooks easier, + // infrastructural dependencies and useful functions are provided on + // `globalThis` so that wrapping scripts don’t have to attempt to + // manage the dependencies themselves. + // + // Note that the `Lemon/window` polyfill will already have + // established some D·O·M‐related global properties by the time this + // runs, so they don’t need to be redeclared here. + globalThis.Lemon = Lemon; + globalThis.Bjørn = { + addContent, + getLanguage, + setLanguage, + }; +} + await (async () => { // this is the run script const writes = []; @@ -1114,6 +1142,7 @@ await (async () => { // this is the run script /* do nothing */ } } + globalThis.bjørnTransformFeedHTML?.(feedTemplate, feedMetadata); writes.push( Deno.writeTextFile( "index.xhtml", @@ -1122,6 +1151,7 @@ await (async () => { // this is the run script ); // Save the feed Atom file. + globalThis.bjørnTransformFeedAtom?.(document, feedMetadata); writes.push( Deno.writeTextFile( "feed.atom", diff --git a/deno.json b/deno.json index e5f93e5..d00db95 100644 --- a/deno.json +++ b/deno.json @@ -1,4 +1 @@ -{ - "fmt": { "options": { "lineWidth": 71 } }, - "lint": { "rules": { "exclude": ["no-irregular-whitespace"] } } -} +{ "fmt": { "lineWidth": 71 } }