@descent-vtt/spec-graph 0.8.0 → 0.9.1

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.
Files changed (103) hide show
  1. package/CHANGELOG.md +483 -38
  2. package/README.md +134 -49
  3. package/dist/cli.d.ts +2 -2
  4. package/dist/cli.js +38 -19
  5. package/dist/cli.js.map +1 -1
  6. package/dist/directives.d.ts +9 -2
  7. package/dist/directives.js +15 -4
  8. package/dist/directives.js.map +1 -1
  9. package/dist/extract.d.ts +1 -1
  10. package/dist/extract.js +50 -16
  11. package/dist/extract.js.map +1 -1
  12. package/dist/glob.d.ts +44 -44
  13. package/dist/glob.js +152 -116
  14. package/dist/glob.js.map +1 -1
  15. package/dist/index.d.ts +3 -3
  16. package/dist/index.js +4 -2
  17. package/dist/index.js.map +1 -1
  18. package/dist/lifecycle.js +10 -2
  19. package/dist/lifecycle.js.map +1 -1
  20. package/dist/markdown.d.ts +53 -161
  21. package/dist/markdown.js +42 -864
  22. package/dist/markdown.js.map +1 -1
  23. package/dist/report.d.ts +23 -0
  24. package/dist/report.js +80 -0
  25. package/dist/report.js.map +1 -1
  26. package/dist/rules.js +48 -14
  27. package/dist/rules.js.map +1 -1
  28. package/dist/sections.d.ts +1 -1
  29. package/dist/sections.js +7 -3
  30. package/dist/sections.js.map +1 -1
  31. package/dist/select.d.ts +2 -2
  32. package/dist/select.js +3 -3
  33. package/dist/select.js.map +1 -1
  34. package/dist/source.d.ts +6 -19
  35. package/dist/source.js +4 -70
  36. package/dist/source.js.map +1 -1
  37. package/dist/types.d.ts +23 -3
  38. package/dist/types.js +1 -1
  39. package/dist/types.js.map +1 -1
  40. package/dist/vendor/spec-core/markdown/frontmatter.d.ts +103 -0
  41. package/dist/vendor/spec-core/markdown/frontmatter.js +459 -0
  42. package/dist/vendor/spec-core/markdown/frontmatter.js.map +1 -0
  43. package/dist/vendor/spec-core/markdown/headings.d.ts +45 -0
  44. package/dist/vendor/spec-core/markdown/headings.js +199 -0
  45. package/dist/vendor/spec-core/markdown/headings.js.map +1 -0
  46. package/dist/vendor/spec-core/markdown/index.d.ts +5 -0
  47. package/dist/vendor/spec-core/markdown/index.js +4 -0
  48. package/dist/vendor/spec-core/markdown/index.js.map +1 -0
  49. package/dist/vendor/spec-core/markdown/layout.d.ts +39 -0
  50. package/dist/vendor/spec-core/markdown/layout.js +28 -0
  51. package/dist/vendor/spec-core/markdown/layout.js.map +1 -0
  52. package/dist/vendor/spec-core/markdown/links.d.ts +25 -0
  53. package/dist/vendor/spec-core/markdown/links.js +394 -0
  54. package/dist/vendor/spec-core/markdown/links.js.map +1 -0
  55. package/dist/vendor/spec-core/markdown/lists.d.ts +22 -0
  56. package/dist/vendor/spec-core/markdown/lists.js +127 -0
  57. package/dist/vendor/spec-core/markdown/lists.js.map +1 -0
  58. package/dist/vendor/spec-core/markdown/scan.d.ts +36 -0
  59. package/dist/vendor/spec-core/markdown/scan.js +463 -0
  60. package/dist/vendor/spec-core/markdown/scan.js.map +1 -0
  61. package/dist/vendor/spec-core/markdown/syntax.d.ts +75 -0
  62. package/dist/vendor/spec-core/markdown/syntax.js +181 -0
  63. package/dist/vendor/spec-core/markdown/syntax.js.map +1 -0
  64. package/dist/vendor/spec-core/markdown/tables.d.ts +18 -0
  65. package/dist/vendor/spec-core/markdown/tables.js +86 -0
  66. package/dist/vendor/spec-core/markdown/tables.js.map +1 -0
  67. package/dist/vendor/spec-core/markdown/types.d.ts +290 -0
  68. package/dist/vendor/spec-core/markdown/types.js +9 -0
  69. package/dist/vendor/spec-core/markdown/types.js.map +1 -0
  70. package/dist/vendor/spec-core/path/index.d.ts +1 -0
  71. package/dist/vendor/spec-core/path/index.js +2 -0
  72. package/dist/vendor/spec-core/path/index.js.map +1 -0
  73. package/dist/vendor/spec-core/path/posix.d.ts +83 -0
  74. package/dist/vendor/spec-core/path/posix.js +150 -0
  75. package/dist/vendor/spec-core/path/posix.js.map +1 -0
  76. package/dist/vendor/spec-core/pattern/automaton.d.ts +129 -0
  77. package/dist/vendor/spec-core/pattern/automaton.js +340 -0
  78. package/dist/vendor/spec-core/pattern/automaton.js.map +1 -0
  79. package/dist/vendor/spec-core/pattern/charset.d.ts +58 -0
  80. package/dist/vendor/spec-core/pattern/charset.js +116 -0
  81. package/dist/vendor/spec-core/pattern/charset.js.map +1 -0
  82. package/dist/vendor/spec-core/pattern/glob.d.ts +121 -0
  83. package/dist/vendor/spec-core/pattern/glob.js +481 -0
  84. package/dist/vendor/spec-core/pattern/glob.js.map +1 -0
  85. package/dist/vendor/spec-core/pattern/index.d.ts +6 -0
  86. package/dist/vendor/spec-core/pattern/index.js +4 -0
  87. package/dist/vendor/spec-core/pattern/index.js.map +1 -0
  88. package/dist/{regex.d.ts → vendor/spec-core/pattern/regex.d.ts} +20 -29
  89. package/dist/{regex.js → vendor/spec-core/pattern/regex.js} +40 -49
  90. package/dist/vendor/spec-core/pattern/regex.js.map +1 -0
  91. package/dist/vendor/spec-core/text/index.d.ts +2 -0
  92. package/dist/vendor/spec-core/text/index.js +2 -0
  93. package/dist/vendor/spec-core/text/index.js.map +1 -0
  94. package/dist/vendor/spec-core/text/lines.d.ts +72 -0
  95. package/dist/vendor/spec-core/text/lines.js +156 -0
  96. package/dist/vendor/spec-core/text/lines.js.map +1 -0
  97. package/dist/yaml.d.ts +44 -12
  98. package/dist/yaml.js +115 -206
  99. package/dist/yaml.js.map +1 -1
  100. package/package.json +4 -3
  101. package/src/vendor/spec-core/LICENSE +21 -0
  102. package/src/vendor/spec-core/README.md +8 -0
  103. package/dist/regex.js.map +0 -1
