@bendyline/squisq 1.4.1 → 1.5.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 (254) hide show
  1. package/README.md +14 -1
  2. package/dist/{ContentContainer-DNx460y8.d.ts → ContentContainer-BXUlIf18.d.ts} +6 -2
  3. package/dist/{Doc-BeSeH2iX.d.ts → Doc-BBVGq1_9.d.ts} +922 -273
  4. package/dist/{ImageEditDoc-BTIvw0oq.d.ts → ImageEditDoc-FuyGtt6o.d.ts} +11 -4
  5. package/dist/{chunk-ZTX4PFFT.js → chunk-2OIBZYKP.js} +75 -2
  6. package/dist/chunk-2OIBZYKP.js.map +1 -0
  7. package/dist/chunk-2UQOHYE2.js +45 -0
  8. package/dist/chunk-2UQOHYE2.js.map +1 -0
  9. package/dist/chunk-6ATE2PSM.js +344 -0
  10. package/dist/chunk-6ATE2PSM.js.map +1 -0
  11. package/dist/{chunk-57CVQCFX.js → chunk-A4O7GIWE.js} +74 -23
  12. package/dist/chunk-A4O7GIWE.js.map +1 -0
  13. package/dist/{chunk-5WFRKURX.js → chunk-DLXZMS5K.js} +4 -2
  14. package/dist/chunk-DLXZMS5K.js.map +1 -0
  15. package/dist/chunk-ET53IIEP.js +1 -0
  16. package/dist/chunk-ET53IIEP.js.map +1 -0
  17. package/dist/chunk-HWVFJAAH.js +362 -0
  18. package/dist/chunk-HWVFJAAH.js.map +1 -0
  19. package/dist/{chunk-2TMAWB4Y.js → chunk-IMSCRLLV.js} +1 -1
  20. package/dist/chunk-IMSCRLLV.js.map +1 -0
  21. package/dist/{chunk-B4EEON3N.js → chunk-KKNUBQ6Y.js} +536 -103
  22. package/dist/chunk-KKNUBQ6Y.js.map +1 -0
  23. package/dist/chunk-LDQ2HJIX.js +596 -0
  24. package/dist/chunk-LDQ2HJIX.js.map +1 -0
  25. package/dist/chunk-LH7I6SH7.js +7208 -0
  26. package/dist/chunk-LH7I6SH7.js.map +1 -0
  27. package/dist/chunk-PGGGKYWG.js +1 -0
  28. package/dist/chunk-PGGGKYWG.js.map +1 -0
  29. package/dist/{chunk-7UDSRZKG.js → chunk-Q3ROPT5H.js} +35 -14
  30. package/dist/chunk-Q3ROPT5H.js.map +1 -0
  31. package/dist/chunk-QE7TWGVT.js +178 -0
  32. package/dist/chunk-QE7TWGVT.js.map +1 -0
  33. package/dist/chunk-RUDYOTA6.js +345 -0
  34. package/dist/chunk-RUDYOTA6.js.map +1 -0
  35. package/dist/{chunk-K32VJONL.js → chunk-T5UK6YOB.js} +41 -2
  36. package/dist/chunk-T5UK6YOB.js.map +1 -0
  37. package/dist/{chunk-3K5OG6KI.js → chunk-TEEEILMP.js} +412 -186
  38. package/dist/chunk-TEEEILMP.js.map +1 -0
  39. package/dist/{chunk-FR2RBTKO.js → chunk-TQWLI6S2.js} +93 -27
  40. package/dist/chunk-TQWLI6S2.js.map +1 -0
  41. package/dist/{chunk-WMOI7FN3.js → chunk-UY7KGQ5R.js} +12 -2
  42. package/dist/{chunk-WMOI7FN3.js.map → chunk-UY7KGQ5R.js.map} +1 -1
  43. package/dist/{chunk-3E5F2XMR.js → chunk-VWUFZ6ZG.js} +29 -2
  44. package/dist/chunk-VWUFZ6ZG.js.map +1 -0
  45. package/dist/chunk-ZLQKNOZQ.js +1 -0
  46. package/dist/chunk-ZLQKNOZQ.js.map +1 -0
  47. package/dist/doc/index.d.ts +5 -5
  48. package/dist/doc/index.js +135 -8
  49. package/dist/generate/index.d.ts +3 -74
  50. package/dist/generate/index.js +2 -7
  51. package/dist/icons/index.d.ts +3 -26
  52. package/dist/icons/index.js +13 -0
  53. package/dist/icons/inlineIconMarker.d.ts +1 -0
  54. package/dist/icons/inlineIconMarker.js +15 -0
  55. package/dist/icons/inlineIconMarker.js.map +1 -0
  56. package/dist/imageEdit/index.d.ts +12 -6
  57. package/dist/imageEdit/index.js +4 -1
  58. package/dist/index.d.ts +14 -11
  59. package/dist/index.js +265 -37
  60. package/dist/inlineIconMarker-CiE8Hlvz.d.ts +59 -0
  61. package/dist/jsonForm/index.d.ts +42 -1
  62. package/dist/jsonForm/index.js +9 -1
  63. package/dist/markdown/index.d.ts +228 -3
  64. package/dist/markdown/index.js +42 -7
  65. package/dist/recommend/index.d.ts +1 -1
  66. package/dist/recommend/index.js +3 -2
  67. package/dist/schemas/index.d.ts +28 -8
  68. package/dist/schemas/index.js +36 -8
  69. package/dist/spatial/index.d.ts +9 -4
  70. package/dist/spatial/index.js +1 -1
  71. package/dist/storage/index.d.ts +2 -2
  72. package/dist/storage/index.js +1 -1
  73. package/dist/story/index.d.ts +1021 -41
  74. package/dist/story/index.js +135 -8
  75. package/dist/{themeLibrary-BHjJ0Qx6.d.ts → themeLibrary-CehcJhzz.d.ts} +1 -1
  76. package/dist/timing/index.js +3 -5
  77. package/dist/transform/index.d.ts +48 -10
  78. package/dist/transform/index.js +17 -481
  79. package/dist/transform/index.js.map +1 -1
  80. package/dist/{types-BdZkdJ3z.d.ts → types-DlAZ7MW4.d.ts} +115 -1
  81. package/dist/versions/index.d.ts +1 -1
  82. package/package.json +6 -1
  83. package/src/__tests__/animationUtils.test.ts +40 -0
  84. package/src/__tests__/annotationCoercion.test.ts +243 -0
  85. package/src/__tests__/applyRenderStyle.test.ts +146 -0
  86. package/src/__tests__/atmosphereLayers.test.ts +108 -0
  87. package/src/__tests__/attrTokens.test.ts +162 -0
  88. package/src/__tests__/contentExtractor.test.ts +60 -0
  89. package/src/__tests__/coverBlock.test.ts +46 -1
  90. package/src/__tests__/customTemplateSample.test.ts +144 -0
  91. package/src/__tests__/customTemplatesFrontmatter.test.ts +236 -0
  92. package/src/__tests__/customThemesFrontmatter.test.ts +145 -0
  93. package/src/__tests__/diagramBlock.test.ts +122 -0
  94. package/src/__tests__/diagramLayout.test.ts +134 -0
  95. package/src/__tests__/drawing.test.ts +109 -0
  96. package/src/__tests__/drawingBlock.test.ts +124 -0
  97. package/src/__tests__/drawingLayout.test.ts +171 -0
  98. package/src/__tests__/geohash.test.ts +6 -5
  99. package/src/__tests__/getLayers.test.ts +6 -2
  100. package/src/__tests__/getLayersFallback.test.ts +103 -0
  101. package/src/__tests__/imageEditExportSvg.test.ts +70 -0
  102. package/src/__tests__/imageEditVersions.test.ts +72 -0
  103. package/src/__tests__/inlineIconMarker.test.ts +36 -0
  104. package/src/__tests__/inputDescriptors.test.ts +162 -0
  105. package/src/__tests__/jsonForm.tokens.test.ts +84 -0
  106. package/src/__tests__/layoutBlock.test.ts +83 -0
  107. package/src/__tests__/layoutLayout.test.ts +169 -0
  108. package/src/__tests__/markdown.test.ts +87 -0
  109. package/src/__tests__/markdownSanitize.test.ts +79 -0
  110. package/src/__tests__/markdownToDoc.test.ts +391 -2
  111. package/src/__tests__/mediaAnnotations.test.ts +91 -0
  112. package/src/__tests__/mediaSchedule.test.ts +118 -0
  113. package/src/__tests__/pandocAttrParse.test.ts +187 -0
  114. package/src/__tests__/resolveDocTheme.test.ts +55 -0
  115. package/src/__tests__/rootExports.test.ts +43 -0
  116. package/src/__tests__/shapeGeometry.test.ts +89 -0
  117. package/src/__tests__/shapeVocabulary.test.ts +133 -0
  118. package/src/__tests__/structuredData.test.ts +249 -0
  119. package/src/__tests__/templateAnnotationParse.test.ts +108 -0
  120. package/src/__tests__/templateMetadata.test.ts +31 -0
  121. package/src/__tests__/templates.test.ts +257 -4
  122. package/src/__tests__/themeCompile.test.ts +42 -0
  123. package/src/__tests__/themeValidator.test.ts +6 -0
  124. package/src/__tests__/transformV2.test.ts +137 -0
  125. package/src/__tests__/transitionNormalize.test.ts +61 -0
  126. package/src/__tests__/validateDoc.test.ts +260 -0
  127. package/src/doc/annotationBlocks.ts +117 -0
  128. package/src/doc/customTemplatesFrontmatter.ts +314 -0
  129. package/src/doc/customThemesFrontmatter.ts +95 -0
  130. package/src/doc/docToMarkdown.ts +104 -5
  131. package/src/doc/getLayers.ts +49 -17
  132. package/src/doc/index.ts +47 -1
  133. package/src/doc/markdownToDoc.ts +411 -13
  134. package/src/doc/mediaAnnotations.ts +100 -0
  135. package/src/doc/resolveDocTheme.ts +55 -0
  136. package/src/doc/standaloneAnnotation.ts +58 -0
  137. package/src/doc/structuredData.ts +301 -0
  138. package/src/doc/templateInputs.ts +240 -0
  139. package/src/doc/templates/__tests__/customTemplate.test.ts +170 -0
  140. package/src/doc/templates/__tests__/customTemplateRegistry.test.ts +110 -0
  141. package/src/doc/templates/accentImage.ts +30 -6
  142. package/src/doc/templates/captionUtils.ts +23 -0
  143. package/src/doc/templates/comparisonBar.ts +33 -18
  144. package/src/doc/templates/coverBlock.ts +35 -5
  145. package/src/doc/templates/customTemplate.ts +51 -0
  146. package/src/doc/templates/dataTable.ts +37 -19
  147. package/src/doc/templates/dateEvent.ts +41 -20
  148. package/src/doc/templates/definitionCard.ts +26 -18
  149. package/src/doc/templates/diagramBlock.ts +204 -0
  150. package/src/doc/templates/diagramLayout.ts +159 -0
  151. package/src/doc/templates/drawingBlock.ts +325 -0
  152. package/src/doc/templates/drawingLayout.ts +539 -0
  153. package/src/doc/templates/factCard.ts +54 -26
  154. package/src/doc/templates/fallbackBlock.ts +123 -0
  155. package/src/doc/templates/featureBlock.ts +20 -13
  156. package/src/doc/templates/fullBleedQuote.ts +18 -8
  157. package/src/doc/templates/imageWithCaption.ts +30 -15
  158. package/src/doc/templates/index.ts +225 -46
  159. package/src/doc/templates/inputDescriptors.ts +432 -0
  160. package/src/doc/templates/layoutBlock.ts +43 -0
  161. package/src/doc/templates/layoutLayout.ts +243 -0
  162. package/src/doc/templates/listBlock.ts +56 -30
  163. package/src/doc/templates/mapBlock.ts +15 -12
  164. package/src/doc/templates/metadata.ts +120 -0
  165. package/src/doc/templates/persistentLayers.ts +129 -11
  166. package/src/doc/templates/photoGrid.ts +22 -34
  167. package/src/doc/templates/pullQuote.ts +30 -12
  168. package/src/doc/templates/quoteBlock.ts +54 -29
  169. package/src/doc/templates/sectionHeader.ts +25 -11
  170. package/src/doc/templates/statHighlight.ts +39 -22
  171. package/src/doc/templates/titleBlock.ts +59 -21
  172. package/src/doc/templates/tokens/__tests__/resolveTokens.test.ts +487 -0
  173. package/src/doc/templates/tokens/resolveTokens.ts +453 -0
  174. package/src/doc/templates/twoColumn.ts +48 -30
  175. package/src/doc/templates/videoPullQuote.ts +22 -12
  176. package/src/doc/templates/videoWithCaption.ts +21 -15
  177. package/src/doc/utils/animationUtils.ts +267 -3
  178. package/src/doc/utils/applyRenderStyle.ts +113 -0
  179. package/src/doc/utils/imageTreatment.ts +70 -0
  180. package/src/doc/utils/nearest.ts +59 -0
  181. package/src/doc/utils/shapeGeometry.ts +464 -0
  182. package/src/doc/utils/themeUtils.ts +75 -1
  183. package/src/doc/validate.ts +575 -0
  184. package/src/generate/contentExtractor.ts +148 -35
  185. package/src/generate/index.ts +0 -3
  186. package/src/icons/index.ts +8 -0
  187. package/src/icons/inlineIconMarker.ts +73 -0
  188. package/src/imageEdit/export.ts +85 -2
  189. package/src/imageEdit/index.ts +1 -0
  190. package/src/imageEdit/persistence.ts +51 -0
  191. package/src/index.ts +2 -0
  192. package/src/jsonForm/index.ts +2 -0
  193. package/src/jsonForm/tokens.ts +78 -0
  194. package/src/markdown/annotationCoercion.ts +295 -0
  195. package/src/markdown/attrTokens.ts +241 -0
  196. package/src/markdown/convert.ts +229 -26
  197. package/src/markdown/index.ts +37 -0
  198. package/src/markdown/sanitize.ts +318 -0
  199. package/src/markdown/stringify.ts +96 -6
  200. package/src/markdown/types.ts +66 -0
  201. package/src/markdown/utils.ts +111 -2
  202. package/src/recommend/templates.ts +24 -0
  203. package/src/schemas/BlockTemplates.ts +133 -4
  204. package/src/schemas/CustomTemplates.ts +126 -0
  205. package/src/schemas/Doc.ts +387 -65
  206. package/src/schemas/ImageEditDoc.ts +11 -4
  207. package/src/schemas/Media.ts +169 -0
  208. package/src/schemas/Theme.ts +23 -1
  209. package/src/schemas/Transitions.ts +224 -0
  210. package/src/schemas/colorUtils.ts +33 -0
  211. package/src/schemas/fontStacks.ts +5 -2
  212. package/src/schemas/index.ts +3 -0
  213. package/src/schemas/themeCompile.ts +24 -5
  214. package/src/schemas/themeValidator.ts +49 -11
  215. package/src/schemas/themes/cinematic.json +69 -12
  216. package/src/schemas/themes/documentary.json +58 -11
  217. package/src/schemas/themes/gezellig.json +60 -11
  218. package/src/schemas/themes/magazine.json +54 -9
  219. package/src/schemas/themes/morning-light.json +52 -9
  220. package/src/schemas/themes/standard-dark.json +48 -13
  221. package/src/schemas/themes/standard.json +44 -12
  222. package/src/schemas/themes/tech-dark.json +65 -12
  223. package/src/spatial/Geohash.ts +52 -21
  224. package/src/storage/ContentContainer.ts +6 -2
  225. package/src/transform/applyTransform.ts +43 -4
  226. package/src/transform/index.ts +1 -0
  227. package/src/transform/registry.ts +44 -13
  228. package/src/transform/styles/dataDriven.ts +2 -1
  229. package/src/transform/styles/documentary.ts +2 -1
  230. package/src/transform/styles/magazine.ts +3 -1
  231. package/src/transform/styles/minimal.ts +2 -1
  232. package/src/transform/styles/narrative.ts +3 -1
  233. package/src/transform/templateSelector.ts +87 -11
  234. package/src/transform/types.ts +35 -2
  235. package/dist/chunk-2TMAWB4Y.js.map +0 -1
  236. package/dist/chunk-3E5F2XMR.js.map +0 -1
  237. package/dist/chunk-3K5OG6KI.js.map +0 -1
  238. package/dist/chunk-4X3JQXNM.js +0 -35
  239. package/dist/chunk-4X3JQXNM.js.map +0 -1
  240. package/dist/chunk-57CVQCFX.js.map +0 -1
  241. package/dist/chunk-5WFRKURX.js.map +0 -1
  242. package/dist/chunk-7UDSRZKG.js.map +0 -1
  243. package/dist/chunk-B4EEON3N.js.map +0 -1
  244. package/dist/chunk-FR2RBTKO.js.map +0 -1
  245. package/dist/chunk-H3AXU4MJ.js +0 -179
  246. package/dist/chunk-H3AXU4MJ.js.map +0 -1
  247. package/dist/chunk-K32VJONL.js.map +0 -1
  248. package/dist/chunk-KSWJR66U.js +0 -3706
  249. package/dist/chunk-KSWJR66U.js.map +0 -1
  250. package/dist/chunk-MYIH7FWD.js +0 -145
  251. package/dist/chunk-MYIH7FWD.js.map +0 -1
  252. package/dist/chunk-ZTX4PFFT.js.map +0 -1
  253. package/src/__tests__/slideshowGenerator.test.ts +0 -128
  254. package/src/generate/slideshowGenerator.ts +0 -273
