@refrakt-md/runes 0.35.0 → 0.37.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/dist/file-ref-resolve.d.ts.map +1 -1
- package/dist/file-ref-resolve.js +36 -1
- package/dist/file-ref-resolve.js.map +1 -1
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -1
- package/dist/lang-map.d.ts.map +1 -1
- package/dist/lang-map.js +8 -0
- package/dist/lang-map.js.map +1 -1
- package/dist/lib/anchor.d.ts +73 -0
- package/dist/lib/anchor.d.ts.map +1 -0
- package/dist/lib/anchor.js +521 -0
- package/dist/lib/anchor.js.map +1 -0
- package/dist/lib/component.d.ts +1 -1
- package/dist/lib/component.d.ts.map +1 -1
- package/dist/lib/invocation.d.ts +22 -0
- package/dist/lib/invocation.d.ts.map +1 -0
- package/dist/lib/invocation.js +67 -0
- package/dist/lib/invocation.js.map +1 -0
- package/dist/lib/languages.d.ts +163 -0
- package/dist/lib/languages.d.ts.map +1 -0
- package/dist/lib/languages.js +383 -0
- package/dist/lib/languages.js.map +1 -0
- package/dist/lib/line-diff.d.ts +35 -0
- package/dist/lib/line-diff.d.ts.map +1 -0
- package/dist/lib/line-diff.js +77 -0
- package/dist/lib/line-diff.js.map +1 -0
- package/dist/lib/mask.d.ts +116 -0
- package/dist/lib/mask.d.ts.map +1 -0
- package/dist/lib/mask.js +378 -0
- package/dist/lib/mask.js.map +1 -0
- package/dist/lib/node.d.ts +1 -1
- package/dist/lib/node.d.ts.map +1 -1
- package/dist/lib/present.d.ts +73 -0
- package/dist/lib/present.d.ts.map +1 -0
- package/dist/lib/present.js +127 -0
- package/dist/lib/present.js.map +1 -0
- package/dist/lib/read-file.d.ts +21 -1
- package/dist/lib/read-file.d.ts.map +1 -1
- package/dist/lib/read-file.js +46 -0
- package/dist/lib/read-file.js.map +1 -1
- package/dist/lib/renderable.d.ts +7 -3
- package/dist/lib/renderable.d.ts.map +1 -1
- package/dist/lib/renderable.js +2 -2
- package/dist/lib/renderable.js.map +1 -1
- package/dist/lib/review-marker.d.ts +113 -0
- package/dist/lib/review-marker.d.ts.map +1 -0
- package/dist/lib/review-marker.js +173 -0
- package/dist/lib/review-marker.js.map +1 -0
- package/dist/snippet-pipeline.d.ts.map +1 -1
- package/dist/snippet-pipeline.js +70 -2
- package/dist/snippet-pipeline.js.map +1 -1
- package/dist/tags/diff.d.ts.map +1 -1
- package/dist/tags/diff.js +1 -38
- package/dist/tags/diff.js.map +1 -1
- package/dist/tags/file-ref.d.ts.map +1 -1
- package/dist/tags/file-ref.js +59 -1
- package/dist/tags/file-ref.js.map +1 -1
- package/dist/tags/snippet.d.ts.map +1 -1
- package/dist/tags/snippet.js +53 -2
- package/dist/tags/snippet.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anchor-native presentation (SPEC-131 D13 + D16; WORK-589).
|
|
3
|
+
*
|
|
4
|
+
* Anchoring makes nested targets easy for the first time — a class method, a
|
|
5
|
+
* key inside `"scripts"`, a rule inside `@media`, a step under `jobs:`. Two
|
|
6
|
+
* existing attributes were defined in terms of `lines=` and stop making sense
|
|
7
|
+
* under an anchor, and one new attribute is needed because the old form
|
|
8
|
+
* re-couples the invocation to the coordinates anchoring exists to decouple it
|
|
9
|
+
* from.
|
|
10
|
+
*
|
|
11
|
+
* **These are deliberately separate entry points, not folded into extraction.**
|
|
12
|
+
* Two later items need to call the pipeline at a chosen point and an inlined
|
|
13
|
+
* transform does not allow it:
|
|
14
|
+
*
|
|
15
|
+
* - WORK-590's codemod verifies a rewritten invocation produces a
|
|
16
|
+
* **byte-identical** slice, and that comparison runs **before** `reindent` —
|
|
17
|
+
* otherwise every nested target fails verification for a difference the
|
|
18
|
+
* codemod itself introduced.
|
|
19
|
+
* - WORK-591's review-marker hash applies `reindent` **first**, so that moving
|
|
20
|
+
* a function into a class — which shifts every line two columns without
|
|
21
|
+
* changing a character of content — does not fire the marker.
|
|
22
|
+
*
|
|
23
|
+
* The ordering is easy to get backwards and produces a confusing failure in
|
|
24
|
+
* each direction, which is why it is stated on both sides.
|
|
25
|
+
*/
|
|
26
|
+
/**
|
|
27
|
+
* Strip the slice's common leading whitespace.
|
|
28
|
+
*
|
|
29
|
+
* Removing the *common* prefix preserves relative structure exactly, so the
|
|
30
|
+
* result stays valid in indentation-significant languages: a dedented Python
|
|
31
|
+
* method is a function, a dedented YAML subtree is that subtree rooted.
|
|
32
|
+
*
|
|
33
|
+
* Blank lines are ignored when measuring the prefix — a blank line inside a
|
|
34
|
+
* block is not evidence that the block is flush left — and are emitted as
|
|
35
|
+
* empty rather than as whatever whitespace they happened to carry.
|
|
36
|
+
*
|
|
37
|
+
* Tabs and spaces are compared as characters, not as widths: a slice mixing
|
|
38
|
+
* them has no common prefix to strip, and guessing a tab width in order to
|
|
39
|
+
* manufacture one would change bytes the author did not ask to change.
|
|
40
|
+
*/
|
|
41
|
+
export declare function reindent(content: string): string;
|
|
42
|
+
/**
|
|
43
|
+
* Whether `reindent` applies, given the addressing mode and the attribute.
|
|
44
|
+
*
|
|
45
|
+
* **The default follows the addressing mode** (D16), for the same reason D9's
|
|
46
|
+
* does. An author writing `lines="10-40"` has seen the file and chosen those
|
|
47
|
+
* columns; changing how they render would be a silent visual change to every
|
|
48
|
+
* existing line-addressed invocation. An author writing `symbol="…"` never saw
|
|
49
|
+
* a column number — the resolver picked the region, so it owns presenting it
|
|
50
|
+
* legibly.
|
|
51
|
+
*/
|
|
52
|
+
export declare function shouldReindent(anchored: boolean, attr: boolean | undefined): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Line numbers within a slice whose text matches any of the given regexes.
|
|
55
|
+
*
|
|
56
|
+
* The anchor-native form of `highlight` (D13). A *numeric* highlight under an
|
|
57
|
+
* anchor is no longer something an author can write from knowledge — the
|
|
58
|
+
* resolver chose the region — so this matches on content instead.
|
|
59
|
+
*
|
|
60
|
+
* Returns 1-based offsets **within the slice**, which is what the fence's
|
|
61
|
+
* `highlight` attribute expects once `linenumbers` has supplied the file
|
|
62
|
+
* offset.
|
|
63
|
+
*
|
|
64
|
+
* @param content The resolved slice.
|
|
65
|
+
* @param patterns One or more regex sources.
|
|
66
|
+
*/
|
|
67
|
+
export declare function highlightMatchLines(content: string, patterns: string[]): number[];
|
|
68
|
+
/** Parse a `highlight-match` attribute into regex sources. Comma-separated,
|
|
69
|
+
* because an attribute is a string and authors reach for a list. */
|
|
70
|
+
export declare function parseHighlightMatch(raw: string | undefined): string[];
|
|
71
|
+
/** Render a list of 1-based slice offsets as the fence's `highlight` value. */
|
|
72
|
+
export declare function formatHighlight(lines: number[]): string;
|
|
73
|
+
//# sourceMappingURL=present.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"present.d.ts","sourceRoot":"","sources":["../../src/lib/present.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CA0BhD;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,OAAO,CAEpF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAajF;AAED;qEACqE;AACrE,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,CAMrE;AAED,+EAA+E;AAC/E,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAEvD"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anchor-native presentation (SPEC-131 D13 + D16; WORK-589).
|
|
3
|
+
*
|
|
4
|
+
* Anchoring makes nested targets easy for the first time — a class method, a
|
|
5
|
+
* key inside `"scripts"`, a rule inside `@media`, a step under `jobs:`. Two
|
|
6
|
+
* existing attributes were defined in terms of `lines=` and stop making sense
|
|
7
|
+
* under an anchor, and one new attribute is needed because the old form
|
|
8
|
+
* re-couples the invocation to the coordinates anchoring exists to decouple it
|
|
9
|
+
* from.
|
|
10
|
+
*
|
|
11
|
+
* **These are deliberately separate entry points, not folded into extraction.**
|
|
12
|
+
* Two later items need to call the pipeline at a chosen point and an inlined
|
|
13
|
+
* transform does not allow it:
|
|
14
|
+
*
|
|
15
|
+
* - WORK-590's codemod verifies a rewritten invocation produces a
|
|
16
|
+
* **byte-identical** slice, and that comparison runs **before** `reindent` —
|
|
17
|
+
* otherwise every nested target fails verification for a difference the
|
|
18
|
+
* codemod itself introduced.
|
|
19
|
+
* - WORK-591's review-marker hash applies `reindent` **first**, so that moving
|
|
20
|
+
* a function into a class — which shifts every line two columns without
|
|
21
|
+
* changing a character of content — does not fire the marker.
|
|
22
|
+
*
|
|
23
|
+
* The ordering is easy to get backwards and produces a confusing failure in
|
|
24
|
+
* each direction, which is why it is stated on both sides.
|
|
25
|
+
*/
|
|
26
|
+
/**
|
|
27
|
+
* Strip the slice's common leading whitespace.
|
|
28
|
+
*
|
|
29
|
+
* Removing the *common* prefix preserves relative structure exactly, so the
|
|
30
|
+
* result stays valid in indentation-significant languages: a dedented Python
|
|
31
|
+
* method is a function, a dedented YAML subtree is that subtree rooted.
|
|
32
|
+
*
|
|
33
|
+
* Blank lines are ignored when measuring the prefix — a blank line inside a
|
|
34
|
+
* block is not evidence that the block is flush left — and are emitted as
|
|
35
|
+
* empty rather than as whatever whitespace they happened to carry.
|
|
36
|
+
*
|
|
37
|
+
* Tabs and spaces are compared as characters, not as widths: a slice mixing
|
|
38
|
+
* them has no common prefix to strip, and guessing a tab width in order to
|
|
39
|
+
* manufacture one would change bytes the author did not ask to change.
|
|
40
|
+
*/
|
|
41
|
+
export function reindent(content) {
|
|
42
|
+
const lines = content.split('\n');
|
|
43
|
+
let prefix;
|
|
44
|
+
for (const line of lines) {
|
|
45
|
+
if (line.trim().length === 0)
|
|
46
|
+
continue;
|
|
47
|
+
const indent = line.slice(0, line.length - line.trimStart().length);
|
|
48
|
+
if (prefix === undefined) {
|
|
49
|
+
prefix = indent;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
// Shrink to the longest shared prefix.
|
|
53
|
+
let i = 0;
|
|
54
|
+
while (i < prefix.length && i < indent.length && prefix[i] === indent[i])
|
|
55
|
+
i++;
|
|
56
|
+
prefix = prefix.slice(0, i);
|
|
57
|
+
if (prefix.length === 0)
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
if (prefix === undefined || prefix.length === 0)
|
|
61
|
+
return content;
|
|
62
|
+
return lines
|
|
63
|
+
.map((line) => {
|
|
64
|
+
if (line.trim().length === 0)
|
|
65
|
+
return '';
|
|
66
|
+
return line.startsWith(prefix) ? line.slice(prefix.length) : line.trimStart();
|
|
67
|
+
})
|
|
68
|
+
.join('\n');
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Whether `reindent` applies, given the addressing mode and the attribute.
|
|
72
|
+
*
|
|
73
|
+
* **The default follows the addressing mode** (D16), for the same reason D9's
|
|
74
|
+
* does. An author writing `lines="10-40"` has seen the file and chosen those
|
|
75
|
+
* columns; changing how they render would be a silent visual change to every
|
|
76
|
+
* existing line-addressed invocation. An author writing `symbol="…"` never saw
|
|
77
|
+
* a column number — the resolver picked the region, so it owns presenting it
|
|
78
|
+
* legibly.
|
|
79
|
+
*/
|
|
80
|
+
export function shouldReindent(anchored, attr) {
|
|
81
|
+
return attr ?? anchored;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Line numbers within a slice whose text matches any of the given regexes.
|
|
85
|
+
*
|
|
86
|
+
* The anchor-native form of `highlight` (D13). A *numeric* highlight under an
|
|
87
|
+
* anchor is no longer something an author can write from knowledge — the
|
|
88
|
+
* resolver chose the region — so this matches on content instead.
|
|
89
|
+
*
|
|
90
|
+
* Returns 1-based offsets **within the slice**, which is what the fence's
|
|
91
|
+
* `highlight` attribute expects once `linenumbers` has supplied the file
|
|
92
|
+
* offset.
|
|
93
|
+
*
|
|
94
|
+
* @param content The resolved slice.
|
|
95
|
+
* @param patterns One or more regex sources.
|
|
96
|
+
*/
|
|
97
|
+
export function highlightMatchLines(content, patterns) {
|
|
98
|
+
const compiled = [];
|
|
99
|
+
for (const raw of patterns) {
|
|
100
|
+
if (raw.length === 0)
|
|
101
|
+
continue;
|
|
102
|
+
compiled.push(new RegExp(raw));
|
|
103
|
+
}
|
|
104
|
+
if (compiled.length === 0)
|
|
105
|
+
return [];
|
|
106
|
+
const hits = [];
|
|
107
|
+
content.split('\n').forEach((line, i) => {
|
|
108
|
+
if (compiled.some((re) => re.test(line)))
|
|
109
|
+
hits.push(i + 1);
|
|
110
|
+
});
|
|
111
|
+
return hits;
|
|
112
|
+
}
|
|
113
|
+
/** Parse a `highlight-match` attribute into regex sources. Comma-separated,
|
|
114
|
+
* because an attribute is a string and authors reach for a list. */
|
|
115
|
+
export function parseHighlightMatch(raw) {
|
|
116
|
+
if (typeof raw !== 'string' || raw.trim().length === 0)
|
|
117
|
+
return [];
|
|
118
|
+
return raw
|
|
119
|
+
.split(',')
|
|
120
|
+
.map((s) => s.trim())
|
|
121
|
+
.filter((s) => s.length > 0);
|
|
122
|
+
}
|
|
123
|
+
/** Render a list of 1-based slice offsets as the fence's `highlight` value. */
|
|
124
|
+
export function formatHighlight(lines) {
|
|
125
|
+
return lines.join(',');
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=present.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"present.js","sourceRoot":"","sources":["../../src/lib/present.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/read-file.d.ts
CHANGED
|
@@ -14,14 +14,29 @@
|
|
|
14
14
|
* runes package tree-shakable for browser bundles.
|
|
15
15
|
*/
|
|
16
16
|
import type { ProjectFiles } from '@refrakt-md/types';
|
|
17
|
+
import { type AnchorOptions } from './anchor.js';
|
|
17
18
|
/** Diagnostics from a single read. */
|
|
18
19
|
export interface ReadFileResult {
|
|
19
|
-
/** Resolved file content (possibly sliced by `lines`). */
|
|
20
|
+
/** Resolved file content (possibly sliced by `lines` or by an anchor). */
|
|
20
21
|
content: string;
|
|
21
22
|
/** Project-root-relative POSIX path — what `data-snippet-source` carries. */
|
|
22
23
|
relativePath: string;
|
|
23
24
|
/** Warnings the preprocess hook should surface (e.g., end-clamp). */
|
|
24
25
|
warnings: string[];
|
|
26
|
+
/**
|
|
27
|
+
* 1-indexed inclusive start line of the slice, in **file** coordinates.
|
|
28
|
+
*
|
|
29
|
+
* The coordinate frame survives anchoring on purpose (D13): `linenumbers`
|
|
30
|
+
* keeps starting at the real line and numeric `highlight` keeps meaning
|
|
31
|
+
* file lines, so the displayed numbers stay a usable pointer back into the
|
|
32
|
+
* file. Undefined only when the whole file was returned.
|
|
33
|
+
*/
|
|
34
|
+
start?: number;
|
|
35
|
+
/** 1-indexed inclusive end line, in file coordinates. */
|
|
36
|
+
end?: number;
|
|
37
|
+
/** Whether the slice was located by anchor rather than by `lines=`. Drives
|
|
38
|
+
* the `reindent` and `doc` defaults, which follow the addressing mode. */
|
|
39
|
+
anchored: boolean;
|
|
25
40
|
}
|
|
26
41
|
export interface ReadFileOptions {
|
|
27
42
|
/** The project's files, rooted at the project root. Reads go through this. */
|
|
@@ -33,6 +48,11 @@ export interface ReadFileOptions {
|
|
|
33
48
|
/** Optional source-page context used in error messages
|
|
34
49
|
* ("Referenced from: docs/getting-started.md:42"). */
|
|
35
50
|
referencingPage?: string;
|
|
51
|
+
/** Optional anchor attributes — `symbol`, `match`, `extent` and friends.
|
|
52
|
+
* Mutually exclusive with `lines`. */
|
|
53
|
+
anchor?: AnchorOptions;
|
|
54
|
+
/** Optional explicit language id, overriding extension inference. */
|
|
55
|
+
lang?: string;
|
|
36
56
|
}
|
|
37
57
|
/** Range parsed from the `lines=` attribute. */
|
|
38
58
|
interface LineRange {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read-file.d.ts","sourceRoot":"","sources":["../../src/lib/read-file.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"read-file.d.ts","sourceRoot":"","sources":["../../src/lib/read-file.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,KAAK,aAAa,EAAwC,MAAM,aAAa,CAAC;AAGvF,sCAAsC;AACtC,MAAM,WAAW,cAAc;IAC9B,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC;IAChB,6EAA6E;IAC7E,YAAY,EAAE,MAAM,CAAC;IACrB,qEAAqE;IACrE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;+EAC2E;IAC3E,QAAQ,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC/B,8EAA8E;IAC9E,KAAK,EAAE,YAAY,CAAC;IACpB,2EAA2E;IAC3E,QAAQ,EAAE,MAAM,CAAC;IACjB,+EAA+E;IAC/E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;2DACuD;IACvD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;2CACuC;IACvC,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,qEAAqE;IACrE,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,gDAAgD;AAChD,UAAU,SAAS;IAClB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AAED;uDACuD;AACvD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,IAAI,CA2CxE;AAED;;gBAEgB;AAChB,wBAAgB,YAAY,CAC3B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,SAAS,GAAG,IAAI,GACrB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAuBxC;AAED;;iFAEiF;AACjF,wBAAgB,eAAe,CAAC,IAAI,EAAE,eAAe,GAAG,cAAc,CAoErE;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAC5C,KAAK,EAAE,YAAY,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACrB,GAAG,MAAM,CAQT;AAED;oDACoD;AACpD,qBAAa,mBAAoB,SAAQ,KAAK;gBACjC,OAAO,EAAE,MAAM;CAI3B"}
|
package/dist/lib/read-file.js
CHANGED
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
* No `node:fs` import — all I/O goes through the provider, which keeps the
|
|
14
14
|
* runes package tree-shakable for browser bundles.
|
|
15
15
|
*/
|
|
16
|
+
import { AnchorResolutionError, resolveAnchor } from './anchor.js';
|
|
17
|
+
import { resolveLanguage } from './languages.js';
|
|
16
18
|
/** Parse a `lines=` attribute. Returns null when the attribute is empty/absent;
|
|
17
19
|
* throws `SnippetSandboxError` on malformed input. */
|
|
18
20
|
export function parseLineRange(raw) {
|
|
@@ -83,12 +85,56 @@ export function readSnippetFile(opts) {
|
|
|
83
85
|
const referenced = opts.referencingPage ? `\n\nReferenced from: ${opts.referencingPage}` : '';
|
|
84
86
|
throw new SnippetSandboxError(`snippet path "${opts.pathAttr}" cannot be resolved — the file is missing, not a regular file, or outside the project root.${referenced}`);
|
|
85
87
|
}
|
|
88
|
+
const anchor = opts.anchor;
|
|
89
|
+
const hasAnchor = anchor !== undefined &&
|
|
90
|
+
((typeof anchor.symbol === 'string' && anchor.symbol.length > 0) ||
|
|
91
|
+
(typeof anchor.match === 'string' && anchor.match.length > 0));
|
|
92
|
+
const hasLines = typeof opts.lines === 'string' && opts.lines.length > 0;
|
|
93
|
+
if (hasAnchor && hasLines) {
|
|
94
|
+
throw new SnippetSandboxError(`snippet "${opts.pathAttr}" sets both \`lines\` and an anchor (\`symbol\`/\`match\`), ` +
|
|
95
|
+
'which are mutually exclusive — an anchor names a region and `lines` addresses one by ' +
|
|
96
|
+
'coordinate. Remove one.');
|
|
97
|
+
}
|
|
98
|
+
if (hasAnchor) {
|
|
99
|
+
const lang = resolveLanguage(opts.lang ?? opts.pathAttr);
|
|
100
|
+
let resolved;
|
|
101
|
+
try {
|
|
102
|
+
resolved = resolveAnchor(rawContent, lang, anchor, opts.pathAttr);
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
// One failure channel. D6: resolution failures raise
|
|
106
|
+
// `SnippetSandboxError`, which the existing path turns into an error
|
|
107
|
+
// fence plus a `ctx.error` diagnostic. No new channel.
|
|
108
|
+
if (err instanceof AnchorResolutionError) {
|
|
109
|
+
const referenced = opts.referencingPage
|
|
110
|
+
? `\n\nReferenced from: ${opts.referencingPage}`
|
|
111
|
+
: '';
|
|
112
|
+
throw new SnippetSandboxError(`snippet ${err.message}${referenced}`);
|
|
113
|
+
}
|
|
114
|
+
throw err;
|
|
115
|
+
}
|
|
116
|
+
const allLines = rawContent.split('\n');
|
|
117
|
+
return {
|
|
118
|
+
content: allLines.slice(resolved.start - 1, resolved.end).join('\n'),
|
|
119
|
+
relativePath: opts.pathAttr,
|
|
120
|
+
warnings: resolved.warnings,
|
|
121
|
+
start: resolved.start,
|
|
122
|
+
end: resolved.end,
|
|
123
|
+
anchored: true,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
86
126
|
const range = parseLineRange(opts.lines);
|
|
87
127
|
const { sliced, warnings } = sliceContent(rawContent, range);
|
|
128
|
+
const total = rawContent.split('\n').length;
|
|
129
|
+
const start = range ? (range.start ?? 1) : undefined;
|
|
130
|
+
const end = range ? Math.min(range.end ?? total, total) : undefined;
|
|
88
131
|
return {
|
|
89
132
|
content: sliced,
|
|
90
133
|
relativePath: opts.pathAttr,
|
|
91
134
|
warnings,
|
|
135
|
+
start,
|
|
136
|
+
end,
|
|
137
|
+
anchored: false,
|
|
92
138
|
};
|
|
93
139
|
}
|
|
94
140
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read-file.js","sourceRoot":"","sources":["../../src/lib/read-file.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;
|
|
1
|
+
{"version":3,"file":"read-file.js","sourceRoot":"","sources":["../../src/lib/read-file.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/renderable.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import Markdoc from '@markdoc/markdoc';
|
|
2
2
|
import type { Tag, RenderableTreeNode } from '@markdoc/markdoc';
|
|
3
|
-
import { NodeType } from '@refrakt-md/types';
|
|
3
|
+
import type { NodeType } from '@refrakt-md/types';
|
|
4
4
|
export declare class RenderableNodeCursor<T extends RenderableTreeNode = RenderableTreeNode> {
|
|
5
5
|
readonly nodes: T[];
|
|
6
6
|
private offset;
|
|
@@ -11,8 +11,12 @@ export declare class RenderableNodeCursor<T extends RenderableTreeNode = Rendera
|
|
|
11
11
|
tags<TagNames extends NodeType[]>(...tags: TagNames): RenderableNodeCursor<Tag<TagNames[number]>>;
|
|
12
12
|
headings(): RenderableNodeCursor<Markdoc.Tag<"h1" | "h2" | "h3" | "h4" | "h5" | "h6", Record<string, any>>>;
|
|
13
13
|
typeof(type: string): RenderableNodeCursor<T>;
|
|
14
|
-
concat(...other: (RenderableTreeNode | RenderableNodeCursor)[]): RenderableNodeCursor<Markdoc.
|
|
15
|
-
|
|
14
|
+
concat(...other: (RenderableTreeNode | RenderableNodeCursor)[]): RenderableNodeCursor<string | number | boolean | Markdoc.Scalar[] | {
|
|
15
|
+
[key: string]: Markdoc.Scalar;
|
|
16
|
+
} | Markdoc.Tag<string, Record<string, any>> | null>;
|
|
17
|
+
flatten(): RenderableNodeCursor<string | number | boolean | Markdoc.Scalar[] | {
|
|
18
|
+
[key: string]: Markdoc.Scalar;
|
|
19
|
+
} | Markdoc.Tag<string, Record<string, any>> | null>;
|
|
16
20
|
limit(count: number): RenderableNodeCursor<T>;
|
|
17
21
|
slice(start: number, end?: number): RenderableNodeCursor<T>;
|
|
18
22
|
toArray(): T[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderable.d.ts","sourceRoot":"","sources":["../../src/lib/renderable.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,EAAE,GAAG,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"renderable.d.ts","sourceRoot":"","sources":["../../src/lib/renderable.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,EAAE,GAAG,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAIlD,qBAAa,oBAAoB,CAAC,CAAC,SAAS,kBAAkB,GAAG,kBAAkB;aAGtD,KAAK,EAAE,CAAC,EAAE;IAFtC,OAAO,CAAC,MAAM,CAAK;gBAES,KAAK,EAAE,CAAC,EAAE;IAEtC,MAAM,CAAC,QAAQ,CAAC,OAAO,SAAS,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO;IAIjE,IAAI,CAAC,OAAO,SAAS,MAAM,EAC1B,GAAG,EAAE,OAAO,EACZ,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAClC,oBAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAIrC,GAAG,CAAC,OAAO,SAAS,QAAQ,EAAE,GAAG,EAAE,OAAO,GAAG,oBAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAO/E,IAAI,CAAC,QAAQ,SAAS,QAAQ,EAAE,EAC/B,GAAG,IAAI,EAAE,QAAQ,GACf,oBAAoB,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAO9C,QAAQ;IAIR,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,CAAC,CAAC,CAAC;IAQ7C,MAAM,CAAC,GAAG,KAAK,EAAE,CAAC,kBAAkB,GAAG,oBAAoB,CAAC,EAAE;;;IAK9D,OAAO;;;IAKP,KAAK,CAAC,KAAK,EAAE,MAAM;IAInB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM;IAIjC,OAAO,IAAI,CAAC,EAAE;IAId,KAAK,IAAI,MAAM;IAIf,IAAI,IAAI,CAAC;CAGT"}
|
package/dist/lib/renderable.js
CHANGED
|
@@ -27,11 +27,11 @@ export class RenderableNodeCursor {
|
|
|
27
27
|
return new RenderableNodeCursor(this.nodes.filter((n) => Markdoc.Tag.isTag(n) && n.attributes['data-rune'] === toKebabCase(type)));
|
|
28
28
|
}
|
|
29
29
|
concat(...other) {
|
|
30
|
-
const nodes = other.
|
|
30
|
+
const nodes = other.flatMap((o) => (o instanceof RenderableNodeCursor ? o.nodes : o));
|
|
31
31
|
return new RenderableNodeCursor([...this.nodes, ...nodes]);
|
|
32
32
|
}
|
|
33
33
|
flatten() {
|
|
34
|
-
const nodes = this.nodes.
|
|
34
|
+
const nodes = this.nodes.flatMap((t) => (Markdoc.Tag.isTag(t) ? Array.from(walkTag(t)) : t));
|
|
35
35
|
return new RenderableNodeCursor(nodes);
|
|
36
36
|
}
|
|
37
37
|
limit(count) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderable.js","sourceRoot":"","sources":["../../src/lib/renderable.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,kBAAkB,CAAC;AAGvC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAErC,MAAM,OAAO,oBAAoB;IAGhC,YAA4B,KAAU;QAAV,UAAK,GAAL,KAAK,CAAK;QAF9B,WAAM,GAAG,CAAC,CAAC;IAEsB,CAAC;IAE1C,MAAM,CAAC,QAAQ,CAA2B,IAAS,EAAE,GAAY;QAChE,OAAO,IAAI,oBAAoB,CAAC,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACrE,CAAC;IAED,IAAI,CACH,GAAY,EACZ,aAAkC,EAAE;QAEpC,OAAO,IAAI,oBAAoB,CAAC,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACjF,CAAC;IAED,GAAG,CAA2B,GAAY;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAC9B,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,GAAG,CAChB,CAAC;QAC/B,OAAO,IAAI,oBAAoB,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC;IAED,IAAI,CACH,GAAG,IAAc;QAEjB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAC9B,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAK,IAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAC5B,CAAC;QACxC,OAAO,IAAI,oBAAoB,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC;IAED,QAAQ;QACP,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,CAAC,IAAY;QAClB,OAAO,IAAI,oBAAoB,CAC9B,IAAI,CAAC,KAAK,CAAC,MAAM,CAChB,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,WAAW,CAAC,KAAK,WAAW,CAAC,IAAI,CAAC,CAC9E,CACD,CAAC;IACH,CAAC;IAED,MAAM,CAAC,GAAG,KAAoD;QAC7D,MAAM,KAAK,GAAG,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"renderable.js","sourceRoot":"","sources":["../../src/lib/renderable.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Review markers for embedded source (SPEC-134, WORK-591).
|
|
3
|
+
*
|
|
4
|
+
* SPEC-131 answers *am I quoting the right region*. This answers the next
|
|
5
|
+
* question up: **the region is right, and the prose around it no longer
|
|
6
|
+
* describes what is in it.**
|
|
7
|
+
*
|
|
8
|
+
* A field is removed, a default flips, a parameter is reordered — the anchor
|
|
9
|
+
* resolves perfectly, the code block renders real current code, and the
|
|
10
|
+
* paragraph above it quietly becomes false. That is the *ordinary* case,
|
|
11
|
+
* because editing a declaration is far more common than renaming or moving one.
|
|
12
|
+
*
|
|
13
|
+
* ```markdoc
|
|
14
|
+
* {% snippet path="packages/types/src/config.ts" symbol="SiteConfig" reviewed="a3f91c4e" /%}
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* Resolution is unchanged. After the slice resolves it is normalized, hashed
|
|
18
|
+
* and compared. A mismatch produces a diagnostic; the page still renders the
|
|
19
|
+
* current code.
|
|
20
|
+
*
|
|
21
|
+
* **`reviewed`, not `pin` (D1).** This freezes nothing — the snippet still
|
|
22
|
+
* tracks HEAD and re-resolves every build. What the attribute records is that a
|
|
23
|
+
* human read this version and the surrounding prose matched. The name is
|
|
24
|
+
* load-bearing: `pin=` would steer an author toward "this is frozen, nothing to
|
|
25
|
+
* do here", which is the opposite of the intended response.
|
|
26
|
+
*/
|
|
27
|
+
export interface HashPair {
|
|
28
|
+
/** The stored hash — reindent, line endings, trailing whitespace. */
|
|
29
|
+
strict: string;
|
|
30
|
+
/** Additionally collapsing whitespace runs and dropping blank lines. */
|
|
31
|
+
loose: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The normalized form that gets hashed.
|
|
35
|
+
*
|
|
36
|
+
* **Normalization is the whole design.** Hash raw bytes and the marker fires on
|
|
37
|
+
* every trailing space and every reformat — and a marker that cries wolf gets
|
|
38
|
+
* deleted. Budget the normalization, not the hash: hashing is a line, and
|
|
39
|
+
* getting normalization wrong produces a feature that is worse than not having
|
|
40
|
+
* it.
|
|
41
|
+
*
|
|
42
|
+
* In order:
|
|
43
|
+
*
|
|
44
|
+
* 1. **Apply `reindent` first.** Moving a function into a class shifts every
|
|
45
|
+
* line two columns without changing a character of content.
|
|
46
|
+
* 2. Normalize line endings, strip per-line trailing whitespace, normalize the
|
|
47
|
+
* trailing newline.
|
|
48
|
+
* 3. **Stop. Comments stay in — D2.**
|
|
49
|
+
*
|
|
50
|
+
* Excluding comments would make markers quieter, and SPEC-131's masker could do
|
|
51
|
+
* it for free. It is still wrong: a doc comment is very often the exact text
|
|
52
|
+
* the surrounding prose paraphrases. If `@param timeout`'s description changes
|
|
53
|
+
* meaning and the marker stays green, the feature has failed at the only job it
|
|
54
|
+
* has.
|
|
55
|
+
*/
|
|
56
|
+
export declare function normalizeStrict(content: string): string;
|
|
57
|
+
/**
|
|
58
|
+
* The loose form — strict, plus collapsing whitespace runs and dropping blank
|
|
59
|
+
* lines.
|
|
60
|
+
*
|
|
61
|
+
* This exists so that "it was just the formatter" is a **fact the tool
|
|
62
|
+
* establishes** rather than a judgement an author makes under time pressure
|
|
63
|
+
* (D3). A repo-wide formatter run would otherwise invalidate every marker at
|
|
64
|
+
* once, and an author re-stamping fifty of them learns nothing — the feature's
|
|
65
|
+
* worst failure mode, and the strongest objection to it.
|
|
66
|
+
*/
|
|
67
|
+
export declare function normalizeLoose(content: string): string;
|
|
68
|
+
/** Both hash levels for a resolved slice. */
|
|
69
|
+
export declare function hashSlice(content: string): HashPair;
|
|
70
|
+
/** What a comparison against a stored marker concluded. */
|
|
71
|
+
export type MarkerVerdict =
|
|
72
|
+
/** The stored hash still matches. Nothing to do. */
|
|
73
|
+
'current'
|
|
74
|
+
/** Strict differs, loose matches — the change is *provably* formatting
|
|
75
|
+
* only, so it can be re-stamped silently (D3). */
|
|
76
|
+
| 'formatting-only'
|
|
77
|
+
/** Both differ. The content carries meaning; hold for review. */
|
|
78
|
+
| 'stale';
|
|
79
|
+
export interface MarkerComparison {
|
|
80
|
+
verdict: MarkerVerdict;
|
|
81
|
+
stored: string;
|
|
82
|
+
current: HashPair;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Compare a stored marker against the slice as it is now.
|
|
86
|
+
*
|
|
87
|
+
* The stored value is compared against the **strict** hash. A stored marker
|
|
88
|
+
* that matches neither level, but whose loose form matches the current loose
|
|
89
|
+
* form, is formatting-only: the author reviewed content that still says the
|
|
90
|
+
* same thing with different whitespace.
|
|
91
|
+
*/
|
|
92
|
+
export declare function compareMarker(stored: string, content: string, storedLoose?: string): MarkerComparison;
|
|
93
|
+
/** Render a marker attribute value. Both levels are stored, separated by a
|
|
94
|
+
* colon, so the formatting-only case can be *proven* rather than assumed. */
|
|
95
|
+
export declare function formatMarker(pair: HashPair): string;
|
|
96
|
+
/** Parse a stored marker value into its levels. A marker written before the
|
|
97
|
+
* loose level existed — or by hand — carries only the strict half. */
|
|
98
|
+
export declare function parseMarker(raw: string): {
|
|
99
|
+
strict: string;
|
|
100
|
+
loose?: string;
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Whether an invocation can meaningfully carry a marker.
|
|
104
|
+
*
|
|
105
|
+
* D10: a slice that cannot change can never fire, so stamping one means
|
|
106
|
+
* nothing and the tool should say so rather than doing it. Today the only such
|
|
107
|
+
* case is an invocation with no resolvable slice at all.
|
|
108
|
+
*/
|
|
109
|
+
export declare function canCarryMarker(opts: {
|
|
110
|
+
hasPath: boolean;
|
|
111
|
+
rune: string;
|
|
112
|
+
}): boolean;
|
|
113
|
+
//# sourceMappingURL=review-marker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-marker.d.ts","sourceRoot":"","sources":["../../src/lib/review-marker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAYH,MAAM,WAAW,QAAQ;IACxB,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,KAAK,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAOvD;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAMtD;AAwCD,6CAA6C;AAC7C,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,CAKnD;AAED,2DAA2D;AAC3D,MAAM,MAAM,aAAa;AACxB,oDAAoD;AAClD,SAAS;AACX;mDACmD;GACjD,iBAAiB;AACnB,iEAAiE;GAC/D,OAAO,CAAC;AAEX,MAAM,WAAW,gBAAgB;IAChC,OAAO,EAAE,aAAa,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,QAAQ,CAAC;CAClB;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC5B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,WAAW,CAAC,EAAE,MAAM,GAClB,gBAAgB,CAiBlB;AAED;8EAC8E;AAC9E,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAEnD;AAED;uEACuE;AACvE,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAG3E;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAMhF"}
|