diff --git a/src/core/render-biblio.js b/src/core/render-biblio.js index 00c8322fe2..5386bb856d 100644 --- a/src/core/render-biblio.js +++ b/src/core/render-biblio.js @@ -2,7 +2,7 @@ // Module core/render-biblio // renders the biblio data pre-processed in core/biblio -import { addId, getIntlData, showError, toId } from "./utils.js"; +import { addId, getIntlData, showError, toId, xmlEscape } from "./utils.js"; import { biblio } from "./biblio.js"; import { html } from "./import-maps.js"; @@ -34,6 +34,12 @@ const localizationStrings = { references: "Referencias", reference_not_found: "Referencia no encontrada.", }, + fr: { + info_references: "Références informatives", + norm_references: "Références normatives", + references: "Références", + reference_not_found: "Référence non trouvée.", + }, ja: { info_references: "参照用参考文献", norm_references: "規範的参考文献", @@ -69,8 +75,6 @@ const REF_STATUSES = new Map([ ["WD", "W3C Working Draft"], ]); -const endWithDot = endNormalizer("."); - /** @param {Conf} conf */ export function run(conf) { const informs = Array.from(conf.informativeReferences); @@ -225,19 +229,6 @@ function showRef(reference) { return result; } -/** - * @param {string} endStr - * @returns {(str: string) => string} - */ -function endNormalizer(endStr) { - return str => { - const trimmed = str.trim(); - const result = - !trimmed || trimmed.endsWith(endStr) ? trimmed : trimmed + endStr; - return result; - }; -} - /** @param {BiblioData|string} ref */ function stringifyReference(ref) { if (typeof ref === "string") return ref; @@ -259,8 +250,15 @@ function stringifyReference(ref) { } } if (ref.publisher) { - output = `${output} ${endWithDot(ref.publisher)} `; + // When pages follow, use a comma after publisher instead of a period. + const publisherEnd = ref.pages ? "," : "."; + const publisherText = ref.publisher.trim(); + const normalizedPublisher = publisherText.endsWith(".") + ? publisherText.slice(0, -1) + : publisherText; + output = `${output} ${normalizedPublisher}${publisherEnd} `; } + if (ref.pages) output += `pp. ${xmlEscape(ref.pages)}. `; if (ref.date) output += `${ref.date}. `; if (ref.status) output += `${REF_STATUSES.get(ref.status) || ref.status}. `; if (ref.href) output += `URL: ${ref.href}`; diff --git a/src/type-helper.d.ts b/src/type-helper.d.ts index d7f3cd1c66..712793bb55 100644 --- a/src/type-helper.d.ts +++ b/src/type-helper.d.ts @@ -78,6 +78,7 @@ interface BiblioData { href?: string; authors?: string[]; publisher?: string; + pages?: string; date?: string; rawDate?: string; isbn?: string; diff --git a/tests/spec/core/biblio-spec.js b/tests/spec/core/biblio-spec.js index be5fa52011..1e24272d88 100644 --- a/tests/spec/core/biblio-spec.js +++ b/tests/spec/core/biblio-spec.js @@ -32,6 +32,12 @@ describe("W3C — Bibliographic References", () => { href: "http://test.com", publisher: "Publisher Here", }, + TestRef4: { + title: "Fourth test", + href: "http://test.com", + publisher: "Publisher Pages", + pages: "369-384", + }, FOOBARGLOP: { aliasOf: "BARBAR", }, @@ -48,7 +54,7 @@ describe("W3C — Bibliographic References", () => { const body = `

[[DOM]] [[dom]] [[fetch]] [[?FeTcH]] [[FETCh]] [[fetCH]] -

foo [[TestRef1]] [[TestRef2]] [[TestRef3]]

+

foo [[TestRef1]] [[TestRef2]] [[TestRef3]] [[TestRef4]]

[[EVERCOOKIE]]

@@ -144,6 +150,13 @@ describe("W3C — Bibliographic References", () => { expect(ref.textContent).toMatch(/Publisher Here\.\s/); }); + it("displays the pages field when present", () => { + const ref = doc.querySelector("#bib-testref4 + dd"); + expect(ref).toBeTruthy(); + // Publisher followed by pages should use comma, not period + expect(ref.textContent).toContain("Publisher Pages, pp. 369-384"); + }); + it("resolves a localy-aliased spec", () => { const ref = doc.querySelector("#bib-foobarglop + dd"); expect(ref).toBeTruthy(); @@ -276,6 +289,16 @@ describe("W3C — Bibliographic References", () => { expect(badRef.textContent.trim()).toBe("Referencia no encontrada."); }); + it("shows localized French references section and error", async () => { + const body = `

[[bad-ref]]

`; + const ops = makeStandardOps({ localBiblio }, body); + ops.htmlAttrs = { lang: "fr" }; + const doc = await makeRSDoc(ops); + const badRef = doc.querySelector("#references-informatives dd"); + expect(badRef).toBeTruthy(); + expect(badRef.textContent.trim()).toBe("Référence non trouvée."); + }); + it("uses cached results from IDB", async () => { const body = `

[[dom]] [[DOM4]] [[DOM]] [[dom4]]

`; const ops = makeStandardOps(null, body);