@nielspeter/eess-md 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -170,6 +170,16 @@ adrEnforcement(c, {
170
170
  })
171
171
  ```
172
172
 
173
+ ## Code blocks that parse: `parseCodeBlocks()` + `codeBlocks()`
174
+
175
+ Check every fenced block of one language with a parser you name. eess-md owns the loop and the
176
+ evidence, and never loads a parser itself. `parseCodeBlocks(corpus, { language, parser })` is the
177
+ one async call; `codeBlocks(parsed).should().parse().check()` is an ordinary synchronous rule over
178
+ what it parsed. A parser names itself and declares canaries it must reject, and every way it can
179
+ fail (a throw, a hang past its budget, a malformed or missing verdict, a canary it accepts) is one
180
+ unsuppressable finding, never a pass. The port and the failure table are in
181
+ [the Markdown dialect's docs](../../docs/markdown.md#code-blocks-that-parse).
182
+
173
183
  ## `@nielspeter/eess-md/internal` is not API
174
184
 
175
185
  | Specifier | What it is |
@@ -0,0 +1,37 @@
1
+ import { RuleBuilder, type CollectResult } from '@nielspeter/eess';
2
+ import { type ParsedCodeBlock, type ParsedCodeBlocks } from '../model/code-block-parse.js';
3
+ /** The instrument's identity: one constant, so several rules over one failed parse dedupe to one. */
4
+ export declare const CODE_BLOCK_PARSER_INSTRUMENT = "eess-md: code-block parser";
5
+ /**
6
+ * Rule builder over the blocks `parseCodeBlocks` parsed. Its elements are the parsed set, so a
7
+ * predicate can only narrow what a parser saw, never select a block no parser saw.
8
+ *
9
+ * No rule surface here is async: the parse happens once in `parseCodeBlocks`, and this builder reads
10
+ * its facts synchronously (plan 0412; an async `check()` would need an ADR).
11
+ */
12
+ export declare class CodeBlockRuleBuilder extends RuleBuilder<ParsedCodeBlock, ParsedCodeBlocks> {
13
+ constructor(parsed: ParsedCodeBlocks);
14
+ protected getElements(): ParsedCodeBlock[];
15
+ /** No Markdown file loaded at all outranks everything, `.expectEmpty()` included (ADR-010). */
16
+ protected sourceEmpty(): boolean;
17
+ /** When near-miss tags are why nothing was examined, send the author to the spelling. */
18
+ protected deadGlobDiagnosis(): string | undefined;
19
+ /** The kernel's verdict, plus the instrument finding once per rule when the parser failed. */
20
+ protected collectViolations(): CollectResult;
21
+ /** Filter to blocks in documents whose repo-relative path matches the file glob. */
22
+ resideInFile(glob: string): this;
23
+ /** Filter to blocks in documents whose repo-relative path matches the folder glob. */
24
+ resideInFolder(glob: string): this;
25
+ /** Assert every selected block parses: an `invalid` or `unrecognised` verdict is a finding. */
26
+ parse(): this;
27
+ }
28
+ /**
29
+ * Entry point: rules over the code blocks one `parseCodeBlocks` call parsed.
30
+ *
31
+ * ```ts
32
+ * const parsed = await parseCodeBlocks(corpus, { language: 'mermaid', parser })
33
+ * codeBlocks(parsed).should().parse().check()
34
+ * ```
35
+ */
36
+ export declare function codeBlocks(parsed: ParsedCodeBlocks): CodeBlockRuleBuilder;
37
+ //# sourceMappingURL=code-blocks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-blocks.d.ts","sourceRoot":"","sources":["../../src/builders/code-blocks.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,WAAW,EAGX,KAAK,aAAa,EAGnB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAGL,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACtB,MAAM,8BAA8B,CAAA;AAIrC,qGAAqG;AACrG,eAAO,MAAM,4BAA4B,+BAA+B,CAAA;AAiExE;;;;;;GAMG;AACH,qBAAa,oBAAqB,SAAQ,WAAW,CAAC,eAAe,EAAE,gBAAgB,CAAC;gBAC1E,MAAM,EAAE,gBAAgB;IAYpC,SAAS,CAAC,WAAW,IAAI,eAAe,EAAE;IAI1C,+FAA+F;cAC5E,WAAW,IAAI,OAAO;IAIzC,yFAAyF;cACtE,iBAAiB,IAAI,MAAM,GAAG,SAAS;IAS1D,8FAA8F;cAC3E,iBAAiB,IAAI,aAAa;IAqBrD,oFAAoF;IACpF,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIhC,sFAAsF;IACtF,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIlC,+FAA+F;IAC/F,KAAK,IAAI,IAAI;CAGd;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,oBAAoB,CAEzE"}
@@ -0,0 +1,143 @@
1
+ import { ArchConfigError, RuleBuilder, collectResult, } from '@nielspeter/eess';
2
+ import { describeNearMisses, isParsedCodeBlocks, } from '../model/code-block-parse.js';
3
+ import { resideInFile, resideInFolder } from '../predicates/document.js';
4
+ import { mdViolation } from '../model/violation.js';
5
+ /** The instrument's identity: one constant, so several rules over one failed parse dedupe to one. */
6
+ export const CODE_BLOCK_PARSER_INSTRUMENT = 'eess-md: code-block parser';
7
+ const onDocument = (p) => ({
8
+ description: p.description,
9
+ test: (b) => p.test(b.doc),
10
+ });
11
+ function bodyLineCount(value) {
12
+ return value === '' ? 0 : value.split('\n').length;
13
+ }
14
+ /** Condition: every selected block's verdict is `valid`. */
15
+ function parse(parsed) {
16
+ const by = `${parsed.parser.name} ${parsed.parser.version}`;
17
+ return {
18
+ description: `parse with ${by}`,
19
+ evaluate: (elements, ctx) => elements.flatMap((e) => {
20
+ const v = e.verdict;
21
+ // No verdict is never a pass: it exists only beside a failure, which the builder reports.
22
+ // `parseCodeBlocks` guarantees that pairing by construction (every path yields one verdict
23
+ // per text or a failure), so no second check here: one that can never fire proves nothing.
24
+ if (v === null || v.outcome === 'valid')
25
+ return [];
26
+ const where = `${e.doc.relPath}:${String(e.block.line)}`;
27
+ if (v.outcome === 'unrecognised') {
28
+ return [
29
+ {
30
+ ...mdViolation({
31
+ element: where,
32
+ file: e.doc.file,
33
+ line: e.block.line,
34
+ message: `${by} does not recognise this \`${parsed.language}\` block: ${v.message}`,
35
+ sourceText: e.doc.text,
36
+ context: ctx,
37
+ }),
38
+ suggestion: v.remedy,
39
+ },
40
+ ];
41
+ }
42
+ const lines = bodyLineCount(e.block.value);
43
+ const inner = v.line;
44
+ const inside = inner !== null && inner >= 1 && inner <= lines;
45
+ const line = inside ? e.block.line + inner : e.block.line;
46
+ const note = inside
47
+ ? ''
48
+ : inner === null
49
+ ? ' (the line inside the block is unknown)'
50
+ : ` (the parser gave line ${String(inner)} for a ${String(lines)}-line block)`;
51
+ return [
52
+ {
53
+ ...mdViolation({
54
+ element: where,
55
+ file: e.doc.file,
56
+ line,
57
+ message: `this \`${parsed.language}\` block does not parse with ${by}: ${v.message}${note}`,
58
+ sourceText: e.doc.text,
59
+ context: ctx,
60
+ }),
61
+ suggestion: v.remedy,
62
+ },
63
+ ];
64
+ }),
65
+ };
66
+ }
67
+ /**
68
+ * Rule builder over the blocks `parseCodeBlocks` parsed. Its elements are the parsed set, so a
69
+ * predicate can only narrow what a parser saw, never select a block no parser saw.
70
+ *
71
+ * No rule surface here is async: the parse happens once in `parseCodeBlocks`, and this builder reads
72
+ * its facts synchronously (plan 0412; an async `check()` would need an ADR).
73
+ */
74
+ export class CodeBlockRuleBuilder extends RuleBuilder {
75
+ constructor(parsed) {
76
+ super(parsed);
77
+ if (!isParsedCodeBlocks(parsed)) {
78
+ throw new ArchConfigError('codeBlocks', "codeBlocks() takes the object this copy of eess-md's parseCodeBlocks() returned. A " +
79
+ 'hand-built object would let any verdict through unchecked. If you built it with ' +
80
+ 'parseCodeBlocks, two copies of @nielspeter/eess-md are installed; dedupe them.');
81
+ }
82
+ }
83
+ getElements() {
84
+ return [...this.project.blocks];
85
+ }
86
+ /** No Markdown file loaded at all outranks everything, `.expectEmpty()` included (ADR-010). */
87
+ sourceEmpty() {
88
+ return this.project.documentsLoaded === 0;
89
+ }
90
+ /** When near-miss tags are why nothing was examined, send the author to the spelling. */
91
+ deadGlobDiagnosis() {
92
+ const { blocks, nearMisses, language } = this.project;
93
+ if (blocks.length > 0 || nearMisses.length === 0)
94
+ return undefined;
95
+ return (`no block is tagged \`${language}\`, and the tag is matched exactly. These are not read: ` +
96
+ `${describeNearMisses(nearMisses)}. Retag them \`${language}\`.`);
97
+ }
98
+ /** The kernel's verdict, plus the instrument finding once per rule when the parser failed. */
99
+ collectViolations() {
100
+ const base = super.collectViolations();
101
+ const failure = this.project.failure;
102
+ if (failure === null)
103
+ return base;
104
+ const { name, version } = this.project.parser;
105
+ const instrument = {
106
+ rule: CODE_BLOCK_PARSER_INSTRUMENT,
107
+ ruleId: CODE_BLOCK_PARSER_INSTRUMENT,
108
+ element: `${name}@${version}`,
109
+ file: '',
110
+ line: 0,
111
+ message: `the ${this.project.language} blocks were not checked: ${failure.cause.replace(/\.$/, '')}. No block of the ` +
112
+ `language has a verdict, so this rule cannot pass.`,
113
+ suggestion: failure.remedy,
114
+ bypassFilters: true,
115
+ };
116
+ // The kernel's evidence, passed through whole, so no field it adds later can be dropped here.
117
+ return collectResult([...base, instrument], base);
118
+ }
119
+ /** Filter to blocks in documents whose repo-relative path matches the file glob. */
120
+ resideInFile(glob) {
121
+ return this.addPredicate(onDocument(resideInFile(glob)));
122
+ }
123
+ /** Filter to blocks in documents whose repo-relative path matches the folder glob. */
124
+ resideInFolder(glob) {
125
+ return this.addPredicate(onDocument(resideInFolder(glob)));
126
+ }
127
+ /** Assert every selected block parses: an `invalid` or `unrecognised` verdict is a finding. */
128
+ parse() {
129
+ return this.addCondition(parse(this.project));
130
+ }
131
+ }
132
+ /**
133
+ * Entry point: rules over the code blocks one `parseCodeBlocks` call parsed.
134
+ *
135
+ * ```ts
136
+ * const parsed = await parseCodeBlocks(corpus, { language: 'mermaid', parser })
137
+ * codeBlocks(parsed).should().parse().check()
138
+ * ```
139
+ */
140
+ export function codeBlocks(parsed) {
141
+ return new CodeBlockRuleBuilder(parsed);
142
+ }
143
+ //# sourceMappingURL=code-blocks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-blocks.js","sourceRoot":"","sources":["../../src/builders/code-blocks.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -27,6 +27,9 @@ export type { MdTaskItem } from './builders/task-items.js';
27
27
  export { collectTaskItems } from './model/task-items.js';
