跳到內容

Document IR

先備知識:核心概念

任何 binding 的 parse() 都回傳下列形狀。目前 irVersion"1.0"syntaxVersion"2.0";兩者獨立,理由請見核心概念

{"irVersion":"1.0","syntaxVersion":"2.0","capabilities":{"mdi":true,"commonMark":true,"gfm":true,"frontMatter":true,"sourceSpans":true},"document":{"span":{"startByte":0,"endByte":0},"children":[]},"diagnostics":[]}

每個 capability 目前都是 truemdi-core 一趟解析完整文件並為每個 node 保留 source span。仍應在自己的程式中檢查 capabilities,不要寫死假設;欄位存在的目的就是讓 consumer 不必猜測,舊或未來的結果可合理地有 false

interface MdiDocument { span: MdiSourceSpan; frontmatter?: MdiFrontmatter; children: MdiNode[]; }
interface MdiFrontmatter { span: MdiSourceSpan; raw: string; entries: Array<{ key: string; value: unknown }>; }

frontmatterchildren同層 sibling,不是其內 node;它是文件 metadata,不是內容,因此走訪可見文件的 children 時不會出現。

每個 node 有 type,source-backed node 有 span;container node 有 children

一般 Markdown node(CommonMark/GFM,未被 MDI 修改)是:paragraphheadingdepth: 1–6)、blockquotelist/listItemorderedstart)、codeinlineCodethematicBreakhtmltable/tableRow/tableCelllinkimageemphasisstrongdeletetextfootnoteReferencefootnoteDefinition

type額外欄位產生方式
rubybase: string, ruby: MdiRubyReading{base|reading}
tcyvalue: string^text^
break[[br]]
emmark: string, children[[em:text]][[em:<mark>:text]]《《text》》
noBreakchildren[[no-break:text]]
warichuchildren[[warichu:text]]
kernamount: string, children[[kern:<amount>:text]]
blank單獨的 \ 行、<br>[[blank]]
pagebreakvariant: "left" | "right" | null[[pagebreak]][[pagebreak:left|right]]
indentbottomparagraphindent?: number, bottom?: number[[indent:N]] / [[bottom]] / [[bottom:N]] 套用至下一段
type MdiRubyReading = { type: "group"; value: string } | { type: "split"; value: string[] };

範例 {雪女|ゆき.おんな}

{"type":"ruby","base":"雪女","ruby":{"type":"split","value":["ゆき","おんな"]},"span":{"startByte":0,"endByte":12}}

span.startByte / span.endByte 是傳給 parse() 的原始字串中 half-open UTF-8 byte range。請見診斷與 UTF-8 source spans,了解原因與如何轉為宿主語言字串索引。

還有第二種較舊、簡單得多的 tree,僅由已 deprecated 的 parse_mdi_syntax / parseMdiSyntax 相容路徑產生:

interface MdiSyntaxDocument { blocks: Array<{ type: "paragraph"; inlines: MdiInline[]; indent: number | null; bottom: number | null } | { type: "blank" } | { type: "pagebreak"; variant: "left" | "right" | null }>; }

它沒有 spans、front matter 或一般 Markdown node,只認得 MDI 專用 inline/block construct,其他文字當成不透明 paragraph。它早於完整 CommonMark/GFM/MDI parser,今日只為避免舊 caller 壞掉;新程式一律使用 parse()/parse_document() 回傳的上方 Document。看到回傳 MdiSyntaxDocument 即表示走了 deprecated 路徑,勿與兩者混淆。