Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .eleventyignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ understanding/*/identify-changes.html
understanding/*/interruptions-minimum.html
understanding/*/seizures.html

# Ignore typings
**/*.d.ts

# Ignore templates used for creating new documents
**/*-template.html

Expand Down
30 changes: 2 additions & 28 deletions 11ty/CustomLiquid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,22 +254,10 @@ export class CustomLiquid extends Liquid {
throw new Error("Incorrectly-nested Benefits section found: please resolve.");
}

// XSLT orders resources then techniques last, opposite of source files
$("body")
.append("\n", $(`body > section#resources`))
.append("\n", $(`body > section#techniques`));

// Expand top-level heading and add box for guideline/SC pages
if ($("section#intent").length) $("h1").replaceWith(generateIncludes("understanding/h1"));
$("section#intent").before(generateIncludes("understanding/about"));

$("section#techniques h2").after(generateIncludes("understanding/intro/techniques"));
if ($("section#sufficient .situation").length) {
$("section#sufficient h3").after(
generateIncludes("understanding/intro/sufficient-situation")
);
}

// Disallow handwritten success-criteria section (should be auto-generated)
if ($("section#success-criteria").length) {
console.error(
Expand All @@ -281,21 +269,7 @@ export class CustomLiquid extends Liquid {
// success-criteria template only renders content for guideline (not SC) pages
$("body").append(generateIncludes("understanding/success-criteria"));

// Remove unpopulated techniques subsections
for (const id of ["sufficient", "advisory", "failure"]) {
$(`section#${id}:not(:has(:not(h3)))`).remove();
}

// Normalize subsection names for Guidelines (h2) and/or SC (h3)
$("section#sufficient h3").text("Sufficient Techniques");
$("section#advisory").find("h2, h3").text("Advisory Techniques");
$("section#failure h3").text("Failures");

// Add intro prose to populated sections
$("section#advisory")
.find("h2, h3")
.after(generateIncludes("understanding/intro/advisory"));
$("section#failure h3").after(generateIncludes("understanding/intro/failure"));
$("section#resources h2").after(generateIncludes("understanding/intro/resources"));

// Expand techniques links to always include title
Expand Down Expand Up @@ -438,8 +412,8 @@ export class CustomLiquid extends Liquid {
if (scope.guideline?.level === "") $("section#techniques").remove();
}

// Process defined terms within #render,
// where we have access to global data and the about box's HTML
// Process defined terms within #render, where we have access to
// global data and the rendered HTML for the About box and related Techniques
const $termLinks = $(termLinkSelector);
const extractTermName = ($el: CheerioAnyNode) => {
const name = $el
Expand Down
71 changes: 71 additions & 0 deletions 11ty/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,77 @@ Maintenance tasks (for working with Eleventy config and supporting files under t
- `npm run check` checks for TypeScript errors
- `npm run fmt` formats all TypeScript files

## Associated Techniques Data

Each success criterion's page contains a Techniques section which links to associated techniques.
These used to be defined directly in HTML in each respective page, but have since been relocated to
a single data file, `understanding/understanding.11tydata.js`, under the key `associatedTechniques`.

This field is typed, in order to provide some degree of autocomplete in IDEs that support TypeScript
(e.g. Visual Studio Code), as well as some amount of immediate feedback while editing.
Further validation is performed when running the build or dev server, to provide more focused error messages for common mistakes.

### Listing Techniques

Techniques may be indicated via an object as outlined below, or using a shorthand string.
Shorthand strings may function as either `id` or `title` seen below, and are
recommended for brevity when no `using` or `and` relationship is present.

The following list outlines properties available on each technique object:

- `id` - Technique ID
- `title` - Technique description (HTML flow content allowed), to define free-form entries that don't reference a specific technique
- `using` - Optional array of further techniques to be populated into a child list
- Child techniques may also include `using`
- `usingConjunction` - When `using` is specified, this overrides the word that appears before `usingQuantity`
- Default: `"using"`; HTML flow content allowed
- `usingQuantity` - When `using` is specified, this overrides the word that appears after `usingConjunction` and before "of the following techniques"
- Default: `"one"`
- May be empty string (`""`), in which case the subsequent "of" is dropped
- `usingPrefix` - Adds text to appear before `usingConjunction`
- `skipUsingPhrase` - Omits the entire "... using ... of the following techniques" phrase
- This is mainly an escape hatch for rare instances where a child list is used but no "using" phrase appears at all (e.g. in 1.4.4: Resize Text)

Typically, either `id` or `title` is required.
If `id` is specified, then `prefix` and/or `suffix` may also be specified (with HTML flow content allowed in each),
resulting in "{prefix} {linked technique title} {suffix}".

In extremely rare cases, `using` may be specified alone without either `id` or `title`,
e.g. for top-level "Using two or more of the following" in 2.4.5: Multiple Ways.

#### Conjunctions

To represent multiple parallel techniques, an `and` key may be specified instead of `id` or `title`. In this case, the following properties are supported:

- `and` - an array of technique objects or shorthand strings (as described above)
- `using` and its related fields (seen above) may optionally be specified alongside `and`
- `andConjunction` may optionally be specified alongside `and`,
to override the default `"<strong>AND</strong>"` phrasing (e.g. in 4.1.3: Status Messages)
- Techniques listed _within_ `and` should be flat, never containing `and` or `using`

### Situations or Other Subsections (Sufficient only)

The top level of the `sufficient` array may consist entirely of either technique entries (see above)
or subsection entries. It should not contain a mix of both.

Subsections are typically used to define multiple "situations", where each title begins with "Situation A:", "Situation B:", etc.;
in rare cases it is used for other purposes, e.g. in 1.4.8: Visual Presentation.

Subsection entries contain the following:

- `title` (required, HTML allowed)
- `techniques` (required) - array of technique entries (see above)
- `note` (optional, HTML allowed) - content to appear in a Note at the end of the subsection (e.g. in 4.1.3: Status Messages)
- `groups` (optional) - array of objects with `id`, `title`, `techniques`; see more below
- `techniques` within `groups` are not expected to involve `and` or `using`

#### Groups within Situations

Most of the situations in 1.1.1: Non-text Content include groupings which start with a boldface paragraph (not a heading),
and are referenced one or more times within preceding "using" clauses.
Groups can be defined at the top level of each situation/section entry as mentioned above.
Defining `groups` automatically implies a "using" relationship, without explicitly defining `using` for each technique.

## Environment Variables

### `WCAG_CVSDIR`
Expand Down
13 changes: 8 additions & 5 deletions 11ty/guidelines.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,24 +35,27 @@ export const actRules = (
JSON.parse(await readFile("guidelines/act-mapping.json", "utf8")) as ActMapping
)["act-rules"];

/** Version-dependent overrides of SC shortcodes for older versions */
export const scSlugOverrides: Record<string, (version: WcagVersion) => string> = {
"target-size-enhanced": (version) => (version < "22" ? "target-size" : "target-size-enhanced"),
};
/** Generates version-dependent overrides of SC shortcodes for older versions */
export const generateScSlugOverrides = (version: WcagVersion): Record<string, string> => ({
...(version < "22" && {
"target-size-enhanced": "target-size",
}),
});

/**
* Flattened object hash, mapping each WCAG 2 SC slug to the earliest WCAG version it applies to.
* (Functionally equivalent to "guidelines-versions" target in build.xml; structurally inverted)
*/
async function resolveScVersions(version: WcagVersion) {
const paths = await glob("*/*.html", { cwd: "understanding" });
const scSlugOverrides = generateScSlugOverrides(version);
const map: Record<string, WcagVersion> = {};

for (const path of paths) {
const [fileVersion, filename] = path.split("/");
assertIsWcagVersion(fileVersion);
const slug = basename(filename, ".html");
map[slug in scSlugOverrides ? scSlugOverrides[slug](version) : slug] = fileVersion;
map[slug in scSlugOverrides ? scSlugOverrides[slug] : slug] = fileVersion;
}

return map;
Expand Down
Loading