diff --git a/11ty/CustomLiquid.ts b/11ty/CustomLiquid.ts index f6a454b7e1..26a118eec0 100644 --- a/11ty/CustomLiquid.ts +++ b/11ty/CustomLiquid.ts @@ -1,3 +1,4 @@ +import { type Options as SlugifyOptions, slugifyWithCounter } from "@sindresorhus/slugify"; import { Liquid, type Template } from "liquidjs"; import type { LiquidOptions, RenderOptions } from "liquidjs/dist/liquid-options"; import compact from "lodash-es/compact"; @@ -9,7 +10,6 @@ import type { GlobalData } from "eleventy.config"; import { biblioPattern, getBiblio, getXmlBiblio } from "./biblio"; import { flattenDom, load, type CheerioAnyNode } from "./cheerio"; -import { generateId } from "./common"; import { getAcknowledgementsForVersion, type TermsMap } from "./guidelines"; import { resolveTechniqueIdFromHref, understandingToTechniqueLinkSelector } from "./techniques"; import { techniqueToUnderstandingLinkSelector } from "./understanding"; @@ -638,6 +638,9 @@ export class CustomLiquid extends Liquid { } else $("section#references").remove(); } + const slugify = slugifyWithCounter(); + const slugifyOptions: SlugifyOptions = { decamelize: false }; + // 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)"; @@ -648,7 +651,8 @@ export class CustomLiquid extends Liquid { // when we have sections and sidebar skeleton already reordered const $tocList = $(".sidebar nav ul"); $h2Sections.each((_, el) => { - if (!el.attribs.id) el.attribs.id = generateId($(el).find(sectionH2Selector).text()); + if (!el.attribs.id) + el.attribs.id = slugify($(el).find(sectionH2Selector).text(), slugifyOptions); $("") .attr("href", `#${el.attribs.id}`) .text(normalizeTocLabel($(el).find(sectionH2Selector).text())) @@ -672,9 +676,14 @@ export class CustomLiquid extends Liquid { $(autoIdSectionSelectors.join(", ")) .filter(`:has(${sectionHeadingSelector})`) .each((_, el) => { - el.attribs.id = generateId($(el).find(sectionHeadingSelector).text()); + el.attribs.id = slugify($(el).find(sectionHeadingSelector).text(), slugifyOptions); }); + // Also autogenerate IDs for any headings with no dedicated section nor explicit ID + $(":is(h3, h4, h5):not(:first-child):not([id])").each((_, el) => { + el.attribs.id = slugify($(el).text(), slugifyOptions); + }); + return stripHtmlComments($.html()); } } diff --git a/package-lock.json b/package-lock.json index a0d864a2cf..088a878aae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "license": "W3C", "dependencies": { "@11ty/eleventy": "^3.1.2", + "@sindresorhus/slugify": "^2.2.1", "axios": "^1.11.0", "cheerio": "^1.0.0", "glob": "^10.3.16", diff --git a/package.json b/package.json index a2f3b44ec6..c67bf86122 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "license": "W3C", "dependencies": { "@11ty/eleventy": "^3.1.2", + "@sindresorhus/slugify": "^2.2.1", "axios": "^1.11.0", "cheerio": "^1.0.0", "glob": "^10.3.16", diff --git a/understanding/understanding-techniques.html b/understanding/understanding-techniques.html index 850e0cbc0f..79e27516a8 100644 --- a/understanding/understanding-techniques.html +++ b/understanding/understanding-techniques.html @@ -44,7 +44,7 @@
From an evaluator's perspective: If web content implements the sufficient techniques for a given criterion correctly and it is accessibility-supported for the content's users, it conforms to that success criterion. (The converse is not true; if content does not implement these sufficient techniques, it does not necessarily fail the success criteria, as explained in Testing Techniques below.)
-There may be other ways to meet success criteria besides the sufficient techniques in W3C's Techniques for WCAG {{ versionDecimal }} document, as explained in Other Techniques below. (See also Techniques are Informative above.)
+There may be other ways to meet success criteria besides the sufficient techniques in W3C's Techniques for WCAG {{ versionDecimal }} document, as explained in Other Techniques below. (See also Techniques are Informative above.)
The W3C-documented sufficient techniques are provided in a numbered list where each list item provides a technique or combination of techniques that can be used to meet the success criterion. Where there are multiple techniques on a numbered list item connected by "AND" then all of the techniques must be used to be sufficient. For example, Sufficient Techniques for 1.3.1 has: "G115: Using semantic elements to mark up structure AND H49: Using semantic markup to mark emphasized or special text (HTML)".
@@ -87,7 +87,7 @@In addition to the techniques in W3C's Techniques for WCAG {{ versionDecimal }} document, there are other ways to meet WCAG {{ versionDecimal }} success criteria. W3C's techniques are not comprehensive and may not cover newer technologies and situations.
-web content does not have to use W3C's published techniques in order to conform to WCAG {{ versionDecimal }}. (See also Techniques are Informative above.)
+web content does not have to use W3C's published techniques in order to conform to WCAG {{ versionDecimal }}. (See also Techniques are Informative above.)
Content authors can develop different techniques. For example, an author could develop a technique for HTML5, WAI-ARIA, or other new technology. Other organizations may develop sets of techniques to meet WCAG {{ versionDecimal }} success criteria.
Any techniques can be sufficient if: