@bendyline/squisq 0.1.2 → 1.0.1

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 (328) hide show
  1. package/dist/{themeLibrary-DySHPcgj.d.ts → Doc-1hmT1LZl.d.ts} +1 -42
  2. package/dist/__tests__/animationUtils.test.d.ts +2 -0
  3. package/dist/__tests__/animationUtils.test.d.ts.map +1 -0
  4. package/dist/__tests__/animationUtils.test.js +60 -0
  5. package/dist/__tests__/animationUtils.test.js.map +1 -0
  6. package/dist/__tests__/contentExtractor.test.d.ts +2 -0
  7. package/dist/__tests__/contentExtractor.test.d.ts.map +1 -0
  8. package/dist/__tests__/contentExtractor.test.js +151 -0
  9. package/dist/__tests__/contentExtractor.test.js.map +1 -0
  10. package/dist/__tests__/geohash.test.d.ts +2 -0
  11. package/dist/__tests__/geohash.test.d.ts.map +1 -0
  12. package/dist/__tests__/geohash.test.js +87 -0
  13. package/dist/__tests__/geohash.test.js.map +1 -0
  14. package/dist/__tests__/getLayers.test.d.ts +2 -0
  15. package/dist/__tests__/getLayers.test.d.ts.map +1 -0
  16. package/dist/__tests__/getLayers.test.js +167 -0
  17. package/dist/__tests__/getLayers.test.js.map +1 -0
  18. package/dist/__tests__/haversine.test.d.ts +2 -0
  19. package/dist/__tests__/haversine.test.d.ts.map +1 -0
  20. package/dist/__tests__/haversine.test.js +56 -0
  21. package/dist/__tests__/haversine.test.js.map +1 -0
  22. package/dist/__tests__/localForageAdapter.test.d.ts +8 -0
  23. package/dist/__tests__/localForageAdapter.test.d.ts.map +1 -0
  24. package/dist/__tests__/localForageAdapter.test.js +130 -0
  25. package/dist/__tests__/localForageAdapter.test.js.map +1 -0
  26. package/dist/__tests__/markdown.test.d.ts +2 -0
  27. package/dist/__tests__/markdown.test.d.ts.map +1 -0
  28. package/dist/__tests__/markdown.test.js +654 -0
  29. package/dist/__tests__/markdown.test.js.map +1 -0
  30. package/dist/__tests__/markdownToDoc.test.d.ts +2 -0
  31. package/dist/__tests__/markdownToDoc.test.d.ts.map +1 -0
  32. package/dist/__tests__/markdownToDoc.test.js +313 -0
  33. package/dist/__tests__/markdownToDoc.test.js.map +1 -0
  34. package/dist/__tests__/seededRandom.test.d.ts +2 -0
  35. package/dist/__tests__/seededRandom.test.d.ts.map +1 -0
  36. package/dist/__tests__/seededRandom.test.js +125 -0
  37. package/dist/__tests__/seededRandom.test.js.map +1 -0
  38. package/dist/__tests__/slideshowGenerator.test.d.ts +2 -0
  39. package/dist/__tests__/slideshowGenerator.test.d.ts.map +1 -0
  40. package/dist/__tests__/slideshowGenerator.test.js +114 -0
  41. package/dist/__tests__/slideshowGenerator.test.js.map +1 -0
  42. package/dist/__tests__/storage.test.d.ts +2 -0
  43. package/dist/__tests__/storage.test.d.ts.map +1 -0
  44. package/dist/__tests__/storage.test.js +51 -0
  45. package/dist/__tests__/storage.test.js.map +1 -0
  46. package/dist/__tests__/templates.test.d.ts +2 -0
  47. package/dist/__tests__/templates.test.d.ts.map +1 -0
  48. package/dist/__tests__/templates.test.js +217 -0
  49. package/dist/__tests__/templates.test.js.map +1 -0
  50. package/dist/__tests__/timing.test.d.ts +2 -0
  51. package/dist/__tests__/timing.test.d.ts.map +1 -0
  52. package/dist/__tests__/timing.test.js +131 -0
  53. package/dist/__tests__/timing.test.js.map +1 -0
  54. package/dist/chunk-3E5F2XMR.js +129 -0
  55. package/dist/chunk-3E5F2XMR.js.map +1 -0
  56. package/dist/chunk-6YJPI6VI.js +35 -0
  57. package/dist/chunk-6YJPI6VI.js.map +1 -0
  58. package/dist/chunk-FVTQSNR7.js +100 -0
  59. package/dist/chunk-FVTQSNR7.js.map +1 -0
  60. package/dist/chunk-V543AI2F.js +1 -0
  61. package/dist/chunk-V543AI2F.js.map +1 -0
  62. package/dist/chunk-VP5SZTZ2.js +792 -0
  63. package/dist/chunk-VP5SZTZ2.js.map +1 -0
  64. package/dist/doc/docToMarkdown.d.ts +41 -0
  65. package/dist/doc/docToMarkdown.d.ts.map +1 -0
  66. package/dist/doc/docToMarkdown.js +88 -0
  67. package/dist/doc/docToMarkdown.js.map +1 -0
  68. package/dist/doc/getLayers.d.ts +65 -0
  69. package/dist/doc/getLayers.d.ts.map +1 -0
  70. package/dist/doc/getLayers.js +103 -0
  71. package/dist/doc/getLayers.js.map +1 -0
  72. package/dist/doc/index.d.ts +9 -3
  73. package/dist/doc/index.d.ts.map +1 -0
  74. package/dist/doc/index.js +6 -125
  75. package/dist/doc/index.js.map +1 -1
  76. package/dist/doc/markdownToDoc.d.ts +68 -0
  77. package/dist/doc/markdownToDoc.d.ts.map +1 -0
  78. package/dist/doc/markdownToDoc.js +225 -0
  79. package/dist/doc/markdownToDoc.js.map +1 -0
  80. package/dist/doc/templates/accentImage.d.ts +59 -0
  81. package/dist/doc/templates/accentImage.d.ts.map +1 -0
  82. package/dist/doc/templates/accentImage.js +275 -0
  83. package/dist/doc/templates/accentImage.js.map +1 -0
  84. package/dist/doc/templates/captionUtils.d.ts +20 -0
  85. package/dist/doc/templates/captionUtils.d.ts.map +1 -0
  86. package/dist/doc/templates/captionUtils.js +29 -0
  87. package/dist/doc/templates/captionUtils.js.map +1 -0
  88. package/dist/doc/templates/comparisonBar.d.ts +13 -0
  89. package/dist/doc/templates/comparisonBar.d.ts.map +1 -0
  90. package/dist/doc/templates/comparisonBar.js +127 -0
  91. package/dist/doc/templates/comparisonBar.js.map +1 -0
  92. package/dist/doc/templates/coverBlock.d.ts +51 -0
  93. package/dist/doc/templates/coverBlock.d.ts.map +1 -0
  94. package/dist/doc/templates/coverBlock.js +125 -0
  95. package/dist/doc/templates/coverBlock.js.map +1 -0
  96. package/dist/doc/templates/dateEvent.d.ts +15 -0
  97. package/dist/doc/templates/dateEvent.d.ts.map +1 -0
  98. package/dist/doc/templates/dateEvent.js +110 -0
  99. package/dist/doc/templates/dateEvent.js.map +1 -0
  100. package/dist/doc/templates/definitionCard.d.ts +13 -0
  101. package/dist/doc/templates/definitionCard.d.ts.map +1 -0
  102. package/dist/doc/templates/definitionCard.js +114 -0
  103. package/dist/doc/templates/definitionCard.js.map +1 -0
  104. package/dist/doc/templates/factCard.d.ts +15 -0
  105. package/dist/doc/templates/factCard.d.ts.map +1 -0
  106. package/dist/doc/templates/factCard.js +100 -0
  107. package/dist/doc/templates/factCard.js.map +1 -0
  108. package/dist/doc/templates/fullBleedQuote.d.ts +13 -0
  109. package/dist/doc/templates/fullBleedQuote.d.ts.map +1 -0
  110. package/dist/doc/templates/fullBleedQuote.js +54 -0
  111. package/dist/doc/templates/fullBleedQuote.js.map +1 -0
  112. package/dist/doc/templates/imageWithCaption.d.ts +13 -0
  113. package/dist/doc/templates/imageWithCaption.d.ts.map +1 -0
  114. package/dist/doc/templates/imageWithCaption.js +142 -0
  115. package/dist/doc/templates/imageWithCaption.js.map +1 -0
  116. package/dist/doc/templates/index.d.ts +104 -0
  117. package/dist/doc/templates/index.d.ts.map +1 -0
  118. package/dist/doc/templates/index.js +442 -0
  119. package/dist/doc/templates/index.js.map +1 -0
  120. package/dist/doc/templates/listBlock.d.ts +13 -0
  121. package/dist/doc/templates/listBlock.d.ts.map +1 -0
  122. package/dist/doc/templates/listBlock.js +89 -0
  123. package/dist/doc/templates/listBlock.js.map +1 -0
  124. package/dist/doc/templates/mapBlock.d.ts +17 -0
  125. package/dist/doc/templates/mapBlock.d.ts.map +1 -0
  126. package/dist/doc/templates/mapBlock.js +112 -0
  127. package/dist/doc/templates/mapBlock.js.map +1 -0
  128. package/dist/doc/templates/persistentLayers.d.ts +39 -0
  129. package/dist/doc/templates/persistentLayers.d.ts.map +1 -0
  130. package/dist/doc/templates/persistentLayers.js +447 -0
  131. package/dist/doc/templates/persistentLayers.js.map +1 -0
  132. package/dist/doc/templates/photoGrid.d.ts +20 -0
  133. package/dist/doc/templates/photoGrid.d.ts.map +1 -0
  134. package/dist/doc/templates/photoGrid.js +172 -0
  135. package/dist/doc/templates/photoGrid.js.map +1 -0
  136. package/dist/doc/templates/pullQuote.d.ts +13 -0
  137. package/dist/doc/templates/pullQuote.d.ts.map +1 -0
  138. package/dist/doc/templates/pullQuote.js +109 -0
  139. package/dist/doc/templates/pullQuote.js.map +1 -0
  140. package/dist/doc/templates/quoteBlock.d.ts +15 -0
  141. package/dist/doc/templates/quoteBlock.d.ts.map +1 -0
  142. package/dist/doc/templates/quoteBlock.js +97 -0
  143. package/dist/doc/templates/quoteBlock.js.map +1 -0
  144. package/dist/doc/templates/sectionHeader.d.ts +14 -0
  145. package/dist/doc/templates/sectionHeader.d.ts.map +1 -0
  146. package/dist/doc/templates/sectionHeader.js +96 -0
  147. package/dist/doc/templates/sectionHeader.js.map +1 -0
  148. package/dist/doc/templates/statHighlight.d.ts +15 -0
  149. package/dist/doc/templates/statHighlight.d.ts.map +1 -0
  150. package/dist/doc/templates/statHighlight.js +99 -0
  151. package/dist/doc/templates/statHighlight.js.map +1 -0
  152. package/dist/doc/templates/titleBlock.d.ts +13 -0
  153. package/dist/doc/templates/titleBlock.d.ts.map +1 -0
  154. package/dist/doc/templates/titleBlock.js +92 -0
  155. package/dist/doc/templates/titleBlock.js.map +1 -0
  156. package/dist/doc/templates/twoColumn.d.ts +15 -0
  157. package/dist/doc/templates/twoColumn.d.ts.map +1 -0
  158. package/dist/doc/templates/twoColumn.js +219 -0
  159. package/dist/doc/templates/twoColumn.js.map +1 -0
  160. package/dist/doc/templates/videoPullQuote.d.ts +20 -0
  161. package/dist/doc/templates/videoPullQuote.d.ts.map +1 -0
  162. package/dist/doc/templates/videoPullQuote.js +118 -0
  163. package/dist/doc/templates/videoPullQuote.js.map +1 -0
  164. package/dist/doc/templates/videoWithCaption.d.ts +20 -0
  165. package/dist/doc/templates/videoWithCaption.d.ts.map +1 -0
  166. package/dist/doc/templates/videoWithCaption.js +104 -0
  167. package/dist/doc/templates/videoWithCaption.js.map +1 -0
  168. package/dist/doc/utils/animationUtils.d.ts +34 -0
  169. package/dist/doc/utils/animationUtils.d.ts.map +1 -0
  170. package/dist/doc/utils/animationUtils.js +110 -0
  171. package/dist/doc/utils/animationUtils.js.map +1 -0
  172. package/dist/doc/utils/themeUtils.d.ts +55 -0
  173. package/dist/doc/utils/themeUtils.d.ts.map +1 -0
  174. package/dist/doc/utils/themeUtils.js +109 -0
  175. package/dist/doc/utils/themeUtils.js.map +1 -0
  176. package/dist/generate/contentExtractor.d.ts +112 -0
  177. package/dist/generate/contentExtractor.d.ts.map +1 -0
  178. package/dist/generate/contentExtractor.js +638 -0
  179. package/dist/generate/contentExtractor.js.map +1 -0
  180. package/dist/generate/index.d.ts +7 -0
  181. package/dist/generate/index.d.ts.map +1 -0
  182. package/dist/generate/index.js +4 -0
  183. package/dist/generate/index.js.map +1 -0
  184. package/dist/generate/slideshowGenerator.d.ts +72 -0
  185. package/dist/generate/slideshowGenerator.d.ts.map +1 -0
  186. package/dist/generate/slideshowGenerator.js +159 -0
  187. package/dist/generate/slideshowGenerator.js.map +1 -0
  188. package/dist/generate/templateMapper.d.ts +23 -0
  189. package/dist/generate/templateMapper.d.ts.map +1 -0
  190. package/dist/generate/templateMapper.js +114 -0
  191. package/dist/generate/templateMapper.js.map +1 -0
  192. package/dist/index.d.ts +9 -8
  193. package/dist/index.d.ts.map +1 -0
  194. package/dist/index.js +8 -216
  195. package/dist/index.js.map +1 -1
  196. package/dist/markdown/convert.d.ts +71 -0
  197. package/dist/markdown/convert.d.ts.map +1 -0
  198. package/dist/markdown/convert.js +746 -0
  199. package/dist/markdown/convert.js.map +1 -0
  200. package/dist/markdown/htmlParse.d.ts +26 -0
  201. package/dist/markdown/htmlParse.d.ts.map +1 -0
  202. package/dist/markdown/htmlParse.js +195 -0
  203. package/dist/markdown/htmlParse.js.map +1 -0
  204. package/dist/markdown/index.d.ts +19 -225
  205. package/dist/markdown/index.d.ts.map +1 -0
  206. package/dist/markdown/index.js +33 -32
  207. package/dist/markdown/index.js.map +1 -1
  208. package/dist/markdown/parse.d.ts +27 -0
  209. package/dist/markdown/parse.d.ts.map +1 -0
  210. package/dist/markdown/parse.js +90 -0
  211. package/dist/markdown/parse.js.map +1 -0
  212. package/dist/markdown/stringify.d.ts +32 -0
  213. package/dist/markdown/stringify.d.ts.map +1 -0
  214. package/dist/markdown/stringify.js +108 -0
  215. package/dist/markdown/stringify.js.map +1 -0
  216. package/dist/markdown/types.d.ts +496 -0
  217. package/dist/markdown/types.d.ts.map +1 -0
  218. package/dist/markdown/types.js +17 -0
  219. package/dist/markdown/types.js.map +1 -0
  220. package/dist/markdown/utils.d.ts +78 -0
  221. package/dist/markdown/utils.d.ts.map +1 -0
  222. package/dist/markdown/utils.js +149 -0
  223. package/dist/markdown/utils.js.map +1 -0
  224. package/dist/random/SeededRandom.d.ts +50 -0
  225. package/dist/random/SeededRandom.d.ts.map +1 -0
  226. package/dist/random/SeededRandom.js +115 -0
  227. package/dist/random/SeededRandom.js.map +1 -0
  228. package/dist/random/index.d.ts +2 -0
  229. package/dist/random/index.d.ts.map +1 -0
  230. package/dist/random/index.js +2 -0
  231. package/dist/random/index.js.map +1 -0
  232. package/dist/schemas/BlockTemplates.d.ts +583 -0
  233. package/dist/schemas/BlockTemplates.d.ts.map +1 -0
  234. package/dist/schemas/BlockTemplates.js +72 -0
  235. package/dist/schemas/BlockTemplates.js.map +1 -0
  236. package/dist/schemas/Doc.d.ts +411 -0
  237. package/dist/schemas/Doc.d.ts.map +1 -0
  238. package/dist/schemas/Doc.js +90 -0
  239. package/dist/schemas/Doc.js.map +1 -0
  240. package/dist/schemas/LayoutStrategy.d.ts +84 -0
  241. package/dist/schemas/LayoutStrategy.d.ts.map +1 -0
  242. package/dist/schemas/LayoutStrategy.js +123 -0
  243. package/dist/schemas/LayoutStrategy.js.map +1 -0
  244. package/dist/schemas/MediaProvider.d.ts +65 -0
  245. package/dist/schemas/MediaProvider.d.ts.map +1 -0
  246. package/dist/schemas/MediaProvider.js +13 -0
  247. package/dist/schemas/MediaProvider.js.map +1 -0
  248. package/dist/schemas/Theme.d.ts +163 -0
  249. package/dist/schemas/Theme.d.ts.map +1 -0
  250. package/dist/schemas/Theme.js +62 -0
  251. package/dist/schemas/Theme.js.map +1 -0
  252. package/dist/schemas/Types.d.ts +14 -0
  253. package/dist/schemas/Types.d.ts.map +1 -0
  254. package/dist/schemas/Types.js +5 -0
  255. package/dist/schemas/Types.js.map +1 -0
  256. package/dist/schemas/Viewport.d.ts +74 -0
  257. package/dist/schemas/Viewport.d.ts.map +1 -0
  258. package/dist/schemas/Viewport.js +63 -0
  259. package/dist/schemas/Viewport.js.map +1 -0
  260. package/dist/schemas/index.d.ts +10 -70
  261. package/dist/schemas/index.d.ts.map +1 -0
  262. package/dist/schemas/index.js +7 -60
  263. package/dist/schemas/index.js.map +1 -1
  264. package/dist/schemas/themeLibrary.d.ts +41 -0
  265. package/dist/schemas/themeLibrary.d.ts.map +1 -0
  266. package/dist/schemas/themeLibrary.js +466 -0
  267. package/dist/schemas/themeLibrary.js.map +1 -0
  268. package/dist/spatial/Geohash.d.ts +85 -0
  269. package/dist/spatial/Geohash.d.ts.map +1 -0
  270. package/dist/spatial/Geohash.js +142 -0
  271. package/dist/spatial/Geohash.js.map +1 -0
  272. package/dist/spatial/Haversine.d.ts +24 -0
  273. package/dist/spatial/Haversine.d.ts.map +1 -0
  274. package/dist/spatial/Haversine.js +48 -0
  275. package/dist/spatial/Haversine.js.map +1 -0
  276. package/dist/spatial/index.d.ts +3 -111
  277. package/dist/spatial/index.d.ts.map +1 -0
  278. package/dist/spatial/index.js +2 -24
  279. package/dist/spatial/index.js.map +1 -1
  280. package/dist/storage/LocalForageAdapter.d.ts +36 -0
  281. package/dist/storage/LocalForageAdapter.d.ts.map +1 -0
  282. package/dist/storage/LocalForageAdapter.js +82 -0
  283. package/dist/storage/LocalForageAdapter.js.map +1 -0
  284. package/dist/storage/LocalStorageAdapter.d.ts +16 -0
  285. package/dist/storage/LocalStorageAdapter.d.ts.map +1 -0
  286. package/dist/storage/LocalStorageAdapter.js +50 -0
  287. package/dist/storage/LocalStorageAdapter.js.map +1 -0
  288. package/dist/storage/MemoryStorageAdapter.d.ts +15 -0
  289. package/dist/storage/MemoryStorageAdapter.d.ts.map +1 -0
  290. package/dist/storage/MemoryStorageAdapter.js +34 -0
  291. package/dist/storage/MemoryStorageAdapter.js.map +1 -0
  292. package/dist/storage/Storage.d.ts +23 -0
  293. package/dist/storage/Storage.d.ts.map +1 -0
  294. package/dist/storage/Storage.js +9 -0
  295. package/dist/storage/Storage.js.map +1 -0
  296. package/dist/storage/index.d.ts +6 -91
  297. package/dist/storage/index.d.ts.map +1 -0
  298. package/dist/storage/index.js +3 -10
  299. package/dist/storage/index.js.map +1 -1
  300. package/dist/story/index.d.ts +3 -2
  301. package/dist/themeLibrary-DR1VRo-8.d.ts +44 -0
  302. package/dist/timing/index.d.ts +4 -0
  303. package/dist/timing/index.d.ts.map +1 -0
  304. package/dist/timing/index.js +3 -0
  305. package/dist/timing/index.js.map +1 -0
  306. package/dist/timing/narrationTiming.d.ts +54 -0
  307. package/dist/timing/narrationTiming.d.ts.map +1 -0
  308. package/dist/timing/narrationTiming.js +190 -0
  309. package/dist/timing/narrationTiming.js.map +1 -0
  310. package/dist/timing/readingTime.d.ts +54 -0
  311. package/dist/timing/readingTime.d.ts.map +1 -0
  312. package/dist/timing/readingTime.js +49 -0
  313. package/dist/timing/readingTime.js.map +1 -0
  314. package/package.json +17 -3
  315. package/src/__tests__/contentExtractor.test.ts +183 -0
  316. package/src/__tests__/seededRandom.test.ts +142 -0
  317. package/src/__tests__/slideshowGenerator.test.ts +128 -0
  318. package/src/__tests__/timing.test.ts +167 -0
  319. package/src/generate/contentExtractor.ts +808 -0
  320. package/src/generate/index.ts +21 -0
  321. package/src/generate/slideshowGenerator.ts +273 -0
  322. package/src/generate/templateMapper.ts +170 -0
  323. package/src/index.ts +3 -0
  324. package/src/random/SeededRandom.ts +127 -0
  325. package/src/random/index.ts +1 -0
  326. package/src/timing/index.ts +17 -0
  327. package/src/timing/narrationTiming.ts +220 -0
  328. package/src/timing/readingTime.ts +94 -0
