@illusions-lab/mdi 2.0.3

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 ADDED
@@ -0,0 +1,83 @@
1
+ # `@illusions-lab/mdi`
2
+
3
+ The JavaScript interface to the Rust-authoritative MDI engine. Give it a
4
+ complete `.mdi` source document and it returns the versioned document IR and
5
+ diagnostics produced by `mdi-core`.
6
+
7
+ ```ts
8
+ import { parse } from "@illusions-lab/mdi";
9
+
10
+ const result = parse(`---
11
+ title: 短篇
12
+ ---
13
+
14
+ # 第一章
15
+
16
+ 第^12^話に[[em:傍点]]を付ける。`);
17
+
18
+ console.log(result.document);
19
+ console.log(result.diagnostics);
20
+ ```
21
+
22
+ ## What the binding does
23
+
24
+ The package has deliberately narrow responsibilities:
25
+
26
+ 1. accept JavaScript strings, byte arrays, and options;
27
+ 2. call `mdi-core` through the generated Rust binding;
28
+ 3. check the returned IR schema version;
29
+ 4. expose typed JavaScript objects, diagnostics, and renderer results.
30
+
31
+ It does not tokenize Markdown or MDI, repair malformed syntax, reinterpret
32
+ source spans, or maintain a JavaScript copy of the grammar. CommonMark, GFM,
33
+ front matter, MDI extensions, escapes, nesting, literal fallback, and all
34
+ syntax validation are decided by Rust.
35
+
36
+ ```text
37
+ complete source
38
+
39
+ JavaScript binding
40
+
41
+ mdi-core parser
42
+
43
+ versioned document IR + diagnostics
44
+ ```
45
+
46
+ ## Parse result
47
+
48
+ Every result carries the syntax version and IR schema version alongside the
49
+ document. Source-backed nodes use half-open UTF-8 byte spans. Recoverable
50
+ problems are returned as ordered diagnostics with stable codes, severity,
51
+ messages, and source spans.
52
+
53
+ Applications should treat the IR version as a wire-protocol version. They
54
+ must not infer grammar rules from object shapes or silently accept an
55
+ unsupported version.
56
+
57
+ ## Rendering
58
+
59
+ Rendering starts from the same Rust IR. Canonical MDI, plain text, HTML, EPUB,
60
+ and DOCX renderers execute in Rust and are exposed through this package. PDF
61
+ uses Rust HTML as its input to a host layout adapter such as
62
+ `@illusions-lab/mdi-to-pdf`; the adapter may control Chromium, but it never
63
+ parses MDI or produces semantic HTML.
64
+
65
+ Browser WebAssembly cannot start Chromium. Browser code sends Rust-rendered
66
+ HTML to a server or desktop host when it needs PDF output.
67
+
68
+ ## Remark compatibility
69
+
70
+ Remark support is an optional adapter between Rust IR and mdast. It exists for
71
+ applications that need unified plugins:
72
+
73
+ ```text
74
+ source → mdi-core → Rust IR ⇄ mdast → unified plugins
75
+ ```
76
+
77
+ The adapter contains no tokenizer, grammar, or syntax fallback. When an mdast
78
+ pipeline needs MDI output, it is converted back to Rust IR and Rust performs
79
+ validation and serialization.
80
+
81
+ The normative human-readable syntax is defined in
82
+ [`SYNTAX.md`](https://github.com/illusions-lab/MDI/blob/main/SYNTAX.md). The
83
+ executable syntax authority is `mdi-core`.
package/dist/index.cjs ADDED
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ MDI_IR_VERSION: () => MDI_IR_VERSION,
24
+ MDI_SPEC_VERSION: () => MDI_SPEC_VERSION,
25
+ parse: () => parse,
26
+ parseMdiSyntax: () => parseMdiSyntax,
27
+ renderDocx: () => renderDocx,
28
+ renderEpub: () => renderEpub,
29
+ renderHtml: () => renderHtml,
30
+ renderText: () => renderText,
31
+ renderTextFormat: () => renderTextFormat,
32
+ serializeMdi: () => serializeMdi
33
+ });
34
+ module.exports = __toCommonJS(index_exports);
35
+ var import_mdi_core = require("@illusions-lab/mdi-core");
36
+ var MDI_SPEC_VERSION = "2.0";
37
+ var MDI_IR_VERSION = "1.0";
38
+ function parse(source) {
39
+ if (typeof source !== "string") throw new TypeError("source must be a string");
40
+ const result = JSON.parse((0, import_mdi_core.parseMdiSyntaxJson)(source));
41
+ if (result.irVersion !== MDI_IR_VERSION) {
42
+ throw new Error(`Unsupported MDI IR version: ${String(result.irVersion)}`);
43
+ }
44
+ return result;
45
+ }
46
+ function renderHtml(source) {
47
+ if (typeof source !== "string") throw new TypeError("source must be a string");
48
+ return (0, import_mdi_core.renderHtml)(source);
49
+ }
50
+ function renderEpub(source) {
51
+ if (typeof source !== "string") throw new TypeError("source must be a string");
52
+ return (0, import_mdi_core.renderEpub)(source);
53
+ }
54
+ function renderDocx(source) {
55
+ if (typeof source !== "string") throw new TypeError("source must be a string");
56
+ return (0, import_mdi_core.renderDocx)(source);
57
+ }
58
+ function serializeMdi(source) {
59
+ if (typeof source !== "string") throw new TypeError("source must be a string");
60
+ return (0, import_mdi_core.serializeMdi)(source);
61
+ }
62
+ function renderText(source) {
63
+ if (typeof source !== "string") throw new TypeError("source must be a string");
64
+ return (0, import_mdi_core.renderText)(source);
65
+ }
66
+ function renderTextFormat(source, format, indentPrefix = "") {
67
+ if (typeof source !== "string" || typeof indentPrefix !== "string") {
68
+ throw new TypeError("source and indentPrefix must be strings");
69
+ }
70
+ return (0, import_mdi_core.renderTextFormat)(source, format, indentPrefix);
71
+ }
72
+ var parseMdiSyntax = parse;
73
+ // Annotate the CommonJS export names for ESM import in node:
74
+ 0 && (module.exports = {
75
+ MDI_IR_VERSION,
76
+ MDI_SPEC_VERSION,
77
+ parse,
78
+ parseMdiSyntax,
79
+ renderDocx,
80
+ renderEpub,
81
+ renderHtml,
82
+ renderText,
83
+ renderTextFormat,
84
+ serializeMdi
85
+ });
@@ -0,0 +1,87 @@
1
+ /** MDI specification version implemented by this binding. */
2
+ declare const MDI_SPEC_VERSION: "2.0";
3
+ /** Version of the complete Rust-owned document IR. */
4
+ declare const MDI_IR_VERSION: "1.0";
5
+ interface MdiParserCapabilities {
6
+ mdi: boolean;
7
+ commonMark: boolean;
8
+ gfm: boolean;
9
+ frontMatter: boolean;
10
+ sourceSpans: boolean;
11
+ }
12
+ interface MdiSourceSpan {
13
+ /** Inclusive UTF-8 byte offset. */
14
+ startByte: number;
15
+ /** Exclusive UTF-8 byte offset. */
16
+ endByte: number;
17
+ }
18
+ interface MdiDiagnostic {
19
+ severity: "warning" | "error";
20
+ code: string;
21
+ message: string;
22
+ span?: MdiSourceSpan;
23
+ }
24
+ type MdiRubyReading = {
25
+ type: "group";
26
+ value: string;
27
+ } | {
28
+ type: "split";
29
+ value: string[];
30
+ };
31
+ /** A tagged CommonMark, GFM, or MDI node produced by Rust. */
32
+ interface MdiNode {
33
+ type: string;
34
+ span?: MdiSourceSpan;
35
+ children?: MdiNode[];
36
+ [key: string]: unknown;
37
+ }
38
+ interface MdiFrontmatter {
39
+ span: MdiSourceSpan;
40
+ raw: string;
41
+ entries: Array<{
42
+ key: string;
43
+ value: unknown;
44
+ }>;
45
+ }
46
+ interface MdiDocument {
47
+ span: MdiSourceSpan;
48
+ frontmatter?: MdiFrontmatter;
49
+ children: MdiNode[];
50
+ }
51
+ /**
52
+ * Versioned result returned by the Rust parser.
53
+ *
54
+ * Capability flags describe the grammar and source information included in
55
+ * this complete Rust-owned document tree.
56
+ */
57
+ interface MdiSyntaxParseResult {
58
+ irVersion: typeof MDI_IR_VERSION;
59
+ syntaxVersion: typeof MDI_SPEC_VERSION;
60
+ capabilities: MdiParserCapabilities;
61
+ document: MdiDocument;
62
+ diagnostics: MdiDiagnostic[];
63
+ }
64
+ /** @deprecated Use {@link MdiDocument}. */
65
+ type MdiSyntaxDocument = MdiDocument;
66
+ /**
67
+ * Parse the complete `.mdi` source in Rust and return the versioned
68
+ * language-neutral document IR. JavaScript performs no grammar work.
69
+ */
70
+ declare function parse(source: string): MdiSyntaxParseResult;
71
+ /** Render complete `.mdi` source to standalone HTML in Rust. */
72
+ declare function renderHtml(source: string): string;
73
+ /** Build a baseline EPUB 3 archive from complete source in Rust. */
74
+ declare function renderEpub(source: string): Uint8Array;
75
+ /** Build a baseline DOCX archive from complete source in Rust. */
76
+ declare function renderDocx(source: string): Uint8Array;
77
+ /** Parse and normalize complete `.mdi` source with Rust's serializer. */
78
+ declare function serializeMdi(source: string): string;
79
+ /** Render complete `.mdi` source to deterministic plain text in Rust. */
80
+ declare function renderText(source: string): string;
81
+ type MdiTextFormat = "txt" | "txt-ruby" | "narou" | "kakuyomu" | "aozora";
82
+ /** Render a named publication-text convention through Rust. */
83
+ declare function renderTextFormat(source: string, format: MdiTextFormat, indentPrefix?: string): string;
84
+ /** @deprecated Use {@link parse}; it now parses the complete document. */
85
+ declare const parseMdiSyntax: typeof parse;
86
+
87
+ export { MDI_IR_VERSION, MDI_SPEC_VERSION, type MdiDiagnostic, type MdiDocument, type MdiFrontmatter, type MdiNode, type MdiParserCapabilities, type MdiRubyReading, type MdiSourceSpan, type MdiSyntaxDocument, type MdiSyntaxParseResult, type MdiTextFormat, parse, parseMdiSyntax, renderDocx, renderEpub, renderHtml, renderText, renderTextFormat, serializeMdi };
@@ -0,0 +1,87 @@
1
+ /** MDI specification version implemented by this binding. */
2
+ declare const MDI_SPEC_VERSION: "2.0";
3
+ /** Version of the complete Rust-owned document IR. */
4
+ declare const MDI_IR_VERSION: "1.0";
5
+ interface MdiParserCapabilities {
6
+ mdi: boolean;
7
+ commonMark: boolean;
8
+ gfm: boolean;
9
+ frontMatter: boolean;
10
+ sourceSpans: boolean;
11
+ }
12
+ interface MdiSourceSpan {
13
+ /** Inclusive UTF-8 byte offset. */
14
+ startByte: number;
15
+ /** Exclusive UTF-8 byte offset. */
16
+ endByte: number;
17
+ }
18
+ interface MdiDiagnostic {
19
+ severity: "warning" | "error";
20
+ code: string;
21
+ message: string;
22
+ span?: MdiSourceSpan;
23
+ }
24
+ type MdiRubyReading = {
25
+ type: "group";
26
+ value: string;
27
+ } | {
28
+ type: "split";
29
+ value: string[];
30
+ };
31
+ /** A tagged CommonMark, GFM, or MDI node produced by Rust. */
32
+ interface MdiNode {
33
+ type: string;
34
+ span?: MdiSourceSpan;
35
+ children?: MdiNode[];
36
+ [key: string]: unknown;
37
+ }
38
+ interface MdiFrontmatter {
39
+ span: MdiSourceSpan;
40
+ raw: string;
41
+ entries: Array<{
42
+ key: string;
43
+ value: unknown;
44
+ }>;
45
+ }
46
+ interface MdiDocument {
47
+ span: MdiSourceSpan;
48
+ frontmatter?: MdiFrontmatter;
49
+ children: MdiNode[];
50
+ }
51
+ /**
52
+ * Versioned result returned by the Rust parser.
53
+ *
54
+ * Capability flags describe the grammar and source information included in
55
+ * this complete Rust-owned document tree.
56
+ */
57
+ interface MdiSyntaxParseResult {
58
+ irVersion: typeof MDI_IR_VERSION;
59
+ syntaxVersion: typeof MDI_SPEC_VERSION;
60
+ capabilities: MdiParserCapabilities;
61
+ document: MdiDocument;
62
+ diagnostics: MdiDiagnostic[];
63
+ }
64
+ /** @deprecated Use {@link MdiDocument}. */
65
+ type MdiSyntaxDocument = MdiDocument;
66
+ /**
67
+ * Parse the complete `.mdi` source in Rust and return the versioned
68
+ * language-neutral document IR. JavaScript performs no grammar work.
69
+ */
70
+ declare function parse(source: string): MdiSyntaxParseResult;
71
+ /** Render complete `.mdi` source to standalone HTML in Rust. */
72
+ declare function renderHtml(source: string): string;
73
+ /** Build a baseline EPUB 3 archive from complete source in Rust. */
74
+ declare function renderEpub(source: string): Uint8Array;
75
+ /** Build a baseline DOCX archive from complete source in Rust. */
76
+ declare function renderDocx(source: string): Uint8Array;
77
+ /** Parse and normalize complete `.mdi` source with Rust's serializer. */
78
+ declare function serializeMdi(source: string): string;
79
+ /** Render complete `.mdi` source to deterministic plain text in Rust. */
80
+ declare function renderText(source: string): string;
81
+ type MdiTextFormat = "txt" | "txt-ruby" | "narou" | "kakuyomu" | "aozora";
82
+ /** Render a named publication-text convention through Rust. */
83
+ declare function renderTextFormat(source: string, format: MdiTextFormat, indentPrefix?: string): string;
84
+ /** @deprecated Use {@link parse}; it now parses the complete document. */
85
+ declare const parseMdiSyntax: typeof parse;
86
+
87
+ export { MDI_IR_VERSION, MDI_SPEC_VERSION, type MdiDiagnostic, type MdiDocument, type MdiFrontmatter, type MdiNode, type MdiParserCapabilities, type MdiRubyReading, type MdiSourceSpan, type MdiSyntaxDocument, type MdiSyntaxParseResult, type MdiTextFormat, parse, parseMdiSyntax, renderDocx, renderEpub, renderHtml, renderText, renderTextFormat, serializeMdi };
package/dist/index.js ADDED
@@ -0,0 +1,59 @@
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
+ var MDI_SPEC_VERSION = "2.0";
12
+ var MDI_IR_VERSION = "1.0";
13
+ function parse(source) {
14
+ if (typeof source !== "string") throw new TypeError("source must be a string");
15
+ const result = JSON.parse(parseMdiSyntaxJson(source));
16
+ if (result.irVersion !== MDI_IR_VERSION) {
17
+ throw new Error(`Unsupported MDI IR version: ${String(result.irVersion)}`);
18
+ }
19
+ return result;
20
+ }
21
+ function renderHtml(source) {
22
+ if (typeof source !== "string") throw new TypeError("source must be a string");
23
+ return renderHtmlFromRust(source);
24
+ }
25
+ function renderEpub(source) {
26
+ if (typeof source !== "string") throw new TypeError("source must be a string");
27
+ return renderEpubFromRust(source);
28
+ }
29
+ function renderDocx(source) {
30
+ if (typeof source !== "string") throw new TypeError("source must be a string");
31
+ return renderDocxFromRust(source);
32
+ }
33
+ function serializeMdi(source) {
34
+ if (typeof source !== "string") throw new TypeError("source must be a string");
35
+ return serializeMdiFromRust(source);
36
+ }
37
+ function renderText(source) {
38
+ if (typeof source !== "string") throw new TypeError("source must be a string");
39
+ return renderTextFromRust(source);
40
+ }
41
+ function renderTextFormat(source, format, indentPrefix = "") {
42
+ if (typeof source !== "string" || typeof indentPrefix !== "string") {
43
+ throw new TypeError("source and indentPrefix must be strings");
44
+ }
45
+ return renderTextFormatFromRust(source, format, indentPrefix);
46
+ }
47
+ var parseMdiSyntax = parse;
48
+ export {
49
+ MDI_IR_VERSION,
50
+ MDI_SPEC_VERSION,
51
+ parse,
52
+ parseMdiSyntax,
53
+ renderDocx,
54
+ renderEpub,
55
+ renderHtml,
56
+ renderText,
57
+ renderTextFormat,
58
+ serializeMdi
59
+ };
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@illusions-lab/mdi",
3
+ "version": "2.0.3",
4
+ "description": "Thin JavaScript binding for the Rust-authoritative MDI parser",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/illusions-lab/MDI.git",
9
+ "directory": "nodejs/packages/mdi"
10
+ },
11
+ "homepage": "https://mdi.illusions.app/",
12
+ "bugs": "https://github.com/illusions-lab/MDI/issues",
13
+ "type": "module",
14
+ "main": "./dist/index.js",
15
+ "types": "./dist/index.d.ts",
16
+ "exports": {
17
+ ".": {
18
+ "types": "./dist/index.d.ts",
19
+ "default": "./dist/index.js"
20
+ }
21
+ },
22
+ "files": [
23
+ "dist"
24
+ ],
25
+ "dependencies": {
26
+ "@illusions-lab/mdi-core": "2.0.3"
27
+ },
28
+ "devDependencies": {
29
+ "tsup": "^8.3.0",
30
+ "typescript": "^5.6.0",
31
+ "vitest": "^2.1.0"
32
+ },
33
+ "scripts": {
34
+ "build": "tsup src/index.ts --format esm,cjs --dts",
35
+ "test": "vitest run --passWithNoTests",
36
+ "typecheck": "tsc --noEmit"
37
+ }
38
+ }