@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
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
  <h1 align="center" style="text-decoration:none;">@temelj/mdx</h1>
3
3
  <br/>
4
4
  <p align="center">
5
- Utilities for working with MDX.
5
+ MDX parsing, formatting, compilation, safe rendering, and streaming.
6
6
  </p>
7
7
  </p>
8
8
 
@@ -29,92 +29,478 @@
29
29
  ## Installation
30
30
 
31
31
  ```sh
32
- # npm
33
32
  $ npm install @temelj/mdx
34
- # jsr
35
- $ deno add jsr:@temelj/mdx # or jsr add @temelj/mdx
36
- ```
37
-
38
- ## Compile
39
-
40
- ```ts ignore
41
- import {
42
- type HastElement,
43
- headingIdPlugin,
44
- MdxCompiler,
45
- syntaxHighlightPlugin,
46
- treeProcessorPlugin,
47
- } from "@temelj/mdx";
48
- import { z } from "zod";
49
-
50
- const compiler = new MdxCompiler()
51
- .withRehypePlugin(headingIdPlugin, {
52
- prefix: "h-",
53
- })
54
- .withRehypePlugin(syntaxHighlightPlugin, {
55
- highlight: {},
56
- lineNumbers: {},
57
- commandLine: {},
58
- shikiHastOptions: {
59
- // themes: {
60
- // light: lightTheme,
61
- // dark: darkTheme,
62
- // },
63
- },
64
- });
65
-
66
- const source = `
67
- ---
68
- title: Demo
69
- ---
70
- # Hello
71
-
72
- This will compile MDX to a render-able artifact.
73
- With '@temelj/mdx-react' you can render it in an React app.
74
-
75
- You can validate the frontmatter with any Standard Schema-compatible validator.
76
-
77
- There are a few useful plugins:
78
- - Use 'headingIdPlugin' to update heading tags (h1, h2, etc.) with IDs generated by slugging their text content.
79
- This is useful for linking to headings in a page.
80
- - Use 'syntaxHighlightPlugin' to highlight code blocks using [Shiki](https://github.com/shikijs/shiki).
81
- You can highlight individual lines, show line numbers, or display a prompt.
82
- - Use 'treeProcessorPlugin' to modify the HAST tree.
83
- For example, change image URLs to point to a CDN.
84
-
85
- \`\`\`bash {"commandLine": "0"}
86
- whoamai
87
- @temelj/mdx
88
- \`\`\`
89
- `.trim();
90
-
91
- const frontmatterSchema = z.object({
92
- title: z.string(),
33
+ ```
34
+
35
+ ## Get started
36
+
37
+ Use `parse()` to parse an MDX string into a tree.
38
+ Then, render that tree as HTML.
39
+
40
+ ```ts
41
+ import { formatHtml, formatMdx, lowerHtml, parse } from "@temelj/mdx";
42
+
43
+ const { document, file } = parse("# Hello\n\nSome **MDX**.");
44
+
45
+ console.log(formatHtml(lowerHtml(document, { source: file })));
46
+ // <h1>Hello</h1>
47
+ // <p>Some <strong>MDX</strong>.</p>
48
+
49
+ // Or write the tree back as canonical MDX.
50
+ console.log(formatMdx(document));
51
+ ```
52
+
53
+ Parser runs in the browser or on the server and returns readonly trees you can serialize as JSON.
54
+ For React, use [`@temelj/mdx-react`](../mdx-react/README.md).
55
+
56
+ ## The MDX dialect
57
+
58
+ The default grammar supports CommonMark 0.31.2 with GFM extensions.
59
+ It also parses MDX v3 syntax.
60
+ You can configure how syntax works.
61
+
62
+ ```ts
63
+ import { parse } from "@temelj/mdx";
64
+
65
+ const source = [
66
+ "---",
67
+ "title: Matrices",
68
+ "---",
69
+ "",
70
+ "The tile area is $M \\times N$.",
71
+ "",
72
+ ":::note",
73
+ "Start with a small tile.",
74
+ ":::",
75
+ ].join("\n");
76
+
77
+ const result = parse(source, {
78
+ syntax: {
79
+ frontmatter: "auto", // Also "yaml" or "toml".
80
+ math: "auto", // Also "dollar" or "tex".
81
+ directives: true,
82
+ strikethroughMarkerCount: 2, // Use 1 to also accept ~deleted~.
83
+ },
84
+ });
85
+ ```
86
+
87
+ Math is disabled by default.
88
+ Set `syntax.math` to `"dollar"` for inline `$...$` and display `$$...$$`, or `"tex"` for inline `\(...\)` and display `\[...\]`.
89
+ `"auto"` accepts both delimiter families in the same document.
90
+
91
+ ## Parse a document
92
+
93
+ ```ts
94
+ import { parse, SourceFile } from "@temelj/mdx";
95
+
96
+ // Give the source a filename for diagnostics.
97
+ const file = new SourceFile({
98
+ name: "article.mdx",
99
+ text: "# Matrices\n\nMultiply **rows**.",
100
+ });
101
+
102
+ const result = parse(file);
103
+ console.log(result.document.kind); // "document"
104
+ console.log(result.diagnostics); // Warnings; syntax errors throw ParseError.
105
+ console.log(result.file.location(2)); // { offset: 2, line: 1, column: 3 }
106
+ ```
107
+
108
+ ## Parse into AST
109
+
110
+ ```ts
111
+ import { formatMdx, nodeText, parse, rewriteMdx, selectMdx } from "@temelj/mdx";
112
+
113
+ const result = parse("# Matrices\n\n![Tile](/tile.png)\n\n---\n");
114
+
115
+ // Select nodes by kind.
116
+ // Origins point into the original source file.
117
+ for (const { node } of selectMdx(result.document, "heading")) {
118
+ console.log(node.depth, nodeText(node)); // 1, "Matrices"
119
+ if (node.origin !== undefined) {
120
+ console.log(result.file.slice(node.origin)); // "# Matrices"
121
+ }
122
+ }
123
+
124
+ // Rewrite without mutating the original document.
125
+ const edited = rewriteMdx(result.document, {
126
+ thematicBreak: () => null, // Remove a node.
127
+ image: ({ node }) => ({ ...node, url: node.url.replace(/\.png$/u, ".webp") }),
128
+ // Returning undefined keeps a node as it is.
129
+ });
130
+
131
+ console.log(formatMdx(edited, { bullet: "-", emphasis: "_" }));
132
+ ```
133
+
134
+ Use `walkMdx()` when you need a visitor rather than a selection.
135
+ HTML trees have matching `walkHtml()`, `selectHtml()`, and `rewriteHtml()` helpers.
136
+
137
+ `indexDocument()` finds definitions and footnotes.
138
+ `documentFrontmatter()` reads decoded frontmatter.
139
+
140
+ ## Render HTML
141
+
142
+ ```ts
143
+ import { formatHtml, lowerHtml, parse } from "@temelj/mdx";
144
+
145
+ const result = parse('{2 + 2}\n\n<Alert title="Note" />');
146
+ const html = lowerHtml(result.document, { source: result.file });
147
+
148
+ console.log(formatHtml(html));
149
+ // {2 + 2}
150
+ //
151
+ // &lt;Alert title="Note" />
152
+ ```
153
+
154
+ Raw HTML is escaped too.
155
+
156
+ For HTML you trust, pass `rawHtml: "trusted"` to the serializer:
157
+
158
+ ```ts
159
+ import { formatHtml, lowerHtml, parse } from "@temelj/mdx";
160
+
161
+ const result = parse("<!-- A comment -->");
162
+ const html = lowerHtml(result.document, { source: result.file });
163
+
164
+ console.log(formatHtml(html)); // &lt;!-- A comment -->
165
+ console.log(formatHtml(html, { rawHtml: "trusted" })); // <!-- A comment -->
166
+ // This option does not evaluate JSX or expressions.
167
+ ```
168
+
169
+ ESM is omitted.
170
+ Unsafe link and image URLs are removed during lowering.
171
+ Use `urlTransform` to customize that.
172
+
173
+ Code blocks, math, and footnotes keep semantic node kinds until rendered.
174
+ Use `htmlFallback()` for their default elements when writing your own renderer.
175
+
176
+ ## Plugins
177
+
178
+ ```ts
179
+ import { formatHtml, Processor } from "@temelj/mdx";
180
+ import { HeadingIdPlugin, LowerHeadingPlugin, RemoveEsmPlugin } from "@temelj/mdx/plugins";
181
+
182
+ const processor = new Processor({
183
+ documentPlugins: [new RemoveEsmPlugin()], // Run before HTML lowering or compilation.
184
+ htmlPlugins: [
185
+ new LowerHeadingPlugin({ offset: 1 }), // h1 -> h2.
186
+ new HeadingIdPlugin({ prefix: "doc-" }), // Add heading IDs.
187
+ ],
93
188
  });
94
189
 
95
- const artifact = await compiler.compile(
96
- source,
97
- {
98
- frontmatterOnly: false,
99
- mdxOptions: {
100
- rehypePlugins: [
101
- [
102
- treeProcessorPlugin,
103
- {
104
- process: (node: HastElement) => assert(typeof node.type === "string"),
105
- },
106
- ],
107
- ],
108
- },
190
+ const source = "export const version = 1\n\n# Introduction";
191
+ const result = processor.processSync(source);
192
+ console.log(formatHtml(result.html));
193
+ // <h2 id="doc-introduction">Introduction</h2>
194
+
195
+ // Async plugins use the async methods. Pass a signal to cancel their work.
196
+ const controller = new AbortController();
197
+ await processor.process(source, { signal: controller.signal });
198
+ ```
199
+
200
+ To write a document plugin, give it a name and a `transform()` method.
201
+ This one removes horizontal rules:
202
+
203
+ ```ts
204
+ import type { DocumentPlugin } from "@temelj/mdx/plugins";
205
+
206
+ import { formatHtml, Processor } from "@temelj/mdx";
207
+
208
+ const removeDividers: DocumentPlugin = {
209
+ name: "remove-dividers",
210
+ transform({ rewrite }) {
211
+ // Return a new tree; null removes the matching node.
212
+ return rewrite({ thematicBreak: () => null });
109
213
  },
110
- frontmatterSchema,
111
- );
112
- assert(artifact.compiled !== undefined);
113
- assertEquals(artifact.frontmatter, {
114
- title: "Demo",
214
+ };
215
+
216
+ const processor = new Processor({ documentPlugins: [removeDividers] });
217
+ const result = processor.processSync("# Introduction\n\n---\n\nHello.");
218
+ console.log(formatHtml(result.html));
219
+ // <h1>Introduction</h1>
220
+ // <p>Hello.</p>
221
+ ```
222
+
223
+ `transform()` runs document plugins.
224
+ `process()` also lowers HTML and runs HTML plugins.
225
+ `transform` and `process` also accept a `SourceFile` or an earlier parse result.
226
+ Their `Sync` variants reject async plugins.
227
+ Plugins return a tree or a promise.
228
+ Errors throw `TransformError` with the plugin name and stage.
229
+
230
+ `MathRenderPlugin` and `SyntaxHighlightPlugin` default to `mode: "tolerant"`.
231
+ If rendering fails, they keep readable content and add a warning.
232
+ Set `mode: "strict"` to throw on failure.
233
+
234
+ Find plugins in [./src/plugins](./src/plugins).
235
+
236
+ ## Compile MDX without evaluating it
237
+
238
+ ```ts
239
+ import { compile, Processor } from "@temelj/mdx";
240
+
241
+ const processor = new Processor({ syntax: { frontmatter: "yaml" } });
242
+ const parsed = await processor.transform("---\ntitle: Hello\n---\n\n# {6 * 7}");
243
+
244
+ // Generate JavaScript without running it.
245
+ const { artifact, frontmatter } = await compile(parsed);
246
+ console.log(artifact.code);
247
+ console.log(frontmatter); // { title: "Hello" }
248
+
249
+ // The default function-body artifact can cross a server/client boundary.
250
+ console.log(JSON.stringify(artifact));
251
+
252
+ // Build tools can request an ESM program instead.
253
+ const program = await compile(parsed, { outputFormat: "program" });
254
+ console.log(program.artifact.code);
255
+ ```
256
+
257
+ `frontmatterSchema` accepts a Standard Schema validator (which can be declared with zod or another validation library).
258
+ Invalid data throws `FrontmatterError`.
259
+ HTML lowering options also apply to compilation, while HTML plugins do not.
260
+
261
+ Use [`compileTrustedMdx()`](../mdx-react/README.md#trusted-compilation) from @temelj/mdx-react in React when you intentionally want to evaluate trusted MDX.
262
+
263
+ ## Stream a document
264
+
265
+ ```ts
266
+ import { formatHtml, MdxStream, previewDocument } from "@temelj/mdx";
267
+
268
+ const stream = new MdxStream({ syntax: { math: "auto" } });
269
+
270
+ const preview = stream.append("Hello **wor");
271
+ console.log(formatHtml(previewDocument(preview)));
272
+ // The open strong emphasis is already visible in the preview.
273
+
274
+ stream.append("ld**.");
275
+ stream.edit({ start: 0, end: 5, text: "Hi" }); // Replace a source range.
276
+
277
+ const completed = stream.complete(); // Strict parse. No later appends or edits.
278
+ console.log(completed.document);
279
+ ```
280
+
281
+ For repeated HTML output, attach a renderer to one stream:
282
+
283
+ ```ts
284
+ import { HtmlStreamRenderer, MdxStream } from "@temelj/mdx";
285
+
286
+ const stream = new MdxStream();
287
+ const renderer = new HtmlStreamRenderer(stream);
288
+
289
+ stream.append("Hello **world**");
290
+ console.log(renderer.render()); // Whole current HTML snapshot.
291
+
292
+ stream.append(" and more.");
293
+ stream.complete();
294
+ console.log(renderer.render()); // Final HTML, with unchanged nodes cached.
295
+ ```
296
+
297
+ When doing snapshots, replace the previous HTML snapshot and do not concatenate snapshots.
298
+ A later link or footnote definition can change an earlier block.
299
+
300
+ Appending stays cheap.
301
+
302
+ ```ts
303
+ import { MdxStream } from "@temelj/mdx";
304
+
305
+ const stream = new MdxStream();
306
+ const before = stream.append("# Heading\n\nOpen paragraph");
307
+ const after = stream.append(" continues.");
308
+
309
+ // Settled blocks keep their identity while the open tail changes.
310
+ console.log(before.blocks[0] === after.blocks[0]); // true
311
+
312
+ // Read only the source range you need.
313
+ // file.text joins the whole document.
314
+ console.log(after.file.slice(after.blocks[0].origin));
315
+ ```
316
+
317
+ An append parses the open tail again and reuses the settled blocks.
318
+ It decodes only new lines inside a "fence".
319
+ Changed definitions refresh the blocks that reference them (e.g like footnotes).
320
+
321
+ ### Open syntax and "pending"
322
+
323
+ This feature allows declaring custom rendering for elements when they're pending.
324
+
325
+ When using React, you can set custom rendering function for a pending element.
326
+
327
+ ```ts
328
+ import { MdxStream, ParseError } from "@temelj/mdx";
329
+
330
+ const stream = new MdxStream();
331
+ const preview = stream.append('<Alert title="Ready"');
332
+ console.log(preview.blocks); // Open JSX has state "pending"; nothing executes.
333
+
334
+ try {
335
+ stream.complete(); // The JSX tag is still unfinished.
336
+ } catch (error) {
337
+ if (!(error instanceof ParseError)) {
338
+ throw error;
339
+ }
340
+
341
+ // Failed completion leaves the stream open for a repair.
342
+ stream.append(" />");
343
+ stream.complete();
344
+ }
345
+ ```
346
+
347
+ | Preview node | Rendering |
348
+ | --------------------- | ----------------------------------------------------------------------------------------------------- |
349
+ | `pending` | Open emphasis, link, fence, math, or other syntax. `pendingFallback()` gives its provisional element. |
350
+ | `unresolvedReference` | Shows the reference source until its definition arrives. |
351
+
352
+ Pending links are not clickable and pending images do not load.
353
+ Invalid syntax ideally stays local to its block.
354
+
355
+ ### Subscribe to changes
356
+
357
+ ```ts
358
+ import { MdxStream } from "@temelj/mdx";
359
+
360
+ const stream = new MdxStream();
361
+ const unsubscribe = stream.subscribe(({ snapshot, start, refreshed }) => {
362
+ console.log(snapshot.blocks.slice(start)); // Replace the tail from this index.
363
+ console.log(refreshed); // Earlier blocks updated by changed definitions.
364
+ console.log(snapshot.footnotes); // The current footnote section.
115
365
  });
366
+
367
+ stream.append("Read [the guide][guide].\n\n");
368
+ stream.append("[guide]: https://example.com\n"); // Refreshes the earlier reference.
369
+ unsubscribe();
116
370
  ```
117
371
 
118
- ## About
372
+ ### Stream trees from a server
373
+
374
+ ```ts
375
+ import { streamBlockEvents } from "@temelj/mdx";
376
+
377
+ // The caller supplies decoded text chunks.
378
+ async function* jsonLines(chunks: AsyncIterable<string>): AsyncGenerator<string> {
379
+ for await (const event of streamBlockEvents(chunks, { syntax: { math: "auto" } })) {
380
+ yield `${JSON.stringify(event)}\n`;
381
+ }
382
+ }
383
+ ```
384
+
385
+ The generator ends with a `complete` event, or `failed` if MDX completion fails.
386
+ An upstream error rejects the iterator.
387
+ Serve the lines as `application/x-ndjson`.
388
+ On the client, `applyBlockEvent()` applies updates to a preview.
389
+
390
+ ### Text from AI clients
391
+
392
+ ```ts
393
+ import { MdxStream } from "@temelj/mdx";
394
+
395
+ async function parseAnswer(chunks: AsyncIterable<string>) {
396
+ const stream = new MdxStream();
397
+
398
+ for await (const text of chunks) {
399
+ stream.append(text); // Render or publish the preview here.
400
+ }
401
+
402
+ return stream.complete(); // Run only after successful generation.
403
+ }
404
+
405
+ // AI SDK Core: await parseAnswer(result.textStream).
406
+ // OpenRouter Agent SDK: await parseAnswer(result.getTextStream()).
407
+ // OpenRouter chat SDK: yield each event's choices[0]?.delta?.content.
408
+ ```
409
+
410
+ Pass decoded text only.
411
+ The SDK handles its wire protocol and reports provider errors.
412
+ Keep reasoning and tool events outside the MDX source, and pass your abort signal to the upstream request.
413
+
414
+ ## Highlight code
415
+
416
+ Put JSON metadata after the fence language:
417
+
418
+ ````md
419
+ ```ts {"fileName":"worker.ts","highlightLines":"2,4-6","lineNumbers":true}
420
+ const worker = createWorker();
421
+ await worker.start();
422
+ ```
423
+ ````
424
+
425
+ ````ts
426
+ import { formatHtml, Processor } from "@temelj/mdx";
427
+ import { createShikiHighlighter, SyntaxHighlightPlugin } from "@temelj/mdx/plugins";
428
+ import { createHighlighter } from "shiki"; // Optional application dependency.
429
+
430
+ const shiki = await createHighlighter({
431
+ langs: ["typescript"],
432
+ themes: ["github-light", "github-dark"],
433
+ });
434
+ const highlighter = createShikiHighlighter(shiki, {
435
+ languageAliases: { ts: "typescript" },
436
+ themes: { light: "github-light", dark: "github-dark" },
437
+ });
438
+ const processor = new Processor({
439
+ htmlPlugins: [new SyntaxHighlightPlugin({ highlighter })],
440
+ });
441
+
442
+ const result = await processor.process("```ts\nconst answer = 42;\n```");
443
+ console.log(formatHtml(result.html)); // Shiki token spans and theme styles.
444
+ ````
445
+
446
+ Use `parseCodeBlockMetadata()` to read metadata yourself.
447
+ Unknown fields remain in `metadata.raw`.
448
+ Your application should supply CSS for themes and line decorations.
449
+
450
+ ## Use Unified plugins
451
+
452
+ It's possible to integrate plugins from "unified" ecosystem.
453
+
454
+ ```ts
455
+ import { formatHtml, Processor } from "@temelj/mdx";
456
+ import { RehypePluginAdapter, RemarkPluginAdapter } from "@temelj/mdx/unified";
457
+ import rehypeSlug from "rehype-slug";
458
+ import remarkToc from "remark-toc";
459
+
460
+ const processor = new Processor({
461
+ documentPlugins: [new RemarkPluginAdapter(remarkToc)], // MDX -> mdast -> MDX.
462
+ htmlPlugins: [new RehypePluginAdapter(rehypeSlug)], // HTML -> hast -> HTML.
463
+ });
464
+
465
+ const result = await processor.process("# Contents\n\n# First section");
466
+ console.log(formatHtml(result.html));
467
+ ```
468
+
469
+ ## Diagnostics
470
+
471
+ ```ts
472
+ import { formatDiagnostic, LimitError, parse, ParseError } from "@temelj/mdx";
473
+
474
+ try {
475
+ parse("# Hello", { limits: { maximumSourceLength: 4 } });
476
+ } catch (error) {
477
+ if (error instanceof ParseError || error instanceof LimitError) {
478
+ for (const diagnostic of error.diagnostics) {
479
+ console.error(formatDiagnostic(diagnostic)); // Location, severity, code, message.
480
+ }
481
+ } else {
482
+ throw error; // Configuration errors are separate from content errors.
483
+ }
484
+ }
485
+ ```
486
+
487
+ Supported limits:
488
+
489
+ | Limit | Default |
490
+ | --------------------------- | ----------------------: |
491
+ | `maximumSourceLength` | 16,777,216 |
492
+ | `maximumNestingDepth` | 1,024 |
493
+ | `maximumNodes` | 1,000,000 |
494
+ | `maximumPendingBlockLength` | 4,194,304, streams only |
495
+
496
+ Source and pending-block lengths use UTF-16 code units.
497
+ Pass `limits` to `parse()`, `Processor`, or `MdxStream`.
498
+ `LimitError` also exposes `limit`, `maximum`, and `actual`. `hasErrorDiagnostics()` checks a diagnostic list.
499
+
500
+ ## Entry points
119
501
 
120
- This package is part of [Temelj](https://github.com/tinrab/temelj) - a core library for TypeScript.
502
+ | Import | Contents |
503
+ | --------------------- | ----------------------------------------------------------------- |
504
+ | `@temelj/mdx` | Parser, source files, trees, formatting, HTML, compiler, streams. |
505
+ | `@temelj/mdx/plugins` | Plugin types, built-ins, code metadata, Shiki adapter. |
506
+ | `@temelj/mdx/unified` | Remark and rehype adapters. |
@@ -0,0 +1,4 @@
1
+ //#region src/character-entities.d.ts
2
+ export declare const NAMED_CHARACTER_REFERENCES: Readonly<Record<string, string>>;
3
+ //#endregion
4
+ //# sourceMappingURL=character-entities.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"character-entities.d.mts","names":[],"sources":["../src/character-entities.ts"],"mappings":";qBAGa,4BAA4B,SAAS"}