@temelj/mdx 0.13.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (369) hide show
  1. package/README.md +468 -82
  2. package/dist/character-entities.d.mts +4 -0
  3. package/dist/character-entities.d.mts.map +1 -0
  4. package/dist/character-entities.mjs +2132 -0
  5. package/dist/character-entities.mjs.map +1 -0
  6. package/dist/character-reference.d.mts +6 -0
  7. package/dist/character-reference.d.mts.map +1 -0
  8. package/dist/character-reference.mjs +18 -0
  9. package/dist/character-reference.mjs.map +1 -0
  10. package/dist/compile-analysis.d.mts +28 -0
  11. package/dist/compile-analysis.d.mts.map +1 -0
  12. package/dist/compile-analysis.mjs +74 -0
  13. package/dist/compile-analysis.mjs.map +1 -0
  14. package/dist/compile-emit.d.mts +9 -0
  15. package/dist/compile-emit.d.mts.map +1 -0
  16. package/dist/compile-emit.mjs +187 -0
  17. package/dist/compile-emit.mjs.map +1 -0
  18. package/dist/compile-esm.d.mts +34 -0
  19. package/dist/compile-esm.d.mts.map +1 -0
  20. package/dist/compile-esm.mjs +187 -0
  21. package/dist/compile-esm.mjs.map +1 -0
  22. package/dist/compile-names.d.mts +13 -0
  23. package/dist/compile-names.d.mts.map +1 -0
  24. package/dist/compile-names.mjs +32 -0
  25. package/dist/compile-names.mjs.map +1 -0
  26. package/dist/compiler.d.mts +69 -85
  27. package/dist/compiler.d.mts.map +1 -1
  28. package/dist/compiler.mjs +185 -418
  29. package/dist/compiler.mjs.map +1 -1
  30. package/dist/diagnostics.d.mts +37 -0
  31. package/dist/diagnostics.d.mts.map +1 -0
  32. package/dist/diagnostics.mjs +57 -0
  33. package/dist/diagnostics.mjs.map +1 -0
  34. package/dist/errors.d.mts +157 -0
  35. package/dist/errors.d.mts.map +1 -0
  36. package/dist/errors.mjs +263 -0
  37. package/dist/errors.mjs.map +1 -0
  38. package/dist/footnote-numbering.d.mts +27 -0
  39. package/dist/footnote-numbering.d.mts.map +1 -0
  40. package/dist/footnote-numbering.mjs +49 -0
  41. package/dist/footnote-numbering.mjs.map +1 -0
  42. package/dist/format-context.d.mts +46 -0
  43. package/dist/format-context.d.mts.map +1 -0
  44. package/dist/format-context.mjs +26 -0
  45. package/dist/format-context.mjs.map +1 -0
  46. package/dist/format-directive.d.mts +9 -0
  47. package/dist/format-directive.d.mts.map +1 -0
  48. package/dist/format-directive.mjs +99 -0
  49. package/dist/format-directive.mjs.map +1 -0
  50. package/dist/format-jsx.d.mts +8 -0
  51. package/dist/format-jsx.d.mts.map +1 -0
  52. package/dist/format-jsx.mjs +47 -0
  53. package/dist/format-jsx.mjs.map +1 -0
  54. package/dist/format-math.d.mts +9 -0
  55. package/dist/format-math.d.mts.map +1 -0
  56. package/dist/format-math.mjs +79 -0
  57. package/dist/format-math.mjs.map +1 -0
  58. package/dist/format-safe.d.mts +25 -0
  59. package/dist/format-safe.d.mts.map +1 -0
  60. package/dist/format-safe.mjs +366 -0
  61. package/dist/format-safe.mjs.map +1 -0
  62. package/dist/format-table.d.mts +8 -0
  63. package/dist/format-table.d.mts.map +1 -0
  64. package/dist/format-table.mjs +55 -0
  65. package/dist/format-table.mjs.map +1 -0
  66. package/dist/format-track.d.mts +18 -0
  67. package/dist/format-track.d.mts.map +1 -0
  68. package/dist/format-track.mjs +34 -0
  69. package/dist/format-track.mjs.map +1 -0
  70. package/dist/format.d.mts +7 -0
  71. package/dist/format.d.mts.map +1 -0
  72. package/dist/format.mjs +549 -0
  73. package/dist/format.mjs.map +1 -0
  74. package/dist/frontmatter.d.mts +15 -0
  75. package/dist/frontmatter.d.mts.map +1 -0
  76. package/dist/frontmatter.mjs +187 -0
  77. package/dist/frontmatter.mjs.map +1 -0
  78. package/dist/heading.d.mts +6 -0
  79. package/dist/heading.d.mts.map +1 -0
  80. package/dist/heading.mjs +19 -0
  81. package/dist/heading.mjs.map +1 -0
  82. package/dist/html-format.d.mts +32 -0
  83. package/dist/html-format.d.mts.map +1 -0
  84. package/dist/html-format.mjs +127 -0
  85. package/dist/html-format.mjs.map +1 -0
  86. package/dist/html-lower.d.mts +78 -0
  87. package/dist/html-lower.d.mts.map +1 -0
  88. package/dist/html-lower.mjs +583 -0
  89. package/dist/html-lower.mjs.map +1 -0
  90. package/dist/html-stream.d.mts +13 -0
  91. package/dist/html-stream.d.mts.map +1 -0
  92. package/dist/html-stream.mjs +32 -0
  93. package/dist/html-stream.mjs.map +1 -0
  94. package/dist/html.d.mts +120 -0
  95. package/dist/html.d.mts.map +1 -0
  96. package/dist/html.mjs +77 -0
  97. package/dist/html.mjs.map +1 -0
  98. package/dist/identifier.d.mts +4 -0
  99. package/dist/identifier.d.mts.map +1 -0
  100. package/dist/identifier.mjs +8 -0
  101. package/dist/identifier.mjs.map +1 -0
  102. package/dist/javascript-ast.d.mts +16 -0
  103. package/dist/javascript-ast.d.mts.map +1 -0
  104. package/dist/javascript-ast.mjs +39 -0
  105. package/dist/javascript-ast.mjs.map +1 -0
  106. package/dist/javascript-jsx.d.mts +24 -0
  107. package/dist/javascript-jsx.d.mts.map +1 -0
  108. package/dist/javascript-jsx.mjs +189 -0
  109. package/dist/javascript-jsx.mjs.map +1 -0
  110. package/dist/javascript.d.mts +9 -0
  111. package/dist/javascript.d.mts.map +1 -0
  112. package/dist/javascript.mjs +31 -0
  113. package/dist/javascript.mjs.map +1 -0
  114. package/dist/jsx-reference.d.mts +15 -0
  115. package/dist/jsx-reference.d.mts.map +1 -0
  116. package/dist/jsx-reference.mjs +31 -0
  117. package/dist/jsx-reference.mjs.map +1 -0
  118. package/dist/mod.d.mts +25 -8
  119. package/dist/mod.mjs +19 -7
  120. package/dist/model.d.mts +196 -0
  121. package/dist/model.d.mts.map +1 -0
  122. package/dist/model.mjs +113 -0
  123. package/dist/model.mjs.map +1 -0
  124. package/dist/parser/block-container-recognizers.d.mts +40 -0
  125. package/dist/parser/block-container-recognizers.d.mts.map +1 -0
  126. package/dist/parser/block-container-recognizers.mjs +90 -0
  127. package/dist/parser/block-container-recognizers.mjs.map +1 -0
  128. package/dist/parser/block-directive-recognizers.d.mts +22 -0
  129. package/dist/parser/block-directive-recognizers.d.mts.map +1 -0
  130. package/dist/parser/block-directive-recognizers.mjs +77 -0
  131. package/dist/parser/block-directive-recognizers.mjs.map +1 -0
  132. package/dist/parser/block-leaf-recognizers.d.mts +53 -0
  133. package/dist/parser/block-leaf-recognizers.d.mts.map +1 -0
  134. package/dist/parser/block-leaf-recognizers.mjs +386 -0
  135. package/dist/parser/block-leaf-recognizers.mjs.map +1 -0
  136. package/dist/parser/block-parser.d.mts +38 -0
  137. package/dist/parser/block-parser.d.mts.map +1 -0
  138. package/dist/parser/block-parser.mjs +895 -0
  139. package/dist/parser/block-parser.mjs.map +1 -0
  140. package/dist/parser/block-syntax.d.mts +240 -0
  141. package/dist/parser/block-syntax.d.mts.map +1 -0
  142. package/dist/parser/characters.d.mts +19 -0
  143. package/dist/parser/characters.d.mts.map +1 -0
  144. package/dist/parser/characters.mjs +52 -0
  145. package/dist/parser/characters.mjs.map +1 -0
  146. package/dist/parser/config.d.mts +16 -0
  147. package/dist/parser/config.d.mts.map +1 -0
  148. package/dist/parser/config.mjs +25 -0
  149. package/dist/parser/config.mjs.map +1 -0
  150. package/dist/parser/directive-attributes.d.mts +9 -0
  151. package/dist/parser/directive-attributes.d.mts.map +1 -0
  152. package/dist/parser/directive-attributes.mjs +24 -0
  153. package/dist/parser/directive-attributes.mjs.map +1 -0
  154. package/dist/parser/embedded-scanner.d.mts +18 -0
  155. package/dist/parser/embedded-scanner.d.mts.map +1 -0
  156. package/dist/parser/embedded-scanner.mjs +199 -0
  157. package/dist/parser/embedded-scanner.mjs.map +1 -0
  158. package/dist/parser/inline-autolink.d.mts +7 -0
  159. package/dist/parser/inline-autolink.d.mts.map +1 -0
  160. package/dist/parser/inline-autolink.mjs +42 -0
  161. package/dist/parser/inline-autolink.mjs.map +1 -0
  162. package/dist/parser/inline-character-reference.d.mts +7 -0
  163. package/dist/parser/inline-character-reference.d.mts.map +1 -0
  164. package/dist/parser/inline-character-reference.mjs +22 -0
  165. package/dist/parser/inline-character-reference.mjs.map +1 -0
  166. package/dist/parser/inline-code.d.mts +7 -0
  167. package/dist/parser/inline-code.d.mts.map +1 -0
  168. package/dist/parser/inline-code.mjs +29 -0
  169. package/dist/parser/inline-code.mjs.map +1 -0
  170. package/dist/parser/inline-directive.d.mts +9 -0
  171. package/dist/parser/inline-directive.d.mts.map +1 -0
  172. package/dist/parser/inline-directive.mjs +45 -0
  173. package/dist/parser/inline-directive.mjs.map +1 -0
  174. package/dist/parser/inline-embedded.d.mts +19 -0
  175. package/dist/parser/inline-embedded.d.mts.map +1 -0
  176. package/dist/parser/inline-embedded.mjs +92 -0
  177. package/dist/parser/inline-embedded.mjs.map +1 -0
  178. package/dist/parser/inline-emphasis.d.mts +11 -0
  179. package/dist/parser/inline-emphasis.d.mts.map +1 -0
  180. package/dist/parser/inline-emphasis.mjs +79 -0
  181. package/dist/parser/inline-emphasis.mjs.map +1 -0
  182. package/dist/parser/inline-input.d.mts +46 -0
  183. package/dist/parser/inline-input.d.mts.map +1 -0
  184. package/dist/parser/inline-input.mjs +137 -0
  185. package/dist/parser/inline-input.mjs.map +1 -0
  186. package/dist/parser/inline-link.d.mts +12 -0
  187. package/dist/parser/inline-link.d.mts.map +1 -0
  188. package/dist/parser/inline-link.mjs +187 -0
  189. package/dist/parser/inline-link.mjs.map +1 -0
  190. package/dist/parser/inline-math.d.mts +10 -0
  191. package/dist/parser/inline-math.d.mts.map +1 -0
  192. package/dist/parser/inline-math.mjs +46 -0
  193. package/dist/parser/inline-math.mjs.map +1 -0
  194. package/dist/parser/inline-output.d.mts +34 -0
  195. package/dist/parser/inline-output.d.mts.map +1 -0
  196. package/dist/parser/inline-output.mjs +62 -0
  197. package/dist/parser/inline-output.mjs.map +1 -0
  198. package/dist/parser/inline-parser.d.mts +14 -0
  199. package/dist/parser/inline-parser.d.mts.map +1 -0
  200. package/dist/parser/inline-parser.mjs +328 -0
  201. package/dist/parser/inline-parser.mjs.map +1 -0
  202. package/dist/parser/inline-pending.d.mts +23 -0
  203. package/dist/parser/inline-pending.d.mts.map +1 -0
  204. package/dist/parser/inline-pending.mjs +100 -0
  205. package/dist/parser/inline-pending.mjs.map +1 -0
  206. package/dist/parser/inline-syntax.d.mts +118 -0
  207. package/dist/parser/inline-syntax.d.mts.map +1 -0
  208. package/dist/parser/inline-syntax.mjs +1 -0
  209. package/dist/parser/javascript-boundary.d.mts +16 -0
  210. package/dist/parser/javascript-boundary.d.mts.map +1 -0
  211. package/dist/parser/javascript-boundary.mjs +42 -0
  212. package/dist/parser/javascript-boundary.mjs.map +1 -0
  213. package/dist/parser/javascript-scanner.d.mts +22 -0
  214. package/dist/parser/javascript-scanner.d.mts.map +1 -0
  215. package/dist/parser/javascript-scanner.mjs +122 -0
  216. package/dist/parser/javascript-scanner.mjs.map +1 -0
  217. package/dist/parser/materialize-cache.d.mts +34 -0
  218. package/dist/parser/materialize-cache.d.mts.map +1 -0
  219. package/dist/parser/materialize-cache.mjs +12 -0
  220. package/dist/parser/materialize-cache.mjs.map +1 -0
  221. package/dist/parser/materialize-jsx.d.mts +14 -0
  222. package/dist/parser/materialize-jsx.d.mts.map +1 -0
  223. package/dist/parser/materialize-jsx.mjs +76 -0
  224. package/dist/parser/materialize-jsx.mjs.map +1 -0
  225. package/dist/parser/materialize.d.mts +61 -0
  226. package/dist/parser/materialize.d.mts.map +1 -0
  227. package/dist/parser/materialize.mjs +736 -0
  228. package/dist/parser/materialize.mjs.map +1 -0
  229. package/dist/parser/recognizer.d.mts +20 -0
  230. package/dist/parser/recognizer.d.mts.map +1 -0
  231. package/dist/parser/recognizer.mjs +24 -0
  232. package/dist/parser/recognizer.mjs.map +1 -0
  233. package/dist/parser/session.d.mts +42 -0
  234. package/dist/parser/session.d.mts.map +1 -0
  235. package/dist/parser/session.mjs +89 -0
  236. package/dist/parser/session.mjs.map +1 -0
  237. package/dist/parser.d.mts +25 -0
  238. package/dist/parser.d.mts.map +1 -0
  239. package/dist/parser.mjs +37 -0
  240. package/dist/parser.mjs.map +1 -0
  241. package/dist/plugin-internal.d.mts +25 -0
  242. package/dist/plugin-internal.d.mts.map +1 -0
  243. package/dist/plugin-internal.mjs +99 -0
  244. package/dist/plugin-internal.mjs.map +1 -0
  245. package/dist/plugin.d.mts +37 -0
  246. package/dist/plugin.d.mts.map +1 -0
  247. package/dist/plugin.mjs +1 -0
  248. package/dist/plugins/code-block-metadata.d.mts +42 -0
  249. package/dist/plugins/code-block-metadata.d.mts.map +1 -0
  250. package/dist/plugins/code-block-metadata.mjs +133 -0
  251. package/dist/plugins/code-block-metadata.mjs.map +1 -0
  252. package/dist/plugins/heading-id.d.mts +15 -0
  253. package/dist/plugins/heading-id.d.mts.map +1 -0
  254. package/dist/plugins/heading-id.mjs +45 -0
  255. package/dist/plugins/heading-id.mjs.map +1 -0
  256. package/dist/plugins/lower-heading.d.mts +16 -0
  257. package/dist/plugins/lower-heading.d.mts.map +1 -0
  258. package/dist/plugins/lower-heading.mjs +28 -0
  259. package/dist/plugins/lower-heading.mjs.map +1 -0
  260. package/dist/plugins/math-render.d.mts +26 -0
  261. package/dist/plugins/math-render.d.mts.map +1 -0
  262. package/dist/plugins/math-render.mjs +51 -0
  263. package/dist/plugins/math-render.mjs.map +1 -0
  264. package/dist/plugins/mod.d.mts +9 -5
  265. package/dist/plugins/mod.mjs +8 -5
  266. package/dist/plugins/remove-esm.d.mts +10 -0
  267. package/dist/plugins/remove-esm.d.mts.map +1 -0
  268. package/dist/plugins/remove-esm.mjs +12 -0
  269. package/dist/plugins/remove-esm.mjs.map +1 -0
  270. package/dist/plugins/shiki.d.mts +21 -0
  271. package/dist/plugins/shiki.d.mts.map +1 -0
  272. package/dist/plugins/shiki.mjs +144 -0
  273. package/dist/plugins/shiki.mjs.map +1 -0
  274. package/dist/plugins/syntax-highlight.d.mts +38 -0
  275. package/dist/plugins/syntax-highlight.d.mts.map +1 -0
  276. package/dist/plugins/syntax-highlight.mjs +106 -0
  277. package/dist/plugins/syntax-highlight.mjs.map +1 -0
  278. package/dist/processor.d.mts +60 -0
  279. package/dist/processor.d.mts.map +1 -0
  280. package/dist/processor.mjs +106 -0
  281. package/dist/processor.mjs.map +1 -0
  282. package/dist/ranges.d.mts +10 -0
  283. package/dist/ranges.d.mts.map +1 -0
  284. package/dist/ranges.mjs +22 -0
  285. package/dist/ranges.mjs.map +1 -0
  286. package/dist/source-map.d.mts +28 -0
  287. package/dist/source-map.d.mts.map +1 -0
  288. package/dist/source-map.mjs +90 -0
  289. package/dist/source-map.mjs.map +1 -0
  290. package/dist/source-text.d.mts +35 -0
  291. package/dist/source-text.d.mts.map +1 -0
  292. package/dist/source-text.mjs +132 -0
  293. package/dist/source-text.mjs.map +1 -0
  294. package/dist/source.d.mts +86 -0
  295. package/dist/source.d.mts.map +1 -0
  296. package/dist/source.mjs +264 -0
  297. package/dist/source.mjs.map +1 -0
  298. package/dist/stream-events.d.mts +59 -0
  299. package/dist/stream-events.d.mts.map +1 -0
  300. package/dist/stream-events.mjs +115 -0
  301. package/dist/stream-events.mjs.map +1 -0
  302. package/dist/stream-session.d.mts +79 -0
  303. package/dist/stream-session.d.mts.map +1 -0
  304. package/dist/stream-session.mjs +904 -0
  305. package/dist/stream-session.mjs.map +1 -0
  306. package/dist/stream-tail.d.mts +84 -0
  307. package/dist/stream-tail.d.mts.map +1 -0
  308. package/dist/stream-tail.mjs +359 -0
  309. package/dist/stream-tail.mjs.map +1 -0
  310. package/dist/stream-types.d.mts +89 -0
  311. package/dist/stream-types.d.mts.map +1 -0
  312. package/dist/stream-types.mjs +1 -0
  313. package/dist/stream.d.mts +28 -0
  314. package/dist/stream.d.mts.map +1 -0
  315. package/dist/stream.mjs +68 -0
  316. package/dist/stream.mjs.map +1 -0
  317. package/dist/syntax-options.d.mts +21 -0
  318. package/dist/syntax-options.d.mts.map +1 -0
  319. package/dist/syntax-options.mjs +26 -0
  320. package/dist/syntax-options.mjs.map +1 -0
  321. package/dist/traversal.d.mts +25 -0
  322. package/dist/traversal.d.mts.map +1 -0
  323. package/dist/traversal.mjs +136 -0
  324. package/dist/traversal.mjs.map +1 -0
  325. package/dist/tree.d.mts +18 -0
  326. package/dist/tree.d.mts.map +1 -0
  327. package/dist/tree.mjs +43 -0
  328. package/dist/tree.mjs.map +1 -0
  329. package/dist/unified/adapter.d.mts +24 -0
  330. package/dist/unified/adapter.d.mts.map +1 -0
  331. package/dist/unified/adapter.mjs +44 -0
  332. package/dist/unified/adapter.mjs.map +1 -0
  333. package/dist/unified/mod.d.mts +2 -0
  334. package/dist/unified/mod.mjs +1 -0
  335. package/dist/unified/runtime.d.mts +10 -0
  336. package/dist/unified/runtime.d.mts.map +1 -0
  337. package/dist/unified/runtime.mjs +115 -0
  338. package/dist/unified/runtime.mjs.map +1 -0
  339. package/dist/unified/tree-bridge.d.mts +63 -0
  340. package/dist/unified/tree-bridge.d.mts.map +1 -0
  341. package/dist/unified/tree-bridge.mjs +876 -0
  342. package/dist/unified/tree-bridge.mjs.map +1 -0
  343. package/dist/uri.d.mts +5 -0
  344. package/dist/uri.d.mts.map +1 -0
  345. package/dist/uri.mjs +32 -0
  346. package/dist/uri.mjs.map +1 -0
  347. package/package.json +56 -27
  348. package/dist/plugins/heading-id/plugin.d.mts +0 -17
  349. package/dist/plugins/heading-id/plugin.d.mts.map +0 -1
  350. package/dist/plugins/heading-id/plugin.mjs +0 -23
  351. package/dist/plugins/heading-id/plugin.mjs.map +0 -1
  352. package/dist/plugins/remove-imports-exports.d.mts +0 -10
  353. package/dist/plugins/remove-imports-exports.d.mts.map +0 -1
  354. package/dist/plugins/remove-imports-exports.mjs +0 -15
  355. package/dist/plugins/remove-imports-exports.mjs.map +0 -1
  356. package/dist/plugins/syntax-highlight/code-meta.d.mts +0 -22
  357. package/dist/plugins/syntax-highlight/code-meta.d.mts.map +0 -1
  358. package/dist/plugins/syntax-highlight/code-meta.mjs +0 -38
  359. package/dist/plugins/syntax-highlight/code-meta.mjs.map +0 -1
  360. package/dist/plugins/syntax-highlight/plugin.d.mts +0 -57
  361. package/dist/plugins/syntax-highlight/plugin.d.mts.map +0 -1
  362. package/dist/plugins/syntax-highlight/plugin.mjs +0 -93
  363. package/dist/plugins/syntax-highlight/plugin.mjs.map +0 -1
  364. package/dist/plugins/tree-processor/plugin.d.mts +0 -19
  365. package/dist/plugins/tree-processor/plugin.d.mts.map +0 -1
  366. package/dist/plugins/tree-processor/plugin.mjs +0 -21
  367. package/dist/plugins/tree-processor/plugin.mjs.map +0 -1
  368. package/dist/types.d.mts +0 -2
  369. /package/dist/{types.mjs → parser/block-syntax.mjs} +0 -0
