diff --git a/src/lint/collect-spelling-diagnostics.ts b/src/lint/collect-spelling-diagnostics.ts index d6506948..245265a8 100644 --- a/src/lint/collect-spelling-diagnostics.ts +++ b/src/lint/collect-spelling-diagnostics.ts @@ -51,6 +51,10 @@ let matchers = [ pattern: /\r/gu, message: 'Only Unix-style (LF) linebreaks are allowed', }, + { + pattern: /(?<=\b[Ss]teps? )\d/gu, + message: 'Prefer using labeled steps and tags over hardcoding step numbers', + }, ]; export function collectSpellingDiagnostics(sourceText: string) { diff --git a/src/lint/rules/algorithm-step-numbering.ts b/src/lint/rules/algorithm-step-numbering.ts index 69604252..4edf2faf 100644 --- a/src/lint/rules/algorithm-step-numbering.ts +++ b/src/lint/rules/algorithm-step-numbering.ts @@ -4,7 +4,7 @@ import type { LintingError } from '../algorithm-error-reporter-type'; const ruleId = 'algorithm-step-numbering'; /* -Checks that step numbers are all `1`, with the exception of top-level lists whose first item is not `1`. +Checks that step numbers are all `1`. */ export default function ( report: (e: LintingError) => void, @@ -12,19 +12,9 @@ export default function ( algorithmSource: string ): Observer { const nodeType = node.tagName; - let depth = -1; - let topLevelIsOne = false; return { enter(node: EcmarkdownNode) { - if (node.name === 'ol') { - ++depth; - if (depth === 0) { - topLevelIsOne = node.start === 1; - } - } else if (node.name === 'ordered-list-item') { - if (depth === 0 && !topLevelIsOne) { - return; - } + if (node.name === 'ordered-list-item') { let itemSource = algorithmSource.slice( node.location!.start.offset, node.location!.end.offset @@ -41,10 +31,5 @@ export default function ( } } }, - exit(node: EcmarkdownNode) { - if (node.name === 'ol') { - --depth; - } - }, }; } diff --git a/test/lint-algorithms.js b/test/lint-algorithms.js index 9c7ff2ad..490a6180 100644 --- a/test/lint-algorithms.js +++ b/test/lint-algorithms.js @@ -121,6 +121,17 @@ describe('linting algorithms', function () { const ruleId = 'algorithm-step-numbering'; it('simple', async function () { + await assertLint( + positioned` + ${M}2. Step. + 1. Step. + `, + { + ruleId, + nodeType, + message: 'expected step number to be "1." (found "2.")', + } + ); await assertLint( positioned` 1. Step. @@ -161,7 +172,7 @@ describe('linting algorithms', function () { await assertLint( positioned` - 2. Step: + 1. Step: ${M}2. Substep. `, { @@ -202,9 +213,9 @@ describe('linting algorithms', function () { it('negative', async function () { await assertLintFree(` - 2. Step. - 3. Step. - 40. Step. + 1. Step. + 1. Step. + 1. Step. `); }); diff --git a/test/lint-spelling.js b/test/lint-spelling.js index 1d5e4287..77c5c2e1 100644 --- a/test/lint-spelling.js +++ b/test/lint-spelling.js @@ -171,6 +171,19 @@ windows:${M}\r ); }); + it('step numbers', async function () { + await assertLint( + positioned` + Something about step ${M}1. + `, + { + ruleId: 'spelling', + nodeType: 'text', + message: 'Prefer using labeled steps and tags over hardcoding step numbers', + } + ); + }); + it('negative', async function () { await assertLintFree(`

@@ -188,6 +201,11 @@ windows:${M}\r

Example

+ + + 1. [label="example-label"] Foo. + + Something about step . `); }); });