コンテンツにスキップ

JavaScript / TypeScript

前提: Getting StartedDocument IR

Terminal window
npm install @illusions-lab/mdi

この package は mdi-core を prebuilt WASM として実行します。Node.js と WASM import 対応 bundler で動き、利用側で native build は不要です。editor/export UI ではまず parse() して warning と span を表示します。

import { parse, renderHtmlWithDiagnostics } from "@illusions-lab/mdi";
const source = "# 第一章\n{東京|とうきょう}は雨だった。";
const parsed = parse(source);
if (parsed.diagnostics.some((item) => item.severity === "error")) {
// code と UTF-8 byte span を editor に表示する
}
const result = renderHtmlWithDiagnostics(source, { bodyOnly: true });
console.log(result.output); // <body> の semantic contents
console.log(result.headings); // depth、text、span を持つ source-order headings

parse は Rust-owned documentdiagnostics、UTF-8 byte span を返します。現時点で実装済み diagnostic code は mdi.version.unsupported だけです。構文の誤りの多くは throw ではなく literal fallback になります。prepareRender(source) も parse-first 用です。*WithDiagnostics は output と同じ parser result を返しますが、warning を error に変えるものではありません。

renderHtml(source) は MDI stylesheet 付き standalone HTML を返します。app が外側の page を持つなら { bodyOnly: true } を使います。semantic HTML は stable な mdi-rubymdi-tcymdi-emmdi-pagebreak 等の class を付けます。

一引数の API は synchronous Rust baseline export です。

import { renderEpub, renderDocx } from "@illusions-lab/mdi";
await writeFile("book.epub", renderEpub(source));
await writeFile("book.docx", renderDocx(source));

publication 設定が必要なら二引数 overload(または WithProfile)を await します。これは Rust IR を EPUB/DOCX adapter に構造変換するため asynchronous ですが、JavaScript で MDI source を再 parse しません。

const epub = await renderEpub(source, {
profile: { layout: { system: "japanese-publisher" } },
title: "雨の東京", author: "Illusions", language: "ja",
publisher: "Illusions Lab", identifier: "urn:isbn:example", date: "2026-07-21",
verticalWriting: true, fontFamily: "Yu Mincho", textIndent: 1,
chapterSplitLevel: "h1", coverImage: coverBytes, coverMediaType: "image/png",
});
const docx = await renderDocx(source, {
layout: { system: "word" },
title: "雨の東京", author: "Illusions", verticalWriting: true,
fontFamily: "Yu Mincho", fontSize: 11, lineSpacing: 1.6, textIndent: 1,
pagination: { gridMode: "typographic" },
pageSize: "A5", landscape: false,
margins: { top: 18, right: 15, bottom: 18, left: 15 },
showPageNumbers: true, pageNumberPosition: "bottom-center", pageNumberFormat: "simple",
});

EPUB は metadata、縦書き、font、indent、h1/h2/h3/none chapter split、PNG/JPEG Uint8Array cover を扱います。DOCX は metadata、page size/orientation/margin、font/size/line spacing/indent、page number(simple/dash/fraction)を扱います。どちらも full nested ExportProfile も使えます。JSON の全 schema は Export profiles を参照してください。

設定付き export は必ず layout.system を指定します。"japanese-publisher" は mirrored の和文 book 用で、横書きは 10 pt 明朝体の Shirokuban・左綴じ 27 字 × 26 行 strict grid、縦書きは A4 landscape の小説原稿・右綴じ 40 字 × 30 行 strict grid が default です。"word" は Word 形式の flowing page 用で、default は A4、四辺 25.4 mm、mirror なし、gridMode: "typographic" です。"word""strict" を reject します。

Rust が grammar、diagnostic、span、semantic HTML/baseline export を所有します。EPUB/DOCX の profile は publication adapter の責務であり、紙面、Chromium、application UI の選択は host の責務です。DOCX は page break、縦書き、paragraph/run を OOXML に落としますが、ruby、tate-chu-yoko、禁則/改行禁止、kern、強制 blank paragraph を browser HTML と pixel-identical に再現する約束ではありません。重要な組版は対象 Word-compatible reader で確認してください。

import { preparePdfExport, renderPdfWithChromium } from "@illusions-lab/mdi/node";
const request = preparePdfExport(source, profile); // Electron の print API に渡せる
const pdf = await renderPdfWithChromium(source, profile);

Node の default PDF adapter には別途 npm install @illusions-lab/mdi-to-pdf が必要です。Electron は { renderHtmlToPdf(html, profile, sourceWritingMode) } adapter を渡せます。PDF profile は paper、landscape、margin、縦横、font、font size/line spacing、文字数/行数、indent、page number を扱います。browser/WASM は main entry point の baseline renderer を使えますが、設定付き publication adapter と PDF は Node/Electron host workflow です。preparePdfExport() を Node/Electron/Tauri/CLI host に送ります。

非 string source と不正 option は TypeError です。diagnostic は document feedback として扱い、I/O/archive/host renderer の failure だけを try/catch してください。span は JavaScript index ではなく UTF-8 byte offset です。