@refrakt-md/runes 0.7.2 → 0.8.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 (193) hide show
  1. package/dist/config.d.ts.map +1 -1
  2. package/dist/config.js +81 -24
  3. package/dist/config.js.map +1 -1
  4. package/dist/documents/page.js +3 -3
  5. package/dist/documents/page.js.map +1 -1
  6. package/dist/examples.d.ts.map +1 -1
  7. package/dist/examples.js +5 -1
  8. package/dist/examples.js.map +1 -1
  9. package/dist/index.d.ts +11 -3
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +36 -3
  12. package/dist/index.js.map +1 -1
  13. package/dist/lib/annotations/annotation.d.ts +1 -1
  14. package/dist/lib/annotations/annotation.d.ts.map +1 -1
  15. package/dist/lib/annotations/annotation.js +20 -2
  16. package/dist/lib/annotations/annotation.js.map +1 -1
  17. package/dist/lib/component.d.ts +10 -2
  18. package/dist/lib/component.d.ts.map +1 -1
  19. package/dist/lib/component.js +16 -3
  20. package/dist/lib/component.js.map +1 -1
  21. package/dist/lib/index.d.ts +40 -2
  22. package/dist/lib/index.d.ts.map +1 -1
  23. package/dist/lib/index.js +302 -3
  24. package/dist/lib/index.js.map +1 -1
  25. package/dist/lib/model.d.ts +4 -0
  26. package/dist/lib/model.d.ts.map +1 -1
  27. package/dist/lib/model.js +17 -0
  28. package/dist/lib/model.js.map +1 -1
  29. package/dist/lib/renderable.d.ts.map +1 -1
  30. package/dist/lib/renderable.js +2 -1
  31. package/dist/lib/renderable.js.map +1 -1
  32. package/dist/lib/resolver.d.ts +73 -0
  33. package/dist/lib/resolver.d.ts.map +1 -0
  34. package/dist/lib/resolver.js +500 -0
  35. package/dist/lib/resolver.js.map +1 -0
  36. package/dist/nodes.js +2 -2
  37. package/dist/nodes.js.map +1 -1
  38. package/dist/packages.d.ts +2 -0
  39. package/dist/packages.d.ts.map +1 -1
  40. package/dist/packages.js +7 -0
  41. package/dist/packages.js.map +1 -1
  42. package/dist/registry.d.ts +8 -0
  43. package/dist/registry.d.ts.map +1 -1
  44. package/dist/registry.js +16 -8
  45. package/dist/registry.js.map +1 -1
  46. package/dist/schema/annotate.d.ts +1 -1
  47. package/dist/schema/annotate.d.ts.map +1 -1
  48. package/dist/schema/annotate.js +1 -1
  49. package/dist/schema/annotate.js.map +1 -1
  50. package/dist/schema/bg.d.ts +11 -0
  51. package/dist/schema/bg.d.ts.map +1 -0
  52. package/dist/schema/bg.js +13 -0
  53. package/dist/schema/bg.js.map +1 -0
  54. package/dist/schema/budget.d.ts +1 -1
  55. package/dist/schema/budget.d.ts.map +1 -1
  56. package/dist/schema/budget.js +1 -1
  57. package/dist/schema/budget.js.map +1 -1
  58. package/dist/schema/form.d.ts +1 -1
  59. package/dist/schema/form.d.ts.map +1 -1
  60. package/dist/schema/form.js +1 -1
  61. package/dist/schema/form.js.map +1 -1
  62. package/dist/schema/gallery.d.ts +8 -0
  63. package/dist/schema/gallery.d.ts.map +1 -0
  64. package/dist/schema/gallery.js +10 -0
  65. package/dist/schema/gallery.js.map +1 -0
  66. package/dist/schema/pullquote.d.ts +1 -1
  67. package/dist/schema/pullquote.d.ts.map +1 -1
  68. package/dist/schema/pullquote.js +1 -1
  69. package/dist/schema/pullquote.js.map +1 -1
  70. package/dist/schema/showcase.d.ts +8 -0
  71. package/dist/schema/showcase.d.ts.map +1 -0
  72. package/dist/schema/showcase.js +10 -0
  73. package/dist/schema/showcase.js.map +1 -0
  74. package/dist/schema/sidenote.d.ts +1 -1
  75. package/dist/schema/sidenote.d.ts.map +1 -1
  76. package/dist/schema/sidenote.js +1 -1
  77. package/dist/schema/sidenote.js.map +1 -1
  78. package/dist/schema/tint.d.ts +5 -0
  79. package/dist/schema/tint.d.ts.map +1 -0
  80. package/dist/schema/tint.js +7 -0
  81. package/dist/schema/tint.js.map +1 -0
  82. package/dist/seo.d.ts +7 -7
  83. package/dist/seo.d.ts.map +1 -1
  84. package/dist/seo.js +99 -391
  85. package/dist/seo.js.map +1 -1
  86. package/dist/tags/accordion.d.ts.map +1 -1
  87. package/dist/tags/accordion.js +63 -55
  88. package/dist/tags/accordion.js.map +1 -1
  89. package/dist/tags/annotate.d.ts.map +1 -1
  90. package/dist/tags/annotate.js +31 -34
  91. package/dist/tags/annotate.js.map +1 -1
  92. package/dist/tags/bg.d.ts +10 -0
  93. package/dist/tags/bg.d.ts.map +1 -0
  94. package/dist/tags/bg.js +56 -0
  95. package/dist/tags/bg.js.map +1 -0
  96. package/dist/tags/breadcrumb.d.ts.map +1 -1
  97. package/dist/tags/breadcrumb.js +42 -39
  98. package/dist/tags/breadcrumb.js.map +1 -1
  99. package/dist/tags/budget.d.ts.map +1 -1
  100. package/dist/tags/budget.js +69 -96
  101. package/dist/tags/budget.js.map +1 -1
  102. package/dist/tags/chart.d.ts.map +1 -1
  103. package/dist/tags/chart.js +21 -38
  104. package/dist/tags/chart.js.map +1 -1
  105. package/dist/tags/codegroup.d.ts.map +1 -1
  106. package/dist/tags/codegroup.js +32 -34
  107. package/dist/tags/codegroup.js.map +1 -1
  108. package/dist/tags/common.d.ts +9 -0
  109. package/dist/tags/common.d.ts.map +1 -1
  110. package/dist/tags/common.js +32 -0
  111. package/dist/tags/common.js.map +1 -1
  112. package/dist/tags/compare.d.ts.map +1 -1
  113. package/dist/tags/compare.js +21 -31
  114. package/dist/tags/compare.js.map +1 -1
  115. package/dist/tags/conversation.d.ts.map +1 -1
  116. package/dist/tags/conversation.js +58 -62
  117. package/dist/tags/conversation.js.map +1 -1
  118. package/dist/tags/datatable.d.ts.map +1 -1
  119. package/dist/tags/datatable.js +23 -43
  120. package/dist/tags/datatable.js.map +1 -1
  121. package/dist/tags/details.d.ts.map +1 -1
  122. package/dist/tags/details.js +20 -39
  123. package/dist/tags/details.js.map +1 -1
  124. package/dist/tags/diagram.d.ts.map +1 -1
  125. package/dist/tags/diagram.js +22 -38
  126. package/dist/tags/diagram.js.map +1 -1
  127. package/dist/tags/diff.d.ts.map +1 -1
  128. package/dist/tags/diff.js +25 -44
  129. package/dist/tags/diff.js.map +1 -1
  130. package/dist/tags/embed.d.ts.map +1 -1
  131. package/dist/tags/embed.js +30 -43
  132. package/dist/tags/embed.js.map +1 -1
  133. package/dist/tags/error.d.ts.map +1 -1
  134. package/dist/tags/error.js +20 -35
  135. package/dist/tags/error.js.map +1 -1
  136. package/dist/tags/figure.d.ts.map +1 -1
  137. package/dist/tags/figure.js +27 -38
  138. package/dist/tags/figure.js.map +1 -1
  139. package/dist/tags/form.d.ts.map +1 -1
  140. package/dist/tags/form.js +157 -184
  141. package/dist/tags/form.js.map +1 -1
  142. package/dist/tags/gallery.d.ts +3 -0
  143. package/dist/tags/gallery.d.ts.map +1 -0
  144. package/dist/tags/gallery.js +63 -0
  145. package/dist/tags/gallery.js.map +1 -0
  146. package/dist/tags/grid.d.ts +2 -1
  147. package/dist/tags/grid.d.ts.map +1 -1
  148. package/dist/tags/grid.js +73 -45
  149. package/dist/tags/grid.js.map +1 -1
  150. package/dist/tags/hint.d.ts.map +1 -1
  151. package/dist/tags/hint.js +20 -27
  152. package/dist/tags/hint.js.map +1 -1
  153. package/dist/tags/layout.d.ts.map +1 -1
  154. package/dist/tags/layout.js +17 -27
  155. package/dist/tags/layout.js.map +1 -1
  156. package/dist/tags/mediatext.d.ts.map +1 -1
  157. package/dist/tags/mediatext.js +24 -37
  158. package/dist/tags/mediatext.js.map +1 -1
  159. package/dist/tags/nav.d.ts.map +1 -1
  160. package/dist/tags/nav.js +61 -76
  161. package/dist/tags/nav.js.map +1 -1
  162. package/dist/tags/pullquote.d.ts.map +1 -1
  163. package/dist/tags/pullquote.js +22 -34
  164. package/dist/tags/pullquote.js.map +1 -1
  165. package/dist/tags/region.d.ts.map +1 -1
  166. package/dist/tags/region.js +19 -32
  167. package/dist/tags/region.js.map +1 -1
  168. package/dist/tags/reveal.d.ts.map +1 -1
  169. package/dist/tags/reveal.js +35 -55
  170. package/dist/tags/reveal.js.map +1 -1
  171. package/dist/tags/sandbox.js +1 -1
  172. package/dist/tags/sandbox.js.map +1 -1
  173. package/dist/tags/showcase.d.ts +3 -0
  174. package/dist/tags/showcase.d.ts.map +1 -0
  175. package/dist/tags/showcase.js +72 -0
  176. package/dist/tags/showcase.js.map +1 -0
  177. package/dist/tags/sidenote.d.ts.map +1 -1
  178. package/dist/tags/sidenote.js +21 -29
  179. package/dist/tags/sidenote.js.map +1 -1
  180. package/dist/tags/tabs.d.ts.map +1 -1
  181. package/dist/tags/tabs.js +52 -58
  182. package/dist/tags/tabs.js.map +1 -1
  183. package/dist/tags/textblock.d.ts.map +1 -1
  184. package/dist/tags/textblock.js +27 -43
  185. package/dist/tags/textblock.js.map +1 -1
  186. package/dist/tags/tint.d.ts +12 -0
  187. package/dist/tags/tint.d.ts.map +1 -0
  188. package/dist/tags/tint.js +88 -0
  189. package/dist/tags/tint.js.map +1 -0
  190. package/dist/tags/toc.d.ts.map +1 -1
  191. package/dist/tags/toc.js +17 -32
  192. package/dist/tags/toc.js.map +1 -1
  193. package/package.json +3 -3
