@react-x11/components 0.7.1 → 0.9.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 (354) hide show
  1. package/README.md +295 -51
  2. package/dist/charts/node.d.ts +1 -1
  3. package/dist/charts/node.d.ts.map +1 -1
  4. package/dist/charts/node.js +6 -2
  5. package/dist/charts/node.js.map +1 -1
  6. package/dist/color-picker/ColorPicker.d.ts.map +1 -1
  7. package/dist/color-picker/ColorPicker.js +43 -33
  8. package/dist/color-picker/ColorPicker.js.map +1 -1
  9. package/dist/embed/client.d.ts +48 -3
  10. package/dist/embed/client.d.ts.map +1 -1
  11. package/dist/embed/client.js +79 -5
  12. package/dist/embed/client.js.map +1 -1
  13. package/dist/embed/index.d.ts +1 -1
  14. package/dist/embed/index.d.ts.map +1 -1
  15. package/dist/embed/index.js +1 -1
  16. package/dist/embed/index.js.map +1 -1
  17. package/dist/html/node.d.ts +3 -1
  18. package/dist/html/node.d.ts.map +1 -1
  19. package/dist/html/node.js +7 -5
  20. package/dist/html/node.js.map +1 -1
  21. package/dist/index.d.ts +1 -1
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +1 -1
  24. package/dist/index.js.map +1 -1
  25. package/dist/{markdown → internal/markdown}/ast.d.ts +12 -0
  26. package/dist/internal/markdown/ast.d.ts.map +1 -0
  27. package/dist/internal/markdown/ast.js +22 -0
  28. package/dist/internal/markdown/ast.js.map +1 -0
  29. package/dist/internal/markdown/parse.d.ts.map +1 -0
  30. package/dist/{markdown → internal/markdown}/parse.js +112 -22
  31. package/dist/internal/markdown/parse.js.map +1 -0
  32. package/dist/internal/markdown/stringify.d.ts +4 -0
  33. package/dist/internal/markdown/stringify.d.ts.map +1 -0
  34. package/dist/internal/markdown/stringify.js +684 -0
  35. package/dist/internal/markdown/stringify.js.map +1 -0
  36. package/dist/internal/markdown/tags.d.ts.map +1 -0
  37. package/dist/internal/markdown/tags.js.map +1 -0
  38. package/dist/internal/scroll.d.ts +3 -2
  39. package/dist/internal/scroll.d.ts.map +1 -1
  40. package/dist/internal/scroll.js +33 -15
  41. package/dist/internal/scroll.js.map +1 -1
  42. package/dist/internal/units.d.ts +2 -0
  43. package/dist/internal/units.d.ts.map +1 -0
  44. package/dist/internal/units.js +35 -0
  45. package/dist/internal/units.js.map +1 -0
  46. package/dist/internal/window.d.ts.map +1 -1
  47. package/dist/internal/window.js +4 -2
  48. package/dist/internal/window.js.map +1 -1
  49. package/dist/maps/anchors.d.ts +98 -0
  50. package/dist/maps/anchors.d.ts.map +1 -0
  51. package/dist/maps/anchors.js +531 -0
  52. package/dist/maps/anchors.js.map +1 -0
  53. package/dist/maps/controller.d.ts +283 -0
  54. package/dist/maps/controller.d.ts.map +1 -0
  55. package/dist/maps/controller.js +743 -0
  56. package/dist/maps/controller.js.map +1 -0
  57. package/dist/maps/gl/buckets.d.ts +95 -0
  58. package/dist/maps/gl/buckets.d.ts.map +1 -0
  59. package/dist/maps/gl/buckets.js +362 -0
  60. package/dist/maps/gl/buckets.js.map +1 -0
  61. package/dist/maps/gl/build-worker.d.ts +13 -0
  62. package/dist/maps/gl/build-worker.d.ts.map +1 -0
  63. package/dist/maps/gl/build-worker.js +44 -0
  64. package/dist/maps/gl/build-worker.js.map +1 -0
  65. package/dist/maps/gl/color.d.ts +8 -0
  66. package/dist/maps/gl/color.d.ts.map +1 -0
  67. package/dist/maps/gl/color.js +57 -0
  68. package/dist/maps/gl/color.js.map +1 -0
  69. package/dist/maps/gl/cover.d.ts +51 -0
  70. package/dist/maps/gl/cover.d.ts.map +1 -0
  71. package/dist/maps/gl/cover.js +124 -0
  72. package/dist/maps/gl/cover.js.map +1 -0
  73. package/dist/maps/gl/index.d.ts +3 -0
  74. package/dist/maps/gl/index.d.ts.map +1 -0
  75. package/dist/maps/gl/index.js +20 -0
  76. package/dist/maps/gl/index.js.map +1 -0
  77. package/dist/maps/gl/markers.d.ts +28 -0
  78. package/dist/maps/gl/markers.d.ts.map +1 -0
  79. package/dist/maps/gl/markers.js +60 -0
  80. package/dist/maps/gl/markers.js.map +1 -0
  81. package/dist/maps/gl/overlays.d.ts +68 -0
  82. package/dist/maps/gl/overlays.d.ts.map +1 -0
  83. package/dist/maps/gl/overlays.js +300 -0
  84. package/dist/maps/gl/overlays.js.map +1 -0
  85. package/dist/maps/gl/pane.d.ts +12 -0
  86. package/dist/maps/gl/pane.d.ts.map +1 -0
  87. package/dist/maps/gl/pane.js +37 -0
  88. package/dist/maps/gl/pane.js.map +1 -0
  89. package/dist/maps/gl/placement.d.ts +111 -0
  90. package/dist/maps/gl/placement.d.ts.map +1 -0
  91. package/dist/maps/gl/placement.js +567 -0
  92. package/dist/maps/gl/placement.js.map +1 -0
  93. package/dist/maps/gl/renderer.d.ts +352 -0
  94. package/dist/maps/gl/renderer.d.ts.map +1 -0
  95. package/dist/maps/gl/renderer.js +1127 -0
  96. package/dist/maps/gl/renderer.js.map +1 -0
  97. package/dist/maps/gl/shaders.d.ts +120 -0
  98. package/dist/maps/gl/shaders.d.ts.map +1 -0
  99. package/dist/maps/gl/shaders.js +451 -0
  100. package/dist/maps/gl/shaders.js.map +1 -0
  101. package/dist/maps/gl/store.d.ts +115 -0
  102. package/dist/maps/gl/store.d.ts.map +1 -0
  103. package/dist/maps/gl/store.js +469 -0
  104. package/dist/maps/gl/store.js.map +1 -0
  105. package/dist/maps/gl/text.d.ts +154 -0
  106. package/dist/maps/gl/text.d.ts.map +1 -0
  107. package/dist/maps/gl/text.js +382 -0
  108. package/dist/maps/gl/text.js.map +1 -0
  109. package/dist/maps/gl/view.d.ts +54 -0
  110. package/dist/maps/gl/view.d.ts.map +1 -0
  111. package/dist/maps/gl/view.js +974 -0
  112. package/dist/maps/gl/view.js.map +1 -0
  113. package/dist/maps/index.d.ts +1 -1
  114. package/dist/maps/index.d.ts.map +1 -1
  115. package/dist/maps/index.js +216 -52
  116. package/dist/maps/index.js.map +1 -1
  117. package/dist/maps/labels.d.ts +37 -16
  118. package/dist/maps/labels.d.ts.map +1 -1
  119. package/dist/maps/labels.js +188 -119
  120. package/dist/maps/labels.js.map +1 -1
  121. package/dist/maps/node.d.ts +162 -56
  122. package/dist/maps/node.d.ts.map +1 -1
  123. package/dist/maps/node.js +607 -515
  124. package/dist/maps/node.js.map +1 -1
  125. package/dist/maps/overlay.d.ts +72 -9
  126. package/dist/maps/overlay.d.ts.map +1 -1
  127. package/dist/maps/overlay.js +108 -28
  128. package/dist/maps/overlay.js.map +1 -1
  129. package/dist/maps/paint.d.ts +3 -0
  130. package/dist/maps/paint.d.ts.map +1 -1
  131. package/dist/maps/paint.js.map +1 -1
  132. package/dist/maps/proj.d.ts +14 -0
  133. package/dist/maps/proj.d.ts.map +1 -1
  134. package/dist/maps/proj.js +28 -0
  135. package/dist/maps/proj.js.map +1 -1
  136. package/dist/maps/renderer.d.ts +69 -0
  137. package/dist/maps/renderer.d.ts.map +1 -0
  138. package/dist/maps/renderer.js +66 -0
  139. package/dist/maps/renderer.js.map +1 -0
  140. package/dist/maps/sources.d.ts +25 -3
  141. package/dist/maps/sources.d.ts.map +1 -1
  142. package/dist/maps/sources.js +17 -0
  143. package/dist/maps/sources.js.map +1 -1
  144. package/dist/maps/theme.d.ts +19 -0
  145. package/dist/maps/theme.d.ts.map +1 -0
  146. package/dist/maps/theme.js +44 -0
  147. package/dist/maps/theme.js.map +1 -0
  148. package/dist/maps/tiles.d.ts +117 -17
  149. package/dist/maps/tiles.d.ts.map +1 -1
  150. package/dist/maps/tiles.js +163 -30
  151. package/dist/maps/tiles.js.map +1 -1
  152. package/dist/maps/types.d.ts +188 -20
  153. package/dist/maps/types.d.ts.map +1 -1
  154. package/dist/markdown/expressions.d.ts +1 -1
  155. package/dist/markdown/expressions.d.ts.map +1 -1
  156. package/dist/markdown/expressions.js.map +1 -1
  157. package/dist/markdown/index.d.ts +7 -6
  158. package/dist/markdown/index.d.ts.map +1 -1
  159. package/dist/markdown/index.js +9 -7
  160. package/dist/markdown/index.js.map +1 -1
  161. package/dist/markdown/spans.d.ts +1 -1
  162. package/dist/markdown/spans.d.ts.map +1 -1
  163. package/dist/media-player/index.d.ts +11 -3
  164. package/dist/media-player/index.d.ts.map +1 -1
  165. package/dist/media-player/index.js +13 -2
  166. package/dist/media-player/index.js.map +1 -1
  167. package/dist/rich-text-editor/clipboard.d.ts +23 -0
  168. package/dist/rich-text-editor/clipboard.d.ts.map +1 -0
  169. package/dist/rich-text-editor/clipboard.js +307 -0
  170. package/dist/rich-text-editor/clipboard.js.map +1 -0
  171. package/dist/rich-text-editor/collab.d.ts +32 -0
  172. package/dist/rich-text-editor/collab.d.ts.map +1 -0
  173. package/dist/rich-text-editor/collab.js +55 -0
  174. package/dist/rich-text-editor/collab.js.map +1 -0
  175. package/dist/rich-text-editor/commands.d.ts +50 -0
  176. package/dist/rich-text-editor/commands.d.ts.map +1 -0
  177. package/dist/rich-text-editor/commands.js +376 -0
  178. package/dist/rich-text-editor/commands.js.map +1 -0
  179. package/dist/rich-text-editor/drag.d.ts +68 -0
  180. package/dist/rich-text-editor/drag.d.ts.map +1 -0
  181. package/dist/rich-text-editor/drag.js +148 -0
  182. package/dist/rich-text-editor/drag.js.map +1 -0
  183. package/dist/rich-text-editor/html.d.ts +145 -0
  184. package/dist/rich-text-editor/html.d.ts.map +1 -0
  185. package/dist/rich-text-editor/html.js +516 -0
  186. package/dist/rich-text-editor/html.js.map +1 -0
  187. package/dist/rich-text-editor/index.d.ts +263 -0
  188. package/dist/rich-text-editor/index.d.ts.map +1 -0
  189. package/dist/rich-text-editor/index.js +822 -0
  190. package/dist/rich-text-editor/index.js.map +1 -0
  191. package/dist/rich-text-editor/inline.d.ts +94 -0
  192. package/dist/rich-text-editor/inline.d.ts.map +1 -0
  193. package/dist/rich-text-editor/inline.js +252 -0
  194. package/dist/rich-text-editor/inline.js.map +1 -0
  195. package/dist/rich-text-editor/keymap.d.ts +71 -0
  196. package/dist/rich-text-editor/keymap.d.ts.map +1 -0
  197. package/dist/rich-text-editor/keymap.js +393 -0
  198. package/dist/rich-text-editor/keymap.js.map +1 -0
  199. package/dist/rich-text-editor/keys.d.ts +29 -0
  200. package/dist/rich-text-editor/keys.d.ts.map +1 -0
  201. package/dist/rich-text-editor/keys.js +93 -0
  202. package/dist/rich-text-editor/keys.js.map +1 -0
  203. package/dist/rich-text-editor/look.d.ts +71 -0
  204. package/dist/rich-text-editor/look.d.ts.map +1 -0
  205. package/dist/rich-text-editor/look.js +342 -0
  206. package/dist/rich-text-editor/look.js.map +1 -0
  207. package/dist/rich-text-editor/markdown.d.ts +18 -0
  208. package/dist/rich-text-editor/markdown.d.ts.map +1 -0
  209. package/dist/rich-text-editor/markdown.js +496 -0
  210. package/dist/rich-text-editor/markdown.js.map +1 -0
  211. package/dist/rich-text-editor/nodes.d.ts +135 -0
  212. package/dist/rich-text-editor/nodes.d.ts.map +1 -0
  213. package/dist/rich-text-editor/nodes.js +397 -0
  214. package/dist/rich-text-editor/nodes.js.map +1 -0
  215. package/dist/rich-text-editor/render.d.ts +68 -0
  216. package/dist/rich-text-editor/render.d.ts.map +1 -0
  217. package/dist/rich-text-editor/render.js +500 -0
  218. package/dist/rich-text-editor/render.js.map +1 -0
  219. package/dist/rich-text-editor/schema.d.ts +16 -0
  220. package/dist/rich-text-editor/schema.d.ts.map +1 -0
  221. package/dist/rich-text-editor/schema.js +386 -0
  222. package/dist/rich-text-editor/schema.js.map +1 -0
  223. package/dist/rich-text-editor/store.d.ts +11 -0
  224. package/dist/rich-text-editor/store.d.ts.map +1 -0
  225. package/dist/rich-text-editor/store.js +43 -0
  226. package/dist/rich-text-editor/store.js.map +1 -0
  227. package/dist/rich-text-editor/suggest.d.ts +127 -0
  228. package/dist/rich-text-editor/suggest.d.ts.map +1 -0
  229. package/dist/rich-text-editor/suggest.js +0 -0
  230. package/dist/rich-text-editor/suggest.js.map +1 -0
  231. package/dist/rich-text-editor/tables.d.ts +41 -0
  232. package/dist/rich-text-editor/tables.d.ts.map +1 -0
  233. package/dist/rich-text-editor/tables.js +204 -0
  234. package/dist/rich-text-editor/tables.js.map +1 -0
  235. package/dist/rich-text-editor/toolbar.d.ts +58 -0
  236. package/dist/rich-text-editor/toolbar.d.ts.map +1 -0
  237. package/dist/rich-text-editor/toolbar.js +548 -0
  238. package/dist/rich-text-editor/toolbar.js.map +1 -0
  239. package/dist/rich-text-editor/view.d.ts +368 -0
  240. package/dist/rich-text-editor/view.d.ts.map +1 -0
  241. package/dist/rich-text-editor/view.js +1968 -0
  242. package/dist/rich-text-editor/view.js.map +1 -0
  243. package/dist/rich-text-editor/virtual.d.ts +54 -0
  244. package/dist/rich-text-editor/virtual.d.ts.map +1 -0
  245. package/dist/rich-text-editor/virtual.js +262 -0
  246. package/dist/rich-text-editor/virtual.js.map +1 -0
  247. package/dist/richtext/node.d.ts +25 -2
  248. package/dist/richtext/node.d.ts.map +1 -1
  249. package/dist/richtext/node.js +46 -24
  250. package/dist/richtext/node.js.map +1 -1
  251. package/dist/table/index.d.ts.map +1 -1
  252. package/dist/table/index.js +14 -5
  253. package/dist/table/index.js.map +1 -1
  254. package/dist/terminal/backends.d.ts +4 -1
  255. package/dist/terminal/backends.d.ts.map +1 -1
  256. package/dist/terminal/backends.js.map +1 -1
  257. package/dist/terminal/index.d.ts +18 -7
  258. package/dist/terminal/index.d.ts.map +1 -1
  259. package/dist/terminal/index.js +28 -11
  260. package/dist/terminal/index.js.map +1 -1
  261. package/dist/terminal/vt/node.d.ts +56 -3
  262. package/dist/terminal/vt/node.d.ts.map +1 -1
  263. package/dist/terminal/vt/node.js +106 -26
  264. package/dist/terminal/vt/node.js.map +1 -1
  265. package/dist/terminal/vt/renderer.d.ts +4 -0
  266. package/dist/terminal/vt/renderer.d.ts.map +1 -1
  267. package/dist/terminal/vt/renderer.js +14 -5
  268. package/dist/terminal/vt/renderer.js.map +1 -1
  269. package/dist/tree/index.d.ts.map +1 -1
  270. package/dist/tree/index.js +6 -4
  271. package/dist/tree/index.js.map +1 -1
  272. package/package.json +23 -4
  273. package/src/charts/node.ts +6 -2
  274. package/src/color-picker/ColorPicker.ts +107 -81
  275. package/src/embed/client.ts +102 -8
  276. package/src/embed/index.ts +2 -0
  277. package/src/html/node.ts +7 -5
  278. package/src/index.ts +2 -0
  279. package/src/{markdown → internal/markdown}/ast.ts +24 -7
  280. package/src/{markdown → internal/markdown}/parse.ts +134 -24
  281. package/src/internal/markdown/stringify.ts +772 -0
  282. package/src/internal/scroll.ts +39 -18
  283. package/src/internal/units.ts +34 -0
  284. package/src/internal/window.ts +4 -2
  285. package/src/maps/anchors.ts +607 -0
  286. package/src/maps/controller.ts +999 -0
  287. package/src/maps/gl/buckets.ts +457 -0
  288. package/src/maps/gl/build-worker.ts +55 -0
  289. package/src/maps/gl/color.ts +62 -0
  290. package/src/maps/gl/cover.ts +170 -0
  291. package/src/maps/gl/index.ts +23 -0
  292. package/src/maps/gl/markers.ts +83 -0
  293. package/src/maps/gl/overlays.ts +379 -0
  294. package/src/maps/gl/pane.ts +42 -0
  295. package/src/maps/gl/placement.ts +816 -0
  296. package/src/maps/gl/renderer.ts +1576 -0
  297. package/src/maps/gl/shaders.ts +486 -0
  298. package/src/maps/gl/store.ts +566 -0
  299. package/src/maps/gl/text.ts +495 -0
  300. package/src/maps/gl/view.ts +1224 -0
  301. package/src/maps/index.ts +270 -81
  302. package/src/maps/labels.ts +214 -121
  303. package/src/maps/node.ts +763 -629
  304. package/src/maps/overlay.ts +148 -43
  305. package/src/maps/paint.ts +3 -0
  306. package/src/maps/proj.ts +31 -0
  307. package/src/maps/renderer.ts +155 -0
  308. package/src/maps/sources.ts +38 -3
  309. package/src/maps/theme.ts +51 -0
  310. package/src/maps/tiles.ts +191 -33
  311. package/src/maps/types.ts +188 -20
  312. package/src/markdown/expressions.ts +5 -1
  313. package/src/markdown/index.ts +14 -11
  314. package/src/markdown/spans.ts +1 -1
  315. package/src/media-player/index.ts +18 -4
  316. package/src/rich-text-editor/clipboard.ts +439 -0
  317. package/src/rich-text-editor/collab.ts +91 -0
  318. package/src/rich-text-editor/commands.ts +448 -0
  319. package/src/rich-text-editor/dom-globals.d.ts +23 -0
  320. package/src/rich-text-editor/drag.ts +211 -0
  321. package/src/rich-text-editor/html.ts +619 -0
  322. package/src/rich-text-editor/index.ts +1331 -0
  323. package/src/rich-text-editor/inline.ts +345 -0
  324. package/src/rich-text-editor/keymap.ts +510 -0
  325. package/src/rich-text-editor/keys.ts +119 -0
  326. package/src/rich-text-editor/look.ts +427 -0
  327. package/src/rich-text-editor/markdown.ts +653 -0
  328. package/src/rich-text-editor/nodes.ts +497 -0
  329. package/src/rich-text-editor/render.ts +800 -0
  330. package/src/rich-text-editor/schema.ts +431 -0
  331. package/src/rich-text-editor/store.ts +39 -0
  332. package/src/rich-text-editor/suggest.ts +597 -0
  333. package/src/rich-text-editor/tables.ts +272 -0
  334. package/src/rich-text-editor/toolbar.ts +724 -0
  335. package/src/rich-text-editor/view.ts +2287 -0
  336. package/src/rich-text-editor/virtual.ts +347 -0
  337. package/src/richtext/node.ts +59 -30
  338. package/src/table/index.ts +14 -5
  339. package/src/terminal/backends.ts +4 -1
  340. package/src/terminal/index.ts +43 -15
  341. package/src/terminal/vt/node.ts +128 -29
  342. package/src/terminal/vt/renderer.ts +27 -5
  343. package/src/tree/index.ts +6 -4
  344. package/dist/markdown/ast.d.ts.map +0 -1
  345. package/dist/markdown/ast.js +0 -17
  346. package/dist/markdown/ast.js.map +0 -1
  347. package/dist/markdown/parse.d.ts.map +0 -1
  348. package/dist/markdown/parse.js.map +0 -1
  349. package/dist/markdown/tags.d.ts.map +0 -1
  350. package/dist/markdown/tags.js.map +0 -1
  351. /package/dist/{markdown → internal/markdown}/parse.d.ts +0 -0
  352. /package/dist/{markdown → internal/markdown}/tags.d.ts +0 -0
  353. /package/dist/{markdown → internal/markdown}/tags.js +0 -0
  354. /package/src/{markdown → internal/markdown}/tags.ts +0 -0