@@ -0,0 +1,895 @@
1
+ import { sourceRange } from "../ranges.mjs";
2
+ import { PhysicalLineScanner } from "../source.mjs";
3
+ import { consumeIndent, isAsciiLetter, isBlank, isSpaceOrTab } from "./characters.mjs";
4
+ import { blockQuoteMarker, footnoteMarker, isSiblingListItem, listMarker, taskListMarker } from "./block-container-recognizers.mjs";
5
+ import { matched, noMatch } from "./recognizer.mjs";
6
+ import { directiveContainerMarker, isClosingDirectiveFence, recognizeLeafDirective } from "./block-directive-recognizers.mjs";
7
+ import { interruptsParagraph, isClosingFence, isClosingMathFence, recognizeAtxHeading, recognizeDefinition, recognizeFence, recognizeFrontmatter, recognizeMathFence, recognizeRawHtml, recognizeSameLineMath, recognizeSetext, recognizeTable, recognizeThematicBreak, tableRow, trimLineEndingOffset } from "./block-leaf-recognizers.mjs";
8
+ import { JavaScriptScanner } from "./javascript-scanner.mjs";
9
+ import { JsxBoundaryScanner } from "./embedded-scanner.mjs";
10
+ import { parseJavaScriptBoundary } from "./javascript-boundary.mjs";
11
+ //#region src/parser/block-parser.ts
12
+ var BlockParser = class BlockParser {
13
+ #blocks = [];
14
+ #containers = [];
15
+ #leaf;
16
+ #syntax;
17
+ #onSettled;
18
+ #settled;
19
+ #items = {
20
+ draft: false,
21
+ owned: /* @__PURE__ */ new WeakMap()
22
+ };
23
+ constructor(syntax, blocks = [], onSettled) {
24
+ this.#syntax = syntax;
25
+ this.#leaf = new LeafParser(syntax);
26
+ this.#blocks.push(...blocks);
27
+ this.#onSettled = onSettled;
28
+ this.#settled = settledLength(this.#blocks);
29
+ }
30
+ /** The number of top-level blocks that later input cannot change. */
31
+ get settledCount() {
32
+ return this.#settled;
33
+ }
34
+ checkpoint() {
35
+ if (this.#containers.length !== 0 || !this.#leaf.idle) return;
36
+ const tail = this.#blocks.at(-1);
37
+ if (tail?.kind === "list") this.#items.owned.delete(tail.items);
38
+ return {
39
+ length: this.#blocks.length,
40
+ tail
41
+ };
42
+ }
43
+ fork(checkpoint) {
44
+ const blocks = this.#blocks.slice(0, checkpoint.length);
45
+ if (checkpoint.tail !== void 0) blocks[blocks.length - 1] = checkpoint.tail;
46
+ return new BlockParser(this.#syntax, blocks, this.#onSettled);
47
+ }
48
+ /**
49
+ * A copy of the unsettled part: a trailing list, the open containers, and
50
+ * the active leaf. Finishing it costs only the open tail.
51
+ */
52
+ tail() {
53
+ const copy = new BlockParser(this.#syntax, this.#blocks.slice(this.#settled));
54
+ copy.#items.draft = true;
55
+ copy.#containers.push(...this.#containers);
56
+ copy.#leaf.copyFrom(this.#leaf);
57
+ return copy;
58
+ }
59
+ pending() {
60
+ return this.#leaf.pending();
61
+ }
62
+ write(source, physicalLine) {
63
+ this.#leaf.rollback();
64
+ this.writeLine(source, physicalLine);
65
+ while (this.#onSettled !== void 0 && this.#settled < settledLength(this.#blocks)) {
66
+ this.#onSettled(this.#blocks[this.#settled], this.#settled);
67
+ this.#settled++;
68
+ }
69
+ }
70
+ writeLine(source, physicalLine) {
71
+ let cursor = physicalLine.range.start === 0 && source.char(0) === "" ? physicalLine.content.start + 1 : physicalLine.content.start;
72
+ let matchedContainers = 0;
73
+ for (const [index, frame] of this.#containers.entries()) {
74
+ if (frame.kind === "directiveContainer" && isClosingDirectiveFence(source, physicalLine, cursor, frame.fenceLength)) {
75
+ this.appendLeafBlocks(this.#leaf.finish());
76
+ const current = this.#containers[index];
77
+ if (current.kind !== "directiveContainer") throw new Error("Directive frame changed while closing its leaf");
78
+ this.#containers[index] = {
79
+ ...current,
80
+ end: physicalLine.range.end
81
+ };
82
+ this.closeContainers(index);
83
+ return;
84
+ }
85
+ const continuation = continueContainer(source, physicalLine, cursor, frame);
86
+ if (continuation === void 0) break;
87
+ cursor = continuation;
88
+ matchedContainers = index + 1;
89
+ this.#containers[index] = {
90
+ ...frame,
91
+ end: physicalLine.range.end
92
+ };
93
+ }
94
+ if (matchedContainers === this.#containers.length && this.#leaf.ownsFollowingLine) {
95
+ this.appendLeafBlocks(this.#leaf.write(source, contentLine(physicalLine, cursor)));
96
+ return;
97
+ }
98
+ const unmatched = matchedContainers < this.#containers.length;
99
+ let line = contentLine(physicalLine, cursor);
100
+ const unmatchedFrame = this.#containers[matchedContainers];
101
+ const siblingItem = unmatchedFrame?.kind === "listItem" && isSiblingListItem(source, line, unmatchedFrame);
102
+ const lazy = unmatched && !siblingItem && this.#leaf.canLazyContinue(source, line);
103
+ if (lazy) for (let index = matchedContainers; index < this.#containers.length; index++) {
104
+ const frame = this.#containers[index];
105
+ this.#containers[index] = {
106
+ ...frame,
107
+ end: physicalLine.range.end
108
+ };
109
+ }
110
+ if (!lazy) {
111
+ if (unmatched) {
112
+ this.appendLeafBlocks(this.#leaf.finish());
113
+ this.closeContainers(matchedContainers);
114
+ }
115
+ if (this.#leaf.hasParagraph) {
116
+ if (opensContainer(source, line, this.#syntax)) {
117
+ this.appendLeafBlocks(this.#leaf.finish());
118
+ cursor = openContainers(source, physicalLine, cursor, this.#containers, this.#syntax);
119
+ }
120
+ } else cursor = openContainers(source, physicalLine, cursor, this.#containers, this.#syntax);
121
+ }
122
+ line = contentLine(physicalLine, cursor);
123
+ const task = taskListMarker(source, line, this.#containers, this.#leaf.hasParagraph);
124
+ if (task !== void 0) {
125
+ this.#containers[this.#containers.length - 1] = {
126
+ ...task.frame,
127
+ checked: task.checked
128
+ };
129
+ line = contentLine(physicalLine, task.contentStart);
130
+ }
131
+ if (isBlankLine(source, line)) markListBlank(this.#containers);
132
+ else settleListBlank(this.#containers, lazy ? this.#containers.length : matchedContainers);
133
+ const allowFrontmatter = physicalLine.line === 1 && this.#blocks.length === 0 && this.#containers.length === 0;
134
+ this.appendLeafBlocks(this.#leaf.write(source, line, allowFrontmatter));
135
+ }
136
+ finish(source) {
137
+ this.#leaf.rollback();
138
+ this.appendLeafBlocks(this.#leaf.finish(source));
139
+ this.closeContainers(0);
140
+ return [...this.#blocks];
141
+ }
142
+ appendLeafBlocks(blocks) {
143
+ for (const block of blocks) appendBlock(this.#blocks, this.#containers, block);
144
+ }
145
+ closeContainers(keep) {
146
+ while (this.#containers.length > keep) {
147
+ const frame = this.#containers.pop();
148
+ if (frame === void 0) throw new Error("Container stack changed while closing a frame");
149
+ if (frame.kind === "blockQuote") appendBlock(this.#blocks, this.#containers, {
150
+ kind: "blockQuote",
151
+ range: sourceRange(frame.start, frame.end),
152
+ children: frame.children
153
+ });
154
+ else if (frame.kind === "listItem") appendListItem(this.#blocks, this.#containers, frame, this.#items);
155
+ else if (frame.kind === "footnoteDefinition") appendBlock(this.#blocks, this.#containers, {
156
+ kind: "footnoteDefinition",
157
+ range: sourceRange(frame.start, frame.end),
158
+ identifier: frame.identifier,
159
+ children: frame.children
160
+ });
161
+ else if (frame.kind === "directiveContainer") appendBlock(this.#blocks, this.#containers, {
162
+ kind: "directive",
163
+ range: sourceRange(frame.start, frame.end),
164
+ name: frame.name,
165
+ label: frame.label,
166
+ attributes: frame.attributes,
167
+ children: frame.children
168
+ });
169
+ }
170
+ }
171
+ };
172
+ /** Arrays an open leaf grows in place. Only the parser that created one extends it. */
173
+ const growable = /* @__PURE__ */ new WeakSet();
174
+ function isGrowable(array) {
175
+ return growable.has(array);
176
+ }
177
+ var LeafParser = class {
178
+ #syntax;
179
+ #active;
180
+ /** Set on a tail draft: extensions are logged so the parser can undo them. */
181
+ #draftLog;
182
+ #log = [];
183
+ #expressionScanner;
184
+ #jsxScanner;
185
+ constructor(syntax) {
186
+ this.#syntax = syntax;
187
+ }
188
+ get hasParagraph() {
189
+ return this.#active?.kind === "paragraph";
190
+ }
191
+ get idle() {
192
+ return this.#active === void 0;
193
+ }
194
+ get ownsFollowingLine() {
195
+ const kind = this.#active?.kind;
196
+ return kind === "fencedCode" || kind === "html" || kind === "frontmatter" || kind === "math" || kind === "expression" || kind === "jsx" || kind === "esm";
197
+ }
198
+ copyFrom(source) {
199
+ source.rollback();
200
+ this.#draftLog = source.#log;
201
+ this.#active = source.#active;
202
+ this.#expressionScanner = source.#expressionScanner?.clone();
203
+ this.#jsxScanner = source.#jsxScanner?.clone();
204
+ }
205
+ /** Undoes a tail draft's extensions, so the open leaf holds only written lines. */
206
+ rollback() {
207
+ for (let index = this.#log.length - 1; index >= 0; index--) {
208
+ const [array, length] = this.#log[index];
209
+ array.length = length;
210
+ }
211
+ this.#log.length = 0;
212
+ }
213
+ /**
214
+ * Appends to a leaf array without copying it. A tail draft logs the old
215
+ * length, so the parser it came from can undo the extension.
216
+ */
217
+ grow(array, ...items) {
218
+ if (!isGrowable(array)) {
219
+ const copy = [...array, ...items];
220
+ growable.add(copy);
221
+ return copy;
222
+ }
223
+ this.#draftLog?.push([array, array.length]);
224
+ array.push(...items);
225
+ return array;
226
+ }
227
+ pending() {
228
+ const active = this.#active;
229
+ if (active === void 0) return;
230
+ if (active.kind === "paragraph") return {
231
+ kind: "paragraph",
232
+ range: sourceRange(active.start, active.end),
233
+ input: active.lines
234
+ };
235
+ if (active.kind === "fencedCode") return {
236
+ kind: "fencedCode",
237
+ range: sourceRange(active.start, active.end),
238
+ value: active.value,
239
+ language: active.language,
240
+ meta: active.meta
241
+ };
242
+ if (active.kind === "math") return {
243
+ kind: "math",
244
+ range: sourceRange(active.start, active.end),
245
+ value: active.value,
246
+ format: active.format
247
+ };
248
+ if (active.kind === "jsx") return {
249
+ kind: "jsx",
250
+ range: sourceRange(active.start, active.end),
251
+ opening: this.#jsxScanner?.opening()
252
+ };
253
+ if (active.kind === "expression" || active.kind === "esm") return {
254
+ kind: active.kind,
255
+ range: sourceRange(active.start, active.end)
256
+ };
257
+ }
258
+ canLazyContinue(source, line) {
259
+ return this.#active?.kind === "paragraph" && !isBlankLine(source, line) && !this.interruptsParagraph(source, line) && !opensContainer(source, line, this.#syntax);
260
+ }
261
+ write(source, line, allowFrontmatter = false) {
262
+ const blocks = [];
263
+ if (this.continueActive(source, line, blocks)) return blocks;
264
+ if (isBlankLine(source, line)) return [...blocks, ...this.finish()];
265
+ if (this.continueParagraph(source, line, blocks)) return blocks;
266
+ this.startLeaf(source, line, allowFrontmatter, blocks);
267
+ return blocks;
268
+ }
269
+ /**
270
+ * Feeds a line to an open leaf that owns its lines. Returns `false` when the
271
+ * leaf closed without consuming the line, so the line starts new content.
272
+ */
273
+ continueActive(source, line, blocks) {
274
+ const active = this.#active;
275
+ switch (active?.kind) {
276
+ case "expression":
277
+ case "jsx":
278
+ this.continueEmbedded(source, line, active, blocks);
279
+ return true;
280
+ case "esm":
281
+ if (isBlankLine(source, line)) blocks.push(this.finishEmbedded(source));
282
+ else this.#active = {
283
+ ...active,
284
+ end: line.range.end,
285
+ value: this.grow(active.value, embeddedSegment(line))
286
+ };
287
+ return true;
288
+ case "html":
289
+ if (source.slice(line.content.start, line.content.end).includes(active.closing)) blocks.push(this.closeActive(line.range.end));
290
+ else this.#active = {
291
+ ...active,
292
+ end: line.range.end
293
+ };
294
+ return true;
295
+ case "frontmatter":
296
+ if (source.slice(line.content.start, line.content.end).trim() === active.fence) blocks.push(this.closeActive(line.range.end));
297
+ else this.#active = {
298
+ ...active,
299
+ end: line.range.end,
300
+ valueEnd: line.range.end
301
+ };
302
+ return true;
303
+ case "math":
304
+ if (isClosingMathFence(source, line, active)) blocks.push(this.closeActive(line.range.end));
305
+ else this.#active = {
306
+ ...active,
307
+ end: line.range.end,
308
+ value: this.grow(active.value, {
309
+ kind: "source",
310
+ range: line.range
311
+ })
312
+ };
313
+ return true;
314
+ case "fencedCode":
315
+ if (isClosingFence(source, line, active)) blocks.push(this.closeActive(line.range.end));
316
+ else this.#active = {
317
+ ...active,
318
+ end: line.range.end,
319
+ value: this.grow(active.value, {
320
+ kind: "source",
321
+ range: line.range
322
+ })
323
+ };
324
+ return true;
325
+ case "indentedCode": return this.continueIndentedCode(source, line, active, blocks);
326
+ case "table": return this.continueTable(source, line, active, blocks);
327
+ case "paragraph":
328
+ case void 0: return false;
329
+ default: return active;
330
+ }
331
+ }
332
+ continueEmbedded(source, line, active, blocks) {
333
+ const scanner = active.kind === "expression" ? this.#expressionScanner : this.#jsxScanner;
334
+ if (scanner === void 0) throw new Error(`Missing retained scanner for ${active.kind}`);
335
+ const result = scanner.append(source.slice(line.range.start, line.range.end));
336
+ this.#active = {
337
+ ...active,
338
+ end: line.range.end,
339
+ value: this.grow(active.value, embeddedSegment(line))
340
+ };
341
+ if (result.kind !== "open") blocks.push(this.finishEmbedded(source, result.kind === "invalid"));
342
+ }
343
+ /** Blank lines stay pending until more indented code follows them. */
344
+ continueIndentedCode(source, line, active, blocks) {
345
+ if (isBlankLine(source, line)) {
346
+ this.#active = {
347
+ ...active,
348
+ end: line.range.end,
349
+ pendingBlank: this.grow(active.pendingBlank, {
350
+ kind: "source",
351
+ range: sourceRange(line.content.end, line.range.end)
352
+ })
353
+ };
354
+ return true;
355
+ }
356
+ const indented = indentedCodeLine(source, line);
357
+ if (indented !== void 0) {
358
+ this.#active = {
359
+ ...active,
360
+ end: line.range.end,
361
+ value: this.grow(active.value, ...active.pendingBlank, ...indented),
362
+ pendingBlank: []
363
+ };
364
+ return true;
365
+ }
366
+ blocks.push(this.closeActive());
367
+ return false;
368
+ }
369
+ continueTable(source, line, active, blocks) {
370
+ if (isBlankLine(source, line)) {
371
+ blocks.push(this.closeActive());
372
+ return false;
373
+ }
374
+ this.#active = {
375
+ ...active,
376
+ end: line.range.end,
377
+ rows: this.grow(active.rows, tableRow(source, line.content))
378
+ };
379
+ return true;
380
+ }
381
+ /**
382
+ * A paragraph line can turn the paragraph into a setext heading or a table,
383
+ * or continue it. Returns `false` when the line interrupts the paragraph.
384
+ */
385
+ continueParagraph(source, line, blocks) {
386
+ const active = this.#active;
387
+ if (active?.kind !== "paragraph") return false;
388
+ const setext = recognizeSetext(source, line, active);
389
+ if (setext.kind === "matched") {
390
+ blocks.push(setext.value);
391
+ this.#active = void 0;
392
+ return true;
393
+ }
394
+ const table = recognizeTable(source, line, active);
395
+ if (table.kind === "matched") {
396
+ this.#active = table.value;
397
+ return true;
398
+ }
399
+ if (this.interruptsParagraph(source, line)) {
400
+ blocks.push(this.closeActive());
401
+ return false;
402
+ }
403
+ this.#active = {
404
+ kind: "paragraph",
405
+ start: active.start,
406
+ end: line.content.end,
407
+ lines: this.grow(active.lines, {
408
+ kind: "source",
409
+ range: active.pendingEnding
410
+ }, {
411
+ kind: "source",
412
+ range: line.content
413
+ }),
414
+ pendingEnding: sourceRange(line.content.end, line.range.end)
415
+ };
416
+ return true;
417
+ }
418
+ /** Starts the leaf a non-blank line opens, in CommonMark precedence order. */
419
+ startLeaf(source, line, allowFrontmatter, blocks) {
420
+ if (!startsParagraph(source, line.content.start)) {
421
+ if (allowFrontmatter) {
422
+ const frontmatter = recognizeFrontmatter(source, line, this.#syntax);
423
+ if (frontmatter.kind === "matched") {
424
+ this.#active = frontmatter.value;
425
+ return;
426
+ }
427
+ }
428
+ for (const recognize of [recognizeLeafDirective, recognizeSameLineMath]) {
429
+ const result = recognize(source, line, this.#syntax);
430
+ if (result.kind === "matched") {
431
+ blocks.push(result.value);
432
+ return;
433
+ }
434
+ }
435
+ const math = recognizeMathFence(source, line, this.#syntax);
436
+ if (math.kind === "matched") {
437
+ this.#active = math.value;
438
+ return;
439
+ }
440
+ if (this.startEmbedded(source, line, blocks)) return;
441
+ for (const recognize of [
442
+ recognizeRawHtml,
443
+ recognizeDefinition,
444
+ recognizeFence,
445
+ recognizeAtxHeading,
446
+ recognizeThematicBreak
447
+ ]) {
448
+ const result = recognize(source, line);
449
+ if (result.kind === "matched") {
450
+ if (result.value.kind === "openLeaf") this.#active = result.value.leaf;
451
+ else blocks.push(result.value.block);
452
+ return;
453
+ }
454
+ }
455
+ const indented = indentedCodeLine(source, line);
456
+ if (indented !== void 0) {
457
+ this.#active = {
458
+ kind: "indentedCode",
459
+ start: line.range.start,
460
+ end: line.range.end,
461
+ value: indented,
462
+ pendingBlank: []
463
+ };
464
+ return;
465
+ }
466
+ }
467
+ this.#active = {
468
+ kind: "paragraph",
469
+ start: line.content.start,
470
+ end: line.content.end,
471
+ lines: [{
472
+ kind: "source",
473
+ range: line.content
474
+ }],
475
+ pendingEnding: sourceRange(line.content.end, line.range.end)
476
+ };
477
+ }
478
+ /**
479
+ * Starts flow JSX, an expression, or ESM. Returns `false` when the construct
480
+ * closes with more content on its line, which makes it phrasing content.
481
+ */
482
+ startEmbedded(source, line, blocks) {
483
+ const embedded = recognizeEmbeddedFlowStart(source, line);
484
+ if (embedded.kind !== "matched") return false;
485
+ this.#active = {
486
+ kind: embedded.value.kind,
487
+ start: line.content.start,
488
+ end: line.range.end,
489
+ value: [embeddedSegment(line)]
490
+ };
491
+ if (embedded.value.kind === "esm") return true;
492
+ const start = embedded.value.kind === "expression" ? embedded.value.markerEnd : line.content.start;
493
+ const text = source.slice(start, line.range.end);
494
+ let result;
495
+ if (embedded.value.kind === "expression") {
496
+ this.#expressionScanner = new JavaScriptScanner("}");
497
+ result = this.#expressionScanner.append(text);
498
+ } else {
499
+ this.#jsxScanner = new JsxBoundaryScanner();
500
+ result = this.#jsxScanner.append(text);
501
+ }
502
+ if (!(result.kind === "closed" && !isBlank(source.slice(start + result.offset, line.content.end)))) {
503
+ if (result.kind !== "open") blocks.push(this.finishEmbedded(source, result.kind === "invalid"));
504
+ return true;
505
+ }
506
+ this.#active = void 0;
507
+ this.#expressionScanner = void 0;
508
+ this.#jsxScanner = void 0;
509
+ return false;
510
+ }
511
+ finish(source) {
512
+ if (this.#active?.kind === "esm" && source !== void 0) return [this.finishEmbedded(source)];
513
+ if (this.#active?.kind === "frontmatter" && source !== void 0) {
514
+ const active = this.#active;
515
+ this.#active = void 0;
516
+ const contentEnd = trimLineEndingOffset(source, active.valueEnd);
517
+ const paragraphStart = active.format === "yaml" ? active.valueStart : active.start;
518
+ const fallback = [];
519
+ if (active.format === "yaml") fallback.push({
520
+ kind: "thematicBreak",
521
+ range: sourceRange(active.start, trimLineEndingOffset(source, active.valueStart))
522
+ });
523
+ if (contentEnd > paragraphStart) fallback.push({
524
+ kind: "paragraph",
525
+ range: sourceRange(paragraphStart, contentEnd),
526
+ input: [{
527
+ kind: "source",
528
+ range: sourceRange(paragraphStart, contentEnd)
529
+ }]
530
+ });
531
+ return fallback;
532
+ }
533
+ if (this.#active?.kind === "expression" || this.#active?.kind === "jsx" || this.#active?.kind === "esm") {
534
+ const active = this.#active;
535
+ const opening = this.#jsxScanner?.opening();
536
+ this.#active = void 0;
537
+ this.#expressionScanner = void 0;
538
+ this.#jsxScanner = void 0;
539
+ return [{
540
+ kind: "invalidMdx",
541
+ range: sourceRange(active.start, active.end),
542
+ syntax: active.kind,
543
+ state: "incomplete",
544
+ opening
545
+ }];
546
+ }
547
+ return this.#active === void 0 ? [] : [this.closeActive()];
548
+ }
549
+ finishEmbedded(source, structurallyInvalid = false) {
550
+ const active = this.#active;
551
+ if (active?.kind !== "expression" && active?.kind !== "jsx" && active?.kind !== "esm") throw new Error("Cannot finish a missing embedded flow leaf");
552
+ this.#active = void 0;
553
+ this.#expressionScanner = void 0;
554
+ this.#jsxScanner = void 0;
555
+ const authored = segmentsText(source, active.value);
556
+ const javascript = active.kind === "expression" ? authored.slice(authored.indexOf("{") + 1, authored.lastIndexOf("}")) : authored;
557
+ const boundary = structurallyInvalid || active.kind === "expression" && javascript.trim() === "" ? void 0 : parseJavaScriptBoundary(active.kind === "jsx" ? "jsxExpression" : active.kind, javascript, active.kind === "expression" ? active.start + authored.indexOf("{") + 1 : active.start);
558
+ return !structurallyInvalid && (active.kind === "expression" && javascript.trim() === "" || boundary?.kind === "valid") ? {
559
+ kind: active.kind,
560
+ range: sourceRange(active.start, active.end)
561
+ } : {
562
+ kind: "invalidMdx",
563
+ range: sourceRange(active.start, active.end),
564
+ syntax: active.kind,
565
+ state: "invalid"
566
+ };
567
+ }
568
+ closeActive(end) {
569
+ const active = this.#active;
570
+ if (active === void 0) throw new Error("Cannot close a missing leaf");
571
+ this.#active = void 0;
572
+ if (active.kind === "paragraph") return {
573
+ kind: "paragraph",
574
+ range: sourceRange(active.start, active.end),
575
+ input: active.lines
576
+ };
577
+ if (active.kind === "fencedCode") return {
578
+ kind: "code",
579
+ range: sourceRange(active.start, end ?? active.end),
580
+ value: active.value,
581
+ fenced: true,
582
+ language: active.language,
583
+ meta: active.meta
584
+ };
585
+ if (active.kind === "indentedCode") return {
586
+ kind: "code",
587
+ range: sourceRange(active.start, active.end),
588
+ value: active.value,
589
+ fenced: false,
590
+ language: void 0,
591
+ meta: void 0
592
+ };
593
+ if (active.kind === "table") return {
594
+ kind: "table",
595
+ range: sourceRange(active.start, active.end),
596
+ alignments: active.alignments,
597
+ rows: active.rows
598
+ };
599
+ if (active.kind === "frontmatter") return {
600
+ kind: "frontmatter",
601
+ range: sourceRange(active.start, end ?? active.end),
602
+ value: sourceRange(active.valueStart, active.valueEnd),
603
+ format: active.format
604
+ };
605
+ if (active.kind === "math") return {
606
+ kind: "math",
607
+ range: sourceRange(active.start, end ?? active.end),
608
+ value: active.value,
609
+ format: active.format,
610
+ meta: active.meta
611
+ };
612
+ if (active.kind === "html") return {
613
+ kind: "rawHtml",
614
+ range: sourceRange(active.start, end ?? active.end)
615
+ };
616
+ throw new Error(`Cannot close unimplemented ${active.kind} leaf`);
617
+ }
618
+ interruptsParagraph(source, line) {
619
+ if (startsParagraph(source, line.content.start)) return false;
620
+ return interruptsParagraph(source, line) || recognizeLeafDirective(source, line, this.#syntax).kind === "matched" || recognizeSameLineMath(source, line, this.#syntax).kind === "matched" || recognizeMathFence(source, line, this.#syntax).kind === "matched" || recognizeEmbeddedFlowStart(source, line).kind === "matched";
621
+ }
622
+ };
623
+ /** Unindented letters start paragraphs, except the ESM keywords import and export. */
624
+ function startsParagraph(source, start) {
625
+ const character = source.char(start);
626
+ return isAsciiLetter(character) && character !== "i" && character !== "e";
627
+ }
628
+ /** Rejects ordinary content before slicing a potentially long, chunked line. */
629
+ function isBlankLine(source, line) {
630
+ return line.content.start === line.content.end || isSpaceOrTab(source.char(line.content.start)) && isBlank(source.slice(line.content.start, line.content.end));
631
+ }
632
+ function matchEmbeddedFlowStart(source, line) {
633
+ const start = consumeIndent(source, line.content.start, line.content.end, 3).offset;
634
+ const content = source.slice(start, line.content.end);
635
+ if (content.startsWith("{")) return {
636
+ kind: "expression",
637
+ markerEnd: start + 1
638
+ };
639
+ if (/^<(?:>|\/(?:>|[A-Za-z_$][\w$-]*(?:[.:][A-Za-z_$][\w$-]*)*(?=[\s>]|$))|[A-Za-z_$][\w$-]*(?:[.:][A-Za-z_$][\w$-]*)*(?=[\s/{>]|$))/u.test(content)) return {
640
+ kind: "jsx",
641
+ markerEnd: start + 1
642
+ };
643
+ if (/^(?:import\s|export(?:\s|\{))/u.test(content)) return {
644
+ kind: "esm",
645
+ markerEnd: start
646
+ };
647
+ }
648
+ function recognizeEmbeddedFlowStart(source, line) {
649
+ const match = matchEmbeddedFlowStart(source, line);
650
+ return match === void 0 ? noMatch : matched(match);
651
+ }
652
+ function segmentsText(source, segments) {
653
+ let value = "";
654
+ for (const segment of segments) value += segment.kind === "source" ? source.slice(segment.range.start, segment.range.end) : " ".repeat(segment.columns);
655
+ return value;
656
+ }
657
+ /**
658
+ * Top-level blocks that later input cannot change. A closing list item merges
659
+ * into a preceding list with the same marker, so only a trailing list can grow.
660
+ */
661
+ function settledLength(blocks) {
662
+ return blocks.at(-1)?.kind === "list" ? blocks.length - 1 : blocks.length;
663
+ }
664
+ function appendBlock(root, containers, block) {
665
+ const parent = containers.at(-1);
666
+ if (parent === void 0) {
667
+ root.push(block);
668
+ return;
669
+ }
670
+ if (parent.kind === "directiveContainer") {
671
+ const children = [...parent.children, block];
672
+ containers[containers.length - 1] = {
673
+ ...parent,
674
+ children
675
+ };
676
+ return;
677
+ }
678
+ const children = [...parent.children, block];
679
+ const index = containers.length - 1;
680
+ containers[index] = {
681
+ ...parent,
682
+ children
683
+ };
684
+ }
685
+ function appendListItem(root, containers, frame, growth) {
686
+ const item = {
687
+ range: sourceRange(frame.rangeStart, frame.end),
688
+ checked: frame.checked,
689
+ spread: frame.spread,
690
+ children: frame.children
691
+ };
692
+ const parent = containers.at(-1);
693
+ const siblings = parent === void 0 ? root : [...parent.children];
694
+ const previous = siblings.at(-1);
695
+ if (previous?.kind === "list" && previous.ordered === frame.ordered && previous.marker === frame.markerCharacter) siblings[siblings.length - 1] = {
696
+ ...previous,
697
+ range: sourceRange(previous.range.start, frame.end),
698
+ spread: previous.spread || previous.trailingBlank || frame.spread,
699
+ ...grownItems(previous, item, parent === void 0 ? growth : void 0),
700
+ trailingBlank: frame.blankPending
701
+ };
702
+ else siblings.push({
703
+ kind: "list",
704
+ range: sourceRange(frame.rangeStart, frame.end),
705
+ ordered: frame.ordered,
706
+ start: frame.start,
707
+ spread: frame.spread,
708
+ marker: frame.markerCharacter,
709
+ items: [item],
710
+ trailingBlank: frame.blankPending
711
+ });
712
+ if (parent !== void 0) containers[containers.length - 1] = {
713
+ ...parent,
714
+ children: siblings
715
+ };
716
+ }
717
+ /** The items after appending `item`, without copying the items a top-level list already has. */
718
+ function grownItems(list, item, growth) {
719
+ if (growth === void 0) return { items: [
720
+ ...list.items,
721
+ ...list.closing ?? [],
722
+ item
723
+ ] };
724
+ if (growth.draft) return {
725
+ items: list.items,
726
+ closing: [...list.closing ?? [], item]
727
+ };
728
+ const owned = growth.owned.get(list.items);
729
+ if (owned !== void 0) {
730
+ owned.push(item);
731
+ return { items: owned };
732
+ }
733
+ const items = [...list.items, item];
734
+ growth.owned.set(items, items);
735
+ return { items };
736
+ }
737
+ function continueContainer(source, line, cursor, frame) {
738
+ if (frame.kind === "blockQuote") return blockQuoteMarker(source, line.content.end, cursor)?.contentStart;
739
+ if (frame.kind === "listItem") {
740
+ if (isBlank(source.slice(cursor, line.content.end))) return line.content.end;
741
+ return consumeColumns(source, cursor, line.content.end, frame.contentIndent);
742
+ }
743
+ if (frame.kind === "footnoteDefinition") {
744
+ if (isBlank(source.slice(cursor, line.content.end))) return line.content.end;
745
+ return consumeColumns(source, cursor, line.content.end, frame.contentIndent);
746
+ }
747
+ if (frame.kind === "directiveContainer") return cursor;
748
+ }
749
+ function openContainers(source, line, initialCursor, containers, syntax) {
750
+ let cursor = initialCursor;
751
+ while (cursor < line.content.end) {
752
+ if (isAsciiLetter(source.char(cursor))) break;
753
+ const quote = blockQuoteMarker(source, line.content.end, cursor);
754
+ if (quote !== void 0) {
755
+ containers.push({
756
+ kind: "blockQuote",
757
+ marker: sourceRange(quote.markerStart, quote.markerEnd),
758
+ contentIndent: quote.contentStart - quote.markerEnd,
759
+ start: quote.markerStart,
760
+ end: line.range.end,
761
+ children: []
762
+ });
763
+ cursor = quote.contentStart;
764
+ continue;
765
+ }
766
+ const footnote = footnoteMarker(source, line.content.end, cursor);
767
+ if (footnote !== void 0) {
768
+ containers.push({
769
+ kind: "footnoteDefinition",
770
+ marker: sourceRange(footnote.markerStart, footnote.markerEnd),
771
+ identifier: footnote.identifier,
772
+ contentIndent: 4,
773
+ start: footnote.markerStart,
774
+ end: line.range.end,
775
+ children: []
776
+ });
777
+ cursor = footnote.contentStart;
778
+ continue;
779
+ }
780
+ const directive = syntax.directives ? directiveContainerMarker(source, line.content.end, cursor) : void 0;
781
+ if (directive !== void 0) {
782
+ containers.push({
783
+ kind: "directiveContainer",
784
+ marker: sourceRange(directive.markerStart, directive.markerEnd),
785
+ name: directive.name,
786
+ fenceLength: directive.fenceLength,
787
+ start: directive.markerStart,
788
+ end: line.range.end,
789
+ children: [],
790
+ label: directive.label,
791
+ attributes: directive.attributes
792
+ });
793
+ cursor = line.content.end;
794
+ continue;
795
+ }
796
+ const adjusted = contentLine(line, cursor);
797
+ if (recognizeThematicBreak(source, adjusted).kind === "matched") break;
798
+ const list = listMarker(source, line.content.end, cursor);
799
+ if (list === void 0) break;
800
+ containers.push({
801
+ kind: "listItem",
802
+ marker: sourceRange(list.markerStart, list.markerEnd),
803
+ markerCharacter: list.markerCharacter,
804
+ contentIndent: list.contentIndent,
805
+ ordered: list.ordered,
806
+ start: list.start,
807
+ checked: void 0,
808
+ spread: false,
809
+ blankPending: false,
810
+ rangeStart: list.markerStart,
811
+ end: line.range.end,
812
+ children: []
813
+ });
814
+ cursor = list.contentStart;
815
+ }
816
+ return cursor;
817
+ }
818
+ function opensContainer(source, line, syntax) {
819
+ if (isAsciiLetter(source.char(line.content.start))) return false;
820
+ return blockQuoteMarker(source, line.content.end, line.content.start) !== void 0 || footnoteMarker(source, line.content.end, line.content.start) !== void 0 || syntax.directives && directiveContainerMarker(source, line.content.end, line.content.start) !== void 0 || recognizeThematicBreak(source, line).kind !== "matched" && listMarker(source, line.content.end, line.content.start, true) !== void 0;
821
+ }
822
+ function consumeColumns(source, start, end, required) {
823
+ const indent = consumeIndent(source, start, end, required);
824
+ return indent.columns >= required ? indent.offset : void 0;
825
+ }
826
+ function indentedCodeLine(source, line) {
827
+ const contentStart = consumeColumns(source, line.content.start, line.content.end, 4);
828
+ return contentStart === void 0 ? void 0 : [{
829
+ kind: "source",
830
+ range: sourceRange(contentStart, line.range.end)
831
+ }];
832
+ }
833
+ /** Records a blank line in the trailing list items that directly contain it. */
834
+ function markListBlank(containers) {
835
+ for (let index = containers.length - 1; index >= 0; index--) {
836
+ const frame = containers[index];
837
+ if (frame.kind !== "listItem") return;
838
+ containers[index] = {
839
+ ...frame,
840
+ blankPending: true
841
+ };
842
+ }
843
+ }
844
+ /**
845
+ * Resolves pending blank lines once content arrives. Only the deepest surviving
846
+ * item receives a new direct child after the blank line, which makes it loose. A
847
+ * new sibling item of a nested list keeps the blank inside that nested list.
848
+ */
849
+ function settleListBlank(containers, surviving) {
850
+ const opened = containers[surviving];
851
+ for (let index = 0; index < surviving; index++) {
852
+ const frame = containers[index];
853
+ if (frame.kind !== "listItem" || !frame.blankPending) continue;
854
+ const last = frame.children.at(-1);
855
+ const nestedSibling = opened?.kind === "listItem" && last?.kind === "list" && last.ordered === opened.ordered && last.marker === opened.markerCharacter;
856
+ containers[index] = {
857
+ ...frame,
858
+ blankPending: false,
859
+ spread: frame.spread || index === surviving - 1 && !nestedSibling
860
+ };
861
+ }
862
+ }
863
+ function contentLine(line, contentStart) {
864
+ if (line.range.start === contentStart) return line;
865
+ return {
866
+ line: line.line,
867
+ range: sourceRange(contentStart, line.range.end),
868
+ content: sourceRange(contentStart, line.content.end),
869
+ ending: line.ending
870
+ };
871
+ }
872
+ /**
873
+ * Parses a nested flow region, such as multi-line JSX children, with offsets in
874
+ * the enclosing source. Frontmatter is never recognized inside the region.
875
+ */
876
+ function parseFlowRange(source, range, syntax) {
877
+ const scanner = new PhysicalLineScanner({ offset: range.start });
878
+ const parser = new BlockParser({
879
+ ...syntax,
880
+ frontmatter: []
881
+ });
882
+ for (const physicalLine of [...scanner.append(source.slice(range.start, range.end)), ...scanner.complete()]) parser.write(source, physicalLine);
883
+ return parser.finish(source);
884
+ }
885
+ /** An embedded flow line from its content to the end of the line, including the ending. */
886
+ function embeddedSegment(line) {
887
+ return {
888
+ kind: "source",
889
+ range: sourceRange(line.content.start, line.range.end)
890
+ };
891
+ }
892
+ //#endregion
893
+ export { BlockParser, parseFlowRange };
894
+
895
+ //# sourceMappingURL=block-parser.mjs.map