markdown-codec 4.0.15 → 4.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/README.md +14 -13
  2. package/dist/block/block.d.cts +3 -3
  3. package/dist/block/block.d.ts +3 -3
  4. package/dist/block/definitions.d.cts +2 -2
  5. package/dist/block/definitions.d.ts +2 -2
  6. package/dist/codec.d.cts +30 -10
  7. package/dist/codec.d.ts +30 -10
  8. package/dist/diagnostics/diagnostics.cjs +12 -4
  9. package/dist/diagnostics/diagnostics.d.cts +2 -2
  10. package/dist/diagnostics/diagnostics.d.ts +2 -2
  11. package/dist/diagnostics/diagnostics.js +12 -5
  12. package/dist/{diagnostics-BWK1iGy7.d.cts → diagnostics-CUMLtGHJ.d.cts} +7 -5
  13. package/dist/{diagnostics-BWK1iGy7.d.ts → diagnostics-CUMLtGHJ.d.ts} +7 -5
  14. package/dist/emit/emit.cjs +93 -27
  15. package/dist/emit/emit.js +96 -30
  16. package/dist/emit/inline.cjs +22 -14
  17. package/dist/emit/inline.d.cts +7 -5
  18. package/dist/emit/inline.d.ts +7 -5
  19. package/dist/emit/inline.js +21 -15
  20. package/dist/emit/table.cjs +1 -1
  21. package/dist/emit/table.d.cts +1 -1
  22. package/dist/emit/table.d.ts +1 -1
  23. package/dist/emit/table.js +1 -1
  24. package/dist/index.cjs +1 -0
  25. package/dist/index.d.cts +2 -2
  26. package/dist/index.d.ts +2 -2
  27. package/dist/index.js +2 -2
  28. package/dist/inline/inline.d.cts +1 -1
  29. package/dist/inline/inline.d.ts +1 -1
  30. package/dist/inline/link.d.cts +17 -1
  31. package/dist/inline/link.d.ts +17 -1
  32. package/dist/{inline-CXVQWQnW.d.cts → inline-CoS1JzxI.d.cts} +1 -1
  33. package/dist/{inline-B_V7bs5j.d.ts → inline-OGXVE6hB.d.ts} +1 -1
  34. package/dist/lower/front-matter.cjs +7 -4
  35. package/dist/lower/front-matter.d.cts +2 -1
  36. package/dist/lower/front-matter.d.ts +2 -1
  37. package/dist/lower/front-matter.js +7 -4
  38. package/dist/lower/inline.cjs +73 -29
  39. package/dist/lower/inline.d.cts +7 -10
  40. package/dist/lower/inline.d.ts +7 -10
  41. package/dist/lower/inline.js +74 -29
  42. package/dist/lower/lower.cjs +140 -71
  43. package/dist/lower/lower.d.cts +8 -1
  44. package/dist/lower/lower.d.ts +8 -1
  45. package/dist/lower/lower.js +142 -74
  46. package/dist/lower/table.cjs +3 -2
  47. package/dist/lower/table.js +3 -2
  48. package/dist/options/options.d.cts +1 -1
  49. package/dist/options/options.d.ts +1 -1
  50. package/dist/read.cjs +45 -9
  51. package/dist/read.d.cts +1 -1
  52. package/dist/read.d.ts +1 -1
  53. package/dist/read.js +46 -10
  54. package/dist/shared/list-id.cjs +6 -0
  55. package/dist/shared/list-id.d.cts +2 -1
  56. package/dist/shared/list-id.d.ts +2 -1
  57. package/dist/shared/list-id.js +6 -1
  58. package/dist/write.cjs +31 -4
  59. package/dist/write.js +31 -4
  60. package/package.json +2 -2
  61. package/dist/link-Dv4kxVjk.d.cts +0 -18
  62. package/dist/link-Dv4kxVjk.d.ts +0 -18
@@ -11,7 +11,7 @@ function buildRun(text, style, fontFamily) {
11
11
  ...fontFamily !== void 0 ? { fontFamily } : {}
12
12
  };
13
13
  }
