diff --git a/tools/check-cited.mjs b/tools/check-cited.mjs index 90cd117..8ecf367 100644 --- a/tools/check-cited.mjs +++ b/tools/check-cited.mjs @@ -76,9 +76,23 @@ function resolve(json, dotted) { but markup between"; \s* quietly allowed a marker on the following line, so the code was looser than its own documentation. Making them agree also keeps the offender report honest — see the count check. */ -const CITE = /([\d]+(?:\.[\d]+)?)[ \t]*(?:%|x)?\**[ \t]*(?:—|-|–)?[ \t]*/g; -/* Every marker, however badly placed. The two counts must agree — see below. */ -const ANY_CITE = //g; +const CITE = /([\d]+(?:\.[\d]+)?)[ \t]*(?:%|x)?\**[ \t]*(?:—|-|–)?[ \t]*/gi; + +/* ANY marker a person might have meant as a citation, however spelled or placed. The two + patterns are deliberately ASYMMETRIC: the reader accepts only what the format specifies, + the counter recognises anything citation-shaped, and the difference is reported. + + Both were once the same literal, and that made the count check blind in exactly the way + it existed to prevent — neither carried `i`, so ``, `` + and `` were invisible to the reader AND to the counter watching for + invisible markers. A citation printing 41 against an artifact holding 40 passed under all + three, reporting OK with a count identical to a clean tree. Capitalising the first word of + a comment is not an exotic mistake; it is what a person does without thinking. + + CITE now tolerates case and a space around the colon, so those spellings simply work. + ANY_CITE stays looser still, so a spelling neither of us anticipated is counted and + named rather than skipped. */ +const ANY_CITE = //gi; let checked = 0; const problems = []; @@ -104,10 +118,12 @@ for (const [rel, abs] of scenarioFiles()) { const unread = markers.filter(m => !spans.some(([a, b]) => m.index >= a && m.index < b)); if (unread.length) { const lineOf = i => text.slice(0, i).split("\n").length; - problems.push(` ${rel}: ${unread.length} citation marker(s) not attached to a number, so ` + problems.push(` ${rel}: ${unread.length} citation marker(s) this guard cannot read, so ` + `nothing checks them — a marker that looks like a citation and is never read is the ` - + `defect this guard exists for. The comment must follow its figure immediately ` - + `(\`**40**\`), with nothing but markup between.`); + + `defect this guard exists for. Either it is misplaced (the comment must follow its ` + + `figure immediately, \`**40**\`, on the same line with ` + + `nothing but markup between) or it is misspelled (case and spaces around the colon ` + + `are fine; the shape \`cite: \` is not optional).`); unread.forEach(m => { const n = lineOf(m.index); problems.push(` line ${n}: ${text.split("\n")[n - 1].trim().slice(0, 110)}`);