@@ -0,0 +1,746 @@
1
+ /**
2
+ * mdast ↔ Squisq Markdown Node Conversion
3
+ *
4
+ * Converts between the remark/mdast AST format and the squisq
5
+ * MarkdownDocument JSON format. This is the bridge layer that allows
6
+ * us to use the battle-tested unified/remark ecosystem for parsing
7
+ * and serialization while exposing our own clean, well-typed interfaces.
8
+ *
9
+ * The conversion is designed for perfect round-tripping:
10
+ * toMdast(fromMdast(tree)) should produce an equivalent mdast tree.
11
+ */
12
+ import { parseHtmlToNodes } from './htmlParse.js';
13
+ // ============================================
14
+ // Position conversion
15
+ // ============================================
16
+ function convertPosition(pos) {
17
+ if (!pos)
18
+ return undefined;
19
+ return {
20
+ start: {
21
+ line: pos.start.line,
22
+ column: pos.start.column,
23
+ ...(pos.start.offset != null ? { offset: pos.start.offset } : {}),
24
+ },
25
+ end: {
26
+ line: pos.end.line,
27
+ column: pos.end.column,
28
+ ...(pos.end.offset != null ? { offset: pos.end.offset } : {}),
29
+ },
30
+ };
31
+ }
32
+ function toMdastPosition(pos) {
33
+ return {
34
+ start: {
35
+ line: pos.start.line,
36
+ column: pos.start.column,
37
+ ...(pos.start.offset != null ? { offset: pos.start.offset } : {}),
38
+ },
39
+ end: {
40
+ line: pos.end.line,
41
+ column: pos.end.column,
42
+ ...(pos.end.offset != null ? { offset: pos.end.offset } : {}),
43
+ },
44
+ };
45
+ }
46
+ /** Conditionally include position in node. */
47
+ function posField(pos) {
48
+ return pos ? { position: pos } : {};
49
+ }
50
+ function mdastPosField(pos) {
51
+ return pos ? { position: toMdastPosition(pos) } : {};
52
+ }
53
+ // ============================================
54
+ // mdast → Squisq (fromMdast)
55
+ // ============================================
56
+ /**
57
+ * Extract plain text content from an mdast node tree.
58
+ * Used for directive labels.
59
+ */
60
+ function extractText(node) {
61
+ if (node.value != null)
62
+ return node.value;
63
+ if (node.children) {
64
+ return node.children.map(extractText).join('');
65
+ }
66
+ return '';
67
+ }
68
+ // ============================================
69
+ // Template annotation helpers
70
+ // ============================================
71
+ /**
72
+ * Regex matching a trailing `{[templateName key=value …]}` annotation.
73
+ * Captures the content between `{[` and `]}`.
74
+ */
75
+ const TEMPLATE_ANNOTATION_RE = /\s*\{\[([^\]]+)\]\}\s*$/;
76
+ /**
77
+ * Extract a `{[templateName key=value …]}` annotation from a heading's
78
+ * inline children. Mutates the children array in-place: strips the
79
+ * annotation text from the last text node (or removes the node entirely).
80
+ *
81
+ * @returns The parsed annotation, or null if none found.
82
+ */
83
+ function extractTemplateAnnotation(children) {
84
+ // Walk backwards to find the last text node
85
+ for (let i = children.length - 1; i >= 0; i--) {
86
+ const child = children[i];
87
+ if (child.type === 'text') {
88
+ const match = child.value.match(TEMPLATE_ANNOTATION_RE);
89
+ if (match) {
90
+ const inner = match[1].trim();
91
+ const annotation = parseAnnotationTokens(inner);
92
+ // Strip the matched portion from the text
93
+ const stripped = child.value.slice(0, match.index).replace(/\s+$/, '');
94
+ if (stripped) {
95
+ child.value = stripped;
96
+ }
97
+ else {
98
+ // Remove the now-empty text node
99
+ children.splice(i, 1);
100
+ }
101
+ return annotation;
102
+ }
103
+ // Only check the last text node (trailing position)
104
+ break;
105
+ }
106
+ // If the last child isn't a text node, there's no annotation
107
+ break;
108
+ }
109
+ return null;
110
+ }
111
+ /**
112
+ * Parse the inner content of a `{[…]}` annotation into template + params.
113
+ *
114
+ * Input: `"chart colorScheme=blue size=large"`
115
+ * Output: `{ template: 'chart', params: { colorScheme: 'blue', size: 'large' } }`
116
+ */
117
+ function parseAnnotationTokens(inner) {
118
+ const tokens = inner.split(/\s+/);
119
+ const template = tokens[0];
120
+ const params = {};
121
+ for (let i = 1; i < tokens.length; i++) {
122
+ const eqIdx = tokens[i].indexOf('=');
123
+ if (eqIdx > 0) {
124
+ params[tokens[i].slice(0, eqIdx)] = tokens[i].slice(eqIdx + 1);
125
+ }
126
+ }
127
+ const result = { template };
128
+ if (Object.keys(params).length > 0) {
129
+ result.params = params;
130
+ }
131
+ return result;
132
+ }
133
+ /**
134
+ * Serialize a HeadingTemplateAnnotation back to `{[templateName key=value …]}` text.
135
+ */
136
+ function serializeTemplateAnnotation(annotation) {
137
+ let result = `{[${annotation.template}`;
138
+ if (annotation.params) {
139
+ for (const [key, value] of Object.entries(annotation.params)) {
140
+ result += ` ${key}=${value}`;
141
+ }
142
+ }
143
+ result += ']}';
144
+ return result;
145
+ }
146
+ /**
147
+ * Convert an mdast Root node to a MarkdownDocument.
148
+ *
149
+ * @param root - The mdast root node (from remark-parse)
150
+ * @param options - Conversion options
151
+ * @returns A MarkdownDocument
152
+ */
153
+ export function fromMdast(root, options) {
154
+ const doParseHtml = options?.parseHtml !== false;
155
+ return {
156
+ type: 'document',
157
+ children: convertBlockChildren(root.children ?? [], doParseHtml),
158
+ ...posField(convertPosition(root.position)),
159
+ };
160
+ }
161
+ function convertBlockChildren(children, parseHtml) {
162
+ const result = [];
163
+ for (const child of children) {
164
+ const node = convertBlockNode(child, parseHtml);
165
+ if (node)
166
+ result.push(node);
167
+ }
168
+ return result;
169
+ }
170
+ function convertInlineChildren(children, parseHtml) {
171
+ const result = [];
172
+ for (const child of children) {
173
+ const node = convertInlineNode(child, parseHtml);
174
+ if (node)
175
+ result.push(node);
176
+ }
177
+ return result;
178
+ }
179
+ function convertBlockNode(node, parseHtml) {
180
+ const pos = convertPosition(node.position);
181
+ switch (node.type) {
182
+ case 'heading': {
183
+ const headingChildren = convertInlineChildren(node.children ?? [], parseHtml);
184
+ const annotation = extractTemplateAnnotation(headingChildren);
185
+ const result = {
186
+ type: 'heading',
187
+ depth: (node.depth ?? 1),
188
+ children: headingChildren,
189
+ ...posField(pos),
190
+ };
191
+ if (annotation) {
192
+ result.templateAnnotation = annotation;
193
+ }
194
+ return result;
195
+ }
196
+ case 'paragraph':
197
+ return {
198
+ type: 'paragraph',
199
+ children: convertInlineChildren(node.children ?? [], parseHtml),
200
+ ...posField(pos),
201
+ };
202
+ case 'blockquote':
203
+ return {
204
+ type: 'blockquote',
205
+ children: convertBlockChildren(node.children ?? [], parseHtml),
206
+ ...posField(pos),
207
+ };
208
+ case 'list':
209
+ return {
210
+ type: 'list',
211
+ ordered: node.ordered ?? false,
212
+ ...(node.start != null ? { start: node.start } : {}),
213
+ ...(node.spread != null ? { spread: node.spread } : {}),
214
+ children: (node.children ?? []).map((item) => convertListItem(item, parseHtml)),
215
+ ...posField(pos),
216
+ };
217
+ case 'code':
218
+ return {
219
+ type: 'code',
220
+ ...(node.lang != null ? { lang: node.lang } : {}),
221
+ ...(node.meta != null ? { meta: node.meta } : {}),
222
+ value: node.value ?? '',
223
+ ...posField(pos),
224
+ };
225
+ case 'thematicBreak':
226
+ return {
227
+ type: 'thematicBreak',
228
+ ...posField(pos),
229
+ };
230
+ case 'table':
231
+ return {
232
+ type: 'table',
233
+ ...(node.align
234
+ ? { align: node.align.map((a) => a) }
235
+ : {}),
236
+ children: (node.children ?? []).map((row, i) => convertTableRow(row, i === 0, parseHtml)),
237
+ ...posField(pos),
238
+ };
239
+ case 'html':
240
+ return {
241
+ type: 'htmlBlock',
242
+ rawHtml: node.value ?? '',
243
+ htmlChildren: parseHtml ? parseHtmlToNodes(node.value ?? '') : [],
244
+ ...posField(pos),
245
+ };
246
+ case 'math':
247
+ return {
248
+ type: 'math',
249
+ value: node.value ?? '',
250
+ ...(node.meta != null ? { meta: node.meta } : {}),
251
+ ...posField(pos),
252
+ };
253
+ case 'definition':
254
+ return {
255
+ type: 'definition',
256
+ identifier: node.identifier ?? '',
257
+ ...(node.label != null ? { label: node.label } : {}),
258
+ url: node.url ?? '',
259
+ ...(node.title != null ? { title: node.title } : {}),
260
+ ...posField(pos),
261
+ };
262
+ case 'footnoteDefinition':
263
+ return {
264
+ type: 'footnoteDefinition',
265
+ identifier: node.identifier ?? '',
266
+ ...(node.label != null ? { label: node.label } : {}),
267
+ children: convertBlockChildren(node.children ?? [], parseHtml),
268
+ ...posField(pos),
269
+ };
270
+ case 'containerDirective': {
271
+ const allChildren = node.children ?? [];
272
+ let label;
273
+ let contentChildren = allChildren;
274
+ // Extract directive label (first paragraph with directiveLabel flag)
275
+ if (allChildren.length > 0 &&
276
+ allChildren[0].type === 'paragraph' &&
277
+ allChildren[0].data?.directiveLabel === true) {
278
+ label = extractText(allChildren[0]);
279
+ contentChildren = allChildren.slice(1);
280
+ }
281
+ return {
282
+ type: 'containerDirective',
283
+ name: node.name ?? '',
284
+ ...(label ? { label } : {}),
285
+ ...(node.attributes && Object.keys(node.attributes).length > 0
286
+ ? { attributes: node.attributes }
287
+ : {}),
288
+ children: convertBlockChildren(contentChildren, parseHtml),
289
+ ...posField(pos),
290
+ };
291
+ }
292
+ case 'leafDirective':
293
+ return {
294
+ type: 'leafDirective',
295
+ name: node.name ?? '',
296
+ ...(node.attributes && Object.keys(node.attributes).length > 0
297
+ ? { attributes: node.attributes }
298
+ : {}),
299
+ children: convertInlineChildren(node.children ?? [], parseHtml),
300
+ ...posField(pos),
301
+ };
302
+ case 'yaml':
303
+ // YAML frontmatter nodes are handled separately in parse.ts — skip silently
304
+ return null;
305
+ default:
306
+ // Unknown block node — skip with a warning
307
+ if (typeof console !== 'undefined') {
308
+ console.warn(`[squisq/markdown] Unknown mdast block node type: "${node.type}"`);
309
+ }
310
+ return null;
311
+ }
312
+ }
313
+ function convertListItem(node, parseHtml) {
314
+ const pos = convertPosition(node.position);
315
+ return {
316
+ type: 'listItem',
317
+ ...(node.checked != null ? { checked: node.checked } : {}),
318
+ ...(node.spread != null ? { spread: node.spread } : {}),
319
+ children: convertBlockChildren(node.children ?? [], parseHtml),
320
+ ...posField(pos),
321
+ };
322
+ }
323
+ function convertTableRow(node, isHeader, parseHtml) {
324
+ const pos = convertPosition(node.position);
325
+ return {
326
+ type: 'tableRow',
327
+ children: (node.children ?? []).map((cell) => convertTableCell(cell, isHeader, parseHtml)),
328
+ ...posField(pos),
329
+ };
330
+ }
331
+ function convertTableCell(node, isHeader, parseHtml) {
332
+ const pos = convertPosition(node.position);
333
+ return {
334
+ type: 'tableCell',
335
+ ...(isHeader ? { isHeader: true } : {}),
336
+ children: convertInlineChildren(node.children ?? [], parseHtml),
337
+ ...posField(pos),
338
+ };
339
+ }
340
+ function convertInlineNode(node, parseHtml) {
341
+ const pos = convertPosition(node.position);
342
+ switch (node.type) {
343
+ case 'text':
344
+ return {
345
+ type: 'text',
346
+ value: node.value ?? '',
347
+ ...posField(pos),
348
+ };
349
+ case 'emphasis':
350
+ return {
351
+ type: 'emphasis',
352
+ children: convertInlineChildren(node.children ?? [], parseHtml),
353
+ ...posField(pos),
354
+ };
355
+ case 'strong':
356
+ return {
357
+ type: 'strong',
358
+ children: convertInlineChildren(node.children ?? [], parseHtml),
359
+ ...posField(pos),
360
+ };
361
+ case 'delete':
362
+ return {
363
+ type: 'delete',
364
+ children: convertInlineChildren(node.children ?? [], parseHtml),
365
+ ...posField(pos),
366
+ };
367
+ case 'inlineCode':
368
+ return {
369
+ type: 'inlineCode',
370
+ value: node.value ?? '',
371
+ ...posField(pos),
372
+ };
373
+ case 'link':
374
+ return {
375
+ type: 'link',
376
+ url: node.url ?? '',
377
+ ...(node.title != null ? { title: node.title } : {}),
378
+ children: convertInlineChildren(node.children ?? [], parseHtml),
379
+ ...posField(pos),
380
+ };
381
+ case 'image':
382
+ return {
383
+ type: 'image',
384
+ url: node.url ?? '',
385
+ ...(node.alt != null ? { alt: node.alt } : {}),
386
+ ...(node.title != null ? { title: node.title } : {}),
387
+ ...posField(pos),
388
+ };
389
+ case 'break':
390
+ return {
391
+ type: 'break',
392
+ ...posField(pos),
393
+ };
394
+ case 'html':
395
+ return {
396
+ type: 'htmlInline',
397
+ rawHtml: node.value ?? '',
398
+ htmlChildren: parseHtml ? parseHtmlToNodes(node.value ?? '') : [],
399
+ ...posField(pos),
400
+ };
401
+ case 'inlineMath':
402
+ return {
403
+ type: 'inlineMath',
404
+ value: node.value ?? '',
405
+ ...posField(pos),
406
+ };
407
+ case 'footnoteReference':
408
+ return {
409
+ type: 'footnoteReference',
410
+ identifier: node.identifier ?? '',
411
+ ...(node.label != null ? { label: node.label } : {}),
412
+ ...posField(pos),
413
+ };
414
+ case 'linkReference':
415
+ return {
416
+ type: 'linkReference',
417
+ identifier: node.identifier ?? '',
418
+ ...(node.label != null ? { label: node.label } : {}),
419
+ referenceType: (node.referenceType ?? 'full'),
420
+ children: convertInlineChildren(node.children ?? [], parseHtml),
421
+ ...posField(pos),
422
+ };
423
+ case 'imageReference':
424
+ return {
425
+ type: 'imageReference',
426
+ identifier: node.identifier ?? '',
427
+ ...(node.label != null ? { label: node.label } : {}),
428
+ referenceType: (node.referenceType ?? 'full'),
429
+ ...(node.alt != null ? { alt: node.alt } : {}),
430
+ ...posField(pos),
431
+ };
432
+ case 'textDirective':
433
+ return {
434
+ type: 'textDirective',
435
+ name: node.name ?? '',
436
+ ...(node.attributes && Object.keys(node.attributes).length > 0
437
+ ? { attributes: node.attributes }
438
+ : {}),
439
+ children: convertInlineChildren(node.children ?? [], parseHtml),
440
+ ...posField(pos),
441
+ };
442
+ default:
443
+ if (typeof console !== 'undefined') {
444
+ console.warn(`[squisq/markdown] Unknown mdast inline node type: "${node.type}"`);
445
+ }
446
+ return null;
447
+ }
448
+ }
449
+ // ============================================
450
+ // Squisq → mdast (toMdast)
451
+ // ============================================
452
+ /**
453
+ * Convert a MarkdownDocument back to an mdast Root node.
454
+ *
455
+ * @param doc - A MarkdownDocument
456
+ * @returns An mdast Root node suitable for remark-stringify
457
+ */
458
+ export function toMdast(doc) {
459
+ return {
460
+ type: 'root',
461
+ children: doc.children.map((n) => blockToMdast(n)),
462
+ ...mdastPosField(doc.position),
463
+ };
464
+ }
465
+ function blockToMdast(node) {
466
+ switch (node.type) {
467
+ case 'heading': {
468
+ const mdastChildren = node.children.map(inlineToMdast);
469
+ if (node.templateAnnotation) {
470
+ const suffix = serializeTemplateAnnotation(node.templateAnnotation);
471
+ // Append to last text node, or create a new one
472
+ const lastChild = mdastChildren[mdastChildren.length - 1];
473
+ if (lastChild && lastChild.type === 'text') {
474
+ lastChild.value = (lastChild.value ?? '') + ' ' + suffix;
475
+ }
476
+ else {
477
+ mdastChildren.push({ type: 'text', value: ' ' + suffix });
478
+ }
479
+ }
480
+ return {
481
+ type: 'heading',
482
+ depth: node.depth,
483
+ children: mdastChildren,
484
+ ...mdastPosField(node.position),
485
+ };
486
+ }
487
+ case 'paragraph':
488
+ return {
489
+ type: 'paragraph',
490
+ children: node.children.map(inlineToMdast),
491
+ ...mdastPosField(node.position),
492
+ };
493
+ case 'blockquote':
494
+ return {
495
+ type: 'blockquote',
496
+ children: node.children.map(blockToMdast),
497
+ ...mdastPosField(node.position),
498
+ };
499
+ case 'list':
500
+ return {
501
+ type: 'list',
502
+ ordered: node.ordered,
503
+ ...(node.start != null ? { start: node.start } : {}),
504
+ ...(node.spread != null ? { spread: node.spread } : {}),
505
+ children: node.children.map(listItemToMdast),
506
+ ...mdastPosField(node.position),
507
+ };
508
+ case 'code':
509
+ return {
510
+ type: 'code',
511
+ ...(node.lang != null ? { lang: node.lang } : {}),
512
+ ...(node.meta != null ? { meta: node.meta } : {}),
513
+ value: node.value,
514
+ ...mdastPosField(node.position),
515
+ };
516
+ case 'thematicBreak':
517
+ return {
518
+ type: 'thematicBreak',
519
+ ...mdastPosField(node.position),
520
+ };
521
+ case 'table':
522
+ return {
523
+ type: 'table',
524
+ ...(node.align ? { align: node.align } : {}),
525
+ children: node.children.map(tableRowToMdast),
526
+ ...mdastPosField(node.position),
527
+ };
528
+ case 'htmlBlock':
529
+ return {
530
+ type: 'html',
531
+ value: node.rawHtml,
532
+ ...mdastPosField(node.position),
533
+ };
534
+ case 'math':
535
+ return {
536
+ type: 'math',
537
+ value: node.value,
538
+ ...(node.meta != null ? { meta: node.meta } : {}),
539
+ ...mdastPosField(node.position),
540
+ };
541
+ case 'definition':
542
+ return {
543
+ type: 'definition',
544
+ identifier: node.identifier,
545
+ ...(node.label != null ? { label: node.label } : {}),
546
+ url: node.url,
547
+ ...(node.title != null ? { title: node.title } : {}),
548
+ ...mdastPosField(node.position),
549
+ };
550
+ case 'footnoteDefinition':
551
+ return {
552
+ type: 'footnoteDefinition',
553
+ identifier: node.identifier,
554
+ ...(node.label != null ? { label: node.label } : {}),
555
+ children: node.children.map(blockToMdast),
556
+ ...mdastPosField(node.position),
557
+ };
558
+ case 'containerDirective': {
559
+ const children = [];
560
+ // Reinject label as first paragraph with directiveLabel flag
561
+ if (node.label) {
562
+ children.push({
563
+ type: 'paragraph',
564
+ data: { directiveLabel: true },
565
+ children: [{ type: 'text', value: node.label }],
566
+ });
567
+ }
568
+ children.push(...node.children.map(blockToMdast));
569
+ return {
570
+ type: 'containerDirective',
571
+ name: node.name,
572
+ ...(node.attributes ? { attributes: node.attributes } : {}),
573
+ children,
574
+ ...mdastPosField(node.position),
575
+ };
576
+ }
577
+ case 'leafDirective':
578
+ return {
579
+ type: 'leafDirective',
580
+ name: node.name,
581
+ ...(node.attributes ? { attributes: node.attributes } : {}),
582
+ children: node.children.map(inlineToMdast),
583
+ ...mdastPosField(node.position),
584
+ };
585
+ case 'definitionList':
586
+ // Definition lists don't map to standard mdast.
587
+ // Convert to HTML as fallback.
588
+ return {
589
+ type: 'html',
590
+ value: definitionListToHtml(node),
591
+ ...mdastPosField(node.position),
592
+ };
593
+ default:
594
+ return { type: 'html', value: '' };
595
+ }
596
+ }
597
+ function listItemToMdast(item) {
598
+ return {
599
+ type: 'listItem',
600
+ ...(item.checked != null ? { checked: item.checked } : {}),
601
+ ...(item.spread != null ? { spread: item.spread } : {}),
602
+ children: item.children.map(blockToMdast),
603
+ ...mdastPosField(item.position),
604
+ };
605
+ }
606
+ function tableRowToMdast(row) {
607
+ return {
608
+ type: 'tableRow',
609
+ children: row.children.map(tableCellToMdast),
610
+ ...mdastPosField(row.position),
611
+ };
612
+ }
613
+ function tableCellToMdast(cell) {
614
+ return {
615
+ type: 'tableCell',
616
+ children: cell.children.map(inlineToMdast),
617
+ ...mdastPosField(cell.position),
618
+ };
619
+ }
620
+ function inlineToMdast(node) {
621
+ switch (node.type) {
622
+ case 'text':
623
+ return {
624
+ type: 'text',
625
+ value: node.value,
626
+ ...mdastPosField(node.position),
627
+ };
628
+ case 'emphasis':
629
+ return {
630
+ type: 'emphasis',
631
+ children: node.children.map(inlineToMdast),
632
+ ...mdastPosField(node.position),
633
+ };
634
+ case 'strong':
635
+ return {
636
+ type: 'strong',
637
+ children: node.children.map(inlineToMdast),
638
+ ...mdastPosField(node.position),
639
+ };
640
+ case 'delete':
641
+ return {
642
+ type: 'delete',
643
+ children: node.children.map(inlineToMdast),
644
+ ...mdastPosField(node.position),
645
+ };
646
+ case 'inlineCode':
647
+ return {
648
+ type: 'inlineCode',
649
+ value: node.value,
650
+ ...mdastPosField(node.position),
651
+ };
652
+ case 'link':
653
+ return {
654
+ type: 'link',
655
+ url: node.url,
656
+ ...(node.title != null ? { title: node.title } : {}),
657
+ children: node.children.map(inlineToMdast),
658
+ ...mdastPosField(node.position),
659
+ };
660
+ case 'image':
661
+ return {
662
+ type: 'image',
663
+ url: node.url,
664
+ ...(node.alt != null ? { alt: node.alt } : {}),
665
+ ...(node.title != null ? { title: node.title } : {}),
666
+ ...mdastPosField(node.position),
667
+ };
668
+ case 'break':
669
+ return {
670
+ type: 'break',
671
+ ...mdastPosField(node.position),
672
+ };
673
+ case 'htmlInline':
674
+ return {
675
+ type: 'html',
676
+ value: node.rawHtml,
677
+ ...mdastPosField(node.position),
678
+ };
679
+ case 'inlineMath':
680
+ return {
681
+ type: 'inlineMath',
682
+ value: node.value,
683
+ ...mdastPosField(node.position),
684
+ };
685
+ case 'footnoteReference':
686
+ return {
687
+ type: 'footnoteReference',
688
+ identifier: node.identifier,
689
+ ...(node.label != null ? { label: node.label } : {}),
690
+ ...mdastPosField(node.position),
691
+ };
692
+ case 'linkReference':
693
+ return {
694
+ type: 'linkReference',
695
+ identifier: node.identifier,
696
+ ...(node.label != null ? { label: node.label } : {}),
697
+ referenceType: node.referenceType,
698
+ children: node.children.map(inlineToMdast),
699
+ ...mdastPosField(node.position),
700
+ };
701
+ case 'imageReference':
702
+ return {
703
+ type: 'imageReference',
704
+ identifier: node.identifier,
705
+ ...(node.label != null ? { label: node.label } : {}),
706
+ referenceType: node.referenceType,
707
+ ...(node.alt != null ? { alt: node.alt } : {}),
708
+ ...mdastPosField(node.position),
709
+ };
710
+ case 'textDirective':
711
+ return {
712
+ type: 'textDirective',
713
+ name: node.name,
714
+ ...(node.attributes ? { attributes: node.attributes } : {}),
715
+ children: node.children.map(inlineToMdast),
716
+ ...mdastPosField(node.position),
717
+ };
718
+ default:
719
+ return { type: 'text', value: '' };
720
+ }
721
+ }
722
+ // ============================================
723
+ // Helpers
724
+ // ============================================
725
+ /**
726
+ * Convert a MarkdownDefinitionList to an HTML <dl> string.
727
+ * Fallback for serialization since mdast doesn't support definition lists.
728
+ */
729
+ function definitionListToHtml(list) {
730
+ let html = '<dl>\n';
731
+ for (const child of list.children) {
732
+ if (child.type === 'definitionTerm') {
733
+ // Extract plain text from inline children
734
+ const text = child.children
735
+ .map((c) => c.value ?? '')
736
+ .join('');
737
+ html += ` <dt>${text}</dt>\n`;
738
+ }
739
+ else if (child.type === 'definitionDescription') {
740
+ html += ` <dd>...</dd>\n`;
741
+ }
742
+ }
743
+ html += '</dl>';
744
+ return html;
745
+ }
746
+ //# sourceMappingURL=convert.js.map