markdown-codec 0.0.0 → 1.0.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.
- 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 +492 -0
- package/dist/codec.d.ts +492 -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,2 @@
|
|
|
1
|
+
import { a as MarkdownInputTooLargeError, c as MarkdownParseError, d as NOOP_MARKDOWN_DIAGNOSTIC_SINK, i as MarkdownDiagnosticSink, l as MarkdownUnsupportedDocumentKindError, n as MarkdownDiagnosticCodes, o as MarkdownInvalidUtf8Error, r as MarkdownDiagnosticSeverity, s as MarkdownNestingLimitExceededError, t as MarkdownDiagnostic, u as MarkdownWriteError } from "../diagnostics-DmuWc7d8.js";
|
|
2
|
+
export { MarkdownDiagnostic, MarkdownDiagnosticCodes, MarkdownDiagnosticSeverity, MarkdownDiagnosticSink, MarkdownInputTooLargeError, MarkdownInvalidUtf8Error, MarkdownNestingLimitExceededError, MarkdownParseError, MarkdownUnsupportedDocumentKindError, MarkdownWriteError, NOOP_MARKDOWN_DIAGNOSTIC_SINK };
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
//#region src/diagnostics/diagnostics.ts
|
|
2
|
+
const NOOP_MARKDOWN_DIAGNOSTIC_SINK = () => {};
|
|
3
|
+
const MarkdownDiagnosticCodes = {
|
|
4
|
+
UNCLOSED_FENCE: "md/unclosed-fence",
|
|
5
|
+
UNTERMINATED_HTML_BLOCK: "md/unterminated-html-block",
|
|
6
|
+
TABLE_CELL_COUNT_MISMATCH: "md/table-cell-count-mismatch",
|
|
7
|
+
DUPLICATE_LINK_REFERENCE: "md/duplicate-link-reference",
|
|
8
|
+
LIST_MARKER_TYPE_CONFLICT: "md/list-marker-type-conflict",
|
|
9
|
+
INVENTED_PAGE_GEOMETRY: "md/invented-page-geometry",
|
|
10
|
+
NESTED_EMPHASIS_FLATTENED: "md/nested-emphasis-flattened",
|
|
11
|
+
LINK_TITLE_DROPPED: "md/link-title-dropped",
|
|
12
|
+
CODE_BLOCK_INFO_STRING_DROPPED: "md/code-block-info-string-dropped",
|
|
13
|
+
BLOCKQUOTE_NESTED_DEPTH: "md/blockquote-nested-depth",
|
|
14
|
+
LIST_ITEM_BLOCK_UNLISTED: "md/list-item-block-unlisted",
|
|
15
|
+
LIST_ITEM_MULTI_BLOCK_FLATTENED: "md/list-item-multi-block-flattened",
|
|
16
|
+
IMAGE_UNRESOLVED: "md/image-unresolved",
|
|
17
|
+
RAW_HTML_PRESERVED_AS_TEXT: "md/raw-html-preserved-as-text",
|
|
18
|
+
RAW_HTML_DROPPED: "md/raw-html-dropped",
|
|
19
|
+
FRONT_MATTER_KEY_UNMAPPED: "md/front-matter-key-unmapped",
|
|
20
|
+
HEADING_LEVEL_CLAMPED: "md/heading-level-clamped",
|
|
21
|
+
ADJACENT_LINKS_MERGED: "md/adjacent-links-merged",
|
|
22
|
+
CODE_SPAN_AS_MONOSPACE_RUN: "md/code-span-as-monospace-run",
|
|
23
|
+
PARAGRAPH_INDENT_DROPPED: "md/paragraph-indent-dropped",
|
|
24
|
+
LIST_NUMID_FALLBACK: "md/list-numid-fallback",
|
|
25
|
+
TABLE_CELL_FORMATTING_DROPPED: "md/table-cell-formatting-dropped",
|
|
26
|
+
TABLE_CELL_MULTI_PARAGRAPH_JOINED: "md/table-cell-multi-paragraph-joined"
|
|
27
|
+
};
|
|
28
|
+
var MarkdownParseError = class extends Error {
|
|
29
|
+
code;
|
|
30
|
+
constructor(code, message) {
|
|
31
|
+
super(message);
|
|
32
|
+
this.name = "MarkdownParseError";
|
|
33
|
+
this.code = code;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
var MarkdownInvalidUtf8Error = class extends MarkdownParseError {
|
|
37
|
+
constructor(message = "input is not valid UTF-8") {
|
|
38
|
+
super("md/invalid-utf8", message);
|
|
39
|
+
this.name = "MarkdownInvalidUtf8Error";
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
var MarkdownInputTooLargeError = class extends MarkdownParseError {
|
|
43
|
+
maxInputBytes;
|
|
44
|
+
actualBytes;
|
|
45
|
+
constructor(maxInputBytes, actualBytes) {
|
|
46
|
+
super("md/input-too-large", `input is ${String(actualBytes)} bytes, exceeding the configured maximum of ${String(maxInputBytes)} bytes`);
|
|
47
|
+
this.name = "MarkdownInputTooLargeError";
|
|
48
|
+
this.maxInputBytes = maxInputBytes;
|
|
49
|
+
this.actualBytes = actualBytes;
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
var MarkdownNestingLimitExceededError = class extends MarkdownParseError {
|
|
53
|
+
maxNesting;
|
|
54
|
+
constructor(maxNesting) {
|
|
55
|
+
super("md/nesting-limit-exceeded", `block nesting exceeds the configured limit of ${String(maxNesting)}`);
|
|
56
|
+
this.name = "MarkdownNestingLimitExceededError";
|
|
57
|
+
this.maxNesting = maxNesting;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
var MarkdownWriteError = class extends Error {
|
|
61
|
+
code;
|
|
62
|
+
constructor(code, message) {
|
|
63
|
+
super(message);
|
|
64
|
+
this.name = "MarkdownWriteError";
|
|
65
|
+
this.code = code;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
var MarkdownUnsupportedDocumentKindError = class extends MarkdownWriteError {
|
|
69
|
+
kind;
|
|
70
|
+
constructor(kind) {
|
|
71
|
+
super("md/write-side-not-wordprocessing", `writeMarkdown only supports a 'wordprocessing' ContentDocument, got '${kind}'`);
|
|
72
|
+
this.name = "MarkdownUnsupportedDocumentKindError";
|
|
73
|
+
this.kind = kind;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
//#endregion
|
|
77
|
+
export { MarkdownDiagnosticCodes, MarkdownInputTooLargeError, MarkdownInvalidUtf8Error, MarkdownNestingLimitExceededError, MarkdownParseError, MarkdownUnsupportedDocumentKindError, MarkdownWriteError, NOOP_MARKDOWN_DIAGNOSTIC_SINK };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
//#region src/diagnostics/diagnostics.d.ts
|
|
2
|
+
type MarkdownDiagnosticSeverity = 'info' | 'warning';
|
|
3
|
+
interface MarkdownDiagnostic {
|
|
4
|
+
readonly code: string;
|
|
5
|
+
readonly severity: MarkdownDiagnosticSeverity;
|
|
6
|
+
readonly message: string;
|
|
7
|
+
readonly line?: number;
|
|
8
|
+
}
|
|
9
|
+
type MarkdownDiagnosticSink = (diagnostic: MarkdownDiagnostic) => void;
|
|
10
|
+
declare const NOOP_MARKDOWN_DIAGNOSTIC_SINK: MarkdownDiagnosticSink;
|
|
11
|
+
declare const MarkdownDiagnosticCodes: {
|
|
12
|
+
readonly UNCLOSED_FENCE: "md/unclosed-fence";
|
|
13
|
+
readonly UNTERMINATED_HTML_BLOCK: "md/unterminated-html-block";
|
|
14
|
+
readonly TABLE_CELL_COUNT_MISMATCH: "md/table-cell-count-mismatch";
|
|
15
|
+
readonly DUPLICATE_LINK_REFERENCE: "md/duplicate-link-reference";
|
|
16
|
+
readonly LIST_MARKER_TYPE_CONFLICT: "md/list-marker-type-conflict";
|
|
17
|
+
readonly INVENTED_PAGE_GEOMETRY: "md/invented-page-geometry";
|
|
18
|
+
readonly NESTED_EMPHASIS_FLATTENED: "md/nested-emphasis-flattened";
|
|
19
|
+
readonly LINK_TITLE_DROPPED: "md/link-title-dropped";
|
|
20
|
+
readonly CODE_BLOCK_INFO_STRING_DROPPED: "md/code-block-info-string-dropped";
|
|
21
|
+
readonly BLOCKQUOTE_NESTED_DEPTH: "md/blockquote-nested-depth";
|
|
22
|
+
readonly LIST_ITEM_BLOCK_UNLISTED: "md/list-item-block-unlisted";
|
|
23
|
+
readonly LIST_ITEM_MULTI_BLOCK_FLATTENED: "md/list-item-multi-block-flattened";
|
|
24
|
+
readonly IMAGE_UNRESOLVED: "md/image-unresolved";
|
|
25
|
+
readonly RAW_HTML_PRESERVED_AS_TEXT: "md/raw-html-preserved-as-text";
|
|
26
|
+
readonly RAW_HTML_DROPPED: "md/raw-html-dropped";
|
|
27
|
+
readonly FRONT_MATTER_KEY_UNMAPPED: "md/front-matter-key-unmapped";
|
|
28
|
+
readonly HEADING_LEVEL_CLAMPED: "md/heading-level-clamped";
|
|
29
|
+
readonly ADJACENT_LINKS_MERGED: "md/adjacent-links-merged";
|
|
30
|
+
readonly CODE_SPAN_AS_MONOSPACE_RUN: "md/code-span-as-monospace-run";
|
|
31
|
+
readonly PARAGRAPH_INDENT_DROPPED: "md/paragraph-indent-dropped";
|
|
32
|
+
readonly LIST_NUMID_FALLBACK: "md/list-numid-fallback";
|
|
33
|
+
readonly TABLE_CELL_FORMATTING_DROPPED: "md/table-cell-formatting-dropped";
|
|
34
|
+
readonly TABLE_CELL_MULTI_PARAGRAPH_JOINED: "md/table-cell-multi-paragraph-joined";
|
|
35
|
+
};
|
|
36
|
+
declare class MarkdownParseError extends Error {
|
|
37
|
+
readonly code: string;
|
|
38
|
+
constructor(code: string, message: string);
|
|
39
|
+
}
|
|
40
|
+
declare class MarkdownInvalidUtf8Error extends MarkdownParseError {
|
|
41
|
+
constructor(message?: string);
|
|
42
|
+
}
|
|
43
|
+
declare class MarkdownInputTooLargeError extends MarkdownParseError {
|
|
44
|
+
readonly maxInputBytes: number;
|
|
45
|
+
readonly actualBytes: number;
|
|
46
|
+
constructor(maxInputBytes: number, actualBytes: number);
|
|
47
|
+
}
|
|
48
|
+
declare class MarkdownNestingLimitExceededError extends MarkdownParseError {
|
|
49
|
+
readonly maxNesting: number;
|
|
50
|
+
constructor(maxNesting: number);
|
|
51
|
+
}
|
|
52
|
+
declare class MarkdownWriteError extends Error {
|
|
53
|
+
readonly code: string;
|
|
54
|
+
constructor(code: string, message: string);
|
|
55
|
+
}
|
|
56
|
+
declare class MarkdownUnsupportedDocumentKindError extends MarkdownWriteError {
|
|
57
|
+
readonly kind: string;
|
|
58
|
+
constructor(kind: string);
|
|
59
|
+
}
|
|
60
|
+
//#endregion
|
|
61
|
+
export { MarkdownInputTooLargeError as a, MarkdownParseError as c, NOOP_MARKDOWN_DIAGNOSTIC_SINK as d, MarkdownDiagnosticSink as i, MarkdownUnsupportedDocumentKindError as l, MarkdownDiagnosticCodes as n, MarkdownInvalidUtf8Error as o, MarkdownDiagnosticSeverity as r, MarkdownNestingLimitExceededError as s, MarkdownDiagnostic as t, MarkdownWriteError as u };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
//#region src/diagnostics/diagnostics.d.ts
|
|
2
|
+
type MarkdownDiagnosticSeverity = 'info' | 'warning';
|
|
3
|
+
interface MarkdownDiagnostic {
|
|
4
|
+
readonly code: string;
|
|
5
|
+
readonly severity: MarkdownDiagnosticSeverity;
|
|
6
|
+
readonly message: string;
|
|
7
|
+
readonly line?: number;
|
|
8
|
+
}
|
|
9
|
+
type MarkdownDiagnosticSink = (diagnostic: MarkdownDiagnostic) => void;
|
|
10
|
+
declare const NOOP_MARKDOWN_DIAGNOSTIC_SINK: MarkdownDiagnosticSink;
|
|
11
|
+
declare const MarkdownDiagnosticCodes: {
|
|
12
|
+
readonly UNCLOSED_FENCE: "md/unclosed-fence";
|
|
13
|
+
readonly UNTERMINATED_HTML_BLOCK: "md/unterminated-html-block";
|
|
14
|
+
readonly TABLE_CELL_COUNT_MISMATCH: "md/table-cell-count-mismatch";
|
|
15
|
+
readonly DUPLICATE_LINK_REFERENCE: "md/duplicate-link-reference";
|
|
16
|
+
readonly LIST_MARKER_TYPE_CONFLICT: "md/list-marker-type-conflict";
|
|
17
|
+
readonly INVENTED_PAGE_GEOMETRY: "md/invented-page-geometry";
|
|
18
|
+
readonly NESTED_EMPHASIS_FLATTENED: "md/nested-emphasis-flattened";
|
|
19
|
+
readonly LINK_TITLE_DROPPED: "md/link-title-dropped";
|
|
20
|
+
readonly CODE_BLOCK_INFO_STRING_DROPPED: "md/code-block-info-string-dropped";
|
|
21
|
+
readonly BLOCKQUOTE_NESTED_DEPTH: "md/blockquote-nested-depth";
|
|
22
|
+
readonly LIST_ITEM_BLOCK_UNLISTED: "md/list-item-block-unlisted";
|
|
23
|
+
readonly LIST_ITEM_MULTI_BLOCK_FLATTENED: "md/list-item-multi-block-flattened";
|
|
24
|
+
readonly IMAGE_UNRESOLVED: "md/image-unresolved";
|
|
25
|
+
readonly RAW_HTML_PRESERVED_AS_TEXT: "md/raw-html-preserved-as-text";
|
|
26
|
+
readonly RAW_HTML_DROPPED: "md/raw-html-dropped";
|
|
27
|
+
readonly FRONT_MATTER_KEY_UNMAPPED: "md/front-matter-key-unmapped";
|
|
28
|
+
readonly HEADING_LEVEL_CLAMPED: "md/heading-level-clamped";
|
|
29
|
+
readonly ADJACENT_LINKS_MERGED: "md/adjacent-links-merged";
|
|
30
|
+
readonly CODE_SPAN_AS_MONOSPACE_RUN: "md/code-span-as-monospace-run";
|
|
31
|
+
readonly PARAGRAPH_INDENT_DROPPED: "md/paragraph-indent-dropped";
|
|
32
|
+
readonly LIST_NUMID_FALLBACK: "md/list-numid-fallback";
|
|
33
|
+
readonly TABLE_CELL_FORMATTING_DROPPED: "md/table-cell-formatting-dropped";
|
|
34
|
+
readonly TABLE_CELL_MULTI_PARAGRAPH_JOINED: "md/table-cell-multi-paragraph-joined";
|
|
35
|
+
};
|
|
36
|
+
declare class MarkdownParseError extends Error {
|
|
37
|
+
readonly code: string;
|
|
38
|
+
constructor(code: string, message: string);
|
|
39
|
+
}
|
|
40
|
+
declare class MarkdownInvalidUtf8Error extends MarkdownParseError {
|
|
41
|
+
constructor(message?: string);
|
|
42
|
+
}
|
|
43
|
+
declare class MarkdownInputTooLargeError extends MarkdownParseError {
|
|
44
|
+
readonly maxInputBytes: number;
|
|
45
|
+
readonly actualBytes: number;
|
|
46
|
+
constructor(maxInputBytes: number, actualBytes: number);
|
|
47
|
+
}
|
|
48
|
+
declare class MarkdownNestingLimitExceededError extends MarkdownParseError {
|
|
49
|
+
readonly maxNesting: number;
|
|
50
|
+
constructor(maxNesting: number);
|
|
51
|
+
}
|
|
52
|
+
declare class MarkdownWriteError extends Error {
|
|
53
|
+
readonly code: string;
|
|
54
|
+
constructor(code: string, message: string);
|
|
55
|
+
}
|
|
56
|
+
declare class MarkdownUnsupportedDocumentKindError extends MarkdownWriteError {
|
|
57
|
+
readonly kind: string;
|
|
58
|
+
constructor(kind: string);
|
|
59
|
+
}
|
|
60
|
+
//#endregion
|
|
61
|
+
export { MarkdownInputTooLargeError as a, MarkdownParseError as c, NOOP_MARKDOWN_DIAGNOSTIC_SINK as d, MarkdownDiagnosticSink as i, MarkdownUnsupportedDocumentKindError as l, MarkdownDiagnosticCodes as n, MarkdownInvalidUtf8Error as o, MarkdownDiagnosticSeverity as r, MarkdownNestingLimitExceededError as s, MarkdownDiagnostic as t, MarkdownWriteError as u };
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
require("../defaults/defaults.cjs");
|
|
3
|
+
const require_diagnostics_diagnostics = require("../diagnostics/diagnostics.cjs");
|
|
4
|
+
const require_shared_list_id = require("../shared/list-id.cjs");
|
|
5
|
+
const require_shared_style_constants = require("../shared/style-constants.cjs");
|
|
6
|
+
const require_emit_front_matter = require("./front-matter.cjs");
|
|
7
|
+
const require_emit_inline = require("./inline.cjs");
|
|
8
|
+
const require_emit_image = require("./image.cjs");
|
|
9
|
+
const require_emit_table = require("./table.cjs");
|
|
10
|
+
//#region src/emit/emit.ts
|
|
11
|
+
const MAX_SETEXT_LEVEL = 2;
|
|
12
|
+
const SETEXT_LEVEL_1_CHAR = "=";
|
|
13
|
+
const SETEXT_LEVEL_2_CHAR = "-";
|
|
14
|
+
const MIN_SETEXT_UNDERLINE_LENGTH = 1;
|
|
15
|
+
function renderSetextHeading(level, text) {
|
|
16
|
+
const underlineChar = level === 1 ? SETEXT_LEVEL_1_CHAR : SETEXT_LEVEL_2_CHAR;
|
|
17
|
+
const firstLine = text.split("\n")[0] ?? "";
|
|
18
|
+
return `${text}\n${underlineChar.repeat(Math.max(MIN_SETEXT_UNDERLINE_LENGTH, firstLine.length))}`;
|
|
19
|
+
}
|
|
20
|
+
const MIN_CODE_FENCE_LENGTH = 3;
|
|
21
|
+
function longestRunLength(text, char) {
|
|
22
|
+
let longest = 0;
|
|
23
|
+
let current = 0;
|
|
24
|
+
for (const candidate of text) if (candidate === char) {
|
|
25
|
+
current += 1;
|
|
26
|
+
longest = Math.max(longest, current);
|
|
27
|
+
} else current = 0;
|
|
28
|
+
return longest;
|
|
29
|
+
}
|
|
30
|
+
function codeFenceFor(literal, fenceChar) {
|
|
31
|
+
return fenceChar.repeat(Math.max(MIN_CODE_FENCE_LENGTH, longestRunLength(literal, fenceChar) + 1));
|
|
32
|
+
}
|
|
33
|
+
const QUOTABLE_STYLE_IDS = /* @__PURE__ */ new Set([
|
|
34
|
+
require_shared_style_constants.QUOTE_STYLE_ID,
|
|
35
|
+
require_shared_style_constants.CODE_BLOCK_STYLE_ID,
|
|
36
|
+
require_shared_style_constants.HORIZONTAL_RULE_STYLE_ID,
|
|
37
|
+
require_shared_style_constants.HTML_PREFORMATTED_STYLE_ID
|
|
38
|
+
]);
|
|
39
|
+
function isQuotableStyle(styleId) {
|
|
40
|
+
if (styleId === void 0) return false;
|
|
41
|
+
return QUOTABLE_STYLE_IDS.has(styleId) || require_shared_style_constants.parseHeadingStyleId(styleId) !== void 0;
|
|
42
|
+
}
|
|
43
|
+
function quoteDepthOf(paragraph) {
|
|
44
|
+
if (paragraph.indentLeftPt === void 0 || paragraph.indentLeftPt <= 0) return 0;
|
|
45
|
+
return Math.max(1, Math.round(paragraph.indentLeftPt / 36));
|
|
46
|
+
}
|
|
47
|
+
function renderParagraphBody(paragraph, context) {
|
|
48
|
+
if (paragraph.styleId === "HorizontalRule") return context.thematicBreakChar.repeat(3);
|
|
49
|
+
if (paragraph.styleId === "CodeBlock") {
|
|
50
|
+
const literal = paragraph.runs.map((run) => run.text).join("");
|
|
51
|
+
const fence = codeFenceFor(literal, context.codeFenceChar);
|
|
52
|
+
return literal.length === 0 ? `${fence}\n${fence}` : `${fence}\n${literal}\n${fence}`;
|
|
53
|
+
}
|
|
54
|
+
if (paragraph.styleId === "HTMLPreformatted") return paragraph.runs.map((run) => run.text).join("");
|
|
55
|
+
const headingLevel = paragraph.styleId === void 0 ? void 0 : require_shared_style_constants.parseHeadingStyleId(paragraph.styleId);
|
|
56
|
+
if (headingLevel !== void 0) {
|
|
57
|
+
let level = headingLevel;
|
|
58
|
+
if (level > 6) {
|
|
59
|
+
context.sink({
|
|
60
|
+
code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.HEADING_LEVEL_CLAMPED,
|
|
61
|
+
severity: "info",
|
|
62
|
+
message: `heading level ${String(level)} exceeds ATX's own six-"#" ceiling and is clamped to ${String(6)}`
|
|
63
|
+
});
|
|
64
|
+
level = 6;
|
|
65
|
+
}
|
|
66
|
+
const text = require_emit_inline.emitRuns(paragraph.runs, context);
|
|
67
|
+
if (context.headingStyle === "setext" && level <= MAX_SETEXT_LEVEL) return renderSetextHeading(level, text);
|
|
68
|
+
return `${"#".repeat(level)} ${text}`;
|
|
69
|
+
}
|
|
70
|
+
return require_emit_inline.emitRuns(paragraph.runs, context);
|
|
71
|
+
}
|
|
72
|
+
function renderParagraph(paragraph, context) {
|
|
73
|
+
const body = renderParagraphBody(paragraph, context);
|
|
74
|
+
const depth = quoteDepthOf(paragraph);
|
|
75
|
+
if (depth === 0) return body;
|
|
76
|
+
if (!isQuotableStyle(paragraph.styleId)) {
|
|
77
|
+
context.sink({
|
|
78
|
+
code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.PARAGRAPH_INDENT_DROPPED,
|
|
79
|
+
severity: "info",
|
|
80
|
+
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`
|
|
81
|
+
});
|
|
82
|
+
return body;
|
|
83
|
+
}
|
|
84
|
+
const prefix = "> ".repeat(depth);
|
|
85
|
+
return body.split("\n").map((line) => `${prefix}${line}`).join("\n");
|
|
86
|
+
}
|
|
87
|
+
function renderTopLevelBlock(block, context) {
|
|
88
|
+
switch (block.kind) {
|
|
89
|
+
case "paragraph": return renderParagraph(block, context);
|
|
90
|
+
case "table": return require_emit_table.emitTable(block, context);
|
|
91
|
+
case "image": return require_emit_image.emitImage(block, context.embedImages);
|
|
92
|
+
case "pageBreak":
|
|
93
|
+
case "embeddedObject": return "";
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function listInfoFor(numId, context) {
|
|
97
|
+
const info = require_shared_list_id.parseListNumId(numId);
|
|
98
|
+
if (info === void 0 && !context.reportedFallbackNumIds.has(numId)) {
|
|
99
|
+
context.reportedFallbackNumIds.add(numId);
|
|
100
|
+
context.sink({
|
|
101
|
+
code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.LIST_NUMID_FALLBACK,
|
|
102
|
+
severity: "info",
|
|
103
|
+
message: `numId "${numId}" was not minted by this package's own src/lower and falls back to an ordinary, tight, non-task bullet list`
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
return info;
|
|
107
|
+
}
|
|
108
|
+
function checkboxPrefixFor(item) {
|
|
109
|
+
const first = item.runs[0];
|
|
110
|
+
if (first === void 0) return;
|
|
111
|
+
if (first.text.startsWith(`☒ `)) return "[x] ";
|
|
112
|
+
if (first.text.startsWith(`☐ `)) return "[ ] ";
|
|
113
|
+
}
|
|
114
|
+
function stripCheckboxRun(item, checkboxPrefix) {
|
|
115
|
+
if (checkboxPrefix === void 0) return item;
|
|
116
|
+
const first = item.runs[0];
|
|
117
|
+
const glyphPrefix = checkboxPrefix === "[x] " ? `☒ ` : `☐ `;
|
|
118
|
+
if (!first?.text.startsWith(glyphPrefix)) return item;
|
|
119
|
+
const strippedText = first.text.slice(glyphPrefix.length);
|
|
120
|
+
const runs = strippedText.length === 0 ? item.runs.slice(1) : [{
|
|
121
|
+
...first,
|
|
122
|
+
text: strippedText
|
|
123
|
+
}, ...item.runs.slice(1)];
|
|
124
|
+
return {
|
|
125
|
+
...item,
|
|
126
|
+
runs
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
function renderListItemMarker(numId, info, item, context) {
|
|
130
|
+
const checkboxText = (info?.task === true ? checkboxPrefixFor(item) : void 0) ?? "";
|
|
131
|
+
if (info?.type === "ordered") {
|
|
132
|
+
const next = context.orderedCounters.get(numId) ?? info.start ?? 1;
|
|
133
|
+
context.orderedCounters.set(numId, next + 1);
|
|
134
|
+
const bare = `${String(next)}${context.orderedDelimiter} `;
|
|
135
|
+
return {
|
|
136
|
+
full: `${bare}${checkboxText}`,
|
|
137
|
+
bareLength: bare.length
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
const bare = `${context.bulletMarker} `;
|
|
141
|
+
return {
|
|
142
|
+
full: `${bare}${checkboxText}`,
|
|
143
|
+
bareLength: bare.length
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
function renderListRegion(items, context) {
|
|
147
|
+
const parts = [];
|
|
148
|
+
let index = 0;
|
|
149
|
+
while (index < items.length) {
|
|
150
|
+
const item = items[index];
|
|
151
|
+
if (item?.list === void 0) break;
|
|
152
|
+
const { numId, level } = item.list;
|
|
153
|
+
const info = listInfoFor(numId, context);
|
|
154
|
+
let lookahead = index + 1;
|
|
155
|
+
while (lookahead < items.length && (items[lookahead]?.list?.level ?? -1) > level) lookahead += 1;
|
|
156
|
+
const nestedItems = items.slice(index + 1, lookahead);
|
|
157
|
+
const checkboxPrefix = info?.task === true ? checkboxPrefixFor(item) : void 0;
|
|
158
|
+
const marker = renderListItemMarker(numId, info, item, context);
|
|
159
|
+
const bodyLines = renderParagraphBody(stripCheckboxRun(item, checkboxPrefix), context).split("\n");
|
|
160
|
+
const indent = " ".repeat(marker.bareLength);
|
|
161
|
+
const [firstLine = "", ...restLines] = bodyLines;
|
|
162
|
+
let text = [`${marker.full}${firstLine}`, ...restLines.map((line) => `${indent}${line}`)].join("\n");
|
|
163
|
+
if (nestedItems.length > 0) {
|
|
164
|
+
const nested = renderListRegion(nestedItems, context).split("\n").map((line) => line.length === 0 ? line : `${indent}${line}`).join("\n");
|
|
165
|
+
text += `\n${nested}`;
|
|
166
|
+
}
|
|
167
|
+
parts.push({
|
|
168
|
+
numId,
|
|
169
|
+
text
|
|
170
|
+
});
|
|
171
|
+
index = lookahead;
|
|
172
|
+
}
|
|
173
|
+
let out = "";
|
|
174
|
+
for (const [partIndex, part] of parts.entries()) {
|
|
175
|
+
if (partIndex > 0) {
|
|
176
|
+
const previous = parts[partIndex - 1];
|
|
177
|
+
const sameList = previous.numId === part.numId;
|
|
178
|
+
const loose = sameList && (require_shared_list_id.parseListNumId(previous.numId)?.loose ?? false);
|
|
179
|
+
out += sameList && !loose ? "\n" : "\n\n";
|
|
180
|
+
}
|
|
181
|
+
out += part.text;
|
|
182
|
+
}
|
|
183
|
+
return out;
|
|
184
|
+
}
|
|
185
|
+
function emitBlocks(blocks, context) {
|
|
186
|
+
const parts = [];
|
|
187
|
+
let index = 0;
|
|
188
|
+
while (index < blocks.length) {
|
|
189
|
+
const block = blocks[index];
|
|
190
|
+
if (block === void 0) break;
|
|
191
|
+
if (block.kind === "paragraph" && block.list !== void 0) {
|
|
192
|
+
const region = [];
|
|
193
|
+
let end = index;
|
|
194
|
+
for (let candidate = blocks[end]; candidate?.kind === "paragraph" && candidate.list !== void 0; candidate = blocks[end]) {
|
|
195
|
+
region.push(candidate);
|
|
196
|
+
end += 1;
|
|
197
|
+
}
|
|
198
|
+
parts.push(renderListRegion(region, context));
|
|
199
|
+
index = end;
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
const rendered = renderTopLevelBlock(block, context);
|
|
203
|
+
if (rendered.length > 0) parts.push(rendered);
|
|
204
|
+
index += 1;
|
|
205
|
+
}
|
|
206
|
+
return parts.join("\n\n");
|
|
207
|
+
}
|
|
208
|
+
function emitMarkdown(document, options = {}) {
|
|
209
|
+
if (document.kind !== "wordprocessing") throw new require_diagnostics_diagnostics.MarkdownUnsupportedDocumentKindError(document.kind);
|
|
210
|
+
const context = {
|
|
211
|
+
sink: options.sink ?? require_diagnostics_diagnostics.NOOP_MARKDOWN_DIAGNOSTIC_SINK,
|
|
212
|
+
emphasisMarker: options.emphasisMarker ?? "_",
|
|
213
|
+
bulletMarker: options.bulletListMarker ?? "-",
|
|
214
|
+
orderedDelimiter: options.orderedListDelimiter ?? ".",
|
|
215
|
+
codeFenceChar: options.codeFenceChar ?? "`",
|
|
216
|
+
thematicBreakChar: options.thematicBreakChar ?? "-",
|
|
217
|
+
headingStyle: options.headingStyle ?? "atx",
|
|
218
|
+
embedImages: options.images ?? true,
|
|
219
|
+
orderedCounters: /* @__PURE__ */ new Map(),
|
|
220
|
+
reportedFallbackNumIds: /* @__PURE__ */ new Set()
|
|
221
|
+
};
|
|
222
|
+
const body = document.sections.map((section) => emitBlocks(section.blocks, context)).join("\n\n");
|
|
223
|
+
const frontMatter = options.frontMatter === true ? require_emit_front_matter.emitFrontMatter(document.metadata) : void 0;
|
|
224
|
+
const text = frontMatter === void 0 ? body : `${frontMatter}\n\n${body}`;
|
|
225
|
+
return (options.lineEnding ?? "lf") === "crlf" ? text.replaceAll("\n", "\r\n") : text;
|
|
226
|
+
}
|
|
227
|
+
//#endregion
|
|
228
|
+
exports.emitMarkdown = emitMarkdown;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { WriteMarkdownOptions } from "../options/options.cjs";
|
|
2
|
+
import { ContentDocument } from "document-schema.js";
|
|
3
|
+
//#region src/emit/emit.d.ts
|
|
4
|
+
declare function emitMarkdown(document: ContentDocument, options?: WriteMarkdownOptions): string;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { emitMarkdown };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { WriteMarkdownOptions } from "../options/options.js";
|
|
2
|
+
import { ContentDocument } from "document-schema.js";
|
|
3
|
+
//#region src/emit/emit.d.ts
|
|
4
|
+
declare function emitMarkdown(document: ContentDocument, options?: WriteMarkdownOptions): string;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { emitMarkdown };
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import "../defaults/defaults.js";
|
|
2
|
+
import { MarkdownDiagnosticCodes, MarkdownUnsupportedDocumentKindError, NOOP_MARKDOWN_DIAGNOSTIC_SINK } from "../diagnostics/diagnostics.js";
|
|
3
|
+
import { parseListNumId } from "../shared/list-id.js";
|
|
4
|
+
import { CODE_BLOCK_STYLE_ID, HORIZONTAL_RULE_STYLE_ID, HTML_PREFORMATTED_STYLE_ID, QUOTE_STYLE_ID, parseHeadingStyleId } from "../shared/style-constants.js";
|
|
5
|
+
import { emitFrontMatter } from "./front-matter.js";
|
|
6
|
+
import { emitRuns } from "./inline.js";
|
|
7
|
+
import { emitImage } from "./image.js";
|
|
8
|
+
import { emitTable } from "./table.js";
|
|
9
|
+
//#region src/emit/emit.ts
|
|
10
|
+
const MAX_SETEXT_LEVEL = 2;
|
|
11
|
+
const SETEXT_LEVEL_1_CHAR = "=";
|
|
12
|
+
const SETEXT_LEVEL_2_CHAR = "-";
|
|
13
|
+
const MIN_SETEXT_UNDERLINE_LENGTH = 1;
|
|
14
|
+
function renderSetextHeading(level, text) {
|
|
15
|
+
const underlineChar = level === 1 ? SETEXT_LEVEL_1_CHAR : SETEXT_LEVEL_2_CHAR;
|
|
16
|
+
const firstLine = text.split("\n")[0] ?? "";
|
|
17
|
+
return `${text}\n${underlineChar.repeat(Math.max(MIN_SETEXT_UNDERLINE_LENGTH, firstLine.length))}`;
|
|
18
|
+
}
|
|
19
|
+
const MIN_CODE_FENCE_LENGTH = 3;
|
|
20
|
+
function longestRunLength(text, char) {
|
|
21
|
+
let longest = 0;
|
|
22
|
+
let current = 0;
|
|
23
|
+
for (const candidate of text) if (candidate === char) {
|
|
24
|
+
current += 1;
|
|
25
|
+
longest = Math.max(longest, current);
|
|
26
|
+
} else current = 0;
|
|
27
|
+
return longest;
|
|
28
|
+
}
|
|
29
|
+
function codeFenceFor(literal, fenceChar) {
|
|
30
|
+
return fenceChar.repeat(Math.max(MIN_CODE_FENCE_LENGTH, longestRunLength(literal, fenceChar) + 1));
|
|
31
|
+
}
|
|
32
|
+
const QUOTABLE_STYLE_IDS = /* @__PURE__ */ new Set([
|
|
33
|
+
QUOTE_STYLE_ID,
|
|
34
|
+
CODE_BLOCK_STYLE_ID,
|
|
35
|
+
HORIZONTAL_RULE_STYLE_ID,
|
|
36
|
+
HTML_PREFORMATTED_STYLE_ID
|
|
37
|
+
]);
|
|
38
|
+
function isQuotableStyle(styleId) {
|
|
39
|
+
if (styleId === void 0) return false;
|
|
40
|
+
return QUOTABLE_STYLE_IDS.has(styleId) || parseHeadingStyleId(styleId) !== void 0;
|
|
41
|
+
}
|
|
42
|
+
function quoteDepthOf(paragraph) {
|
|
43
|
+
if (paragraph.indentLeftPt === void 0 || paragraph.indentLeftPt <= 0) return 0;
|
|
44
|
+
return Math.max(1, Math.round(paragraph.indentLeftPt / 36));
|
|
45
|
+
}
|
|
46
|
+
function renderParagraphBody(paragraph, context) {
|
|
47
|
+
if (paragraph.styleId === "HorizontalRule") return context.thematicBreakChar.repeat(3);
|
|
48
|
+
if (paragraph.styleId === "CodeBlock") {
|
|
49
|
+
const literal = paragraph.runs.map((run) => run.text).join("");
|
|
50
|
+
const fence = codeFenceFor(literal, context.codeFenceChar);
|
|
51
|
+
return literal.length === 0 ? `${fence}\n${fence}` : `${fence}\n${literal}\n${fence}`;
|
|
52
|
+
}
|
|
53
|
+
if (paragraph.styleId === "HTMLPreformatted") return paragraph.runs.map((run) => run.text).join("");
|
|
54
|
+
const headingLevel = paragraph.styleId === void 0 ? void 0 : parseHeadingStyleId(paragraph.styleId);
|
|
55
|
+
if (headingLevel !== void 0) {
|
|
56
|
+
let level = headingLevel;
|
|
57
|
+
if (level > 6) {
|
|
58
|
+
context.sink({
|
|
59
|
+
code: MarkdownDiagnosticCodes.HEADING_LEVEL_CLAMPED,
|
|
60
|
+
severity: "info",
|
|
61
|
+
message: `heading level ${String(level)} exceeds ATX's own six-"#" ceiling and is clamped to ${String(6)}`
|
|
62
|
+
});
|
|
63
|
+
level = 6;
|
|
64
|
+
}
|
|
65
|
+
const text = emitRuns(paragraph.runs, context);
|
|
66
|
+
if (context.headingStyle === "setext" && level <= MAX_SETEXT_LEVEL) return renderSetextHeading(level, text);
|
|
67
|
+
return `${"#".repeat(level)} ${text}`;
|
|
68
|
+
}
|
|
69
|
+
return emitRuns(paragraph.runs, context);
|
|
70
|
+
}
|
|
71
|
+
function renderParagraph(paragraph, context) {
|
|
72
|
+
const body = renderParagraphBody(paragraph, context);
|
|
73
|
+
const depth = quoteDepthOf(paragraph);
|
|
74
|
+
if (depth === 0) return body;
|
|
75
|
+
if (!isQuotableStyle(paragraph.styleId)) {
|
|
76
|
+
context.sink({
|
|
77
|
+
code: MarkdownDiagnosticCodes.PARAGRAPH_INDENT_DROPPED,
|
|
78
|
+
severity: "info",
|
|
79
|
+
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`
|
|
80
|
+
});
|
|
81
|
+
return body;
|
|
82
|
+
}
|
|
83
|
+
const prefix = "> ".repeat(depth);
|
|
84
|
+
return body.split("\n").map((line) => `${prefix}${line}`).join("\n");
|
|
85
|
+
}
|
|
86
|
+
function renderTopLevelBlock(block, context) {
|
|
87
|
+
switch (block.kind) {
|
|
88
|
+
case "paragraph": return renderParagraph(block, context);
|
|
89
|
+
case "table": return emitTable(block, context);
|
|
90
|
+
case "image": return emitImage(block, context.embedImages);
|
|
91
|
+
case "pageBreak":
|
|
92
|
+
case "embeddedObject": return "";
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
function listInfoFor(numId, context) {
|
|
96
|
+
const info = parseListNumId(numId);
|
|
97
|
+
if (info === void 0 && !context.reportedFallbackNumIds.has(numId)) {
|
|
98
|
+
context.reportedFallbackNumIds.add(numId);
|
|
99
|
+
context.sink({
|
|
100
|
+
code: MarkdownDiagnosticCodes.LIST_NUMID_FALLBACK,
|
|
101
|
+
severity: "info",
|
|
102
|
+
message: `numId "${numId}" was not minted by this package's own src/lower and falls back to an ordinary, tight, non-task bullet list`
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
return info;
|
|
106
|
+
}
|
|
107
|
+
function checkboxPrefixFor(item) {
|
|
108
|
+
const first = item.runs[0];
|
|
109
|
+
if (first === void 0) return;
|
|
110
|
+
if (first.text.startsWith(`☒ `)) return "[x] ";
|
|
111
|
+
if (first.text.startsWith(`☐ `)) return "[ ] ";
|
|
112
|
+
}
|
|
113
|
+
function stripCheckboxRun(item, checkboxPrefix) {
|
|
114
|
+
if (checkboxPrefix === void 0) return item;
|
|
115
|
+
const first = item.runs[0];
|
|
116
|
+
const glyphPrefix = checkboxPrefix === "[x] " ? `☒ ` : `☐ `;
|
|
117
|
+
if (!first?.text.startsWith(glyphPrefix)) return item;
|
|
118
|
+
const strippedText = first.text.slice(glyphPrefix.length);
|
|
119
|
+
const runs = strippedText.length === 0 ? item.runs.slice(1) : [{
|
|
120
|
+
...first,
|
|
121
|
+
text: strippedText
|
|
122
|
+
}, ...item.runs.slice(1)];
|
|
123
|
+
return {
|
|
124
|
+
...item,
|
|
125
|
+
runs
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function renderListItemMarker(numId, info, item, context) {
|
|
129
|
+
const checkboxText = (info?.task === true ? checkboxPrefixFor(item) : void 0) ?? "";
|
|
130
|
+
if (info?.type === "ordered") {
|
|
131
|
+
const next = context.orderedCounters.get(numId) ?? info.start ?? 1;
|
|
132
|
+
context.orderedCounters.set(numId, next + 1);
|
|
133
|
+
const bare = `${String(next)}${context.orderedDelimiter} `;
|
|
134
|
+
return {
|
|
135
|
+
full: `${bare}${checkboxText}`,
|
|
136
|
+
bareLength: bare.length
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
const bare = `${context.bulletMarker} `;
|
|
140
|
+
return {
|
|
141
|
+
full: `${bare}${checkboxText}`,
|
|
142
|
+
bareLength: bare.length
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
function renderListRegion(items, context) {
|
|
146
|
+
const parts = [];
|
|
147
|
+
let index = 0;
|
|
148
|
+
while (index < items.length) {
|
|
149
|
+
const item = items[index];
|
|
150
|
+
if (item?.list === void 0) break;
|
|
151
|
+
const { numId, level } = item.list;
|
|
152
|
+
const info = listInfoFor(numId, context);
|
|
153
|
+
let lookahead = index + 1;
|
|
154
|
+
while (lookahead < items.length && (items[lookahead]?.list?.level ?? -1) > level) lookahead += 1;
|
|
155
|
+
const nestedItems = items.slice(index + 1, lookahead);
|
|
156
|
+
const checkboxPrefix = info?.task === true ? checkboxPrefixFor(item) : void 0;
|
|
157
|
+
const marker = renderListItemMarker(numId, info, item, context);
|
|
158
|
+
const bodyLines = renderParagraphBody(stripCheckboxRun(item, checkboxPrefix), context).split("\n");
|
|
159
|
+
const indent = " ".repeat(marker.bareLength);
|
|
160
|
+
const [firstLine = "", ...restLines] = bodyLines;
|
|
161
|
+
let text = [`${marker.full}${firstLine}`, ...restLines.map((line) => `${indent}${line}`)].join("\n");
|
|
162
|
+
if (nestedItems.length > 0) {
|
|
163
|
+
const nested = renderListRegion(nestedItems, context).split("\n").map((line) => line.length === 0 ? line : `${indent}${line}`).join("\n");
|
|
164
|
+
text += `\n${nested}`;
|
|
165
|
+
}
|
|
166
|
+
parts.push({
|
|
167
|
+
numId,
|
|
168
|
+
text
|
|
169
|
+
});
|
|
170
|
+
index = lookahead;
|
|
171
|
+
}
|
|
172
|
+
let out = "";
|
|
173
|
+
for (const [partIndex, part] of parts.entries()) {
|
|
174
|
+
if (partIndex > 0) {
|
|
175
|
+
const previous = parts[partIndex - 1];
|
|
176
|
+
const sameList = previous.numId === part.numId;
|
|
177
|
+
const loose = sameList && (parseListNumId(previous.numId)?.loose ?? false);
|
|
178
|
+
out += sameList && !loose ? "\n" : "\n\n";
|
|
179
|
+
}
|
|
180
|
+
out += part.text;
|
|
181
|
+
}
|
|
182
|
+
return out;
|
|
183
|
+
}
|
|
184
|
+
function emitBlocks(blocks, context) {
|
|
185
|
+
const parts = [];
|
|
186
|
+
let index = 0;
|
|
187
|
+
while (index < blocks.length) {
|
|
188
|
+
const block = blocks[index];
|
|
189
|
+
if (block === void 0) break;
|
|
190
|
+
if (block.kind === "paragraph" && block.list !== void 0) {
|
|
191
|
+
const region = [];
|
|
192
|
+
let end = index;
|
|
193
|
+
for (let candidate = blocks[end]; candidate?.kind === "paragraph" && candidate.list !== void 0; candidate = blocks[end]) {
|
|
194
|
+
region.push(candidate);
|
|
195
|
+
end += 1;
|
|
196
|
+
}
|
|
197
|
+
parts.push(renderListRegion(region, context));
|
|
198
|
+
index = end;
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
const rendered = renderTopLevelBlock(block, context);
|
|
202
|
+
if (rendered.length > 0) parts.push(rendered);
|
|
203
|
+
index += 1;
|
|
204
|
+
}
|
|
205
|
+
return parts.join("\n\n");
|
|
206
|
+
}
|
|
207
|
+
function emitMarkdown(document, options = {}) {
|
|
208
|
+
if (document.kind !== "wordprocessing") throw new MarkdownUnsupportedDocumentKindError(document.kind);
|
|
209
|
+
const context = {
|
|
210
|
+
sink: options.sink ?? NOOP_MARKDOWN_DIAGNOSTIC_SINK,
|
|
211
|
+
emphasisMarker: options.emphasisMarker ?? "_",
|
|
212
|
+
bulletMarker: options.bulletListMarker ?? "-",
|
|
213
|
+
orderedDelimiter: options.orderedListDelimiter ?? ".",
|
|
214
|
+
codeFenceChar: options.codeFenceChar ?? "`",
|
|
215
|
+
thematicBreakChar: options.thematicBreakChar ?? "-",
|
|
216
|
+
headingStyle: options.headingStyle ?? "atx",
|
|
217
|
+
embedImages: options.images ?? true,
|
|
218
|
+
orderedCounters: /* @__PURE__ */ new Map(),
|
|
219
|
+
reportedFallbackNumIds: /* @__PURE__ */ new Set()
|
|
220
|
+
};
|
|
221
|
+
const body = document.sections.map((section) => emitBlocks(section.blocks, context)).join("\n\n");
|
|
222
|
+
const frontMatter = options.frontMatter === true ? emitFrontMatter(document.metadata) : void 0;
|
|
223
|
+
const text = frontMatter === void 0 ? body : `${frontMatter}\n\n${body}`;
|
|
224
|
+
return (options.lineEnding ?? "lf") === "crlf" ? text.replaceAll("\n", "\r\n") : text;
|
|
225
|
+
}
|
|
226
|
+
//#endregion
|
|
227
|
+
export { emitMarkdown };
|