lens-content-processor 0.48.0 → 0.50.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.
Files changed (56) hide show
  1. package/dist/bundler/article.d.ts +51 -45
  2. package/dist/bundler/article.js +106 -50
  3. package/dist/bundler/article.js.map +1 -1
  4. package/dist/content-schema.d.ts +22 -0
  5. package/dist/content-schema.js +58 -29
  6. package/dist/content-schema.js.map +1 -1
  7. package/dist/flattener/index.js +69 -77
  8. package/dist/flattener/index.js.map +1 -1
  9. package/dist/flattener/test-helpers.js +1 -0
  10. package/dist/flattener/test-helpers.js.map +1 -1
  11. package/dist/index.d.ts +24 -5
  12. package/dist/index.js +19 -6
  13. package/dist/index.js.map +1 -1
  14. package/dist/parser/article-elements.d.ts +139 -0
  15. package/dist/parser/article-elements.js +489 -0
  16. package/dist/parser/article-elements.js.map +1 -0
  17. package/dist/parser/article.d.ts +4 -0
  18. package/dist/parser/article.js +7 -4
  19. package/dist/parser/article.js.map +1 -1
  20. package/dist/parser/code-fence.d.ts +7 -0
  21. package/dist/parser/code-fence.js +34 -0
  22. package/dist/parser/code-fence.js.map +1 -0
  23. package/dist/parser/frames.d.ts +51 -0
  24. package/dist/parser/frames.js +116 -0
  25. package/dist/parser/frames.js.map +1 -0
  26. package/dist/parser/learning-outcome.js +4 -2
  27. package/dist/parser/learning-outcome.js.map +1 -1
  28. package/dist/parser/lens.d.ts +40 -6
  29. package/dist/parser/lens.js +56 -72
  30. package/dist/parser/lens.js.map +1 -1
  31. package/dist/parser/module.js +7 -27
  32. package/dist/parser/module.js.map +1 -1
  33. package/dist/parser/response-segments.d.ts +16 -32
  34. package/dist/parser/response-segments.js +24 -11
  35. package/dist/parser/response-segments.js.map +1 -1
  36. package/dist/parser/sections.d.ts +21 -1
  37. package/dist/parser/sections.js +94 -14
  38. package/dist/parser/sections.js.map +1 -1
  39. package/dist/parser/survey.js +9 -5
  40. package/dist/parser/survey.js.map +1 -1
  41. package/dist/source-location.js +6 -1
  42. package/dist/source-location.js.map +1 -1
  43. package/dist/validator/article-structure.js +24 -4
  44. package/dist/validator/article-structure.js.map +1 -1
  45. package/dist/validator/directives.js +61 -58
  46. package/dist/validator/directives.js.map +1 -1
  47. package/dist/validator/test-segments.d.ts +6 -6
  48. package/dist/validator/test-segments.js +7 -7
  49. package/dist/validator/test-segments.js.map +1 -1
  50. package/dist/validator/tier.d.ts +2 -2
  51. package/dist/validator/tier.js +20 -18
  52. package/dist/validator/tier.js.map +1 -1
  53. package/package.json +1 -1
  54. package/dist/validator/article-imports.d.ts +0 -68
  55. package/dist/validator/article-imports.js +0 -265
  56. package/dist/validator/article-imports.js.map +0 -1
