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
@@ -1,4 +1,4 @@
1
- import { MarkdownBulletListMarker, MarkdownCodeFenceChar, MarkdownEmphasisMarker, MarkdownHeadingStyle, MarkdownLineEnding, MarkdownOrderedListDelimiter, MarkdownThematicBreakChar } from "../options/options.cjs";
1
+ import { a as MarkdownLineEnding, i as MarkdownHeadingStyle, n as MarkdownCodeFenceChar, o as MarkdownOrderedListDelimiter, r as MarkdownEmphasisMarker, s as MarkdownThematicBreakChar, t as MarkdownBulletListMarker } from "../options-ZnZOMG3X.cjs";
2
2
  import { Margins } from "document-schema.js";
3
3
  //#region src/defaults/defaults.d.ts
4
4
  declare const DEFAULT_MARGINS: Margins;
@@ -1,4 +1,4 @@
1
- import { MarkdownBulletListMarker, MarkdownCodeFenceChar, MarkdownEmphasisMarker, MarkdownHeadingStyle, MarkdownLineEnding, MarkdownOrderedListDelimiter, MarkdownThematicBreakChar } from "../options/options.js";
1
+ import { a as MarkdownLineEnding, i as MarkdownHeadingStyle, n as MarkdownCodeFenceChar, o as MarkdownOrderedListDelimiter, r as MarkdownEmphasisMarker, s as MarkdownThematicBreakChar, t as MarkdownBulletListMarker } from "../options-CZoMEGL8.js";
2
2
  import { Margins } from "document-schema.js";
3
3
  //#region src/defaults/defaults.d.ts
4
4
  declare const DEFAULT_MARGINS: Margins;
