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.
- package/LICENSE +21 -0
- package/README.md +215 -0
- package/dist/ast/ast.cjs +25 -0
- package/dist/ast/ast.d.cts +2 -0
- package/dist/ast/ast.d.ts +2 -0
- package/dist/ast/ast.js +23 -0
- package/dist/ast-BXYwy08e.d.cts +160 -0
- package/dist/ast-BXYwy08e.d.ts +160 -0
- package/dist/block/block.cjs +530 -0
- package/dist/block/block.d.cts +18 -0
- package/dist/block/block.d.ts +18 -0
- package/dist/block/block.js +529 -0
- package/dist/block/definitions.cjs +59 -0
- package/dist/block/definitions.d.cts +6 -0
- package/dist/block/definitions.d.ts +6 -0
- package/dist/block/definitions.js +58 -0
- package/dist/block/line.cjs +76 -0
- package/dist/block/line.d.cts +28 -0
- package/dist/block/line.d.ts +28 -0
- package/dist/block/line.js +74 -0
- package/dist/block/list.cjs +110 -0
- package/dist/block/list.d.cts +8 -0
- package/dist/block/list.d.ts +8 -0
- package/dist/block/list.js +107 -0
- package/dist/block/node.cjs +68 -0
- package/dist/block/node.d.cts +45 -0
- package/dist/block/node.d.ts +45 -0
- package/dist/block/node.js +65 -0
- package/dist/block/table.cjs +64 -0
- package/dist/block/table.d.cts +7 -0
- package/dist/block/table.d.ts +7 -0
- package/dist/block/table.js +61 -0
- package/dist/codec.cjs +22 -0
- package/dist/codec.d.cts +361 -0
- package/dist/codec.d.ts +361 -0
- package/dist/codec.js +20 -0
- package/dist/defaults/defaults.cjs +31 -0
- package/dist/defaults/defaults.d.cts +16 -0
- package/dist/defaults/defaults.d.ts +16 -0
- package/dist/defaults/defaults.js +20 -0
- package/dist/diagnostics/diagnostics.cjs +85 -0
- package/dist/diagnostics/diagnostics.d.cts +2 -0
- package/dist/diagnostics/diagnostics.d.ts +2 -0
- package/dist/diagnostics/diagnostics.js +77 -0
- package/dist/diagnostics-DmuWc7d8.d.cts +61 -0
- package/dist/diagnostics-DmuWc7d8.d.ts +61 -0
- package/dist/emit/emit.cjs +228 -0
- package/dist/emit/emit.d.cts +6 -0
- package/dist/emit/emit.d.ts +6 -0
- package/dist/emit/emit.js +227 -0
- package/dist/emit/front-matter.cjs +24 -0
- package/dist/emit/front-matter.d.cts +5 -0
- package/dist/emit/front-matter.d.ts +5 -0
- package/dist/emit/front-matter.js +23 -0
- package/dist/emit/image.cjs +10 -0
- package/dist/emit/image.d.cts +5 -0
- package/dist/emit/image.d.ts +5 -0
- package/dist/emit/image.js +9 -0
- package/dist/emit/inline.cjs +183 -0
- package/dist/emit/inline.d.cts +12 -0
- package/dist/emit/inline.d.ts +12 -0
- package/dist/emit/inline.js +180 -0
- package/dist/emit/table.cjs +73 -0
- package/dist/emit/table.d.cts +10 -0
- package/dist/emit/table.d.ts +10 -0
- package/dist/emit/table.js +72 -0
- package/dist/html/html.cjs +116 -0
- package/dist/html/html.d.cts +2 -0
- package/dist/html/html.d.ts +2 -0
- package/dist/html/html.js +113 -0
- package/dist/html/render.cjs +193 -0
- package/dist/html/render.d.cts +8 -0
- package/dist/html/render.d.ts +8 -0
- package/dist/html/render.js +189 -0
- package/dist/html-bkz2QTuq.d.cts +7 -0
- package/dist/html-bkz2QTuq.d.ts +7 -0
- package/dist/image/image.cjs +129 -0
- package/dist/image/image.d.cts +2 -0
- package/dist/image/image.d.ts +2 -0
- package/dist/image/image.js +125 -0
- package/dist/image-C4KYmz_L.d.cts +19 -0
- package/dist/image-Cm3hT5PS.d.ts +19 -0
- package/dist/image-DescdRgq.d.cts +12 -0
- package/dist/image-DescdRgq.d.ts +12 -0
- package/dist/index.cjs +17 -0
- package/dist/index.d.cts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +5 -0
- package/dist/inline/chars.cjs +50 -0
- package/dist/inline/chars.d.cts +11 -0
- package/dist/inline/chars.d.ts +11 -0
- package/dist/inline/chars.js +42 -0
- package/dist/inline/delimiter.cjs +136 -0
- package/dist/inline/delimiter.d.cts +29 -0
- package/dist/inline/delimiter.d.ts +29 -0
- package/dist/inline/delimiter.js +132 -0
- package/dist/inline/entity.cjs +67 -0
- package/dist/inline/entity.d.cts +9 -0
- package/dist/inline/entity.d.ts +9 -0
- package/dist/inline/entity.js +65 -0
- package/dist/inline/gfm-autolink.cjs +156 -0
- package/dist/inline/gfm-autolink.d.cts +5 -0
- package/dist/inline/gfm-autolink.d.ts +5 -0
- package/dist/inline/gfm-autolink.js +155 -0
- package/dist/inline/inline.cjs +457 -0
- package/dist/inline/inline.d.cts +2 -0
- package/dist/inline/inline.d.ts +2 -0
- package/dist/inline/inline.js +456 -0
- package/dist/inline/link.cjs +130 -0
- package/dist/inline/link.d.cts +2 -0
- package/dist/inline/link.d.ts +2 -0
- package/dist/inline/link.js +124 -0
- package/dist/inline/node.cjs +57 -0
- package/dist/inline/node.d.cts +23 -0
- package/dist/inline/node.d.ts +23 -0
- package/dist/inline/node.js +55 -0
- package/dist/inline-B50cM6cn.d.ts +10 -0
- package/dist/inline-C9YEGDV5.d.cts +10 -0
- package/dist/link-Dv4kxVjk.d.cts +18 -0
- package/dist/link-Dv4kxVjk.d.ts +18 -0
- package/dist/lower/front-matter.cjs +75 -0
- package/dist/lower/front-matter.d.cts +10 -0
- package/dist/lower/front-matter.d.ts +10 -0
- package/dist/lower/front-matter.js +74 -0
- package/dist/lower/image.cjs +29 -0
- package/dist/lower/image.d.cts +2 -0
- package/dist/lower/image.d.ts +2 -0
- package/dist/lower/image.js +28 -0
- package/dist/lower/inline.cjs +96 -0
- package/dist/lower/inline.d.cts +19 -0
- package/dist/lower/inline.d.ts +19 -0
- package/dist/lower/inline.js +93 -0
- package/dist/lower/lower.cjs +293 -0
- package/dist/lower/lower.d.cts +8 -0
- package/dist/lower/lower.d.ts +8 -0
- package/dist/lower/lower.js +291 -0
- package/dist/lower/table.cjs +27 -0
- package/dist/lower/table.d.cts +7 -0
- package/dist/lower/table.d.ts +7 -0
- package/dist/lower/table.js +26 -0
- package/dist/options/options.cjs +0 -0
- package/dist/options/options.d.cts +43 -0
- package/dist/options/options.d.ts +43 -0
- package/dist/options/options.js +0 -0
- package/dist/read.cjs +20 -0
- package/dist/read.d.cts +11 -0
- package/dist/read.d.ts +11 -0
- package/dist/read.js +19 -0
- package/dist/scan/entity-table.cjs +2131 -0
- package/dist/scan/entity-table.d.cts +4 -0
- package/dist/scan/entity-table.d.ts +4 -0
- package/dist/scan/entity-table.js +2130 -0
- package/dist/scan/scan.cjs +80 -0
- package/dist/scan/scan.d.cts +2 -0
- package/dist/scan/scan.d.ts +2 -0
- package/dist/scan/scan.js +78 -0
- package/dist/scan-DeBxgG-r.d.cts +30 -0
- package/dist/scan-DeBxgG-r.d.ts +30 -0
- package/dist/shared/list-id.cjs +36 -0
- package/dist/shared/list-id.d.cts +22 -0
- package/dist/shared/list-id.d.ts +22 -0
- package/dist/shared/list-id.js +32 -0
- package/dist/shared/style-constants.cjs +34 -0
- package/dist/shared/style-constants.d.cts +14 -0
- package/dist/shared/style-constants.d.ts +14 -0
- package/dist/shared/style-constants.js +23 -0
- package/dist/write.cjs +9 -0
- package/dist/write.d.cts +6 -0
- package/dist/write.d.ts +6 -0
- package/dist/write.js +8 -0
- package/package.json +92 -2
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { MarkdownDiagnosticCodes } from "../diagnostics/diagnostics.js";
|
|
2
|
+
import { MONOSPACE_FONT_FAMILY } from "../shared/style-constants.js";
|
|
3
|
+
//#region src/lower/inline.ts
|
|
4
|
+
function buildRun(text, style, fontFamily) {
|
|
5
|
+
return {
|
|
6
|
+
text,
|
|
7
|
+
...style.bold === true ? { bold: true } : {},
|
|
8
|
+
...style.italic === true ? { italic: true } : {},
|
|
9
|
+
...style.strike === true ? { strike: true } : {},
|
|
10
|
+
...style.hyperlink !== void 0 ? { hyperlink: style.hyperlink } : {},
|
|
11
|
+
...fontFamily !== void 0 ? { fontFamily } : {}
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
function lowerNestedEmphasisLike(kind, node, style, context) {
|
|
15
|
+
if (style[kind] === true) context.sink({
|
|
16
|
+
code: MarkdownDiagnosticCodes.NESTED_EMPHASIS_FLATTENED,
|
|
17
|
+
severity: "info",
|
|
18
|
+
message: `a ${kind === "italic" ? "emphasis" : kind === "bold" ? "strong emphasis" : "strikethrough"} span is nested inside another span of the same kind; ContentRun has no nesting depth of its own, so both collapse to one flat run`
|
|
19
|
+
});
|
|
20
|
+
const childStyle = {
|
|
21
|
+
...style,
|
|
22
|
+
[kind]: true
|
|
23
|
+
};
|
|
24
|
+
return node.children.flatMap((child) => lowerInlineNode(child, childStyle, context));
|
|
25
|
+
}
|
|
26
|
+
function lowerInlineNode(node, style, context) {
|
|
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)];
|
|
33
|
+
case "rawHtml":
|
|
34
|
+
if (context.rawHtml === "drop") {
|
|
35
|
+
context.sink({
|
|
36
|
+
code: MarkdownDiagnosticCodes.RAW_HTML_DROPPED,
|
|
37
|
+
severity: "info",
|
|
38
|
+
message: "inline raw HTML was dropped per the rawHtml: \"drop\" option"
|
|
39
|
+
});
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
context.sink({
|
|
43
|
+
code: MarkdownDiagnosticCodes.RAW_HTML_PRESERVED_AS_TEXT,
|
|
44
|
+
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"
|
|
46
|
+
});
|
|
47
|
+
return node.literal.length === 0 ? [] : [buildRun(node.literal, style)];
|
|
48
|
+
case "autolink": {
|
|
49
|
+
const destination = node.email ? `mailto:${node.destination}` : node.destination;
|
|
50
|
+
return [buildRun(node.destination, {
|
|
51
|
+
...style,
|
|
52
|
+
hyperlink: destination
|
|
53
|
+
})];
|
|
54
|
+
}
|
|
55
|
+
case "link": {
|
|
56
|
+
if (node.title !== void 0) context.sink({
|
|
57
|
+
code: MarkdownDiagnosticCodes.LINK_TITLE_DROPPED,
|
|
58
|
+
severity: "info",
|
|
59
|
+
message: `link title "${node.title}" has no ContentRun equivalent and was dropped`
|
|
60
|
+
});
|
|
61
|
+
const childStyle = {
|
|
62
|
+
...style,
|
|
63
|
+
hyperlink: node.destination
|
|
64
|
+
};
|
|
65
|
+
const runs = node.children.flatMap((child) => lowerInlineNode(child, childStyle, context));
|
|
66
|
+
return runs.length > 0 ? runs : [buildRun("", childStyle)];
|
|
67
|
+
}
|
|
68
|
+
case "image":
|
|
69
|
+
if (node.title !== void 0) context.sink({
|
|
70
|
+
code: MarkdownDiagnosticCodes.LINK_TITLE_DROPPED,
|
|
71
|
+
severity: "info",
|
|
72
|
+
message: `image title "${node.title}" has no ContentRun equivalent and was dropped`
|
|
73
|
+
});
|
|
74
|
+
return [buildRun(node.alt, {
|
|
75
|
+
...style,
|
|
76
|
+
hyperlink: node.destination
|
|
77
|
+
})];
|
|
78
|
+
case "emphasis": return lowerNestedEmphasisLike("italic", node, style, context);
|
|
79
|
+
case "strong": return lowerNestedEmphasisLike("bold", node, style, context);
|
|
80
|
+
case "strikethrough": return lowerNestedEmphasisLike("strike", node, style, context);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function lowerInlineNodes(nodes, context) {
|
|
84
|
+
return nodes.flatMap((node) => lowerInlineNode(node, {}, context));
|
|
85
|
+
}
|
|
86
|
+
function lowerCodeBlockRun(literal) {
|
|
87
|
+
return {
|
|
88
|
+
text: literal,
|
|
89
|
+
fontFamily: MONOSPACE_FONT_FAMILY
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
//#endregion
|
|
93
|
+
export { lowerCodeBlockRun, lowerInlineNode, lowerInlineNodes };
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_defaults_defaults = require("../defaults/defaults.cjs");
|
|
3
|
+
const require_diagnostics_diagnostics = require("../diagnostics/diagnostics.cjs");
|
|
4
|
+
const require_block_block = require("../block/block.cjs");
|
|
5
|
+
const require_shared_list_id = require("../shared/list-id.cjs");
|
|
6
|
+
const require_shared_style_constants = require("../shared/style-constants.cjs");
|
|
7
|
+
const require_lower_front_matter = require("./front-matter.cjs");
|
|
8
|
+
const require_lower_image = require("./image.cjs");
|
|
9
|
+
const require_lower_inline = require("./inline.cjs");
|
|
10
|
+
const require_lower_table = require("./table.cjs");
|
|
11
|
+
let document_schema_js = require("document-schema.js");
|
|
12
|
+
//#region src/lower/lower.ts
|
|
13
|
+
function inlineContext(context) {
|
|
14
|
+
return {
|
|
15
|
+
sink: context.sink,
|
|
16
|
+
rawHtml: context.rawHtmlMode
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function decorateParagraph(paragraph, context) {
|
|
20
|
+
let result = paragraph;
|
|
21
|
+
if (context.quoteDepth > 0) result = {
|
|
22
|
+
...result,
|
|
23
|
+
indentLeftPt: context.quoteDepth * 36,
|
|
24
|
+
...result.styleId === void 0 ? { styleId: require_shared_style_constants.QUOTE_STYLE_ID } : {}
|
|
25
|
+
};
|
|
26
|
+
if (context.list !== void 0) result = {
|
|
27
|
+
...result,
|
|
28
|
+
list: {
|
|
29
|
+
numId: context.list.numId,
|
|
30
|
+
level: context.list.level
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
function lowerHeading(node, context) {
|
|
36
|
+
return [decorateParagraph({
|
|
37
|
+
kind: "paragraph",
|
|
38
|
+
runs: require_lower_inline.lowerInlineNodes(node.children, inlineContext(context)),
|
|
39
|
+
styleId: require_shared_style_constants.headingStyleId(node.level)
|
|
40
|
+
}, context)];
|
|
41
|
+
}
|
|
42
|
+
function lowerParagraph(node, context) {
|
|
43
|
+
const blocks = [];
|
|
44
|
+
const inlineCtx = inlineContext(context);
|
|
45
|
+
let segment = [];
|
|
46
|
+
const flushSegment = (force) => {
|
|
47
|
+
if (segment.length === 0 && !force) return;
|
|
48
|
+
blocks.push(decorateParagraph({
|
|
49
|
+
kind: "paragraph",
|
|
50
|
+
runs: require_lower_inline.lowerInlineNodes(segment, inlineCtx)
|
|
51
|
+
}, context));
|
|
52
|
+
segment = [];
|
|
53
|
+
};
|
|
54
|
+
for (const child of node.children) {
|
|
55
|
+
if (child.type !== "image") {
|
|
56
|
+
segment.push(child);
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
const resolved = require_lower_image.resolveMarkdownImage(child.destination, {
|
|
60
|
+
alt: child.alt,
|
|
61
|
+
title: child.title
|
|
62
|
+
}, context.images);
|
|
63
|
+
if (resolved === void 0) {
|
|
64
|
+
context.sink({
|
|
65
|
+
code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.IMAGE_UNRESOLVED,
|
|
66
|
+
severity: "info",
|
|
67
|
+
message: `image "${child.destination}" could not be resolved to real bytes; it degrades to a text run of its own alt text, hyperlinked at its own destination`
|
|
68
|
+
});
|
|
69
|
+
segment.push(child);
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (child.title !== void 0) context.sink({
|
|
73
|
+
code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.LINK_TITLE_DROPPED,
|
|
74
|
+
severity: "info",
|
|
75
|
+
message: `image title "${child.title}" has no ContentImageBlock equivalent and was dropped`
|
|
76
|
+
});
|
|
77
|
+
flushSegment(false);
|
|
78
|
+
if (context.list !== void 0) context.sink({
|
|
79
|
+
code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.LIST_ITEM_BLOCK_UNLISTED,
|
|
80
|
+
severity: "info",
|
|
81
|
+
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"
|
|
82
|
+
});
|
|
83
|
+
blocks.push({
|
|
84
|
+
kind: "image",
|
|
85
|
+
format: resolved.format,
|
|
86
|
+
base64: resolved.base64,
|
|
87
|
+
widthPt: resolved.widthPt,
|
|
88
|
+
heightPt: resolved.heightPt,
|
|
89
|
+
...child.alt.length > 0 ? { altText: child.alt } : {}
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
flushSegment(blocks.length === 0);
|
|
93
|
+
return blocks;
|
|
94
|
+
}
|
|
95
|
+
function lowerCodeBlock(node, context) {
|
|
96
|
+
if (node.fenced && node.infoString !== void 0 && node.infoString.length > 0) context.sink({
|
|
97
|
+
code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.CODE_BLOCK_INFO_STRING_DROPPED,
|
|
98
|
+
severity: "info",
|
|
99
|
+
message: `fenced code block's own info string "${node.infoString}" has no ContentParagraph equivalent and was dropped`
|
|
100
|
+
});
|
|
101
|
+
return [decorateParagraph({
|
|
102
|
+
kind: "paragraph",
|
|
103
|
+
runs: [require_lower_inline.lowerCodeBlockRun(node.literal.replace(/\n$/, ""))],
|
|
104
|
+
styleId: require_shared_style_constants.CODE_BLOCK_STYLE_ID
|
|
105
|
+
}, context)];
|
|
106
|
+
}
|
|
107
|
+
function lowerThematicBreak(context) {
|
|
108
|
+
return [decorateParagraph({
|
|
109
|
+
kind: "paragraph",
|
|
110
|
+
runs: [],
|
|
111
|
+
styleId: require_shared_style_constants.HORIZONTAL_RULE_STYLE_ID
|
|
112
|
+
}, context)];
|
|
113
|
+
}
|
|
114
|
+
function lowerHtmlBlock(node, context) {
|
|
115
|
+
if (context.rawHtmlMode === "drop") {
|
|
116
|
+
context.sink({
|
|
117
|
+
code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.RAW_HTML_DROPPED,
|
|
118
|
+
severity: "info",
|
|
119
|
+
message: "block-level raw HTML was dropped per the rawHtml: \"drop\" option"
|
|
120
|
+
});
|
|
121
|
+
return [];
|
|
122
|
+
}
|
|
123
|
+
context.sink({
|
|
124
|
+
code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.RAW_HTML_PRESERVED_AS_TEXT,
|
|
125
|
+
severity: "info",
|
|
126
|
+
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"
|
|
127
|
+
});
|
|
128
|
+
const literal = node.literal.replace(/\n+$/, "");
|
|
129
|
+
return [decorateParagraph({
|
|
130
|
+
kind: "paragraph",
|
|
131
|
+
runs: literal.length === 0 ? [] : [{ text: literal }],
|
|
132
|
+
styleId: require_shared_style_constants.HTML_PREFORMATTED_STYLE_ID
|
|
133
|
+
}, context)];
|
|
134
|
+
}
|
|
135
|
+
function lowerBlockquote(node, context, contentWidthPt) {
|
|
136
|
+
if (context.quoteDepth >= 1) context.sink({
|
|
137
|
+
code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.BLOCKQUOTE_NESTED_DEPTH,
|
|
138
|
+
severity: "info",
|
|
139
|
+
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`
|
|
140
|
+
});
|
|
141
|
+
const nested = {
|
|
142
|
+
...context,
|
|
143
|
+
quoteDepth: context.quoteDepth + 1
|
|
144
|
+
};
|
|
145
|
+
const blocks = node.children.flatMap((child) => lowerBlock(child, nested, contentWidthPt));
|
|
146
|
+
if (blocks.length === 0) return [decorateParagraph({
|
|
147
|
+
kind: "paragraph",
|
|
148
|
+
runs: []
|
|
149
|
+
}, nested)];
|
|
150
|
+
return blocks;
|
|
151
|
+
}
|
|
152
|
+
function applyTaskCheckbox(blocks, checked) {
|
|
153
|
+
const first = blocks[0];
|
|
154
|
+
if (first?.kind !== "paragraph") return false;
|
|
155
|
+
const checkboxRun = { text: `${checked ? "☒" : "☐"} ` };
|
|
156
|
+
blocks[0] = {
|
|
157
|
+
...first,
|
|
158
|
+
runs: [checkboxRun, ...first.runs]
|
|
159
|
+
};
|
|
160
|
+
return true;
|
|
161
|
+
}
|
|
162
|
+
function lowerListItem(item, numId, level, context, contentWidthPt) {
|
|
163
|
+
if (item.children.filter((child) => child.type !== "list").length > 1) context.sink({
|
|
164
|
+
code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.LIST_ITEM_MULTI_BLOCK_FLATTENED,
|
|
165
|
+
severity: "info",
|
|
166
|
+
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\""
|
|
167
|
+
});
|
|
168
|
+
const itemContext = {
|
|
169
|
+
...context,
|
|
170
|
+
list: {
|
|
171
|
+
numId,
|
|
172
|
+
level
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
const blocks = [];
|
|
176
|
+
let checkboxApplied = item.checked === void 0;
|
|
177
|
+
let ownLevelBlockCount = 0;
|
|
178
|
+
for (const child of item.children) {
|
|
179
|
+
if (child.type === "list") {
|
|
180
|
+
blocks.push(...lowerList(child, numId, level + 1, context, contentWidthPt));
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
const childBlocks = lowerBlock(child, itemContext, contentWidthPt);
|
|
184
|
+
ownLevelBlockCount += childBlocks.length;
|
|
185
|
+
if (!checkboxApplied) checkboxApplied = applyTaskCheckbox(childBlocks, item.checked === true);
|
|
186
|
+
blocks.push(...childBlocks);
|
|
187
|
+
}
|
|
188
|
+
if (ownLevelBlockCount === 0) {
|
|
189
|
+
const placeholder = [decorateParagraph({
|
|
190
|
+
kind: "paragraph",
|
|
191
|
+
runs: []
|
|
192
|
+
}, itemContext)];
|
|
193
|
+
if (!checkboxApplied) applyTaskCheckbox(placeholder, item.checked === true);
|
|
194
|
+
blocks.unshift(...placeholder);
|
|
195
|
+
}
|
|
196
|
+
return blocks;
|
|
197
|
+
}
|
|
198
|
+
function lowerList(node, ancestorNumId, level, context, contentWidthPt) {
|
|
199
|
+
let numId;
|
|
200
|
+
if (ancestorNumId === void 0) {
|
|
201
|
+
const task = node.children.some((item) => item.checked !== void 0);
|
|
202
|
+
numId = require_shared_list_id.mintListNumId(context.numIdState, {
|
|
203
|
+
type: node.markerType,
|
|
204
|
+
start: node.start,
|
|
205
|
+
task,
|
|
206
|
+
loose: !node.tight
|
|
207
|
+
});
|
|
208
|
+
} else {
|
|
209
|
+
numId = ancestorNumId;
|
|
210
|
+
const mintedType = require_shared_list_id.mintedListType(numId);
|
|
211
|
+
if (mintedType !== void 0 && mintedType !== node.markerType) context.sink({
|
|
212
|
+
code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.LIST_MARKER_TYPE_CONFLICT,
|
|
213
|
+
severity: "warning",
|
|
214
|
+
message: `a nested ${node.markerType} list sits under a list minted as ${mintedType}; the enclosing list's own marker type is kept (first-wins) and this nested list's own type is not separately represented`
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
return node.children.flatMap((item) => lowerListItem(item, numId, level, context, contentWidthPt));
|
|
218
|
+
}
|
|
219
|
+
function lowerBlock(node, context, contentWidthPt) {
|
|
220
|
+
switch (node.type) {
|
|
221
|
+
case "paragraph": return lowerParagraph(node, context);
|
|
222
|
+
case "heading": return lowerHeading(node, context);
|
|
223
|
+
case "blockquote": return lowerBlockquote(node, context, contentWidthPt);
|
|
224
|
+
case "list": return lowerList(node, void 0, 0, context, contentWidthPt);
|
|
225
|
+
case "codeBlock": return lowerCodeBlock(node, context);
|
|
226
|
+
case "thematicBreak": return lowerThematicBreak(context);
|
|
227
|
+
case "htmlBlock": return lowerHtmlBlock(node, context);
|
|
228
|
+
case "table":
|
|
229
|
+
if (context.list !== void 0) context.sink({
|
|
230
|
+
code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.LIST_ITEM_BLOCK_UNLISTED,
|
|
231
|
+
severity: "info",
|
|
232
|
+
message: "a table 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"
|
|
233
|
+
});
|
|
234
|
+
return [require_lower_table.lowerTable(node, contentWidthPt, inlineContext(context))];
|
|
235
|
+
case "document":
|
|
236
|
+
case "listItem":
|
|
237
|
+
case "tableRow":
|
|
238
|
+
case "tableCell": return [];
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
function lowerParsedMarkdown(parsed, options = {}, metadata = {}) {
|
|
242
|
+
const sink = options.sink ?? require_diagnostics_diagnostics.NOOP_MARKDOWN_DIAGNOSTIC_SINK;
|
|
243
|
+
sink({
|
|
244
|
+
code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.INVENTED_PAGE_GEOMETRY,
|
|
245
|
+
severity: "info",
|
|
246
|
+
message: "markdown carries no page geometry of its own; the resulting ContentSection uses a synthesised page size and margins (ReadMarkdownOptions.pageSize/margins, or document-schema.js's own PAGE_SIZE_A4 default)"
|
|
247
|
+
});
|
|
248
|
+
const pageSize = options.pageSize ?? document_schema_js.PAGE_SIZE_A4;
|
|
249
|
+
const margins = options.margins ?? require_defaults_defaults.DEFAULT_MARGINS;
|
|
250
|
+
const contentWidthPt = pageSize.widthPt - margins.leftPt - margins.rightPt;
|
|
251
|
+
const context = {
|
|
252
|
+
sink,
|
|
253
|
+
images: options.images,
|
|
254
|
+
rawHtmlMode: options.rawHtml ?? "preserve",
|
|
255
|
+
numIdState: require_shared_list_id.createNumIdMintState(),
|
|
256
|
+
quoteDepth: 0,
|
|
257
|
+
list: void 0
|
|
258
|
+
};
|
|
259
|
+
const blocks = parsed.document.children.flatMap((child) => lowerBlock(child, context, contentWidthPt));
|
|
260
|
+
return {
|
|
261
|
+
kind: "wordprocessing",
|
|
262
|
+
formatVersion: document_schema_js.CONTENT_FORMAT_VERSION,
|
|
263
|
+
metadata,
|
|
264
|
+
sections: [{
|
|
265
|
+
pageSize,
|
|
266
|
+
margins,
|
|
267
|
+
blocks
|
|
268
|
+
}]
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
function lowerMarkdown(source, options = {}) {
|
|
272
|
+
if (options.maxInputBytes !== void 0) {
|
|
273
|
+
const actualBytes = new TextEncoder().encode(source).length;
|
|
274
|
+
if (actualBytes > options.maxInputBytes) throw new require_diagnostics_diagnostics.MarkdownInputTooLargeError(options.maxInputBytes, actualBytes);
|
|
275
|
+
}
|
|
276
|
+
const sink = options.sink ?? require_diagnostics_diagnostics.NOOP_MARKDOWN_DIAGNOSTIC_SINK;
|
|
277
|
+
const { metadata, rest } = options.frontMatter ?? false ? require_lower_front_matter.extractFrontMatter(source, sink) : {
|
|
278
|
+
metadata: {},
|
|
279
|
+
rest: source
|
|
280
|
+
};
|
|
281
|
+
const parseOptions = {
|
|
282
|
+
gfmTables: options.gfmTables,
|
|
283
|
+
gfmAutolinks: options.gfmAutolinks,
|
|
284
|
+
gfmStrikethrough: options.gfmStrikethrough,
|
|
285
|
+
gfmTaskLists: options.gfmTaskLists,
|
|
286
|
+
maxNesting: options.maxBlockNesting,
|
|
287
|
+
sink
|
|
288
|
+
};
|
|
289
|
+
return lowerParsedMarkdown(require_block_block.parseMarkdown(rest, parseOptions), options, metadata);
|
|
290
|
+
}
|
|
291
|
+
//#endregion
|
|
292
|
+
exports.lowerMarkdown = lowerMarkdown;
|
|
293
|
+
exports.lowerParsedMarkdown = lowerParsedMarkdown;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ParsedMarkdown } from "../block/block.cjs";
|
|
2
|
+
import { ReadMarkdownOptions } from "../options/options.cjs";
|
|
3
|
+
import { ContentDocument, LayoutMetadata } from "document-schema.js";
|
|
4
|
+
//#region src/lower/lower.d.ts
|
|
5
|
+
declare function lowerParsedMarkdown(parsed: ParsedMarkdown, options?: ReadMarkdownOptions, metadata?: LayoutMetadata): ContentDocument;
|
|
6
|
+
declare function lowerMarkdown(source: string, options?: ReadMarkdownOptions): ContentDocument;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { lowerMarkdown, lowerParsedMarkdown };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ParsedMarkdown } from "../block/block.js";
|
|
2
|
+
import { ReadMarkdownOptions } from "../options/options.js";
|
|
3
|
+
import { ContentDocument, LayoutMetadata } from "document-schema.js";
|
|
4
|
+
//#region src/lower/lower.d.ts
|
|
5
|
+
declare function lowerParsedMarkdown(parsed: ParsedMarkdown, options?: ReadMarkdownOptions, metadata?: LayoutMetadata): ContentDocument;
|
|
6
|
+
declare function lowerMarkdown(source: string, options?: ReadMarkdownOptions): ContentDocument;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { lowerMarkdown, lowerParsedMarkdown };
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import { DEFAULT_MARGINS } from "../defaults/defaults.js";
|
|
2
|
+
import { MarkdownDiagnosticCodes, MarkdownInputTooLargeError, NOOP_MARKDOWN_DIAGNOSTIC_SINK } from "../diagnostics/diagnostics.js";
|
|
3
|
+
import { parseMarkdown } from "../block/block.js";
|
|
4
|
+
import { createNumIdMintState, mintListNumId, mintedListType } from "../shared/list-id.js";
|
|
5
|
+
import { CODE_BLOCK_STYLE_ID, HORIZONTAL_RULE_STYLE_ID, HTML_PREFORMATTED_STYLE_ID, QUOTE_STYLE_ID, headingStyleId } from "../shared/style-constants.js";
|
|
6
|
+
import { extractFrontMatter } from "./front-matter.js";
|
|
7
|
+
import { resolveMarkdownImage } from "./image.js";
|
|
8
|
+
import { lowerCodeBlockRun, lowerInlineNodes } from "./inline.js";
|
|
9
|
+
import { lowerTable } from "./table.js";
|
|
10
|
+
import { CONTENT_FORMAT_VERSION, PAGE_SIZE_A4 } from "document-schema.js";
|
|
11
|
+
//#region src/lower/lower.ts
|
|
12
|
+
function inlineContext(context) {
|
|
13
|
+
return {
|
|
14
|
+
sink: context.sink,
|
|
15
|
+
rawHtml: context.rawHtmlMode
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function decorateParagraph(paragraph, context) {
|
|
19
|
+
let result = paragraph;
|
|
20
|
+
if (context.quoteDepth > 0) result = {
|
|
21
|
+
...result,
|
|
22
|
+
indentLeftPt: context.quoteDepth * 36,
|
|
23
|
+
...result.styleId === void 0 ? { styleId: QUOTE_STYLE_ID } : {}
|
|
24
|
+
};
|
|
25
|
+
if (context.list !== void 0) result = {
|
|
26
|
+
...result,
|
|
27
|
+
list: {
|
|
28
|
+
numId: context.list.numId,
|
|
29
|
+
level: context.list.level
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
function lowerHeading(node, context) {
|
|
35
|
+
return [decorateParagraph({
|
|
36
|
+
kind: "paragraph",
|
|
37
|
+
runs: lowerInlineNodes(node.children, inlineContext(context)),
|
|
38
|
+
styleId: headingStyleId(node.level)
|
|
39
|
+
}, context)];
|
|
40
|
+
}
|
|
41
|
+
function lowerParagraph(node, context) {
|
|
42
|
+
const blocks = [];
|
|
43
|
+
const inlineCtx = inlineContext(context);
|
|
44
|
+
let segment = [];
|
|
45
|
+
const flushSegment = (force) => {
|
|
46
|
+
if (segment.length === 0 && !force) return;
|
|
47
|
+
blocks.push(decorateParagraph({
|
|
48
|
+
kind: "paragraph",
|
|
49
|
+
runs: lowerInlineNodes(segment, inlineCtx)
|
|
50
|
+
}, context));
|
|
51
|
+
segment = [];
|
|
52
|
+
};
|
|
53
|
+
for (const child of node.children) {
|
|
54
|
+
if (child.type !== "image") {
|
|
55
|
+
segment.push(child);
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
const resolved = resolveMarkdownImage(child.destination, {
|
|
59
|
+
alt: child.alt,
|
|
60
|
+
title: child.title
|
|
61
|
+
}, context.images);
|
|
62
|
+
if (resolved === void 0) {
|
|
63
|
+
context.sink({
|
|
64
|
+
code: MarkdownDiagnosticCodes.IMAGE_UNRESOLVED,
|
|
65
|
+
severity: "info",
|
|
66
|
+
message: `image "${child.destination}" could not be resolved to real bytes; it degrades to a text run of its own alt text, hyperlinked at its own destination`
|
|
67
|
+
});
|
|
68
|
+
segment.push(child);
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
if (child.title !== void 0) context.sink({
|
|
72
|
+
code: MarkdownDiagnosticCodes.LINK_TITLE_DROPPED,
|
|
73
|
+
severity: "info",
|
|
74
|
+
message: `image title "${child.title}" has no ContentImageBlock equivalent and was dropped`
|
|
75
|
+
});
|
|
76
|
+
flushSegment(false);
|
|
77
|
+
if (context.list !== void 0) context.sink({
|
|
78
|
+
code: MarkdownDiagnosticCodes.LIST_ITEM_BLOCK_UNLISTED,
|
|
79
|
+
severity: "info",
|
|
80
|
+
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"
|
|
81
|
+
});
|
|
82
|
+
blocks.push({
|
|
83
|
+
kind: "image",
|
|
84
|
+
format: resolved.format,
|
|
85
|
+
base64: resolved.base64,
|
|
86
|
+
widthPt: resolved.widthPt,
|
|
87
|
+
heightPt: resolved.heightPt,
|
|
88
|
+
...child.alt.length > 0 ? { altText: child.alt } : {}
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
flushSegment(blocks.length === 0);
|
|
92
|
+
return blocks;
|
|
93
|
+
}
|
|
94
|
+
function lowerCodeBlock(node, context) {
|
|
95
|
+
if (node.fenced && node.infoString !== void 0 && node.infoString.length > 0) context.sink({
|
|
96
|
+
code: MarkdownDiagnosticCodes.CODE_BLOCK_INFO_STRING_DROPPED,
|
|
97
|
+
severity: "info",
|
|
98
|
+
message: `fenced code block's own info string "${node.infoString}" has no ContentParagraph equivalent and was dropped`
|
|
99
|
+
});
|
|
100
|
+
return [decorateParagraph({
|
|
101
|
+
kind: "paragraph",
|
|
102
|
+
runs: [lowerCodeBlockRun(node.literal.replace(/\n$/, ""))],
|
|
103
|
+
styleId: CODE_BLOCK_STYLE_ID
|
|
104
|
+
}, context)];
|
|
105
|
+
}
|
|
106
|
+
function lowerThematicBreak(context) {
|
|
107
|
+
return [decorateParagraph({
|
|
108
|
+
kind: "paragraph",
|
|
109
|
+
runs: [],
|
|
110
|
+
styleId: HORIZONTAL_RULE_STYLE_ID
|
|
111
|
+
}, context)];
|
|
112
|
+
}
|
|
113
|
+
function lowerHtmlBlock(node, context) {
|
|
114
|
+
if (context.rawHtmlMode === "drop") {
|
|
115
|
+
context.sink({
|
|
116
|
+
code: MarkdownDiagnosticCodes.RAW_HTML_DROPPED,
|
|
117
|
+
severity: "info",
|
|
118
|
+
message: "block-level raw HTML was dropped per the rawHtml: \"drop\" option"
|
|
119
|
+
});
|
|
120
|
+
return [];
|
|
121
|
+
}
|
|
122
|
+
context.sink({
|
|
123
|
+
code: MarkdownDiagnosticCodes.RAW_HTML_PRESERVED_AS_TEXT,
|
|
124
|
+
severity: "info",
|
|
125
|
+
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"
|
|
126
|
+
});
|
|
127
|
+
const literal = node.literal.replace(/\n+$/, "");
|
|
128
|
+
return [decorateParagraph({
|
|
129
|
+
kind: "paragraph",
|
|
130
|
+
runs: literal.length === 0 ? [] : [{ text: literal }],
|
|
131
|
+
styleId: HTML_PREFORMATTED_STYLE_ID
|
|
132
|
+
}, context)];
|
|
133
|
+
}
|
|
134
|
+
function lowerBlockquote(node, context, contentWidthPt) {
|
|
135
|
+
if (context.quoteDepth >= 1) context.sink({
|
|
136
|
+
code: MarkdownDiagnosticCodes.BLOCKQUOTE_NESTED_DEPTH,
|
|
137
|
+
severity: "info",
|
|
138
|
+
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`
|
|
139
|
+
});
|
|
140
|
+
const nested = {
|
|
141
|
+
...context,
|
|
142
|
+
quoteDepth: context.quoteDepth + 1
|
|
143
|
+
};
|
|
144
|
+
const blocks = node.children.flatMap((child) => lowerBlock(child, nested, contentWidthPt));
|
|
145
|
+
if (blocks.length === 0) return [decorateParagraph({
|
|
146
|
+
kind: "paragraph",
|
|
147
|
+
runs: []
|
|
148
|
+
}, nested)];
|
|
149
|
+
return blocks;
|
|
150
|
+
}
|
|
151
|
+
function applyTaskCheckbox(blocks, checked) {
|
|
152
|
+
const first = blocks[0];
|
|
153
|
+
if (first?.kind !== "paragraph") return false;
|
|
154
|
+
const checkboxRun = { text: `${checked ? "☒" : "☐"} ` };
|
|
155
|
+
blocks[0] = {
|
|
156
|
+
...first,
|
|
157
|
+
runs: [checkboxRun, ...first.runs]
|
|
158
|
+
};
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
function lowerListItem(item, numId, level, context, contentWidthPt) {
|
|
162
|
+
if (item.children.filter((child) => child.type !== "list").length > 1) context.sink({
|
|
163
|
+
code: MarkdownDiagnosticCodes.LIST_ITEM_MULTI_BLOCK_FLATTENED,
|
|
164
|
+
severity: "info",
|
|
165
|
+
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\""
|
|
166
|
+
});
|
|
167
|
+
const itemContext = {
|
|
168
|
+
...context,
|
|
169
|
+
list: {
|
|
170
|
+
numId,
|
|
171
|
+
level
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
const blocks = [];
|
|
175
|
+
let checkboxApplied = item.checked === void 0;
|
|
176
|
+
let ownLevelBlockCount = 0;
|
|
177
|
+
for (const child of item.children) {
|
|
178
|
+
if (child.type === "list") {
|
|
179
|
+
blocks.push(...lowerList(child, numId, level + 1, context, contentWidthPt));
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
const childBlocks = lowerBlock(child, itemContext, contentWidthPt);
|
|
183
|
+
ownLevelBlockCount += childBlocks.length;
|
|
184
|
+
if (!checkboxApplied) checkboxApplied = applyTaskCheckbox(childBlocks, item.checked === true);
|
|
185
|
+
blocks.push(...childBlocks);
|
|
186
|
+
}
|
|
187
|
+
if (ownLevelBlockCount === 0) {
|
|
188
|
+
const placeholder = [decorateParagraph({
|
|
189
|
+
kind: "paragraph",
|
|
190
|
+
runs: []
|
|
191
|
+
}, itemContext)];
|
|
192
|
+
if (!checkboxApplied) applyTaskCheckbox(placeholder, item.checked === true);
|
|
193
|
+
blocks.unshift(...placeholder);
|
|
194
|
+
}
|
|
195
|
+
return blocks;
|
|
196
|
+
}
|
|
197
|
+
function lowerList(node, ancestorNumId, level, context, contentWidthPt) {
|
|
198
|
+
let numId;
|
|
199
|
+
if (ancestorNumId === void 0) {
|
|
200
|
+
const task = node.children.some((item) => item.checked !== void 0);
|
|
201
|
+
numId = mintListNumId(context.numIdState, {
|
|
202
|
+
type: node.markerType,
|
|
203
|
+
start: node.start,
|
|
204
|
+
task,
|
|
205
|
+
loose: !node.tight
|
|
206
|
+
});
|
|
207
|
+
} else {
|
|
208
|
+
numId = ancestorNumId;
|
|
209
|
+
const mintedType = mintedListType(numId);
|
|
210
|
+
if (mintedType !== void 0 && mintedType !== node.markerType) context.sink({
|
|
211
|
+
code: MarkdownDiagnosticCodes.LIST_MARKER_TYPE_CONFLICT,
|
|
212
|
+
severity: "warning",
|
|
213
|
+
message: `a nested ${node.markerType} list sits under a list minted as ${mintedType}; the enclosing list's own marker type is kept (first-wins) and this nested list's own type is not separately represented`
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
return node.children.flatMap((item) => lowerListItem(item, numId, level, context, contentWidthPt));
|
|
217
|
+
}
|
|
218
|
+
function lowerBlock(node, context, contentWidthPt) {
|
|
219
|
+
switch (node.type) {
|
|
220
|
+
case "paragraph": return lowerParagraph(node, context);
|
|
221
|
+
case "heading": return lowerHeading(node, context);
|
|
222
|
+
case "blockquote": return lowerBlockquote(node, context, contentWidthPt);
|
|
223
|
+
case "list": return lowerList(node, void 0, 0, context, contentWidthPt);
|
|
224
|
+
case "codeBlock": return lowerCodeBlock(node, context);
|
|
225
|
+
case "thematicBreak": return lowerThematicBreak(context);
|
|
226
|
+
case "htmlBlock": return lowerHtmlBlock(node, context);
|
|
227
|
+
case "table":
|
|
228
|
+
if (context.list !== void 0) context.sink({
|
|
229
|
+
code: MarkdownDiagnosticCodes.LIST_ITEM_BLOCK_UNLISTED,
|
|
230
|
+
severity: "info",
|
|
231
|
+
message: "a table 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"
|
|
232
|
+
});
|
|
233
|
+
return [lowerTable(node, contentWidthPt, inlineContext(context))];
|
|
234
|
+
case "document":
|
|
235
|
+
case "listItem":
|
|
236
|
+
case "tableRow":
|
|
237
|
+
case "tableCell": return [];
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
function lowerParsedMarkdown(parsed, options = {}, metadata = {}) {
|
|
241
|
+
const sink = options.sink ?? NOOP_MARKDOWN_DIAGNOSTIC_SINK;
|
|
242
|
+
sink({
|
|
243
|
+
code: MarkdownDiagnosticCodes.INVENTED_PAGE_GEOMETRY,
|
|
244
|
+
severity: "info",
|
|
245
|
+
message: "markdown carries no page geometry of its own; the resulting ContentSection uses a synthesised page size and margins (ReadMarkdownOptions.pageSize/margins, or document-schema.js's own PAGE_SIZE_A4 default)"
|
|
246
|
+
});
|
|
247
|
+
const pageSize = options.pageSize ?? PAGE_SIZE_A4;
|
|
248
|
+
const margins = options.margins ?? DEFAULT_MARGINS;
|
|
249
|
+
const contentWidthPt = pageSize.widthPt - margins.leftPt - margins.rightPt;
|
|
250
|
+
const context = {
|
|
251
|
+
sink,
|
|
252
|
+
images: options.images,
|
|
253
|
+
rawHtmlMode: options.rawHtml ?? "preserve",
|
|
254
|
+
numIdState: createNumIdMintState(),
|
|
255
|
+
quoteDepth: 0,
|
|
256
|
+
list: void 0
|
|
257
|
+
};
|
|
258
|
+
const blocks = parsed.document.children.flatMap((child) => lowerBlock(child, context, contentWidthPt));
|
|
259
|
+
return {
|
|
260
|
+
kind: "wordprocessing",
|
|
261
|
+
formatVersion: CONTENT_FORMAT_VERSION,
|
|
262
|
+
metadata,
|
|
263
|
+
sections: [{
|
|
264
|
+
pageSize,
|
|
265
|
+
margins,
|
|
266
|
+
blocks
|
|
267
|
+
}]
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
function lowerMarkdown(source, options = {}) {
|
|
271
|
+
if (options.maxInputBytes !== void 0) {
|
|
272
|
+
const actualBytes = new TextEncoder().encode(source).length;
|
|
273
|
+
if (actualBytes > options.maxInputBytes) throw new MarkdownInputTooLargeError(options.maxInputBytes, actualBytes);
|
|
274
|
+
}
|
|
275
|
+
const sink = options.sink ?? NOOP_MARKDOWN_DIAGNOSTIC_SINK;
|
|
276
|
+
const { metadata, rest } = options.frontMatter ?? false ? extractFrontMatter(source, sink) : {
|
|
277
|
+
metadata: {},
|
|
278
|
+
rest: source
|
|
279
|
+
};
|
|
280
|
+
const parseOptions = {
|
|
281
|
+
gfmTables: options.gfmTables,
|
|
282
|
+
gfmAutolinks: options.gfmAutolinks,
|
|
283
|
+
gfmStrikethrough: options.gfmStrikethrough,
|
|
284
|
+
gfmTaskLists: options.gfmTaskLists,
|
|
285
|
+
maxNesting: options.maxBlockNesting,
|
|
286
|
+
sink
|
|
287
|
+
};
|
|
288
|
+
return lowerParsedMarkdown(parseMarkdown(rest, parseOptions), options, metadata);
|
|
289
|
+
}
|
|
290
|
+
//#endregion
|
|
291
|
+
export { lowerMarkdown, lowerParsedMarkdown };
|