]> Lady’s Gitweb - Beorn/blobdiff - build.js
Be more precise checking for date‐named directories
[Beorn] / build.js
index 024698acde71ebcb1fc22b8dd789320ec8cf0425..9ae91c9f68f5702518d1662b67eaf87aef9b86ce 100755 (executable)
--- 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 */
@@ -510,31 +511,63 @@ const basePath = `./${Deno.args[0] ?? ""}`;
  *
  * - "literal": This is a plaintext field.
  */
-const context = {
-  author: { namespace: DC11, localName: "creator", type: "person" },
+const context = Object.freeze({
+  author: Object.freeze({
+    namespace: DC11,
+    localName: "creator",
+    type: "person",
+  }),
   // category is not supported at this time
-  content: { namespace: SIOC, localName: "content", type: "text" },
-  contributor: {
+  content: Object.freeze({
+    namespace: SIOC,
+    localName: "content",
+    type: "text",
+  }),
+  contributor: Object.freeze({
     namespace: DC11,
     localName: "contributor",
     type: "person",
-  },
+  }),
   // generator is provided by the build script
-  icon: { namespace: AWOL, localName: "icon", type: "literal" },
+  icon: Object.freeze({
+    namespace: AWOL,
+    localName: "icon",
+    type: "literal",
+  }),
   // link is provided by the build script
-  logo: { namespace: AWOL, localName: "logo", type: "literal" },
-  published: {
+  logo: Object.freeze({
+    namespace: AWOL,
+    localName: "logo",
+    type: "literal",
+  }),
+  published: Object.freeze({
     namespace: DC11,
     localName: "date",
     type: "literal",
-  },
-  rights: { namespace: DC11, localName: "rights", type: "text" },
+  }),
+  rights: Object.freeze({
+    namespace: DC11,
+    localName: "rights",
+    type: "text",
+  }),
   // source is not supported at this time
-  subtitle: { namespace: RDFS, localName: "label", type: "text" },
-  summary: { namespace: DC11, localName: "abstract", type: "text" },
-  title: { namespace: DC11, localName: "title", type: "text" },
+  subtitle: Object.freeze({
+    namespace: RDFS,
+    localName: "label",
+    type: "text",
+  }),
+  summary: Object.freeze({
+    namespace: DC11,
+    localName: "abstract",
+    type: "text",
+  }),
+  title: Object.freeze({
+    namespace: DC11,
+    localName: "title",
+    type: "text",
+  }),
   // updated is provided by the build script
-};
+});
 
 const {
   /**
@@ -639,6 +672,7 @@ const fillOutHead = (document, metadata, type) => {
         .href("./feed.atom")``,
     );
   }
+  globalThis.bjørnTransformHead?.(head, metadata, type);
 };
 
 /**
@@ -866,6 +900,7 @@ const metadataFromDocument = (
       /* do nothing */
     }
   }
+  globalThis.bjørnTransformMetadata?.(result, documentType);
   return validateMetadata(result, documentType);
 };
 
@@ -906,6 +941,32 @@ 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,
+    context,
+    getLanguage,
+    setLanguage,
+  };
+}
+
 await (async () => { // this is the run script
   const writes = [];
 
@@ -957,7 +1018,7 @@ await (async () => { // this is the run script
   ) {
     // Iterate over each directory and process the ones which are
     // dates.
-    if (!isDirectory || !/[0-9]{4}-[0-9]{2}-[0-9]{2}/u.test(date)) {
+    if (!isDirectory || !/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/u.test(date)) {
       // This isn’t a dated directory.
       continue;
     } else {
@@ -1114,6 +1175,7 @@ await (async () => { // this is the run script
       /* do nothing */
     }
   }
+  globalThis.bjørnTransformFeedHTML?.(feedTemplate, feedMetadata);
   writes.push(
     Deno.writeTextFile(
       "index.xhtml",
@@ -1122,6 +1184,7 @@ await (async () => { // this is the run script
   );
 
   // Save the feed Atom file.
+  globalThis.bjørnTransformFeedAtom?.(document, feedMetadata);
   writes.push(
     Deno.writeTextFile(
       "feed.atom",
This page took 0.055951 seconds and 4 git commands to generate.