Skip to content

Commit

Permalink
Add build support for linking to bibliographical references (#4124)
Browse files Browse the repository at this point in the history
Refs #2535

This adds support to the Eleventy build system for resolving
bibliographical references within paragraphs in the format `[[ref]]`,
and converting them into links within single brackets instead.

This resolves against both specref.org and the local bibliography
configured in `biblio.js` in this repo.

Note that there are some references that have no resolution in either of
these sources, which is why I'm not marking this as fully resolving the
related issue.

Details at
#2535 (comment)
  • Loading branch information
kfranqueiro authored Nov 20, 2024
1 parent 3d88e14 commit 1744c59
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 2 deletions.
21 changes: 19 additions & 2 deletions 11ty/CustomLiquid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { basename } from "path";

import type { GlobalData } from "eleventy.config";

import { biblioPattern, getBiblio } from "./biblio";
import { flattenDom, load } from "./cheerio";
import { generateId } from "./common";
import { getTermsMap } from "./guidelines";
Expand All @@ -21,6 +22,7 @@ const indexPattern = /(techniques|understanding)\/(index|about)\.html$/;
const techniquesPattern = /\btechniques\//;
const understandingPattern = /\bunderstanding\//;

const biblio = await getBiblio();
const termsMap = await getTermsMap();
const termLinkSelector = "a:not([href])";

Expand Down Expand Up @@ -89,7 +91,7 @@ export class CustomLiquid extends Liquid {
const isIndex = indexPattern.test(filepath);
const isTechniques = techniquesPattern.test(filepath);
const isUnderstanding = understandingPattern.test(filepath);

if (!isTechniques && !isUnderstanding) return super.parse(html);

const $ = flattenDom(html, filepath);
Expand Down Expand Up @@ -507,7 +509,7 @@ export class CustomLiquid extends Liquid {
<p>${$el.html()}</p>
</div>`);
});

// Add header to example sections in Key Terms (aside) and Conformance (div)
$("aside.example, div.example").each((_, el) => {
const $el = $(el);
Expand Down Expand Up @@ -540,6 +542,21 @@ export class CustomLiquid extends Liquid {
});
}

// Link biblio references
if (scope.isUnderstanding) {
$("p").each((_, el) => {
const $el = $(el);
const html = $el.html();
if (html && biblioPattern.test(html)) {
$el.html(
html.replace(biblioPattern, (substring, code) =>
biblio[code]?.href ? `[<a href="${biblio[code].href}">${code}</a>]` : substring
)
);
}
});
}

// Allow autogenerating missing top-level section IDs in understanding docs,
// but don't pick up incorrectly-nested sections in some techniques pages (e.g. H91)
const sectionSelector = scope.isUnderstanding ? "section" : "section[id]:not(.obsolete)";
Expand Down
35 changes: 35 additions & 0 deletions 11ty/biblio.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import axios from "axios";
import { readFile } from "fs/promises";
import { glob } from "glob";
import uniq from "lodash-es/uniq";

export const biblioPattern = /\[\[\??([\w-]+)\]\]/g;

/** Compiles URLs from local biblio + specref for linking in Understanding documents. */
export async function getBiblio() {
const localBiblio = eval(
(await readFile("biblio.js", "utf8"))
.replace(/^respecConfig\.localBiblio\s*=\s*/, "(")
.replace("};", "})")
);

const refs: string[] = [];
for (const path of await glob(["guidelines/**/*.html", "understanding/*/*.html"])) {
const content = await readFile(path, "utf8");
let match;
while ((match = biblioPattern.exec(content))) if (!localBiblio[match[1]]) refs.push(match[1]);
}
const uniqueRefs = uniq(refs);

const response = await axios.get(`https://api.specref.org/bibrefs?refs=${uniqueRefs.join(",")}`);
const fullBiblio = {
...response.data,
...localBiblio,
};

const resolvedRefs = Object.keys(fullBiblio);
const unresolvedRefs = uniqueRefs.filter((ref) => !resolvedRefs.includes(ref));
if (unresolvedRefs.length) console.warn(`Unresolved biblio refs: ${unresolvedRefs.join(", ")}`);

return fullBiblio;
}
91 changes: 91 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 1744c59

Please sign in to comment.