@@ -1,134 +1,284 @@
1
+ import {
2
+ parseFrontmatter,
3
+ parseHtmlToNodes
4
+ } from "./chunk-HWVFJAAH.js";
1
5
  import {
2
6
  resolveIcon
3
7
  } from "./chunk-DBS6RIFL.js";
4
8
  import {
5
- parseFrontmatter
6
- } from "./chunk-H3AXU4MJ.js";
9
+ TRANSITION_DIRECTIONS,
10
+ TRANSITION_TYPES,
11
+ normalizeTransitionDirection,
12
+ normalizeTransitionType
13
+ } from "./chunk-QE7TWGVT.js";
7
14
 
8
- // src/markdown/parse.ts
9
- import { unified } from "unified";
10
- import remarkParse from "remark-parse";
11
- import remarkGfm from "remark-gfm";
12
- import remarkMath from "remark-math";
13
- import remarkDirective from "remark-directive";
14
- import remarkFrontmatter from "remark-frontmatter";
15
-
16
- // src/markdown/htmlParse.ts
17
- import { fromHtml } from "hast-util-from-html";
18
- var HAST_PROP_TO_ATTR = {
19
- className: "class",
20
- htmlFor: "for",
21
- httpEquiv: "http-equiv",
22
- acceptCharset: "accept-charset"
15
+ // src/markdown/annotationCoercion.ts
16
+ var KNOWN_BLOCK_META_KEYS = {
17
+ x: "number",
18
+ y: "number",
19
+ startTime: "time",
20
+ duration: "time",
21
+ connectsTo: "connectionList",
22
+ transition: "transition",
23
+ transitionDuration: "time",
24
+ transitionDirection: "transitionDirection"
23
25
  };
24
- var VOID_ELEMENTS = /* @__PURE__ */ new Set([
25
- "area",
26
- "base",
27
- "br",
28
- "col",
29
- "embed",
30
- "hr",
31
- "img",
32
- "input",
33
- "link",
34
- "meta",
35
- "param",
36
- "source",
37
- "track",
38
- "wbr"
39
- ]);
40
- function propertyToAttribute(prop) {
41
- if (HAST_PROP_TO_ATTR[prop]) return HAST_PROP_TO_ATTR[prop];
42
- if (prop.length > 4 && prop.startsWith("data") && prop[4] >= "A" && prop[4] <= "Z") {
43
- return "data-" + prop.slice(4).replace(/[A-Z]/g, (m) => "-" + m.toLowerCase()).replace(/^-/, "");
26
+ var BLOCK_META_KEY_DESCRIPTORS = [
27
+ {
28
+ key: "transition",
29
+ description: "Block-to-block transition effect",
30
+ values: TRANSITION_TYPES
31
+ },
32
+ {
33
+ key: "transitionDuration",
34
+ description: "How long the transition lasts",
35
+ valueHint: "seconds \u2014 e.g. 0.7, 700ms"
36
+ },
37
+ {
38
+ key: "transitionDirection",
39
+ description: "Directional variant for the transition",
40
+ values: TRANSITION_DIRECTIONS
41
+ },
42
+ {
43
+ key: "startTime",
44
+ description: "Timeline start time of this block",
45
+ valueHint: "mm:ss or seconds \u2014 e.g. 01:30, 5, 1500ms"
46
+ },
47
+ {
48
+ key: "duration",
49
+ description: "How long this block lasts",
50
+ valueHint: "mm:ss or seconds \u2014 e.g. 45, 1500ms"
51
+ },
52
+ {
53
+ key: "x",
54
+ description: "Horizontal position on the diagram canvas",
55
+ valueHint: "number \u2014 e.g. 600"
56
+ },
57
+ {
58
+ key: "y",
59
+ description: "Vertical position on the diagram canvas",
60
+ valueHint: "number \u2014 e.g. 300"
61
+ },
62
+ {
63
+ key: "connectsTo",
64
+ description: "Diagram connections to other blocks",
65
+ valueHint: "comma-separated target or target:type \u2014 e.g. foo,bar:flow"
66
+ }
67
+ ];
68
+ function coerceAnnotationValues(params) {
69
+ const blockMeta = {};
70
+ const metadata = {};
71
+ const warnings = [];
72
+ let transitionType = null;
73
+ let transitionDuration;
74
+ let transitionDirection;
75
+ for (const [key, raw] of Object.entries(params)) {
76
+ const kind = KNOWN_BLOCK_META_KEYS[key];
77
+ if (!kind) {
78
+ metadata[key] = raw;
79
+ continue;
80
+ }
81
+ if (kind === "number") {
82
+ const n = parseNumber(raw);
83
+ if (n == null) {
84
+ warnings.push(`Invalid number for "${key}": ${JSON.stringify(raw)}`);
85
+ } else {
86
+ blockMeta[key] = n;
87
+ }
88
+ } else if (kind === "time") {
89
+ const s = parseTimeSeconds(raw);
90
+ if (s == null) {
91
+ warnings.push(`Invalid time for "${key}": ${JSON.stringify(raw)}`);
92
+ } else if (key === "transitionDuration") {
93
+ transitionDuration = s;
94
+ } else {
95
+ blockMeta[key] = s;
96
+ }
97
+ } else if (kind === "connectionList") {
98
+ const { list, warning } = parseConnectionList(raw);
99
+ if (warning) warnings.push(`"${key}": ${warning}`);
100
+ blockMeta.connectsTo = list;
101
+ } else if (kind === "transition") {
102
+ const transition = normalizeTransitionType(raw);
103
+ if (transition == null) {
104
+ warnings.push(`Invalid transition for "${key}": ${JSON.stringify(raw)}`);
105
+ } else {
106
+ transitionType = transition;
107
+ }
108
+ } else if (kind === "transitionDirection") {
109
+ const direction = normalizeTransitionDirection(raw);
110
+ if (direction == null) {
111
+ warnings.push(`Invalid transition direction for "${key}": ${JSON.stringify(raw)}`);
112
+ } else {
113
+ transitionDirection = direction;
114
+ }
115
+ }
44
116
  }
45
- if (prop.length > 4 && prop.startsWith("aria") && prop[4] >= "A" && prop[4] <= "Z") {
46
- return "aria-" + prop.slice(4).replace(/[A-Z]/g, (m) => "-" + m.toLowerCase()).replace(/^-/, "");
117
+ if (transitionType) {
118
+ blockMeta.transition = {
119
+ type: transitionType,
120
+ ...transitionDuration !== void 0 ? { duration: transitionDuration } : {},
121
+ ...transitionDirection !== void 0 ? { direction: transitionDirection } : {}
122
+ };
47
123
  }
48
- return prop.toLowerCase();
124
+ return { blockMeta, metadata, warnings };
49
125
  }
50
- function convertHastProperties(properties) {
51
- const attrs = {};
52
- for (const [key, value] of Object.entries(properties)) {
53
- if (value === false || value === void 0 || value === null) continue;
54
- const attrName = propertyToAttribute(key);
55
- if (value === true) {
56
- attrs[attrName] = "";
57
- } else if (Array.isArray(value)) {
58
- attrs[attrName] = value.join(" ");
59
- } else {
60
- attrs[attrName] = String(value);
126
+ function parseNumber(raw) {
127
+ if (raw.trim() === "") return null;
128
+ const n = Number(raw);
129
+ return Number.isFinite(n) ? n : null;
130
+ }
131
+ var TIME_BARE_RE = /^\d+(?:\.\d+)?$/;
132
+ var TIME_MS_RE = /^(\d+(?:\.\d+)?)ms$/;
133
+ var TIME_MMSS_RE = /^(\d+):(\d{1,2})(?:\.(\d+))?$/;
134
+ function parseTimeSeconds(raw) {
135
+ const trimmed = raw.trim();
136
+ if (!trimmed) return null;
137
+ if (TIME_BARE_RE.test(trimmed)) {
138
+ const n = Number(trimmed);
139
+ return Number.isFinite(n) ? n : null;
140
+ }
141
+ const msMatch = trimmed.match(TIME_MS_RE);
142
+ if (msMatch) {
143
+ const n = Number(msMatch[1]);
144
+ return Number.isFinite(n) ? n / 1e3 : null;
145
+ }
146
+ const mmssMatch = trimmed.match(TIME_MMSS_RE);
147
+ if (mmssMatch) {
148
+ const mins = Number(mmssMatch[1]);
149
+ const secs = Number(mmssMatch[2]);
150
+ const frac = mmssMatch[3] ? Number(`0.${mmssMatch[3]}`) : 0;
151
+ if (!Number.isFinite(mins) || !Number.isFinite(secs) || !Number.isFinite(frac)) {
152
+ return null;
61
153
  }
154
+ if (secs >= 60) return null;
155
+ return mins * 60 + secs + frac;
62
156
  }
63
- return attrs;
157
+ return null;
64
158
  }
65
- function hastChildrenToNodes(children) {
66
- const result = [];
67
- for (const child of children) {
68
- const node = hastNodeToHtmlNode(child);
69
- if (node) result.push(node);
159
+ function parseConnectionList(raw) {
160
+ const trimmed = raw.trim();
161
+ if (!trimmed) return { list: [], warning: null };
162
+ const list = [];
163
+ let droppedEmpty = false;
164
+ for (const part of trimmed.split(",")) {
165
+ const entry = part.trim();
166
+ if (!entry) {
167
+ droppedEmpty = true;
168
+ continue;
169
+ }
170
+ const colonIdx = entry.indexOf(":");
171
+ if (colonIdx < 0) {
172
+ list.push({ target: entry });
173
+ } else {
174
+ const target = entry.slice(0, colonIdx).trim();
175
+ const type = entry.slice(colonIdx + 1).trim();
176
+ if (!target) {
177
+ droppedEmpty = true;
178
+ continue;
179
+ }
180
+ list.push(type ? { target, type } : { target });
181
+ }
70
182
  }
71
- return result;
183
+ return {
184
+ list,
185
+ warning: droppedEmpty ? "dropped empty connection entries" : null
186
+ };
72
187
  }
73
- function hastNodeToHtmlNode(node) {
74
- switch (node.type) {
75
- case "element": {
76
- const tagName = node.tagName;
77
- const properties = node.properties ?? {};
78
- const children = node.children ?? [];
79
- return {
80
- type: "htmlElement",
81
- tagName,
82
- attributes: convertHastProperties(properties),
83
- children: hastChildrenToNodes(children),
84
- selfClosing: VOID_ELEMENTS.has(tagName) && children.length === 0
85
- };
188
+
189
+ // src/markdown/attrTokens.ts
190
+ var DQ_RUN = `"(?:[^"\\\\]|\\\\.)*"`;
191
+ var SQ_RUN = `'(?:[^'\\\\]|\\\\.)*'`;
192
+ var TEMPLATE_STRICT_RE = new RegExp(
193
+ `\\s*\\{\\[((?:[^\\]"']|${DQ_RUN}|${SQ_RUN})+)\\]\\}[\\s\\]}]*$`
194
+ );
195
+ var TEMPLATE_LEGACY_RE = /\s*\{\[([^\]]+)\]\}[\s\]}]*$/;
196
+ var PANDOC_STRICT_RE = new RegExp(`\\s*\\{(?!\\[)((?:[^}"']|${DQ_RUN}|${SQ_RUN})*)\\}\\s*$`);
197
+ var PANDOC_LEGACY_RE = /\s*\{(?!\[)([^}]*)\}\s*$/;
198
+ function matchTrailing(text, strict, legacy) {
199
+ const m = strict.exec(text) ?? legacy.exec(text);
200
+ return m ? { inner: m[1], index: m.index } : null;
201
+ }
202
+ function matchTrailingTemplateAnnotation(text) {
203
+ return matchTrailing(text, TEMPLATE_STRICT_RE, TEMPLATE_LEGACY_RE);
204
+ }
205
+ function matchTrailingPandocAttr(text) {
206
+ return matchTrailing(text, PANDOC_STRICT_RE, PANDOC_LEGACY_RE);
207
+ }
208
+ var WHITESPACE_RE = /\s/;
209
+ function tokenizeAttrTokens(input) {
210
+ const tokens = [];
211
+ let i = 0;
212
+ const n = input.length;
213
+ while (i < n) {
214
+ while (i < n && WHITESPACE_RE.test(input[i])) i++;
215
+ if (i >= n) break;
216
+ let token = "";
217
+ while (i < n && !WHITESPACE_RE.test(input[i])) {
218
+ const ch = input[i];
219
+ const atValueStart = token === "" || token.endsWith("=");
220
+ if ((ch === '"' || ch === "'") && atValueStart) {
221
+ token += ch;
222
+ i++;
223
+ while (i < n && input[i] !== ch) {
224
+ if (input[i] === "\\" && i + 1 < n && (input[i + 1] === ch || input[i + 1] === "\\")) {
225
+ token += input[i] + input[i + 1];
226
+ i += 2;
227
+ } else {
228
+ token += input[i];
229
+ i++;
230
+ }
231
+ }
232
+ if (i < n && input[i] === ch) {
233
+ token += ch;
234
+ i++;
235
+ }
236
+ } else {
237
+ token += ch;
238
+ i++;
239
+ }
86
240
  }
87
- case "text":
88
- return {
89
- type: "htmlText",
90
- value: node.value
91
- };
92
- case "comment":
93
- return {
94
- type: "htmlComment",
95
- value: node.value
96
- };
97
- case "doctype":
98
- return null;
99
- default:
100
- return null;
241
+ if (token) tokens.push(token);
101
242
  }
243
+ return tokens;
102
244
  }
103
- function parseHtmlToNodes(html) {
104
- if (!html || !html.trim()) return [];
105
- try {
106
- const tree = fromHtml(html, { fragment: true });
107
- return hastChildrenToNodes(tree.children);
108
- } catch {
109
- return [{ type: "htmlText", value: html }];
245
+ var DQ_UNESCAPE_RE = /\\([\\"])/g;
246
+ var SQ_UNESCAPE_RE = /\\([\\'])/g;
247
+ function unquoteAttrValue(raw) {
248
+ if (raw.length >= 2) {
249
+ const q = raw[0];
250
+ if ((q === '"' || q === "'") && raw.endsWith(q)) {
251
+ const body = raw.slice(1, -1);
252
+ return body.replace(q === '"' ? DQ_UNESCAPE_RE : SQ_UNESCAPE_RE, "$1");
253
+ }
110
254
  }
255
+ return raw;
111
256
  }
112
- function escapeHtmlAttr(value) {
113
- return value.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
257
+ function splitKeyValueToken(token) {
258
+ const eqIdx = token.indexOf("=");
259
+ if (eqIdx <= 0) return null;
260
+ return { key: token.slice(0, eqIdx), value: unquoteAttrValue(token.slice(eqIdx + 1)) };
114
261
  }
115
- function stringifyNode(node) {
116
- switch (node.type) {
117
- case "htmlElement": {
118
- const attrs = Object.entries(node.attributes).map(([k, v]) => v === "" ? k : `${k}="${escapeHtmlAttr(v)}"`).join(" ");
119
- const open = attrs ? `<${node.tagName} ${attrs}>` : `<${node.tagName}>`;
120
- if (node.selfClosing) return open;
121
- const inner = node.children.map(stringifyNode).join("");
122
- return `${open}${inner}</${node.tagName}>`;
123
- }
124
- case "htmlText":
125
- return node.value;
126
- case "htmlComment":
127
- return `<!--${node.value}-->`;
262
+ var NEEDS_QUOTING_RE = /[\s"'[\]{}]/;
263
+ var DQ_ESCAPE_RE = /[\\"]/g;
264
+ var SQ_ESCAPE_RE = /[\\']/g;
265
+ function needsQuoting(value) {
266
+ return value === "" || NEEDS_QUOTING_RE.test(value);
267
+ }
268
+ function quoteAttrValue(value) {
269
+ if (!needsQuoting(value)) return value;
270
+ if (value.includes('"') && !value.includes("'")) {
271
+ return `'${value.replace(SQ_ESCAPE_RE, (ch) => `\\${ch}`)}'`;
128
272
  }
273
+ return `"${value.replace(DQ_ESCAPE_RE, (ch) => `\\${ch}`)}"`;
129
274
  }
130
- function stringifyHtmlNodes(nodes) {
131
- return nodes.map(stringifyNode).join("");
275
+ function serializeAnnotation(template, params) {
276
+ const parts = [];
277
+ if (template) parts.push(template);
278
+ for (const [key, value] of Object.entries(params ?? {})) {
279
+ parts.push(`${key}=${quoteAttrValue(value)}`);
280
+ }
281
+ return `{[${parts.join(" ")}]}`;
132
282
  }
133
283
 
134
284
  // src/markdown/convert.ts
@@ -174,14 +324,13 @@ function extractText(node) {
174
324
  }
175
325
  return "";
176
326
  }
177
- var TEMPLATE_ANNOTATION_RE = /\s*\{\[([^\]]+)\]\}[\s\]}]*$/;
178
327
  function extractTemplateAnnotation(children) {
179
328
  for (let i = children.length - 1; i >= 0; i--) {
180
329
  const child = children[i];
181
330
  if (child.type === "text") {
182
- const match = child.value.match(TEMPLATE_ANNOTATION_RE);
331
+ const match = matchTrailingTemplateAnnotation(child.value);
183
332
  if (match) {
184
- const inner = match[1].trim();
333
+ const inner = match.inner.trim();
185
334
  const annotation = parseAnnotationTokens(inner);
186
335
  const stripped = child.value.slice(0, match.index).replace(/\s+$/, "");
187
336
  if (stripped) {
@@ -198,15 +347,15 @@ function extractTemplateAnnotation(children) {
198
347
  return null;
199
348
  }
200
349
  function parseAnnotationTokens(inner) {
201
- const tokens = inner.split(/\s+/);
350
+ const tokens = tokenizeAttrTokens(inner);
202
351
  const params = {};
203
- const firstIsParam = tokens[0].indexOf("=") > 0;
204
- const template = firstIsParam ? void 0 : tokens[0];
352
+ const firstIsParam = tokens.length > 0 && tokens[0].indexOf("=") > 0;
353
+ const template = firstIsParam || tokens.length === 0 ? void 0 : tokens[0];
205
354
  const startIdx = firstIsParam ? 0 : 1;
206
355
  for (let i = startIdx; i < tokens.length; i++) {
207
- const eqIdx = tokens[i].indexOf("=");
208
- if (eqIdx > 0) {
209
- params[tokens[i].slice(0, eqIdx)] = tokens[i].slice(eqIdx + 1);
356
+ const kv = splitKeyValueToken(tokens[i]);
357
+ if (kv) {
358
+ params[kv.key] = kv.value;
210
359
  }
211
360
  }
212
361
  const result = {};
@@ -218,6 +367,95 @@ function parseAnnotationTokens(inner) {
218
367
  }
219
368
  return result;
220
369
  }
370
+ function extractPandocAttributes(children) {
371
+ const trail = [];
372
+ for (let i = children.length - 1; i >= 0; i--) {
373
+ const c = children[i];
374
+ if (c.type === "text") {
375
+ trail.unshift({ val: c.value, idx: i, len: c.value.length });
376
+ } else if (c.type === "textDirective") {
377
+ const td = c;
378
+ const isBare = (!td.children || td.children.length === 0) && (!td.attributes || Object.keys(td.attributes).length === 0);
379
+ if (!isBare) break;
380
+ const synthesized = ":" + (td.name ?? "");
381
+ trail.unshift({ val: synthesized, idx: i, len: synthesized.length });
382
+ } else {
383
+ break;
384
+ }
385
+ }
386
+ if (trail.length === 0) return null;
387
+ const joined = trail.map((t) => t.val).join("");
388
+ const match = matchTrailingPandocAttr(joined);
389
+ if (!match) return null;
390
+ const inner = match.inner.trim();
391
+ const attrs = parsePandocAttrTokens(inner);
392
+ const matchStart = match.index;
393
+ let scannedLen = 0;
394
+ for (let ti = 0; ti < trail.length; ti++) {
395
+ const t = trail[ti];
396
+ if (scannedLen + t.len <= matchStart) {
397
+ scannedLen += t.len;
398
+ continue;
399
+ }
400
+ const firstNode = children[t.idx];
401
+ const keepLen = matchStart - scannedLen;
402
+ if (firstNode.type === "text") {
403
+ const trimmed = firstNode.value.slice(0, keepLen).replace(/\s+$/, "");
404
+ if (trimmed) {
405
+ firstNode.value = trimmed;
406
+ children.splice(t.idx + 1);
407
+ } else {
408
+ children.splice(t.idx);
409
+ }
410
+ } else {
411
+ children.splice(t.idx);
412
+ }
413
+ return attrs;
414
+ }
415
+ children.splice(trail[0].idx);
416
+ return attrs;
417
+ }
418
+ function parsePandocAttrTokens(inner) {
419
+ const tokens = tokenizeAttrTokens(inner);
420
+ const attrs = {};
421
+ const params = {};
422
+ const classes = [];
423
+ for (const token of tokens) {
424
+ if (token.startsWith("#") && !token.includes("=")) {
425
+ attrs.id = token.slice(1);
426
+ } else if (token.startsWith(".") && !token.includes("=")) {
427
+ const cls = token.slice(1);
428
+ if (cls) classes.push(cls);
429
+ } else {
430
+ const kv = splitKeyValueToken(token);
431
+ if (kv) {
432
+ params[kv.key] = kv.value;
433
+ }
434
+ }
435
+ }
436
+ if (classes.length > 0) attrs.classes = classes;
437
+ if (Object.keys(params).length > 0) {
438
+ attrs.params = params;
439
+ const { blockMeta, metadata } = coerceAnnotationValues(params);
440
+ if (Object.keys(blockMeta).length > 0) attrs.blockMeta = blockMeta;
441
+ if (Object.keys(metadata).length > 0) attrs.metadata = metadata;
442
+ }
443
+ return attrs;
444
+ }
445
+ function serializePandocAttributes(attrs) {
446
+ const parts = [];
447
+ if (attrs.id) parts.push(`#${attrs.id}`);
448
+ if (attrs.classes) {
449
+ for (const cls of attrs.classes) parts.push(`.${cls}`);
450
+ }
451
+ if (attrs.params) {
452
+ for (const [key, value] of Object.entries(attrs.params)) {
453
+ parts.push(`${key}=${quoteAttrValue(value)}`);
454
+ }
455
+ }
456
+ if (parts.length === 0) return "{}";
457
+ return `{${parts.join(" ")}}`;
458
+ }
221
459
  function serializeTemplateAnnotation(annotation) {
222
460
  const parts = [];
223
461
  if (annotation.template) {
@@ -225,7 +463,7 @@ function serializeTemplateAnnotation(annotation) {
225
463
  }
226
464
  if (annotation.params) {
227
465
  for (const [key, value] of Object.entries(annotation.params)) {
228
- parts.push(`${key}=${value}`);
466
+ parts.push(`${key}=${quoteAttrValue(value)}`);
229
467
  }
230
468
  }
231
469
  return `{[${parts.join(" ")}]}`;
@@ -373,7 +611,26 @@ function convertBlockNode(node, parseHtml) {
373
611
  switch (node.type) {
374
612
  case "heading": {
375
613
  const headingChildren = convertInlineChildren(node.children ?? [], parseHtml, false);
376
- const annotation = extractTemplateAnnotation(headingChildren);
614
+ let annotation = null;
615
+ let attrs = null;
616
+ for (let pass = 0; pass < 4; pass++) {
617
+ let matched = false;
618
+ if (!annotation) {
619
+ const t = extractTemplateAnnotation(headingChildren);
620
+ if (t) {
621
+ annotation = t;
622
+ matched = true;
623
+ }
624
+ }
625
+ if (!attrs) {
626
+ const a = extractPandocAttributes(headingChildren);
627
+ if (a) {
628
+ attrs = a;
629
+ matched = true;
630
+ }
631
+ }
632
+ if (!matched) break;
633
+ }
377
634
  const finalChildren = splitInlineIcons(headingChildren);
378
635
  const result = {
379
636
  type: "heading",
@@ -384,6 +641,9 @@ function convertBlockNode(node, parseHtml) {
384
641
  if (annotation) {
385
642
  result.templateAnnotation = annotation;
386
643
  }
644
+ if (attrs) {
645
+ result.attributes = attrs;
646
+ }
387
647
  return result;
388
648
  }
389
649
  case "paragraph":
@@ -637,8 +897,16 @@ function blockToMdast(node) {
637
897
  switch (node.type) {
638
898
  case "heading": {
639
899
  const mdastChildren = inlineChildrenToMdast(node.children);
900
+ const suffixes = [];
901
+ if (node.attributes) {
902
+ const pandoc = serializePandocAttributes(node.attributes);
903
+ if (pandoc != null) suffixes.push(pandoc);
904
+ }
640
905
  if (node.templateAnnotation) {
641
- const suffix = serializeTemplateAnnotation(node.templateAnnotation);
906
+ suffixes.push(serializeTemplateAnnotation(node.templateAnnotation));
907
+ }
908
+ if (suffixes.length > 0) {
909
+ const suffix = suffixes.join(" ");
642
910
  const lastChild = mdastChildren[mdastChildren.length - 1];
643
911
  if (lastChild && lastChild.type === "text") {
644
912
  lastChild.value = (lastChild.value ?? "") + " " + suffix;
@@ -932,6 +1200,12 @@ function definitionListToHtml(list) {
932
1200
  }
933
1201
 
934
1202
  // src/markdown/parse.ts
1203
+ import { unified } from "unified";
1204
+ import remarkParse from "remark-parse";
1205
+ import remarkGfm from "remark-gfm";
1206
+ import remarkMath from "remark-math";
1207
+ import remarkDirective from "remark-directive";
1208
+ import remarkFrontmatter from "remark-frontmatter";
935
1209
  var defaultProcessor;
936
1210
  function parseMarkdown(markdown, options) {
937
1211
  const useDefaults = !options || options.gfm !== false && options.math !== false && options.directive !== false && options.frontmatter !== false;
@@ -972,72 +1246,24 @@ function parseMarkdown(markdown, options) {
972
1246
  return doc;
973
1247
  }
974
1248
 
975
- // src/markdown/stringify.ts
976
- import { unified as unified2 } from "unified";
977
- import remarkStringify from "remark-stringify";
978
- import remarkGfm2 from "remark-gfm";
979
- import remarkMath2 from "remark-math";
980
- import remarkDirective2 from "remark-directive";
981
- var defaultProcessor2;
982
- function stringifyMarkdown(doc, options) {
983
- const mdastTree = toMdast(doc);
984
- const useDefaults = !options || options.gfm !== false && options.math !== false && options.directive !== false && !options.bullet && !options.bulletOrdered && !options.emphasis && !options.strong && !options.rule && !options.fence && options.setext == null;
985
- let processor;
986
- if (useDefaults) {
987
- if (!defaultProcessor2) {
988
- defaultProcessor2 = unified2().use(remarkGfm2).use(remarkMath2).use(remarkDirective2).use(remarkStringify, {
989
- bullet: "-",
990
- bulletOrdered: ".",
991
- emphasis: "*",
992
- strong: "*",
993
- rule: "-",
994
- fence: "`",
995
- setext: false
996
- });
997
- }
998
- processor = defaultProcessor2;
999
- } else {
1000
- processor = unified2();
1001
- if (options?.gfm !== false) {
1002
- processor = processor.use(remarkGfm2);
1003
- }
1004
- if (options?.math !== false) {
1005
- processor = processor.use(remarkMath2);
1006
- }
1007
- if (options?.directive !== false) {
1008
- processor = processor.use(remarkDirective2);
1009
- }
1010
- processor = processor.use(remarkStringify, {
1011
- bullet: options?.bullet ?? "-",
1012
- bulletOrdered: options?.bulletOrdered ?? ".",
1013
- emphasis: options?.emphasis ?? "*",
1014
- strong: options?.strong ?? "*",
1015
- rule: options?.rule ?? "-",
1016
- fence: options?.fence ?? "`",
1017
- setext: options?.setext ?? false
1018
- });
1019
- }
1020
- const result = processor.stringify(mdastTree);
1021
- const cleaned = result.replace(/\{\\\[([^\]]+)\]\}/g, "{[$1]}");
1022
- if (doc.frontmatter && Object.keys(doc.frontmatter).length > 0) {
1023
- const yamlLines = Object.entries(doc.frontmatter).map(
1024
- ([k, v]) => `${k}: ${typeof v === "string" ? v : JSON.stringify(v)}`
1025
- );
1026
- return `---
1027
- ${yamlLines.join("\n")}
1028
- ---
1029
-
1030
- ${cleaned}`;
1031
- }
1032
- return cleaned;
1033
- }
1034
-
1035
1249
  export {
1036
- parseHtmlToNodes,
1037
- stringifyHtmlNodes,
1250
+ KNOWN_BLOCK_META_KEYS,
1251
+ BLOCK_META_KEY_DESCRIPTORS,
1252
+ coerceAnnotationValues,
1253
+ parseNumber,
1254
+ parseTimeSeconds,
1255
+ matchTrailingTemplateAnnotation,
1256
+ matchTrailingPandocAttr,
1257
+ tokenizeAttrTokens,
1258
+ unquoteAttrValue,
1259
+ splitKeyValueToken,
1260
+ needsQuoting,
1261
+ quoteAttrValue,
1262
+ serializeAnnotation,
1263
+ parsePandocAttrTokens,
1264
+ serializePandocAttributes,
1038
1265
  fromMdast,
1039
1266
  toMdast,
1040
- parseMarkdown,
1041
- stringifyMarkdown
1267
+ parseMarkdown
1042
1268
  };
1043
- //# sourceMappingURL=chunk-3K5OG6KI.js.map
1269
+ //# sourceMappingURL=chunk-TEEEILMP.js.map