[{"data":1,"prerenderedAt":650},["ShallowReactive",2],{"markdown-doc:\u002Fguide\u002Fheadless":3,"markdown-source:recipes\u002Fsnapshot.ts":383,"mdc-neknl9-key":384},{"id":4,"title":5,"body":6,"description":372,"extension":373,"keywords":374,"locale":375,"meta":376,"navigation":65,"order":377,"path":378,"section":379,"seo":380,"stem":381,"__hash__":382},"docs\u002Fguide\u002Fheadless.zh-CN.md","无框架解析",{"type":7,"value":8,"toc":366},"minimark",[9,18,23,30,112,133,137,147,235,255,265,269,272,325,339,345,348,358,362],[10,11,12,13,17],"p",{},"如果只需要分析 Markdown 内容，或给自己的渲染器提供语法树，可以直接使用 ",[14,15,16],"code",{},"@quirekit\u002Fincremark-core","。这个入口不导入 Vue\u002FUI，也不创建可编辑视图；目前仍通过 MSFE 依赖 CodeMirror 模块。",[19,20,22],"h2",{"id":21},"_1-解析一份完整文本","1. 解析一份完整文本",[10,24,25,26,29],{},"文本已经接收完毕时，调用 ",[14,27,28],{},"parseMarkdown()","：",[31,32,38],"pre",{"className":33,"code":34,"filename":35,"language":36,"meta":37,"style":37},"language-ts shiki shiki-themes github-light github-light github-dark","import { parseMarkdown } from '@quirekit\u002Fincremark-core'\n\nconst state = parseMarkdown('# Hello')\nconst text = state.doc.toString()\n","解析完整文本","ts","",[14,39,40,60,67,93],{"__ignoreMap":37},[41,42,45,49,53,56],"span",{"class":43,"line":44},"line",1,[41,46,48],{"class":47},"sDD9d","import",[41,50,52],{"class":51},"sVPnS"," { parseMarkdown } ",[41,54,55],{"class":47},"from",[41,57,59],{"class":58},"s-HEn"," '@quirekit\u002Fincremark-core'\n",[41,61,63],{"class":43,"line":62},2,[41,64,66],{"emptyLinePlaceholder":65},true,"\n",[41,68,70,73,77,80,84,87,90],{"class":43,"line":69},3,[41,71,72],{"class":47},"const",[41,74,76],{"class":75},"sUNQB"," state",[41,78,79],{"class":47}," =",[41,81,83],{"class":82},"sgQzM"," parseMarkdown",[41,85,86],{"class":51},"(",[41,88,89],{"class":58},"'# Hello'",[41,91,92],{"class":51},")\n",[41,94,96,98,101,103,106,109],{"class":43,"line":95},4,[41,97,72],{"class":47},[41,99,100],{"class":75}," text",[41,102,79],{"class":47},[41,104,105],{"class":51}," state.doc.",[41,107,108],{"class":82},"toString",[41,110,111],{"class":51},"()\n",[10,113,114,117,118,121,122,125,126,129,130,132],{},[14,115,116],{},"state"," 是 CodeMirror 的只读 ",[14,119,120],{},"EditorState","，里面包含文本、语法树及扩展维护的语义信息；它不是 HTML，也不是 mdast\u002Fhast。上面的 ",[14,123,124],{},"text"," 仍是 ",[14,127,128],{},"# Hello","。保存时保留原始 Markdown，不要序列化 ",[14,131,120],{},"。",[19,134,136],{"id":135},"_2-接收陆续到来的文本","2. 接收陆续到来的文本",[10,138,139,140,143,144,29],{},"持续收到新片段时，保留同一个 ",[14,141,142],{},"MarkdownStream","，把每个新片段交给 ",[14,145,146],{},"append()",[31,148,151],{"className":33,"code":149,"filename":150,"language":36,"meta":37,"style":37},"import { MarkdownStream } from '@quirekit\u002Fincremark-core'\n\nconst stream = new MarkdownStream()\nstream.append('# Hello')\nconst complete = stream.advance(4)\nconst snapshot = stream.state\n","追加一个片段",[14,152,153,164,168,185,199,222],{"__ignoreMap":37},[41,154,155,157,160,162],{"class":43,"line":44},[41,156,48],{"class":47},[41,158,159],{"class":51}," { MarkdownStream } ",[41,161,55],{"class":47},[41,163,59],{"class":58},[41,165,166],{"class":43,"line":62},[41,167,66],{"emptyLinePlaceholder":65},[41,169,170,172,175,177,180,183],{"class":43,"line":69},[41,171,72],{"class":47},[41,173,174],{"class":75}," stream",[41,176,79],{"class":47},[41,178,179],{"class":47}," new",[41,181,182],{"class":82}," MarkdownStream",[41,184,111],{"class":51},[41,186,187,190,193,195,197],{"class":43,"line":95},[41,188,189],{"class":51},"stream.",[41,191,192],{"class":82},"append",[41,194,86],{"class":51},[41,196,89],{"class":58},[41,198,92],{"class":51},[41,200,202,204,207,209,212,215,217,220],{"class":43,"line":201},5,[41,203,72],{"class":47},[41,205,206],{"class":75}," complete",[41,208,79],{"class":47},[41,210,211],{"class":51}," stream.",[41,213,214],{"class":82},"advance",[41,216,86],{"class":51},[41,218,219],{"class":75},"4",[41,221,92],{"class":51},[41,223,225,227,230,232],{"class":43,"line":224},6,[41,226,72],{"class":47},[41,228,229],{"class":75}," snapshot",[41,231,79],{"class":47},[41,233,234],{"class":51}," stream.state\n",[10,236,237,239,240,132,243,246,247,250,251,254],{},[14,238,146],{}," 接收新增加的部分；如果应用已经累计了完整文本，改用 ",[14,241,242],{},"stream.update(全文)",[14,244,245],{},"advance(4)"," 给解析器约 4 毫秒的额外预算，返回 ",[14,248,249],{},"true"," 表示当前文本的语法与引用分组已完成，返回 ",[14,252,253],{},"false"," 时由应用安排下一次调用。",[10,256,257,258,260,261,264],{},"类本身没有定时器。不要用同步循环一直等待 ",[14,259,249],{},"，否则会阻塞界面。预算是协作式提示，不保证所有处理严格在 4 毫秒内结束；后续引用检查和界面渲染也需要时间。",[14,262,263],{},"snapshot"," 可以先读取，但尚未完成时不应把它当作最终解析结果。",[19,266,268],{"id":267},"_3-读取语法树","3. 读取语法树",[10,270,271],{},"从完成的状态中取得 Lezer 语法树：",[31,273,276],{"className":33,"code":274,"filename":275,"language":36,"meta":37,"style":37},"import { syntaxTree } from '@quirekit\u002Fcm-language'\n\nconst tree = syntaxTree(state)\nconst description = tree.toString()\n","读取语法结构",[14,277,278,290,294,309],{"__ignoreMap":37},[41,279,280,282,285,287],{"class":43,"line":44},[41,281,48],{"class":47},[41,283,284],{"class":51}," { syntaxTree } ",[41,286,55],{"class":47},[41,288,289],{"class":58}," '@quirekit\u002Fcm-language'\n",[41,291,292],{"class":43,"line":62},[41,293,66],{"emptyLinePlaceholder":65},[41,295,296,298,301,303,306],{"class":43,"line":69},[41,297,72],{"class":47},[41,299,300],{"class":75}," tree",[41,302,79],{"class":47},[41,304,305],{"class":82}," syntaxTree",[41,307,308],{"class":51},"(state)\n",[41,310,311,313,316,318,321,323],{"class":43,"line":95},[41,312,72],{"class":47},[41,314,315],{"class":75}," description",[41,317,79],{"class":47},[41,319,320],{"class":51}," tree.",[41,322,108],{"class":82},[41,324,111],{"class":51},[10,326,327,328,330,331,334,335,338],{},"对于 ",[14,329,128],{},"，紧凑描述是 ",[14,332,333],{},"Document(ATXHeading1(HeaderMark))","：整个文档里有一个一级标题及其 ",[14,336,337],{},"#"," 标记。自己的遍历逻辑可以通过树的 cursor、firstChild、nextSibling 读取节点和 UTF-16 范围。",[10,340,341,344],{},[14,342,343],{},"state.doc"," 使用规范化换行。链接和脚注等跨块关系由扩展维护，不能仅凭某个源码前缀推断最终链接目标。树描述适合调试，不是存档格式。",[19,346,347],{"id":347},"完整函数参考",[10,349,350,353,354,357],{},[14,351,352],{},"recipes\u002Fsnapshot.ts"," 将第一步和第三步封装成 ",[14,355,356],{},"inspectMarkdown(source)","，返回状态、文本和树描述。需要在自己的分析工具中复用时，可查阅这个单文件函数：",[359,360],"docs-recipe",{"name":361},"recipes\u002Fsnapshot",[363,364,365],"style",{},"html pre.shiki code .sDD9d, html code.shiki .sDD9d{--shiki-default:#D73A49;--shiki-light:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVPnS, html code.shiki .sVPnS{--shiki-default:#24292E;--shiki-light:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s-HEn, html code.shiki .s-HEn{--shiki-default:#032F62;--shiki-light:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sUNQB, html code.shiki .sUNQB{--shiki-default:#005CC5;--shiki-light:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sgQzM, html code.shiki .sgQzM{--shiki-default:#6F42C1;--shiki-light:#6F42C1;--shiki-dark:#B392F0}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":37,"searchDepth":62,"depth":62,"links":367},[368,369,370,371],{"id":21,"depth":62,"text":22},{"id":135,"depth":62,"text":136},{"id":267,"depth":62,"text":268},{"id":347,"depth":62,"text":347},"不创建阅读组件，直接把 Markdown 解析为文本与语法树。","md",null,"zh-CN",{},7,"\u002Fguide\u002Fheadless","接入指南",{"title":5,"description":372},"guide\u002Fheadless.zh-CN","wfTBQsHdJ2yOJb8czxqtTKYVx6huCBXknP-Hn2PiRzk","import { parseMarkdown } from \"@quirekit\u002Fincremark-core\";\nimport { syntaxTree } from \"@quirekit\u002Fcm-language\";\n\n\u002F**\n * Parse once without mounting an editor or creating Vue components.\n * @param source - Exact Markdown supplied by the host.\n * @returns The immutable snapshot, canonical text and a compact syntax-tree description.\n *\u002F\nexport function inspectMarkdown(source: string) {\n  const state = parseMarkdown(source);\n  return { state, text: state.doc.toString(), syntax: syntaxTree(state).toString() };\n}\n",{"data":385,"body":386},{},{"type":387,"children":388},"root",[389,645],{"type":390,"tag":31,"props":391,"children":393},"element",{"className":33,"code":392,"language":36,"meta":37,"style":37},"import { parseMarkdown } from \"@quirekit\u002Fincremark-core\";\nimport { syntaxTree } from \"@quirekit\u002Fcm-language\";\n\n\u002F**\n * Parse once without mounting an editor or creating Vue components.\n * @param source - Exact Markdown supplied by the host.\n * @returns The immutable snapshot, canonical text and a compact syntax-tree description.\n *\u002F\nexport function inspectMarkdown(source: string) {\n  const state = parseMarkdown(source);\n  return { state, text: state.doc.toString(), syntax: syntaxTree(state).toString() };\n}\n\n",[394],{"type":390,"tag":14,"props":395,"children":396},{"__ignoreMap":37},[397,425,449,456,465,473,496,513,522,568,594,636],{"type":390,"tag":41,"props":398,"children":399},{"class":43,"line":44},[400,405,410,414,420],{"type":390,"tag":41,"props":401,"children":403},{"style":402},"--shiki-default:#D73A49;--shiki-light:#D73A49;--shiki-dark:#F97583",[404],{"type":124,"value":48},{"type":390,"tag":41,"props":406,"children":408},{"style":407},"--shiki-default:#24292E;--shiki-light:#24292E;--shiki-dark:#E1E4E8",[409],{"type":124,"value":52},{"type":390,"tag":41,"props":411,"children":412},{"style":402},[413],{"type":124,"value":55},{"type":390,"tag":41,"props":415,"children":417},{"style":416},"--shiki-default:#032F62;--shiki-light:#032F62;--shiki-dark:#9ECBFF",[418],{"type":124,"value":419}," \"@quirekit\u002Fincremark-core\"",{"type":390,"tag":41,"props":421,"children":422},{"style":407},[423],{"type":124,"value":424},";\n",{"type":390,"tag":41,"props":426,"children":427},{"class":43,"line":62},[428,432,436,440,445],{"type":390,"tag":41,"props":429,"children":430},{"style":402},[431],{"type":124,"value":48},{"type":390,"tag":41,"props":433,"children":434},{"style":407},[435],{"type":124,"value":284},{"type":390,"tag":41,"props":437,"children":438},{"style":402},[439],{"type":124,"value":55},{"type":390,"tag":41,"props":441,"children":442},{"style":416},[443],{"type":124,"value":444}," \"@quirekit\u002Fcm-language\"",{"type":390,"tag":41,"props":446,"children":447},{"style":407},[448],{"type":124,"value":424},{"type":390,"tag":41,"props":450,"children":451},{"class":43,"line":69},[452],{"type":390,"tag":41,"props":453,"children":454},{"emptyLinePlaceholder":65},[455],{"type":124,"value":66},{"type":390,"tag":41,"props":457,"children":458},{"class":43,"line":95},[459],{"type":390,"tag":41,"props":460,"children":462},{"style":461},"--shiki-default:#6A737D;--shiki-light:#6A737D;--shiki-dark:#6A737D",[463],{"type":124,"value":464},"\u002F**\n",{"type":390,"tag":41,"props":466,"children":467},{"class":43,"line":201},[468],{"type":390,"tag":41,"props":469,"children":470},{"style":461},[471],{"type":124,"value":472}," * Parse once without mounting an editor or creating Vue components.\n",{"type":390,"tag":41,"props":474,"children":475},{"class":43,"line":224},[476,481,486,491],{"type":390,"tag":41,"props":477,"children":478},{"style":461},[479],{"type":124,"value":480}," * ",{"type":390,"tag":41,"props":482,"children":483},{"style":402},[484],{"type":124,"value":485},"@param",{"type":390,"tag":41,"props":487,"children":488},{"style":407},[489],{"type":124,"value":490}," source",{"type":390,"tag":41,"props":492,"children":493},{"style":461},[494],{"type":124,"value":495}," - Exact Markdown supplied by the host.\n",{"type":390,"tag":41,"props":497,"children":498},{"class":43,"line":377},[499,503,508],{"type":390,"tag":41,"props":500,"children":501},{"style":461},[502],{"type":124,"value":480},{"type":390,"tag":41,"props":504,"children":505},{"style":402},[506],{"type":124,"value":507},"@returns",{"type":390,"tag":41,"props":509,"children":510},{"style":461},[511],{"type":124,"value":512}," The immutable snapshot, canonical text and a compact syntax-tree description.\n",{"type":390,"tag":41,"props":514,"children":516},{"class":43,"line":515},8,[517],{"type":390,"tag":41,"props":518,"children":519},{"style":461},[520],{"type":124,"value":521}," *\u002F\n",{"type":390,"tag":41,"props":523,"children":525},{"class":43,"line":524},9,[526,531,536,542,546,552,557,563],{"type":390,"tag":41,"props":527,"children":528},{"style":402},[529],{"type":124,"value":530},"export",{"type":390,"tag":41,"props":532,"children":533},{"style":402},[534],{"type":124,"value":535}," function",{"type":390,"tag":41,"props":537,"children":539},{"style":538},"--shiki-default:#6F42C1;--shiki-light:#6F42C1;--shiki-dark:#B392F0",[540],{"type":124,"value":541}," inspectMarkdown",{"type":390,"tag":41,"props":543,"children":544},{"style":407},[545],{"type":124,"value":86},{"type":390,"tag":41,"props":547,"children":549},{"style":548},"--shiki-default:#E36209;--shiki-light:#E36209;--shiki-dark:#FFAB70",[550],{"type":124,"value":551},"source",{"type":390,"tag":41,"props":553,"children":554},{"style":402},[555],{"type":124,"value":556},":",{"type":390,"tag":41,"props":558,"children":560},{"style":559},"--shiki-default:#005CC5;--shiki-light:#005CC5;--shiki-dark:#79B8FF",[561],{"type":124,"value":562}," string",{"type":390,"tag":41,"props":564,"children":565},{"style":407},[566],{"type":124,"value":567},") {\n",{"type":390,"tag":41,"props":569,"children":571},{"class":43,"line":570},10,[572,577,581,585,589],{"type":390,"tag":41,"props":573,"children":574},{"style":402},[575],{"type":124,"value":576},"  const",{"type":390,"tag":41,"props":578,"children":579},{"style":559},[580],{"type":124,"value":76},{"type":390,"tag":41,"props":582,"children":583},{"style":402},[584],{"type":124,"value":79},{"type":390,"tag":41,"props":586,"children":587},{"style":538},[588],{"type":124,"value":83},{"type":390,"tag":41,"props":590,"children":591},{"style":407},[592],{"type":124,"value":593},"(source);\n",{"type":390,"tag":41,"props":595,"children":597},{"class":43,"line":596},11,[598,603,608,612,617,622,627,631],{"type":390,"tag":41,"props":599,"children":600},{"style":402},[601],{"type":124,"value":602},"  return",{"type":390,"tag":41,"props":604,"children":605},{"style":407},[606],{"type":124,"value":607}," { state, text: state.doc.",{"type":390,"tag":41,"props":609,"children":610},{"style":538},[611],{"type":124,"value":108},{"type":390,"tag":41,"props":613,"children":614},{"style":407},[615],{"type":124,"value":616},"(), syntax: ",{"type":390,"tag":41,"props":618,"children":619},{"style":538},[620],{"type":124,"value":621},"syntaxTree",{"type":390,"tag":41,"props":623,"children":624},{"style":407},[625],{"type":124,"value":626},"(state).",{"type":390,"tag":41,"props":628,"children":629},{"style":538},[630],{"type":124,"value":108},{"type":390,"tag":41,"props":632,"children":633},{"style":407},[634],{"type":124,"value":635},"() };\n",{"type":390,"tag":41,"props":637,"children":639},{"class":43,"line":638},12,[640],{"type":390,"tag":41,"props":641,"children":642},{"style":407},[643],{"type":124,"value":644},"}\n",{"type":390,"tag":363,"props":646,"children":647},{},[648],{"type":124,"value":649},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",1793045321582]