@@ -0,0 +1,489 @@
1
+ import { parseTimestamp } from "../bundler/video.js";
2
+ import { isValidHeight } from "./widget.js";
3
+ import { parseFields } from "./sections.js";
4
+ import { calloutFrame } from "./frames.js";
5
+ import { makeFenceTracker } from "./code-fence.js";
6
+ import { convertSegment, validateRawSegment, } from "./lens.js";
7
+ import { RESPONSE_QUESTION_SUBTYPES, SUBTYPE_DISPLAY, } from "./response-segments.js";
8
+ // ::video{attr}[[path|alias]] or ::video[[path|alias]]{attr}, anchored to a
9
+ // full (trimmed) line. Alias is accepted for wikilink-tooling compatibility
10
+ // but unused — the display title comes from the transcript frontmatter.
11
+ const VIDEO_IMPORT_LINE_RE = /^::video(?:\{([^}]*)\})?\[\[([^\]|]+)(?:\|[^\]]+)?\]\](?:\{([^}]*)\})?$/;
12
+ // Anything that looks like an attempted ::video import (used to flag
13
+ // malformed/misplaced usages without false-positives on prose that merely
14
+ // mentions "::video").
15
+ const VIDEO_IMPORT_CANDIDATE_RE = /::video[[{]/;
16
+ // ![[path]] or ![[path|modifier]], anchored to a full (trimmed) line.
17
+ const WIDGET_EMBED_LINE_RE = /^!\[\[([^\]|]+)(?:\|([^\]]*))?\]\]$/;
18
+ // Every ![[...]] on a line; the target decides whether it is a widget embed.
19
+ const WIDGET_EMBED_CANDIDATE_RE = /!\[\[([^\]|]+)(?:\|[^\]]*)?\]\]/g;
20
+ // A file directly under a widgets/ folder, written relative to the article
21
+ // (`../widgets/name`) or to the vault root (`widgets/name`), no fragment.
22
+ const WIDGET_TARGET_RE = /^(?:\.\.?\/)*widgets\/[^/#|]+$/;
23
+ // Inline code is not prose: an element mentioned in backticks is neither an
24
+ // element nor a mistake.
25
+ const INLINE_CODE_RE = /`[^`]*`/g;
26
+ // Container directive lines, shared with the directive validator so both
27
+ // agree on what is a container. Like any block, up to three spaces of indent
28
+ // (more is an indented code block); nothing may follow the attributes.
29
+ export const CONTAINER_OPEN = /^ {0,3}(:{3,})([\w-]+)(?:\s*\{([^}]*)\})?\s*$/;
30
+ /** A `:::name` line that fails CONTAINER_OPEN (trailing text): markdown
31
+ * renders it as prose, so the validator reports it. */
32
+ export const CONTAINER_OPEN_LOOSE = /^ {0,3}(:{3,})([\w-]+)/;
33
+ /** A closing marker; the optional `{…}` is an authoring mistake. */
34
+ export const CONTAINER_CLOSE = /^ {0,3}(:{3,})\s*(?:\{([^}]*)\})?\s*$/;
35
+ /** The `:::callout{…}` attributes: the callout segment's fields plus its title. */
36
+ export const CALLOUT_ATTRIBUTES = ["title", "tone", "collapse"];
37
+ /** Element kinds, with the error-code stem and author-facing label of each. */
38
+ export const ARTICLE_ELEMENT_KINDS = {
39
+ video: { code: "video-import", label: "::video import" },
40
+ widget: { code: "widget-embed", label: "widget embed" },
41
+ question: { code: "question-block", label: ":::question block" },
42
+ };
43
+ /**
44
+ * Parse `key="value" …` directive attributes into fields. `allowed` closes
45
+ * the key set: directives have no typo detector, so an unknown key is
46
+ * reported rather than silently ignored. Every problem is reported and the
47
+ * well-formed attributes are kept, so a validator lists them all and a
48
+ * callout with one stray attribute still renders its title and tone.
49
+ */
50
+ export function parseDirectiveAttributes(attr, allowed) {
51
+ const fields = {};
52
+ const problems = [];
53
+ if (attr === undefined || attr.trim() === "")
54
+ return { fields, problems };
55
+ const tokens = [...attr.matchAll(/([\w-]+)\s*=\s*"([^"]*)"/g)];
56
+ const consumed = tokens.map((m) => m[0]).join(" ");
57
+ if (consumed.replace(/\s+/g, " ").trim() !== attr.replace(/\s+/g, " ").trim()) {
58
+ problems.push({
59
+ kind: "syntax",
60
+ reason: `invalid attributes '{${attr}}'`,
61
+ suggestion: `Use key="value" attributes: ${allowed.join(", ")}`,
62
+ });
63
+ return { fields, problems };
64
+ }
65
+ for (const token of tokens) {
66
+ const key = token[1];
67
+ if (!allowed.includes(key)) {
68
+ problems.push({
69
+ kind: "unknown",
70
+ key,
71
+ reason: `unrecognized attribute '${key}'`,
72
+ suggestion: `Only ${allowed.join(" and ")} attributes are supported`,
73
+ });
74
+ }
75
+ else if (key in fields) {
76
+ problems.push({
77
+ kind: "duplicate",
78
+ key,
79
+ reason: `duplicate attribute '${key}'`,
80
+ suggestion: `Keep only one ${key} attribute`,
81
+ });
82
+ }
83
+ else {
84
+ fields[key] = token[2];
85
+ }
86
+ }
87
+ return { fields, problems };
88
+ }
89
+ function rawSegment(type, fields, line, title) {
90
+ const raw = { type, fields, line };
91
+ if (title)
92
+ raw.title = title;
93
+ return raw;
94
+ }
95
+ /**
96
+ * Classify a single line of article body text as a ::video import.
97
+ * - "element": a valid own-line ::video import
98
+ * - "invalid": an attempted import with broken syntax
99
+ * - "none": not a video import at all
100
+ */
101
+ export function parseVideoImportLine(line, lineNumber = 0) {
102
+ const trimmed = line.trim();
103
+ if (!VIDEO_IMPORT_CANDIDATE_RE.test(trimmed.replace(INLINE_CODE_RE, ""))) {
104
+ return { kind: "none" };
105
+ }
106
+ const invalid = (reason, suggestion) => ({
107
+ kind: "invalid",
108
+ kindName: "video",
109
+ reason,
110
+ suggestion,
111
+ });
112
+ const match = trimmed.match(VIDEO_IMPORT_LINE_RE);
113
+ if (!match) {
114
+ if (trimmed.startsWith("::video")) {
115
+ return invalid("malformed ::video import", 'Use ::video[[../video_transcripts/name]] with optional {from="1:30" to="4:10"}, alone on its own line');
116
+ }
117
+ // ::video appears mid-line — an import buried in prose.
118
+ return invalid("::video import must be alone on its own line", "Move the ::video[[...]] import to its own line");
119
+ }
120
+ const preAttr = match[1];
121
+ const target = match[2].trim();
122
+ const postAttr = match[3];
123
+ if (preAttr !== undefined && postAttr !== undefined) {
124
+ return invalid("attributes given both before and after the wikilink", "Use a single {from=... to=...} block after the ]]");
125
+ }
126
+ const attrs = parseDirectiveAttributes(preAttr ?? postAttr, ["from", "to"]);
127
+ const [problem] = attrs.problems;
128
+ if (problem)
129
+ return invalid(problem.reason, problem.suggestion);
130
+ for (const key of ["from", "to"]) {
131
+ const value = attrs.fields[key];
132
+ if (value !== undefined && parseTimestamp(value) === null) {
133
+ return invalid(`invalid timestamp in '${key}="${value}"'`, "Use M:SS (e.g. 1:30) or H:MM:SS (e.g. 1:30:00)");
134
+ }
135
+ }
136
+ if (target === "") {
137
+ return invalid("empty wikilink target", "Reference a transcript: ::video[[../video_transcripts/name]]");
138
+ }
139
+ return {
140
+ kind: "element",
141
+ element: {
142
+ raw: rawSegment("video", { source: `[[${target}]]`, ...attrs.fields }, lineNumber),
143
+ rawLine: trimmed,
144
+ },
145
+ };
146
+ }
147
+ /** True when a wikilink target names a file directly under a widgets/ folder. */
148
+ export function isWidgetEmbedTarget(target) {
149
+ return WIDGET_TARGET_RE.test(target.trim());
150
+ }
151
+ /** True when a line mentions a widget embed anywhere outside inline code. */
152
+ function hasWidgetEmbedCandidate(line) {
153
+ return [
154
+ ...line.replace(INLINE_CODE_RE, "").matchAll(WIDGET_EMBED_CANDIDATE_RE),
155
+ ].some((m) => isWidgetEmbedTarget(m[1]));
156
+ }
157
+ /**
158
+ * Classify a single line of article body text as a widget embed.
159
+ * - "element": a valid own-line ![[../widgets/name]] embed
160
+ * - "invalid": a widget embed with broken syntax or buried in prose
161
+ * - "none": not a widget embed (other ![[...]] embeds included)
162
+ */
163
+ export function parseWidgetEmbedLine(line, lineNumber = 0) {
164
+ const trimmed = line.trim();
165
+ if (!hasWidgetEmbedCandidate(trimmed))
166
+ return { kind: "none" };
167
+ const invalid = (reason, suggestion) => ({
168
+ kind: "invalid",
169
+ kindName: "widget",
170
+ reason,
171
+ suggestion,
172
+ });
173
+ const match = trimmed.match(WIDGET_EMBED_LINE_RE);
174
+ if (!match || !isWidgetEmbedTarget(match[1])) {
175
+ return invalid("widget embed must be alone on its own line", "Move the ![[../widgets/name]] embed to its own line");
176
+ }
177
+ const target = match[1].trim();
178
+ const modifier = match[2]?.trim();
179
+ const fields = { source: `[[${target}]]` };
180
+ if (modifier !== undefined && modifier !== "") {
181
+ const heightMatch = modifier.match(/^height\s*=\s*(\S+)$/);
182
+ if (!heightMatch || !isValidHeight(heightMatch[1])) {
183
+ return invalid(`invalid modifier '|${modifier}'`, 'The only modifier is height, e.g. ![[../widgets/name|height=480px]] ("auto" or a CSS length)');
184
+ }
185
+ fields.height = heightMatch[1];
186
+ }
187
+ return {
188
+ kind: "element",
189
+ element: {
190
+ raw: rawSegment("widget", fields, lineNumber),
191
+ rawLine: trimmed,
192
+ },
193
+ };
194
+ }
195
+ /** Classify a line as any of the single-line article elements. */
196
+ export function parseArticleElementLine(line, lineNumber = 0) {
197
+ const video = parseVideoImportLine(line, lineNumber);
198
+ return video.kind === "none" ? parseWidgetEmbedLine(line, lineNumber) : video;
199
+ }
200
+ /**
201
+ * Turn a `:::question{type="…"}` block (opening fence, field lines, closing
202
+ * fence) into the RawSegment its `#### Question: <Type>` twin would be.
203
+ */
204
+ function parseQuestionBlock(attrs, bodyLines, lineNumber, file) {
205
+ const invalid = (reason, suggestion) => ({
206
+ kind: "invalid",
207
+ kindName: "question",
208
+ reason,
209
+ suggestion,
210
+ });
211
+ const parsed = parseDirectiveAttributes(attrs, ["type"]);
212
+ const [problem] = parsed.problems;
213
+ if (problem)
214
+ return invalid(problem.reason, problem.suggestion);
215
+ const subtype = parsed.fields.type?.trim().toLowerCase();
216
+ if (!subtype) {
217
+ return invalid("missing type attribute", `Write :::question{type="open"} (one of ${RESPONSE_QUESTION_SUBTYPES.join(", ")})`);
218
+ }
219
+ const title = SUBTYPE_DISPLAY[subtype];
220
+ if (!title) {
221
+ return invalid(`unknown question type '${subtype}'`, `Use one of ${RESPONSE_QUESTION_SUBTYPES.join(", ")}`);
222
+ }
223
+ // The fence line plays the header's role, so field lines come out exact.
224
+ const section = {
225
+ type: "question",
226
+ title,
227
+ rawType: "Question",
228
+ fields: {},
229
+ fieldLines: {},
230
+ body: "",
231
+ line: lineNumber,
232
+ level: 4,
233
+ };
234
+ const { warnings } = parseFields(section, file, bodyLines.join("\n"));
235
+ const raw = {
236
+ type: "question",
237
+ title,
238
+ fields: section.fields,
239
+ fieldLines: section.fieldLines,
240
+ line: lineNumber,
241
+ };
242
+ return {
243
+ kind: "element",
244
+ element: { raw, rawLine: ":::question", fieldWarnings: warnings },
245
+ };
246
+ }
247
+ /**
248
+ * Walk an article body line by line, tracking fenced code, container
249
+ * directives and elements, so every consumer skips the same regions and
250
+ * agrees on where each element and callout starts and ends. `firstLine` is
251
+ * the file line number of body line 0, so element RawSegments carry exact
252
+ * lines when the caller has them.
253
+ */
254
+ export function scanArticleBody(body, file = "", firstLine = 1) {
255
+ const lines = body.split("\n");
256
+ const out = [];
257
+ const fence = makeFenceTracker();
258
+ // Open container directives, innermost last.
259
+ const containerStack = [];
260
+ const calloutIndices = () => containerStack.filter((c) => c.name === "callout").map((c) => c.index);
261
+ const hiddenIn = () => containerStack.find((c) => c.name === "hide" || c.name === "collapse")
262
+ ?.name;
263
+ const prose = (line) => {
264
+ const entry = { line, prose: true };
265
+ const hidden = hiddenIn();
266
+ if (hidden)
267
+ entry.hiddenIn = hidden;
268
+ const callouts = calloutIndices();
269
+ if (callouts.length > 0)
270
+ entry.callouts = callouts;
271
+ return entry;
272
+ };
273
+ for (let i = 0; i < lines.length; i++) {
274
+ const line = lines[i];
275
+ if (fence.step(line) || fence.inside) {
276
+ out.push({ line, prose: false });
277
+ continue;
278
+ }
279
+ const openMatch = line.match(CONTAINER_OPEN);
280
+ if (openMatch && openMatch[2] === "question") {
281
+ // A question block runs to the first closing fence at its own depth.
282
+ const colons = openMatch[1].length;
283
+ let depth = 0;
284
+ let end = -1;
285
+ // A fenced example inside a field is code: its `:::` closes nothing.
286
+ const innerFence = makeFenceTracker();
287
+ for (let j = i + 1; j < lines.length; j++) {
288
+ const inner = lines[j];
289
+ if (innerFence.step(inner) || innerFence.inside)
290
+ continue;
291
+ if (CONTAINER_OPEN.test(inner)) {
292
+ depth++;
293
+ continue;
294
+ }
295
+ const close = inner.match(CONTAINER_CLOSE);
296
+ if (!close)
297
+ continue;
298
+ if (depth > 0) {
299
+ depth--;
300
+ continue;
301
+ }
302
+ if (close[1].length >= colons) {
303
+ end = j;
304
+ break;
305
+ }
306
+ }
307
+ const entry = prose(line);
308
+ entry.prose = false;
309
+ if (end === -1) {
310
+ entry.invalid = {
311
+ kind: "invalid",
312
+ kindName: "question",
313
+ reason: "unclosed :::question block",
314
+ suggestion: "Close the block with a ':::' line after its last field",
315
+ };
316
+ out.push(entry);
317
+ continue;
318
+ }
319
+ const parsed = parseQuestionBlock(openMatch[3], lines.slice(i + 1, end), firstLine + i, file);
320
+ if (parsed.kind === "invalid")
321
+ entry.invalid = parsed;
322
+ else if (parsed.kind === "element") {
323
+ entry.element = { ...parsed.element, endIndex: end };
324
+ }
325
+ out.push(entry);
326
+ for (let j = i + 1; j <= end; j++)
327
+ out.push({ line: lines[j], prose: false });
328
+ i = end;
329
+ continue;
330
+ }
331
+ if (openMatch) {
332
+ containerStack.push({
333
+ name: openMatch[2],
334
+ index: i,
335
+ colons: openMatch[1].length,
336
+ });
337
+ out.push({
338
+ line,
339
+ prose: false,
340
+ marker: {
341
+ kind: "open",
342
+ name: openMatch[2],
343
+ attrs: openMatch[3],
344
+ colons: openMatch[1].length,
345
+ },
346
+ });
347
+ continue;
348
+ }
349
+ const closeMatch = line.match(CONTAINER_CLOSE);
350
+ if (closeMatch) {
351
+ const top = containerStack[containerStack.length - 1];
352
+ // A closing fence needs at least as many colons as its opener; a
353
+ // shorter one is text, as markdown reads it.
354
+ if (!top || closeMatch[1].length >= top.colons) {
355
+ containerStack.pop();
356
+ out.push({
357
+ line,
358
+ prose: false,
359
+ marker: { kind: "close", opener: top?.index ?? -1 },
360
+ });
361
+ continue;
362
+ }
363
+ }
364
+ const entry = prose(line);
365
+ const parsed = parseArticleElementLine(line, firstLine + i);
366
+ if (parsed.kind === "element") {
367
+ entry.prose = false;
368
+ entry.element = { ...parsed.element, endIndex: i };
369
+ }
370
+ else if (parsed.kind === "invalid") {
371
+ entry.invalid = parsed;
372
+ }
373
+ out.push(entry);
374
+ }
375
+ return out;
376
+ }
377
+ /**
378
+ * Parse-time validation of the elements in an article body: syntax,
379
+ * placement (an element inside hide/collapse would vanish with the collapsed
380
+ * text), and for question blocks the same field checks a lens question gets.
381
+ * Resolution errors (missing file, bad range) are reported later by the
382
+ * flattener, which has the file map.
383
+ */
384
+ export function parseArticleElements(body, file, bodyStartLine) {
385
+ const errors = [];
386
+ const elements = [];
387
+ const scanned = scanArticleBody(body, file, bodyStartLine);
388
+ for (let i = 0; i < scanned.length; i++) {
389
+ const { invalid, element, hiddenIn } = scanned[i];
390
+ const absLine = bodyStartLine + i;
391
+ if (invalid) {
392
+ const { code, label } = ARTICLE_ELEMENT_KINDS[invalid.kindName];
393
+ const notOwnLine = invalid.reason.includes("own line");
394
+ errors.push({
395
+ file,
396
+ line: absLine,
397
+ code: `article.${code}-${notOwnLine ? "not-own-line" : "invalid"}`,
398
+ message: `Invalid ${label}: ${invalid.reason}`,
399
+ suggestion: invalid.suggestion,
400
+ severity: "error",
401
+ });
402
+ continue;
403
+ }
404
+ if (!element)
405
+ continue;
406
+ const kind = element.raw.type;
407
+ const { code, label } = ARTICLE_ELEMENT_KINDS[kind];
408
+ // Elements inside hide/collapse would silently vanish from rendered
409
+ // output (the collapsed string strips them), so they are rejected outright.
410
+ if (hiddenIn) {
411
+ errors.push({
412
+ file,
413
+ line: absLine,
414
+ code: `article.${code}-in-hide`,
415
+ message: `${label} inside a ':::${hiddenIn}' container`,
416
+ suggestion: `Move the import outside the hidden block — hidden text is collapsed and the ${kind} would never render`,
417
+ severity: "error",
418
+ });
419
+ continue;
420
+ }
421
+ const converted = convertSegment(element.raw, "lens", file);
422
+ if (kind === "question") {
423
+ const fieldErrors = [
424
+ ...(element.fieldWarnings ?? []),
425
+ ...validateRawSegment(element.raw, file),
426
+ ...converted.errors,
427
+ ];
428
+ errors.push(...fieldErrors.map((error) => ({
429
+ code: `article.${code}-invalid`,
430
+ ...error,
431
+ })));
432
+ }
433
+ if (converted.segment)
434
+ elements.push(converted.segment);
435
+ }
436
+ return { elements, errors };
437
+ }
438
+ /**
439
+ * Lens text segments do not resolve inline article elements — catch attempts
440
+ * there with a pointer to the segment form.
441
+ */
442
+ export function validateNoArticleElementsInLensText(content, file, line) {
443
+ const errors = [];
444
+ const lines = content.split("\n");
445
+ const fence = makeFenceTracker();
446
+ for (let i = 0; i < lines.length; i++) {
447
+ // Examples in fenced code are not attempts
448
+ if (fence.step(lines[i]) || fence.inside)
449
+ continue;
450
+ const prose = lines[i].replace(INLINE_CODE_RE, "");
451
+ if (VIDEO_IMPORT_CANDIDATE_RE.test(prose)) {
452
+ errors.push({
453
+ file,
454
+ line: line + i,
455
+ message: "::video imports are only supported in article bodies",
456
+ suggestion: "Use a '#### Video' segment in the lens, or move the import into the article file",
457
+ severity: "error",
458
+ });
459
+ }
460
+ else if (hasWidgetEmbedCandidate(prose)) {
461
+ errors.push({
462
+ file,
463
+ line: line + i,
464
+ message: "Widget embeds (![[../widgets/...]]) are only supported in article bodies",
465
+ suggestion: "Use a '#### Widget' segment in the lens, or move the embed into the article file",
466
+ severity: "error",
467
+ });
468
+ }
469
+ else if (/^:{3,}question\b/.test(prose.trim())) {
470
+ errors.push({
471
+ file,
472
+ line: line + i,
473
+ message: ":::question blocks are only supported in article bodies",
474
+ suggestion: "Use a '#### Question: <Type>' segment in the lens (inside a '#### Callout:' if it should be boxed)",
475
+ severity: "error",
476
+ });
477
+ }
478
+ }
479
+ return errors;
480
+ }
481
+ /** The callout frame for a lifted `:::callout{…}` fence (attributes already
482
+ * validated by validator/directives.ts; unknown values are dropped). */
483
+ export function calloutFrameFromAttributes(file, line, attrs) {
484
+ // Problems were reported by the directive validator; the well-formed
485
+ // attributes still shape the box.
486
+ const { fields } = parseDirectiveAttributes(attrs, CALLOUT_ATTRIBUTES);
487
+ return calloutFrame(file, line, fields.title, fields);
488
+ }
489
+ //# sourceMappingURL=article-elements.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"article-elements.js","sourceRoot":"","sources":["../../src/parser/article-elements.ts"],"names":[],"mappings":"AAmCA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EACL,cAAc,EACd,kBAAkB,GAGnB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,0BAA0B,EAC1B,eAAe,GAEhB,MAAM,wBAAwB,CAAC;AAEhC,4EAA4E;AAC5E,4EAA4E;AAC5E,wEAAwE;AACxE,MAAM,oBAAoB,GACxB,yEAAyE,CAAC;AAE5E,qEAAqE;AACrE,0EAA0E;AAC1E,uBAAuB;AACvB,MAAM,yBAAyB,GAAG,aAAa,CAAC;AAEhD,sEAAsE;AACtE,MAAM,oBAAoB,GAAG,qCAAqC,CAAC;AAEnE,6EAA6E;AAC7E,MAAM,yBAAyB,GAAG,kCAAkC,CAAC;AAErE,2EAA2E;AAC3E,0EAA0E;AAC1E,MAAM,gBAAgB,GAAG,gCAAgC,CAAC;AAE1D,4EAA4E;AAC5E,yBAAyB;AACzB,MAAM,cAAc,GAAG,UAAU,CAAC;AAElC,yEAAyE;AACzE,6EAA6E;AAC7E,uEAAuE;AACvE,MAAM,CAAC,MAAM,cAAc,GAAG,+CAA+C,CAAC;AAC9E;uDACuD;AACvD,MAAM,CAAC,MAAM,oBAAoB,GAAG,wBAAwB,CAAC;AAC7D,oEAAoE;AACpE,MAAM,CAAC,MAAM,eAAe,GAAG,uCAAuC,CAAC;AAEvE,mFAAmF;AACnF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAU,CAAC;AAEzE,+EAA+E;AAC/E,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,KAAK,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,gBAAgB,EAAE;IACxD,MAAM,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAE;IACvD,QAAQ,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,mBAAmB,EAAE;CACxD,CAAC;AAgCX;;;;;;GAMG;AACH,MAAM,UAAU,wBAAwB,CACtC,IAAwB,EACxB,OAA0B;IAE1B,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,MAAM,QAAQ,GAAuB,EAAE,CAAC;IACxC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IAC1E,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,2BAA2B,CAAC,CAAC,CAAC;IAC/D,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACnD,IACE,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,EACzE,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,wBAAwB,IAAI,IAAI;YACxC,UAAU,EAAE,+BAA+B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;SAChE,CAAC,CAAC;QACH,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IAC9B,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACrB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3B,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,SAAS;gBACf,GAAG;gBACH,MAAM,EAAE,2BAA2B,GAAG,GAAG;gBACzC,UAAU,EAAE,QAAQ,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,2BAA2B;aACrE,CAAC,CAAC;QACL,CAAC;aAAM,IAAI,GAAG,IAAI,MAAM,EAAE,CAAC;YACzB,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,WAAW;gBACjB,GAAG;gBACH,MAAM,EAAE,wBAAwB,GAAG,GAAG;gBACtC,UAAU,EAAE,iBAAiB,GAAG,YAAY;aAC7C,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AAC9B,CAAC;AAED,SAAS,UAAU,CACjB,IAAY,EACZ,MAA8B,EAC9B,IAAY,EACZ,KAAc;IAEd,MAAM,GAAG,GAAe,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAC/C,IAAI,KAAK;QAAE,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC;IAC7B,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAClC,IAAY,EACZ,UAAU,GAAG,CAAC;IAEd,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC;QACzE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC1B,CAAC;IACD,MAAM,OAAO,GAAG,CACd,MAAc,EACd,UAAkB,EACG,EAAE,CAAC,CAAC;QACzB,IAAI,EAAE,SAAS;QACf,QAAQ,EAAE,OAAO;QACjB,MAAM;QACN,UAAU;KACX,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IAClD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,IAAI,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAClC,OAAO,OAAO,CACZ,0BAA0B,EAC1B,uGAAuG,CACxG,CAAC;QACJ,CAAC;QACD,wDAAwD;QACxD,OAAO,OAAO,CACZ,8CAA8C,EAC9C,gDAAgD,CACjD,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACzB,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/B,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAC1B,IAAI,OAAO,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QACpD,OAAO,OAAO,CACZ,qDAAqD,EACrD,mDAAmD,CACpD,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,GAAG,wBAAwB,CAAC,OAAO,IAAI,QAAQ,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IAC5E,MAAM,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC;IACjC,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IAChE,KAAK,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,CAAU,EAAE,CAAC;QAC1C,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,KAAK,KAAK,SAAS,IAAI,cAAc,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;YAC1D,OAAO,OAAO,CACZ,yBAAyB,GAAG,KAAK,KAAK,IAAI,EAC1C,gDAAgD,CACjD,CAAC;QACJ,CAAC;IACH,CAAC;IACD,IAAI,MAAM,KAAK,EAAE,EAAE,CAAC;QAClB,OAAO,OAAO,CACZ,uBAAuB,EACvB,8DAA8D,CAC/D,CAAC;IACJ,CAAC;IACD,OAAO;QACL,IAAI,EAAE,SAAS;QACf,OAAO,EAAE;YACP,GAAG,EAAE,UAAU,CACb,OAAO,EACP,EAAE,MAAM,EAAE,KAAK,MAAM,IAAI,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,EAC5C,UAAU,CACX;YACD,OAAO,EAAE,OAAO;SACjB;KACF,CAAC;AACJ,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,mBAAmB,CAAC,MAAc;IAChD,OAAO,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;AAC9C,CAAC;AAED,6EAA6E;AAC7E,SAAS,uBAAuB,CAAC,IAAY;IAC3C,OAAO;QACL,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,yBAAyB,CAAC;KACxE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAClC,IAAY,EACZ,UAAU,GAAG,CAAC;IAEd,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC/D,MAAM,OAAO,GAAG,CACd,MAAc,EACd,UAAkB,EACG,EAAE,CAAC,CAAC;QACzB,IAAI,EAAE,SAAS;QACf,QAAQ,EAAE,QAAQ;QAClB,MAAM;QACN,UAAU;KACX,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IAClD,IAAI,CAAC,KAAK,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7C,OAAO,OAAO,CACZ,4CAA4C,EAC5C,qDAAqD,CACtD,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/B,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;IAClC,MAAM,MAAM,GAA2B,EAAE,MAAM,EAAE,KAAK,MAAM,IAAI,EAAE,CAAC;IACnE,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,EAAE,EAAE,CAAC;QAC9C,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAC3D,IAAI,CAAC,WAAW,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACnD,OAAO,OAAO,CACZ,sBAAsB,QAAQ,GAAG,EACjC,8FAA8F,CAC/F,CAAC;QACJ,CAAC;QACD,MAAM,CAAC,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;IACjC,CAAC;IACD,OAAO;QACL,IAAI,EAAE,SAAS;QACf,OAAO,EAAE;YACP,GAAG,EAAE,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC;YAC7C,OAAO,EAAE,OAAO;SACjB;KACF,CAAC;AACJ,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,uBAAuB,CACrC,IAAY,EACZ,UAAU,GAAG,CAAC;IAEd,MAAM,KAAK,GAAG,oBAAoB,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACrD,OAAO,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,oBAAoB,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAChF,CAAC;AAED;;;GAGG;AACH,SAAS,kBAAkB,CACzB,KAAyB,EACzB,SAAmB,EACnB,UAAkB,EAClB,IAAY;IAEZ,MAAM,OAAO,GAAG,CACd,MAAc,EACd,UAAkB,EACG,EAAE,CAAC,CAAC;QACzB,IAAI,EAAE,SAAS;QACf,QAAQ,EAAE,UAAU;QACpB,MAAM;QACN,UAAU;KACX,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,wBAAwB,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IACzD,MAAM,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC;IAClC,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IAChE,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACzD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,OAAO,CACZ,wBAAwB,EACxB,0CAA0C,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CACnF,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,GAAG,eAAe,CAAC,OAAkC,CAAC,CAAC;IAClE,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,OAAO,CACZ,0BAA0B,OAAO,GAAG,EACpC,cAAc,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACtD,CAAC;IACJ,CAAC;IACD,yEAAyE;IACzE,MAAM,OAAO,GAAG;QACd,IAAI,EAAE,UAAU;QAChB,KAAK;QACL,OAAO,EAAE,UAAU;QACnB,MAAM,EAAE,EAA4B;QACpC,UAAU,EAAE,EAA4B;QACxC,IAAI,EAAE,EAAE;QACR,IAAI,EAAE,UAAU;QAChB,KAAK,EAAE,CAAC;KACT,CAAC;IACF,MAAM,EAAE,QAAQ,EAAE,GAAG,WAAW,CAAC,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACtE,MAAM,GAAG,GAAe;QACtB,IAAI,EAAE,UAAU;QAChB,KAAK;QACL,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,IAAI,EAAE,UAAU;KACjB,CAAC;IACF,OAAO;QACL,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,QAAQ,EAAE;KAClE,CAAC;AACJ,CAAC;AAoBD;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAC7B,IAAY,EACZ,IAAI,GAAG,EAAE,EACT,SAAS,GAAG,CAAC;IAEb,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,GAAG,GAAyB,EAAE,CAAC;IACrC,MAAM,KAAK,GAAG,gBAAgB,EAAE,CAAC;IACjC,6CAA6C;IAC7C,MAAM,cAAc,GAAsD,EAAE,CAAC;IAC7E,MAAM,cAAc,GAAG,GAAG,EAAE,CAC1B,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACzE,MAAM,QAAQ,GAAG,GAAG,EAAE,CACpB,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC;QACpE,EAAE,IAAI,CAAC;IACX,MAAM,KAAK,GAAG,CAAC,IAAY,EAAsB,EAAE;QACjD,MAAM,KAAK,GAAuB,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACxD,MAAM,MAAM,GAAG,QAAQ,EAAE,CAAC;QAC1B,IAAI,MAAM;YAAE,KAAK,CAAC,QAAQ,GAAG,MAAM,CAAC;QACpC,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAC;QAClC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;YAAE,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACnD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IACF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YACrC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;YACjC,SAAS;QACX,CAAC;QACD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QAC7C,IAAI,SAAS,IAAI,SAAS,CAAC,CAAC,CAAC,KAAK,UAAU,EAAE,CAAC;YAC7C,qEAAqE;YACrE,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YACnC,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC;YACb,qEAAqE;YACrE,MAAM,UAAU,GAAG,gBAAgB,EAAE,CAAC;YACtC,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC1C,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBACvB,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,MAAM;oBAAE,SAAS;gBAC1D,IAAI,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC/B,KAAK,EAAE,CAAC;oBACR,SAAS;gBACX,CAAC;gBACD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;gBAC3C,IAAI,CAAC,KAAK;oBAAE,SAAS;gBACrB,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;oBACd,KAAK,EAAE,CAAC;oBACR,SAAS;gBACX,CAAC;gBACD,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,MAAM,EAAE,CAAC;oBAC9B,GAAG,GAAG,CAAC,CAAC;oBACR,MAAM;gBACR,CAAC;YACH,CAAC;YACD,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;YAC1B,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;YACpB,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;gBACf,KAAK,CAAC,OAAO,GAAG;oBACd,IAAI,EAAE,SAAS;oBACf,QAAQ,EAAE,UAAU;oBACpB,MAAM,EAAE,4BAA4B;oBACpC,UAAU,EAAE,wDAAwD;iBACrE,CAAC;gBACF,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAChB,SAAS;YACX,CAAC;YACD,MAAM,MAAM,GAAG,kBAAkB,CAC/B,SAAS,CAAC,CAAC,CAAC,EACZ,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,EACvB,SAAS,GAAG,CAAC,EACb,IAAI,CACL,CAAC;YACF,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS;gBAAE,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;iBACjD,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBACnC,KAAK,CAAC,OAAO,GAAG,EAAE,GAAG,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;YACvD,CAAC;YACD,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAChB,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,EAAE;gBAC/B,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;YAC7C,CAAC,GAAG,GAAG,CAAC;YACR,SAAS;QACX,CAAC;QACD,IAAI,SAAS,EAAE,CAAC;YACd,cAAc,CAAC,IAAI,CAAC;gBAClB,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;gBAClB,KAAK,EAAE,CAAC;gBACR,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM;aAC5B,CAAC,CAAC;YACH,GAAG,CAAC,IAAI,CAAC;gBACP,IAAI;gBACJ,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE;oBACN,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;oBAClB,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;oBACnB,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM;iBAC5B;aACF,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QACD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;QAC/C,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,GAAG,GAAG,cAAc,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACtD,iEAAiE;YACjE,6CAA6C;YAC7C,IAAI,CAAC,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;gBAC/C,cAAc,CAAC,GAAG,EAAE,CAAC;gBACrB,GAAG,CAAC,IAAI,CAAC;oBACP,IAAI;oBACJ,KAAK,EAAE,KAAK;oBACZ,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC,CAAC,EAAE;iBACpD,CAAC,CAAC;gBACH,SAAS;YACX,CAAC;QACH,CAAC;QACD,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;QAC1B,MAAM,MAAM,GAAG,uBAAuB,CAAC,IAAI,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC;QAC5D,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC9B,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;YACpB,KAAK,CAAC,OAAO,GAAG,EAAE,GAAG,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;QACrD,CAAC;aAAM,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YACrC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;QACzB,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAQD;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAClC,IAAY,EACZ,IAAY,EACZ,aAAqB;IAErB,MAAM,MAAM,GAAmB,EAAE,CAAC;IAClC,MAAM,QAAQ,GAAwB,EAAE,CAAC;IACzC,MAAM,OAAO,GAAG,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC;IAE3D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QAClD,MAAM,OAAO,GAAG,aAAa,GAAG,CAAC,CAAC;QAClC,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,qBAAqB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YAChE,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;YACvD,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI;gBACJ,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,WAAW,IAAI,IAAI,UAAU,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,EAAE;gBAClE,OAAO,EAAE,WAAW,KAAK,KAAK,OAAO,CAAC,MAAM,EAAE;gBAC9C,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,QAAQ,EAAE,OAAO;aAClB,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QACD,IAAI,CAAC,OAAO;YAAE,SAAS;QACvB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAA0B,CAAC;QACpD,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;QACpD,oEAAoE;QACpE,4EAA4E;QAC5E,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI;gBACJ,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,WAAW,IAAI,UAAU;gBAC/B,OAAO,EAAE,GAAG,KAAK,iBAAiB,QAAQ,aAAa;gBACvD,UAAU,EAAE,+EAA+E,IAAI,qBAAqB;gBACpH,QAAQ,EAAE,OAAO;aAClB,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QACD,MAAM,SAAS,GAAG,cAAc,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QAC5D,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;YACxB,MAAM,WAAW,GAAG;gBAClB,GAAG,CAAC,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC;gBAChC,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC;gBACxC,GAAG,SAAS,CAAC,MAAM;aACpB,CAAC;YACF,MAAM,CAAC,IAAI,CACT,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;gBAC7B,IAAI,EAAE,WAAW,IAAI,UAAU;gBAC/B,GAAG,KAAK;aACT,CAAC,CAAC,CACJ,CAAC;QACJ,CAAC;QACD,IAAI,SAAS,CAAC,OAAO;YAAE,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAC1D,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;AAC9B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mCAAmC,CACjD,OAAe,EACf,IAAY,EACZ,IAAY;IAEZ,MAAM,MAAM,GAAmB,EAAE,CAAC;IAClC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,KAAK,GAAG,gBAAgB,EAAE,CAAC;IACjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,2CAA2C;QAC3C,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM;YAAE,SAAS;QACnD,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QACnD,IAAI,yBAAyB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1C,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI;gBACJ,IAAI,EAAE,IAAI,GAAG,CAAC;gBACd,OAAO,EAAE,sDAAsD;gBAC/D,UAAU,EACR,kFAAkF;gBACpF,QAAQ,EAAE,OAAO;aAClB,CAAC,CAAC;QACL,CAAC;aAAM,IAAI,uBAAuB,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1C,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI;gBACJ,IAAI,EAAE,IAAI,GAAG,CAAC;gBACd,OAAO,EACL,0EAA0E;gBAC5E,UAAU,EACR,kFAAkF;gBACpF,QAAQ,EAAE,OAAO;aAClB,CAAC,CAAC;QACL,CAAC;aAAM,IAAI,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;YACjD,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI;gBACJ,IAAI,EAAE,IAAI,GAAG,CAAC;gBACd,OAAO,EAAE,yDAAyD;gBAClE,UAAU,EACR,oGAAoG;gBACtG,QAAQ,EAAE,OAAO;aAClB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;wEACwE;AACxE,MAAM,UAAU,0BAA0B,CACxC,IAAY,EACZ,IAAY,EACZ,KAAyB;IAEzB,qEAAqE;IACrE,kCAAkC;IAClC,MAAM,EAAE,MAAM,EAAE,GAAG,wBAAwB,CAAC,KAAK,EAAE,kBAAkB,CAAC,CAAC;IACvE,OAAO,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AACxD,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import type { ContentError } from "../index.js";
2
+ import type { ParsedLensSegment } from "./lens.js";
2
3
  export interface ParsedArticle {
3
4
  title: string;
4
5
  author: string;
@@ -9,6 +10,9 @@ export interface ParsedArticle {
9
10
  line: number;
10
11
  }>;
11
12
  allowUnreachableUrl?: boolean;
13
+ /** Elements declared inline in the body (videos, widgets, questions),
14
+ * converted as the lens parser converts segments. */
15
+ elements: ParsedLensSegment[];
12
16
  }