28
28
  export type { MdTaskItemRef } from './model/task-items.js';
29
29
  export { vocabulary, terms, TermRuleBuilder } from './builders/vocabulary.js';
30
+ export { parseCodeBlocks, DEFAULT_CODE_BLOCK_BUDGET } from './model/code-block-parse.js';
31
+ export type { CodeBlockVerdict, CodeBlockCanary, CodeBlockParser, CodeBlockBudget, ParseCodeBlocksOptions, ParsedCodeBlock, ParsedCodeBlocks, CodeBlockInstrumentFailure, NearMissTag, } from './model/code-block-parse.js';
32
+ export { codeBlocks, CodeBlockRuleBuilder, CODE_BLOCK_PARSER_INSTRUMENT, } from './builders/code-blocks.js';
30
33
  export type { Vocabulary, VocabularyOptions, MdTerm, TermsOptions } from './builders/vocabulary.js';
31
34
  export { haveSection, haveTable } from './conditions/structure.js';
32
35
  export type { HaveTableOptions } from './conditions/structure.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,YAAY,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAOxD,YAAY,EACV,SAAS,EACT,SAAS,EACT,gBAAgB,EAChB,OAAO,EACP,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,GAAG,EACH,YAAY,EACZ,iBAAiB,EAMjB,gBAAgB,EAChB,iBAAiB,EAEjB,eAAe,GAChB,MAAM,kBAAkB,CAAA;AASzB,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAA;AAOxE,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAClF,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAMrD,YAAY,EAAE,qBAAqB,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAGlF,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACtF,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACvF,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAChD,YAAY,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAGzD,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAC1D,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAC5D,YAAY,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AACjD,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AACnD,YAAY,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AACrD,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3F,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AACrE,YAAY,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAA;AACtE,YAAY,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAA;AAC5E,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAC1D,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AACzE,YAAY,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,YAAY,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAC1D,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAC7E,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAGnG,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AAClE,YAAY,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAA;AACpE,YAAY,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -42,6 +42,9 @@ export { rows, RowsRuleBuilder } from './builders/rows.js';