@@ -1,648 +1,8 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_inline_footnote = require("../inline/footnote.cjs");
3
- require("../defaults/defaults.cjs");
4
- const require_diagnostics_diagnostics = require("../diagnostics/diagnostics.cjs");
5
- const require_html_html = require("../html/html.cjs");
6
- const require_shared_line_ending = require("../shared/line-ending.cjs");
7
- const require_block_line = require("../block/line.cjs");
8
- const require_block_list = require("../block/list.cjs");
9
- const require_block_table = require("../block/table.cjs");
10
- const require_block_block = require("../block/block.cjs");
11
- const require_shared_style_constants = require("../shared/style-constants.cjs");
12
- const require_shared_list_id = require("../shared/list-id.cjs");
13
- const require_emit_front_matter = require("./front-matter.cjs");
14
- const require_emit_inline = require("./inline.cjs");
15
- const require_emit_image = require("./image.cjs");
16
- const require_emit_table = require("./table.cjs");
17
- let document_schema_js = require("document-schema.js");
18
- //#region src/emit/emit.ts
19
- function isDataUri(destination) {
20
- return destination.startsWith("data:");
21
- }
22
- const MAX_SETEXT_LEVEL = 2;
23
- const SETEXT_LEVEL_1_CHAR = "=";
24
- const SETEXT_LEVEL_2_CHAR = "-";
25
- const MIN_SETEXT_UNDERLINE_LENGTH = 1;
26
- function splitLines(text, pattern) {
27
- const [first, ...rest] = text.split(pattern);
28
- return [first, ...rest];
29
- }
30
- function renderSetextHeading(level, text) {
31
- const underlineChar = level === 1 ? SETEXT_LEVEL_1_CHAR : SETEXT_LEVEL_2_CHAR;
32
- const [firstLine] = splitLines(text, require_shared_line_ending.LINE_ENDING_PATTERN);
33
- return `${text}\n${underlineChar.repeat(Math.max(MIN_SETEXT_UNDERLINE_LENGTH, firstLine.length))}`;
34
- }
35
- function renderAtxHeading(level, text) {
36
- const collapsed = text.replace(require_shared_line_ending.ESCAPED_HARD_BREAK_PATTERN, " ").split(require_shared_line_ending.LINE_ENDING_PATTERN).join(" ");
37
- return `${"#".repeat(level)} ${collapsed}`;
38
- }
39
- const MIN_CODE_FENCE_LENGTH = 3;
40
- const THEMATIC_BREAK_CHAR_COUNT = 3;
41
- function longestRunLength(text, char) {
42
- let longest = 0;
43
- let current = 0;
44
- for (const candidate of text) if (candidate === char) {
45
- current += 1;
46
- longest = Math.max(longest, current);
47
- } else current = 0;
48
- return longest;
49
- }
50
- function codeFenceFor(literal, fenceChar) {
51
- return fenceChar.repeat(Math.max(MIN_CODE_FENCE_LENGTH, longestRunLength(literal, fenceChar) + 1));
52
- }
53
- const QUOTABLE_STYLE_IDS = /* @__PURE__ */ new Set([
54
- require_shared_style_constants.QUOTE_STYLE_ID,
55
- require_shared_style_constants.CODE_BLOCK_STYLE_ID,
56
- require_shared_style_constants.HORIZONTAL_RULE_STYLE_ID,
57
- require_shared_style_constants.HTML_PREFORMATTED_STYLE_ID,
58
- require_shared_style_constants.MATH_BLOCK_STYLE_ID
59
- ]);
60
- function isQuotableStyle(styleId) {
61
- if (styleId === void 0) return false;
62
- return QUOTABLE_STYLE_IDS.has(styleId) || require_shared_style_constants.parseHeadingStyleId(styleId) !== void 0;
63
- }
64
- function terminatesCleanly(styleId) {
65
- return styleId === "CodeBlock" || styleId === "MathBlock" || styleId === "HorizontalRule" || styleId !== void 0 && require_shared_style_constants.parseHeadingStyleId(styleId) !== void 0;
66
- }
67
- const BLANK_OR_WHITESPACE_ONLY_LINE = /^[ \t]*$/;
68
- function firstContentLineIndex(text) {
69
- return text.split(require_shared_line_ending.LINE_ENDING_PATTERN).findIndex((line) => !BLANK_OR_WHITESPACE_ONLY_LINE.test(line));
70
- }
71
- function leadingIndentReachesCodeThreshold(line) {
72
- let column = 0;
73
- while (line[column] === " ") column += 1;
74
- if (column >= 4) return true;
75
- return line[column] === " ";
76
- }
77
- const MAX_LEADING_BLANK_LINES_FOR_SETEXT = 1;
78
- function interruptsSetextParagraph(line, atBlockStart) {
79
- const cursor = new require_block_line.LineCursor(line);
80
- if (cursor.indented) return false;
81
- if (cursor.peekNextNonspace() === ">") return true;
82
- const rest = cursor.restFromNextNonspace();
83
- if (require_block_block.ATX_MARKER_PATTERN.test(rest) || require_block_block.CODE_FENCE_PATTERN.test(rest) || require_block_block.THEMATIC_BREAK_PATTERN.test(rest) || require_block_block.MATH_BLOCK_MARKER_PATTERN.test(rest) || require_html_html.matchHtmlBlockStart(rest, !atBlockStart) !== void 0) return true;
84
- return require_block_list.parseListMarker(cursor, !atBlockStart) !== void 0;
85
- }
86
- function tableDelimiterRowPromotesPrecedingLine(line, precedingLine) {
87
- const cursor = new require_block_line.LineCursor(line);
88
- if (cursor.indented) return false;
89
- return require_block_table.parseTableDelimiterRow(cursor.restFromNextNonspace())?.length === require_block_table.splitTableRow(precedingLine).length;
90
- }
91
- function unsafeSetextBreakReason(text) {
92
- let leadingBlankLines = 0;
93
- let precedingLine;
94
- for (const line of text.split(require_shared_line_ending.LINE_ENDING_PATTERN)) {
95
- const isBlank = BLANK_OR_WHITESPACE_ONLY_LINE.test(line);
96
- if (precedingLine === void 0) {
97
- if (isBlank) {
98
- leadingBlankLines += 1;
99
- if (leadingBlankLines > MAX_LEADING_BLANK_LINES_FOR_SETEXT) return "blank-line";
100
- continue;
101
- }
102
- if (leadingIndentReachesCodeThreshold(line)) return "leading-indentation";
103
- if (interruptsSetextParagraph(line, true)) return "interrupting-line";
104
- precedingLine = line;
105
- continue;
106
- }
107
- if (isBlank) return "blank-line";
108
- if (interruptsSetextParagraph(line, false) || tableDelimiterRowPromotesPrecedingLine(line, precedingLine)) return "interrupting-line";
109
- precedingLine = line;
110
- }
111
- return precedingLine === void 0 ? "blank-line" : void 0;
112
- }
113
- function embedsUnsafeBreakForSetext(text) {
114
- return unsafeSetextBreakReason(text) !== void 0;
115
- }
116
- function unsafeSetextDiagnosticMessage(level, reason, embedsLineBreak) {
117
- const hazard = reason === "leading-indentation" ? `the line that would become the setext heading's own first line of text opens with 4 or more columns of space/tab indentation — setext's own grammar (spec 0.31.2) requires the first line to have "not more than 3 spaces of indentation", so promoting would read that line back as an indented code block instead of heading text` : reason === "interrupting-line" ? `a line of the heading's own text — including possibly its first — would itself be interpretable as a code fence, ATX heading, block quote, thematic break, list item, HTML block, math block, or GFM table delimiter row — setext's own grammar (spec 0.31.2) requires every one of the heading's lines to instead read as ordinary paragraph text, so promoting would read that line back as the start of a fresh, unrelated block (or, for a table delimiter row, a conversion of the line before it) rather than more of the heading` : `promoting would leave the setext underline with no heading text of its own to attach to — either a blank line immediately before it (a trailing break), a blank line in the middle of the heading's own text (a genuinely interior break), or the heading's own rendered text being entirely blank to begin with — setext's own grammar requires "one or more lines of text, not interrupted by a blank line"`;
118
- return embedsLineBreak ? `a level ${String(level)} heading's own content contains a line break, but ${hazard}; ATX collapses the break to a single space instead of promoting into a corrupt reparse` : `the effective WriteMarkdownOptions.headingStyle is 'setext' (an explicit caller choice — a break-free heading only reaches this path when requested outright), but ${hazard}; rendered as ATX instead of promoting into a corrupt reparse`;
119
- }
120
- function willRenderAsSetext(paragraph, level, context) {
121
- if (level > MAX_SETEXT_LEVEL) return false;
122
- const text = require_emit_inline.emitRuns(paragraph.runs, {
123
- sink: require_diagnostics_diagnostics.NOOP_MARKDOWN_DIAGNOSTIC_SINK,
124
- emphasisMarker: context.emphasisMarker
125
- }, paragraph.constructs);
126
- if (embedsUnsafeBreakForSetext(text)) return false;
127
- return context.headingStyle === "setext" || require_shared_line_ending.LINE_ENDING_PATTERN.test(text);
128
- }
129
- function canInterruptOpenParagraph(paragraph, context) {
130
- const styleId = paragraph.styleId;
131
- if (styleId === void 0) return false;
132
- if (styleId === "CodeBlock" || styleId === "MathBlock") return true;
133
- if (styleId === "HorizontalRule") return context.thematicBreakChar !== SETEXT_LEVEL_2_CHAR;
134
- const headingLevel = require_shared_style_constants.parseHeadingStyleId(styleId);
135
- if (headingLevel !== void 0) return !willRenderAsSetext(paragraph, (0, document_schema_js.clampHeadingLevel)(headingLevel), context);
136
- return false;
137
- }
138
- function quoteDepthOf(paragraph) {
139
- if (paragraph.indentLeftPt === void 0 || paragraph.indentLeftPt <= 0) return 0;
140
- return Math.max(1, Math.round(paragraph.indentLeftPt / 36));
141
- }
142
- function renderParagraphBody(paragraph, context) {
143
- if (paragraph.styleId === "HorizontalRule") return context.thematicBreakChar.repeat(THEMATIC_BREAK_CHAR_COUNT);
144
- if (paragraph.styleId === "CodeBlock") {
145
- const literal = paragraph.runs.map((run) => run.text).join("");
146
- const fence = codeFenceFor(literal, context.codeFenceChar);
147
- const remainder = paragraph.source?.format === "markdown" ? paragraph.source.xml : void 0;
148
- const info = [paragraph.codeLanguage, remainder].filter((part) => part !== void 0 && part.length > 0).join(" ");
149
- const opening = info.length > 0 ? `${fence} ${info}` : fence;
150
- return literal.length === 0 ? `${opening}\n${fence}` : `${opening}\n${literal}\n${fence}`;
151
- }
152
- if (paragraph.styleId === "HTMLPreformatted") return paragraph.source?.format === "markdown" ? paragraph.source.xml : paragraph.runs.map((run) => run.text).join("");
153
- if (paragraph.styleId === "MathBlock") return `$$\n${paragraph.runs.map((run) => run.text).join("")}\n$$`;
154
- const headingLevel = paragraph.styleId === void 0 ? void 0 : require_shared_style_constants.parseHeadingStyleId(paragraph.styleId);
155
- if (headingLevel !== void 0) {
156
- const level = (0, document_schema_js.clampHeadingLevel)(headingLevel);
157
- if (level !== headingLevel) context.sink({
158
- code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.HEADING_LEVEL_CLAMPED,
159
- severity: "info",
160
- message: `heading level ${String(headingLevel)} exceeds ATX's own six-"#" ceiling and is clamped to ${String(level)}`
161
- });
162
- const text = require_emit_inline.emitRuns(paragraph.runs, context, paragraph.constructs);
163
- const embedsLineBreak = require_shared_line_ending.LINE_ENDING_PATTERN.test(text);
164
- const unsafeSetextReason = unsafeSetextBreakReason(text);
165
- const unsafeForSetext = unsafeSetextReason !== void 0;
166
- const setextRequested = context.headingStyle === "setext" || embedsLineBreak;
167
- if (setextRequested && level <= MAX_SETEXT_LEVEL && !unsafeForSetext) {
168
- if (context.headingStyle !== "setext") {
169
- const leadingBreakAbsorbed = firstContentLineIndex(text) > 0;
170
- context.sink({
171
- code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.HEADING_STYLE_OVERRIDDEN_FOR_LINE_BREAK,
172
- severity: "info",
173
- message: leadingBreakAbsorbed ? `the effective WriteMarkdownOptions.headingStyle is 'atx' (its own default, or an explicit caller choice), but this level ${String(level)} heading's own content contains a line break ATX has no way to hold — rendered as setext instead, though the heading's own leading blank line is absorbed as ordinary space ahead of it on read-back rather than reproduced inside it` : `the effective WriteMarkdownOptions.headingStyle is 'atx' (its own default, or an explicit caller choice), but this level ${String(level)} heading's own content contains a line break ATX has no way to hold — rendered as setext instead so the break survives`
174
- });
175
- }
176
- return renderSetextHeading(level, text);
177
- }
178
- if (setextRequested && level <= MAX_SETEXT_LEVEL && unsafeForSetext) {
179
- context.sink({
180
- code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.HEADING_LINE_BREAK_UNSAFE_FOR_SETEXT,
181
- severity: "info",
182
- message: unsafeSetextDiagnosticMessage(level, unsafeSetextReason, embedsLineBreak)
183
- });
184
- return renderAtxHeading(level, text);
185
- }
186
- if (embedsLineBreak) context.sink({
187
- code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.HEADING_LINE_BREAK_COLLAPSED,
188
- severity: "info",
189
- message: `a level ${String(level)} heading's own content contains a line break; only setext's own level-1/2 grammar can hold one, so ATX collapses it to a single space`
190
- });
191
- return renderAtxHeading(level, text);
192
- }
193
- return require_emit_inline.emitRuns(paragraph.runs, context, paragraph.constructs);
194
- }
195
- function renderParagraph(paragraph, context) {
196
- const body = renderParagraphBody(paragraph, context);
197
- const depth = context.divisionDepth > 0 ? 0 : quoteDepthOf(paragraph);
198
- if (depth === 0) return body;
199
- if (!isQuotableStyle(paragraph.styleId)) {
200
- context.sink({
201
- code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.PARAGRAPH_INDENT_DROPPED,
202
- severity: "info",
203
- message: `paragraph carries indentLeftPt (${String(paragraph.indentLeftPt)}pt) with no styleId this package recognises as quotable; the indent has no other markdown representation and is dropped`
204
- });
205
- return body;
206
- }
207
- const prefix = "> ".repeat(depth);
208
- return body.split("\n").map((line) => `${prefix}${line}`).join("\n");
209
- }
210
- function renderTopLevelBlock(block, context) {
211
- switch (block.kind) {
212
- case "paragraph": return renderParagraph(block, context);
213
- case "table": return require_emit_table.emitTable(block, context);
214
- case "image": return require_emit_image.emitImage(block, context.embedImages);
215
- case "embeddedObject":
216
- if (block.objectKind === "formula" && block.document.kind === "formula" && block.document.formula.presentation !== void 0) {
217
- const latex = block.document.formula.presentation.latex;
218
- return latex.length === 0 ? "$$\n$$" : `$$\n${latex}\n$$`;
219
- }
220
- return "";
221
- case "pageBreak": return "";
222
- }
223
- return assertNeverRenderableBlock(block);
224
- }
225
- function listInfoFor(numId, context) {
226
- if (numId === void 0) {
227
- if (!context.reportedAbsentNumIdFallback) {
228
- context.reportedAbsentNumIdFallback = true;
229
- context.sink({
230
- code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.LIST_NUMID_FALLBACK,
231
- severity: "info",
232
- message: "a list membership with no numId of its own (a depth-only ContentListMembership) has no marker type, task-ness, or loose-ness to recover and falls back to an ordinary, tight, non-task bullet list"
233
- });
234
- }
235
- return;
236
- }
237
- const info = require_shared_list_id.parseListNumId(numId);
238
- if (info === void 0 && !context.reportedFallbackNumIds.has(numId)) {
239
- context.reportedFallbackNumIds.add(numId);
240
- context.sink({
241
- code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.LIST_NUMID_FALLBACK,
242
- severity: "info",
243
- message: `numId "${numId}" was not minted by this package's own src/lower and falls back to an ordinary, tight, non-task bullet list`
244
- });
245
- }
246
- return info;
247
- }
248
- function stripCheckboxRun(item) {
249
- const first = item.runs[0];
250
- const glyphPrefix = first?.text.startsWith(`☒ `) === true ? `☒ ` : `☐ `;
251
- if (first?.text.startsWith(glyphPrefix) !== true) return item;
252
- const strippedText = first.text.slice(glyphPrefix.length);
253
- const runs = strippedText.length === 0 ? item.runs.slice(1) : [{
254
- ...first,
255
- text: strippedText
256
- }, ...item.runs.slice(1)];
257
- return {
258
- ...item,
259
- runs
260
- };
261
- }
262
- function toEmitItem(item) {
263
- return item.kind === "paragraph" ? { block: item.block } : item.item;
264
- }
265
- function firstBlockCheckbox(first, taskNumId) {
266
- if (first.list.checked !== void 0) return {
267
- checkboxText: first.list.checked ? "[x] " : "[ ] ",
268
- strippedFirstBlock: void 0
269
- };
270
- if (!taskNumId || first.kind !== "paragraph") return {
271
- checkboxText: "",
272
- strippedFirstBlock: void 0
273
- };
274
- const leading = first.block.runs[0]?.text;
275
- if (leading?.startsWith(`☒ `) === true) return {
276
- checkboxText: "[x] ",
277
- strippedFirstBlock: stripCheckboxRun(first.block)
278
- };
279
- if (leading?.startsWith(`☐ `) === true) return {
280
- checkboxText: "[ ] ",
281
- strippedFirstBlock: stripCheckboxRun(first.block)
282
- };
283
- return {
284
- checkboxText: "",
285
- strippedFirstBlock: void 0
286
- };
287
- }
288
- function renderListItemMarker(numId, info, glyph, checkboxText, context) {
289
- if (info?.type === "ordered" && numId !== void 0) {
290
- const next = context.orderedCounters.get(numId) ?? info.start ?? 1;
291
- context.orderedCounters.set(numId, next + 1);
292
- const bare = `${String(next)}${glyph} `;
293
- return {
294
- full: `${bare}${checkboxText}`,
295
- bareLength: bare.length
296
- };
297
- }
298
- const bare = `${glyph} `;
299
- return {
300
- full: `${bare}${checkboxText}`,
301
- bareLength: bare.length
302
- };
303
- }
304
- const BULLET_GLYPH_CANDIDATES = [
305
- "-",
306
- "+",
307
- "*"
308
- ];
309
- const ORDERED_GLYPH_CANDIDATES = [".", ")"];
310
- function resolveListGlyph(numId, type, previousSibling, context) {
311
- const cached = context.resolvedListGlyphs.get(numId);
312
- if (cached !== void 0) return cached;
313
- const defaultGlyph = type === "ordered" ? context.orderedDelimiter : context.bulletMarker;
314
- const glyph = previousSibling?.type === type && previousSibling.glyph === defaultGlyph ? (type === "ordered" ? ORDERED_GLYPH_CANDIDATES : BULLET_GLYPH_CANDIDATES).find((candidate) => candidate !== defaultGlyph) ?? defaultGlyph : defaultGlyph;
315
- context.resolvedListGlyphs.set(numId, glyph);
316
- return glyph;
317
- }
318
- function consumeSameItemRun(items, from, level, itemId) {
319
- let end = from;
320
- for (;;) {
321
- const candidate = items[end];
322
- if (candidate?.list.level !== level || candidate.list.itemId !== itemId) break;
323
- end += 1;
324
- }
325
- return end;
326
- }
327
- function collectListItem(items, start, level, itemId) {
328
- const segments = [];
329
- let index = start;
330
- const ownEnd = itemId === void 0 ? index + 1 : consumeSameItemRun(items, index, level, itemId);
331
- segments.push({
332
- kind: "own",
333
- blocks: items.slice(index, ownEnd)
334
- });
335
- index = ownEnd;
336
- for (;;) {
337
- let nestedEnd = index;
338
- for (;;) {
339
- const candidateLevel = items[nestedEnd]?.list.level;
340
- if (candidateLevel === void 0 || candidateLevel <= level) break;
341
- nestedEnd += 1;
342
- }
343
- if (nestedEnd === index) break;
344
- segments.push({
345
- kind: "nested",
346
- blocks: items.slice(index, nestedEnd)
347
- });
348
- index = nestedEnd;
349
- if (itemId === void 0) break;
350
- const resumedEnd = consumeSameItemRun(items, index, level, itemId);
351
- segments.push({
352
- kind: "own",
353
- blocks: items.slice(index, resumedEnd)
354
- });
355
- index = resumedEnd;
356
- }
357
- return {
358
- segments,
359
- next: index
360
- };
361
- }
362
- function emitItemCanInterrupt(item, context) {
363
- if (!isConstructItem(item)) return item.block.kind === "paragraph" ? canInterruptOpenParagraph(item.block, context) : true;
364
- if (isMaterialisedDivision(item)) return true;
365
- const first = item.children[0];
366
- return first === void 0 ? true : emitItemCanInterrupt(first, context);
367
- }
368
- function lastStyleIdOf(item) {
369
- if (isConstructItem(item)) {
370
- const last = item.children[item.children.length - 1];
371
- return last === void 0 ? void 0 : lastStyleIdOf(last);
372
- }
373
- return item.block.kind === "paragraph" ? item.block.styleId : void 0;
374
- }
375
- function regionItemCanInterrupt(item, context) {
376
- return emitItemCanInterrupt(toEmitItem(item), context);
377
- }
378
- function lastStyleIdOfRegionItem(item) {
379
- return lastStyleIdOf(toEmitItem(item));
380
- }
381
- function listRegionItemBody(item, context, overrideParagraph) {
382
- if (item.kind === "paragraph") return renderParagraphBody(overrideParagraph ?? item.block, context);
383
- const previousEnclosingItemId = context.enclosingItemId;
384
- context.enclosingItemId = item.list.itemId;
385
- const body = renderConstruct(item.item, context);
386
- context.enclosingItemId = previousEnclosingItemId;
387
- return body;
388
- }
389
- function requiresBlankLineBefore(next, previousStyleId, context) {
390
- if (previousStyleId === "HTMLPreformatted") return true;
391
- return !terminatesCleanly(previousStyleId) && !regionItemCanInterrupt(next, context);
392
- }
393
- function renderListRegion(items, context) {
394
- const parts = [];
395
- let index = 0;
396
- let previousSibling;
397
- for (;;) {
398
- const item = items[index];
399
- if (item === void 0) break;
400
- const { numId, level, itemId } = item.list;
401
- const info = listInfoFor(numId, context);
402
- const loose = info?.loose === true;
403
- const type = info?.type ?? "bullet";
404
- const glyph = numId === void 0 ? context.bulletMarker : resolveListGlyph(numId, type, previousSibling, context);
405
- if (numId !== void 0) previousSibling = {
406
- numId,
407
- type,
408
- glyph
409
- };
410
- const { segments, next } = collectListItem(items, index, level, itemId);
411
- const first = segments[0]?.blocks[0];
412
- if (first === void 0) break;
413
- const { checkboxText, strippedFirstBlock } = firstBlockCheckbox(first, info?.task === true);
414
- const marker = renderListItemMarker(numId, info, glyph, checkboxText, context);
415
- const indent = " ".repeat(marker.bareLength);
416
- let text = marker.full;
417
- let renderedFirstLine = false;
418
- let previousStyleId;
419
- for (const segment of segments) {
420
- if (segment.kind === "nested") {
421
- const nested = renderListRegion(segment.blocks, context).split("\n").map((line) => line.length === 0 ? line : `${indent}${line}`).join("\n");
422
- text += `\n${nested}`;
423
- const lastNested = segment.blocks[segment.blocks.length - 1];
424
- previousStyleId = lastNested === void 0 ? void 0 : lastStyleIdOfRegionItem(lastNested);
425
- continue;
426
- }
427
- for (const block of segment.blocks) {
428
- if (!renderedFirstLine) {
429
- const [firstLine, ...restLines] = splitLines(listRegionItemBody(block, context, strippedFirstBlock), "\n");
430
- text += [firstLine, ...restLines.map((line) => `${indent}${line}`)].join("\n");
431
- renderedFirstLine = true;
432
- previousStyleId = lastStyleIdOfRegionItem(block);
433
- continue;
434
- }
435
- const rendered = listRegionItemBody(block, context, void 0).split("\n").map((line) => line.length === 0 ? line : `${indent}${line}`).join("\n");
436
- const blank = loose || requiresBlankLineBefore(block, previousStyleId, context);
437
- text += blank ? `\n\n${rendered}` : `\n${rendered}`;
438
- previousStyleId = lastStyleIdOfRegionItem(block);
439
- }
440
- }
441
- parts.push({
442
- numId,
443
- text
444
- });
445
- index = next;
446
- }
447
- let out = "";
448
- for (const [partIndex, part] of parts.entries()) {
449
- if (partIndex > 0) {
450
- const previous = parts[partIndex - 1];
451
- const continuesTightly = previous.numId === part.numId && (previous.numId === void 0 || require_shared_list_id.parseListNumId(previous.numId)?.loose !== true);
452
- out += continuesTightly ? "\n" : "\n\n";
453
- }
454
- out += part.text;
455
- }
456
- return out;
457
- }
458
- function isConstructItem(item) {
459
- return "descriptor" in item;
460
- }
461
- const UNINDENTED_PT = 0;
462
- function isMaterialisedDivision(item) {
463
- return item.descriptor.kind === "division" && item.children.every((child) => {
464
- if (isConstructItem(child)) return true;
465
- return child.block.kind !== "paragraph" || (child.block.indentLeftPt ?? UNINDENTED_PT) >= 36;
466
- });
467
- }
468
- function groupConstructItems(blocks, start) {
469
- const items = [];
470
- let index = start;
471
- for (;;) {
472
- const block = blocks[index];
473
- if (block === void 0) break;
474
- index += 1;
475
- if (block.kind === "constructEnd") return {
476
- items,
477
- next: index
478
- };
479
- if (block.kind === "constructStart") {
480
- const nested = groupConstructItems(blocks, index);
481
- items.push({
482
- descriptor: block.descriptor,
483
- children: nested.items
484
- });
485
- index = nested.next;
486
- continue;
487
- }
488
- items.push({ block });
489
- }
490
- return {
491
- items,
492
- next: index
493
- };
494
- }
495
- const FOOTNOTE_CONTINUATION_INDENT = 4;
496
- function renderFootnoteDefinition(name, body) {
497
- const marker = `[^${name}]:`;
498
- if (body.length === 0) return marker;
499
- const indent = " ".repeat(FOOTNOTE_CONTINUATION_INDENT);
500
- const [firstLine, ...restLines] = splitLines(body, "\n");
501
- return [`${marker} ${firstLine}`, ...restLines.map((line) => line.length === 0 ? line : `${indent}${line}`)].join("\n");
502
- }
503
- function renderConstruct(item, context) {
504
- const { descriptor } = item;
505
- if (descriptor.kind === "anchor" && descriptor.anchorType === "footnote") {
506
- const body = renderItems(item.children, context);
507
- if (require_inline_footnote.isValidFootnoteLabel(descriptor.name)) return renderFootnoteDefinition(descriptor.name, body);
508
- context.sink({
509
- code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.CONSTRUCT_UNREPRESENTED,
510
- severity: "info",
511
- message: `a footnote anchor's own name "${descriptor.name}" cannot be spelled as a "[^label]:" marker (whitespace or "]" would reparse as something else); its own extent still renders in place, but the construct itself is not represented`
512
- });
513
- return body;
514
- }
515
- if (isMaterialisedDivision(item)) {
516
- context.divisionDepth += 1;
517
- const body = renderItems(item.children, context);
518
- context.divisionDepth -= 1;
519
- return body.split("\n").map((line) => line.length === 0 ? ">" : `> ${line}`).join("\n");
520
- }
521
- if (descriptor.kind === "link" && descriptor.target.kind === "external") {
522
- const onlyChild = item.children.length === 1 && !isConstructItem(item.children[0]) ? item.children[0].block : void 0;
523
- if (onlyChild?.kind === "image" && !isDataUri(descriptor.target.uri)) return `![${require_emit_inline.escapeMarkdownText(onlyChild.altText ?? "")}](${require_emit_inline.escapeLinkDestination(descriptor.target.uri)}${descriptor.title === void 0 ? "" : ` "${require_emit_inline.renderLinkTitle(descriptor.title)}"`})`;
524
- if (onlyChild?.kind === "image" && isDataUri(descriptor.target.uri) && !context.embedImages) return require_emit_image.emitImage(onlyChild, false);
525
- }
526
- const body = renderItems(item.children, context);
527
- const detail = descriptor.kind === "anchor" ? `${descriptor.kind} (${descriptor.anchorType})` : descriptor.kind;
528
- context.sink({
529
- code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.CONSTRUCT_UNREPRESENTED,
530
- severity: "info",
531
- message: `a "${detail}" construct has no markdown syntax; its own extent still renders in place, but the construct itself is not represented`
532
- });
533
- return body;
534
- }
535
- function constructCarriesListItemId(item, itemId) {
536
- return item.children.some((child) => {
537
- if (isConstructItem(child)) return constructCarriesListItemId(child, itemId);
538
- if (child.block.kind !== "paragraph") return false;
539
- const list = child.block.list;
540
- if (list?.itemId === itemId) return true;
541
- return list?.numId !== void 0 && require_shared_list_id.parseListNumId(list.numId)?.ownerItemId === itemId;
542
- });
543
- }
544
- function isInheritedListMembership(list, context) {
545
- return list.itemId !== void 0 && list.itemId === context.enclosingItemId;
546
- }
547
- function renderItems(items, context) {
548
- const parts = [];
549
- let index = 0;
550
- for (;;) {
551
- const item = items[index];
552
- if (item === void 0) break;
553
- if (isConstructItem(item)) {
554
- const rendered = renderConstruct(item, context);
555
- if (rendered.length > 0) parts.push(rendered);
556
- index += 1;
557
- continue;
558
- }
559
- if (item.block.kind === "paragraph" && item.block.list !== void 0 && !isInheritedListMembership(item.block.list, context)) {
560
- const region = [];
561
- let end = index;
562
- const openMemberships = [];
563
- for (;;) {
564
- const candidate = items[end];
565
- if (candidate === void 0) break;
566
- if (isConstructItem(candidate)) {
567
- let matched;
568
- for (let i = openMemberships.length - 1; i >= 0; i -= 1) {
569
- const membership = openMemberships[i];
570
- if (membership.itemId !== void 0 && constructCarriesListItemId(candidate, membership.itemId)) {
571
- matched = membership;
572
- break;
573
- }
574
- }
575
- if (matched === void 0) break;
576
- region.push({
577
- kind: "construct",
578
- item: candidate,
579
- list: matched
580
- });
581
- end += 1;
582
- continue;
583
- }
584
- if (candidate.block.kind !== "paragraph" || candidate.block.list === void 0 || isInheritedListMembership(candidate.block.list, context)) break;
585
- const list = candidate.block.list;
586
- while (openMemberships.length > 0 && openMemberships[openMemberships.length - 1].level >= list.level) openMemberships.pop();
587
- openMemberships.push(list);
588
- region.push({
589
- kind: "paragraph",
590
- block: candidate.block,
591
- list
592
- });
593
- end += 1;
594
- }
595
- parts.push(renderListRegion(region, context));
596
- index = end;
597
- continue;
598
- }
599
- const rendered = renderTopLevelBlock(item.block, context);
600
- if (rendered.length > 0) parts.push(rendered);
601
- index += 1;
602
- }
603
- return parts.join("\n\n");
604
- }
605
- function emitBlocks(blocks, context) {
606
- const imbalance = (0, document_schema_js.findConstructMarkerImbalance)(blocks);
607
- if (imbalance !== void 0) throw new require_diagnostics_diagnostics.MarkdownUnbalancedConstructMarkersError(imbalance.kind, imbalance.index);
608
- validateRunConstructExtents(blocks);
609
- return renderItems(groupConstructItems(blocks, 0).items, context);
610
- }
611
- function validateRunConstructExtents(blocks) {
612
- for (const block of blocks) {
613
- if (block.kind === "paragraph") {
614
- const fault = (0, document_schema_js.findRunConstructFault)(block);
615
- if (fault !== void 0) throw new require_diagnostics_diagnostics.MarkdownInvalidRunConstructExtentError(fault.kind, fault.index);
616
- }
617
- if (block.kind === "table") for (const row of block.rows) for (const cell of row.cells) validateRunConstructExtents(cell.blocks);
618
- }
619
- }
620
- function emitMarkdown(document, options = {}) {
621
- if (document.kind !== "wordprocessing") throw new require_diagnostics_diagnostics.MarkdownUnsupportedDocumentKindError(document.kind);
622
- const context = {
623
- sink: options.sink ?? require_diagnostics_diagnostics.NOOP_MARKDOWN_DIAGNOSTIC_SINK,
624
- emphasisMarker: options.emphasisMarker ?? "_",
625
- bulletMarker: options.bulletListMarker ?? "-",
626
- orderedDelimiter: options.orderedListDelimiter ?? ".",
627
- codeFenceChar: options.codeFenceChar ?? "`",
628
- thematicBreakChar: options.thematicBreakChar ?? "-",
629
- headingStyle: options.headingStyle ?? "atx",
630
- embedImages: options.images ?? true,
631
- orderedCounters: /* @__PURE__ */ new Map(),
632
- resolvedListGlyphs: /* @__PURE__ */ new Map(),
633
- reportedFallbackNumIds: /* @__PURE__ */ new Set(),
634
- reportedAbsentNumIdFallback: false,
635
- divisionDepth: 0,
636
- enclosingItemId: void 0
637
- };
638
- const body = document.sections.map((section) => emitBlocks(section.blocks, context)).join("\n\n");
639
- const frontMatter = options.frontMatter === true ? require_emit_front_matter.emitFrontMatter(document.metadata) : void 0;
640
- const text = frontMatter === void 0 ? body : `${frontMatter}\n\n${body}`;
641
- return (options.lineEnding ?? "lf") === "crlf" ? text.replaceAll("\n", "\r\n") : text;
642
- }
643
- function assertNeverRenderableBlock(block) {
644
- throw new Error(`markdown-codec: unhandled renderable block ${JSON.stringify(block)}`);
645
- }
646
- //#endregion
647
- exports.assertNeverRenderableBlock = assertNeverRenderableBlock;
648
- exports.emitMarkdown = emitMarkdown;
2
+ const require_emit = require("../emit-CCOoudJW.cjs");
3
+ exports.assertNeverRenderableBlock = require_emit.assertNeverRenderableBlock;
4
+ exports.canInterruptOpenParagraph = require_emit.canInterruptOpenParagraph;
5
+ exports.emitMarkdown = require_emit.emitMarkdown;
6
+ exports.isDataUri = require_emit.isDataUri;
7
+ exports.renderParagraphBody = require_emit.renderParagraphBody;
8
+ exports.renderTopLevelBlock = require_emit.renderTopLevelBlock;