markdown-codec 11.1.12 → 11.1.14

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 (99) hide show
  1. package/dist/block/block.cjs +23 -612
  2. package/dist/block/block.d.cts +22 -3
  3. package/dist/block/block.d.ts +22 -3
  4. package/dist/block/block.js +2 -607
  5. package/dist/block/definitions.d.cts +1 -1
  6. package/dist/block/definitions.d.ts +1 -1
  7. package/dist/block/list.d.cts +1 -1
  8. package/dist/block/list.d.ts +1 -1
  9. package/dist/block/node.d.cts +1 -45
  10. package/dist/block/node.d.ts +1 -45
  11. package/dist/block/parser.cjs +3 -0
  12. package/dist/block/parser.d.cts +57 -0
  13. package/dist/block/parser.d.ts +57 -0
  14. package/dist/block/parser.js +2 -0
  15. package/dist/block-C3ftt8qO.js +610 -0
  16. package/dist/block-DsxTiUms.cjs +747 -0
  17. package/dist/defaults/defaults.d.cts +1 -1
  18. package/dist/defaults/defaults.d.ts +1 -1
  19. package/dist/emit/emit.cjs +7 -647
  20. package/dist/emit/emit.d.cts +22 -3
  21. package/dist/emit/emit.d.ts +22 -3
  22. package/dist/emit/emit.js +2 -646
  23. package/dist/emit/html-table.d.cts +1 -1
  24. package/dist/emit/html-table.d.ts +1 -1
  25. package/dist/emit/inline.cjs +1 -1
  26. package/dist/emit/inline.js +1 -1
  27. package/dist/emit/list-render.cjs +29 -0
  28. package/dist/emit/list-render.d.cts +81 -0
  29. package/dist/emit/list-render.d.ts +81 -0
  30. package/dist/emit/list-render.js +2 -0
  31. package/dist/emit/setext.cjs +143 -0
  32. package/dist/emit/setext.d.cts +30 -0
  33. package/dist/emit/setext.d.ts +30 -0
  34. package/dist/emit/setext.js +119 -0
  35. package/dist/emit/table.d.cts +1 -11
  36. package/dist/emit/table.d.ts +1 -11
  37. package/dist/emit-CCOoudJW.cjs +734 -0
  38. package/dist/emit-Do1KMQHB.js +537 -0
  39. package/dist/index.d.cts +2 -2
  40. package/dist/index.d.ts +2 -2
  41. package/dist/inline/entity.cjs +1 -1
  42. package/dist/inline/entity.js +1 -1
  43. package/dist/inline/inline.cjs +2 -2
  44. package/dist/inline/inline.d.cts +1 -1
  45. package/dist/inline/inline.d.ts +1 -1
  46. package/dist/inline/inline.js +2 -2
  47. package/dist/{inline-CArcArOD.d.ts → inline-BG6ge5m2.d.ts} +1 -1
  48. package/dist/{inline-GzD5QtFh.d.cts → inline-BxX0iOy6.d.cts} +1 -1
  49. package/dist/lower/lower.cjs +3 -3
  50. package/dist/lower/lower.d.cts +1 -1
  51. package/dist/lower/lower.d.ts +1 -1
  52. package/dist/lower/lower.js +2 -2
  53. package/dist/node-DcxnTjF0.d.cts +46 -0
  54. package/dist/node-w8dVfAUD.d.ts +46 -0
  55. package/dist/options/options.d.cts +1 -43
  56. package/dist/options/options.d.ts +1 -43
  57. package/dist/options-CZoMEGL8.d.ts +44 -0
  58. package/dist/options-ZnZOMG3X.d.cts +44 -0
  59. package/dist/read.d.cts +1 -1
  60. package/dist/read.d.ts +1 -1
  61. package/dist/scan/entity-table-n-z.cjs +207 -0
  62. package/dist/scan/entity-table-n-z.d.cts +4 -0
  63. package/dist/scan/entity-table-n-z.d.ts +4 -0
  64. package/dist/scan/entity-table-n-z.js +206 -0
  65. package/dist/scan/entity-table-t-z.cjs +28 -0
  66. package/dist/scan/entity-table-t-z.d.cts +4 -0
  67. package/dist/scan/entity-table-t-z.d.ts +4 -0
  68. package/dist/scan/entity-table-t-z.js +27 -0
  69. package/dist/scan/entity-table-u-z.cjs +59 -0
  70. package/dist/scan/entity-table-u-z.d.cts +4 -0
  71. package/dist/scan/entity-table-u-z.d.ts +4 -0
  72. package/dist/scan/entity-table-u-z.js +58 -0
  73. package/dist/scan/entity-table-w-z.cjs +11 -0
  74. package/dist/scan/entity-table-w-z.d.cts +4 -0
  75. package/dist/scan/entity-table-w-z.d.ts +4 -0
  76. package/dist/scan/entity-table-w-z.js +10 -0
  77. package/dist/scan/entity-table-x-z.cjs +10 -0
  78. package/dist/scan/entity-table-x-z.d.cts +4 -0
  79. package/dist/scan/entity-table-x-z.d.ts +4 -0
  80. package/dist/scan/entity-table-x-z.js +9 -0
  81. package/dist/scan/entity-table-y-z-2.cjs +780 -0
  82. package/dist/scan/entity-table-y-z-2.d.cts +4 -0
  83. package/dist/scan/entity-table-y-z-2.d.ts +4 -0
  84. package/dist/scan/entity-table-y-z-2.js +779 -0
  85. package/dist/scan/entity-table-y-z.cjs +779 -0
  86. package/dist/scan/entity-table-y-z.d.cts +4 -0
  87. package/dist/scan/entity-table-y-z.d.ts +4 -0
  88. package/dist/scan/entity-table-y-z.js +778 -0
  89. package/dist/scan/entity-table.cjs +20 -1834
  90. package/dist/scan/entity-table.d.cts +2 -1
  91. package/dist/scan/entity-table.d.ts +2 -1
  92. package/dist/scan/entity-table.js +20 -1835
  93. package/dist/table-BFbOhm0R.d.ts +12 -0
  94. package/dist/table-PtkYEYdL.d.cts +12 -0
  95. package/dist/write.cjs +2 -2
  96. package/dist/write.d.cts +1 -1
  97. package/dist/write.d.ts +1 -1
  98. package/dist/write.js +1 -1
  99. package/package.json +2 -2