14
- function lowerNestedEmphasisLike(kind, node, style, context) {
14
+ function lowerNestedEmphasisLike(kind, node, style, context, runs, extents) {
15
15
  if (style[kind] === true) context.sink({
16
16
  code: MarkdownDiagnosticCodes.NESTED_EMPHASIS_FLATTENED,
17
17
  severity: "info",
@@ -21,15 +21,25 @@ function lowerNestedEmphasisLike(kind, node, style, context) {
21
21
  ...style,
22
22
  [kind]: true
23
23
  };
24
- return node.children.flatMap((child) => lowerInlineNode(child, childStyle, context));
24
+ lowerNodesInto(node.children, childStyle, context, runs, extents);
25
25
  }
26
- function lowerInlineNode(node, style, context) {
26
+ function lowerInlineNodeInto(node, style, context, runs, extents) {
27
27
  switch (node.type) {
28
- case "text": return node.value.length === 0 ? [] : [buildRun(node.value, style)];
29
- case "entity": return node.value.length === 0 ? [] : [buildRun(node.value, style)];
30
- case "softBreak": return [buildRun(" ", style)];
31
- case "hardBreak": return [buildRun("\n", style)];
32
- case "codeSpan": return [buildRun(node.literal, style, MONOSPACE_FONT_FAMILY)];
28
+ case "text":
29
+ if (node.value.length > 0) runs.push(buildRun(node.value, style));
30
+ return;
31
+ case "entity":
32
+ if (node.value.length > 0) runs.push(buildRun(node.value, style));
33
+ return;
34
+ case "softBreak":
35
+ runs.push(buildRun(" ", style));
36
+ return;
37
+ case "hardBreak":
38
+ runs.push(buildRun("\n", style));
39
+ return;
40
+ case "codeSpan":
41
+ runs.push(buildRun(node.literal, style, MONOSPACE_FONT_FAMILY));
42
+ return;
33
43
  case "rawHtml":
34
44
  if (context.rawHtml === "drop") {
35
45
  context.sink({
@@ -37,47 +47,66 @@ function lowerInlineNode(node, style, context) {
37
47
  severity: "info",
38
48
  message: "inline raw HTML was dropped per the rawHtml: \"drop\" option"
39
49
  });
40
- return [];
50
+ return;
41
51
  }
42
52
  context.sink({
43
53
  code: MarkdownDiagnosticCodes.RAW_HTML_PRESERVED_AS_TEXT,
44
54
  severity: "info",
45
- message: "inline raw HTML was preserved as literal text; it will not be rendered as HTML by any consumer of the resulting ContentDocument"
55
+ message: "inline raw HTML was preserved as literal text; it will not be rendered as HTML by any consumer of the resulting ContentDocument, and its verbatim original rides the run's own markdown residue for this package's writer to re-emit as-is"
46
56
  });
47
- return node.literal.length === 0 ? [] : [buildRun(node.literal, style)];
57
+ if (node.literal.length > 0) runs.push({
58
+ ...buildRun(node.literal, style),
59
+ source: {
60
+ format: "markdown",
61
+ xml: node.literal
62
+ }
63
+ });
64
+ return;
48
65
  case "mathInline":
49
66
  context.sink({
50
67
  code: MarkdownDiagnosticCodes.MATH_INLINE_PRESERVED_AS_TEXT,
51
68
  severity: "info",
52
69
  message: "inline math (\\( \\)) was preserved as literal raw LaTeX text; it is not parsed as LaTeX or converted to MathML by this package"
53
70
  });
54
- return [buildRun(node.literal, style, MATH_INLINE_FONT_MARKER)];
71
+ runs.push(buildRun(node.literal, style, MATH_INLINE_FONT_MARKER));
72
+ return;
55
73
  case "footnoteReference":
56
74
  context.sink({
57
75
  code: MarkdownDiagnosticCodes.FOOTNOTE_REFERENCE_PRESERVED_AS_TEXT,
58
76
  severity: "info",
59
77
  message: `footnote reference "[^${node.label}]" is preserved as a marked text run rather than an anchor construct: a construct's extent is block-scoped, and a reference site sits between two runs inside a paragraph, which no block-level boundary marker can bracket`
60
78
  });
61
- return [buildRun(`[^${node.label}]`, style, FOOTNOTE_REFERENCE_FONT_MARKER)];
79
+ runs.push(buildRun(`[^${node.label}]`, style, FOOTNOTE_REFERENCE_FONT_MARKER));
80
+ return;
62
81
  case "autolink": {
63
82
  const destination = node.email ? `mailto:${node.destination}` : node.destination;
64
- return [buildRun(node.destination, {
83
+ runs.push(buildRun(node.destination, {
65
84
  ...style,
66
85
  hyperlink: destination
67
- })];
86
+ }));
87
+ return;
68
88
  }
69
89
  case "link": {
70
- if (node.title !== void 0) context.sink({
71
- code: MarkdownDiagnosticCodes.LINK_TITLE_DROPPED,
72
- severity: "info",
73
- message: `link title "${node.title}" has no ContentRun equivalent and was dropped`
74
- });
75
90
  const childStyle = {
76
91
  ...style,
77
92
  hyperlink: node.destination
78
93
  };
79
- const runs = node.children.flatMap((child) => lowerInlineNode(child, childStyle, context));
80
- return runs.length > 0 ? runs : [buildRun("", childStyle)];
94
+ const startRun = runs.length;
95
+ lowerNodesInto(node.children, childStyle, context, runs, extents);
96
+ if (runs.length === startRun) runs.push(buildRun("", childStyle));
97
+ if (node.title !== void 0) extents.push({
98
+ descriptor: {
99
+ kind: "link",
100
+ target: {
101
+ kind: "external",
102
+ uri: node.destination
103
+ },
104
+ title: node.title
105
+ },
106
+ startRun,
107
+ endRun: runs.length
108
+ });
109
+ return;
81
110
  }
82
111
  case "image":
83
112
  if (node.title !== void 0) context.sink({
@@ -85,17 +114,33 @@ function lowerInlineNode(node, style, context) {
85
114
  severity: "info",
86
115
  message: `image title "${node.title}" has no ContentRun equivalent and was dropped`
87
116
  });
88
- return [buildRun(node.alt, {
117
+ runs.push(buildRun(node.alt, {
89
118
  ...style,
90
119
  hyperlink: node.destination
91
- })];
92
- case "emphasis": return lowerNestedEmphasisLike("italic", node, style, context);
93
- case "strong": return lowerNestedEmphasisLike("bold", node, style, context);
94
- case "strikethrough": return lowerNestedEmphasisLike("strike", node, style, context);
120
+ }));
121
+ return;
122
+ case "emphasis":
123
+ lowerNestedEmphasisLike("italic", node, style, context, runs, extents);
124
+ return;
125
+ case "strong":
126
+ lowerNestedEmphasisLike("bold", node, style, context, runs, extents);
127
+ return;
128
+ case "strikethrough":
129
+ lowerNestedEmphasisLike("strike", node, style, context, runs, extents);
130
+ return;
95
131
  }
96
132
  }
133
+ function lowerNodesInto(nodes, style, context, runs, extents) {
134
+ for (const node of nodes) lowerInlineNodeInto(node, style, context, runs, extents);
135
+ }
97
136
  function lowerInlineNodes(nodes, context) {
98
- return nodes.flatMap((node) => lowerInlineNode(node, {}, context));
137
+ const runs = [];
138
+ const extents = [];
139
+ lowerNodesInto(nodes, {}, context, runs, extents);
140
+ return {
141
+ runs,
142
+ linkTitleExtents: extents
143
+ };
99
144
  }
100
145
  function lowerCodeBlockRun(literal) {
101
146
  return {
@@ -104,4 +149,4 @@ function lowerCodeBlockRun(literal) {
104
149
  };
105
150
  }
106
151
  //#endregion
107
- export { lowerCodeBlockRun, lowerInlineNode, lowerInlineNodes };
152
+ export { lowerCodeBlockRun, lowerInlineNodes };
@@ -25,17 +25,21 @@ function decorateParagraph(paragraph, context) {
25
25
  };
26
26
  if (context.list !== void 0) result = {
27
27
  ...result,
28
- list: {
29
- numId: context.list.numId,
30
- level: context.list.level
31
- }
28
+ list: { ...context.list }
32
29
  };
33
30
  return result;
34
31
  }
32
+ function paragraphWithConstructs(runs, linkTitleExtents) {
33
+ return {
34
+ runs,
35
+ ...linkTitleExtents.length > 0 ? { constructs: [...linkTitleExtents] } : {}
36
+ };
37
+ }
35
38
  function lowerHeading(node, context) {
39
+ const inline = require_lower_inline.lowerInlineNodes(node.children, inlineContext(context));
36
40
  return [decorateParagraph({
37
41
  kind: "paragraph",
38
- runs: require_lower_inline.lowerInlineNodes(node.children, inlineContext(context)),
42
+ ...paragraphWithConstructs(inline.runs, inline.linkTitleExtents),
39
43
  styleId: require_shared_style_constants.headingStyleId(node.level),
40
44
  headingLevel: node.level
41
45
  }, context)];
@@ -46,9 +50,10 @@ function lowerParagraph(node, context) {
46
50
  let segment = [];
47
51
  const flushSegment = (force) => {
48
52
  if (segment.length === 0 && !force) return;
53
+ const inline = require_lower_inline.lowerInlineNodes(segment, inlineCtx);
49
54
  blocks.push(decorateParagraph({
50
55
  kind: "paragraph",
51
- runs: require_lower_inline.lowerInlineNodes(segment, inlineCtx)
56
+ ...paragraphWithConstructs(inline.runs, inline.linkTitleExtents)
52
57
  }, context));
53
58
  segment = [];
54
59
  };
@@ -70,39 +75,73 @@ function lowerParagraph(node, context) {
70
75
  segment.push(child);
71
76
  continue;
72
77
  }
73
- if (child.title !== void 0) context.sink({
74
- code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.LINK_TITLE_DROPPED,
75
- severity: "info",
76
- message: `image title "${child.title}" has no ContentImageBlock equivalent and was dropped`
77
- });
78
78
  flushSegment(false);
79
79
  if (context.list !== void 0) context.sink({
80
80
  code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.LIST_ITEM_BLOCK_UNLISTED,
81
81
  severity: "info",
82
82
  message: "a resolved image block directly inside a list item has no ContentListMembership field of its own -- only ContentParagraph carries .list -- so its association with the enclosing list item is lost"
83
83
  });
84
- blocks.push({
84
+ const image = {
85
85
  kind: "image",
86
86
  format: resolved.format,
87
87
  base64: resolved.base64,
88
88
  widthPt: resolved.widthPt,
89
89
  heightPt: resolved.heightPt,
90
90
  ...child.alt.length > 0 ? { altText: child.alt } : {}
91
- });
91
+ };
92
+ if (child.title === void 0) {
93
+ blocks.push(image);
94
+ continue;
95
+ }
96
+ blocks.push({
97
+ kind: "constructStart",
98
+ descriptor: {
99
+ kind: "link",
100
+ target: {
101
+ kind: "external",
102
+ uri: child.destination
103
+ },
104
+ title: child.title
105
+ }
106
+ }, image, { kind: "constructEnd" });
92
107
  }
93
108
  flushSegment(blocks.length === 0);
94
109
  return blocks;
95
110
  }
111
+ function splitInfoString(infoString) {
112
+ const firstWhitespace = infoString.search(/\s/);
113
+ if (firstWhitespace === -1) return infoString.startsWith("{") ? {
114
+ language: void 0,
115
+ remainder: infoString
116
+ } : {
117
+ language: infoString,
118
+ remainder: void 0
119
+ };
120
+ const firstWord = infoString.slice(0, firstWhitespace);
121
+ const remainder = infoString.slice(firstWhitespace).trim();
122
+ if (firstWord.startsWith("{")) return {
123
+ language: void 0,
124
+ remainder: infoString.trim()
125
+ };
126
+ return {
127
+ language: firstWord,
128
+ remainder: remainder.length > 0 ? remainder : void 0
129
+ };
130
+ }
96
131
  function lowerCodeBlock(node, context) {
97
- if (node.fenced && node.infoString !== void 0 && node.infoString.length > 0) context.sink({
98
- code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.CODE_BLOCK_INFO_STRING_DROPPED,
99
- severity: "info",
100
- message: `fenced code block's own info string "${node.infoString}" has no ContentParagraph equivalent and was dropped`
101
- });
132
+ const info = node.fenced && node.infoString !== void 0 && node.infoString.length > 0 ? splitInfoString(node.infoString) : {
133
+ language: void 0,
134
+ remainder: void 0
135
+ };
102
136
  return [decorateParagraph({
103
137
  kind: "paragraph",
104
138
  runs: [require_lower_inline.lowerCodeBlockRun(node.literal.replace(/\n$/, ""))],
105
- styleId: require_shared_style_constants.CODE_BLOCK_STYLE_ID
139
+ styleId: require_shared_style_constants.CODE_BLOCK_STYLE_ID,
140
+ ...info.language !== void 0 ? { codeLanguage: info.language } : {},
141
+ ...info.remainder !== void 0 ? { source: {
142
+ format: "markdown",
143
+ xml: info.remainder
144
+ } } : {}
106
145
  }, context)];
107
146
  }
108
147
  function lowerThematicBreak(context) {
@@ -124,70 +163,95 @@ function lowerHtmlBlock(node, context) {
124
163
  context.sink({
125
164
  code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.RAW_HTML_PRESERVED_AS_TEXT,
126
165
  severity: "info",
127
- message: "block-level raw HTML was preserved as literal text (styleId \"HTMLPreformatted\"); it will not be rendered as HTML by any consumer of the resulting ContentDocument"
166
+ message: "block-level raw HTML was preserved as literal text (styleId \"HTMLPreformatted\"); it will not be rendered as HTML by any consumer of the resulting ContentDocument, and its verbatim original rides the paragraph's own markdown residue for this package's writer to re-emit as-is"
128
167
  });
129
168
  const literal = node.literal.replace(/\n+$/, "");
130
169
  return [decorateParagraph({
131
170
  kind: "paragraph",
132
171
  runs: literal.length === 0 ? [] : [{ text: literal }],
133
- styleId: require_shared_style_constants.HTML_PREFORMATTED_STYLE_ID
172
+ styleId: require_shared_style_constants.HTML_PREFORMATTED_STYLE_ID,
173
+ source: {
174
+ format: "markdown",
175
+ xml: node.literal
176
+ }
134
177
  }, context)];
135
178
  }
136
179
  function lowerMathBlock(node, context) {
137
- context.sink({
138
- code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.MATH_BLOCK_PRESERVED_AS_TEXT,
180
+ if (context.list !== void 0) context.sink({
181
+ code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.LIST_ITEM_BLOCK_UNLISTED,
139
182
  severity: "info",
140
- message: "block math ($$...$$) was preserved as literal raw LaTeX text (styleId \"MathBlock\"); it is not parsed as LaTeX or converted to MathML by this package"
183
+ message: "a display-math block directly inside a list item has no ContentListMembership field of its own -- only ContentParagraph carries .list -- so its association with the enclosing list item is lost"
141
184
  });
142
- const literal = node.literal.replace(/\n$/, "");
143
- return [decorateParagraph({
144
- kind: "paragraph",
145
- runs: literal.length === 0 ? [] : [{ text: literal }],
146
- styleId: require_shared_style_constants.MATH_BLOCK_STYLE_ID
147
- }, context)];
185
+ return [{
186
+ kind: "embeddedObject",
187
+ objectKind: "formula",
188
+ document: {
189
+ kind: "formula",
190
+ metadata: {},
191
+ formula: {
192
+ mathml: [],
193
+ presentation: { latex: node.literal.replace(/\n$/, "") }
194
+ }
195
+ },
196
+ frame: {
197
+ xPt: 0,
198
+ yPt: 0,
199
+ widthPt: 0,
200
+ heightPt: 0
201
+ }
202
+ }];
203
+ }
204
+ function blockquoteSubtreeContainsHeading(node) {
205
+ const walk = (block) => {
206
+ switch (block.type) {
207
+ case "heading": return true;
208
+ case "blockquote":
209
+ case "list":
210
+ case "listItem": return block.children.some(walk);
211
+ default: return false;
212
+ }
213
+ };
214
+ return node.children.some(walk);
148
215
  }
149
216
  function lowerBlockquote(node, context, contentWidthPt) {
150
- if (context.quoteDepth >= 1) context.sink({
151
- code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.BLOCKQUOTE_NESTED_DEPTH,
152
- severity: "info",
153
- message: `blockquote nesting beyond level 1 is represented only as a larger indentLeftPt (${String((context.quoteDepth + 1) * 36)}pt); recovering the exact nesting depth back out is an approximation, not an exact inverse`
154
- });
155
217
  const nested = {
156
218
  ...context,
157
219
  quoteDepth: context.quoteDepth + 1
158
220
  };
159
221
  const blocks = node.children.flatMap((child) => lowerBlock(child, nested, contentWidthPt));
160
- if (blocks.length === 0) return [decorateParagraph({
222
+ const inner = blocks.length === 0 ? [decorateParagraph({
161
223
  kind: "paragraph",
162
224
  runs: []
163
- }, nested)];
164
- return blocks;
165
- }
166
- function applyTaskCheckbox(blocks, checked) {
167
- const first = blocks[0];
168
- if (first?.kind !== "paragraph") return false;
169
- const checkboxRun = { text: `${checked ? "☒" : "☐"} ` };
170
- blocks[0] = {
171
- ...first,
172
- runs: [checkboxRun, ...first.runs]
173
- };
174
- return true;
225
+ }, nested)] : blocks;
226
+ if (blockquoteSubtreeContainsHeading(node)) {
227
+ context.sink({
228
+ code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.BLOCKQUOTE_CONTAINER_SKIPPED,
229
+ severity: "info",
230
+ message: "a blockquote containing a heading cannot carry its division construct -- a marker extent may not open a heading scope, and the last heading inside an extent always leaves one standing -- so this quote degrades to indent-only structure while the heading keeps its heading fidelity"
231
+ });
232
+ return inner;
233
+ }
234
+ return [
235
+ {
236
+ kind: "constructStart",
237
+ descriptor: { kind: "division" }
238
+ },
239
+ ...inner,
240
+ { kind: "constructEnd" }
241
+ ];
175
242
  }
176
243
  function lowerListItem(item, numId, level, context, contentWidthPt) {
177
- if (item.children.filter((child) => child.type !== "list").length > 1) context.sink({
178
- code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.LIST_ITEM_MULTI_BLOCK_FLATTENED,
179
- severity: "info",
180
- message: "a list item directly containing more than one block loses its own item boundary once lowered -- ContentListMembership carries only numId/level, with no field distinguishing \"one item, several blocks\" from \"several items sharing this numId/level\""
181
- });
244
+ const membership = {
245
+ numId,
246
+ level,
247
+ ...item.checked !== void 0 ? { checked: item.checked } : {},
248
+ itemId: require_shared_list_id.mintListItemId(context.numIdState)
249
+ };
182
250
  const itemContext = {
183
251
  ...context,
184
- list: {
185
- numId,
186
- level
187
- }
252
+ list: membership
188
253
  };
189
254
  const blocks = [];
190
- let checkboxApplied = item.checked === void 0;
191
255
  let ownLevelBlockCount = 0;
192
256
  for (const child of item.children) {
193
257
  if (child.type === "list") {
@@ -196,17 +260,12 @@ function lowerListItem(item, numId, level, context, contentWidthPt) {
196
260
  }
197
261
  const childBlocks = lowerBlock(child, itemContext, contentWidthPt);
198
262
  ownLevelBlockCount += childBlocks.length;
199
- if (!checkboxApplied) checkboxApplied = applyTaskCheckbox(childBlocks, item.checked === true);
200
263
  blocks.push(...childBlocks);
201
264
  }
202
- if (ownLevelBlockCount === 0) {
203
- const placeholder = [decorateParagraph({
204
- kind: "paragraph",
205
- runs: []
206
- }, itemContext)];
207
- if (!checkboxApplied) applyTaskCheckbox(placeholder, item.checked === true);
208
- blocks.unshift(...placeholder);
209
- }
265
+ if (ownLevelBlockCount === 0) blocks.unshift(decorateParagraph({
266
+ kind: "paragraph",
267
+ runs: []
268
+ }, itemContext));
210
269
  return blocks;
211
270
  }
212
271
  function lowerList(node, ancestorNumId, level, context, contentWidthPt) {
@@ -331,15 +390,16 @@ function lowerParsedMarkdown(parsed, options = {}, metadata = {}) {
331
390
  }]
332
391
  };
333
392
  }
334
- function lowerMarkdown(source, options = {}) {
393
+ function lowerMarkdownDetailed(source, options = {}) {
335
394
  if (options.maxInputBytes !== void 0) {
336
395
  const actualBytes = new TextEncoder().encode(source).length;
337
396
  if (actualBytes > options.maxInputBytes) throw new require_diagnostics_diagnostics.MarkdownInputTooLargeError(options.maxInputBytes, actualBytes);
338
397
  }
339
398
  const sink = options.sink ?? require_diagnostics_diagnostics.NOOP_MARKDOWN_DIAGNOSTIC_SINK;
340
- const { metadata, rest } = options.frontMatter ?? false ? require_lower_front_matter.extractFrontMatter(source, sink) : {
399
+ const extracted = options.frontMatter ?? false ? require_lower_front_matter.extractFrontMatter(source, sink) : {
341
400
  metadata: {},
342
- rest: source
401
+ rest: source,
402
+ source: void 0
343
403
  };
344
404
  const parseOptions = {
345
405
  gfmTables: options.gfmTables,
@@ -350,8 +410,17 @@ function lowerMarkdown(source, options = {}) {
350
410
  maxNesting: options.maxBlockNesting,
351
411
  sink
352
412
  };
353
- return lowerParsedMarkdown(require_block_block.parseMarkdown(rest, parseOptions), options, metadata);
413
+ const parsed = require_block_block.parseMarkdown(extracted.rest, parseOptions);
414
+ return {
415
+ document: lowerParsedMarkdown(parsed, options, extracted.metadata),
416
+ references: parsed.references,
417
+ frontMatterSource: extracted.source
418
+ };
419
+ }
420
+ function lowerMarkdown(source, options = {}) {
421
+ return lowerMarkdownDetailed(source, options).document;
354
422
  }
355
423
  //#endregion
356
424
  exports.lowerMarkdown = lowerMarkdown;
425
+ exports.lowerMarkdownDetailed = lowerMarkdownDetailed;
357
426
  exports.lowerParsedMarkdown = lowerParsedMarkdown;
@@ -1,8 +1,15 @@
1
+ import { LinkReferenceMap } from "../inline/link.cjs";
1
2
  import { ParsedMarkdown } from "../block/block.cjs";
2
3
  import { ReadMarkdownOptions } from "../options/options.cjs";
3
4
  import { ContentDocument, LayoutMetadata } from "document-schema.js";
4
5
  //#region src/lower/lower.d.ts
5
6
  declare function lowerParsedMarkdown(parsed: ParsedMarkdown, options?: ReadMarkdownOptions, metadata?: LayoutMetadata): ContentDocument;
7
+ interface LoweredMarkdownDetail {
8
+ readonly document: ContentDocument;
9
+ readonly references: LinkReferenceMap;
10
+ readonly frontMatterSource: string | undefined;
11
+ }
12
+ declare function lowerMarkdownDetailed(source: string, options?: ReadMarkdownOptions): LoweredMarkdownDetail;
6
13
  declare function lowerMarkdown(source: string, options?: ReadMarkdownOptions): ContentDocument;
7
14
  //#endregion
8
- export { lowerMarkdown, lowerParsedMarkdown };
15
+ export { LoweredMarkdownDetail, lowerMarkdown, lowerMarkdownDetailed, lowerParsedMarkdown };
@@ -1,8 +1,15 @@
1
+ import { LinkReferenceMap } from "../inline/link.js";
1
2
  import { ParsedMarkdown } from "../block/block.js";
2
3
  import { ReadMarkdownOptions } from "../options/options.js";
3
4
  import { ContentDocument, LayoutMetadata } from "document-schema.js";
4
5
  //#region src/lower/lower.d.ts
5
6
  declare function lowerParsedMarkdown(parsed: ParsedMarkdown, options?: ReadMarkdownOptions, metadata?: LayoutMetadata): ContentDocument;
7
+ interface LoweredMarkdownDetail {
8
+ readonly document: ContentDocument;
9
+ readonly references: LinkReferenceMap;
10
+ readonly frontMatterSource: string | undefined;
11
+ }
12
+ declare function lowerMarkdownDetailed(source: string, options?: ReadMarkdownOptions): LoweredMarkdownDetail;
6
13
  declare function lowerMarkdown(source: string, options?: ReadMarkdownOptions): ContentDocument;
7
14
  //#endregion
8
- export { lowerMarkdown, lowerParsedMarkdown };
15
+ export { LoweredMarkdownDetail, lowerMarkdown, lowerMarkdownDetailed, lowerParsedMarkdown };