markdown-codec 0.0.0 → 1.0.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 (171) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +215 -0
  3. package/dist/ast/ast.cjs +25 -0
  4. package/dist/ast/ast.d.cts +2 -0
  5. package/dist/ast/ast.d.ts +2 -0
  6. package/dist/ast/ast.js +23 -0
  7. package/dist/ast-BXYwy08e.d.cts +160 -0
  8. package/dist/ast-BXYwy08e.d.ts +160 -0
  9. package/dist/block/block.cjs +530 -0
  10. package/dist/block/block.d.cts +18 -0
  11. package/dist/block/block.d.ts +18 -0
  12. package/dist/block/block.js +529 -0
  13. package/dist/block/definitions.cjs +59 -0
  14. package/dist/block/definitions.d.cts +6 -0
  15. package/dist/block/definitions.d.ts +6 -0
  16. package/dist/block/definitions.js +58 -0
  17. package/dist/block/line.cjs +76 -0
  18. package/dist/block/line.d.cts +28 -0
  19. package/dist/block/line.d.ts +28 -0
  20. package/dist/block/line.js +74 -0
  21. package/dist/block/list.cjs +110 -0
  22. package/dist/block/list.d.cts +8 -0
  23. package/dist/block/list.d.ts +8 -0
  24. package/dist/block/list.js +107 -0
  25. package/dist/block/node.cjs +68 -0
  26. package/dist/block/node.d.cts +45 -0
  27. package/dist/block/node.d.ts +45 -0
  28. package/dist/block/node.js +65 -0
  29. package/dist/block/table.cjs +64 -0
  30. package/dist/block/table.d.cts +7 -0
  31. package/dist/block/table.d.ts +7 -0
  32. package/dist/block/table.js +61 -0
  33. package/dist/codec.cjs +22 -0
  34. package/dist/codec.d.cts +361 -0
  35. package/dist/codec.d.ts +361 -0
  36. package/dist/codec.js +20 -0
  37. package/dist/defaults/defaults.cjs +31 -0
  38. package/dist/defaults/defaults.d.cts +16 -0
  39. package/dist/defaults/defaults.d.ts +16 -0
  40. package/dist/defaults/defaults.js +20 -0
  41. package/dist/diagnostics/diagnostics.cjs +85 -0
  42. package/dist/diagnostics/diagnostics.d.cts +2 -0
  43. package/dist/diagnostics/diagnostics.d.ts +2 -0
  44. package/dist/diagnostics/diagnostics.js +77 -0
  45. package/dist/diagnostics-DmuWc7d8.d.cts +61 -0
  46. package/dist/diagnostics-DmuWc7d8.d.ts +61 -0
  47. package/dist/emit/emit.cjs +228 -0
  48. package/dist/emit/emit.d.cts +6 -0
  49. package/dist/emit/emit.d.ts +6 -0
  50. package/dist/emit/emit.js +227 -0
  51. package/dist/emit/front-matter.cjs +24 -0
  52. package/dist/emit/front-matter.d.cts +5 -0
  53. package/dist/emit/front-matter.d.ts +5 -0
  54. package/dist/emit/front-matter.js +23 -0
  55. package/dist/emit/image.cjs +10 -0
  56. package/dist/emit/image.d.cts +5 -0
  57. package/dist/emit/image.d.ts +5 -0
  58. package/dist/emit/image.js +9 -0
  59. package/dist/emit/inline.cjs +183 -0
  60. package/dist/emit/inline.d.cts +12 -0
  61. package/dist/emit/inline.d.ts +12 -0
  62. package/dist/emit/inline.js +180 -0
  63. package/dist/emit/table.cjs +73 -0
  64. package/dist/emit/table.d.cts +10 -0
  65. package/dist/emit/table.d.ts +10 -0
  66. package/dist/emit/table.js +72 -0
  67. package/dist/html/html.cjs +116 -0
  68. package/dist/html/html.d.cts +2 -0
  69. package/dist/html/html.d.ts +2 -0
  70. package/dist/html/html.js +113 -0
  71. package/dist/html/render.cjs +193 -0
  72. package/dist/html/render.d.cts +8 -0
  73. package/dist/html/render.d.ts +8 -0
  74. package/dist/html/render.js +189 -0
  75. package/dist/html-bkz2QTuq.d.cts +7 -0
  76. package/dist/html-bkz2QTuq.d.ts +7 -0
  77. package/dist/image/image.cjs +129 -0
  78. package/dist/image/image.d.cts +2 -0
  79. package/dist/image/image.d.ts +2 -0
  80. package/dist/image/image.js +125 -0
  81. package/dist/image-C4KYmz_L.d.cts +19 -0
  82. package/dist/image-Cm3hT5PS.d.ts +19 -0
  83. package/dist/image-DescdRgq.d.cts +12 -0
  84. package/dist/image-DescdRgq.d.ts +12 -0
  85. package/dist/index.cjs +17 -0
  86. package/dist/index.d.cts +7 -0
  87. package/dist/index.d.ts +7 -0
  88. package/dist/index.js +5 -0
  89. package/dist/inline/chars.cjs +50 -0
  90. package/dist/inline/chars.d.cts +11 -0
  91. package/dist/inline/chars.d.ts +11 -0
  92. package/dist/inline/chars.js +42 -0
  93. package/dist/inline/delimiter.cjs +136 -0
  94. package/dist/inline/delimiter.d.cts +29 -0
  95. package/dist/inline/delimiter.d.ts +29 -0
  96. package/dist/inline/delimiter.js +132 -0
  97. package/dist/inline/entity.cjs +67 -0
  98. package/dist/inline/entity.d.cts +9 -0
  99. package/dist/inline/entity.d.ts +9 -0
  100. package/dist/inline/entity.js +65 -0
  101. package/dist/inline/gfm-autolink.cjs +156 -0
  102. package/dist/inline/gfm-autolink.d.cts +5 -0
  103. package/dist/inline/gfm-autolink.d.ts +5 -0
  104. package/dist/inline/gfm-autolink.js +155 -0
  105. package/dist/inline/inline.cjs +457 -0
  106. package/dist/inline/inline.d.cts +2 -0
  107. package/dist/inline/inline.d.ts +2 -0
  108. package/dist/inline/inline.js +456 -0
  109. package/dist/inline/link.cjs +130 -0
  110. package/dist/inline/link.d.cts +2 -0
  111. package/dist/inline/link.d.ts +2 -0
  112. package/dist/inline/link.js +124 -0
  113. package/dist/inline/node.cjs +57 -0
  114. package/dist/inline/node.d.cts +23 -0
  115. package/dist/inline/node.d.ts +23 -0
  116. package/dist/inline/node.js +55 -0
  117. package/dist/inline-B50cM6cn.d.ts +10 -0
  118. package/dist/inline-C9YEGDV5.d.cts +10 -0
  119. package/dist/link-Dv4kxVjk.d.cts +18 -0
  120. package/dist/link-Dv4kxVjk.d.ts +18 -0
  121. package/dist/lower/front-matter.cjs +75 -0
  122. package/dist/lower/front-matter.d.cts +10 -0
  123. package/dist/lower/front-matter.d.ts +10 -0
  124. package/dist/lower/front-matter.js +74 -0
  125. package/dist/lower/image.cjs +29 -0
  126. package/dist/lower/image.d.cts +2 -0
  127. package/dist/lower/image.d.ts +2 -0
  128. package/dist/lower/image.js +28 -0
  129. package/dist/lower/inline.cjs +96 -0
  130. package/dist/lower/inline.d.cts +19 -0
  131. package/dist/lower/inline.d.ts +19 -0
  132. package/dist/lower/inline.js +93 -0
  133. package/dist/lower/lower.cjs +293 -0
  134. package/dist/lower/lower.d.cts +8 -0
  135. package/dist/lower/lower.d.ts +8 -0
  136. package/dist/lower/lower.js +291 -0
  137. package/dist/lower/table.cjs +27 -0
  138. package/dist/lower/table.d.cts +7 -0
  139. package/dist/lower/table.d.ts +7 -0
  140. package/dist/lower/table.js +26 -0
  141. package/dist/options/options.cjs +0 -0
  142. package/dist/options/options.d.cts +43 -0
  143. package/dist/options/options.d.ts +43 -0
  144. package/dist/options/options.js +0 -0
  145. package/dist/read.cjs +20 -0
  146. package/dist/read.d.cts +11 -0
  147. package/dist/read.d.ts +11 -0
  148. package/dist/read.js +19 -0
  149. package/dist/scan/entity-table.cjs +2131 -0
  150. package/dist/scan/entity-table.d.cts +4 -0
  151. package/dist/scan/entity-table.d.ts +4 -0
  152. package/dist/scan/entity-table.js +2130 -0
  153. package/dist/scan/scan.cjs +80 -0
  154. package/dist/scan/scan.d.cts +2 -0
  155. package/dist/scan/scan.d.ts +2 -0
  156. package/dist/scan/scan.js +78 -0
  157. package/dist/scan-DeBxgG-r.d.cts +30 -0
  158. package/dist/scan-DeBxgG-r.d.ts +30 -0
  159. package/dist/shared/list-id.cjs +36 -0
  160. package/dist/shared/list-id.d.cts +22 -0
  161. package/dist/shared/list-id.d.ts +22 -0
  162. package/dist/shared/list-id.js +32 -0
  163. package/dist/shared/style-constants.cjs +34 -0
  164. package/dist/shared/style-constants.d.cts +14 -0
  165. package/dist/shared/style-constants.d.ts +14 -0
  166. package/dist/shared/style-constants.js +23 -0
  167. package/dist/write.cjs +9 -0
  168. package/dist/write.d.cts +6 -0
  169. package/dist/write.d.ts +6 -0
  170. package/dist/write.js +8 -0
  171. package/package.json +92 -2