@@ -0,0 +1,610 @@
1
+ import { BlockNode, canContain, suppressesBlockStarts } from "./block/node.js";
2
+ import { MarkdownDiagnosticCodes, MarkdownNestingLimitExceededError, NOOP_MARKDOWN_DIAGNOSTIC_SINK } from "./diagnostics/diagnostics.js";
3
+ import { matchHtmlBlockStart, matchesHtmlBlockEnd } from "./html/html.js";
4
+ import { unescapeString } from "./inline/entity.js";
5
+ import { matchFootnoteDefinitionMarker } from "./inline/footnote.js";
6
+ import { parseInlines } from "./inline/inline.js";
7
+ import { LINE_ENDING_PATTERN } from "./shared/line-ending.js";
8
+ import "./defaults/defaults.js";
9
+ import { LineCursor } from "./block/line.js";
10
+ import { finalizeListTightness, listsMatch, parseListMarker } from "./block/list.js";
11
+ import { fitRowToColumns, parseTableDelimiterRow, splitTableRow } from "./block/table.js";
12
+ import { extractDefinitions } from "./block/definitions.js";
13
+ //#region src/block/parser.ts
14
+ var BlockParser = class {
15
+ references = /* @__PURE__ */ new Map();
16
+ footnotes = /* @__PURE__ */ new Set();
17
+ document = new BlockNode("document", 1);
18
+ tables;
19
+ footnotesEnabled;
20
+ sink;
21
+ maxNesting;
22
+ tip = this.document;
23
+ oldTip = this.document;
24
+ lastMatchedContainer = this.document;
25
+ line;
26
+ lineNumber = 0;
27
+ nestingDepth = 0;
28
+ constructor(options) {
29
+ this.tables = options.gfmTables ?? true;
30
+ this.footnotesEnabled = options.footnotes ?? true;
31
+ this.sink = options.sink ?? NOOP_MARKDOWN_DIAGNOSTIC_SINK;
32
+ this.maxNesting = options.maxNesting ?? 250;
33
+ }
34
+ parse(source) {
35
+ const lines = source.split(LINE_ENDING_PATTERN);
36
+ const count = source.endsWith("\n") || source.endsWith("\r") ? lines.length - 1 : lines.length;
37
+ for (let index = 0; index < count; index += 1) {
38
+ const text = lines[index];
39
+ if (text !== void 0) this.incorporateLine(text);
40
+ }
41
+ while (this.tip !== this.document) {
42
+ this.reportUnterminatedAtEof(this.tip);
43
+ this.finalize(this.tip);
44
+ }
45
+ return this.document;
46
+ }
47
+ reportUnterminatedAtEof(node) {
48
+ if (node.fenced) {
49
+ this.sink({
50
+ code: MarkdownDiagnosticCodes.UNCLOSED_FENCE,
51
+ severity: "warning",
52
+ message: `fenced code block starting at line ${String(node.startLine)} was never closed by a matching closing fence before the end of the document`,
53
+ line: node.startLine
54
+ });
55
+ return;
56
+ }
57
+ if (node.kind === "htmlBlock" && !HTML_BLOCK_BLANK_LINE_END_TYPES.includes(node.htmlBlockType)) {
58
+ this.sink({
59
+ code: MarkdownDiagnosticCodes.UNTERMINATED_HTML_BLOCK,
60
+ severity: "warning",
61
+ message: `HTML block (type ${String(node.htmlBlockType)}) starting at line ${String(node.startLine)} never met its own end condition before the end of the document`,
62
+ line: node.startLine
63
+ });
64
+ return;
65
+ }
66
+ if (node.kind === "mathBlock") this.sink({
67
+ code: MarkdownDiagnosticCodes.UNCLOSED_MATH_BLOCK,
68
+ severity: "warning",
69
+ message: `math block starting at line ${String(node.startLine)} was never closed by a matching closing $$ before the end of the document`,
70
+ line: node.startLine
71
+ });
72
+ }
73
+ incorporateLine(rawText) {
74
+ this.lineNumber += 1;
75
+ this.line = new LineCursor(rawText.replace(NUL_PATTERN, "�"));
76
+ this.oldTip = this.tip;
77
+ const matched = this.walkOpenBlocks();
78
+ if (matched === void 0) return;
79
+ this.lastMatchedContainer = matched;
80
+ this.addTextToContainer(this.openNewBlocks(matched));
81
+ }
82
+ walkOpenBlocks() {
83
+ let container = this.document;
84
+ for (;;) {
85
+ const lastChild = container.lastChild;
86
+ if (lastChild?.open !== true) return container;
87
+ this.line.findNextNonspace();
88
+ const result = this.continueBlock(lastChild);
89
+ if (result !== "matched") return result === "finished" ? void 0 : container;
90
+ container = lastChild;
91
+ }
92
+ }
93
+ continueBlock(node) {
94
+ switch (node.kind) {
95
+ case "document":
96
+ case "list": return "matched";
97
+ case "blockquote": return this.continueBlockquote();
98
+ case "listItem": return this.continueListItem(node);
99
+ case "footnoteDefinition": return this.continueFootnoteDefinition(node);
100
+ case "codeBlock": return this.continueCodeBlock(node);
101
+ case "mathBlock": return this.continueMathBlock(node);
102
+ case "htmlBlock": return this.line.blank && HTML_BLOCK_BLANK_LINE_END_TYPES.includes(node.htmlBlockType) ? "not-matched" : "matched";
103
+ case "paragraph":
104
+ case "table": return this.line.blank ? "not-matched" : "matched";
105
+ case "heading":
106
+ case "thematicBreak": return "not-matched";
107
+ }
108
+ return assertNeverBlockKind(node.kind);
109
+ }
110
+ continueBlockquote() {
111
+ if (!this.consumeBlockquoteMarker()) return "not-matched";
112
+ return "matched";
113
+ }
114
+ consumeBlockquoteMarker() {
115
+ if (this.line.indented || this.line.peekNextNonspace() !== ">") return false;
116
+ this.line.advanceToNextNonspace();
117
+ this.line.advance(1);
118
+ if (this.line.peek() === " ") this.line.advance(1);
119
+ return true;
120
+ }
121
+ continueListItem(node) {
122
+ const listData = node.listData;
123
+ if (listData === void 0) return "not-matched";
124
+ if (this.line.blank) {
125
+ if (node.children.length === 0) return "not-matched";
126
+ this.line.advanceToNextNonspace();
127
+ return "matched";
128
+ }
129
+ if (this.line.indent >= listData.markerOffset + listData.padding) {
130
+ this.line.advance(listData.markerOffset + listData.padding);
131
+ return "matched";
132
+ }
133
+ return "not-matched";
134
+ }
135
+ continueFootnoteDefinition(node) {
136
+ if (this.line.blank) {
137
+ if (node.children.length === 0) return "not-matched";
138
+ this.line.advanceToNextNonspace();
139
+ return "matched";
140
+ }
141
+ if (this.line.indent >= 4) {
142
+ this.line.advance(4);
143
+ return "matched";
144
+ }
145
+ return "not-matched";
146
+ }
147
+ continueCodeBlock(node) {
148
+ if (!node.fenced) {
149
+ if (this.line.indent >= 4) {
150
+ this.line.advance(4);
151
+ return "matched";
152
+ }
153
+ if (this.line.blank) {
154
+ this.line.advanceToNextNonspace();
155
+ return "matched";
156
+ }
157
+ return "not-matched";
158
+ }
159
+ const rest = this.line.restFromNextNonspace();
160
+ const closing = this.line.indented || !rest.startsWith(node.fenceChar) ? null : CLOSING_CODE_FENCE_PATTERN.exec(rest);
161
+ if (closing !== null && closing[0].length >= node.fenceLength) {
162
+ this.finalize(node);
163
+ return "finished";
164
+ }
165
+ for (let remaining = node.fenceOffset; remaining > 0 && this.line.peek() === " "; remaining -= 1) this.line.advance(1);
166
+ return "matched";
167
+ }
168
+ continueMathBlock(node) {
169
+ if (!this.line.indented && MATH_BLOCK_MARKER_PATTERN.test(this.line.restFromNextNonspace())) {
170
+ this.finalize(node);
171
+ return "finished";
172
+ }
173
+ return "matched";
174
+ }
175
+ openNewBlocks(matchedContainer) {
176
+ let container = matchedContainer;
177
+ let matchedLeaf = suppressesBlockStarts(container.kind);
178
+ while (!matchedLeaf) {
179
+ this.line.findNextNonspace();
180
+ const result = this.tryBlockStart(container);
181
+ if (result === "none") {
182
+ this.line.advanceToNextNonspace();
183
+ break;
184
+ }
185
+ container = this.tip;
186
+ matchedLeaf = result === "leaf";
187
+ }
188
+ return container;
189
+ }
190
+ tryBlockStart(container) {
191
+ const starts = [
192
+ () => this.tryBlockquoteStart(),
193
+ () => this.tryAtxHeadingStart(),
194
+ () => this.tryCodeFenceStart(),
195
+ () => this.tryMathBlockStart(),
196
+ () => this.tryFootnoteDefinitionStart(container),
197
+ () => this.tryHtmlBlockStart(),
198
+ () => this.tryPromoteParagraph(container),
199
+ () => this.tryThematicBreakStart(),
200
+ () => this.tryListItemStart(container),
201
+ () => this.tryIndentedCodeStart()
202
+ ];
203
+ for (const start of starts) {
204
+ const result = start();
205
+ if (result !== "none") return result;
206
+ }
207
+ return "none";
208
+ }
209
+ tryBlockquoteStart() {
210
+ if (!this.consumeBlockquoteMarker()) return "none";
211
+ this.closeUnmatchedBlocks();
212
+ this.addChild("blockquote");
213
+ return "container";
214
+ }
215
+ tryAtxHeadingStart() {
216
+ if (this.line.indented) return "none";
217
+ const rest = this.line.restFromNextNonspace();
218
+ const match = ATX_MARKER_PATTERN.exec(rest);
219
+ if (match === null) return "none";
220
+ this.closeUnmatchedBlocks();
221
+ const heading = this.addChild("heading");
222
+ heading.level = headingLevelOf(match[0].trim().length);
223
+ heading.content = rest.slice(match[0].length).replace(ATX_ONLY_CLOSING_SEQUENCE_PATTERN, "").replace(ATX_TRAILING_CLOSING_SEQUENCE_PATTERN, "");
224
+ this.line.advanceToEndOfLine();
225
+ return "leaf";
226
+ }
227
+ tryCodeFenceStart() {
228
+ if (this.line.indented) return "none";
229
+ const match = CODE_FENCE_PATTERN.exec(this.line.restFromNextNonspace());
230
+ if (match === null) return "none";
231
+ const fence = match[0];
232
+ const fenceChar = fence.charAt(0);
233
+ if (fenceChar !== "`" && fenceChar !== "~") return "none";
234
+ this.closeUnmatchedBlocks();
235
+ const block = this.addChild("codeBlock");
236
+ block.fenced = true;
237
+ block.fenceChar = fenceChar;
238
+ block.fenceLength = fence.length;
239
+ block.fenceOffset = this.line.indent;
240
+ this.line.advanceToNextNonspace();
241
+ this.line.advance(fence.length);
242
+ return "leaf";
243
+ }
244
+ tryMathBlockStart() {
245
+ if (this.line.indented) return "none";
246
+ if (!MATH_BLOCK_MARKER_PATTERN.test(this.line.restFromNextNonspace())) return "none";
247
+ this.closeUnmatchedBlocks();
248
+ this.addChild("mathBlock");
249
+ this.line.advanceToEndOfLine();
250
+ return "leaf";
251
+ }
252
+ tryFootnoteDefinitionStart(container) {
253
+ if (!this.footnotesEnabled || this.line.indented || !this.footnoteDefinitionMayOpenIn(container)) return "none";
254
+ const marker = matchFootnoteDefinitionMarker(this.line.restFromNextNonspace());
255
+ if (marker === void 0) return "none";
256
+ if (this.footnotes.has(marker.label)) this.sink({
257
+ code: MarkdownDiagnosticCodes.DUPLICATE_FOOTNOTE_DEFINITION,
258
+ severity: "warning",
259
+ message: `footnote "${marker.label}" was already defined earlier in the document; every reference resolves to the first definition, and both definitions are kept as written`,
260
+ line: this.lineNumber
261
+ });
262
+ this.footnotes.add(marker.label);
263
+ this.line.advanceToNextNonspace();
264
+ this.closeUnmatchedBlocks();
265
+ const node = this.addChild("footnoteDefinition");
266
+ node.footnoteLabel = marker.label;
267
+ this.line.advance(marker.markerLength);
268
+ return "container";
269
+ }
270
+ footnoteDefinitionMayOpenIn(container) {
271
+ let node = container;
272
+ while (node?.kind === "list") node = node.parent;
273
+ return node?.kind === "document" || node?.kind === "blockquote" || node?.kind === "listItem";
274
+ }
275
+ tryHtmlBlockStart() {
276
+ if (this.line.indented) return "none";
277
+ const interruptsParagraph = this.tip.kind === "paragraph";
278
+ const type = matchHtmlBlockStart(this.line.restFromNextNonspace(), interruptsParagraph);
279
+ if (type === void 0) return "none";
280
+ this.closeUnmatchedBlocks();
281
+ this.addChild("htmlBlock").htmlBlockType = type;
282
+ return "leaf";
283
+ }
284
+ tryPromoteParagraph(container) {
285
+ if (this.line.indented || container.kind !== "paragraph") return "none";
286
+ const setext = this.trySetextHeading(container);
287
+ return setext === "none" ? this.tryTableHeader(container) : setext;
288
+ }
289
+ trySetextHeading(paragraph) {
290
+ const match = SETEXT_UNDERLINE_PATTERN.exec(this.line.restFromNextNonspace());
291
+ if (match === null) return "none";
292
+ paragraph.content = extractDefinitions(paragraph.content, this.references, this.sink, paragraph.startLine);
293
+ if (isBlankContent(paragraph.content)) return "none";
294
+ const heading = new BlockNode("heading", paragraph.startLine);
295
+ heading.level = match[0].startsWith("=") ? 1 : 2;
296
+ heading.setext = true;
297
+ heading.content = paragraph.content;
298
+ paragraph.replaceWith(heading);
299
+ this.tip = heading;
300
+ this.line.advanceToEndOfLine();
301
+ return "leaf";
302
+ }
303
+ tryTableHeader(paragraph) {
304
+ if (!this.tables) return "none";
305
+ const alignments = parseTableDelimiterRow(this.line.restFromNextNonspace());
306
+ if (alignments === void 0) return "none";
307
+ const lines = paragraph.content.split("\n");
308
+ const secondToLastLineOffset = -2;
309
+ const headerLine = lines.at(secondToLastLineOffset);
310
+ if (headerLine === void 0 || splitTableRow(headerLine).length !== alignments.length) return "none";
311
+ paragraph.content = lines.slice(0, secondToLastLineOffset).map((text) => `${text}\n`).join("");
312
+ const table = this.addChild("table");
313
+ table.alignments = alignments;
314
+ table.headerLine = headerLine;
315
+ this.line.advanceToEndOfLine();
316
+ return "leaf";
317
+ }
318
+ tryThematicBreakStart() {
319
+ if (this.line.indented || !THEMATIC_BREAK_PATTERN.test(this.line.restFromNextNonspace())) return "none";
320
+ this.closeUnmatchedBlocks();
321
+ this.addChild("thematicBreak");
322
+ this.line.advanceToEndOfLine();
323
+ return "leaf";
324
+ }
325
+ tryListItemStart(container) {
326
+ const data = parseListMarker(this.line, container.kind === "paragraph");
327
+ if (data === void 0) return "none";
328
+ this.closeUnmatchedBlocks();
329
+ const openList = this.tip.listData;
330
+ if (this.tip.kind !== "list" || openList === void 0 || !listsMatch(openList, data)) this.addChild("list").listData = data;
331
+ this.addChild("listItem").listData = data;
332
+ return "container";
333
+ }
334
+ tryIndentedCodeStart() {
335
+ if (!this.line.indented || this.tip.kind === "paragraph" || this.line.blank) return "none";
336
+ this.line.advance(4);
337
+ this.closeUnmatchedBlocks();
338
+ this.addChild("codeBlock");
339
+ return "leaf";
340
+ }
341
+ addTextToContainer(container) {
342
+ if (this.tip.kind === "paragraph" && !this.line.blank) {
343
+ this.addLine();
344
+ return;
345
+ }
346
+ this.closeUnmatchedBlocks();
347
+ const lastChild = container.lastChild;
348
+ if (this.line.blank && lastChild !== void 0) lastChild.lastLineBlank = true;
349
+ this.recordBlankLineForTightness(container);
350
+ if (suppressesBlockStarts(container.kind) || container.kind === "table") {
351
+ this.addLine();
352
+ if (container.kind === "htmlBlock" && matchesHtmlBlockEnd(this.line.rest(), container.htmlBlockType)) this.finalize(container);
353
+ return;
354
+ }
355
+ if (!this.line.atEnd && !this.line.blank) {
356
+ this.addChild("paragraph");
357
+ this.addLine();
358
+ }
359
+ }
360
+ recordBlankLineForTightness(container) {
361
+ const blank = this.line.blank && !(container.kind === "blockquote" || container.fenced || container.kind === "listItem");
362
+ for (let node = container; node !== void 0; node = node.parent) node.lastLineBlank = blank;
363
+ }
364
+ addLine() {
365
+ this.tip.content += `${this.line.rest()}
366
+ `;
367
+ }
368
+ addChild(kind) {
369
+ while (!canContain(this.tip.kind, kind)) this.finalize(this.tip);
370
+ if (this.nestingDepth >= this.maxNesting) throw new MarkdownNestingLimitExceededError(this.maxNesting);
371
+ const node = new BlockNode(kind, this.lineNumber);
372
+ this.tip.appendChild(node);
373
+ this.tip = node;
374
+ this.nestingDepth += 1;
375
+ return node;
376
+ }
377
+ closeUnmatchedBlocks() {
378
+ while (this.oldTip !== this.lastMatchedContainer) {
379
+ const parent = this.oldTip.parent;
380
+ this.finalize(this.oldTip);
381
+ if (parent === void 0) break;
382
+ this.oldTip = parent;
383
+ }
384
+ }
385
+ finalize(node) {
386
+ const above = node.parent;
387
+ node.open = false;
388
+ this.finalizeContent(node);
389
+ this.nestingDepth -= 1;
390
+ this.tip = above ?? this.document;
391
+ }
392
+ finalizeContent(node) {
393
+ switch (node.kind) {
394
+ case "paragraph":
395
+ node.content = extractDefinitions(node.content, this.references, this.sink, node.startLine);
396
+ if (isBlankContent(node.content)) node.unlink();
397
+ return;
398
+ case "codeBlock":
399
+ this.finalizeCodeBlock(node);
400
+ return;
401
+ case "mathBlock":
402
+ this.finalizeMathBlock(node);
403
+ return;
404
+ case "htmlBlock":
405
+ node.literal = node.content.replace(TRAILING_HTML_BLANK_LINES_PATTERN, "");
406
+ return;
407
+ case "list":
408
+ finalizeListTightness(node);
409
+ return;
410
+ default: return;
411
+ }
412
+ }
413
+ finalizeCodeBlock(node) {
414
+ if (!node.fenced) {
415
+ node.literal = node.content.replace(TRAILING_BLANK_LINES_PATTERN, "\n");
416
+ return;
417
+ }
418
+ const breakIndex = node.content.indexOf("\n");
419
+ node.infoString = unescapeString(node.content.slice(0, breakIndex).trim());
420
+ node.literal = node.content.slice(breakIndex + 1);
421
+ }
422
+ finalizeMathBlock(node) {
423
+ node.literal = node.content.slice(1);
424
+ }
425
+ };
426
+ //#endregion
427
+ //#region src/block/block.ts
428
+ const TASK_LIST_MARKER_PATTERN = /^\[([ xX])\][ \t]/;
429
+ const NUL_REPLACEMENT = "�";
430
+ const NUL_PATTERN = /\0/g;
431
+ const ATX_MARKER_PATTERN = /^#{1,6}(?:[ \t]+|$)/;
432
+ const ATX_ONLY_CLOSING_SEQUENCE_PATTERN = /^[ \t]*#+[ \t]*$/;
433
+ const ATX_TRAILING_CLOSING_SEQUENCE_PATTERN = /[ \t]+#+[ \t]*$/;
434
+ const CODE_FENCE_PATTERN = /^`{3,}(?!.*`)|^~{3,}/;
435
+ const CLOSING_CODE_FENCE_PATTERN = /^(?:`{3,}|~{3,})(?=[ \t]*$)/;
436
+ const MATH_BLOCK_MARKER_PATTERN = /^\$\$[ \t]*$/;
437
+ const ACCUMULATED_LINE_ENDING = "\n";
438
+ const SETEXT_UNDERLINE_PATTERN = /^(?:=+|-+)[ \t]*$/;
439
+ const THEMATIC_BREAK_PATTERN = /^(?:\*[ \t]*){3,}$|^(?:_[ \t]*){3,}$|^(?:-[ \t]*){3,}$/;
440
+ const BLANK_CONTENT_PATTERN = /^[ \t\n]*$/;
441
+ const TRAILING_BLANK_LINES_PATTERN = /(?:\n[ \t]*)+$/;
442
+ const TRAILING_HTML_BLANK_LINES_PATTERN = /(?:\n *)+$/;
443
+ const MAX_HEADING_LEVEL = 6;
444
+ const SETEXT_LEVEL_1 = 1;
445
+ const SETEXT_LEVEL_2 = 2;
446
+ const HTML_BLOCK_BLANK_LINE_END_TYPES = [6, 7];
447
+ function isBlankContent(content) {
448
+ return BLANK_CONTENT_PATTERN.test(content);
449
+ }
450
+ function headingLevelOf(hashes) {
451
+ if (hashes >= 1 && hashes < MAX_HEADING_LEVEL) return hashes;
452
+ return MAX_HEADING_LEVEL;
453
+ }
454
+ const BLOCK_EDGE_SPACE_OR_TAB_PATTERN = /^[ \t]+|[ \t]+$/g;
455
+ function trimBlockContent(text) {
456
+ return (text.endsWith("\n") ? text.slice(0, -1) : text).replace(BLOCK_EDGE_SPACE_OR_TAB_PATTERN, "");
457
+ }
458
+ function toInlineChildren(content, context) {
459
+ return parseInlines(trimBlockContent(content), context.references, context.footnotes, context.options);
460
+ }
461
+ function toHeadingNode(node, context) {
462
+ return {
463
+ type: "heading",
464
+ level: node.level,
465
+ style: node.setext ? "setext" : "atx",
466
+ children: toInlineChildren(node.content, context)
467
+ };
468
+ }
469
+ function extractTaskListMarker(itemChildren) {
470
+ const first = itemChildren[0];
471
+ if (first?.kind !== "paragraph") return;
472
+ const match = TASK_LIST_MARKER_PATTERN.exec(first.content);
473
+ if (match === null) return;
474
+ first.content = first.content.slice(match[0].length);
475
+ return match[1] !== " ";
476
+ }
477
+ function toListItemNode(item, context) {
478
+ const checked = context.options.gfmTaskLists ?? true ? extractTaskListMarker(item.children) : void 0;
479
+ return checked === void 0 ? {
480
+ type: "listItem",
481
+ children: toAstBlocks(item.children, context)
482
+ } : {
483
+ type: "listItem",
484
+ checked,
485
+ children: toAstBlocks(item.children, context)
486
+ };
487
+ }
488
+ function toListNode(node, context) {
489
+ const children = node.children.map((item) => toListItemNode(item, context));
490
+ const data = node.listData;
491
+ if (data?.type === "ordered") return {
492
+ type: "list",
493
+ markerType: "ordered",
494
+ orderedDelimiter: data.delimiter,
495
+ start: data.start,
496
+ tight: node.tight,
497
+ children
498
+ };
499
+ return {
500
+ type: "list",
501
+ markerType: "bullet",
502
+ bulletMarker: data?.bulletChar,
503
+ tight: node.tight,
504
+ children
505
+ };
506
+ }
507
+ function toTableRow(cells, header, context) {
508
+ return {
509
+ type: "tableRow",
510
+ header,
511
+ children: cells.map((cell) => ({
512
+ type: "tableCell",
513
+ children: toInlineChildren(cell, context)
514
+ }))
515
+ };
516
+ }
517
+ function toTableNode(node, context) {
518
+ const sink = context.options.sink ?? NOOP_MARKDOWN_DIAGNOSTIC_SINK;
519
+ const columnCount = node.alignments.length;
520
+ const rows = [toTableRow(fitRowToColumns(splitTableRow(node.headerLine), columnCount), true, context)];
521
+ for (const rowLine of node.content.split("\n")) {
522
+ if (rowLine.length === 0) continue;
523
+ const cells = splitTableRow(rowLine);
524
+ if (cells.length !== columnCount) sink({
525
+ code: MarkdownDiagnosticCodes.TABLE_CELL_COUNT_MISMATCH,
526
+ severity: "warning",
527
+ message: `table row has ${String(cells.length)} cell(s), but the header row declares ${String(columnCount)}; the row is padded with empty cells or truncated to fit`,
528
+ line: node.startLine
529
+ });
530
+ rows.push(toTableRow(fitRowToColumns(cells, columnCount), false, context));
531
+ }
532
+ return {
533
+ type: "table",
534
+ alignments: node.alignments,
535
+ children: rows
536
+ };
537
+ }
538
+ function toAstBlock(node, context) {
539
+ switch (node.kind) {
540
+ case "paragraph": return {
541
+ type: "paragraph",
542
+ children: toInlineChildren(node.content, context)
543
+ };
544
+ case "heading": return toHeadingNode(node, context);
545
+ case "blockquote": return {
546
+ type: "blockquote",
547
+ children: toAstBlocks(node.children, context)
548
+ };
549
+ case "list": return toListNode(node, context);
550
+ case "footnoteDefinition": return {
551
+ type: "footnoteDefinition",
552
+ label: node.footnoteLabel,
553
+ children: toAstBlocks(node.children, context)
554
+ };
555
+ case "codeBlock": return node.fenced ? {
556
+ type: "codeBlock",
557
+ fenced: true,
558
+ fenceChar: node.fenceChar,
559
+ infoString: node.infoString,
560
+ literal: node.literal
561
+ } : {
562
+ type: "codeBlock",
563
+ fenced: false,
564
+ literal: node.literal
565
+ };
566
+ case "htmlBlock": return {
567
+ type: "htmlBlock",
568
+ literal: node.literal
569
+ };
570
+ case "thematicBreak": return { type: "thematicBreak" };
571
+ case "mathBlock": return {
572
+ type: "mathBlock",
573
+ literal: node.literal
574
+ };
575
+ case "table": return toTableNode(node, context);
576
+ case "document":
577
+ case "listItem": return;
578
+ }
579
+ return assertNeverBlockKind(node.kind);
580
+ }
581
+ function toAstBlocks(nodes, context) {
582
+ const blocks = [];
583
+ for (const node of nodes) {
584
+ const converted = toAstBlock(node, context);
585
+ if (converted !== void 0) blocks.push(converted);
586
+ }
587
+ return blocks;
588
+ }
589
+ function parseMarkdown(source, options = {}) {
590
+ const parser = new BlockParser(options);
591
+ const root = parser.parse(source);
592
+ const context = {
593
+ references: parser.references,
594
+ footnotes: parser.footnotes,
595
+ options
596
+ };
597
+ return {
598
+ document: {
599
+ type: "document",
600
+ children: toAstBlocks(root.children, context)
601
+ },
602
+ references: context.references,
603
+ footnotes: context.footnotes
604
+ };
605
+ }
606
+ function assertNeverBlockKind(kind) {
607
+ throw new Error(`markdown-codec: unhandled block kind ${JSON.stringify(kind)}`);
608
+ }
609
+ //#endregion
610
+ export { BlockParser as C, trimBlockContent as S, TRAILING_HTML_BLANK_LINES_PATTERN as _, CLOSING_CODE_FENCE_PATTERN as a, isBlankContent as b, MATH_BLOCK_MARKER_PATTERN as c, SETEXT_LEVEL_1 as d, SETEXT_LEVEL_2 as f, TRAILING_BLANK_LINES_PATTERN as g, THEMATIC_BREAK_PATTERN as h, ATX_TRAILING_CLOSING_SEQUENCE_PATTERN as i, NUL_PATTERN as l, TASK_LIST_MARKER_PATTERN as m, ATX_MARKER_PATTERN as n, CODE_FENCE_PATTERN as o, SETEXT_UNDERLINE_PATTERN as p, ATX_ONLY_CLOSING_SEQUENCE_PATTERN as r, HTML_BLOCK_BLANK_LINE_END_TYPES as s, ACCUMULATED_LINE_ENDING as t, NUL_REPLACEMENT as u, assertNeverBlockKind as v, parseMarkdown as x, headingLevelOf as y };