@@ -0,0 +1,394 @@
1
+ /**
2
+ * Links, images and reference definitions, read from the structure mask so
3
+ * that nothing in code or a comment is one.
4
+ *
5
+ * Six forms: inline `[text](dest "title")`, full and collapsed reference
6
+ * `[text][label]` and `[label][]`, shortcut `[label]`, autolink `<https://x>`,
7
+ * wiki `[[target|text]]`, and the definition `[label]: dest` the reference
8
+ * forms are read through. Each may be an image, written with a leading `!`.
9
+ * A link's text is read again for images, which CommonMark renders there - a
10
+ * badge wrapped in a link has two destinations - and for nothing else; each
11
+ * is listed after the link it lies in.
12
+ *
13
+ * Brackets are paired once per paragraph with a stack, and the tables that
14
+ * say where a destination or a title ends are built once per paragraph, so
15
+ * no bracket searches the text again for its partner. A document of nothing
16
+ * but brackets costs its length.
17
+ *
18
+ * A paragraph ends at `to`, and the character there is a line terminator,
19
+ * which no loop here acts on; nor is any lookup made at the first three
20
+ * offsets of a paragraph, before the shortest `[](` could end. Mutants that
21
+ * move a bound onto those places change no answer, and are equivalent.
22
+ */
23
+ import { inRanges, mergeRanges } from '../text/index.js';
24
+ import { isMarkdown, isSpaceOrTab, visibleLead } from './layout.js';
25
+ const BANG = 33;
26
+ const DOUBLE_QUOTE = 34;
27
+ const SINGLE_QUOTE = 39;
28
+ const OPEN_PAREN = 40;
29
+ const CLOSE_PAREN = 41;
30
+ const LESS_THAN = 60;
31
+ const GREATER_THAN = 62;
32
+ const OPEN_BRACKET = 91;
33
+ const BACKSLASH = 92;
34
+ const CLOSE_BRACKET = 93;
35
+ const LF = 10;
36
+ const CR = 13;
37
+ /** CommonMark: a link label holds at most 999 characters. */
38
+ const MAX_LABEL = 999;
39
+ const DEFINITION = /^ {0,3}\[(?!\^)([^\]]+)\]:[ \t]*(<[^<>]*>|\S+)/;
40
+ /** What may follow a definition's destination: nothing, or a title after whitespace. */
41
+ const TITLE_ONLY = /^(?:[ \t]+(?:"[^"]*"|'[^']*'|\([^)]*\)))?[ \t]*$/;
42
+ const AUTOLINK = /<((?:https?|ftp|mailto):[^<>\s]+)>/g;
43
+ export function findLinks(layout) {
44
+ const definitions = new Map();
45
+ const defined = readDefinitions(layout, definitions);
46
+ const bracketed = readBrackets(layout, definitions, new Set(defined.map((d) => d.line)));
47
+ // `<https://x>` as a link's destination or text is part of that link.
48
+ const taken = mergeRanges([...defined, ...bracketed]);
49
+ const autolinks = readAutolinks(layout).filter((link) => !inRanges(taken, link.start));
50
+ return [...defined, ...bracketed, ...autolinks].sort((a, b) => a.start - b.start);
51
+ }
52
+ /**
53
+ * How labels compare: trimmed, whitespace collapsed, and case folded as
54
+ * CommonMark's reference implementations fold it, down and then up, so that
55
+ * `ẞ` and `SS` are one label.
56
+ */
57
+ function normalizeLabel(label) {
58
+ return label.trim().replace(/\s+/g, ' ').toLowerCase().toUpperCase();
59
+ }
60
+ /**
61
+ * Definitions come first: the reference forms are read through them, and a
62
+ * definition is conventionally written at the foot of the file, after the
63
+ * links that use it. The first definition of a label wins.
64
+ *
65
+ * `[Note]: this matters` is prose that looks like one, so a definition has
66
+ * nothing after its destination but a title. `[^1]: text` is a footnote.
67
+ */
68
+ function readDefinitions(layout, definitions) {
69
+ const { text, structure } = layout;
70
+ const out = [];
71
+ for (const line of layout.lines) {
72
+ if (!isMarkdown(line) || !visibleLead(layout, line))
73
+ continue;
74
+ const masked = structure.slice(line.contentStart, line.end);
75
+ const match = DEFINITION.exec(masked);
76
+ if (match === null || !TITLE_ONLY.test(masked.slice(match[0].length)))
77
+ continue;
78
+ const start = line.contentStart + match[0].indexOf('[');
79
+ const label = text.slice(start + 1, start + 1 + match[1].length).trim();
80
+ if (label.length === 0)
81
+ continue;
82
+ const written = match[2];
83
+ const end = line.contentStart + match[0].length;
84
+ const angle = written.charCodeAt(0) === LESS_THAN ? 1 : 0;
85
+ const targetStart = end - written.length + angle;
86
+ const targetEnd = end - angle;
87
+ const target = text.slice(targetStart, targetEnd);
88
+ const key = normalizeLabel(label);
89
+ if (!definitions.has(key))
90
+ definitions.set(key, { target, targetStart, targetEnd });
91
+ out.push({ form: 'definition', image: false, text: label, target, label, start, end, targetStart, targetEnd, line: line.line });
92
+ }
93
+ return out;
94
+ }
95
+ function readAutolinks(layout) {
96
+ const out = [];
97
+ for (const match of layout.structure.matchAll(AUTOLINK)) {
98
+ const start = match.index;
99
+ const end = start + match[0].length;
100
+ out.push({
101
+ form: 'autolink',
102
+ image: false,
103
+ text: '',
104
+ target: match[1],
105
+ label: null,
106
+ start,
107
+ end,
108
+ targetStart: start + 1,
109
+ targetEnd: end - 1,
110
+ line: layout.index.positionAt(start).line,
111
+ });
112
+ }
113
+ return out;
114
+ }
115
+ /** Pairs `[` with `]` inside a paragraph, innermost first, skipping escaped ones. */
116
+ function pairBrackets(structure, from, to) {
117
+ const pairs = new Map();
118
+ const open = [];
119
+ for (let at = from; at < to; at += 1) {
120
+ const ch = structure.charCodeAt(at);
121
+ if (ch === BACKSLASH)
122
+ at += 1;
123
+ else if (ch === OPEN_BRACKET)
124
+ open.push(at);
125
+ else if (ch === CLOSE_BRACKET) {
126
+ // A `]` with nothing to close pairs with nothing; recorded under
127
+ // `undefined` it would not be found either, so this test changes no
128
+ // answer, only what the map holds.
129
+ const opened = open.pop();
130
+ if (opened !== undefined)
131
+ pairs.set(opened, at);
132
+ }
133
+ }
134
+ return pairs;
135
+ }
136
+ function endsOf(structure, from, to) {
137
+ const length = to - from;
138
+ const escaped = new Uint8Array(length + 1);
139
+ for (let x = 0; x < length; x += 1) {
140
+ if (escaped[x] === 0 && structure.charCodeAt(from + x) === BACKSLASH)
141
+ escaped[x + 1] = 1;
142
+ }
143
+ // Two past the last offset: a `(` whose `)` is the paragraph's last
144
+ // character looks one further for the next unmatched `)`, and finds none.
145
+ const make = () => new Int32Array(length + 2).fill(to);
146
+ const ends = { space: make(), paren: make(), doubleQuote: make(), singleQuote: make(), closeParen: make(), openParen: make() };
147
+ for (let x = length - 1; x >= 0; x -= 1) {
148
+ const at = from + x;
149
+ const ch = structure.charCodeAt(at);
150
+ const plain = escaped[x] === 0;
151
+ ends.space[x] = ch <= 32 || ch === 127 ? at : ends.space[x + 1];
152
+ // From a `(`, the first unmatched `)` is the first one after the `)` that
153
+ // closes it, which is the first unmatched `)` after the `(`.
154
+ const unmatched = ends.paren[x + 1];
155
+ if (plain && ch === CLOSE_PAREN)
156
+ ends.paren[x] = at;
157
+ else if (plain && ch === OPEN_PAREN)
158
+ ends.paren[x] = ends.paren[unmatched + 1 - from];
159
+ else
160
+ ends.paren[x] = unmatched;
161
+ ends.doubleQuote[x] = plain && ch === DOUBLE_QUOTE ? at : ends.doubleQuote[x + 1];
162
+ ends.singleQuote[x] = plain && ch === SINGLE_QUOTE ? at : ends.singleQuote[x + 1];
163
+ ends.closeParen[x] = plain && ch === CLOSE_PAREN ? at : ends.closeParen[x + 1];
164
+ ends.openParen[x] = plain && ch === OPEN_PAREN ? at : ends.openParen[x + 1];
165
+ }
166
+ return ends;
167
+ }
168
+ /**
169
+ * The bracket forms, a paragraph at a time. A paragraph here is a run of
170
+ * Markdown lines, none blank, each continuing the one above: a bracket never
171
+ * pairs across a blank line, a heading, or the start of another block.
172
+ */
173
+ function readBrackets(layout, definitions, defined) {
174
+ const { lines, continues, structure, text } = layout;
175
+ const out = [];
176
+ // The first `]]` at or after the last place one was looked for; the cursor
177
+ // only moves forward, so each is found once.
178
+ let doubleClose = -2;
179
+ const lookup = (from, to) => to - from > MAX_LABEL ? undefined : definitions.get(normalizeLabel(text.slice(from, to)));
180
+ // A blank or code line let into a paragraph would bring only characters the
181
+ // structure mask blanks, so this test shapes the runs and changes no link.
182
+ const inParagraph = (i) => {
183
+ const line = lines[i];
184
+ return line !== undefined && isMarkdown(line) && !line.blank;
185
+ };
186
+ for (let first = 0; first < lines.length; first += 1) {
187
+ if (!inParagraph(first))
188
+ continue;
189
+ let last = first;
190
+ while (inParagraph(last + 1) && continues.has(last + 2))
191
+ last += 1;
192
+ const from = lines[first].start;
193
+ const to = lines[last].end;
194
+ const pairs = pairBrackets(structure, from, to);
195
+ let ends = null;
196
+ // Spaces and tabs, and at most one line ending inside the paragraph. The
197
+ // character at `to` ends the paragraph's last line and is none of these.
198
+ const skipSpace = (start) => {
199
+ let at = start;
200
+ while (isSpaceOrTab(structure, at))
201
+ at += 1;
202
+ if (at < to) {
203
+ if (structure.charCodeAt(at) === CR)
204
+ at += 1;
205
+ if (structure.charCodeAt(at) === LF)
206
+ at += 1;
207
+ while (isSpaceOrTab(structure, at))
208
+ at += 1;
209
+ }
210
+ return at;
211
+ };
212
+ const destination = (open) => {
213
+ const at = skipSpace(open);
214
+ let targetStart;
215
+ let targetEnd;
216
+ let after;
217
+ if (structure.charCodeAt(at) === LESS_THAN) {
218
+ // `<dest>`: no line ending and no unescaped `<` inside.
219
+ let close = at + 1;
220
+ for (;;) {
221
+ if (close >= to)
222
+ return null;
223
+ const ch = structure.charCodeAt(close);
224
+ if (ch === GREATER_THAN)
225
+ break;
226
+ if (ch === LESS_THAN || ch === LF || ch === CR)
227
+ return null;
228
+ close += ch === BACKSLASH ? 2 : 1;
229
+ }
230
+ targetStart = at + 1;
231
+ targetEnd = close;
232
+ after = close + 1;
233
+ }
234
+ else {
235
+ ends ??= endsOf(structure, from, to);
236
+ const space = ends.space[at - from];
237
+ const paren = ends.paren[at - from];
238
+ targetStart = at;
239
+ // The two are equal only when neither is found, at `to`.
240
+ targetEnd = paren < space ? paren : space;
241
+ after = targetEnd;
242
+ // An empty destination points nowhere a reader can follow.
243
+ if (targetEnd === at)
244
+ return null;
245
+ }
246
+ let k = skipSpace(after);
247
+ if (structure.charCodeAt(k) === CLOSE_PAREN)
248
+ return { targetStart, targetEnd, end: k + 1 };
249
+ // A title is separated from the destination by whitespace, and quoted.
250
+ if (k === after)
251
+ return null;
252
+ ends ??= endsOf(structure, from, to);
253
+ const x = k + 1 - from;
254
+ const quote = structure.charCodeAt(k);
255
+ let close;
256
+ if (quote === DOUBLE_QUOTE)
257
+ close = ends.doubleQuote[x];
258
+ else if (quote === SINGLE_QUOTE)
259
+ close = ends.singleQuote[x];
260
+ // A title in parentheses may not hold an unescaped `(`.
261
+ else if (quote === OPEN_PAREN)
262
+ close = ends.openParen[x] < ends.closeParen[x] ? to : ends.closeParen[x];
263
+ else
264
+ return null;
265
+ // Equal ends are `to`, where the title fails either way. Past `to` the
266
+ // next line opens a block of its own, and none opens with `)`.
267
+ if (close === to)
268
+ return null;
269
+ k = skipSpace(close + 1);
270
+ return structure.charCodeAt(k) === CLOSE_PAREN ? { targetStart, targetEnd, end: k + 1 } : null;
271
+ };
272
+ const wiki = (at, start, image, line) => {
273
+ if (structure.charCodeAt(at + 1) !== OPEN_BRACKET)
274
+ return null;
275
+ if (doubleClose !== -1 && doubleClose < at + 2)
276
+ doubleClose = structure.indexOf(']]', at + 2);
277
+ const close = doubleClose;
278
+ if (close < 0 || close + 2 > line.end)
279
+ return null;
280
+ const inner = text.slice(at + 2, close);
281
+ const written = inner.trim();
282
+ const pipe = written.indexOf('|');
283
+ const target = (pipe < 0 ? written : written.slice(0, pipe)).trim();
284
+ // `[[ ]]` and `[[|text]]` name nothing to link to.
285
+ if (target.length === 0)
286
+ return null;
287
+ const targetStart = at + 2 + inner.length - inner.trimStart().length;
288
+ return {
289
+ form: 'wiki',
290
+ image,
291
+ text: written,
292
+ target,
293
+ label: null,
294
+ start,
295
+ end: close + 2,
296
+ targetStart,
297
+ targetEnd: targetStart + target.length,
298
+ line: line.line,
299
+ };
300
+ };
301
+ const bracket = (at, start, image, line) => {
302
+ const close = pairs.get(at);
303
+ if (close === undefined)
304
+ return null;
305
+ const label = () => text.slice(at + 1, close).trim();
306
+ if (structure.charCodeAt(close + 1) === OPEN_PAREN) {
307
+ const dest = destination(close + 2);
308
+ if (dest !== null) {
309
+ const target = text.slice(dest.targetStart, dest.targetEnd);
310
+ return { form: 'inline', image, text: label(), target, label: null, start, line: line.line, ...dest };
311
+ }
312
+ }
313
+ else {
314
+ // Only a `[` is paired, so a second label follows exactly when this finds one.
315
+ const refClose = pairs.get(close + 1);
316
+ if (refClose !== undefined) {
317
+ // `[text][]` is read through its text; `[text][label]` through its label.
318
+ const collapsed = refClose - close - 2 <= MAX_LABEL && text.slice(close + 2, refClose).trim() === '';
319
+ const found = collapsed ? lookup(at + 1, close) : lookup(close + 2, refClose);
320
+ if (found === undefined)
321
+ return null;
322
+ const written = collapsed ? label() : text.slice(close + 2, refClose).trim();
323
+ return { form: 'reference', image, text: label(), label: written, start, end: refClose + 1, line: line.line, ...found };
324
+ }
325
+ }
326
+ // `[text](not a destination)` is a shortcut followed by text, as CommonMark reads it.
327
+ const found = lookup(at + 1, close);
328
+ if (found === undefined)
329
+ return null;
330
+ return { form: 'shortcut', image, text: label(), label: label(), start, end: close + 1, line: line.line, ...found };
331
+ };
332
+ let escaped = -1;
333
+ let at = from;
334
+ // Inside a link's text, up to its `]`, where CommonMark reads an image -
335
+ // a badge wrapped in a link - but no other link; then on past the link.
336
+ let textEnd = -1;
337
+ let resume = -1;
338
+ while (at < to) {
339
+ if (textEnd >= 0 && at >= textEnd) {
340
+ at = resume;
341
+ textEnd = -1;
342
+ continue;
343
+ }
344
+ const ch = structure.charCodeAt(at);
345
+ if (ch === BACKSLASH) {
346
+ escaped = at + 1;
347
+ at += 2;
348
+ continue;
349
+ }
350
+ if (ch !== OPEN_BRACKET) {
351
+ at += 1;
352
+ continue;
353
+ }
354
+ const line = lines[layout.index.positionAt(at).line - 1];
355
+ // A definition's line holds its label, its destination and its title,
356
+ // and none of them is a link.
357
+ if (defined.has(line.line)) {
358
+ at = line.end;
359
+ continue;
360
+ }
361
+ const image = structure.charCodeAt(at - 1) === BANG && escaped !== at - 1;
362
+ const start = image ? at - 1 : at;
363
+ const link = wiki(at, start, image, line) ?? bracket(at, start, image, line);
364
+ if (textEnd >= 0) {
365
+ // An image that closes inside the text; its own text is alt text, and
366
+ // holds nothing a reader follows.
367
+ if (link !== null && link.image && link.form !== 'wiki' && link.end <= textEnd) {
368
+ out.push(link);
369
+ at = link.end;
370
+ }
371
+ else {
372
+ at += 1;
373
+ }
374
+ }
375
+ else if (link === null) {
376
+ at += 1;
377
+ }
378
+ else {
379
+ out.push(link);
380
+ if (!link.image && link.form !== 'wiki') {
381
+ textEnd = pairs.get(at);
382
+ resume = link.end;
383
+ at += 1;
384
+ }
385
+ else {
386
+ at = link.end;
387
+ }
388
+ }
389
+ }
390
+ first = last;
391
+ }
392
+ return out;
393
+ }
394
+ //# sourceMappingURL=links.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"links.js","sourceRoot":"","sources":["../../../../src/vendor/spec-core/markdown/links.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Links, images and reference definitions, read from the structure mask so\n * that nothing in code or a comment is one.\n *\n * Six forms: inline `[text](dest \"title\")`, full and collapsed reference\n * `[text][label]` and `[label][]`, shortcut `[label]`, autolink `<https://x>`,\n * wiki `[[target|text]]`, and the definition `[label]: dest` the reference\n * forms are read through. Each may be an image, written with a leading `!`.\n * A link's text is read again for images, which CommonMark renders there - a\n * badge wrapped in a link has two destinations - and for nothing else; each\n * is listed after the link it lies in.\n *\n * Brackets are paired once per paragraph with a stack, and the tables that\n * say where a destination or a title ends are built once per paragraph, so\n * no bracket searches the text again for its partner. A document of nothing\n * but brackets costs its length.\n *\n * A paragraph ends at `to`, and the character there is a line terminator,\n * which no loop here acts on; nor is any lookup made at the first three\n * offsets of a paragraph, before the shortest `[](` could end. Mutants that\n * move a bound onto those places change no answer, and are equivalent.\n */\n\nimport { inRanges, mergeRanges } from '../text/index.js';\nimport { isMarkdown, isSpaceOrTab, visibleLead, type Layout } from './layout.js';\nimport type { Link, ScannedLine } from './types.js';\n\nconst BANG = 33;\nconst DOUBLE_QUOTE = 34;\nconst SINGLE_QUOTE = 39;\nconst OPEN_PAREN = 40;\nconst CLOSE_PAREN = 41;\nconst LESS_THAN = 60;\nconst GREATER_THAN = 62;\nconst OPEN_BRACKET = 91;\nconst BACKSLASH = 92;\nconst CLOSE_BRACKET = 93;\nconst LF = 10;\nconst CR = 13;\n\n/** CommonMark: a link label holds at most 999 characters. */\nconst MAX_LABEL = 999;\n\nconst DEFINITION = /^ {0,3}\\[(?!\\^)([^\\]]+)\\]:[ \\t]*(<[^<>]*>|\\S+)/;\n/** What may follow a definition's destination: nothing, or a title after whitespace. */\nconst TITLE_ONLY = /^(?:[ \\t]+(?:\"[^\"]*\"|'[^']*'|\\([^)]*\\)))?[ \\t]*$/;\nconst AUTOLINK = /<((?:https?|ftp|mailto):[^<>\\s]+)>/g;\n\ninterface Definition {\n readonly target: string;\n readonly targetStart: number;\n readonly targetEnd: number;\n}\n\nexport function findLinks(layout: Layout): Link[] {\n const definitions = new Map<string, Definition>();\n const defined = readDefinitions(layout, definitions);\n const bracketed = readBrackets(layout, definitions, new Set(defined.map((d) => d.line)));\n // `<https://x>` as a link's destination or text is part of that link.\n const taken = mergeRanges([...defined, ...bracketed]);\n const autolinks = readAutolinks(layout).filter((link) => !inRanges(taken, link.start));\n return [...defined, ...bracketed, ...autolinks].sort((a, b) => a.start - b.start);\n}\n\n/**\n * How labels compare: trimmed, whitespace collapsed, and case folded as\n * CommonMark's reference implementations fold it, down and then up, so that\n * `ẞ` and `SS` are one label.\n */\nfunction normalizeLabel(label: string): string {\n return label.trim().replace(/\\s+/g, ' ').toLowerCase().toUpperCase();\n}\n\n/**\n * Definitions come first: the reference forms are read through them, and a\n * definition is conventionally written at the foot of the file, after the\n * links that use it. The first definition of a label wins.\n *\n * `[Note]: this matters` is prose that looks like one, so a definition has\n * nothing after its destination but a title. `[^1]: text` is a footnote.\n */\nfunction readDefinitions(layout: Layout, definitions: Map<string, Definition>): Link[] {\n const { text, structure } = layout;\n const out: Link[] = [];\n for (const line of layout.lines) {\n if (!isMarkdown(line) || !visibleLead(layout, line)) continue;\n const masked = structure.slice(line.contentStart, line.end);\n const match = DEFINITION.exec(masked);\n if (match === null || !TITLE_ONLY.test(masked.slice(match[0].length))) continue;\n const start = line.contentStart + match[0].indexOf('[');\n const label = text.slice(start + 1, start + 1 + (match[1] as string).length).trim();\n if (label.length === 0) continue;\n const written = match[2] as string;\n const end = line.contentStart + match[0].length;\n const angle = written.charCodeAt(0) === LESS_THAN ? 1 : 0;\n const targetStart = end - written.length + angle;\n const targetEnd = end - angle;\n const target = text.slice(targetStart, targetEnd);\n const key = normalizeLabel(label);\n if (!definitions.has(key)) definitions.set(key, { target, targetStart, targetEnd });\n out.push({ form: 'definition', image: false, text: label, target, label, start, end, targetStart, targetEnd, line: line.line });\n }\n return out;\n}\n\nfunction readAutolinks(layout: Layout): Link[] {\n const out: Link[] = [];\n for (const match of layout.structure.matchAll(AUTOLINK)) {\n const start = match.index;\n const end = start + match[0].length;\n out.push({\n form: 'autolink',\n image: false,\n text: '',\n target: match[1] as string,\n label: null,\n start,\n end,\n targetStart: start + 1,\n targetEnd: end - 1,\n line: layout.index.positionAt(start).line,\n });\n }\n return out;\n}\n\n/** Pairs `[` with `]` inside a paragraph, innermost first, skipping escaped ones. */\nfunction pairBrackets(structure: string, from: number, to: number): Map<number, number> {\n const pairs = new Map<number, number>();\n const open: number[] = [];\n for (let at = from; at < to; at += 1) {\n const ch = structure.charCodeAt(at);\n if (ch === BACKSLASH) at += 1;\n else if (ch === OPEN_BRACKET) open.push(at);\n else if (ch === CLOSE_BRACKET) {\n // A `]` with nothing to close pairs with nothing; recorded under\n // `undefined` it would not be found either, so this test changes no\n // answer, only what the map holds.\n const opened = open.pop();\n if (opened !== undefined) pairs.set(opened, at);\n }\n }\n return pairs;\n}\n\n/**\n * For every offset of a paragraph, where what starts there ends, or the end\n * of the paragraph when nothing does: a bare destination at the next space or\n * control character, or at the first `)` its own parentheses leave unmatched;\n * a title at its next unescaped closing quote or parenthesis. Filled from the\n * right in one pass, so every lookup is a read.\n */\ninterface Ends {\n readonly space: Int32Array;\n readonly paren: Int32Array;\n readonly doubleQuote: Int32Array;\n readonly singleQuote: Int32Array;\n readonly closeParen: Int32Array;\n readonly openParen: Int32Array;\n}\n\nfunction endsOf(structure: string, from: number, to: number): Ends {\n const length = to - from;\n const escaped = new Uint8Array(length + 1);\n for (let x = 0; x < length; x += 1) {\n if (escaped[x] === 0 && structure.charCodeAt(from + x) === BACKSLASH) escaped[x + 1] = 1;\n }\n // Two past the last offset: a `(` whose `)` is the paragraph's last\n // character looks one further for the next unmatched `)`, and finds none.\n const make = (): Int32Array => new Int32Array(length + 2).fill(to);\n const ends: Ends = { space: make(), paren: make(), doubleQuote: make(), singleQuote: make(), closeParen: make(), openParen: make() };\n for (let x = length - 1; x >= 0; x -= 1) {\n const at = from + x;\n const ch = structure.charCodeAt(at);\n const plain = escaped[x] === 0;\n ends.space[x] = ch <= 32 || ch === 127 ? at : (ends.space[x + 1] as number);\n // From a `(`, the first unmatched `)` is the first one after the `)` that\n // closes it, which is the first unmatched `)` after the `(`.\n const unmatched = ends.paren[x + 1] as number;\n if (plain && ch === CLOSE_PAREN) ends.paren[x] = at;\n else if (plain && ch === OPEN_PAREN) ends.paren[x] = ends.paren[unmatched + 1 - from] as number;\n else ends.paren[x] = unmatched;\n ends.doubleQuote[x] = plain && ch === DOUBLE_QUOTE ? at : (ends.doubleQuote[x + 1] as number);\n ends.singleQuote[x] = plain && ch === SINGLE_QUOTE ? at : (ends.singleQuote[x + 1] as number);\n ends.closeParen[x] = plain && ch === CLOSE_PAREN ? at : (ends.closeParen[x + 1] as number);\n ends.openParen[x] = plain && ch === OPEN_PAREN ? at : (ends.openParen[x + 1] as number);\n }\n return ends;\n}\n\ninterface Destination {\n readonly targetStart: number;\n readonly targetEnd: number;\n /** Offset just past the closing `)`. */\n readonly end: number;\n}\n\n/**\n * The bracket forms, a paragraph at a time. A paragraph here is a run of\n * Markdown lines, none blank, each continuing the one above: a bracket never\n * pairs across a blank line, a heading, or the start of another block.\n */\nfunction readBrackets(layout: Layout, definitions: ReadonlyMap<string, Definition>, defined: ReadonlySet<number>): Link[] {\n const { lines, continues, structure, text } = layout;\n const out: Link[] = [];\n // The first `]]` at or after the last place one was looked for; the cursor\n // only moves forward, so each is found once.\n let doubleClose = -2;\n\n const lookup = (from: number, to: number): Definition | undefined =>\n to - from > MAX_LABEL ? undefined : definitions.get(normalizeLabel(text.slice(from, to)));\n\n // A blank or code line let into a paragraph would bring only characters the\n // structure mask blanks, so this test shapes the runs and changes no link.\n const inParagraph = (i: number): boolean => {\n const line = lines[i];\n return line !== undefined && isMarkdown(line) && !line.blank;\n };\n\n for (let first = 0; first < lines.length; first += 1) {\n if (!inParagraph(first)) continue;\n let last = first;\n while (inParagraph(last + 1) && continues.has(last + 2)) last += 1;\n const from = (lines[first] as ScannedLine).start;\n const to = (lines[last] as ScannedLine).end;\n const pairs = pairBrackets(structure, from, to);\n let ends: Ends | null = null;\n\n // Spaces and tabs, and at most one line ending inside the paragraph. The\n // character at `to` ends the paragraph's last line and is none of these.\n const skipSpace = (start: number): number => {\n let at = start;\n while (isSpaceOrTab(structure, at)) at += 1;\n if (at < to) {\n if (structure.charCodeAt(at) === CR) at += 1;\n if (structure.charCodeAt(at) === LF) at += 1;\n while (isSpaceOrTab(structure, at)) at += 1;\n }\n return at;\n };\n\n const destination = (open: number): Destination | null => {\n const at = skipSpace(open);\n let targetStart: number;\n let targetEnd: number;\n let after: number;\n if (structure.charCodeAt(at) === LESS_THAN) {\n // `<dest>`: no line ending and no unescaped `<` inside.\n let close = at + 1;\n for (;;) {\n if (close >= to) return null;\n const ch = structure.charCodeAt(close);\n if (ch === GREATER_THAN) break;\n if (ch === LESS_THAN || ch === LF || ch === CR) return null;\n close += ch === BACKSLASH ? 2 : 1;\n }\n targetStart = at + 1;\n targetEnd = close;\n after = close + 1;\n } else {\n ends ??= endsOf(structure, from, to);\n const space = ends.space[at - from] as number;\n const paren = ends.paren[at - from] as number;\n targetStart = at;\n // The two are equal only when neither is found, at `to`.\n targetEnd = paren < space ? paren : space;\n after = targetEnd;\n // An empty destination points nowhere a reader can follow.\n if (targetEnd === at) return null;\n }\n let k = skipSpace(after);\n if (structure.charCodeAt(k) === CLOSE_PAREN) return { targetStart, targetEnd, end: k + 1 };\n // A title is separated from the destination by whitespace, and quoted.\n if (k === after) return null;\n ends ??= endsOf(structure, from, to);\n const x = k + 1 - from;\n const quote = structure.charCodeAt(k);\n let close: number;\n if (quote === DOUBLE_QUOTE) close = ends.doubleQuote[x] as number;\n else if (quote === SINGLE_QUOTE) close = ends.singleQuote[x] as number;\n // A title in parentheses may not hold an unescaped `(`.\n else if (quote === OPEN_PAREN) close = (ends.openParen[x] as number) < (ends.closeParen[x] as number) ? to : (ends.closeParen[x] as number);\n else return null;\n // Equal ends are `to`, where the title fails either way. Past `to` the\n // next line opens a block of its own, and none opens with `)`.\n if (close === to) return null;\n k = skipSpace(close + 1);\n return structure.charCodeAt(k) === CLOSE_PAREN ? { targetStart, targetEnd, end: k + 1 } : null;\n };\n\n const wiki = (at: number, start: number, image: boolean, line: ScannedLine): Link | null => {\n if (structure.charCodeAt(at + 1) !== OPEN_BRACKET) return null;\n if (doubleClose !== -1 && doubleClose < at + 2) doubleClose = structure.indexOf(']]', at + 2);\n const close = doubleClose;\n if (close < 0 || close + 2 > line.end) return null;\n const inner = text.slice(at + 2, close);\n const written = inner.trim();\n const pipe = written.indexOf('|');\n const target = (pipe < 0 ? written : written.slice(0, pipe)).trim();\n // `[[ ]]` and `[[|text]]` name nothing to link to.\n if (target.length === 0) return null;\n const targetStart = at + 2 + inner.length - inner.trimStart().length;\n return {\n form: 'wiki',\n image,\n text: written,\n target,\n label: null,\n start,\n end: close + 2,\n targetStart,\n targetEnd: targetStart + target.length,\n line: line.line,\n };\n };\n\n const bracket = (at: number, start: number, image: boolean, line: ScannedLine): Link | null => {\n const close = pairs.get(at);\n if (close === undefined) return null;\n const label = (): string => text.slice(at + 1, close).trim();\n if (structure.charCodeAt(close + 1) === OPEN_PAREN) {\n const dest = destination(close + 2);\n if (dest !== null) {\n const target = text.slice(dest.targetStart, dest.targetEnd);\n return { form: 'inline', image, text: label(), target, label: null, start, line: line.line, ...dest };\n }\n } else {\n // Only a `[` is paired, so a second label follows exactly when this finds one.\n const refClose = pairs.get(close + 1);\n if (refClose !== undefined) {\n // `[text][]` is read through its text; `[text][label]` through its label.\n const collapsed = refClose - close - 2 <= MAX_LABEL && text.slice(close + 2, refClose).trim() === '';\n const found = collapsed ? lookup(at + 1, close) : lookup(close + 2, refClose);\n if (found === undefined) return null;\n const written = collapsed ? label() : text.slice(close + 2, refClose).trim();\n return { form: 'reference', image, text: label(), label: written, start, end: refClose + 1, line: line.line, ...found };\n }\n }\n // `[text](not a destination)` is a shortcut followed by text, as CommonMark reads it.\n const found = lookup(at + 1, close);\n if (found === undefined) return null;\n return { form: 'shortcut', image, text: label(), label: label(), start, end: close + 1, line: line.line, ...found };\n };\n\n let escaped = -1;\n let at = from;\n // Inside a link's text, up to its `]`, where CommonMark reads an image -\n // a badge wrapped in a link - but no other link; then on past the link.\n let textEnd = -1;\n let resume = -1;\n while (at < to) {\n if (textEnd >= 0 && at >= textEnd) {\n at = resume;\n textEnd = -1;\n continue;\n }\n const ch = structure.charCodeAt(at);\n if (ch === BACKSLASH) {\n escaped = at + 1;\n at += 2;\n continue;\n }\n if (ch !== OPEN_BRACKET) {\n at += 1;\n continue;\n }\n const line = lines[layout.index.positionAt(at).line - 1] as ScannedLine;\n // A definition's line holds its label, its destination and its title,\n // and none of them is a link.\n if (defined.has(line.line)) {\n at = line.end;\n continue;\n }\n const image = structure.charCodeAt(at - 1) === BANG && escaped !== at - 1;\n const start = image ? at - 1 : at;\n const link = wiki(at, start, image, line) ?? bracket(at, start, image, line);\n if (textEnd >= 0) {\n // An image that closes inside the text; its own text is alt text, and\n // holds nothing a reader follows.\n if (link !== null && link.image && link.form !== 'wiki' && link.end <= textEnd) {\n out.push(link);\n at = link.end;\n } else {\n at += 1;\n }\n } else if (link === null) {\n at += 1;\n } else {\n out.push(link);\n if (!link.image && link.form !== 'wiki') {\n textEnd = pairs.get(at) as number;\n resume = link.end;\n at += 1;\n } else {\n at = link.end;\n }\n }\n }\n first = last;\n }\n return out;\n}\n"]}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * List items, as blocks rather than lines.
3
+ *
4
+ * An item owns what is nested under it - anything indented past its marker -
5
+ * and its lazy continuation lines: text directly under it, with no blank line
6
+ * between, that opens nothing of its own. So a resolution written on the
7
+ * second line of a bullet is found instead of missed, and a fenced example
8
+ * nested under an item is the item's.
9
+ *
10
+ * The items open at a line are kept on a stack, innermost last, and each line
11
+ * closes items from the top. Every item is opened and closed once, so the
12
+ * pass is linear however deep the nesting.
13
+ */
14
+ import { type Layout } from './layout.js';
15
+ import type { Heading, ListItem } from './types.js';
16
+ /**
17
+ * Items end where CommonMark's do, near enough: at a heading; at a line no
18
+ * deeper than the marker after a blank line; and at a line no deeper than the
19
+ * marker that opens something - another item, a block quote, a thematic
20
+ * break, a fence. A block of code is owned whole or not at all.
21
+ */
22
+ export declare function findListItems(layout: Layout, headings: readonly Heading[]): ListItem[];
@@ -0,0 +1,127 @@
1
+ /**
2
+ * List items, as blocks rather than lines.
3
+ *
4
+ * An item owns what is nested under it - anything indented past its marker -
5
+ * and its lazy continuation lines: text directly under it, with no blank line
6
+ * between, that opens nothing of its own. So a resolution written on the
7
+ * second line of a bullet is found instead of missed, and a fenced example
8
+ * nested under an item is the item's.
9
+ *
10
+ * The items open at a line are kept on a stack, innermost last, and each line
11
+ * closes items from the top. Every item is opened and closed once, so the
12
+ * pass is linear however deep the nesting.
13
+ */
14
+ import { visibleLead } from './layout.js';
15
+ import { isThematicBreak, listMarker, measureIndentAt, stripQuotes } from './syntax.js';
16
+ const CHECKBOX = /^\[([ xX~\-?!*/+])\](?=[ \t]|$)/;
17
+ /**
18
+ * Items end where CommonMark's do, near enough: at a heading; at a line no
19
+ * deeper than the marker after a blank line; and at a line no deeper than the
20
+ * marker that opens something - another item, a block quote, a thematic
21
+ * break, a fence. A block of code is owned whole or not at all.
22
+ */
23
+ export function findListItems(layout, headings) {
24
+ const { lines, text, structure, blocks } = layout;
25
+ const heading = new Set();
26
+ for (const h of headings)
27
+ for (let line = h.line; line <= h.endLine; line += 1)
28
+ heading.add(line);
29
+ const items = [];
30
+ const stack = [];
31
+ // Whether a blank line came since the last line read. Its first value is
32
+ // never asked for: no item is open before a marker line, which clears it.
33
+ let sawBlank = false;
34
+ // The last line every open item owns: each owns every line it has not been closed by.
35
+ let lastEnd = 0;
36
+ let lastLine = 0;
37
+ let block = 0;
38
+ const closeWhile = (closes) => {
39
+ for (let top = stack[stack.length - 1]; top !== undefined && closes(top); top = stack[stack.length - 1]) {
40
+ top.end = lastEnd;
41
+ top.endLine = lastLine;
42
+ stack.pop();
43
+ }
44
+ };
45
+ // Front matter is blank in the structure mask, so no marker is visible in it.
46
+ for (let i = 0; i < lines.length; i += 1) {
47
+ const line = lines[i];
48
+ // A blank line inside a block of code is skipped with the block.
49
+ if (line.blank) {
50
+ sawBlank = true;
51
+ continue;
52
+ }
53
+ // No item is open after a heading, so whether a blank line came before it
54
+ // is never asked.
55
+ if (heading.has(line.line)) {
56
+ closeWhile(() => true);
57
+ continue;
58
+ }
59
+ if (line.code || line.html) {
60
+ while (blocks[block].endLine < line.line)
61
+ block += 1;
62
+ const owned = blocks[block];
63
+ closeWhile((item) => indentFor(text, line, item) <= item.indent);
64
+ lastEnd = owned.end;
65
+ lastLine = owned.endLine;
66
+ i = owned.endLine - 1;
67
+ sawBlank = false;
68
+ continue;
69
+ }
70
+ const marker = visibleLead(layout, line) ? listMarker(line.content) : null;
71
+ const opens = marker !== null || (visibleLead(layout, line) && isThematicBreak(line.content));
72
+ closeWhile((item) => {
73
+ if (indentFor(text, line, item) > item.indent)
74
+ return false;
75
+ return sawBlank || opens || line.quoteDepth > item.quoteDepth;
76
+ });
77
+ lastEnd = line.end;
78
+ lastLine = line.line;
79
+ sawBlank = false;
80
+ if (marker === null)
81
+ continue;
82
+ const markerStart = line.contentStart + marker.offset;
83
+ let textStart = markerStart + marker.width;
84
+ const box = CHECKBOX.exec(structure.slice(textStart, line.end));
85
+ const checkboxStart = box === null ? null : textStart;
86
+ if (box !== null) {
87
+ // The character at the end of the line is its terminator, not a space.
88
+ textStart += 3;
89
+ while (text.charCodeAt(textStart) === 32 || text.charCodeAt(textStart) === 9)
90
+ textStart += 1;
91
+ }
92
+ const item = {
93
+ start: line.contentStart,
94
+ end: line.end,
95
+ markerStart,
96
+ marker: marker.marker,
97
+ textStart,
98
+ checkbox: box === null ? null : box[1],
99
+ checkboxStart,
100
+ firstLine: text.slice(textStart, line.end).trim(),
101
+ line: line.line,
102
+ endLine: line.line,
103
+ depth: stack.length,
104
+ indent: line.indent,
105
+ quoteDepth: line.quoteDepth,
106
+ };
107
+ items.push(item);
108
+ stack.push(item);
109
+ }
110
+ closeWhile(() => true);
111
+ return items.map((item) => ({
112
+ ...item,
113
+ body: text.slice(item.textStart, item.end),
114
+ maskedBody: structure.slice(item.textStart, item.end),
115
+ }));
116
+ }
117
+ /**
118
+ * A line's indentation as an item sees it: measured inside the item's block
119
+ * quote. A line quoted deeper than the item is measured up to its extra `>`,
120
+ * so a quote nested under an item is nested, and one at the item's own
121
+ * indentation opens a block quote beside it.
122
+ */
123
+ function indentFor(text, line, item) {
124
+ const q = stripQuotes(text, line.start, item.quoteDepth);
125
+ return measureIndentAt(text, q.contentStart, line.end);
126
+ }
127
+ //# sourceMappingURL=lists.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lists.js","sourceRoot":"","sources":["../../../../src/vendor/spec-core/markdown/lists.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * List items, as blocks rather than lines.\n *\n * An item owns what is nested under it - anything indented past its marker -\n * and its lazy continuation lines: text directly under it, with no blank line\n * between, that opens nothing of its own. So a resolution written on the\n * second line of a bullet is found instead of missed, and a fenced example\n * nested under an item is the item's.\n *\n * The items open at a line are kept on a stack, innermost last, and each line\n * closes items from the top. Every item is opened and closed once, so the\n * pass is linear however deep the nesting.\n */\n\nimport { visibleLead, type Layout } from './layout.js';\nimport { isThematicBreak, listMarker, measureIndentAt, stripQuotes } from './syntax.js';\nimport type { Block, Heading, ListItem, ScannedLine } from './types.js';\n\nconst CHECKBOX = /^\\[([ xX~\\-?!*/+])\\](?=[ \\t]|$)/;\n\ntype Draft = { -readonly [K in Exclude<keyof ListItem, 'body' | 'maskedBody'>]: ListItem[K] };\n\n/**\n * Items end where CommonMark's do, near enough: at a heading; at a line no\n * deeper than the marker after a blank line; and at a line no deeper than the\n * marker that opens something - another item, a block quote, a thematic\n * break, a fence. A block of code is owned whole or not at all.\n */\nexport function findListItems(layout: Layout, headings: readonly Heading[]): ListItem[] {\n const { lines, text, structure, blocks } = layout;\n const heading = new Set<number>();\n for (const h of headings) for (let line = h.line; line <= h.endLine; line += 1) heading.add(line);\n\n const items: Draft[] = [];\n const stack: Draft[] = [];\n // Whether a blank line came since the last line read. Its first value is\n // never asked for: no item is open before a marker line, which clears it.\n let sawBlank = false;\n // The last line every open item owns: each owns every line it has not been closed by.\n let lastEnd = 0;\n let lastLine = 0;\n let block = 0;\n\n const closeWhile = (closes: (item: Draft) => boolean): void => {\n for (let top = stack[stack.length - 1]; top !== undefined && closes(top); top = stack[stack.length - 1]) {\n top.end = lastEnd;\n top.endLine = lastLine;\n stack.pop();\n }\n };\n\n // Front matter is blank in the structure mask, so no marker is visible in it.\n for (let i = 0; i < lines.length; i += 1) {\n const line = lines[i] as ScannedLine;\n // A blank line inside a block of code is skipped with the block.\n if (line.blank) {\n sawBlank = true;\n continue;\n }\n // No item is open after a heading, so whether a blank line came before it\n // is never asked.\n if (heading.has(line.line)) {\n closeWhile(() => true);\n continue;\n }\n\n if (line.code || line.html) {\n while ((blocks[block] as Block).endLine < line.line) block += 1;\n const owned = blocks[block] as Block;\n closeWhile((item) => indentFor(text, line, item) <= item.indent);\n lastEnd = owned.end;\n lastLine = owned.endLine;\n i = owned.endLine - 1;\n sawBlank = false;\n continue;\n }\n\n const marker = visibleLead(layout, line) ? listMarker(line.content) : null;\n const opens = marker !== null || (visibleLead(layout, line) && isThematicBreak(line.content));\n closeWhile((item) => {\n if (indentFor(text, line, item) > item.indent) return false;\n return sawBlank || opens || line.quoteDepth > item.quoteDepth;\n });\n lastEnd = line.end;\n lastLine = line.line;\n sawBlank = false;\n if (marker === null) continue;\n\n const markerStart = line.contentStart + marker.offset;\n let textStart = markerStart + marker.width;\n const box = CHECKBOX.exec(structure.slice(textStart, line.end));\n const checkboxStart = box === null ? null : textStart;\n if (box !== null) {\n // The character at the end of the line is its terminator, not a space.\n textStart += 3;\n while (text.charCodeAt(textStart) === 32 || text.charCodeAt(textStart) === 9) textStart += 1;\n }\n const item: Draft = {\n start: line.contentStart,\n end: line.end,\n markerStart,\n marker: marker.marker,\n textStart,\n checkbox: box === null ? null : (box[1] as string),\n checkboxStart,\n firstLine: text.slice(textStart, line.end).trim(),\n line: line.line,\n endLine: line.line,\n depth: stack.length,\n indent: line.indent,\n quoteDepth: line.quoteDepth,\n };\n items.push(item);\n stack.push(item);\n }\n closeWhile(() => true);\n\n return items.map((item) => ({\n ...item,\n body: text.slice(item.textStart, item.end),\n maskedBody: structure.slice(item.textStart, item.end),\n }));\n}\n\n/**\n * A line's indentation as an item sees it: measured inside the item's block\n * quote. A line quoted deeper than the item is measured up to its extra `>`,\n * so a quote nested under an item is nested, and one at the item's own\n * indentation opens a block quote beside it.\n */\nfunction indentFor(text: string, line: ScannedLine, item: Draft): number {\n const q = stripQuotes(text, line.start, item.quoteDepth);\n return measureIndentAt(text, q.contentStart, line.end);\n}\n"]}