13
17
  export interface ArticleParseResult {
14
18
  article: ParsedArticle | null;
@@ -1,7 +1,7 @@
1
1
  import { parseFrontmatter } from "./frontmatter.js";
2
2
  import { validateFrontmatter } from "../validator/validate-frontmatter.js";
3
3
  import { validateDirectives } from "../validator/directives.js";
4
- import { validateArticleImports } from "../validator/article-imports.js";
4
+ import { parseArticleElements } from "./article-elements.js";
5
5
  import { validateHtmlTags } from "../validator/html-tags.js";
6
6
  import { validateTrailingHr } from "../validator/trailing-hr.js";
7
7
  import { validateEmphasis } from "../validator/emphasis.js";
@@ -107,9 +107,11 @@ function parseArticlePrepared(content, file) {
107
107
  ...error,
108
108
  code: "article.directive-invalid",
109
109
  })));
110
- // Validate inline ::video[[...]] / ![[../widgets/...]] imports (syntax and
111
- // placement; resolution against the file map happens in the flattener).
112
- errors.push(...validateArticleImports(body, file, bodyStartLine));
110
+ // Inline elements (::video, widget embeds, :::question blocks): syntax,
111
+ // placement and question fields; resolution against the file map happens
112
+ // in the flattener.
113
+ const elements = parseArticleElements(body, file, bodyStartLine);
114
+ errors.push(...elements.errors);
113
115
  // Flag raw HTML/XML tags (scrape artifacts) in the article body
