MDI とは?
前提知識: なし。このページは MDI の知識がないことを前提にしていますが、通常の Markdown(# 見出し、*強調*、[リンク](url))は既に知っているものとします。
MDI とは?
Section titled “MDI とは?”MDI(illusion Markdown、拡張子 .mdi)は、日本語組版のための拡張構文をいくつか加えた、ふつうの Markdown です。ルビ(振り仮名)、縦中横(縦書き中の数字を横向きに組む)、傍点(圏点による強調)、割注(行内の二行組注記)、明示的な改行、改ページ、ブロック指定、縦書きなどを追加します。
通常の Markdown 文書はすべて、そのまま有効な MDI 文書でもあります。MDI は構文を追加するだけで、CommonMark や GFM の何かを取り除いたり意味を変えたりしません。.mdi ファイルは通常の UTF-8 テキストファイルであり、バイト列としては .md ファイルと何ら変わりません。拡張子は単なる慣習であり、パーサーがそれを検査するわけではありません。
---mdi: "2.0"title: 雪女lang: jawriting-mode: vertical---
# 第一章
{雪女|ゆきおんな}が現れたのは、第^12^話のことだった。[[em:決して]]忘れない、と彼は思った。この例からフロントマターと {...}/^...^/`…` の記法を取り除けば、ごく普通の Markdown 文書になります。これが MDI の設計そのものです。MDI は Markdown に、フォールバックする(一致しない場合は無視されるかリテラルになる)組版拡張を足したものです。
MDI が存在する理由
Section titled “MDI が存在する理由”日本の小説、特にライトノベルやウェブ小説は、CommonMark にも GFM にも Pandoc Markdown にも記法が存在しない組版上の工夫に依存しています。
- 漢字だけでは曖昧・不慣れなため、読み仮名を文字の上や脇に添える必要がある(ルビ)――
{東京|とうきょう}。 - 縦書きの中で、数個の算用数字を1文字ずつ縦に積むのではなく横向きに直立させたい(縦中横)――
第^12^話。 - 日本語の組版はイタリックで強調しないため、文字の脇に圏点を打って強調したい ―― `それ`。
- 脚注ではなく、行の中に二行組の注記を挟みたい ―― `注記`。
- 文書全体を横書きではなく縦書き・右から左(縦書き)で組みたい。
既存のツールはこれらを場当たり的に解決してきました。一部の投稿プラットフォーム(カクヨム、なろう)は独自の括弧記法を発明し、一部のエディタは共有された文法のない独自の Markdown 拡張を後付けしています。MDI が提供するのは、単一の仕様(SYNTAX.md)と単一の実行可能な実装(mdi-core Rust クレート)です。これにより、同じ .mdi ファイルはどのツールで開いても ―― エディタでも、CLI でも、Web アプリでも、出版パイプラインでも ―― 同じように解析されます。
MDI と通常の Markdown
Section titled “MDI と通常の Markdown”| 通常の Markdown(CommonMark/GFM) | MDI | |
|---|---|---|
| 見出し・リスト・リンク・表・コードフェンス・強調 | あり | あり、変更なし |
フロントマター(--- ... ---) | CommonMark の一部ではなく、ツール依存 | あり。MDI 固有のキー(writing-mode、page-progression)を追加 |
| ルビ・縦中横・傍点・割注・字間調整 | 記法なし | あり |
| 明示的な改行 vs 段落改行 | 末尾2スペースの壊れやすいハードブレークのみ | [[br]](曖昧さなし) vs 空行 |
| 縦書き | 概念がない | フロントマターの属性。複数の構文の描画方法に影響するため |
| どの構文が有効かを決めるのは誰か | 使用しているライブラリ次第 | 単一の仕様(SYNTAX.md)、単一の実装(mdi-core) |
MDI 固有の構文を含まない .md ファイルと .mdi ファイルは、まったく同じように描画されます。違いが現れるのは MDI 固有の記法を使ったときだけです ―― しかもそのときでさえ、無効・曖昧な MDI 記法は文書を壊さずリテラルテキストへフォールバックするよう設計されています(各構文ページの「よくある間違い」節に正確なフォールバック規則があります)。
ソースから出力までの全体パイプライン
Section titled “ソースから出力までの全体パイプライン”言語に関わらず、すべての MDI ツールが従う唯一の流れです。
.mdi ソース(UTF-8 テキスト) │ ▼ mdi-core(Rust)── CommonMark + GFM + フロントマター + MDI を一度に解析 │ ▼バージョン付きドキュメント IR ── タグ付きの木構造。すべてのノードが UTF-8 バイト span を持つ │ ├──▶ renderHtml() → HTML 文字列 ├──▶ renderText(format) → TXT / なろう / カクヨム / 青空文庫 文字列 ├──▶ renderEpub() → EPUB 3 バイト列 ├──▶ renderDocx() → DOCX バイト列 └──▶ renderHtml() + Chromium printToPDF → PDF バイト列2点、注目してください。
- 解析は Rust で一度だけ行われます。 どのレンダラーも元のテキストを読み直したり、ルビの範囲をどこから始めるか再判定したりしません。すべてのレンダラーは
mdi-coreが既に構築した同じ木を消費します。 - PDF は「HTML+印刷ステップ」です。 Rust はブラウザに渡すのと同じ HTML/CSS を描画し、ローカルにインストールされた Chromium 系ブラウザにそのレイアウトと
printToPDFの呼び出しを依頼します。Chromium は.mdiソースを読むことも、構文上の判断をすることも一切ありません ―― 渡された HTML をレイアウトするだけです。Chromium の責務がどこで始まりどこで終わるかは レンダリングモデルと Chromium/PDF の境界 を参照してください。
試してみる:ソース → HTML
Section titled “試してみる:ソース → HTML”以下は実際に今日動く @illusions-lab/mdi の JavaScript API です。
import { parse, renderHtml } from "@illusions-lab/mdi";
const source = "{雪女|ゆきおんな}が第^12^話に現れた。";
const { document, diagnostics } = parse(source);console.log(diagnostics); // [] ―― このソースには問題なしconsole.log(document.children[0]); // 解析済みの段落ノード。MDI のルビ/縦中横を含む
console.log(renderHtml(source));<!DOCTYPE html><html lang="ja"><head><meta charset="utf-8"><style>/* Rust がマークアップと一緒に出力する .mdi-* スタイルシート */</style></head><body><p><ruby class="mdi-ruby">雪女<rp>(</rp><rt>ゆきおんな</rt><rp>)</rp></ruby>が第<span class="mdi-tcy">12</span>話に現れた。</p></body></html>自分で CLI と JavaScript パッケージをインストールして実行する手順は はじめに にあります。
どんなときに MDI を使うべきか
Section titled “どんなときに MDI を使うべきか”- ルビ・縦書き・圏点強調が必要な日本語の小説(ライトノベル、ウェブ小説、脚本)をプレーンテキストで、バージョン管理しやすいソース形式で書きたいとき。
- 1つのソースファイルから、HTML(Web リーダー向け)、EPUB(電子書籍リーダー向け)、DOCX(出版社向け)、プレーンテキスト(なろうやカクヨムなど特定プラットフォームへの投稿用)を、各出力を手作業で編集せずに得たいとき。
- 同じソースがエディタでも、ビルドパイプラインでも、CLI でも同じように解析される保証がほしいとき ―― 3つの異なる再実装ではなく、3つとも同じ Rust コードを呼び出しているからです。
MDI が ではないもの
Section titled “MDI が ではないもの”- ワープロや WYSIWYG 形式ではありません。 MDI はソース記法であり、DOCX/PDF 出力はその描画結果であって、逆ではありません。
- 汎用の組版言語ではありません。
SYNTAX.mdに列挙された、名前の付いた日本語組版の仕組みをカバーするだけで、構文自体に「任意の CSS プロパティ」という汎用エスケープハッチはありません。 - 対応プラットフォームで利用できます。 Rust、Node.js、Swift、Kotlin、Python はすべて同じ Rust-authoritative grammar と Document IR を利用します。各プラットフォームは Bindings を参照してください。
次のステップ
Section titled “次のステップ”- コア概念 ―― IR・診断・span・capabilities など、他のすべてのページで使う語彙。
- はじめに ―― CLI と JavaScript パッケージをインストールし、最初の変換を実行します。
- 完全構文リファレンス ―― すべての MDI 構文を1つずつ解説します。