@@ -0,0 +1,529 @@
1
+ import "../defaults/defaults.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 { parseInlines } from "../inline/inline.js";
6
+ import { extractDefinitions } from "./definitions.js";
7
+ import { LineCursor } from "./line.js";
8
+ import { finalizeListTightness, listsMatch, parseListMarker } from "./list.js";
9
+ import { BlockNode, acceptsLines, canContain } from "./node.js";
10
+ import { fitRowToColumns, parseTableDelimiterRow, splitTableRow } from "./table.js";
11
+ //#region src/block/block.ts
12
+ const TASK_LIST_MARKER_PATTERN = /^\[([ xX])\][ \t]/;
13
+ const NUL_REPLACEMENT = "�";
14
+ const NUL_PATTERN = /\0/g;
15
+ const LINE_ENDING_PATTERN = /\r\n|\n|\r/;
16
+ const MAYBE_SPECIAL_PATTERN = /^[#`~*+_=<>0-9|:-]/;
17
+ const ATX_MARKER_PATTERN = /^#{1,6}(?:[ \t]+|$)/;
18
+ const ATX_ONLY_CLOSING_SEQUENCE_PATTERN = /^[ \t]*#+[ \t]*$/;
19
+ const ATX_TRAILING_CLOSING_SEQUENCE_PATTERN = /[ \t]+#+[ \t]*$/;
20
+ const CODE_FENCE_PATTERN = /^`{3,}(?!.*`)|^~{3,}/;
21
+ const CLOSING_CODE_FENCE_PATTERN = /^(?:`{3,}|~{3,})(?=[ \t]*$)/;
22
+ const SETEXT_UNDERLINE_PATTERN = /^(?:=+|-+)[ \t]*$/;
23
+ const THEMATIC_BREAK_PATTERN = /^(?:\*[ \t]*){3,}$|^(?:_[ \t]*){3,}$|^(?:-[ \t]*){3,}$/;
24
+ const BLANK_CONTENT_PATTERN = /^[ \t\n]*$/;
25
+ const TRAILING_BLANK_LINES_PATTERN = /(?:\n[ \t]*)+$/;
26
+ const TRAILING_HTML_BLANK_LINES_PATTERN = /(?:\n *)+$/;
27
+ const MAX_HEADING_LEVEL = 6;
28
+ const SETEXT_LEVEL_1 = 1;
29
+ const SETEXT_LEVEL_2 = 2;
30
+ const HTML_BLOCK_BLANK_LINE_END_TYPES = [6, 7];
31
+ function isBlankContent(content) {
32
+ return BLANK_CONTENT_PATTERN.test(content);
33
+ }
34
+ function headingLevelOf(hashes) {
35
+ switch (hashes) {
36
+ case 1: return 1;
37
+ case 2: return 2;
38
+ case 3: return 3;
39
+ case 4: return 4;
40
+ case 5: return 5;
41
+ default: return MAX_HEADING_LEVEL;
42
+ }
43
+ }
44
+ var BlockParser = class {
45
+ references = /* @__PURE__ */ new Map();
46
+ document = new BlockNode("document", 1);
47
+ tables;
48
+ sink;
49
+ maxNesting;
50
+ tip = this.document;
51
+ oldTip = this.document;
52
+ lastMatchedContainer = this.document;
53
+ allClosed = true;
54
+ line = new LineCursor("");
55
+ lineNumber = 0;
56
+ nestingDepth = 0;
57
+ constructor(options) {
58
+ this.tables = options.gfmTables ?? true;
59
+ this.sink = options.sink ?? NOOP_MARKDOWN_DIAGNOSTIC_SINK;
60
+ this.maxNesting = options.maxNesting ?? 250;
61
+ }
62
+ parse(source) {
63
+ const lines = source.split(LINE_ENDING_PATTERN);
64
+ const count = source.endsWith("\n") || source.endsWith("\r") ? lines.length - 1 : lines.length;
65
+ for (let index = 0; index < count; index += 1) {
66
+ const text = lines[index];
67
+ if (text !== void 0) this.incorporateLine(text);
68
+ }
69
+ while (this.tip.open) {
70
+ this.reportUnterminatedAtEof(this.tip);
71
+ this.finalize(this.tip);
72
+ }
73
+ return this.document;
74
+ }
75
+ reportUnterminatedAtEof(node) {
76
+ if (node.kind === "codeBlock" && node.fenced) {
77
+ this.sink({
78
+ code: MarkdownDiagnosticCodes.UNCLOSED_FENCE,
79
+ severity: "warning",
80
+ message: `fenced code block starting at line ${String(node.startLine)} was never closed by a matching closing fence before the end of the document`,
81
+ line: node.startLine
82
+ });
83
+ return;
84
+ }
85
+ if (node.kind === "htmlBlock" && !HTML_BLOCK_BLANK_LINE_END_TYPES.includes(node.htmlBlockType)) this.sink({
86
+ code: MarkdownDiagnosticCodes.UNTERMINATED_HTML_BLOCK,
87
+ severity: "warning",
88
+ 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`,
89
+ line: node.startLine
90
+ });
91
+ }
92
+ incorporateLine(rawText) {
93
+ this.lineNumber += 1;
94
+ this.line = new LineCursor(rawText.replace(NUL_PATTERN, NUL_REPLACEMENT));
95
+ this.oldTip = this.tip;
96
+ const matched = this.walkOpenBlocks();
97
+ if (matched === void 0) return;
98
+ this.allClosed = matched === this.oldTip;
99
+ this.lastMatchedContainer = matched;
100
+ this.addTextToContainer(this.openNewBlocks(matched));
101
+ }
102
+ walkOpenBlocks() {
103
+ let container = this.document;
104
+ for (;;) {
105
+ const lastChild = container.lastChild;
106
+ if (lastChild?.open !== true) return container;
107
+ this.line.findNextNonspace();
108
+ const result = this.continueBlock(lastChild);
109
+ if (result === "finished") return;
110
+ if (result === "not-matched") return container;
111
+ container = lastChild;
112
+ }
113
+ }
114
+ continueBlock(node) {
115
+ switch (node.kind) {
116
+ case "document":
117
+ case "list": return "matched";
118
+ case "blockquote": return this.continueBlockquote();
119
+ case "listItem": return this.continueListItem(node);
120
+ case "codeBlock": return this.continueCodeBlock(node);
121
+ case "htmlBlock": return this.line.blank && HTML_BLOCK_BLANK_LINE_END_TYPES.includes(node.htmlBlockType) ? "not-matched" : "matched";
122
+ case "paragraph":
123
+ case "table": return this.line.blank ? "not-matched" : "matched";
124
+ case "heading":
125
+ case "thematicBreak": return "not-matched";
126
+ }
127
+ }
128
+ continueBlockquote() {
129
+ if (!this.consumeBlockquoteMarker()) return "not-matched";
130
+ return "matched";
131
+ }
132
+ consumeBlockquoteMarker() {
133
+ if (this.line.indented || this.line.peekNextNonspace() !== ">") return false;
134
+ this.line.advanceToNextNonspace();
135
+ this.line.advance(1);
136
+ if (this.line.peek() === " ") this.line.advance(1);
137
+ return true;
138
+ }
139
+ continueListItem(node) {
140
+ const listData = node.listData;
141
+ if (listData === void 0) return "not-matched";
142
+ if (this.line.blank) {
143
+ if (node.children.length === 0) return "not-matched";
144
+ this.line.advanceToNextNonspace();
145
+ return "matched";
146
+ }
147
+ if (this.line.indent >= listData.markerOffset + listData.padding) {
148
+ this.line.advance(listData.markerOffset + listData.padding);
149
+ return "matched";
150
+ }
151
+ return "not-matched";
152
+ }
153
+ continueCodeBlock(node) {
154
+ if (!node.fenced) {
155
+ if (this.line.indent >= 4) {
156
+ this.line.advance(4);
157
+ return "matched";
158
+ }
159
+ if (this.line.blank) {
160
+ this.line.advanceToNextNonspace();
161
+ return "matched";
162
+ }
163
+ return "not-matched";
164
+ }
165
+ const rest = this.line.restFromNextNonspace();
166
+ const closing = this.line.indented || !rest.startsWith(node.fenceChar) ? null : CLOSING_CODE_FENCE_PATTERN.exec(rest);
167
+ if (closing !== null && closing[0].length >= node.fenceLength) {
168
+ this.finalize(node);
169
+ return "finished";
170
+ }
171
+ for (let remaining = node.fenceOffset; remaining > 0 && this.line.peek() === " "; remaining -= 1) this.line.advance(1);
172
+ return "matched";
173
+ }
174
+ openNewBlocks(matchedContainer) {
175
+ let container = matchedContainer;
176
+ let matchedLeaf = container.kind !== "paragraph" && container.kind !== "table" && acceptsLines(container.kind);
177
+ while (!matchedLeaf) {
178
+ this.line.findNextNonspace();
179
+ if (!this.line.indented && !MAYBE_SPECIAL_PATTERN.test(this.line.restFromNextNonspace())) {
180
+ this.line.advanceToNextNonspace();
181
+ break;
182
+ }
183
+ const result = this.tryBlockStart(container);
184
+ if (result === "none") {
185
+ this.line.advanceToNextNonspace();
186
+ break;
187
+ }
188
+ container = this.tip;
189
+ matchedLeaf = result === "leaf";
190
+ }
191
+ return container;
192
+ }
193
+ tryBlockStart(container) {
194
+ const starts = [
195
+ () => this.tryBlockquoteStart(),
196
+ () => this.tryAtxHeadingStart(),
197
+ () => this.tryCodeFenceStart(),
198
+ () => this.tryHtmlBlockStart(container),
199
+ () => this.tryPromoteParagraph(container),
200
+ () => this.tryThematicBreakStart(),
201
+ () => this.tryListItemStart(container),
202
+ () => this.tryIndentedCodeStart()
203
+ ];
204
+ for (const start of starts) {
205
+ const result = start();
206
+ if (result !== "none") return result;
207
+ }
208
+ return "none";
209
+ }
210
+ tryBlockquoteStart() {
211
+ if (!this.consumeBlockquoteMarker()) return "none";
212
+ this.closeUnmatchedBlocks();
213
+ this.addChild("blockquote");
214
+ return "container";
215
+ }
216
+ tryAtxHeadingStart() {
217
+ if (this.line.indented) return "none";
218
+ const rest = this.line.restFromNextNonspace();
219
+ const match = ATX_MARKER_PATTERN.exec(rest);
220
+ if (match === null) return "none";
221
+ this.line.advanceToNextNonspace();
222
+ this.closeUnmatchedBlocks();
223
+ const heading = this.addChild("heading");
224
+ heading.level = headingLevelOf(match[0].trim().length);
225
+ heading.content = rest.slice(match[0].length).replace(ATX_ONLY_CLOSING_SEQUENCE_PATTERN, "").replace(ATX_TRAILING_CLOSING_SEQUENCE_PATTERN, "");
226
+ this.line.advanceToEndOfLine();
227
+ return "leaf";
228
+ }
229
+ tryCodeFenceStart() {
230
+ if (this.line.indented) return "none";
231
+ const match = CODE_FENCE_PATTERN.exec(this.line.restFromNextNonspace());
232
+ if (match === null) return "none";
233
+ const fence = match[0];
234
+ const fenceChar = fence.charAt(0);
235
+ if (fenceChar !== "`" && fenceChar !== "~") return "none";
236
+ this.closeUnmatchedBlocks();
237
+ const block = this.addChild("codeBlock");
238
+ block.fenced = true;
239
+ block.fenceChar = fenceChar;
240
+ block.fenceLength = fence.length;
241
+ block.fenceOffset = this.line.indent;
242
+ this.line.advanceToNextNonspace();
243
+ this.line.advance(fence.length);
244
+ return "leaf";
245
+ }
246
+ tryHtmlBlockStart(container) {
247
+ if (this.line.indented || this.line.peekNextNonspace() !== "<") return "none";
248
+ const interruptsParagraph = container.kind === "paragraph" || !this.allClosed && !this.line.blank && this.tip.kind === "paragraph";
249
+ const type = matchHtmlBlockStart(this.line.restFromNextNonspace(), interruptsParagraph);
250
+ if (type === void 0) return "none";
251
+ this.closeUnmatchedBlocks();
252
+ this.addChild("htmlBlock").htmlBlockType = type;
253
+ return "leaf";
254
+ }
255
+ tryPromoteParagraph(container) {
256
+ if (this.line.indented || container.kind !== "paragraph") return "none";
257
+ const setext = this.trySetextHeading(container);
258
+ return setext === "none" ? this.tryTableHeader(container) : setext;
259
+ }
260
+ trySetextHeading(paragraph) {
261
+ const match = SETEXT_UNDERLINE_PATTERN.exec(this.line.restFromNextNonspace());
262
+ if (match === null) return "none";
263
+ this.closeUnmatchedBlocks();
264
+ paragraph.content = extractDefinitions(paragraph.content, this.references, this.sink, paragraph.startLine);
265
+ if (isBlankContent(paragraph.content)) return "none";
266
+ const heading = new BlockNode("heading", paragraph.startLine);
267
+ heading.level = match[0].startsWith("=") ? SETEXT_LEVEL_1 : SETEXT_LEVEL_2;
268
+ heading.setext = true;
269
+ heading.content = paragraph.content;
270
+ paragraph.replaceWith(heading);
271
+ this.tip = heading;
272
+ this.line.advanceToEndOfLine();
273
+ return "leaf";
274
+ }
275
+ tryTableHeader(paragraph) {
276
+ if (!this.tables) return "none";
277
+ const alignments = parseTableDelimiterRow(this.line.restFromNextNonspace());
278
+ if (alignments === void 0) return "none";
279
+ const lines = paragraph.content.split("\n");
280
+ const headerLine = lines.at(-2);
281
+ if (headerLine === void 0 || splitTableRow(headerLine).length !== alignments.length) return "none";
282
+ this.closeUnmatchedBlocks();
283
+ paragraph.content = lines.slice(0, -2).map((text) => `${text}\n`).join("");
284
+ this.finalize(paragraph);
285
+ const table = this.addChild("table");
286
+ table.alignments = alignments;
287
+ table.headerLine = headerLine;
288
+ this.line.advanceToEndOfLine();
289
+ return "leaf";
290
+ }
291
+ tryThematicBreakStart() {
292
+ if (this.line.indented || !THEMATIC_BREAK_PATTERN.test(this.line.restFromNextNonspace())) return "none";
293
+ this.closeUnmatchedBlocks();
294
+ this.addChild("thematicBreak");
295
+ this.line.advanceToEndOfLine();
296
+ return "leaf";
297
+ }
298
+ tryListItemStart(container) {
299
+ const data = parseListMarker(this.line, container.kind === "paragraph");
300
+ if (data === void 0) return "none";
301
+ this.closeUnmatchedBlocks();
302
+ const openList = this.tip.listData;
303
+ if (this.tip.kind !== "list" || openList === void 0 || !listsMatch(openList, data)) this.addChild("list").listData = data;
304
+ this.addChild("listItem").listData = data;
305
+ return "container";
306
+ }
307
+ tryIndentedCodeStart() {
308
+ if (!this.line.indented || this.tip.kind === "paragraph" || this.line.blank) return "none";
309
+ this.line.advance(4);
310
+ this.closeUnmatchedBlocks();
311
+ this.addChild("codeBlock");
312
+ return "leaf";
313
+ }
314
+ addTextToContainer(container) {
315
+ if (!this.allClosed && !this.line.blank && this.tip.kind === "paragraph") {
316
+ this.addLine();
317
+ return;
318
+ }
319
+ this.closeUnmatchedBlocks();
320
+ const lastChild = container.lastChild;
321
+ if (this.line.blank && lastChild !== void 0) lastChild.lastLineBlank = true;
322
+ this.recordBlankLineForTightness(container);
323
+ if (acceptsLines(container.kind)) {
324
+ this.addLine();
325
+ if (container.kind === "htmlBlock" && matchesHtmlBlockEnd(this.line.rest(), container.htmlBlockType)) this.finalize(container);
326
+ return;
327
+ }
328
+ if (!this.line.atEnd && !this.line.blank) {
329
+ this.addChild("paragraph");
330
+ this.line.advanceToNextNonspace();
331
+ this.addLine();
332
+ }
333
+ }
334
+ recordBlankLineForTightness(container) {
335
+ const blank = this.line.blank && !(container.kind === "blockquote" || container.kind === "codeBlock" && container.fenced || container.kind === "listItem" && container.children.length === 0 && container.startLine === this.lineNumber);
336
+ for (let node = container; node !== void 0; node = node.parent) node.lastLineBlank = blank;
337
+ }
338
+ addLine() {
339
+ this.tip.content += `${this.line.rest()}\n`;
340
+ }
341
+ addChild(kind) {
342
+ while (!canContain(this.tip.kind, kind)) this.finalize(this.tip);
343
+ if (this.nestingDepth >= this.maxNesting) throw new MarkdownNestingLimitExceededError(this.maxNesting);
344
+ const node = new BlockNode(kind, this.lineNumber);
345
+ this.tip.appendChild(node);
346
+ this.tip = node;
347
+ this.nestingDepth += 1;
348
+ return node;
349
+ }
350
+ closeUnmatchedBlocks() {
351
+ if (this.allClosed) return;
352
+ while (this.oldTip !== this.lastMatchedContainer) {
353
+ const parent = this.oldTip.parent;
354
+ this.finalize(this.oldTip);
355
+ if (parent === void 0) break;
356
+ this.oldTip = parent;
357
+ }
358
+ this.allClosed = true;
359
+ }
360
+ finalize(node) {
361
+ const above = node.parent;
362
+ node.open = false;
363
+ this.finalizeContent(node);
364
+ if (node !== this.document) this.nestingDepth -= 1;
365
+ this.tip = above ?? this.document;
366
+ }
367
+ finalizeContent(node) {
368
+ switch (node.kind) {
369
+ case "paragraph":
370
+ node.content = extractDefinitions(node.content, this.references, this.sink, node.startLine);
371
+ if (isBlankContent(node.content)) node.unlink();
372
+ return;
373
+ case "codeBlock":
374
+ this.finalizeCodeBlock(node);
375
+ return;
376
+ case "htmlBlock":
377
+ node.literal = node.content.replace(TRAILING_HTML_BLANK_LINES_PATTERN, "");
378
+ return;
379
+ case "list":
380
+ finalizeListTightness(node);
381
+ return;
382
+ default: return;
383
+ }
384
+ }
385
+ finalizeCodeBlock(node) {
386
+ if (!node.fenced) {
387
+ node.literal = node.content.replace(TRAILING_BLANK_LINES_PATTERN, "\n");
388
+ return;
389
+ }
390
+ const breakIndex = node.content.indexOf("\n");
391
+ node.infoString = unescapeString(node.content.slice(0, breakIndex).trim());
392
+ node.literal = node.content.slice(breakIndex + 1);
393
+ }
394
+ };
395
+ function toInlineChildren(content, references, options) {
396
+ return parseInlines(content.trim(), references, options);
397
+ }
398
+ function toHeadingNode(node, references, options) {
399
+ return {
400
+ type: "heading",
401
+ level: node.level,
402
+ style: node.setext ? "setext" : "atx",
403
+ children: toInlineChildren(node.content, references, options)
404
+ };
405
+ }
406
+ function extractTaskListMarker(itemChildren) {
407
+ const first = itemChildren[0];
408
+ if (first?.kind !== "paragraph") return;
409
+ const match = TASK_LIST_MARKER_PATTERN.exec(first.content);
410
+ if (match === null) return;
411
+ first.content = first.content.slice(match[0].length);
412
+ return match[1] !== " ";
413
+ }
414
+ function toListItemNode(item, references, options) {
415
+ const checked = options.gfmTaskLists ?? true ? extractTaskListMarker(item.children) : void 0;
416
+ return checked === void 0 ? {
417
+ type: "listItem",
418
+ children: toAstBlocks(item.children, references, options)
419
+ } : {
420
+ type: "listItem",
421
+ checked,
422
+ children: toAstBlocks(item.children, references, options)
423
+ };
424
+ }
425
+ function toListNode(node, references, options) {
426
+ const children = node.children.map((item) => toListItemNode(item, references, options));
427
+ const data = node.listData;
428
+ if (data?.type === "ordered") return {
429
+ type: "list",
430
+ markerType: "ordered",
431
+ orderedDelimiter: data.delimiter,
432
+ start: data.start,
433
+ tight: node.tight,
434
+ children
435
+ };
436
+ return {
437
+ type: "list",
438
+ markerType: "bullet",
439
+ bulletMarker: data?.bulletChar,
440
+ tight: node.tight,
441
+ children
442
+ };
443
+ }
444
+ function toTableRow(cells, header, references, options) {
445
+ return {
446
+ type: "tableRow",
447
+ header,
448
+ children: cells.map((cell) => ({
449
+ type: "tableCell",
450
+ children: toInlineChildren(cell, references, options)
451
+ }))
452
+ };
453
+ }
454
+ function toTableNode(node, references, options) {
455
+ const sink = options.sink ?? NOOP_MARKDOWN_DIAGNOSTIC_SINK;
456
+ const columnCount = node.alignments.length;
457
+ const rows = [toTableRow(fitRowToColumns(splitTableRow(node.headerLine), columnCount), true, references, options)];
458
+ for (const rowLine of node.content.split("\n")) {
459
+ if (rowLine.trim().length === 0) continue;
460
+ const cells = splitTableRow(rowLine);
461
+ if (cells.length !== columnCount) sink({
462
+ code: MarkdownDiagnosticCodes.TABLE_CELL_COUNT_MISMATCH,
463
+ severity: "warning",
464
+ 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`,
465
+ line: node.startLine
466
+ });
467
+ rows.push(toTableRow(fitRowToColumns(cells, columnCount), false, references, options));
468
+ }
469
+ return {
470
+ type: "table",
471
+ alignments: node.alignments,
472
+ children: rows
473
+ };
474
+ }
475
+ function toAstBlock(node, references, options) {
476
+ switch (node.kind) {
477
+ case "paragraph": return {
478
+ type: "paragraph",
479
+ children: toInlineChildren(node.content, references, options)
480
+ };
481
+ case "heading": return toHeadingNode(node, references, options);
482
+ case "blockquote": return {
483
+ type: "blockquote",
484
+ children: toAstBlocks(node.children, references, options)
485
+ };
486
+ case "list": return toListNode(node, references, options);
487
+ case "codeBlock": return node.fenced ? {
488
+ type: "codeBlock",
489
+ fenced: true,
490
+ fenceChar: node.fenceChar,
491
+ infoString: node.infoString,
492
+ literal: node.literal
493
+ } : {
494
+ type: "codeBlock",
495
+ fenced: false,
496
+ literal: node.literal
497
+ };
498
+ case "htmlBlock": return {
499
+ type: "htmlBlock",
500
+ literal: node.literal
501
+ };
502
+ case "thematicBreak": return { type: "thematicBreak" };
503
+ case "table": return toTableNode(node, references, options);
504
+ case "document":
505
+ case "listItem": return;
506
+ }
507
+ }
508
+ function toAstBlocks(nodes, references, options) {
509
+ const blocks = [];
510
+ for (const node of nodes) {
511
+ const converted = toAstBlock(node, references, options);
512
+ if (converted !== void 0) blocks.push(converted);
513
+ }
514
+ return blocks;
515
+ }
516
+ function parseMarkdown(source, options = {}) {
517
+ const parser = new BlockParser(options);
518
+ const root = parser.parse(source);
519
+ const references = parser.references;
520
+ return {
521
+ document: {
522
+ type: "document",
523
+ children: toAstBlocks(root.children, references, options)
524
+ },
525
+ references
526
+ };
527
+ }
528
+ //#endregion
529
+ export { parseMarkdown };
@@ -0,0 +1,59 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_diagnostics_diagnostics = require("../diagnostics/diagnostics.cjs");
3
+ const require_inline_link = require("../inline/link.cjs");
4
+ //#region src/block/definitions.ts
5
+ const MIN_DEFINITION_LABEL_LENGTH = 3;
6
+ function parseDefinition(content, start) {
7
+ const labelLength = require_inline_link.matchLinkLabel(content, start);
8
+ if (labelLength < MIN_DEFINITION_LABEL_LENGTH) return;
9
+ const label = require_inline_link.normalizeLinkLabel(content.slice(start, start + labelLength));
10
+ if (label.length === 0) return;
11
+ let cursor = start + labelLength;
12
+ if (content.charAt(cursor) !== ":") return;
13
+ cursor = require_inline_link.skipInlineWhitespace(content, cursor + 1);
14
+ const destination = require_inline_link.parseLinkDestination(content, cursor);
15
+ if (destination === void 0) return;
16
+ const afterDestination = destination.end;
17
+ let title;
18
+ cursor = afterDestination;
19
+ const beforeTitle = require_inline_link.skipInlineWhitespace(content, afterDestination);
20
+ if (beforeTitle > afterDestination) {
21
+ const parsedTitle = require_inline_link.parseLinkTitle(content, beforeTitle);
22
+ if (parsedTitle !== void 0 && require_inline_link.isBlankRemainderOfLine(content, parsedTitle.end)) {
23
+ title = parsedTitle.value;
24
+ cursor = parsedTitle.end;
25
+ }
26
+ }
27
+ if (!require_inline_link.isBlankRemainderOfLine(content, cursor)) return;
28
+ const lineEnd = content.indexOf("\n", cursor);
29
+ return {
30
+ label,
31
+ definition: title === void 0 ? { destination: destination.value } : {
32
+ destination: destination.value,
33
+ title
34
+ },
35
+ end: lineEnd === -1 ? content.length : lineEnd + 1
36
+ };
37
+ }
38
+ function extractDefinitions(content, references, sink = require_diagnostics_diagnostics.NOOP_MARKDOWN_DIAGNOSTIC_SINK, startLine = 0) {
39
+ let cursor = 0;
40
+ for (;;) {
41
+ const parsed = parseDefinition(content, cursor);
42
+ if (parsed === void 0) return content.slice(cursor);
43
+ if (references.has(parsed.label)) sink({
44
+ code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.DUPLICATE_LINK_REFERENCE,
45
+ severity: "warning",
46
+ message: `link reference definition "${parsed.label}" was already defined earlier in the document; this later definition is ignored`,
47
+ line: startLine + countNewlines(content, cursor)
48
+ });
49
+ else references.set(parsed.label, parsed.definition);
50
+ cursor = parsed.end;
51
+ }
52
+ }
53
+ function countNewlines(content, upTo) {
54
+ let count = 0;
55
+ for (let index = 0; index < upTo && index < content.length; index += 1) if (content.charAt(index) === "\n") count += 1;
56
+ return count;
57
+ }
58
+ //#endregion
59
+ exports.extractDefinitions = extractDefinitions;
@@ -0,0 +1,6 @@
1
+ import { i as MarkdownDiagnosticSink } from "../diagnostics-DmuWc7d8.cjs";
2
+ import { t as LinkReferenceDefinition } from "../link-Dv4kxVjk.cjs";
3
+ //#region src/block/definitions.d.ts
4
+ declare function extractDefinitions(content: string, references: Map<string, LinkReferenceDefinition>, sink?: MarkdownDiagnosticSink, startLine?: number): string;
5
+ //#endregion
6
+ export { extractDefinitions };
@@ -0,0 +1,6 @@
1
+ import { i as MarkdownDiagnosticSink } from "../diagnostics-DmuWc7d8.js";
2
+ import { t as LinkReferenceDefinition } from "../link-Dv4kxVjk.js";
3
+ //#region src/block/definitions.d.ts
4
+ declare function extractDefinitions(content: string, references: Map<string, LinkReferenceDefinition>, sink?: MarkdownDiagnosticSink, startLine?: number): string;
5
+ //#endregion
6
+ export { extractDefinitions };
@@ -0,0 +1,58 @@
1
+ import { MarkdownDiagnosticCodes, NOOP_MARKDOWN_DIAGNOSTIC_SINK } from "../diagnostics/diagnostics.js";
2
+ import { isBlankRemainderOfLine, matchLinkLabel, normalizeLinkLabel, parseLinkDestination, parseLinkTitle, skipInlineWhitespace } from "../inline/link.js";
3
+ //#region src/block/definitions.ts
4
+ const MIN_DEFINITION_LABEL_LENGTH = 3;
5
+ function parseDefinition(content, start) {
6
+ const labelLength = matchLinkLabel(content, start);
7
+ if (labelLength < MIN_DEFINITION_LABEL_LENGTH) return;
8
+ const label = normalizeLinkLabel(content.slice(start, start + labelLength));
9
+ if (label.length === 0) return;
10
+ let cursor = start + labelLength;
11
+ if (content.charAt(cursor) !== ":") return;
12
+ cursor = skipInlineWhitespace(content, cursor + 1);
13
+ const destination = parseLinkDestination(content, cursor);
14
+ if (destination === void 0) return;
15
+ const afterDestination = destination.end;
16
+ let title;
17
+ cursor = afterDestination;
18
+ const beforeTitle = skipInlineWhitespace(content, afterDestination);
19
+ if (beforeTitle > afterDestination) {
20
+ const parsedTitle = parseLinkTitle(content, beforeTitle);
21
+ if (parsedTitle !== void 0 && isBlankRemainderOfLine(content, parsedTitle.end)) {
22
+ title = parsedTitle.value;
23
+ cursor = parsedTitle.end;
24
+ }
25
+ }
26
+ if (!isBlankRemainderOfLine(content, cursor)) return;
27
+ const lineEnd = content.indexOf("\n", cursor);
28
+ return {
29
+ label,
30
+ definition: title === void 0 ? { destination: destination.value } : {
31
+ destination: destination.value,
32
+ title
33
+ },
34
+ end: lineEnd === -1 ? content.length : lineEnd + 1
35
+ };
36
+ }
37
+ function extractDefinitions(content, references, sink = NOOP_MARKDOWN_DIAGNOSTIC_SINK, startLine = 0) {
38
+ let cursor = 0;
39
+ for (;;) {
40
+ const parsed = parseDefinition(content, cursor);
41
+ if (parsed === void 0) return content.slice(cursor);
42
+ if (references.has(parsed.label)) sink({
43
+ code: MarkdownDiagnosticCodes.DUPLICATE_LINK_REFERENCE,
44
+ severity: "warning",
45
+ message: `link reference definition "${parsed.label}" was already defined earlier in the document; this later definition is ignored`,
46
+ line: startLine + countNewlines(content, cursor)
47
+ });
48
+ else references.set(parsed.label, parsed.definition);
49
+ cursor = parsed.end;
50
+ }
51
+ }
52
+ function countNewlines(content, upTo) {
53
+ let count = 0;
54
+ for (let index = 0; index < upTo && index < content.length; index += 1) if (content.charAt(index) === "\n") count += 1;
55
+ return count;
56
+ }
57
+ //#endregion
58
+ export { extractDefinitions };