@@ -0,0 +1,684 @@
1
+ import { parseInline } from './parse.js';
2
+ /** Markdown for a document, or for a run of blocks. */
3
+ export function stringify(doc) {
4
+ const blocks = 'blocks' in doc ? doc.blocks : doc;
5
+ return blockSequence(blocks, false).join('\n');
6
+ }
7
+ /** A list line with a marker and nothing after it. */
8
+ const EMPTY_ITEM = /^(?:\d{1,9}[.)]|[-+*])(?: \[[ x]\])? *$/;
9
+ /**
10
+ * The lines for a run of sibling blocks, with a blank line between each two.
11
+ * The exception is a nested list straight after the paragraph of a tight
12
+ * item — "- a\n - b" — which is how a tight list stays tight.
13
+ */
14
+ function blockSequence(blocks, tightItem) {
15
+ const out = [];
16
+ let prevList = null;
17
+ for (const block of blocks) {
18
+ let lines;
19
+ let list = null;
20
+ if (block.type === 'list') {
21
+ // Two lists in a row with the same marker are one list to a reader —
22
+ // a blank line between them only makes it loose — so the second takes
23
+ // its kind's other marker, which is the break CommonMark recognises.
24
+ const base = block.ordered ? '.' : '-';
25
+ const other = block.ordered ? ')' : '*';
26
+ const marker = prevList &&
27
+ prevList.ordered === block.ordered &&
28
+ prevList.marker === base
29
+ ? other
30
+ : base;
31
+ list = { ordered: block.ordered, marker };
32
+ lines = listLines(block, marker);
33
+ }
34
+ else {
35
+ lines = blockLines(block);
36
+ }
37
+ // an empty paragraph has no markdown; dropping it is the only honest
38
+ // spelling of "nothing", and it keeps adjacent lists adjacent
39
+ if (lines.length === 0)
40
+ continue;
41
+ // …and an empty item cannot interrupt a paragraph ("a\n3." is one
42
+ // paragraph), so a list that opens with one keeps its blank line
43
+ const interrupts = tightItem && block.type === 'list' && !EMPTY_ITEM.test(lines[0]);
44
+ if (out.length > 0 && !interrupts)
45
+ out.push('');
46
+ out.push(...lines);
47
+ prevList = list;
48
+ }
49
+ return out;
50
+ }
51
+ function blockLines(block) {
52
+ switch (block.type) {
53
+ case 'paragraph': {
54
+ const text = inline(block.children, 'block');
55
+ return text === '' ? [] : text.split('\n');
56
+ }
57
+ case 'heading':
58
+ return [headingLine(block.depth, block.children)];
59
+ case 'code':
60
+ return fenceLines(block);
61
+ case 'quote':
62
+ return blockSequence(block.children, false).map((line) => line === '' ? '>' : `> ${line}`);
63
+ case 'list':
64
+ return listLines(block, block.ordered ? '.' : '-');
65
+ case 'table':
66
+ return tableLines(block);
67
+ case 'rule':
68
+ return ['---'];
69
+ case 'component':
70
+ // The editor never builds one; an AST that has one keeps its content.
71
+ return blockSequence(block.children, false);
72
+ }
73
+ }
74
+ function headingLine(depth, children) {
75
+ let text = inline(children, 'heading');
76
+ // `# Title #` loses its closing run to the ATX rule — so a heading that
77
+ // really ends in a `#` escapes the last one
78
+ if (/(^|[ \t])#+$/.test(text))
79
+ text = `${text.slice(0, -1)}\\#`;
80
+ const level = Math.max(1, Math.min(6, Math.round(depth)));
81
+ return '#'.repeat(level) + (text ? ` ${text}` : '');
82
+ }
83
+ function fenceLines(block) {
84
+ const info = (block.info ?? block.lang).trim();
85
+ // a backtick fence cannot carry a backtick in its info string
86
+ const char = info.includes('`') ? '~' : '`';
87
+ let longest = 0;
88
+ for (const m of block.text.matchAll(char === '`' ? /`+/g : /~+/g)) {
89
+ longest = Math.max(longest, m[0].length);
90
+ }
91
+ const fence = char.repeat(Math.max(3, longest + 1));
92
+ const body = block.text === '' ? [] : block.text.split('\n');
93
+ return [fence + info, ...body, fence];
94
+ }
95
+ function listLines(list, marker) {
96
+ const out = [];
97
+ list.items.forEach((item, index) => {
98
+ const bullet = list.ordered ? `${list.start + index}${marker}` : marker;
99
+ const pad = ' '.repeat(bullet.length + 1);
100
+ const task = item.checked === null ? '' : item.checked ? '[x] ' : '[ ] ';
101
+ const body = blockSequence(item.children, list.tight);
102
+ if (index > 0 && !list.tight)
103
+ out.push('');
104
+ if (body.length === 0) {
105
+ // "- [ ] " keeps the space: a task marker needs one after it
106
+ out.push(task ? `${bullet} ${task}` : bullet);
107
+ return;
108
+ }
109
+ out.push(`${bullet} ${task}${body[0]}`);
110
+ for (let i = 1; i < body.length; i++) {
111
+ out.push(body[i] === '' ? '' : pad + body[i]);
112
+ }
113
+ });
114
+ return out;
115
+ }
116
+ function tableLines(table) {
117
+ const row = (cells) => `| ${cells.map((c) => c || ' ').join(' | ')} |`;
118
+ const cell = (nodes) => inline(nodes, 'cell');
119
+ const delimiter = table.align.map((a) => a === 'left'
120
+ ? ':---'
121
+ : a === 'center'
122
+ ? ':---:'
123
+ : a === 'right'
124
+ ? '---:'
125
+ : '---');
126
+ return [
127
+ row(table.header.map(cell)),
128
+ row(delimiter),
129
+ ...table.rows.map((r) => row(r.map(cell))),
130
+ ];
131
+ }
132
+ /**
133
+ * Inline content as markdown — checked. The rules above cover what prose
134
+ * does, but the flanking rules have corners no delimiter placement escapes
135
+ * (bold that ends in punctuation, glued to the word after it, next to
136
+ * italic that does the same), and a corner is where a document loses text
137
+ * to literal asterisks. So the output is read back with the parser and
138
+ * compared, as flat runs of marked text, with what was meant; if they
139
+ * differ, the same content is written without its emphasis, and failing
140
+ * that as plain text. Links, code and every character survive either way.
141
+ */
142
+ function inline(nodes, mode) {
143
+ const meant = expel(nodes);
144
+ const first = write(meant, mode);
145
+ if (!checkable(meant) || readsAs(first, meant, mode))
146
+ return first;
147
+ const plainer = expel(stripEmphasis(meant));
148
+ const second = write(plainer, mode);
149
+ if (readsAs(second, plainer, mode))
150
+ return second;
151
+ return write(expel(textOnly(meant)), mode);
152
+ }
153
+ function write(nodes, mode) {
154
+ const w = new InlineWriter(mode);
155
+ w.nodes(nodes);
156
+ return w.finish();
157
+ }
158
+ /** Only content the parser can say back — no MDX nodes — is checked. */
159
+ function checkable(nodes) {
160
+ return nodes.every((n) => n.type !== 'expression' &&
161
+ n.type !== 'component' &&
162
+ (!('children' in n) || checkable(n.children)));
163
+ }
164
+ /** Whether `text`, read back where it will be read, is `meant`. */
165
+ function readsAs(text, meant, mode) {
166
+ // a row is split on bare pipes before its cells are read, and a cell is
167
+ // trimmed; the other two modes read their text as it is
168
+ const source = mode === 'cell' ? text.replace(/\\\|/g, '|').trim() : text;
169
+ const back = parseInline(source, false);
170
+ return flatKey(back, mode) === flatKey(meant, mode);
171
+ }
172
+ /**
173
+ * Inline content as flat runs of marked text — what a ProseMirror document
174
+ * holds, and so what has to survive. Nesting order is not in it (`***x***`
175
+ * is bold and italic either way round), and neither are the breaks that
176
+ * trail a paragraph, which markdown cannot hold.
177
+ */
178
+ function flatKey(nodes, mode) {
179
+ const runs = [];
180
+ const push = (marks, text) => {
181
+ const last = runs[runs.length - 1];
182
+ if (last && last[0] === marks)
183
+ last[1] += text;
184
+ else
185
+ runs.push([marks, text]);
186
+ };
187
+ const walk = (list, marks) => {
188
+ for (const node of list) {
189
+ switch (node.type) {
190
+ case 'text':
191
+ for (const part of node.text.split(/(\n)/)) {
192
+ if (part === '\n')
193
+ push('\n', mode === 'block' ? '\n' : ' ');
194
+ else if (part)
195
+ push(marks, part);
196
+ }
197
+ break;
198
+ case 'code':
199
+ push(`${marks}|code`, node.text.replace(/\n/g, ' '));
200
+ break;
201
+ case 'break':
202
+ if (mode === 'block')
203
+ push('\n', '\n');
204
+ else
205
+ push(marks, ' ');
206
+ break;
207
+ case 'link':
208
+ if (node.image)
209
+ push(`${marks}|img:${node.href}:${node.title ?? ''}`, plain(node.children) || '');
210
+ else if (node.href === null)
211
+ walk(node.children, marks);
212
+ else
213
+ walk(node.children, `${marks}|a:${node.href}:${node.title ?? ''}`);
214
+ break;
215
+ case 'strong':
216
+ case 'em':
217
+ case 'del':
218
+ walk(node.children, [...marks.split('|').filter(Boolean), node.type].sort().join('|'));
219
+ break;
220
+ default:
221
+ break;
222
+ }
223
+ }
224
+ };
225
+ walk(nodes, '');
226
+ while (runs.length && runs[runs.length - 1][0] === '\n')
227
+ runs.pop();
228
+ return JSON.stringify(runs);
229
+ }
230
+ function plain(nodes) {
231
+ let out = '';
232
+ for (const node of nodes) {
233
+ if (node.type === 'text' || node.type === 'code')
234
+ out += node.text;
235
+ else if ('children' in node)
236
+ out += plain(node.children);
237
+ }
238
+ return out;
239
+ }
240
+ function stripEmphasis(nodes) {
241
+ const out = [];
242
+ for (const node of nodes) {
243
+ if (node.type === 'strong' || node.type === 'em' || node.type === 'del') {
244
+ out.push(...stripEmphasis(node.children));
245
+ }
246
+ else if (node.type === 'link') {
247
+ out.push({ ...node, children: stripEmphasis(node.children) });
248
+ }
249
+ else
250
+ out.push(node);
251
+ }
252
+ return out;
253
+ }
254
+ function textOnly(nodes) {
255
+ const out = [];
256
+ for (const node of nodes) {
257
+ if (node.type === 'text' || node.type === 'break')
258
+ out.push(node);
259
+ else if (node.type === 'code')
260
+ out.push({ type: 'text', text: node.text });
261
+ else if ('children' in node)
262
+ out.push(...textOnly(node.children));
263
+ }
264
+ return out;
265
+ }
266
+ const WS = /\s/u;
267
+ const WORD = /[\p{L}\p{N}]/u;
268
+ const ENTITY_LIKE = /^&(?:#\d{1,7}|#[xX][0-9a-fA-F]{1,6}|[a-zA-Z][a-zA-Z0-9]{1,31});/;
269
+ class InlineWriter {
270
+ mode;
271
+ out = '';
272
+ /** The next character starts a line — the top of the text, or just after
273
+ * a hard break — which is where block syntax lives. */
274
+ lineStart = true;
275
+ constructor(mode) {
276
+ this.mode = mode;
277
+ }
278
+ finish() {
279
+ let text = this.out;
280
+ if (this.mode === 'block') {
281
+ // A hard break has to be followed by something: at the very end of a
282
+ // paragraph it would read back as a literal backslash, so it goes.
283
+ text = text.replace(/(\\\n)+$/, '');
284
+ }
285
+ else if (/\s$/u.test(text)) {
286
+ // The ATX rule and a cell's trim both eat trailing whitespace; the last
287
+ // character of it is spelled as a reference so the text keeps it.
288
+ const last = text[text.length - 1];
289
+ text = text.slice(0, -1) + (last === '\t' ? '&#9;' : '&#32;');
290
+ }
291
+ return text;
292
+ }
293
+ /** `after` is the character the output continues with once these nodes
294
+ * are written — a closing delimiter, a `]`, or nothing at all. */
295
+ nodes(nodes, after) {
296
+ for (let i = 0; i < nodes.length; i++) {
297
+ const node = nodes[i];
298
+ const next = i + 1 < nodes.length ? leadOf(nodes[i + 1]) : after;
299
+ switch (node.type) {
300
+ case 'text':
301
+ this.text(node.text, next);
302
+ break;
303
+ case 'code':
304
+ this.code(node.text);
305
+ break;
306
+ case 'strong':
307
+ this.wrap('**', node.children, next);
308
+ break;
309
+ case 'em': {
310
+ // Beside another `*` run — italic at the start of bold, at its
311
+ // end, or right before it — the two delimiters would merge into
312
+ // one run and be read differently (`***x***` is bold inside
313
+ // italic), so this one is `_`, where `_` can stand: not against a
314
+ // word on either side.
315
+ const besideStar = this.out.endsWith('*') || next === '*';
316
+ const underscore = besideStar &&
317
+ !WORD.test(lastChar(this.out) ?? '') &&
318
+ !WORD.test(next ?? '');
319
+ this.wrap(underscore ? '_' : '*', node.children, next);
320
+ break;
321
+ }
322
+ case 'del':
323
+ this.wrap('~~', node.children, next);
324
+ break;
325
+ case 'link':
326
+ this.link(node);
327
+ break;
328
+ case 'break':
329
+ this.hardBreak();
330
+ break;
331
+ case 'expression':
332
+ this.raw(`{${node.src}}`);
333
+ break;
334
+ case 'component':
335
+ this.nodes(node.children);
336
+ break;
337
+ }
338
+ }
339
+ }
340
+ raw(text) {
341
+ this.out += text;
342
+ if (text)
343
+ this.lineStart = false;
344
+ }
345
+ hardBreak() {
346
+ if (this.mode !== 'block') {
347
+ // a heading or a cell is one line: the break is a space, spelled the
348
+ // way any other space at its edge is
349
+ this.text(' ', undefined);
350
+ return;
351
+ }
352
+ this.out += '\\\n';
353
+ this.lineStart = true;
354
+ }
355
+ /**
356
+ * A delimited run. Whether a delimiter opens or closes depends on the
357
+ * characters either side of it — CommonMark's flanking rules — so the
358
+ * content is written first and the placement checked against what
359
+ * actually surrounds it. Some placements have no spelling at all: `**`
360
+ * cannot close after punctuation when a letter follows (`**"a"**s`). Then
361
+ * the text is kept and the emphasis is not, because a word that stops
362
+ * being bold is a smaller loss than a document that grows literal
363
+ * asterisks every time it is saved.
364
+ *
365
+ * A dropped run is written again rather than unwrapped: what is inside it
366
+ * was judged against this run's delimiters, which are no longer there, so
367
+ * an inner run that stood beside them may not stand beside what replaced
368
+ * them — and a line start it sat after is a line start again.
369
+ */
370
+ wrap(delimiter, children, after) {
371
+ const start = this.out.length;
372
+ const wasLineStart = this.lineStart;
373
+ const before = lastChar(this.out);
374
+ this.raw(delimiter);
375
+ const innerStart = this.out.length;
376
+ this.nodes(children, delimiter[0]);
377
+ const inner = this.out.slice(innerStart);
378
+ const ch = delimiter[0];
379
+ if (inner !== '' &&
380
+ canOpen(ch, before, firstChar(inner)) &&
381
+ canClose(ch, lastChar(inner), after)) {
382
+ this.raw(delimiter);
383
+ return;
384
+ }
385
+ this.out = this.out.slice(0, start);
386
+ this.lineStart = wasLineStart;
387
+ this.nodes(children, after);
388
+ }
389
+ code(text) {
390
+ const flat = text.replace(/\n/g, ' ');
391
+ let longest = 0;
392
+ for (const m of flat.matchAll(/`+/g))
393
+ longest = Math.max(longest, m[0].length);
394
+ const fence = '`'.repeat(longest + 1);
395
+ // CommonMark shaves one space off each end when both have one, and a
396
+ // span that starts or ends in a backtick would merge with its fence
397
+ const pad = flat.startsWith('`') ||
398
+ flat.endsWith('`') ||
399
+ (flat.startsWith(' ') && flat.endsWith(' ') && flat.trim() !== '')
400
+ ? ' '
401
+ : '';
402
+ this.raw(this.cellSafe(fence + pad + flat + pad + fence));
403
+ }
404
+ /**
405
+ * In a table cell a bare `|` ends the cell — inside a code span or a link
406
+ * destination too, because a table row is split before its cells' inline
407
+ * syntax is read, and `\|` is turned back into `|` as it is split.
408
+ */
409
+ cellSafe(raw) {
410
+ return this.mode === 'cell' ? raw.replace(/\|/g, '\\|') : raw;
411
+ }
412
+ link(node) {
413
+ if (node.href === null) {
414
+ this.nodes(node.children); // a link still streaming in has nowhere to go
415
+ return;
416
+ }
417
+ const tail = this.cellSafe(`](${destination(node.href)}${titlePart(node.title)})`);
418
+ if (node.image) {
419
+ this.raw('![');
420
+ this.nodes(node.children, ']');
421
+ this.raw(tail);
422
+ return;
423
+ }
424
+ const auto = autolink(node);
425
+ if (auto !== null) {
426
+ this.raw(this.cellSafe(auto));
427
+ return;
428
+ }
429
+ this.raw('[');
430
+ this.nodes(node.children, ']');
431
+ this.raw(tail);
432
+ }
433
+ /** `after` is the character the output continues with past this text, so
434
+ * a character at the text's edge is judged by its real neighbour and not
435
+ * by where one node happened to end. */
436
+ text(text, after) {
437
+ for (let i = 0; i < text.length; i++) {
438
+ const ch = text[i];
439
+ if (ch === '\n') {
440
+ this.hardBreak(); // a text node the editor built may carry one
441
+ continue;
442
+ }
443
+ if (this.lineStart) {
444
+ this.lineStart = false;
445
+ const lead = this.lineLead(text, i);
446
+ if (lead !== null) {
447
+ this.out += lead.text;
448
+ i += lead.consumed - 1;
449
+ continue;
450
+ }
451
+ }
452
+ this.out += this.escape(text, i, after);
453
+ }
454
+ }
455
+ /**
456
+ * The first character of a line, when it would open a block: `# ` a
457
+ * heading, `>` a quote, `-`/`+`/`=`/`:`/`|`/`~` a list, a setext underline,
458
+ * a table's delimiter row or a fence, `12.` an ordered list, and leading
459
+ * whitespace an indented code block (or nothing, after a trim). The last is
460
+ * spelled as a character reference, which no block rule looks at.
461
+ */
462
+ lineLead(text, i) {
463
+ const ch = text[i];
464
+ if (ch === ' ')
465
+ return { text: '&#32;', consumed: 1 };
466
+ if (ch === '\t')
467
+ return { text: '&#9;', consumed: 1 };
468
+ if (this.mode !== 'block')
469
+ return null;
470
+ if ('#>-+=:|~'.includes(ch))
471
+ return { text: `\\${ch}`, consumed: 1 };
472
+ const ordered = /^(\d{1,9})([.)])/.exec(text.slice(i));
473
+ if (ordered) {
474
+ const after = text[i + ordered[0].length];
475
+ if (after === undefined || WS.test(after)) {
476
+ return {
477
+ text: `${ordered[1]}\\${ordered[2]}`,
478
+ consumed: ordered[0].length,
479
+ };
480
+ }
481
+ }
482
+ return null;
483
+ }
484
+ escape(text, i, after) {
485
+ const ch = text[i];
486
+ const prev = i > 0 ? text[i - 1] : lastChar(this.out);
487
+ const next = i + 1 < text.length ? text[i + 1] : after;
488
+ switch (ch) {
489
+ case '\\':
490
+ case '`':
491
+ case '*':
492
+ case '[':
493
+ case ']':
494
+ return `\\${ch}`;
495
+ case '_':
496
+ // intraword `_` is never emphasis — snake_case needs nothing
497
+ return WORD.test(prev ?? '') && WORD.test(next ?? '') ? ch : `\\${ch}`;
498
+ case '~':
499
+ // strikethrough is `~~` only, so a lone tilde is text — but one
500
+ // beside another, or beside a strikethrough's own delimiter, is not
501
+ return prev === '~' || next === '~' ? `\\${ch}` : ch;
502
+ case '<':
503
+ return /[A-Za-z/!?]/.test(text[i + 1] ?? '') ? `\\${ch}` : ch;
504
+ case '&':
505
+ return ENTITY_LIKE.test(text.slice(i)) ? `\\${ch}` : ch;
506
+ case '!':
507
+ // `!` then a link is an image
508
+ return next === '[' ? `\\${ch}` : ch;
509
+ case '|':
510
+ return this.mode === 'cell' ? `\\${ch}` : ch;
511
+ default:
512
+ return ch;
513
+ }
514
+ }
515
+ }
516
+ // --- flanking -----------------------------------------------------------------
517
+ //
518
+ // The parser's own rules (`./parse.ts`, the emphasis scan), asked in advance.
519
+ const PUNCT = /[\p{P}\p{S}]/u;
520
+ function kind(ch) {
521
+ if (ch === undefined || ch === '' || WS.test(ch))
522
+ return 'ws';
523
+ return PUNCT.test(ch) ? 'punct' : 'other';
524
+ }
525
+ function flanks(before, after) {
526
+ const b = kind(before);
527
+ const a = kind(after);
528
+ return {
529
+ b,
530
+ a,
531
+ left: a !== 'ws' && (a !== 'punct' || b !== 'other'),
532
+ right: b !== 'ws' && (b !== 'punct' || a !== 'other'),
533
+ };
534
+ }
535
+ function canOpen(ch, before, first) {
536
+ const f = flanks(before, first);
537
+ return ch === '_' ? f.left && (!f.right || f.b === 'punct') : f.left;
538
+ }
539
+ function canClose(ch, last, after) {
540
+ const f = flanks(last, after);
541
+ return ch === '_' ? f.right && (!f.left || f.a === 'punct') : f.right;
542
+ }
543
+ /** The whole last character of `text` — both halves of a surrogate pair. */
544
+ function lastChar(text) {
545
+ if (text === '')
546
+ return undefined;
547
+ const unit = text.charCodeAt(text.length - 1);
548
+ return unit >= 0xdc00 && unit <= 0xdfff && text.length >= 2
549
+ ? text.slice(-2)
550
+ : text[text.length - 1];
551
+ }
552
+ function firstChar(text) {
553
+ const cp = text.codePointAt(0);
554
+ return cp === undefined ? undefined : String.fromCodePoint(cp);
555
+ }
556
+ /** The first character a node writes — all its neighbour's flanking can
557
+ * see. Every delimiter and bracket is punctuation, whichever it turns out
558
+ * to be. */
559
+ function leadOf(node) {
560
+ switch (node.type) {
561
+ case 'text':
562
+ return firstChar(node.text);
563
+ case 'code':
564
+ return '`';
565
+ case 'strong':
566
+ case 'em':
567
+ return '*';
568
+ case 'del':
569
+ return '~';
570
+ case 'link':
571
+ return node.image ? '!' : '[';
572
+ case 'break':
573
+ return '\\';
574
+ case 'expression':
575
+ return '{';
576
+ case 'component':
577
+ return node.children.length ? leadOf(node.children[0]) : undefined;
578
+ }
579
+ }
580
+ /** `<https://…>` for a link whose text is its own target. */
581
+ function autolink(node) {
582
+ if (node.title || !node.href || node.children.length !== 1)
583
+ return null;
584
+ const only = node.children[0];
585
+ if (only.type !== 'text')
586
+ return null;
587
+ const text = only.text;
588
+ if (text === node.href &&
589
+ /^[a-zA-Z][a-zA-Z0-9+.-]{1,31}:[^<>\s]*$/.test(text)) {
590
+ return `<${text}>`;
591
+ }
592
+ if (node.href === `mailto:${text}` &&
593
+ /^[^<>\s@]+@[^<>\s@]+\.[^<>\s@]+$/.test(text)) {
594
+ return `<${text}>`;
595
+ }
596
+ return null;
597
+ }
598
+ /** A link destination: bare with its parentheses escaped, or in `<…>` when
599
+ * it has whitespace in it — the one form a space survives in. */
600
+ function destination(href) {
601
+ if (href === '')
602
+ return '<>';
603
+ if (/[\s<>]/.test(href)) {
604
+ return `<${href.replace(/[\n\r]/g, '').replace(/[<>]/g, (c) => encodeURIComponent(c))}>`;
605
+ }
606
+ return href.replace(/[\\()]/g, (c) => `\\${c}`);
607
+ }
608
+ /** ` "title"`, in whichever of the three quote styles the title does not
609
+ * contain — the parser's title scan has no escapes. */
610
+ function titlePart(title) {
611
+ if (!title)
612
+ return '';
613
+ if (!title.includes('"'))
614
+ return ` "${title}"`;
615
+ if (!title.includes("'"))
616
+ return ` '${title}'`;
617
+ if (!title.includes(')'))
618
+ return ` (${title})`;
619
+ return ` "${title.replace(/"/g, '&quot;')}"`;
620
+ }
621
+ /**
622
+ * Emphasis can open only before non-space and close only after it (the
623
+ * flanking rules), so `**bold **` is not bold. Whitespace at the edge of a
624
+ * strong/em/del node moves outside it, and a node that was all whitespace
625
+ * becomes that whitespace.
626
+ */
627
+ function expel(nodes) {
628
+ const out = [];
629
+ for (const node of nodes) {
630
+ if (node.type === 'strong' || node.type === 'em' || node.type === 'del') {
631
+ const children = expel(node.children);
632
+ const lead = takeEdge(children, 'start');
633
+ const trail = takeEdge(children, 'end');
634
+ if (lead)
635
+ out.push({ type: 'text', text: lead });
636
+ if (children.length > 0)
637
+ out.push({ type: node.type, children });
638
+ if (trail)
639
+ out.push({ type: 'text', text: trail });
640
+ }
641
+ else if (node.type === 'link' || node.type === 'component') {
642
+ out.push({ ...node, children: expel(node.children) });
643
+ }
644
+ else {
645
+ out.push(node);
646
+ }
647
+ }
648
+ return mergeTexts(out);
649
+ }
650
+ /** Remove, and return, the whitespace at one end of `nodes` (in place). */
651
+ function takeEdge(nodes, side) {
652
+ const at = side === 'start' ? 0 : nodes.length - 1;
653
+ const node = nodes[at];
654
+ if (!node || node.type !== 'text')
655
+ return '';
656
+ const m = side === 'start' ? /^\s+/u.exec(node.text) : /\s+$/u.exec(node.text);
657
+ if (!m)
658
+ return '';
659
+ const rest = side === 'start'
660
+ ? node.text.slice(m[0].length)
661
+ : node.text.slice(0, node.text.length - m[0].length);
662
+ if (rest === '')
663
+ nodes.splice(at, 1);
664
+ else
665
+ nodes[at] = { type: 'text', text: rest };
666
+ return m[0];
667
+ }
668
+ function mergeTexts(nodes) {
669
+ const out = [];
670
+ for (const node of nodes) {
671
+ const prev = out[out.length - 1];
672
+ if (node.type === 'text') {
673
+ if (node.text === '')
674
+ continue;
675
+ if (prev?.type === 'text') {
676
+ out[out.length - 1] = { type: 'text', text: prev.text + node.text };
677
+ continue;
678
+ }
679
+ }
680
+ out.push(node);
681
+ }
682
+ return out;
683
+ }
684
+ //# sourceMappingURL=stringify.js.map