Skip to content

Commit 1744c59

Browse files
authored
Add build support for linking to bibliographical references (#4124)
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)
1 parent 3d88e14 commit 1744c59

File tree

3 files changed

+145
-2
lines changed

3 files changed

+145
-2
lines changed

11ty/CustomLiquid.ts

+19-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { basename } from "path";
88

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

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

25+
const biblio = await getBiblio();
2426
const termsMap = await getTermsMap();
2527
const termLinkSelector = "a:not([href])";
2628

@@ -89,7 +91,7 @@ export class CustomLiquid extends Liquid {
8991
const isIndex = indexPattern.test(filepath);
9092
const isTechniques = techniquesPattern.test(filepath);
9193
const isUnderstanding = understandingPattern.test(filepath);
92-
94+
9395
if (!isTechniques && !isUnderstanding) return super.parse(html);
9496

9597
const $ = flattenDom(html, filepath);
@@ -507,7 +509,7 @@ export class CustomLiquid extends Liquid {
507509
<p>${$el.html()}</p>
508510
</div>`);
509511
});
510-
512+
511513
// Add header to example sections in Key Terms (aside) and Conformance (div)
512514
$("aside.example, div.example").each((_, el) => {
513515
const $el = $(el);
@@ -540,6 +542,21 @@ export class CustomLiquid extends Liquid {
540542
});
541543
}
542544

545+
// Link biblio references
546+
if (scope.isUnderstanding) {
547+
$("p").each((_, el) => {
548+
const $el = $(el);
549+
const html = $el.html();
550+
if (html && biblioPattern.test(html)) {
551+
$el.html(
552+
html.replace(biblioPattern, (substring, code) =>
553+
biblio[code]?.href ? `[<a href="${biblio[code].href}">${code}</a>]` : substring
554+
)
555+
);
556+
}
557+
});
558+
}
559+
543560
// Allow autogenerating missing top-level section IDs in understanding docs,
544561
// but don't pick up incorrectly-nested sections in some techniques pages (e.g. H91)
545562
const sectionSelector = scope.isUnderstanding ? "section" : "section[id]:not(.obsolete)";

11ty/biblio.ts

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import axios from "axios";
2+
import { readFile } from "fs/promises";
3+
import { glob } from "glob";
4+
import uniq from "lodash-es/uniq";
5+
6+
export const biblioPattern = /\[\[\??([\w-]+)\]\]/g;
7+
8+
/** Compiles URLs from local biblio + specref for linking in Understanding documents. */
9+
export async function getBiblio() {
10+
const localBiblio = eval(
11+
(await readFile("biblio.js", "utf8"))
12+
.replace(/^respecConfig\.localBiblio\s*=\s*/, "(")
13+
.replace("};", "})")
14+
);
15+
16+
const refs: string[] = [];
17+
for (const path of await glob(["guidelines/**/*.html", "understanding/*/*.html"])) {
18+
const content = await readFile(path, "utf8");
19+
let match;
20+
while ((match = biblioPattern.exec(content))) if (!localBiblio[match[1]]) refs.push(match[1]);
21+
}
22+
const uniqueRefs = uniq(refs);
23+
24+
const response = await axios.get(`https://api.specref.org/bibrefs?refs=${uniqueRefs.join(",")}`);
25+
const fullBiblio = {
26+
...response.data,
27+
...localBiblio,
28+
};
29+
30+
const resolvedRefs = Object.keys(fullBiblio);
31+
const unresolvedRefs = uniqueRefs.filter((ref) => !resolvedRefs.includes(ref));
32+
if (unresolvedRefs.length) console.warn(`Unresolved biblio refs: ${unresolvedRefs.join(", ")}`);
33+
34+
return fullBiblio;
35+
}

package-lock.json

+91
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)