42
42
  export { taskItems, TaskItemRuleBuilder } from './builders/task-items.js';
43
43
  export { collectTaskItems } from './model/task-items.js';
44
44
  export { vocabulary, terms, TermRuleBuilder } from './builders/vocabulary.js';
45
+ // Plan 0412: a code block parses with the parser the caller names.
46
+ export { parseCodeBlocks, DEFAULT_CODE_BLOCK_BUDGET } from './model/code-block-parse.js';
47
+ export { codeBlocks, CodeBlockRuleBuilder, CODE_BLOCK_PARSER_INSTRUMENT, } from './builders/code-blocks.js';
45
48
  // Conditions (for composing custom rules / presets)
46
49
  export { haveSection, haveTable } from './conditions/structure.js';
47
50
  export { haveTableRowsSatisfying } from './conditions/table-rows.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,EAAE;AACF,iFAAiF;AACjF,gFAAgF;AAChF,gFAAgF;AAChF,wCAAwC;AAExC,gBAAgB;AAChB,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAgBpC,OAAO,EACL,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,GAAG,EACH,YAAY,EACZ,iBAAiB;AACjB,4EAA4E;AAC5E,yEAAyE;AACzE,iEAAiE;AACjE,8EAA8E;AAC9E,4DAA4D;AAC5D,gBAAgB,EAChB,iBAAiB;AACjB,uEAAuE;AACvE,eAAe,GAChB,MAAM,kBAAkB,CAAA;AACzB,0EAA0E;AAC1E,2EAA2E;AAC3E,4EAA4E;AAC5E,+DAA+D;AAC/D,6EAA6E;AAC7E,qEAAqE;AACrE,2EAA2E;AAC3E,wBAAwB;AACxB,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAA;AACxE,6EAA6E;AAC7E,gFAAgF;AAChF,EAAE;AACF,8EAA8E;AAC9E,iFAAiF;AACjF,oEAAoE;AACpE,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAYlF,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAGhD,eAAe;AACf,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAC1D,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAI5D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAErD,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAErE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAA;AAEtE,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAC1D,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAEzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAExD,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAG7E,oDAAoD;AACpD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AAElE,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,EAAE;AACF,iFAAiF;AACjF,gFAAgF;AAChF,gFAAgF;AAChF,wCAAwC;AAExC,gBAAgB;AAChB,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAgBpC,OAAO,EACL,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,GAAG,EACH,YAAY,EACZ,iBAAiB;AACjB,4EAA4E;AAC5E,yEAAyE;AACzE,iEAAiE;AACjE,8EAA8E;AAC9E,4DAA4D;AAC5D,gBAAgB,EAChB,iBAAiB;AACjB,uEAAuE;AACvE,eAAe,GAChB,MAAM,kBAAkB,CAAA;AACzB,0EAA0E;AAC1E,2EAA2E;AAC3E,4EAA4E;AAC5E,+DAA+D;AAC/D,6EAA6E;AAC7E,qEAAqE;AACrE,2EAA2E;AAC3E,wBAAwB;AACxB,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAA;AACxE,6EAA6E;AAC7E,gFAAgF;AAChF,EAAE;AACF,8EAA8E;AAC9E,iFAAiF;AACjF,oEAAoE;AACpE,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAYlF,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAGhD,eAAe;AACf,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAC1D,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAI5D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAErD,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAErE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAA;AAEtE,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAC1D,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAEzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAExD,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAC7E,mEAAmE;AACnE,OAAO,EAAE,eAAe,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAA;AAYxF,OAAO,EACL,UAAU,EACV,oBAAoB,EACpB,4BAA4B,GAC7B,MAAM,2BAA2B,CAAA;AAGlC,oDAAoD;AACpD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AAElE,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAA"}
