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];
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"
);