]> Lady’s Gitweb - Blog/blobdiff - build.js
[2023-07-29] git_wiki
[Blog] / build.js
index a3e7630d8dca71268c42f3469aee2e983f139ace..07eeb0ac0ffeefb710f2ecd31fbb78ac2ce07cee 100755 (executable)
--- a/build.js
+++ b/build.js
@@ -8,24 +8,31 @@
 
 import hljs from "npm:highlight.js@11.8.0";
 
-const processContent = (content) => {
+const contentLinks = new WeakMap();
+
+const processContent = function (content) {
   if (content == null || Object(content) instanceof String) {
+    // The provided content is nullish or a string.
     /* do nothing */
   } else if (Array.isArray(content)) {
     // The provided content is an array.
-    content.forEach(processContent);
+    content.forEach(processContent.bind(this));
   } else {
+    // The provided content is a NodeList.
     for (const child of Array.from(content)) {
-      applyHighlighting(child);
+      applyTransforms.call(this, child);
     }
   }
 };
 
-const applyHighlighting = (node) => {
+const applyTransforms = function (node) {
+  const document = node.ownerDocument;
+  const LMN = Lemon.bind(document);
   if (
     node.localName == "pre" && node.childNodes.length == 1 &&
     node.firstChild.localName == "code"
   ) {
+    // This is a code block and should be highlighted.
     const code = node.firstChild;
     const language = /language-(.*)/u.exec(code.getAttribute("class"))
       ?.[1];
@@ -47,20 +54,107 @@ const applyHighlighting = (node) => {
         for (const node of Array.from(nodes)) {
           code.appendChild(code.ownerDocument.importNode(node, true));
         }
+        return; // don’t continue processing this node
       } catch (e) {
         console.warn(e);
       }
     }
-  } else if (node.nodeType == 1) {
-    Array.from(node.childNodes).forEach(applyHighlighting);
+  } else if (node.localName == "a") {
+    const href = node.getAttribute("href");
+    const title = node.getAttribute("title");
+    if (title && href) {
+      contentLinks.get(this)[title] = href;
+    }
+  }
+  if (node.nodeType == 1) {
+    // This is an element; process its children.
+    if (node.localName == "code") {
+      // This is a `<code>` element; wrap it in a `Word-Wrap: Pre` with
+      // any previous/next characters to prevent line‐breaking due to
+      // it being rendered as an inline block.
+      const prev = node.previousSibling;
+      const prevText = prev?.nodeType == 3 ? prev.textContent : "";
+      const prevWrap = prevText.match(/(?:(?!—)\S)*$/u)[0];
+      const next = node.nextSibling;
+      const nextText = next?.nodeType == 3 ? next.textContent : "";
+      const nextWrap = nextText.match(/^(?:(?!—)\S)*/u)[0];
+      if (prevWrap || nextWrap) {
+        const span = LMN.span.style("White-Space: Pre")``;
+        node.parentNode.replaceChild(span, node);
+        if (prevWrap) {
+          prev.parentNode.replaceChild(
+            document.createTextNode(
+              prevText.substring(0, prevText.length - prevWrap.length),
+            ),
+            prev,
+          );
+          span.appendChild(
+            document.createTextNode(
+              prevText.substring(prevText.length - prevWrap.length),
+            ),
+          );
+        }
+        span.appendChild(node);
+        if (nextWrap) {
+          const nexts = [
+            document.createTextNode(
+              nextText.substring(0, nextWrap.length),
+            ),
+            document.createTextNode(
+              nextText.substring(nextWrap.length),
+            ),
+          ];
+          span.appendChild(nexts[0]);
+          next.parentNode.replaceChild(nexts[1], next);
+          for (const nextNode of nexts) {
+            applyTransforms.call(this, nextNode);
+          }
+        }
+      }
+    }
+    Array.from(node.childNodes).forEach(applyTransforms.bind(this));
+  } else if (node.nodeType == 3) {
+    // This is a text node; apply replacements.
+    node.textContent = node.textContent.replaceAll(":—", ":\u2060—");
   }
 };
 
 globalThis.bjørnTransformMetadata = (metadata, _type) => {
-  processContent(metadata.content);
-  processContent(metadata.summary);
+  contentLinks.set(metadata, {});
+  processContent.call(metadata, metadata.content);
+  processContent.call(metadata, metadata.summary);
+};
+
+globalThis.bjørnTransformFeedHTML = (document, _metadata) => {
+  const LMN = Lemon.bind({ document });
+  const h1 = document.getElementsByTagNameNS(
+    "http://www.w3.org/1999/xhtml",
+    "h1",
+  )[0];
+  const link = LMN.a.href("/")``;
+  for (const child of Array.from(h1.childNodes)) {
+    link.appendChild(child);
+  }
+  h1.appendChild(link);
+};
+
+globalThis.bjørnTransformEntryHTML = (document, metadata) => {
+  const LMN = Lemon.bind({ document });
+  const links = Object.entries(contentLinks.get(metadata));
+  if (links.length) {
+    document.getElementById("entry.content").appendChild(
+      LMN.footer`${LMN.nav`${[
+        LMN.h2`This post contains links.`,
+        LMN.ul`${
+          links.map(([name, href]) =>
+            LMN.li`${LMN.a.href(href)`${name}`}`
+          )
+        }`,
+      ]}`}`,
+    );
+  }
 };
 
 await import(
-  "https://git.ladys.computer/Beorn/blob_plain/0.2.3:/build.js"
+  "https://git.ladys.computer/Beorn/blob_plain/0.2.4:/build.js"
 );
This page took 0.043254 seconds and 4 git commands to generate.