@@ -0,0 +1,118 @@
1
+ import type { Corpus } from '../corpus.js';
2
+ import type { MdCodeBlock, MdDocument } from './document.js';
3
+ /**
4
+ * Plan 0412: a code block parses with the parser the caller names.
5
+ *
6
+ * eess-md owns the loop and the evidence; the caller names the parser. eess-md never loads one
7
+ * itself, because the one with a consumer (Mermaid's) needs a DOM and a worker, and owning a grammar
8
+ * per language would put a second authority beside the real one.
9
+ */
10
+ /** What a parser says about one block. Never inferred: a parser that cannot tell says so. */
11
+ export type CodeBlockVerdict = {
12
+ readonly outcome: 'valid';
13
+ } | {
14
+ readonly outcome: 'invalid';
15
+ readonly message: string;
16
+ /** 1-based, counted from the block's first body line; `null` when the parser cannot tell. */
17
+ readonly line: number | null;
18
+ readonly remedy: string;
19
+ } | {
20
+ readonly outcome: 'unrecognised';
21
+ readonly message: string;
22
+ readonly remedy: string;
23
+ };
24
+ /** A block the parser must reject, with the outcome it must give. */
25
+ export interface CodeBlockCanary {
26
+ readonly text: string;
27
+ readonly expect: 'invalid' | 'unrecognised';
28
+ }
29
+ /** A parser, named. eess-md never loads one itself. */
30
+ export interface CodeBlockParser {
31
+ readonly name: string;
32
+ readonly version: string;
33
+ /** At least one. eess-md parses them in the same batch and checks their verdicts. */
34
+ readonly canaries: readonly CodeBlockCanary[];
35
+ /**
36
+ * One `CodeBlockVerdict` per text, in order. May be synchronous. Must stop when `signal` aborts.
37
+ *
38
+ * Typed `unknown` on purpose: a parser is code eess-md does not own (a JavaScript parser, a
39
+ * worker's message), so eess-md checks the shape of every verdict it is handed and reports one
40
+ * that is not a verdict as the instrument. It never reads one as `valid`.
41
+ *
42
+ * `texts` holds the canaries first, in declared order, then the blocks in document order.
43
+ *
44
+ * A parser that knows why it failed rejects with an error carrying `remedy: string` and
45
+ * `blockIndex: number | null` (an index into `texts`). eess-md reads both by shape.
46
+ *
47
+ * `signal` is aborted only when the budget runs out. A parser that holds a resource (a worker,
48
+ * a process) releases it itself once it has answered.
49
+ */
50
+ parse(texts: readonly string[], options: {
51
+ readonly signal: AbortSignal;
52
+ readonly budgetMs: number;
53
+ }): readonly unknown[] | PromiseLike<readonly unknown[]>;
54
+ }
55
+ /** The time a parse may take: a start-up allowance plus an allowance per text. */
56
+ export interface CodeBlockBudget {
57
+ readonly startUpMs?: number;
58
+ readonly perBlockMs?: number;
59
+ }
60
+ /**
61
+ * The defaults, decided when plan 0412 was frozen: about 25× a worker's measured cold start and 16×
62
+ * its measured cost per block. A budget is a hang detector, not a performance gate.
63
+ */
64
+ export declare const DEFAULT_CODE_BLOCK_BUDGET: Readonly<Required<CodeBlockBudget>>;
65
+ export interface ParseCodeBlocksOptions {
66
+ /** The info-string language, matched exactly: `mermaid` does not read a `Mermaid` block. */
67
+ readonly language: string;
68
+ readonly parser: CodeBlockParser;
69
+ readonly budget?: CodeBlockBudget;
70
+ }
71
+ /** One block of the language, with the verdict its parser gave. `null` only beside a `failure`. */
72
+ export interface ParsedCodeBlock {
73
+ readonly doc: MdDocument;
74
+ readonly block: MdCodeBlock;
75
+ readonly verdict: CodeBlockVerdict | null;
76
+ }
77
+ /** Why the parser could not answer for the batch: the instrument, not any block. */
78
+ export interface CodeBlockInstrumentFailure {
79
+ readonly cause: string;
80
+ readonly remedy: string;
81
+ }
82
+ /** A block whose tag equals the language only when case-folded. Disclosed, never read. */
83
+ export interface NearMissTag {
84
+ readonly tag: string;
85
+ readonly file: string;
86
+ readonly line: number;
87
+ }
88
+ /** The facts a rule reads. Built only by `parseCodeBlocks`; `codeBlocks()` refuses any other. */
89
+ export interface ParsedCodeBlocks {
90
+ readonly language: string;
91
+ readonly parser: {
92
+ readonly name: string;
93
+ readonly version: string;
94
+ };
95
+ readonly blocks: readonly ParsedCodeBlock[];
96
+ readonly failure: CodeBlockInstrumentFailure | null;
97
+ readonly nearMisses: readonly NearMissTag[];
98
+ readonly documentsLoaded: number;
99
+ /**
100
+ * "N mermaid blocks parsed with mermaid 11.17.2", plus any near-miss tags left unread. When the
101
+ * parser failed, it says so and gives the cause: no block was checked.
102
+ */
103
+ summary(): string;
104
+ }
105
+ /** Did `parseCodeBlocks` build this object? A hand-built one would skip every guard. */
106
+ export declare function isParsedCodeBlocks(value: object): boolean;
107
+ /**
108
+ * Parse every block of one language in the corpus, in one batch, with the parser the caller names.
109
+ * The only async call: the rule built from what it returns is synchronous.
110
+ *
111
+ * Throws `ArchConfigError` for a parser with no name, no version or no canaries, before anything is
112
+ * selected. Every other failure of the parser is recorded on the result and reported by each rule
113
+ * over it as the instrument.
114
+ */
115
+ export declare function parseCodeBlocks(corpus: Corpus, options: ParseCodeBlocksOptions): Promise<ParsedCodeBlocks>;
116
+ /** `Mermaid` at docs/a.md:3, … */
117
+ export declare function describeNearMisses(nearMisses: readonly NearMissTag[]): string;
118
+ //# sourceMappingURL=code-block-parse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-block-parse.d.ts","sourceRoot":"","sources":["../../src/model/code-block-parse.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAE5D;;;;;;GAMG;AAEH,6FAA6F;AAC7F,MAAM,MAAM,gBAAgB,GACxB;IAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAC7B;IACE,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAA;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,6FAA6F;IAC7F,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB,GACD;IAAE,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAE3F,qEAAqE;AACrE,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,cAAc,CAAA;CAC5C;AAED,uDAAuD;AACvD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,qFAAqF;IACrF,QAAQ,CAAC,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAA;IAC7C;;;;;;;;;;;;;;OAcG;IACH,KAAK,CACH,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,OAAO,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;QAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GACnE,SAAS,OAAO,EAAE,GAAG,WAAW,CAAC,SAAS,OAAO,EAAE,CAAC,CAAA;CACxD;AAED,kFAAkF;AAClF,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAC7B;AAED;;;GAGG;AACH,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,QAAQ,CAAC,eAAe,CAAC,CAGxE,CAAA;AAEF,MAAM,WAAW,sBAAsB;IACrC,4FAA4F;IAC5F,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAA;IAChC,QAAQ,CAAC,MAAM,CAAC,EAAE,eAAe,CAAA;CAClC;AAED,mGAAmG;AACnG,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAA;IACxB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAA;IAC3B,QAAQ,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAA;CAC1C;AAED,oFAAoF;AACpF,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAED,0FAA0F;AAC1F,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED,iGAAiG;AACjG,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;IACpE,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAA;IAC3C,QAAQ,CAAC,OAAO,EAAE,0BAA0B,GAAG,IAAI,CAAA;IACnD,QAAQ,CAAC,UAAU,EAAE,SAAS,WAAW,EAAE,CAAA;IAC3C,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;IAChC;;;OAGG;IACH,OAAO,IAAI,MAAM,CAAA;CAClB;AAID,wFAAwF;AACxF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEzD;AA2ID;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CA0G3B;AAoBD,kCAAkC;AAClC,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,SAAS,WAAW,EAAE,GAAG,MAAM,CAE7E"}
@@ -0,0 +1,368 @@
1
+ import { ArchConfigError } from '@nielspeter/eess';
2
+ /**
3
+ * The defaults, decided when plan 0412 was frozen: about 25× a worker's measured cold start and 16×
4
+ * its measured cost per block. A budget is a hang detector, not a performance gate.
5
+ */
6
+ export const DEFAULT_CODE_BLOCK_BUDGET = Object.freeze({
7
+ startUpMs: 10_000,
8
+ perBlockMs: 250,
9
+ });
10
+ const REGISTERED = new WeakSet();
11
+ /** Did `parseCodeBlocks` build this object? A hand-built one would skip every guard. */
12
+ export function isParsedCodeBlocks(value) {
13
+ return REGISTERED.has(value);
14
+ }
15
+ function nonEmpty(value) {
16
+ return typeof value === 'string' && value.trim() !== '';
17
+ }
18
+ /**
19
+ * Read one value a parser returned, ONCE. Each field is read a single time into a local, so a value
20
+ * whose getters answer differently on a second read cannot pass one check and fail the next.
21
+ */
22
+ function readVerdict(value) {
23
+ if (typeof value !== 'object' || value === null || !('outcome' in value)) {
24
+ return { problem: 'is not a verdict' };
25
+ }
26
+ const outcome = value.outcome;
27
+ if (outcome === 'valid')
28
+ return { verdict: { outcome: 'valid' } };
29
+ if (outcome !== 'invalid' && outcome !== 'unrecognised') {
30
+ return { problem: `is not a verdict (outcome ${JSON.stringify(outcome) ?? 'undefined'})` };
31
+ }
32
+ const message = 'message' in value ? value.message : undefined;
33
+ const remedy = 'remedy' in value ? value.remedy : undefined;
34
+ if (!nonEmpty(message))
35
+ return { problem: 'has an empty message' };
36
+ if (!nonEmpty(remedy))
37
+ return { problem: 'has an empty remedy' };
38
+ if (outcome === 'unrecognised')
39
+ return { verdict: { outcome, message, remedy } };
40
+ const line = 'line' in value ? value.line : undefined;
41
+ if (line === null)
42
+ return { verdict: { outcome, message, line: null, remedy } };
43
+ if (typeof line === 'number' && Number.isInteger(line)) {
44
+ return { verdict: { outcome, message, line, remedy } };
45
+ }
46
+ return { problem: 'has a line that is neither a whole number nor null' };
47
+ }
48
+ /**
49
+ * Copy an array with a plain index loop into a fresh plain array. Not `map`, `slice` or spread: on an
50
+ * `Array` subclass those build the result through its own species constructor, which can hand back
51
+ * an object that reports a length and yields nothing (review of PR #209).
52
+ */
53
+ function plainCopy(value) {
54
+ if (!Array.isArray(value))
55
+ return null;
56
+ const source = value;
57
+ const length = source.length;
58
+ const copy = [];
59
+ for (let i = 0; i < length; i++)
60
+ copy.push(source[i]);
61
+ return copy;
62
+ }
63
+ /** The parser's identity and canaries, read once and checked. Throws before anything is selected. */
64
+ function snapshotParser(parser) {
65
+ const name = parser.name;
66
+ const version = parser.version;
67
+ if (!nonEmpty(name) || !nonEmpty(version)) {
68
+ throw new ArchConfigError('parseCodeBlocks', `parseCodeBlocks: the parser has no ${nonEmpty(name) ? 'version' : 'name'}. ` +
69
+ 'A parser names itself, so a finding can say what judged the block.');
70
+ }
71
+ const declared = parser.canaries;
72
+ let list;
73
+ try {
74
+ list = plainCopy(declared) ?? [];
75
+ }
76
+ catch (error) {
77
+ throw new ArchConfigError('parseCodeBlocks', `parseCodeBlocks: the canaries of ${name}@${version} could not be read: ${messageOf(error)}`);
78
+ }
79
+ if (list.length === 0) {
80
+ throw new ArchConfigError('parseCodeBlocks', `parseCodeBlocks: the parser ${name}@${version} declares no canaries. A parser declares at ` +
81
+ 'least one block it must reject, so a parser that accepts everything is caught.');
82
+ }
83
+ const canaries = [];
84
+ for (const [i, entry] of list.entries()) {
85
+ const text = typeof entry === 'object' && entry !== null && 'text' in entry ? entry.text : undefined;
86
+ const expect = typeof entry === 'object' && entry !== null && 'expect' in entry ? entry.expect : undefined;
87
+ if (!nonEmpty(text) || (expect !== 'invalid' && expect !== 'unrecognised')) {
88
+ throw new ArchConfigError('parseCodeBlocks', `parseCodeBlocks: canary ${String(i + 1)} of ${name}@${version} is not a block the parser ` +
89
+ `must reject: it needs a non-empty \`text\` and \`expect\` of "invalid" or "unrecognised" ` +
90
+ `(got ${JSON.stringify(expect) ?? 'undefined'}). A canary the parser may accept catches nothing.`);
91
+ }
92
+ canaries.push(Object.freeze({ text, expect }));
93
+ }
94
+ return { name, version, canaries: Object.freeze(canaries) };
95
+ }
96
+ /** A whole number of milliseconds a timer can hold, or a configuration error. */
97
+ function budgetPart(value, fallback, field) {
98
+ if (value === undefined)
99
+ return fallback;
100
+ if (!Number.isInteger(value) || value < 0 || value > MAX_TIMER_MS) {
101
+ throw new ArchConfigError('parseCodeBlocks', `parseCodeBlocks: budget.${field} is ${JSON.stringify(value) ?? String(value)}; it must be a whole number of ` +
102
+ `milliseconds from 0 to ${String(MAX_TIMER_MS)}.`);
103
+ }
104
+ return value;
105
+ }
106
+ /** The longest delay `setTimeout` honours; past it Node fires after 1 ms. */
107
+ const MAX_TIMER_MS = 2_147_483_647;
108
+ /** A thrown value's `remedy` and `blockIndex`, read by shape (plan 0413 imports nothing of ours). */
109
+ function structured(error) {
110
+ if (typeof error !== 'object' || error === null)
111
+ return {};
112
+ const remedy = 'remedy' in error && nonEmpty(error.remedy) ? error.remedy : undefined;
113
+ const index = 'blockIndex' in error ? error.blockIndex : undefined;
114
+ const blockIndex = typeof index === 'number' && Number.isInteger(index) ? index : undefined;
115
+ return {
116
+ ...(remedy !== undefined && { remedy }),
117
+ ...(blockIndex !== undefined && { blockIndex }),
118
+ };
119
+ }
120
+ function messageOf(error) {
121
+ if (error instanceof Error)
122
+ return error.message;
123
+ return String(error);
124
+ }
125
+ const ENVIRONMENT_REMEDY = "Fix the parser's environment or the parser itself: this failure is not a verdict about any block, " +
126
+ 'and no block was judged.';
127
+ /**
128
+ * Parse every block of one language in the corpus, in one batch, with the parser the caller names.
129
+ * The only async call: the rule built from what it returns is synchronous.
130
+ *
131
+ * Throws `ArchConfigError` for a parser with no name, no version or no canaries, before anything is
132
+ * selected. Every other failure of the parser is recorded on the result and reported by each rule
133
+ * over it as the instrument.
134
+ */
135
+ export async function parseCodeBlocks(corpus, options) {
136
+ const { language, parser } = options;
137
+ if (!nonEmpty(language)) {
138
+ throw new ArchConfigError('parseCodeBlocks', 'parseCodeBlocks: `language` is empty. Name the info-string tag to check, e.g. "mermaid".');
139
+ }
140
+ const { name, version, canaries } = snapshotParser(parser);
141
+ const startUpMs = budgetPart(options.budget?.startUpMs, DEFAULT_CODE_BLOCK_BUDGET.startUpMs, 'startUpMs');
142
+ const perBlockMs = budgetPart(options.budget?.perBlockMs, DEFAULT_CODE_BLOCK_BUDGET.perBlockMs, 'perBlockMs');
143
+ const documents = corpus.documents();
144
+ const located = [];
145
+ const nearMisses = [];
146
+ const folded = language.toLowerCase();
147
+ for (const doc of documents) {
148
+ for (const block of doc.codeBlocks) {
149
+ if (block.lang === language)
150
+ located.push({ doc, block });
151
+ else if (block.lang?.toLowerCase() === folded) {
152
+ nearMisses.push(Object.freeze({ tag: block.lang, file: doc.relPath, line: block.line }));
153
+ }
154
+ }
155
+ }
156
+ const texts = Object.freeze([
157
+ ...canaries.map((c) => c.text),
158
+ ...located.map((l) => l.block.value),
159
+ ]);
160
+ const wanted = startUpMs + perBlockMs * texts.length;
161
+ const budgetMs = Math.min(wanted, MAX_TIMER_MS);
162
+ const fromCaller = options.budget?.startUpMs !== undefined || options.budget?.perBlockMs !== undefined;
163
+ const budgetSource = fromCaller ? "the caller's budget" : 'the defaults';
164
+ const budgetText = `${String(budgetMs)} ms (${String(startUpMs)} ms start-up + ${String(perBlockMs)} ms × ` +
165
+ `${String(texts.length)} texts, from ${budgetSource}` +
166
+ `${wanted > MAX_TIMER_MS ? `, capped from ${String(wanted)} ms at the longest a timer holds` : ''})`;
167
+ const where = (index) => {
168
+ if (index === undefined)
169
+ return '';
170
+ if (index < canaries.length)
171
+ return ` while parsing canary ${String(index + 1)}`;
172
+ const l = located[index - canaries.length];
173
+ return l === undefined ? '' : ` at the block at ${l.doc.relPath}:${String(l.block.line)}`;
174
+ };
175
+ let failure = null;
176
+ let verdicts = null;
177
+ // An instrument failure needs a parse; a corpus with no block of the language parses nothing.
178
+ if (located.length > 0) {
179
+ const outcome = await runParser(parser, texts, budgetMs);
180
+ if (outcome.kind === 'threw') {
181
+ const s = structured(outcome.error);
182
+ failure = {
183
+ cause: `the parser threw${where(s.blockIndex)}: ${messageOf(outcome.error)}`,
184
+ remedy: s.remedy ?? ENVIRONMENT_REMEDY,
185
+ };
186
+ }
187
+ else if (outcome.kind === 'timeout') {
188
+ const s = structured(outcome.error);
189
+ failure = {
190
+ cause: `the parse ran past its budget of ${budgetText}${where(s.blockIndex)}`,
191
+ remedy: s.remedy ??
192
+ 'Find the block that hangs the parser, or raise the budget with ' +
193
+ '`budget: { startUpMs, perBlockMs }` if the parser is merely slow.',
194
+ };
195
+ }
196
+ else {
197
+ const read = readAll(outcome.values, {
198
+ textCount: texts.length,
199
+ canaries,
200
+ budgetMs,
201
+ budgetText,
202
+ elapsedMs: outcome.elapsedMs,
203
+ });
204
+ if ('failure' in read)
205
+ failure = read.failure;
206
+ else
207
+ verdicts = read.verdicts.slice(canaries.length);
208
+ }
209
+ }
210
+ const blocks = located.map((l, i) => Object.freeze({ doc: l.doc, block: l.block, verdict: verdicts?.[i] ?? null }));
211
+ // Every block has a verdict or there is a failure: `readAll` returns one verdict per text or a
212
+ // failure, and the other two outcomes are failures. No block is left without either.
213
+ const finalFailure = failure === null ? null : Object.freeze({ ...failure });
214
+ const identity = Object.freeze({ name, version });
215
+ const frozenNearMisses = Object.freeze(nearMisses);
216
+ const parsed = Object.freeze({
217
+ language,
218
+ parser: identity,
219
+ blocks: Object.freeze(blocks),
220
+ failure: finalFailure,
221
+ nearMisses: frozenNearMisses,
222
+ documentsLoaded: documents.length,
223
+ summary: () => summarise(language, identity, blocks, finalFailure, frozenNearMisses),
224
+ });
225
+ REGISTERED.add(parsed);
226
+ return parsed;
227
+ }
228
+ function summarise(language, identity, blocks, failure, nearMisses) {
229
+ const n = blocks.length;
230
+ const noun = `${language} block${n === 1 ? '' : 's'}`;
231
+ const by = `${identity.name} ${identity.version}`;
232
+ const head = failure === null
233
+ ? `${String(n)} ${noun} parsed with ${by}`
234
+ : `0 of ${String(n)} ${noun} checked: ${by} failed — ${failure.cause}`;
235
+ if (nearMisses.length === 0)
236
+ return head;
237
+ return `${head}; not read, tagged ${describeNearMisses(nearMisses)}`;
238
+ }
239
+ /** `Mermaid` at docs/a.md:3, … */
240
+ export function describeNearMisses(nearMisses) {
241
+ return nearMisses.map((n) => `\`${n.tag}\` at ${n.file}:${String(n.line)}`).join(', ');
242
+ }
243
+ function readAll(returned, run) {
244
+ const { textCount, canaries, budgetMs, budgetText, elapsedMs } = run;
245
+ if (elapsedMs > budgetMs) {
246
+ // A synchronous parser cannot be interrupted, so its overrun is found after it returns.
247
+ return {
248
+ failure: {
249
+ cause: `the parse took ${String(Math.round(elapsedMs))} ms, past its budget of ${budgetText}`,
250
+ remedy: 'Find the block that slows the parser, or raise the budget with ' +
251
+ '`budget: { startUpMs, perBlockMs }` if the parser is merely slow.',
252
+ },
253
+ };
254
+ }
255
+ // Copied once: a value that changes between two reads is read as it was the first time.
256
+ let values;
257
+ try {
258
+ values = plainCopy(returned);
259
+ }
260
+ catch (error) {
261
+ return {
262
+ failure: {
263
+ cause: `reading the parser's answer threw: ${messageOf(error)}`,
264
+ remedy: 'A parser returns a plain array of plain verdict objects.',
265
+ },
266
+ };
267
+ }
268
+ if (values?.length !== textCount) {
269
+ const got = values === null ? 'no array of' : String(values.length);
270
+ return {
271
+ failure: {
272
+ cause: `the parser returned the wrong number of verdicts: ${String(textCount)} texts, ${got} verdicts`,
273
+ remedy: 'A parser returns exactly one verdict per text, in order.',
274
+ },
275
+ };
276
+ }
277
+ const verdicts = [];
278
+ for (const [i, value] of values.entries()) {
279
+ let read;
280
+ try {
281
+ read = readVerdict(value);
282
+ }
283
+ catch (error) {
284
+ read = { problem: `could not be read (${messageOf(error)})` };
285
+ }
286
+ if ('problem' in read) {
287
+ return {
288
+ failure: {
289
+ cause: `the parser's answer for text ${String(i + 1)} ${read.problem}`,
290
+ remedy: "Return { outcome: 'valid' }, { outcome: 'invalid', message, line, remedy } or " +
291
+ "{ outcome: 'unrecognised', message, remedy } for every text, with a non-empty message " +
292
+ 'and remedy.',
293
+ },
294
+ };
295
+ }
296
+ verdicts.push(Object.freeze(read.verdict));
297
+ }
298
+ for (const [i, canary] of canaries.entries()) {
299
+ const got = verdicts[i];
300
+ if (got?.outcome !== canary.expect) {
301
+ return {
302
+ failure: {
303
+ cause: `canary ${String(i + 1)} was answered wrongly: expected "${canary.expect}", got ` +
304
+ `"${got?.outcome ?? 'nothing'}"; a parser that accepts a block it must reject cannot be ` +
305
+ 'trusted to reject a broken one',
306
+ remedy: 'Check that the parser is the real one, at a version whose errors its canaries were ' +
307
+ 'written for, and that it is not catching its own errors.',
308
+ },
309
+ };
310
+ }
311
+ }
312
+ return { verdicts };
313
+ }
314
+ /**
315
+ * Run the parser under its budget. On overrun the signal is aborted and the parser is given a short
316
+ * grace to reject with a structured failure naming its block; after that it is no longer awaited.
317
+ */
318
+ async function runParser(parser, texts, budgetMs) {
319
+ const controller = new AbortController();
320
+ const started = performance.now();
321
+ let result;
322
+ try {
323
+ result = parser.parse(texts, { signal: controller.signal, budgetMs });
324
+ }
325
+ catch (error) {
326
+ return { kind: 'threw', error };
327
+ }
328
+ if (Array.isArray(result)) {
329
+ return { kind: 'returned', values: result, elapsedMs: performance.now() - started };
330
+ }
331
+ // Anything else is awaited, so a thenable that is not a native Promise is still a promise here. A
332
+ // value that is neither resolves to itself and is reported as "no array of verdicts". The parser's
333
+ // promise is settled into a value, so a rejection after we stop waiting is never unhandled.
334
+ const settled = Promise.resolve(result).then((values) => ({
335
+ kind: 'returned',
336
+ values,
337
+ elapsedMs: performance.now() - started,
338
+ }), (error) => ({ kind: 'threw', error }));
339
+ let timer;
340
+ const expired = new Promise((resolve) => {
341
+ timer = setTimeout(() => resolve('expired'), budgetMs);
342
+ });
343
+ try {
344
+ const first = await Promise.race([settled, expired]);
345
+ if (first !== 'expired')
346
+ return first;
347
+ }
348
+ finally {
349
+ clearTimeout(timer);
350
+ }
351
+ controller.abort();
352
+ const graceMs = Math.min(1000, budgetMs);
353
+ let graceTimer;
354
+ const graceOver = new Promise((resolve) => {
355
+ graceTimer = setTimeout(() => resolve('over'), graceMs);
356
+ });
357
+ try {
358
+ const late = await Promise.race([settled, graceOver]);
359
+ return {
360
+ kind: 'timeout',
361
+ error: late === 'over' || late.kind !== 'threw' ? undefined : late.error,
362
+ };
363
+ }
364
+ finally {
365
+ clearTimeout(graceTimer);
366
+ }
367
+ }
368
+ //# sourceMappingURL=code-block-parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-block-parse.js","sourceRoot":"","sources":["../../src/model/code-block-parse.ts"],"names":[],"mappings":"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"}
@@ -56,7 +56,10 @@ export interface MdDocument {
56
56
  readonly text: string;
57
57
  readonly sections: readonly MdSection[];
58
58
  readonly tables: readonly MdTable[];
59
- /** Fenced code blocks (e.g. embedded `mermaid` diagrams). */
59
+ /**
60
+ * Code blocks (e.g. embedded `mermaid` diagrams) at any depth, in document order — including one
61
+ * in a list item or a blockquote, whose `value` has the container's markers removed.
62
+ */
60
63
  readonly codeBlocks: readonly MdCodeBlock[];
61
64
  /** mdast root (internal / advanced) */
62
65
  readonly root: Root;
@@ -71,7 +74,8 @@ export declare function enterHeading(stack: string[], depth: number, name: strin
71
74
  /**
72
75
  * Build an `MdDocument` from a parsed mdast `Root`.
73
76
  *
74
- * Walks top-level nodes once, collecting headings (as sections) and GFM tables.
77
+ * Walks top-level nodes once, collecting headings (as sections) and GFM tables; code blocks are
78
+ * collected at every depth by `collectCode`.
75
79
  * Tables record the heading path they sit under so a rule can scope to
76
80
  * "the table in the `## Enforcement` section".
77
81
  */
@@ -1 +1 @@
1
- {"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../../src/model/document.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAE9C;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,uCAAuC;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,2CAA2C;IAC3C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,4CAA4C;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,iCAAiC;IACjC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;IAClC,qDAAqD;IACrD,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,CAAA;IAC7C;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;IACpC,0CAA0C;IAC1C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,iFAAiF;IACjF,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAA;CACxC;AAED,kDAAkD;AAClD,MAAM,WAAW,WAAW;IAC1B,yEAAyE;IACzE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,4BAA4B;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,2CAA2C;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,yBAAyB;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,oGAAoG;IACpG,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,sBAAsB;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,SAAS,SAAS,EAAE,CAAA;IACvC,QAAQ,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,CAAA;IACnC,6DAA6D;IAC7D,QAAQ,CAAC,UAAU,EAAE,SAAS,WAAW,EAAE,CAAA;IAC3C,uCAAuC;IACvC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;CACpB;AAkBD,qGAAqG;AACrG,wBAAgB,WAAW,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAErD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAG/E;AAMD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAClC,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,OAAO,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,IAAI,CAAA;CACX,GAAG,UAAU,CAuCb"}
1
+ {"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../../src/model/document.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAE9C;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,uCAAuC;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,2CAA2C;IAC3C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,4CAA4C;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,iCAAiC;IACjC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;IAClC,qDAAqD;IACrD,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,CAAA;IAC7C;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;IACpC,0CAA0C;IAC1C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,iFAAiF;IACjF,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAA;CACxC;AAED,kDAAkD;AAClD,MAAM,WAAW,WAAW;IAC1B,yEAAyE;IACzE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,4BAA4B;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,2CAA2C;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,yBAAyB;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,oGAAoG;IACpG,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,sBAAsB;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,SAAS,SAAS,EAAE,CAAA;IACvC,QAAQ,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,CAAA;IACnC;;;OAGG;IACH,QAAQ,CAAC,UAAU,EAAE,SAAS,WAAW,EAAE,CAAA;IAC3C,uCAAuC;IACvC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;CACpB;AAkBD,qGAAqG;AACrG,wBAAgB,WAAW,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAErD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAG/E;AAkBD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAClC,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,OAAO,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,IAAI,CAAA;CACX,GAAG,UAAU,CAsCb"}
@@ -29,10 +29,24 @@ export function enterHeading(stack, depth, name) {
29
29
  function lineOf(node) {
30
30
  return node.position?.start.line ?? 0;
31
31
  }
32
+ /**
33
+ * Every code block at any depth, in document order — one in a list item or a blockquote included.
34
+ * Bug 0290: only the root's direct children were read, so a nested diagram was never checked.
35
+ */
36
+ function collectCode(node, into) {
37
+ if (node.type === 'code') {
38
+ into.push({ lang: node.lang ?? null, value: node.value, line: lineOf(node) });
39
+ return;
40
+ }
41
+ if ('children' in node)
42
+ for (const child of node.children)
43
+ collectCode(child, into);
44
+ }
32
45
  /**
33
46
  * Build an `MdDocument` from a parsed mdast `Root`.
34
47
  *
35
- * Walks top-level nodes once, collecting headings (as sections) and GFM tables.
48
+ * Walks top-level nodes once, collecting headings (as sections) and GFM tables; code blocks are
49
+ * collected at every depth by `collectCode`.
36
50
  * Tables record the heading path they sit under so a rule can scope to
37
51
  * "the table in the `## Enforcement` section".
38
52
  */
@@ -61,10 +75,8 @@ export function buildDocument(args) {
61
75
  sectionPath: headingStack.filter((h) => h !== undefined),
62
76
  });
63
77
  }
64
- else if (node.type === 'code') {
65
- codeBlocks.push({ lang: node.lang ?? null, value: node.value, line: lineOf(node) });
66
- }
67
78
  }
79
+ collectCode(args.root, codeBlocks);
68
80
  return {
69
81
  file: args.file,
70
82
  relPath: args.relPath,
@@ -1 +1 @@
1
- {"version":3,"file":"document.js","sourceRoot":"","sources":["../../src/model/document.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"document.js","sourceRoot":"","sources":["../../src/model/document.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nielspeter/eess-md",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "Architecture testing for a Markdown corpus — the Markdown dialect of the eess family. Links resolve, code pointers ground, ADRs declare enforcement.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -53,7 +53,7 @@
53
53
  "eess"
54
54
  ],
55
55
  "dependencies": {
56
- "@nielspeter/eess": "^0.6.1",
56
+ "@nielspeter/eess": "^0.7.0",
57
57
  "mdast-util-from-markdown": "^2.0.3",
58
58
  "mdast-util-frontmatter": "^2.0.1",
59
59
  "mdast-util-gfm": "^3.1.0",