@@ -5,6 +5,10 @@ import { RenderableNodeCursor } from './renderable.js';
5
5
  export declare class Model {
6
6
  readonly node: Node;
7
7
  readonly config: Config;
8
+ /** Extracted tint child node (set by processChildren before @group runs) */
9
+ _tintNode: Node | null;
10
+ /** Extracted bg child node (set by processChildren before @group runs) */
11
+ _bgNode: Node | null;
8
12
  constructor(node: Node, config: Config);
9
13
  processChildren(nodes: Node[]): Markdoc.Node[];
10
14
  transform(): RenderableTreeNodes;
@@ -1 +1 @@
1
- {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/lib/model.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC5F,OAAO,EAAE,QAAQ,IAAI,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAKvD,qBAAa,KAAK;aAEE,IAAI,EAAE,IAAI;aACV,MAAM,EAAE,MAAM;gBADd,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM;IAOhC,eAAe,CAAC,KAAK,EAAE,IAAI,EAAE;IAS7B,SAAS,IAAI,mBAAmB;IAIhC,iBAAiB,CACf,KAAK,GAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,KAAK,mBAAmB,CAAC,CAAC,CAAM,GACzH,oBAAoB;CAQxB"}
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/lib/model.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC5F,OAAO,EAAE,QAAQ,IAAI,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAKvD,qBAAa,KAAK;aAOE,IAAI,EAAE,IAAI;aACV,MAAM,EAAE,MAAM;IAPhC,4EAA4E;IAC5E,SAAS,EAAE,IAAI,GAAG,IAAI,CAAQ;IAC9B,0EAA0E;IAC1E,OAAO,EAAE,IAAI,GAAG,IAAI,CAAQ;gBAGV,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM;IAOhC,eAAe,CAAC,KAAK,EAAE,IAAI,EAAE;IAwB7B,SAAS,IAAI,mBAAmB;IAIhC,iBAAiB,CACf,KAAK,GAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,KAAK,mBAAmB,CAAC,CAAC,CAAM,GACzH,oBAAoB;CAQxB"}
package/dist/lib/model.js CHANGED
@@ -7,11 +7,28 @@ export class Model {
7
7
  constructor(node, config) {
8
8
  this.node = node;
9
9
  this.config = config;
10
+ /** Extracted tint child node (set by processChildren before @group runs) */
11
+ this._tintNode = null;
12
+ /** Extracted bg child node (set by processChildren before @group runs) */
13
+ this._bgNode = null;
10
14
  for (const annotation of GeneratedAttributeAnnotation.onClass(this.constructor, true)) {
11
15
  annotation.create(node, config);
12
16
  }
13
17
  }
14
18
  processChildren(nodes) {
19
+ // Extract tint tag before @group processing so it doesn't interfere
20
+ // with header/body splitting (tint has type 'tag', which breaks @group)
21
+ const tintIdx = nodes.findIndex(n => n.type === 'tag' && n.tag === 'tint');
22
+ if (tintIdx !== -1) {
23
+ this._tintNode = nodes[tintIdx];
24
+ nodes = [...nodes.slice(0, tintIdx), ...nodes.slice(tintIdx + 1)];
25
+ }
26
+ // Extract bg tag before @group processing (same pattern as tint)
27
+ const bgIdx = nodes.findIndex(n => n.type === 'tag' && n.tag === 'bg');
28
+ if (bgIdx !== -1) {
29
+ this._bgNode = nodes[bgIdx];
30
+ nodes = [...nodes.slice(0, bgIdx), ...nodes.slice(bgIdx + 1)];
31
+ }
15
32
  let index = 0;
16
33
  for (const annotation of AbstractGroupAnnotation.onClass(this.constructor, true)) {
17
34
  index = annotation.create(nodes, index, this.config);
@@ -1 +1 @@
1
- {"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/lib/model.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,kBAAkB,CAAC;AAGvC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,MAAM,OAAO,KAAK;IAChB,YACkB,IAAU,EACV,MAAc;QADd,SAAI,GAAJ,IAAI,CAAM;QACV,WAAM,GAAN,MAAM,CAAQ;QAE9B,KAAK,MAAM,UAAU,IAAI,4BAA4B,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC;YACtF,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED,eAAe,CAAC,KAAa;QAC3B,IAAI,KAAK,GAAG,CAAC,CAAC;QAEd,KAAK,MAAM,UAAU,IAAI,uBAAuB,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC;YACjF,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACvD,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC;IAC1C,CAAC;IAED,iBAAiB,CACf,QAAwH,EAAE;QAE1H,MAAM,UAAU,GAAQ,EAAE,CAAC;QAC3B,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9C,UAAU,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;QACnC,CAAC;QACD,MAAM,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,UAAU,EAAE,EAAE,CAAC;QAClF,OAAO,IAAI,oBAAoB,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;IACjF,CAAC;CACF"}
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/lib/model.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"renderable.d.ts","sourceRoot":"","sources":["../../src/lib/renderable.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,EAAE,GAAG,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAG7C,qBAAa,oBAAoB,CAAC,CAAC,SAAS,kBAAkB,GAAG,kBAAkB;aAGrD,KAAK,EAAE,CAAC,EAAE;IAFtC,OAAO,CAAC,MAAM,CAAK;gBAES,KAAK,EAAE,CAAC,EAAE;IAEtC,MAAM,CAAC,QAAQ,CAAC,OAAO,SAAS,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO;IAIjE,IAAI,CAAC,OAAO,SAAS,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAAG,oBAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAIpH,GAAG,CAAC,OAAO,SAAS,QAAQ,EAAE,GAAG,EAAE,OAAO,GAAG,oBAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAK/E,IAAI,CAAC,QAAQ,SAAS,QAAQ,EAAE,EAAE,GAAG,IAAI,EAAE,QAAQ,GAAG,oBAAoB,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAKjG,QAAQ;IAIR,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,CAAC,CAAC,CAAC;IAI7C,MAAM,CAAC,GAAG,KAAK,EAAE,CAAC,kBAAkB,GAAG,oBAAoB,CAAC,EAAE;IAK9D,OAAO;IAKP,KAAK,CAAC,KAAK,EAAE,MAAM;IAInB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM;IAIjC,OAAO,IAAI,CAAC,EAAE;IAId,KAAK,IAAI,MAAM;IAIf,IAAI,IAAI,CAAC;CAGV"}
1
+ {"version":3,"file":"renderable.d.ts","sourceRoot":"","sources":["../../src/lib/renderable.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,EAAE,GAAG,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAI7C,qBAAa,oBAAoB,CAAC,CAAC,SAAS,kBAAkB,GAAG,kBAAkB;aAGrD,KAAK,EAAE,CAAC,EAAE;IAFtC,OAAO,CAAC,MAAM,CAAK;gBAES,KAAK,EAAE,CAAC,EAAE;IAEtC,MAAM,CAAC,QAAQ,CAAC,OAAO,SAAS,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO;IAIjE,IAAI,CAAC,OAAO,SAAS,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAAG,oBAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAIpH,GAAG,CAAC,OAAO,SAAS,QAAQ,EAAE,GAAG,EAAE,OAAO,GAAG,oBAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAK/E,IAAI,CAAC,QAAQ,SAAS,QAAQ,EAAE,EAAE,GAAG,IAAI,EAAE,QAAQ,GAAG,oBAAoB,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAKjG,QAAQ;IAIR,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,CAAC,CAAC,CAAC;IAI7C,MAAM,CAAC,GAAG,KAAK,EAAE,CAAC,kBAAkB,GAAG,oBAAoB,CAAC,EAAE;IAK9D,OAAO;IAKP,KAAK,CAAC,KAAK,EAAE,MAAM;IAInB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM;IAIjC,OAAO,IAAI,CAAC,EAAE;IAId,KAAK,IAAI,MAAM;IAIf,IAAI,IAAI,CAAC;CAGV"}
@@ -1,4 +1,5 @@
1
1
  import Markdoc from '@markdoc/markdoc';
2
+ import { toKebabCase } from '@refrakt-md/transform';
2
3
  import { walkTag } from '../util.js';
3
4
  export class RenderableNodeCursor {
4
5
  constructor(nodes) {
@@ -23,7 +24,7 @@ export class RenderableNodeCursor {
23
24
  return this.tags('h1', 'h2', 'h3', 'h4', 'h5', 'h6');
24
25
  }
25
26
  typeof(type) {
26
- return new RenderableNodeCursor(this.nodes.filter(n => Markdoc.Tag.isTag(n) && n.attributes.typeof === type));
27
+ return new RenderableNodeCursor(this.nodes.filter(n => Markdoc.Tag.isTag(n) && n.attributes['data-rune'] === toKebabCase(type)));
27
28
  }
28
29
  concat(...other) {
29
30
  const nodes = other.map(o => o instanceof RenderableNodeCursor ? o.nodes : o).flat();
@@ -1 +1 @@
1
- {"version":3,"file":"renderable.js","sourceRoot":"","sources":["../../src/lib/renderable.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"renderable.js","sourceRoot":"","sources":["../../src/lib/renderable.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Content model resolver engine.
3
+ *
4
+ * Pure functions that resolve a rune's AST children against a declarative
5
+ * content model, producing named fields without per-rune imperative code.
6
+ */
7
+ import type { Node } from '@markdoc/markdoc';
8
+ import type { ContentModel, ContentFieldDefinition, DelimitedModel, SectionsModel, ContentModelCondition, ItemModel, ResolvedContent } from '@refrakt-md/types';
9
+ export interface ResolveResult {
10
+ /** Resolved content fields. */
11
+ content: ResolvedContent;
12
+ /** Extracted tint child tag (if present). */
13
+ tintNode?: Node;
14
+ /** Extracted bg child tag (if present). */
15
+ bgNode?: Node;
16
+ }
17
+ /**
18
+ * Check whether an AST node matches a field's `match` string.
19
+ *
20
+ * Supported match values:
21
+ * - `'paragraph'`, `'heading'`, `'image'`, `'blockquote'`, `'fence'`,
22
+ * `'hr'`, `'list'` — match on `node.type`
23
+ * - `'heading:N'` — heading with a specific level
24
+ * - `'list:ordered'` / `'list:unordered'` — list with a specific ordering
25
+ * - `'tag:NAME'` — a child rune tag with a specific tag name
26
+ * - `'any'` — matches any node
27
+ */
28
+ export declare function matchesType(node: Node, match: string): boolean;
29
+ /**
30
+ * Resolve a sequence model: walk children in order, matching each against
31
+ * the next field in the model.
32
+ *
33
+ * - Optional fields are skipped when the next child doesn't match.
34
+ * - Greedy fields consume all consecutive matching nodes into an array.
35
+ */
36
+ export declare function resolveSequence(children: Node[], fields: ContentFieldDefinition[]): ResolvedContent;
37
+ /**
38
+ * Resolve a delimited model: split children by delimiter nodes, then
39
+ * resolve each zone's content.
40
+ */
41
+ export declare function resolveDelimited(children: Node[], model: DelimitedModel): ResolvedContent;
42
+ /**
43
+ * Resolve a sections model: split children at heading boundaries,
44
+ * optionally extracting heading data and emitting child rune tags.
45
+ *
46
+ * - Preamble (content before first section heading) is resolved via `fields`.
47
+ * - When `emitTag` is set, sections become AST tag nodes for child rune processing.
48
+ * - When `emitTag` is absent, sections are resolved objects with heading info + body.
49
+ */
50
+ export declare function resolveSections(children: Node[], model: SectionsModel): ResolvedContent;
51
+ /**
52
+ * Evaluate a content model condition against children and attributes.
53
+ */
54
+ export declare function evaluateCondition(condition: ContentModelCondition, children: Node[], attributes: Record<string, unknown>): boolean;
55
+ /**
56
+ * Resolve structured data from list item inline content.
57
+ *
58
+ * Two-phase extraction:
59
+ * 1. Match typed inline nodes (strong, em, link, image, code)
60
+ * 2. Collect remaining text, run regex pattern fields
61
+ */
62
+ export declare function resolveListItems(listNode: Node, itemModel: ItemModel): Record<string, unknown>[];
63
+ /**
64
+ * Resolve a content model against AST children.
65
+ * Dispatches to the pattern-specific resolver based on `model.type`.
66
+ */
67
+ export declare function resolve(children: Node[], model: ContentModel, attributes?: Record<string, unknown>): ResolvedContent;
68
+ /**
69
+ * Full resolution entry point: extracts special tags (tint, bg), then
70
+ * resolves the content model.
71
+ */
72
+ export declare function resolveContentModel(children: Node[], model: ContentModel, attributes?: Record<string, unknown>): ResolveResult;
73
+ //# sourceMappingURL=resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/lib/resolver.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,KAAK,EACX,YAAY,EACZ,sBAAsB,EACtB,cAAc,EAEd,aAAa,EAGb,qBAAqB,EACrB,SAAS,EAGT,eAAe,EACf,MAAM,mBAAmB,CAAC;AAM3B,MAAM,WAAW,aAAa;IAC7B,+BAA+B;IAC/B,OAAO,EAAE,eAAe,CAAC;IAEzB,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,IAAI,CAAC;IAEhB,2CAA2C;IAC3C,MAAM,CAAC,EAAE,IAAI,CAAC;CACd;AAiCD;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CA8B9D;AAMD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC9B,QAAQ,EAAE,IAAI,EAAE,EAChB,MAAM,EAAE,sBAAsB,EAAE,GAC9B,eAAe,CA0CjB;AAMD;;;GAGG;AACH,wBAAgB,gBAAgB,CAC/B,QAAQ,EAAE,IAAI,EAAE,EAChB,KAAK,EAAE,cAAc,GACnB,eAAe,CA6BjB;AA8CD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC9B,QAAQ,EAAE,IAAI,EAAE,EAChB,KAAK,EAAE,aAAa,GAClB,eAAe,CA0FjB;AAMD;;GAEG;AACH,wBAAgB,iBAAiB,CAChC,SAAS,EAAE,qBAAqB,EAChC,QAAQ,EAAE,IAAI,EAAE,EAChB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAYT;AAiDD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC/B,QAAQ,EAAE,IAAI,EACd,SAAS,EAAE,SAAS,GAClB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAiH3B;AAMD;;;GAGG;AACH,wBAAgB,OAAO,CACtB,QAAQ,EAAE,IAAI,EAAE,EAChB,KAAK,EAAE,YAAY,EACnB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAClC,eAAe,CAuBjB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAClC,QAAQ,EAAE,IAAI,EAAE,EAChB,KAAK,EAAE,YAAY,EACnB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAClC,aAAa,CAIf"}
@@ -0,0 +1,500 @@
1
+ /**
2
+ * Content model resolver engine.
3
+ *
4
+ * Pure functions that resolve a rune's AST children against a declarative
5
+ * content model, producing named fields without per-rune imperative code.
6
+ */
7
+ import Markdoc from '@markdoc/markdoc';
8
+ const { Ast } = Markdoc;
9
+ /**
10
+ * Extract special child tags (tint, bg) from children before resolving.
11
+ * Returns the filtered children and extracted nodes.
12
+ */
13
+ function extractSpecialTags(children) {
14
+ let tintNode;
15
+ let bgNode;
16
+ const filtered = children.filter(n => {
17
+ if (n.type === 'tag' && n.tag === 'tint') {
18
+ tintNode = n;
19
+ return false;
20
+ }
21
+ if (n.type === 'tag' && n.tag === 'bg') {
22
+ bgNode = n;
23
+ return false;
24
+ }
25
+ return true;
26
+ });
27
+ return { filtered, tintNode, bgNode };
28
+ }
29
+ // ---------------------------------------------------------------------------
30
+ // Type matching
31
+ // ---------------------------------------------------------------------------
32
+ /**
33
+ * Check whether an AST node matches a field's `match` string.
34
+ *
35
+ * Supported match values:
36
+ * - `'paragraph'`, `'heading'`, `'image'`, `'blockquote'`, `'fence'`,
37
+ * `'hr'`, `'list'` — match on `node.type`
38
+ * - `'heading:N'` — heading with a specific level
39
+ * - `'list:ordered'` / `'list:unordered'` — list with a specific ordering
40
+ * - `'tag:NAME'` — a child rune tag with a specific tag name
41
+ * - `'any'` — matches any node
42
+ */
43
+ export function matchesType(node, match) {
44
+ if (match === 'any')
45
+ return true;
46
+ // Pipe-separated alternatives: 'list|fence' matches either
47
+ if (match.includes('|')) {
48
+ return match.split('|').some(m => matchesType(node, m));
49
+ }
50
+ // heading:N
51
+ if (match.startsWith('heading:')) {
52
+ const level = parseInt(match.slice(8), 10);
53
+ return node.type === 'heading' && node.attributes?.level === level;
54
+ }
55
+ // list:ordered / list:unordered
56
+ if (match === 'list:ordered') {
57
+ return node.type === 'list' && node.attributes?.ordered === true;
58
+ }
59
+ if (match === 'list:unordered') {
60
+ return node.type === 'list' && node.attributes?.ordered !== true;
61
+ }
62
+ // tag:NAME
63
+ if (match.startsWith('tag:')) {
64
+ const tagName = match.slice(4);
65
+ return node.type === 'tag' && node.tag === tagName;
66
+ }
67
+ // Simple type match
68
+ return node.type === match;
69
+ }
70
+ // ---------------------------------------------------------------------------
71
+ // Sequence resolver
72
+ // ---------------------------------------------------------------------------
73
+ /**
74
+ * Resolve a sequence model: walk children in order, matching each against
75
+ * the next field in the model.
76
+ *
77
+ * - Optional fields are skipped when the next child doesn't match.
78
+ * - Greedy fields consume all consecutive matching nodes into an array.
79
+ */
80
+ export function resolveSequence(children, fields) {
81
+ const result = {};
82
+ let childIndex = 0;
83
+ for (const field of fields) {
84
+ if (childIndex >= children.length) {
85
+ continue;
86
+ }
87
+ const child = children[childIndex];
88
+ if (matchesType(child, field.match)) {
89
+ if (field.greedy) {
90
+ const collected = [];
91
+ while (childIndex < children.length &&
92
+ matchesType(children[childIndex], field.match)) {
93
+ collected.push(children[childIndex]);
94
+ childIndex++;
95
+ }
96
+ result[field.name] = collected;
97
+ }
98
+ else {
99
+ result[field.name] = child;
100
+ childIndex++;
101
+ }
102
+ // If this list field has an itemModel, extract structured data
103
+ if (field.itemModel) {
104
+ const node = result[field.name];
105
+ if (node && typeof node === 'object' && 'type' in node) {
106
+ result[`${field.name}Data`] = resolveListItems(node, field.itemModel);
107
+ }
108
+ }
109
+ }
110
+ else if (!field.optional) {
111
+ // Required field didn't match — skip the child and move on
112
+ childIndex++;
113
+ }
114
+ // If optional and doesn't match, just skip the field (don't advance child)
115
+ }
116
+ return result;
117
+ }
118
+ // ---------------------------------------------------------------------------
119
+ // Delimited resolver
120
+ // ---------------------------------------------------------------------------
121
+ /**
122
+ * Resolve a delimited model: split children by delimiter nodes, then
123
+ * resolve each zone's content.
124
+ */
125
+ export function resolveDelimited(children, model) {
126
+ // Split children into groups at each delimiter
127
+ const groups = [[]];
128
+ for (const child of children) {
129
+ if (matchesType(child, model.delimiter)) {
130
+ groups.push([]);
131
+ }
132
+ else {
133
+ groups[groups.length - 1].push(child);
134
+ }
135
+ }
136
+ if (model.dynamicZones && model.zoneModel) {
137
+ return {
138
+ zones: groups.map(group => resolve(group, model.zoneModel)),
139
+ };
140
+ }
141
+ // Named zones: each group maps to a declared zone by index
142
+ const result = {};
143
+ if (model.zones) {
144
+ for (let i = 0; i < model.zones.length; i++) {
145
+ const zone = model.zones[i];
146
+ const group = i < groups.length ? groups[i] : [];
147
+ result[zone.name] = resolveSequence(group, zone.fields);
148
+ }
149
+ }
150
+ return result;
151
+ }
152
+ // ---------------------------------------------------------------------------
153
+ // Sections resolver
154
+ // ---------------------------------------------------------------------------
155
+ /** Extract plain text from a heading AST node by walking its children. */
156
+ function extractHeadingText(headingNode) {
157
+ const texts = [];
158
+ for (const child of headingNode.walk()) {
159
+ if (child.type === 'text' && child.attributes?.content) {
160
+ texts.push(child.attributes.content);
161
+ }
162
+ }
163
+ return texts.join(' ');
164
+ }
165
+ /**
166
+ * Apply heading extract patterns to heading text, producing named fields.
167
+ * Each field's regex is applied in order; 'remainder' captures what's left.
168
+ */
169
+ function applyHeadingExtract(text, extract) {
170
+ const result = {};
171
+ let remaining = text;
172
+ for (const field of extract.fields) {
173
+ if (field.pattern === 'remainder') {
174
+ result[field.name] = remaining.trim();
175
+ remaining = '';
176
+ }
177
+ else {
178
+ const match = remaining.match(field.pattern);
179
+ if (match) {
180
+ result[field.name] = (match[1] || match[0]).trim();
181
+ remaining = remaining.slice(match[0].length);
182
+ }
183
+ else if (!field.optional) {
184
+ result[field.name] = remaining.trim();
185
+ }
186
+ }
187
+ }
188
+ return result;
189
+ }
190
+ /**
191
+ * Resolve a sections model: split children at heading boundaries,
192
+ * optionally extracting heading data and emitting child rune tags.
193
+ *
194
+ * - Preamble (content before first section heading) is resolved via `fields`.
195
+ * - When `emitTag` is set, sections become AST tag nodes for child rune processing.
196
+ * - When `emitTag` is absent, sections are resolved objects with heading info + body.
197
+ */
198
+ export function resolveSections(children, model) {
199
+ // 1. Determine heading level
200
+ const headingSpec = model.sectionHeading;
201
+ let level;
202
+ if (headingSpec.includes(':')) {
203
+ level = parseInt(headingSpec.split(':')[1], 10);
204
+ }
205
+ else {
206
+ // Auto-detect from first heading child
207
+ level = children.find(n => n.type === 'heading')?.attributes?.level;
208
+ }
209
+ if (level === undefined) {
210
+ // No headings found — everything is preamble
211
+ const preamble = model.fields
212
+ ? resolveSequence(children, model.fields)
213
+ : {};
214
+ return { ...preamble, sections: [] };
215
+ }
216
+ // 2. Split at section-level headings
217
+ const preambleNodes = [];
218
+ const rawSections = [];
219
+ let current = null;
220
+ for (const child of children) {
221
+ if (child.type === 'heading' && child.attributes?.level === level) {
222
+ if (current)
223
+ rawSections.push(current);
224
+ current = { headingNode: child, body: [] };
225
+ }
226
+ else if (current) {
227
+ current.body.push(child);
228
+ }
229
+ else {
230
+ preambleNodes.push(child);
231
+ }
232
+ }
233
+ if (current)
234
+ rawSections.push(current);
235
+ // 3. Resolve preamble fields
236
+ const preamble = model.fields
237
+ ? resolveSequence(preambleNodes, model.fields)
238
+ : {};
239
+ // 4. Process each section
240
+ if (model.emitTag) {
241
+ // emitTag: convert sections to AST tag nodes
242
+ const tagNodes = rawSections.map(section => {
243
+ const headingText = extractHeadingText(section.headingNode);
244
+ const extracted = model.headingExtract
245
+ ? applyHeadingExtract(headingText, model.headingExtract)
246
+ : {};
247
+ const attrs = {};
248
+ if (model.emitAttributes) {
249
+ for (const [key, ref] of Object.entries(model.emitAttributes)) {
250
+ if (ref === '$heading') {
251
+ attrs[key] = headingText;
252
+ }
253
+ else if (ref.startsWith('$')) {
254
+ attrs[key] = extracted[ref.slice(1)] ?? '';
255
+ }
256
+ else {
257
+ attrs[key] = ref;
258
+ }
259
+ }
260
+ }
261
+ return new Ast.Node('tag', attrs, section.body, model.emitTag);
262
+ });
263
+ return { ...preamble, sections: tagNodes };
264
+ }
265
+ // No emitTag: return resolved section data
266
+ const resolvedSections = rawSections.map(section => {
267
+ const headingText = extractHeadingText(section.headingNode);
268
+ const extracted = model.headingExtract
269
+ ? applyHeadingExtract(headingText, model.headingExtract)
270
+ : {};
271
+ const bodyResolved = resolve(section.body, model.sectionModel);
272
+ return {
273
+ $heading: headingText,
274
+ $headingNode: section.headingNode,
275
+ ...Object.fromEntries(Object.entries(extracted).map(([k, v]) => [`$${k}`, v])),
276
+ ...bodyResolved,
277
+ };
278
+ });
279
+ return { ...preamble, sections: resolvedSections };
280
+ }
281
+ // ---------------------------------------------------------------------------
282
+ // Conditional evaluation
283
+ // ---------------------------------------------------------------------------
284
+ /**
285
+ * Evaluate a content model condition against children and attributes.
286
+ */
287
+ export function evaluateCondition(condition, children, attributes) {
288
+ if ('hasChild' in condition) {
289
+ return children.some(c => matchesType(c, condition.hasChild));
290
+ }
291
+ if ('in' in condition) {
292
+ const value = String(attributes[condition.attribute] ?? '');
293
+ return condition.in.includes(value);
294
+ }
295
+ if ('exists' in condition) {
296
+ return attributes[condition.attribute] != null && attributes[condition.attribute] !== '';
297
+ }
298
+ return false;
299
+ }
300
+ /**
301
+ * Check whether a content model is conditional (has `when` branches).
302
+ */
303
+ function isConditional(model) {
304
+ return 'when' in model && Array.isArray(model.when);
305
+ }
306
+ // ---------------------------------------------------------------------------
307
+ // Inline item model resolver
308
+ // ---------------------------------------------------------------------------
309
+ /** Extract plain text from an AST node by walking its children. */
310
+ function extractNodeText(n) {
311
+ if (n.type === 'text')
312
+ return n.attributes?.content ?? '';
313
+ const texts = [];
314
+ for (const child of n.walk()) {
315
+ if (child.type === 'text' && child.attributes?.content) {
316
+ texts.push(child.attributes.content);
317
+ }
318
+ }
319
+ return texts.join('');
320
+ }
321
+ /**
322
+ * Find an inline match within a node, handling link-wrapping-strong patterns.
323
+ * E.g., `[**Name**](/url)` — a link wrapping bold text.
324
+ */
325
+ function findInlineMatch(n, matchType) {
326
+ if (n.type === matchType)
327
+ return n;
328
+ // Check inside links for nested inline types
329
+ if (n.type === 'link' && matchType !== 'link') {
330
+ for (const child of n.children ?? []) {
331
+ if (child.type === matchType)
332
+ return child;
333
+ }
334
+ }
335
+ // Check inside strong/em for nested types
336
+ if ((n.type === 'strong' || n.type === 'em') && matchType !== n.type) {
337
+ for (const child of n.children ?? []) {
338
+ if (child.type === matchType)
339
+ return child;
340
+ }
341
+ }
342
+ return null;
343
+ }
344
+ /**
345
+ * Resolve structured data from list item inline content.
346
+ *
347
+ * Two-phase extraction:
348
+ * 1. Match typed inline nodes (strong, em, link, image, code)
349
+ * 2. Collect remaining text, run regex pattern fields
350
+ */
351
+ export function resolveListItems(listNode, itemModel) {
352
+ const listItems = listNode.children ?? [];
353
+ return listItems.map(listItem => {
354
+ const result = {};
355
+ // Flatten `inline` wrapper nodes — Markdoc wraps inline content in
356
+ // an `inline` node (item > inline > [strong, text, em, ...]).
357
+ // Block-level children (paragraph, list) remain at the item level.
358
+ const inlineChildren = [];
359
+ for (const child of listItem.children ?? []) {
360
+ if (child.type === 'inline') {
361
+ inlineChildren.push(...(child.children ?? []));
362
+ }
363
+ else {
364
+ inlineChildren.push(child);
365
+ }
366
+ }
367
+ const consumed = new Set();
368
+ // Phase 1: Match typed inline nodes
369
+ // Soft-consumed: a child inside a wrapper was matched (e.g., strong
370
+ // inside a link). The wrapper is still available for a direct match.
371
+ const softConsumed = new Set();
372
+ for (const field of itemModel.fields) {
373
+ if (field.match === 'text')
374
+ continue; // handle in phase 2
375
+ // Nested list (cue points, sub-items)
376
+ if (field.match === 'list') {
377
+ const idx = inlineChildren.findIndex((c, i) => !consumed.has(i) && (c.type === 'list'));
378
+ if (idx >= 0) {
379
+ consumed.add(idx);
380
+ result[field.name] = field.itemModel
381
+ ? resolveListItems(inlineChildren[idx], field.itemModel)
382
+ : inlineChildren[idx];
383
+ }
384
+ continue;
385
+ }
386
+ // Block-level children (paragraphs under list items)
387
+ if (field.match === 'paragraph' && field.greedy) {
388
+ const paragraphs = [];
389
+ inlineChildren.forEach((c, i) => {
390
+ if (!consumed.has(i) && c.type === 'paragraph') {
391
+ consumed.add(i);
392
+ paragraphs.push(c);
393
+ }
394
+ });
395
+ if (paragraphs.length > 0)
396
+ result[field.name] = paragraphs;
397
+ continue;
398
+ }
399
+ // Inline node matching (strong, em, link, image, code)
400
+ for (let i = 0; i < inlineChildren.length; i++) {
401
+ // Skip hard-consumed; allow soft-consumed for direct matches
402
+ if (consumed.has(i))
403
+ continue;
404
+ if (softConsumed.has(i) && field.match !== inlineChildren[i].type)
405
+ continue;
406
+ const child = inlineChildren[i];
407
+ const matched = findInlineMatch(child, field.match);
408
+ if (matched) {
409
+ if (matched === child) {
410
+ // Direct match → hard consume
411
+ consumed.add(i);
412
+ }
413
+ else {
414
+ // Child-inside-wrapper → soft consume
415
+ softConsumed.add(i);
416
+ }
417
+ if (field.extract) {
418
+ // For extract, get the attribute from the wrapper (e.g., href from link)
419
+ const source = child.attributes?.[field.extract] != null ? child : matched;
420
+ result[field.name] = source.attributes?.[field.extract];
421
+ }
422
+ else {
423
+ result[field.name] = extractNodeText(matched);
424
+ }
425
+ break;
426
+ }
427
+ }
428
+ }
429
+ // Merge soft-consumed into consumed for text collection
430
+ for (const idx of softConsumed)
431
+ consumed.add(idx);
432
+ // Phase 2: Collect remaining text, run pattern fields
433
+ const textFields = itemModel.fields.filter(f => f.match === 'text');
434
+ if (textFields.length > 0) {
435
+ const remainingText = inlineChildren
436
+ .filter((_, i) => !consumed.has(i))
437
+ .filter(c => c.type === 'text' || c.type === 'softbreak')
438
+ .map(c => c.attributes?.content ?? '')
439
+ .join('')
440
+ .trim();
441
+ let textToProcess = remainingText;
442
+ for (const field of textFields) {
443
+ if (field.pattern === 'remainder') {
444
+ const trimmed = textToProcess.trim();
445
+ if (trimmed || !field.optional) {
446
+ result[field.name] = trimmed;
447
+ }
448
+ }
449
+ else if (field.pattern instanceof RegExp) {
450
+ const match = textToProcess.match(field.pattern);
451
+ if (match) {
452
+ result[field.name] = match[1] ?? match[0];
453
+ textToProcess = textToProcess.replace(field.pattern, '');
454
+ }
455
+ }
456
+ }
457
+ }
458
+ return result;
459
+ });
460
+ }
461
+ // ---------------------------------------------------------------------------
462
+ // Top-level resolver
463
+ // ---------------------------------------------------------------------------
464
+ /**
465
+ * Resolve a content model against AST children.
466
+ * Dispatches to the pattern-specific resolver based on `model.type`.
467
+ */
468
+ export function resolve(children, model, attributes) {
469
+ // Handle conditional models
470
+ if (isConditional(model)) {
471
+ for (const branch of model.when) {
472
+ if (evaluateCondition(branch.condition, children, attributes ?? {})) {
473
+ return resolve(children, branch.model, attributes);
474
+ }
475
+ }
476
+ return resolve(children, model.default, attributes);
477
+ }
478
+ switch (model.type) {
479
+ case 'sequence':
480
+ return resolveSequence(children, model.fields);
481
+ case 'sections':
482
+ return resolveSections(children, model);
483
+ case 'delimited':
484
+ return resolveDelimited(children, model);
485
+ case 'custom':
486
+ return { children: model.processChildren(children, attributes ?? {}) };
487
+ default:
488
+ return {};
489
+ }
490
+ }
491
+ /**
492
+ * Full resolution entry point: extracts special tags (tint, bg), then
493
+ * resolves the content model.
494
+ */
495
+ export function resolveContentModel(children, model, attributes) {
496
+ const { filtered, tintNode, bgNode } = extractSpecialTags(children);
497
+ const content = resolve(filtered, model, attributes);
498
+ return { content, tintNode, bgNode };
499
+ }
500
+ //# sourceMappingURL=resolver.js.map