コンテンツにスキップ

Python

前提: Getting StartedDocument IR

illusion-markdown は PyO3/maturin native extension として同じ mdi-core を呼びます。Python 側に独自 grammar はありません。

Django/Flask の publishing backend、Jupyter を使う manuscript pipeline、Python の static-site generator から、CLI を起動せずに .mdi を解析・描画できます。Python 側の wrapper は約 60 行で、全関数が他の binding と同じ Rust code を直接呼びます。

Terminal window
pip install illusion-markdown

PyPI distribution 名は illusion-markdown、import 名は mdi です。Python 3.10+。macOS、Linux x64、Windows x64 の wheel があり、その他では Rust toolchain を必要とする source distribution に fallback します。

import mdi
source = "# {東京|とうきょう}の夜\n\n第^12^話\n"
result = mdi.parse(source)
print(result["document"]["children"][0]["type"])
open("book.html", "w", encoding="utf-8").write(mdi.render_html(source))
mdi.MDI_SPEC_VERSION; mdi.MDI_IR_VERSION; mdi.TextFormat; mdi.MdiRenderError
mdi.parse(source: str) -> dict
mdi.render_html(source: str) -> str
mdi.render_text(source: str) -> str
mdi.render_text_format(source: str, format, indent_prefix: str = "") -> str
mdi.render_epub(source: str) -> bytes
mdi.render_docx(source: str) -> bytes
mdi.serialize_mdi(source: str) -> str
mdi.parse_mdi_syntax # deprecated alias

parse は typed class や dataclass ではなく、JSON wire format をそのまま decode した dict[str, Any] を返します。key は正確に camelCase です。たとえば result["document"]["children"][0]["type"]、span は startByte/endByte であり start_byte/end_byte ではありません。Document IR の node 一覧をそのまま dict に適用できます。render_epubrender_docxbytes を返すため、"wb" で開いた file に書き込んでください。

不正な MDI 記法は例外ではなく literal fallback と diagnostics で扱います。warning の全一覧は Diagnostics を参照してください。non-string input は PyO3 により TypeError、未知の text format は ValueError、EPUB/DOCX archive writer の実際の失敗だけは mdi.MdiRenderError です。mdi.parse() を diagnostics の代わりに try/except で包まないでください。

mdi.parse(None) # TypeError
mdi.render_text_format("text", "invalid") # ValueError

mdi.parse() は decoded irVersionmdi.MDI_IR_VERSION と照合し、違えば RuntimeError を送出します。返るすべての span は UTF-8 byte offset です。Python の str は code point の列なので、文字 index にするには明示的な変換が必要です。

def byte_span_to_str_index(source: str, byte_offset: int) -> int:
return len(source.encode("utf-8")[:byte_offset].decode("utf-8", errors="ignore"))

Python binding は 実装済み・公開済み・テスト済み です。test suite は IR shape、diagnostic、byte span、六つの text format、EPUB/DOCX archive、ここにある error path を検証し、branch coverage 95% を要求します。

  • PDF function はまだありません。 Python には WASM のような原理的制限はありませんが、現在 mdi.render_pdf は export されていません。Python 隣接 workflow の PDF は CLI を使ってください。
  • 独自 grammar はありません。 CLI/Rust と差があれば短い wrapper か core のバグです。
  • export profile の引数はまだありません。 render_epub/render_docx は現在 source だけを受け取ります。設定付き EPUB/DOCX の実装は既に Rust にあり、Python wrapper が profile と cover の引数をまだ公開していない状態です。

分割規則は Rust が一元管理します。本文の50%の字級、固定2行、行間なしで表示します。先頭の断片には本文行の残り幅、後続には行全体の幅を指定できます。幅の単位は割注字級の半角emです。文字幅の推定であり、比例フォントの厳密な均衡は保証しません。

from mdi import layout_warichu
fragments = layout_warichu([{"type": "text", "value": "一二三四五六"}], 4, first_capacity=2)

戻り値は lineshtmlwidthsoverflowhardBreakAftersources を含みます。path は入力配列からの子インデックス列、startUtf8 / endUtf8 は可視文字列内の半開UTF-8バイト範囲です。同一の group は書式境界をまたぐ書記素も分割しません。ルビ、縦中横、改行禁止は一体として扱います。明示改行を保ち、自動分割は正規MDIや平文に書き戻しません。静的HTML/EPUBは閲覧ソフトにより再配置が異なります。DOCXはネイティブの双行グループを使います。XMLやインポーターの検証をWordの描画実測とは記載しません。