]> Lady’s Gitweb - GitWikiWeb/blobdiff - build.js
Style horizontal rules
[GitWikiWeb] / build.js
index e8b700344c66acd85b81731b1f9324d68bdd3954..0eb61fd8de30773f9abed8bea7f99eb6cd9d674e 100644 (file)
--- a/build.js
+++ b/build.js
@@ -20,7 +20,7 @@
 //     export GITWIKIWEB=/srv/git/GitWikiWeb
 //     git archive --remote=$GITWIKIWEB HEAD build.js \
 //       | tar -xO \
-//       | deno run -A - ~/public/wiki $GITWIKIWEB
+//       | deno run -A - ~/public/wiki $GITWIKIWEB current
 //
 // The directory `~/public/wiki` (or whatever you specify as the first
 // argument to `deno run -A -`) **will be deleted** and a new static
@@ -50,6 +50,7 @@ import domSerializer from "npm:dom-serializer@2.0.0";
 
 const DESTINATION = Deno.args[0] ?? "~/public/wiki";
 const REMOTE = Deno.args[1] ?? "/srv/git/GitWikiWeb";
+const REV = Deno.args[2] ?? "HEAD";
 
 const READ_ONLY = {
   configurable: false,
@@ -93,7 +94,7 @@ const getDOM = (source) => {
 
 const getRemoteContent = async (pathName) => {
   const getArchive = new Deno.Command("git", {
-    args: ["archive", `--remote=${REMOTE}`, "HEAD", pathName],
+    args: ["archive", `--remote=${REMOTE}`, REV, pathName],
     stdout: "piped",
     stderr: "piped",
   }).spawn();
@@ -146,8 +147,8 @@ const logErrorsAndCollectResults = (results) =>
   });
 
 const getReferenceFromPath = (path) =>
-  /Sources\/([A-Z][0-9A-Za-z]*\/[A-Z][0-9A-Za-z]*)\.djot$/u.exec(path)
-    ?.[1]?.replace?.("/", ":");
+  /Sources\/([A-Z][0-9A-Za-z]*(?:\/[A-Z][0-9A-Za-z]*)+)\.djot$/u
+    .exec(path)?.[1]?.replace?.("/", ":"); // only replaces first slash
 
 const listOfInternalLinks = (references, wrapper = ($) => $) => ({
   tag: "bullet_list",
@@ -234,7 +235,6 @@ class GitWikiWebPage {
             const links_section = [];
             if (internalLinks.size || externalLinks.size) {
               links_section.push(
-                rawBlock`<footer>`,
                 rawBlock`<nav id="links">`,
                 {
                   tag: "heading",
@@ -293,35 +293,16 @@ class GitWikiWebPage {
               }
               links_section.push(
                 rawBlock`</nav>`,
-                rawBlock`</footer>`,
               );
             } else {
               /* do nothing */
             }
-            e.children.push(...links_section);
-          },
-        },
-        emph: {
-          enter: (_) => {},
-          exit: (e) => {
-            const attributes = e.attributes ?? NIL;
-            const { as } = attributes;
-            if (as) {
-              delete attributes.as;
-              if (
-                as == "b" || as == "cite" || as == "i" || as == "u"
-              ) {
-                return [
-                  rawInline`<${as}>`,
-                  ...e.children,
-                  rawInline`</${as}>`,
-                ];
-              } else {
-                /* do nothing */
-              }
-            } else {
-              /* do nothing */
-            }
+            e.children.push(
+              rawBlock`<footer>`,
+              rawBlock`${"\uFFFF"}`, // footnote placeholder
+              ...links_section,
+              rawBlock`</footer>`,
+            );
           },
         },
         hard_break: {
@@ -350,7 +331,7 @@ class GitWikiWebPage {
             e.attributes ??= {};
             const { attributes, reference, destination } = e;
             if (
-              /^(?:[A-Z][0-9A-Za-z]*|[@#])?:(?:[A-Z][0-9A-Za-z]*)?$/u
+              /^(?:[A-Z][0-9A-Za-z]*|[@#])?:(?:[A-Z][0-9A-Za-z]*(?:\/[A-Z][0-9A-Za-z]*)*)?$/u
                 .test(reference ?? "")
             ) {
               const [namespacePrefix, pageName] = splitReference(
@@ -512,12 +493,44 @@ class GitWikiWebPage {
   }
 }
 
+{
+  // Patches for Djot HTML renderer.
+  const { HTMLRenderer: { prototype: htmlRendererPrototype } } = djot;
+  const { inTags: upstreamInTags } = htmlRendererPrototype;
+  htmlRendererPrototype.inTags = function (
+    tag,
+    node,
+    newlines,
+    extraAttrs = undefined,
+  ) {
+    const attributes = node.attributes ?? NIL;
+    if ("as" in attributes) {
+      const newTag = attributes.as;
+      delete attributes.as;
+      return upstreamInTags.call(
+        this,
+        newTag,
+        node,
+        newlines,
+        extraAttrs,
+      );
+    } else {
+      return upstreamInTags.call(
+        this,
+        tag,
+        node,
+        newlines,
+        extraAttrs,
+      );
+    }
+  };
+}
 {
   const config = await getRemoteContent("config.yaml").then((yaml) =>
     parseYaml(yaml, { schema: JSON_SCHEMA })
   );
   const ls = new Deno.Command("git", {
-    args: ["ls-tree", "-rz", "live"],
+    args: ["ls-tree", "-rz", "HEAD"],
     stdout: "piped",
     stderr: "piped",
   }).spawn();
@@ -663,7 +676,8 @@ class GitWikiWebPage {
         }
         const results = new Array(6);
         const seen = new Set();
-        let recency = 5;
+        const maxRecency = Math.max(config.max_recency | 0, 0);
+        let recency = maxRecency;
         let current;
         do {
           const show = new Deno.Command("git", {
@@ -671,7 +685,7 @@ class GitWikiWebPage {
               "show",
               "-s",
               "--format=%H%x00%cI%x00%cD",
-              recency ? `HEAD~${5 - recency}` : commit,
+              recency ? `HEAD~${maxRecency - recency}` : commit,
             ],
             stdout: "piped",
             stderr: "piped",
@@ -910,8 +924,25 @@ class GitWikiWebPage {
           },
         };
       });
+      const renderedAST = djot.renderAST(ast);
       const doc = getDOM(template);
-      const result = getDOM(`${djot.renderHTML(ast)}`);
+      const result = getDOM(djot.renderHTML(ast, {
+        overrides: {
+          raw_block: (node, context) => {
+            if (node.format == "html" && node.text == "\uFFFF") {
+              if (context.nextFootnoteIndex > 1) {
+                const result = context.renderNotes(ast.footnotes);
+                context.nextFootnoteIndex = 1;
+                return result;
+              } else {
+                return "";
+              }
+            } else {
+              return context.renderAstNodeDefault(node);
+            }
+          },
+        },
+      }));
       const headElement = domutils.findOne(
         (node) => node.name == "head",
         doc,
@@ -951,7 +982,7 @@ class GitWikiWebPage {
           "GitWikiWeb: Template did not include a <gitwikiweb-content> element.",
         );
       } else {
-        for (const node of result) {
+        for (const node of [...result]) {
           domutils.prepend(contentElement, node);
         }
         domutils.removeElement(contentElement);
@@ -968,6 +999,13 @@ class GitWikiWebPage {
           { createNew: true },
         ),
       );
+      promises.push(
+        Deno.writeTextFile(
+          `${DESTINATION}/${pageRef}/index.ast`,
+          renderedAST,
+          { createNew: true },
+        ),
+      );
       promises.push(
         Deno.writeTextFile(
           `${DESTINATION}/${pageRef}/source.djot`,
This page took 0.02852 seconds and 4 git commands to generate.