@illusions-lab/mdi 2.0.7 → 2.0.9
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/README.md +62 -3
- package/dist/chunk-FA5R33XH.js +383 -0
- package/dist/index.cjs +347 -7
- package/dist/index.d.cts +148 -3
- package/dist/index.d.ts +148 -3
- package/dist/index.js +30 -47
- package/dist/node.cjs +160 -0
- package/dist/node.d.cts +41 -0
- package/dist/node.d.ts +41 -0
- package/dist/node.js +97 -0
- package/package.json +46 -36
package/README.md
CHANGED
|
@@ -62,15 +62,74 @@ unsupported version.
|
|
|
62
62
|
|
|
63
63
|
## Rendering
|
|
64
64
|
|
|
65
|
-
Rendering starts from the same Rust IR. Canonical MDI, plain text, HTML,
|
|
66
|
-
|
|
67
|
-
uses Rust HTML as its input to a host layout adapter such as
|
|
65
|
+
Rendering starts from the same Rust IR. Canonical MDI, plain text, HTML, and
|
|
66
|
+
the one-argument baseline EPUB/DOCX renderers execute in Rust and are exposed
|
|
67
|
+
through this package. PDF uses Rust HTML as its input to a host layout adapter such as
|
|
68
68
|
`@illusions-lab/mdi-to-pdf`; the adapter may control Chromium, but it never
|
|
69
69
|
parses MDI or produces semantic HTML.
|
|
70
70
|
|
|
71
71
|
Browser WebAssembly cannot start Chromium. Browser code sends Rust-rendered
|
|
72
72
|
HTML to a server or desktop host when it needs PDF output.
|
|
73
73
|
|
|
74
|
+
### HTML, diagnostics, and host workflows
|
|
75
|
+
|
|
76
|
+
`renderHtml(source)` returns a standalone HTML document with the stable MDI
|
|
77
|
+
classes emitted by Rust. Pass `{ bodyOnly: true }` to embed its semantic body
|
|
78
|
+
in an application shell; this changes only the outer document wrapper, never
|
|
79
|
+
the MDI-to-HTML semantics.
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
import { renderHtmlWithDiagnostics } from "@illusions-lab/mdi";
|
|
83
|
+
|
|
84
|
+
const result = renderHtmlWithDiagnostics(source, { bodyOnly: true });
|
|
85
|
+
preview.replaceChildren(htmlToDom(result.output));
|
|
86
|
+
showDiagnostics(result.diagnostics); // stable codes and UTF-8 source spans
|
|
87
|
+
buildOutline(result.headings); // source-backed heading nodes, not HTML scraping
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
For a parse-first flow, call `prepareRender(source)` (or `parse(source)`) and
|
|
91
|
+
display `diagnostics` before choosing an exporter. The public Rust ABI accepts
|
|
92
|
+
source text for renderer calls today, so renderers re-enter the same
|
|
93
|
+
Rust-authoritative parser rather than accepting mutable JavaScript IR. This
|
|
94
|
+
keeps the source spans and error codes predictable and prevents JavaScript from
|
|
95
|
+
becoming a second syntax implementation.
|
|
96
|
+
|
|
97
|
+
Configuration ownership is deliberately split: Rust owns MDI parsing and
|
|
98
|
+
semantic HTML; publication profiles own EPUB/DOCX metadata and typesetting;
|
|
99
|
+
the host owns Chromium/Electron, paper-printer integration, and application UI
|
|
100
|
+
preferences. This keeps platform-specific pagination controls out of the
|
|
101
|
+
parser and lets Electron supply its own PDF adapter.
|
|
102
|
+
|
|
103
|
+
### Configured EPUB and DOCX
|
|
104
|
+
|
|
105
|
+
For publication output, pass an export profile to the overloads (or use the
|
|
106
|
+
explicit `WithProfile` functions). These Node.js-only async paths map the
|
|
107
|
+
Rust-owned IR through the publication adapters and retain configuration for
|
|
108
|
+
metadata, chapter splitting, vertical writing, font selection, paper size,
|
|
109
|
+
margins, and page numbers. EPUB also accepts in-memory PNG or JPEG cover art.
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
import { renderDocxWithProfile, renderEpubWithProfile } from "@illusions-lab/mdi";
|
|
113
|
+
|
|
114
|
+
const epub = await renderEpubWithProfile(source, {
|
|
115
|
+
profile: {
|
|
116
|
+
metadata: { title: "Book", author: "Author" },
|
|
117
|
+
typesetting: { writingMode: "vertical", fontFamily: "Noto Serif JP" },
|
|
118
|
+
epub: { chapterSplitLevel: "h1" },
|
|
119
|
+
},
|
|
120
|
+
cover: { data: coverBytes, mediaType: "image/png" },
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
const docx = await renderDocxWithProfile(source, {
|
|
124
|
+
pagination: { pageSize: "A5", margins: { top: 12, bottom: 12, left: 14, right: 14 } },
|
|
125
|
+
});
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
`renderEpub(source)` and `renderDocx(source)` remain synchronous,
|
|
129
|
+
backward-compatible Rust baseline exports. `renderEpub(source, options)` and
|
|
130
|
+
`renderDocx(source, profile)` are equivalent async overloads for configured
|
|
131
|
+
publication output.
|
|
132
|
+
|
|
74
133
|
## Remark compatibility
|
|
75
134
|
|
|
76
135
|
Remark support is an optional adapter between Rust IR and mdast. It exists for
|
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import {
|
|
3
|
+
parseMdiSyntaxJson,
|
|
4
|
+
renderHtml as renderHtmlFromRust,
|
|
5
|
+
renderEpub as renderEpubFromRust,
|
|
6
|
+
renderDocx as renderDocxFromRust,
|
|
7
|
+
renderText as renderTextFromRust,
|
|
8
|
+
renderTextFormat as renderTextFormatFromRust,
|
|
9
|
+
serializeMdi as serializeMdiFromRust
|
|
10
|
+
} from "@illusions-lab/mdi-core";
|
|
11
|
+
import {
|
|
12
|
+
requireLayoutSystem
|
|
13
|
+
} from "@illusions-lab/mdi-export-profile";
|
|
14
|
+
import { parse as parseYaml } from "yaml";
|
|
15
|
+
var MDI_SPEC_VERSION = "2.0";
|
|
16
|
+
var MDI_IR_VERSION = "1.0";
|
|
17
|
+
function parse(source) {
|
|
18
|
+
if (typeof source !== "string") throw new TypeError("source must be a string");
|
|
19
|
+
const result = JSON.parse(parseMdiSyntaxJson(source));
|
|
20
|
+
if (result.irVersion !== MDI_IR_VERSION) {
|
|
21
|
+
throw new Error(`Unsupported MDI IR version: ${String(result.irVersion)}`);
|
|
22
|
+
}
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
function renderHtml(source, options) {
|
|
26
|
+
assertSource(source);
|
|
27
|
+
assertHtmlOptions(options);
|
|
28
|
+
const html = renderHtmlFromRust(source);
|
|
29
|
+
return options?.bodyOnly ? htmlBody(html) : html;
|
|
30
|
+
}
|
|
31
|
+
function renderHtmlWithDiagnostics(source, options) {
|
|
32
|
+
assertSource(source);
|
|
33
|
+
assertHtmlOptions(options);
|
|
34
|
+
return renderWithDiagnostics(source, () => renderHtml(source, options));
|
|
35
|
+
}
|
|
36
|
+
function prepareRender(source) {
|
|
37
|
+
return parse(source);
|
|
38
|
+
}
|
|
39
|
+
function renderEpub(source, options) {
|
|
40
|
+
if (typeof source !== "string") throw new TypeError("source must be a string");
|
|
41
|
+
if (options !== void 0) {
|
|
42
|
+
assertEpubOptions(options);
|
|
43
|
+
return renderEpubWithProfile(source, options);
|
|
44
|
+
}
|
|
45
|
+
return renderEpubFromRust(source);
|
|
46
|
+
}
|
|
47
|
+
function renderEpubWithDiagnostics(source, options) {
|
|
48
|
+
return options === void 0 ? renderWithDiagnostics(source, () => renderEpub(source)) : renderWithDiagnosticsAsync(source, () => renderEpub(source, options));
|
|
49
|
+
}
|
|
50
|
+
function renderDocx(source, profile) {
|
|
51
|
+
if (typeof source !== "string") throw new TypeError("source must be a string");
|
|
52
|
+
if (profile !== void 0) {
|
|
53
|
+
assertPlainObject(profile, "profile");
|
|
54
|
+
return renderDocxWithProfile(source, profile);
|
|
55
|
+
}
|
|
56
|
+
return renderDocxFromRust(source);
|
|
57
|
+
}
|
|
58
|
+
function renderDocxWithDiagnostics(source, profile) {
|
|
59
|
+
return profile === void 0 ? renderWithDiagnostics(source, () => renderDocx(source)) : renderWithDiagnosticsAsync(source, () => renderDocx(source, profile));
|
|
60
|
+
}
|
|
61
|
+
async function renderEpubWithProfile(source, options = {}) {
|
|
62
|
+
assertSource(source);
|
|
63
|
+
assertEpubOptions(options);
|
|
64
|
+
const { mdiToEpub } = await import("@illusions-lab/mdi-to-epub");
|
|
65
|
+
const normalized = normalizeEpubOptions(options);
|
|
66
|
+
requireLayoutSystem(normalized.profile);
|
|
67
|
+
return mdiToEpub(toPublicationMdast(parse(source).document), normalized);
|
|
68
|
+
}
|
|
69
|
+
async function renderDocxWithProfile(source, profile = {}) {
|
|
70
|
+
assertSource(source);
|
|
71
|
+
assertPlainObject(profile, "profile");
|
|
72
|
+
prepareNodeDocxImport();
|
|
73
|
+
const { mdiToDocx } = await import("@illusions-lab/mdi-to-docx");
|
|
74
|
+
const normalized = normalizeDocxProfile(profile);
|
|
75
|
+
requireLayoutSystem(normalized);
|
|
76
|
+
return mdiToDocx(toPublicationMdast(parse(source).document), normalized);
|
|
77
|
+
}
|
|
78
|
+
function prepareNodeDocxImport() {
|
|
79
|
+
const nodeProcess = globalThis.process;
|
|
80
|
+
if (nodeProcess?.release?.name === "node" && !nodeProcess.execArgv?.some((argument) => argument.startsWith("--localstorage-file="))) {
|
|
81
|
+
const descriptor = Object.getOwnPropertyDescriptor(globalThis, "localStorage");
|
|
82
|
+
if (descriptor?.configurable && descriptor.get)
|
|
83
|
+
Object.defineProperty(globalThis, "localStorage", {
|
|
84
|
+
value: void 0,
|
|
85
|
+
configurable: true
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function toPublicationMdast(document) {
|
|
90
|
+
const children = document.children.map(toPublicationMdastNode);
|
|
91
|
+
const tree = { type: "root", children };
|
|
92
|
+
if (document.frontmatter) {
|
|
93
|
+
children.unshift({ type: "yaml", value: document.frontmatter.raw });
|
|
94
|
+
const frontmatter = publicationFrontmatter(document.frontmatter.raw);
|
|
95
|
+
tree.data ??= {};
|
|
96
|
+
tree.data.frontmatter = frontmatter;
|
|
97
|
+
}
|
|
98
|
+
return tree;
|
|
99
|
+
}
|
|
100
|
+
function toPublicationMdastNode(node) {
|
|
101
|
+
const { span: _span, children, ...rest } = node;
|
|
102
|
+
const mapped = { ...rest };
|
|
103
|
+
if (children) mapped.children = children.map(toPublicationMdastNode);
|
|
104
|
+
switch (node.type) {
|
|
105
|
+
case "ruby": {
|
|
106
|
+
const ruby = node.ruby;
|
|
107
|
+
return { ...mapped, type: "mdiRuby", ruby: ruby.value };
|
|
108
|
+
}
|
|
109
|
+
case "tcy":
|
|
110
|
+
return { ...mapped, type: "mdiTcy" };
|
|
111
|
+
case "break":
|
|
112
|
+
return { ...mapped, type: "mdiBreak" };
|
|
113
|
+
case "em":
|
|
114
|
+
return { ...mapped, type: "mdiEm" };
|
|
115
|
+
case "noBreak":
|
|
116
|
+
return { ...mapped, type: "mdiNoBreak" };
|
|
117
|
+
case "warichu":
|
|
118
|
+
return { ...mapped, type: "mdiWarichu" };
|
|
119
|
+
case "kern":
|
|
120
|
+
return { ...mapped, type: "mdiKern" };
|
|
121
|
+
case "blank":
|
|
122
|
+
return { ...mapped, type: "mdiBlank" };
|
|
123
|
+
case "pagebreak": {
|
|
124
|
+
if (mapped.variant === null) delete mapped.variant;
|
|
125
|
+
return { ...mapped, type: "mdiPagebreak" };
|
|
126
|
+
}
|
|
127
|
+
case "paragraph": {
|
|
128
|
+
const data = {};
|
|
129
|
+
if (typeof mapped.indent === "number") data.mdiIndent = mapped.indent;
|
|
130
|
+
if (typeof mapped.bottom === "number") data.mdiBottom = mapped.bottom;
|
|
131
|
+
delete mapped.indent;
|
|
132
|
+
delete mapped.bottom;
|
|
133
|
+
if (Object.keys(data).length) mapped.data = data;
|
|
134
|
+
return mapped;
|
|
135
|
+
}
|
|
136
|
+
default:
|
|
137
|
+
return mapped;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function publicationFrontmatter(raw) {
|
|
141
|
+
let value;
|
|
142
|
+
try {
|
|
143
|
+
value = parseYaml(raw);
|
|
144
|
+
} catch {
|
|
145
|
+
value = void 0;
|
|
146
|
+
}
|
|
147
|
+
const source = isRecord(value) ? value : {};
|
|
148
|
+
const writingMode = source["writing-mode"] === "vertical" ? "vertical" : "horizontal";
|
|
149
|
+
return {
|
|
150
|
+
mdi: stringValue(source.mdi) ?? "2.0",
|
|
151
|
+
title: stringValue(source.title),
|
|
152
|
+
author: stringValue(source.author),
|
|
153
|
+
lang: stringValue(source.lang) ?? "ja",
|
|
154
|
+
date: stringValue(source.date),
|
|
155
|
+
writingMode,
|
|
156
|
+
pageProgression: source["page-progression"] === "ltr" || source["page-progression"] === "rtl" ? source["page-progression"] : writingMode === "vertical" ? "rtl" : "ltr"
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
function isRecord(value) {
|
|
160
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
161
|
+
}
|
|
162
|
+
function stringValue(value) {
|
|
163
|
+
return typeof value === "string" ? value : void 0;
|
|
164
|
+
}
|
|
165
|
+
function renderWithDiagnostics(source, render) {
|
|
166
|
+
const parsed = parse(source);
|
|
167
|
+
return {
|
|
168
|
+
output: render(),
|
|
169
|
+
document: parsed.document,
|
|
170
|
+
diagnostics: parsed.diagnostics,
|
|
171
|
+
headings: headingsFromDocument(parsed.document)
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
async function renderWithDiagnosticsAsync(source, render) {
|
|
175
|
+
const parsed = parse(source);
|
|
176
|
+
return {
|
|
177
|
+
output: await render(),
|
|
178
|
+
document: parsed.document,
|
|
179
|
+
diagnostics: parsed.diagnostics,
|
|
180
|
+
headings: headingsFromDocument(parsed.document)
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
function assertSource(source) {
|
|
184
|
+
if (typeof source !== "string") throw new TypeError("source must be a string");
|
|
185
|
+
}
|
|
186
|
+
function assertHtmlOptions(options) {
|
|
187
|
+
if (options === void 0) return;
|
|
188
|
+
assertPlainObject(options, "options");
|
|
189
|
+
if (options.bodyOnly !== void 0 && typeof options.bodyOnly !== "boolean") {
|
|
190
|
+
throw new TypeError("options.bodyOnly must be a boolean");
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
function htmlBody(html) {
|
|
194
|
+
const match = /<body(?:\s[^>]*)?>([\s\S]*)<\/body>/i.exec(html);
|
|
195
|
+
if (!match) throw new Error("Rust HTML renderer returned a document without a body");
|
|
196
|
+
return match[1];
|
|
197
|
+
}
|
|
198
|
+
function headingsFromDocument(document) {
|
|
199
|
+
const headings = [];
|
|
200
|
+
visitNodes(document.children, (node) => {
|
|
201
|
+
if (node.type !== "heading" || !isHeadingDepth(node.depth)) return;
|
|
202
|
+
headings.push({
|
|
203
|
+
depth: node.depth,
|
|
204
|
+
text: plainNodeText(node),
|
|
205
|
+
span: node.span,
|
|
206
|
+
node
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
return headings;
|
|
210
|
+
}
|
|
211
|
+
function visitNodes(nodes, visit) {
|
|
212
|
+
for (const node of nodes) {
|
|
213
|
+
visit(node);
|
|
214
|
+
if (node.children) visitNodes(node.children, visit);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
function isHeadingDepth(value) {
|
|
218
|
+
return typeof value === "number" && Number.isInteger(value) && value >= 1 && value <= 6;
|
|
219
|
+
}
|
|
220
|
+
function plainNodeText(node) {
|
|
221
|
+
if (node.type === "ruby" && typeof node.base === "string") return node.base;
|
|
222
|
+
const value = node.value;
|
|
223
|
+
const ownText = typeof value === "string" ? value : "";
|
|
224
|
+
return ownText + (node.children?.map(plainNodeText).join("") ?? "");
|
|
225
|
+
}
|
|
226
|
+
function assertPlainObject(value, label) {
|
|
227
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
228
|
+
throw new TypeError(`${label} must be an object`);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
function assertEpubOptions(options) {
|
|
232
|
+
assertPlainObject(options, "options");
|
|
233
|
+
if (options.cover !== void 0) {
|
|
234
|
+
assertPlainObject(options.cover, "options.cover");
|
|
235
|
+
if (!(options.cover.data instanceof Uint8Array)) {
|
|
236
|
+
throw new TypeError("options.cover.data must be a Uint8Array");
|
|
237
|
+
}
|
|
238
|
+
if (options.cover.mediaType !== "image/jpeg" && options.cover.mediaType !== "image/png") {
|
|
239
|
+
throw new TypeError("options.cover.mediaType must be image/jpeg or image/png");
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
if (options.coverImage !== void 0 && !(options.coverImage instanceof Uint8Array)) {
|
|
243
|
+
throw new TypeError("options.coverImage must be a Uint8Array");
|
|
244
|
+
}
|
|
245
|
+
if (options.coverMediaType !== void 0 && options.coverMediaType !== "image/jpeg" && options.coverMediaType !== "image/png") {
|
|
246
|
+
throw new TypeError("options.coverMediaType must be image/jpeg or image/png");
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
function normalizeEpubOptions(options) {
|
|
250
|
+
const {
|
|
251
|
+
title,
|
|
252
|
+
author,
|
|
253
|
+
publisher,
|
|
254
|
+
identifier,
|
|
255
|
+
language,
|
|
256
|
+
date,
|
|
257
|
+
verticalWriting,
|
|
258
|
+
fontFamily,
|
|
259
|
+
fontSize,
|
|
260
|
+
lineSpacing,
|
|
261
|
+
textIndent,
|
|
262
|
+
fullwidthSpaceIndent,
|
|
263
|
+
gridMode,
|
|
264
|
+
chapterSplitLevel,
|
|
265
|
+
coverImage,
|
|
266
|
+
coverMediaType,
|
|
267
|
+
cover,
|
|
268
|
+
profile
|
|
269
|
+
} = options;
|
|
270
|
+
const metadata = { ...profile?.metadata, ...defined({ title, author, publisher, identifier, language, date }) };
|
|
271
|
+
const writingMode = verticalWriting === void 0 ? void 0 : verticalWriting ? "vertical" : "horizontal";
|
|
272
|
+
const typesetting = {
|
|
273
|
+
...profile?.typesetting,
|
|
274
|
+
...defined({
|
|
275
|
+
writingMode,
|
|
276
|
+
fontFamily,
|
|
277
|
+
fontSize,
|
|
278
|
+
lineSpacing,
|
|
279
|
+
textIndentEm: textIndent,
|
|
280
|
+
fullwidthSpaceIndent
|
|
281
|
+
})
|
|
282
|
+
};
|
|
283
|
+
const epub = { ...profile?.epub, ...defined({ chapterSplitLevel }) };
|
|
284
|
+
return {
|
|
285
|
+
profile: {
|
|
286
|
+
...profile,
|
|
287
|
+
metadata,
|
|
288
|
+
typesetting,
|
|
289
|
+
epub,
|
|
290
|
+
pagination: { ...profile?.pagination, ...defined({ gridMode }) }
|
|
291
|
+
},
|
|
292
|
+
cover: cover ?? (coverImage ? { data: coverImage, mediaType: coverMediaType ?? "image/png" } : void 0)
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
function normalizeDocxProfile(profile) {
|
|
296
|
+
const {
|
|
297
|
+
title,
|
|
298
|
+
author,
|
|
299
|
+
publisher,
|
|
300
|
+
identifier,
|
|
301
|
+
language,
|
|
302
|
+
date,
|
|
303
|
+
verticalWriting,
|
|
304
|
+
fontFamily,
|
|
305
|
+
fontSize,
|
|
306
|
+
lineSpacing,
|
|
307
|
+
textIndent,
|
|
308
|
+
pageSize,
|
|
309
|
+
landscape,
|
|
310
|
+
gridMode,
|
|
311
|
+
charactersPerLine,
|
|
312
|
+
linesPerPage,
|
|
313
|
+
margins,
|
|
314
|
+
fullwidthSpaceIndent,
|
|
315
|
+
showPageNumbers,
|
|
316
|
+
pageNumberPosition,
|
|
317
|
+
pageNumberFormat,
|
|
318
|
+
...nested
|
|
319
|
+
} = profile;
|
|
320
|
+
const writingMode = verticalWriting === void 0 ? void 0 : verticalWriting ? "vertical" : "horizontal";
|
|
321
|
+
return {
|
|
322
|
+
...nested,
|
|
323
|
+
metadata: { ...nested.metadata, ...defined({ title, author, publisher, identifier, language, date }) },
|
|
324
|
+
typesetting: {
|
|
325
|
+
...nested.typesetting,
|
|
326
|
+
...defined({ writingMode, fontFamily, fontSize, lineSpacing, textIndentEm: textIndent, fullwidthSpaceIndent })
|
|
327
|
+
},
|
|
328
|
+
pagination: {
|
|
329
|
+
...nested.pagination,
|
|
330
|
+
...defined({ pageSize, landscape, gridMode, charactersPerLine, linesPerPage, margins }),
|
|
331
|
+
pageNumbers: {
|
|
332
|
+
...nested.pagination?.pageNumbers,
|
|
333
|
+
...defined({ enabled: showPageNumbers, position: pageNumberPosition, format: pageNumberFormat })
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
function defined(value) {
|
|
339
|
+
return Object.fromEntries(Object.entries(value).filter(([, item]) => item !== void 0));
|
|
340
|
+
}
|
|
341
|
+
function serializeMdi(source) {
|
|
342
|
+
if (typeof source !== "string") throw new TypeError("source must be a string");
|
|
343
|
+
return serializeMdiFromRust(source);
|
|
344
|
+
}
|
|
345
|
+
function renderText(source) {
|
|
346
|
+
if (typeof source !== "string") throw new TypeError("source must be a string");
|
|
347
|
+
return renderTextFromRust(source);
|
|
348
|
+
}
|
|
349
|
+
function renderTextWithDiagnostics(source) {
|
|
350
|
+
return renderWithDiagnostics(source, () => renderText(source));
|
|
351
|
+
}
|
|
352
|
+
function renderTextFormat(source, format, indentPrefix = "") {
|
|
353
|
+
if (typeof source !== "string" || typeof indentPrefix !== "string") {
|
|
354
|
+
throw new TypeError("source and indentPrefix must be strings");
|
|
355
|
+
}
|
|
356
|
+
return renderTextFormatFromRust(source, format, indentPrefix);
|
|
357
|
+
}
|
|
358
|
+
function renderTextFormatWithDiagnostics(source, format, indentPrefix = "") {
|
|
359
|
+
return renderWithDiagnostics(source, () => renderTextFormat(source, format, indentPrefix));
|
|
360
|
+
}
|
|
361
|
+
var parseMdiSyntax = parse;
|
|
362
|
+
|
|
363
|
+
export {
|
|
364
|
+
MDI_SPEC_VERSION,
|
|
365
|
+
MDI_IR_VERSION,
|
|
366
|
+
parse,
|
|
367
|
+
renderHtml,
|
|
368
|
+
renderHtmlWithDiagnostics,
|
|
369
|
+
prepareRender,
|
|
370
|
+
renderEpub,
|
|
371
|
+
renderEpubWithDiagnostics,
|
|
372
|
+
renderDocx,
|
|
373
|
+
renderDocxWithDiagnostics,
|
|
374
|
+
renderEpubWithProfile,
|
|
375
|
+
renderDocxWithProfile,
|
|
376
|
+
toPublicationMdast,
|
|
377
|
+
serializeMdi,
|
|
378
|
+
renderText,
|
|
379
|
+
renderTextWithDiagnostics,
|
|
380
|
+
renderTextFormat,
|
|
381
|
+
renderTextFormatWithDiagnostics,
|
|
382
|
+
parseMdiSyntax
|
|
383
|
+
};
|