[{"data":1,"prerenderedAt":647},["ShallowReactive",2],{"markdown-doc:\u002Fen\u002Fguide\u002Fheadless":3,"markdown-source:recipes\u002Fsnapshot.ts":381,"mdc-neknl9-key":382},{"id":4,"title":5,"body":6,"description":370,"extension":371,"keywords":372,"locale":373,"meta":374,"navigation":65,"order":375,"path":376,"section":377,"seo":378,"stem":379,"__hash__":380},"docs\u002Fguide\u002Fheadless.en.md","Headless parsing",{"type":7,"value":8,"toc":364},"minimark",[9,18,23,30,112,133,137,147,235,252,262,266,269,322,336,342,346,356,360],[10,11,12,13,17],"p",{},"Use ",[14,15,16],"code",{},"@quirekit\u002Fincremark-core"," to analyze Markdown or supply a syntax tree to your own renderer. This entry imports neither Vue nor UI and creates no editable view. It currently still depends on CodeMirror modules through MSFE.",[19,20,22],"h2",{"id":21},"_1-parse-a-complete-text","1. Parse a complete text",[10,24,25,26,29],{},"When all text has arrived, call ",[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","Parse complete text","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"," is a CodeMirror ",[14,119,120],{},"EditorState"," used read-only. It contains text, a syntax tree and extension-maintained semantics; it is neither HTML nor mdast\u002Fhast. The resulting ",[14,123,124],{},"text"," is still ",[14,127,128],{},"# Hello",". Persist the original Markdown rather than serializing ",[14,131,120],{},".",[19,134,136],{"id":135},"_2-receive-text-over-time","2. Receive text over time",[10,138,139,140,143,144,29],{},"Retain one ",[14,141,142],{},"MarkdownStream"," and pass each new piece to ",[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","Append one piece",[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,243,244,247,248,251],{},[14,238,146],{}," takes only the newly received portion. If the application already accumulates the full text, use ",[14,241,242],{},"stream.update(fullText)"," instead. ",[14,245,246],{},"advance(4)"," gives the parser approximately four milliseconds of extra budget. It returns ",[14,249,250],{},"true"," when syntax and reference grouping for the current text are complete; otherwise the application schedules another call.",[10,253,254,255,257,258,261],{},"The class owns no timers. Do not spin synchronously until it returns ",[14,256,250],{},", which would block the interface. The budget is a cooperative hint, not a strict four-millisecond limit; reference checks and interface rendering also take time. You can read ",[14,259,260],{},"snapshot"," while parsing is pending, but it is not yet a final result.",[19,263,265],{"id":264},"_3-read-the-syntax-tree","3. Read the syntax tree",[10,267,268],{},"Get the Lezer tree from a completed state:",[31,270,273],{"className":33,"code":271,"filename":272,"language":36,"meta":37,"style":37},"import { syntaxTree } from '@quirekit\u002Fcm-language'\n\nconst tree = syntaxTree(state)\nconst description = tree.toString()\n","Read syntax structure",[14,274,275,287,291,306],{"__ignoreMap":37},[41,276,277,279,282,284],{"class":43,"line":44},[41,278,48],{"class":47},[41,280,281],{"class":51}," { syntaxTree } ",[41,283,55],{"class":47},[41,285,286],{"class":58}," '@quirekit\u002Fcm-language'\n",[41,288,289],{"class":43,"line":62},[41,290,66],{"emptyLinePlaceholder":65},[41,292,293,295,298,300,303],{"class":43,"line":69},[41,294,72],{"class":47},[41,296,297],{"class":75}," tree",[41,299,79],{"class":47},[41,301,302],{"class":82}," syntaxTree",[41,304,305],{"class":51},"(state)\n",[41,307,308,310,313,315,318,320],{"class":43,"line":95},[41,309,72],{"class":47},[41,311,312],{"class":75}," description",[41,314,79],{"class":47},[41,316,317],{"class":51}," tree.",[41,319,108],{"class":82},[41,321,111],{"class":51},[10,323,324,325,327,328,331,332,335],{},"For ",[14,326,128],{},", the compact description is ",[14,329,330],{},"Document(ATXHeading1(HeaderMark))",": a document containing a level-one heading and its ",[14,333,334],{},"#"," marker. Use the tree's cursor, firstChild and nextSibling APIs to traverse node kinds and UTF-16 ranges.",[10,337,338,341],{},[14,339,340],{},"state.doc"," uses normalized newlines. Extensions maintain cross-block relationships such as links and footnotes; a source prefix alone does not establish a final link target. Tree descriptions are useful for debugging, not persistence.",[19,343,345],{"id":344},"complete-function","Complete function",[10,347,348,351,352,355],{},[14,349,350],{},"recipes\u002Fsnapshot.ts"," combines steps one and three as ",[14,353,354],{},"inspectMarkdown(source)",", returning the state, text and tree description. Consult this single-file function when integrating an analysis tool:",[357,358],"docs-recipe",{"name":359},"recipes\u002Fsnapshot",[361,362,363],"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":365},[366,367,368,369],{"id":21,"depth":62,"text":22},{"id":135,"depth":62,"text":136},{"id":264,"depth":62,"text":265},{"id":344,"depth":62,"text":345},"Parse Markdown into text and a syntax tree without creating a reading component.","md",null,"en",{},7,"\u002Fen\u002Fguide\u002Fheadless","Integration",{"title":5,"description":370},"guide\u002Fheadless.en","4ph6hp1qX2ke4PRzR6bva1cMuwjxJseBYSgmiasCAyQ","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":383,"body":384},{},{"type":385,"children":386},"root",[387,642],{"type":388,"tag":31,"props":389,"children":391},"element",{"className":33,"code":390,"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",[392],{"type":388,"tag":14,"props":393,"children":394},{"__ignoreMap":37},[395,423,447,454,463,471,494,511,520,565,591,633],{"type":388,"tag":41,"props":396,"children":397},{"class":43,"line":44},[398,403,408,412,418],{"type":388,"tag":41,"props":399,"children":401},{"style":400},"--shiki-default:#D73A49;--shiki-light:#D73A49;--shiki-dark:#F97583",[402],{"type":124,"value":48},{"type":388,"tag":41,"props":404,"children":406},{"style":405},"--shiki-default:#24292E;--shiki-light:#24292E;--shiki-dark:#E1E4E8",[407],{"type":124,"value":52},{"type":388,"tag":41,"props":409,"children":410},{"style":400},[411],{"type":124,"value":55},{"type":388,"tag":41,"props":413,"children":415},{"style":414},"--shiki-default:#032F62;--shiki-light:#032F62;--shiki-dark:#9ECBFF",[416],{"type":124,"value":417}," \"@quirekit\u002Fincremark-core\"",{"type":388,"tag":41,"props":419,"children":420},{"style":405},[421],{"type":124,"value":422},";\n",{"type":388,"tag":41,"props":424,"children":425},{"class":43,"line":62},[426,430,434,438,443],{"type":388,"tag":41,"props":427,"children":428},{"style":400},[429],{"type":124,"value":48},{"type":388,"tag":41,"props":431,"children":432},{"style":405},[433],{"type":124,"value":281},{"type":388,"tag":41,"props":435,"children":436},{"style":400},[437],{"type":124,"value":55},{"type":388,"tag":41,"props":439,"children":440},{"style":414},[441],{"type":124,"value":442}," \"@quirekit\u002Fcm-language\"",{"type":388,"tag":41,"props":444,"children":445},{"style":405},[446],{"type":124,"value":422},{"type":388,"tag":41,"props":448,"children":449},{"class":43,"line":69},[450],{"type":388,"tag":41,"props":451,"children":452},{"emptyLinePlaceholder":65},[453],{"type":124,"value":66},{"type":388,"tag":41,"props":455,"children":456},{"class":43,"line":95},[457],{"type":388,"tag":41,"props":458,"children":460},{"style":459},"--shiki-default:#6A737D;--shiki-light:#6A737D;--shiki-dark:#6A737D",[461],{"type":124,"value":462},"\u002F**\n",{"type":388,"tag":41,"props":464,"children":465},{"class":43,"line":201},[466],{"type":388,"tag":41,"props":467,"children":468},{"style":459},[469],{"type":124,"value":470}," * Parse once without mounting an editor or creating Vue components.\n",{"type":388,"tag":41,"props":472,"children":473},{"class":43,"line":224},[474,479,484,489],{"type":388,"tag":41,"props":475,"children":476},{"style":459},[477],{"type":124,"value":478}," * ",{"type":388,"tag":41,"props":480,"children":481},{"style":400},[482],{"type":124,"value":483},"@param",{"type":388,"tag":41,"props":485,"children":486},{"style":405},[487],{"type":124,"value":488}," source",{"type":388,"tag":41,"props":490,"children":491},{"style":459},[492],{"type":124,"value":493}," - Exact Markdown supplied by the host.\n",{"type":388,"tag":41,"props":495,"children":496},{"class":43,"line":375},[497,501,506],{"type":388,"tag":41,"props":498,"children":499},{"style":459},[500],{"type":124,"value":478},{"type":388,"tag":41,"props":502,"children":503},{"style":400},[504],{"type":124,"value":505},"@returns",{"type":388,"tag":41,"props":507,"children":508},{"style":459},[509],{"type":124,"value":510}," The immutable snapshot, canonical text and a compact syntax-tree description.\n",{"type":388,"tag":41,"props":512,"children":514},{"class":43,"line":513},8,[515],{"type":388,"tag":41,"props":516,"children":517},{"style":459},[518],{"type":124,"value":519}," *\u002F\n",{"type":388,"tag":41,"props":521,"children":523},{"class":43,"line":522},9,[524,529,534,540,544,550,554,560],{"type":388,"tag":41,"props":525,"children":526},{"style":400},[527],{"type":124,"value":528},"export",{"type":388,"tag":41,"props":530,"children":531},{"style":400},[532],{"type":124,"value":533}," function",{"type":388,"tag":41,"props":535,"children":537},{"style":536},"--shiki-default:#6F42C1;--shiki-light:#6F42C1;--shiki-dark:#B392F0",[538],{"type":124,"value":539}," inspectMarkdown",{"type":388,"tag":41,"props":541,"children":542},{"style":405},[543],{"type":124,"value":86},{"type":388,"tag":41,"props":545,"children":547},{"style":546},"--shiki-default:#E36209;--shiki-light:#E36209;--shiki-dark:#FFAB70",[548],{"type":124,"value":549},"source",{"type":388,"tag":41,"props":551,"children":552},{"style":400},[553],{"type":124,"value":29},{"type":388,"tag":41,"props":555,"children":557},{"style":556},"--shiki-default:#005CC5;--shiki-light:#005CC5;--shiki-dark:#79B8FF",[558],{"type":124,"value":559}," string",{"type":388,"tag":41,"props":561,"children":562},{"style":405},[563],{"type":124,"value":564},") {\n",{"type":388,"tag":41,"props":566,"children":568},{"class":43,"line":567},10,[569,574,578,582,586],{"type":388,"tag":41,"props":570,"children":571},{"style":400},[572],{"type":124,"value":573},"  const",{"type":388,"tag":41,"props":575,"children":576},{"style":556},[577],{"type":124,"value":76},{"type":388,"tag":41,"props":579,"children":580},{"style":400},[581],{"type":124,"value":79},{"type":388,"tag":41,"props":583,"children":584},{"style":536},[585],{"type":124,"value":83},{"type":388,"tag":41,"props":587,"children":588},{"style":405},[589],{"type":124,"value":590},"(source);\n",{"type":388,"tag":41,"props":592,"children":594},{"class":43,"line":593},11,[595,600,605,609,614,619,624,628],{"type":388,"tag":41,"props":596,"children":597},{"style":400},[598],{"type":124,"value":599},"  return",{"type":388,"tag":41,"props":601,"children":602},{"style":405},[603],{"type":124,"value":604}," { state, text: state.doc.",{"type":388,"tag":41,"props":606,"children":607},{"style":536},[608],{"type":124,"value":108},{"type":388,"tag":41,"props":610,"children":611},{"style":405},[612],{"type":124,"value":613},"(), syntax: ",{"type":388,"tag":41,"props":615,"children":616},{"style":536},[617],{"type":124,"value":618},"syntaxTree",{"type":388,"tag":41,"props":620,"children":621},{"style":405},[622],{"type":124,"value":623},"(state).",{"type":388,"tag":41,"props":625,"children":626},{"style":536},[627],{"type":124,"value":108},{"type":388,"tag":41,"props":629,"children":630},{"style":405},[631],{"type":124,"value":632},"() };\n",{"type":388,"tag":41,"props":634,"children":636},{"class":43,"line":635},12,[637],{"type":388,"tag":41,"props":638,"children":639},{"style":405},[640],{"type":124,"value":641},"}\n",{"type":388,"tag":361,"props":643,"children":644},{},[645],{"type":124,"value":646},"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);}",1793045320730]