114
116
  errors.push(...validateHtmlTags(body, file, bodyStartLine).map((error) => ({
115
117
  ...error,
@@ -134,6 +136,7 @@ function parseArticlePrepared(content, file) {
134
136
  : undefined,
135
137
  imageUrls,
136
138
  allowUnreachableUrl: frontmatter.allowUnreachableUrl === true,
139
+ elements: elements.elements,
137
140
  };
138
141
  return { article, errors };
139
142
  }
@@ -1 +1 @@
1
- {"version":3,"file":"article.js","sourceRoot":"","sources":["../../src/parser/article.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EACL,oBAAoB,EACpB,iCAAiC,EACjC,mBAAmB,GACpB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,mCAAmC,CAAC;AAkB3C;;;;;;;;GAQG;AACH,SAAS,qBAAqB,CAAC,KAAa,EAAE,IAAY;IACxD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACpC,MAAM,UAAU,GAAG;QACjB,OAAO;QACP,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;KAC7D,CAAC;IACF,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;QACjE,IAAI,IAAI,MAAM,CAAC,cAAc,OAAO,YAAY,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACpE,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,oBAAoB,CAC3B,OAAe,EACf,IAAY;IAEZ,MAAM,MAAM,GAAmB,EAAE,CAAC;IAElC,MAAM,iBAAiB,GAAG,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC1D,IAAI,iBAAiB,CAAC,KAAK,EAAE,CAAC;QAC5B,MAAM,CAAC,IAAI,CAAC;YACV,GAAG,iBAAiB,CAAC,KAAK;YAC1B,IAAI,EAAE,6BAA6B;SACpC,CAAC,CAAC;QACH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IACnC,CAAC;IAED,MAAM,EAAE,WAAW,EAAE,GAAG,iBAAiB,CAAC;IAE1C,yEAAyE;IACzE,MAAM,iBAAiB,GAAG,mBAAmB,CAAC,WAAW,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IAC5E,KAAK,MAAM,KAAK,IAAI,iBAAiB;QACnC,KAAK,CAAC,IAAI,GAAG,6BAA6B,CAAC;IAC7C,MAAM,CAAC,IAAI,CAAC,GAAG,iBAAiB,CAAC,CAAC;IAElC,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,IAAI,CAC7C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAC9B,CAAC;IACF,IAAI,gBAAgB,EAAE,CAAC;QACrB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IACnC,CAAC;IAED,kEAAkE;IAClE,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAU,CAAC;IAChD,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;QAC/B,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACpE,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9C,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI;gBACJ,IAAI,EAAE,CAAC;gBACP,OAAO,EAAE,UAAU,KAAK,wCAAwC;gBAChE,UAAU,EAAE,wBAAwB,KAAK,GAAG;gBAC5C,QAAQ,EAAE,OAAO;aAClB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,6EAA6E;IAC7E,8DAA8D;IAC9D,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;IAC9C,IAAI,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7B,MAAM,CAAC,IAAI,CAAC;YACV,IAAI;YACJ,IAAI,EAAE,CAAC;YACP,OAAO,EAAE,4CAA4C;YACrD,UAAU,EACR,kEAAkE;YACpE,QAAQ,EAAE,OAAO;SAClB,CAAC,CAAC;IACL,CAAC;IACD,yEAAyE;IACzE,0DAA0D;IAC1D,IAAI,WAAW,CAAC,kBAAkB,KAAK,IAAI,EAAE,CAAC;QAC5C,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC;YACnD,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC;YAChC,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC;QACvC,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;YAC/B,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YACpD,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI;oBACJ,IAAI,EAAE,CAAC;oBACP,OAAO,EAAE,mCAAmC,QAAQ,GAAG;oBACvD,UAAU,EACR,gEAAgE;wBAChE,iHAAiH;oBACnH,QAAQ,EAAE,OAAO;iBAClB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,GAAG,iBAAiB,CAAC;IAElD,4CAA4C;IAC5C,MAAM,eAAe,GAAG,kBAAkB,CAAC,IAAI,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC;IACtE,MAAM,CAAC,IAAI,CACT,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACjC,GAAG,KAAK;QACR,IAAI,EAAE,2BAA2B;KAClC,CAAC,CAAC,CACJ,CAAC;IAEF,2EAA2E;IAC3E,wEAAwE;IACxE,MAAM,CAAC,IAAI,CAAC,GAAG,sBAAsB,CAAC,IAAI,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC;IAElE,gEAAgE;IAChE,MAAM,CAAC,IAAI,CACT,GAAG,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC7D,GAAG,KAAK;QACR,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,uBAAuB;KAC5C,CAAC,CAAC,CACJ,CAAC;IAEF,sEAAsE;IACtE,MAAM,CAAC,IAAI,CAAC,GAAG,kBAAkB,CAAC,IAAI,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC;IAE9D,mEAAmE;IACnE,MAAM,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC;IAE5D,yEAAyE;IACzE,qDAAqD;IACrD,MAAM,SAAS,GAAG,oBAAoB,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;IAC5D,MAAM,CAAC,IAAI,CAAC,GAAG,sBAAsB,CAAC,IAAI,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC;IAElE,MAAM,OAAO,GAAkB;QAC7B,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC;QAChC,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC;YACvC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;YAC/B,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC;QAC9B,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC;QACzC,SAAS,EACP,WAAW,CAAC,SAAS,KAAK,SAAS;YACjC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC;YAC/B,CAAC,CAAC,SAAS;QACf,SAAS;QACT,mBAAmB,EAAE,WAAW,CAAC,mBAAmB,KAAK,IAAI;KAC9D,CAAC;IAEF,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,OAAe,EACf,IAAY;IAEZ,MAAM,gBAAgB,GAAG,iCAAiC,CAAC,OAAO,CAAC,CAAC;IACpE,MAAM,MAAM,GAAG,oBAAoB,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;IAE5D,MAAM,eAAe,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;IACtD,IAAI,eAAe,KAAK,gBAAgB;QAAE,OAAO,MAAM,CAAC;IACxD,MAAM,SAAS,GAAG,oBAAoB,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;IAC9D,4EAA4E;IAC5E,qEAAqE;IACrE,IAAI,CAAC,SAAS,CAAC,OAAO;QAAE,OAAO,MAAM,CAAC;IACtC,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IACtC,OAAO,mBAAmB,CAAC,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC;QAC3D,CAAC,CAAC,MAAM;QACR,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"article.js","sourceRoot":"","sources":["../../src/parser/article.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export interface FenceTracker {
2
+ /** Feed a line; returns true when the line is a fence marker. */
3
+ step(line: string): boolean;
4
+ /** True while inside a fenced block (the markers themselves excluded). */
5
+ readonly inside: boolean;
6
+ }
7
+ export declare function makeFenceTracker(): FenceTracker;
@@ -0,0 +1,34 @@
1
+ // src/parser/code-fence.ts — fenced code tracking shared by the line
2
+ // scanners. Inside a fence nothing is structure: a `#### Text` line in a
3
+ // ```md example is prose, `key::` is not a field, `:::` is not a directive.
4
+ // CommonMark: a fence is three or more backticks or tildes, up to three
5
+ // leading spaces; the closing fence uses the same character, at least as
6
+ // many of them, and nothing else on the line.
7
+ const FENCE_RE = /^ {0,3}(`{3,}|~{3,})/;
8
+ export function makeFenceTracker() {
9
+ let fence = null;
10
+ return {
11
+ step(line) {
12
+ const match = line.match(FENCE_RE);
13
+ if (!match)
14
+ return false;
15
+ const marker = match[1];
16
+ if (!fence) {
17
+ fence = { char: marker[0], length: marker.length };
18
+ return true;
19
+ }
20
+ if (marker[0] === fence.char &&
21
+ marker.length >= fence.length &&
22
+ line.trim() === marker) {
23
+ fence = null;
24
+ return true;
25
+ }
26
+ // A different fence inside an open one is code, not a marker
27
+ return false;
28
+ },
29
+ get inside() {
30
+ return fence !== null;
31
+ },
32
+ };
33
+ }
34
+ //# sourceMappingURL=code-fence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-fence.js","sourceRoot":"","sources":["../../src/parser/code-fence.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,yEAAyE;AACzE,4EAA4E;AAC5E,wEAAwE;AACxE,yEAAyE;AACzE,8CAA8C;AAE9C,MAAM,QAAQ,GAAG,sBAAsB,CAAC;AASxC,MAAM,UAAU,gBAAgB;IAC9B,IAAI,KAAK,GAA4C,IAAI,CAAC;IAC1D,OAAO;QACL,IAAI,CAAC,IAAY;YACf,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YACnC,IAAI,CAAC,KAAK;gBAAE,OAAO,KAAK,CAAC;YACzB,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACxB,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,KAAK,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;gBACnD,OAAO,IAAI,CAAC;YACd,CAAC;YACD,IACE,MAAM,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI;gBACxB,MAAM,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM;gBAC7B,IAAI,CAAC,IAAI,EAAE,KAAK,MAAM,EACtB,CAAC;gBACD,KAAK,GAAG,IAAI,CAAC;gBACb,OAAO,IAAI,CAAC;YACd,CAAC;YACD,6DAA6D;YAC7D,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,MAAM;YACR,OAAO,KAAK,KAAK,IAAI,CAAC;QACxB,CAAC;KACF,CAAC;AACJ,CAAC"}