@wdprlib/parser 3.2.0 → 4.0.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 (433) hide show
  1. package/dist/index.cjs +10451 -8402
  2. package/dist/index.d.cts +313 -337
  3. package/dist/index.d.ts +313 -337
  4. package/dist/index.js +10438 -8389
  5. package/package.json +1 -1
  6. package/src/index.ts +7 -0
  7. package/src/lexer/anchor.ts +48 -0
  8. package/src/lexer/index.ts +3 -2
  9. package/src/lexer/lexer.ts +73 -559
  10. package/src/lexer/options.ts +19 -0
  11. package/src/lexer/punctuation.ts +70 -0
  12. package/src/lexer/quoted-string.ts +16 -0
  13. package/src/lexer/runs.ts +85 -0
  14. package/src/lexer/spacing-actions.ts +24 -0
  15. package/src/lexer/state.ts +103 -0
  16. package/src/lexer/syntax-actions.ts +80 -0
  17. package/src/lexer/text-actions.ts +41 -0
  18. package/src/lexer/token-actions.ts +136 -0
  19. package/src/lexer/token-factory.ts +62 -0
  20. package/src/lexer/tokenize.ts +18 -0
  21. package/src/parser/constants.ts +2 -0
  22. package/src/parser/depth/index.ts +111 -0
  23. package/src/parser/depth/stack.ts +82 -0
  24. package/src/parser/parse/block.ts +42 -0
  25. package/src/parser/parse/context.ts +26 -0
  26. package/src/parser/parse/footnotes.ts +25 -0
  27. package/src/parser/parse/index.ts +42 -0
  28. package/src/parser/parse/options.ts +34 -0
  29. package/src/parser/parse/parser.ts +79 -0
  30. package/src/parser/parse/plain-non-ascii.ts +129 -0
  31. package/src/parser/parse/result.ts +57 -0
  32. package/src/parser/parse/source.ts +11 -0
  33. package/src/parser/postprocess/divAdjacentParagraph.ts +1 -1
  34. package/src/parser/postprocess/spanStrip/clean-element.ts +168 -0
  35. package/src/parser/postprocess/spanStrip/cleanup.ts +25 -0
  36. package/src/parser/postprocess/spanStrip/empty-spans.ts +36 -0
  37. package/src/parser/postprocess/spanStrip/escaped.ts +78 -0
  38. package/src/parser/postprocess/spanStrip/factory.ts +23 -0
  39. package/src/parser/postprocess/spanStrip/index.ts +8 -0
  40. package/src/parser/postprocess/spanStrip/merge.ts +117 -0
  41. package/src/parser/postprocess/spanStrip/predicates.ts +59 -0
  42. package/src/parser/postprocess/spanStrip/split.ts +67 -0
  43. package/src/parser/preprocess/expr/chars.ts +15 -0
  44. package/src/parser/preprocess/expr/evaluate.ts +22 -0
  45. package/src/parser/preprocess/expr/index.ts +45 -0
  46. package/src/parser/preprocess/expr/kind.ts +19 -0
  47. package/src/parser/preprocess/expr/parse.ts +103 -0
  48. package/src/parser/preprocess/expr/scan.ts +34 -0
  49. package/src/parser/preprocess/expr/types.ts +14 -0
  50. package/src/parser/preprocess/typography.ts +70 -5
  51. package/src/parser/preprocess/utils/bracket-depths.ts +98 -0
  52. package/src/parser/preprocess/utils/index.ts +13 -0
  53. package/src/parser/preprocess/utils/raw-regions.ts +153 -0
  54. package/src/parser/preprocess/whitespace/detection.ts +39 -0
  55. package/src/parser/preprocess/whitespace/index.ts +79 -0
  56. package/src/parser/preprocess/whitespace/leading-spaces.ts +11 -0
  57. package/src/parser/preprocess/whitespace/patterns.ts +23 -0
  58. package/src/parser/rules/block/align/body.ts +46 -0
  59. package/src/parser/rules/block/align/element.ts +13 -0
  60. package/src/parser/rules/block/align/index.ts +90 -0
  61. package/src/parser/rules/block/align/syntax.ts +113 -0
  62. package/src/parser/rules/block/bibliography/body.ts +81 -0
  63. package/src/parser/rules/block/bibliography/entries.ts +49 -0
  64. package/src/parser/rules/block/bibliography/entry-content.ts +73 -0
  65. package/src/parser/rules/block/bibliography/entry-key.ts +83 -0
  66. package/src/parser/rules/block/bibliography/index.ts +90 -0
  67. package/src/parser/rules/block/bibliography/open.ts +53 -0
  68. package/src/parser/rules/block/block-list/bare-content.ts +105 -0
  69. package/src/parser/rules/block/block-list/bare-paragraph.ts +60 -0
  70. package/src/parser/rules/block/block-list/index.ts +51 -0
  71. package/src/parser/rules/block/block-list/item-content.ts +132 -0
  72. package/src/parser/rules/block/block-list/li-content.ts +107 -0
  73. package/src/parser/rules/block/block-list/li-item.ts +77 -0
  74. package/src/parser/rules/block/block-list/list-block.ts +100 -0
  75. package/src/parser/rules/block/block-list/open.ts +51 -0
  76. package/src/parser/rules/block/block-list/tags.ts +50 -0
  77. package/src/parser/rules/block/blockquote/build.ts +62 -0
  78. package/src/parser/rules/block/blockquote/index.ts +80 -0
  79. package/src/parser/rules/block/blockquote/line.ts +79 -0
  80. package/src/parser/rules/block/blockquote/lines.ts +39 -0
  81. package/src/parser/rules/block/{center.ts → center/index.ts} +7 -22
  82. package/src/parser/rules/block/center/open.ts +27 -0
  83. package/src/parser/rules/block/{clear-float.ts → clear-float/index.ts} +6 -30
  84. package/src/parser/rules/block/clear-float/syntax.ts +43 -0
  85. package/src/parser/rules/block/code/attributes.ts +30 -0
  86. package/src/parser/rules/block/code/content.ts +57 -0
  87. package/src/parser/rules/block/code/index.ts +100 -0
  88. package/src/parser/rules/block/collapsible/attributes.ts +95 -0
  89. package/src/parser/rules/block/collapsible/body.ts +69 -0
  90. package/src/parser/rules/block/collapsible/index.ts +117 -0
  91. package/src/parser/rules/block/collapsible/open.ts +51 -0
  92. package/src/parser/rules/block/collapsible/orphans.ts +31 -0
  93. package/src/parser/rules/block/collapsible/tags.ts +17 -0
  94. package/src/parser/rules/block/comment/consume.ts +37 -0
  95. package/src/parser/rules/block/{comment.ts → comment/index.ts} +12 -38
  96. package/src/parser/rules/block/{content-separator.ts → content-separator/index.ts} +5 -35
  97. package/src/parser/rules/block/content-separator/syntax.ts +33 -0
  98. package/src/parser/rules/block/definition-list/collect.ts +40 -0
  99. package/src/parser/rules/block/definition-list/index.ts +63 -0
  100. package/src/parser/rules/block/definition-list/item-key.ts +95 -0
  101. package/src/parser/rules/block/definition-list/item-value.ts +56 -0
  102. package/src/parser/rules/block/definition-list/items.ts +54 -0
  103. package/src/parser/rules/block/div/body.ts +41 -0
  104. package/src/parser/rules/block/div/close.ts +41 -0
  105. package/src/parser/rules/block/div/failed.ts +117 -0
  106. package/src/parser/rules/block/div/index.ts +112 -0
  107. package/src/parser/rules/block/div/nesting.ts +37 -0
  108. package/src/parser/rules/block/div/open.ts +59 -0
  109. package/src/parser/rules/block/div/paragraph-strip.ts +44 -0
  110. package/src/parser/rules/block/embed-block/content.ts +53 -0
  111. package/src/parser/rules/block/embed-block/index.ts +91 -0
  112. package/src/parser/rules/block/embed-block/open.ts +52 -0
  113. package/src/parser/rules/block/embed-block/tags.ts +5 -0
  114. package/src/parser/rules/block/footnoteblock/attributes.ts +73 -0
  115. package/src/parser/rules/block/footnoteblock/index.ts +82 -0
  116. package/src/parser/rules/block/footnoteblock/open.ts +53 -0
  117. package/src/parser/rules/block/heading/index.ts +87 -0
  118. package/src/parser/rules/block/heading/open.ts +50 -0
  119. package/src/parser/rules/block/heading/toc-text.ts +26 -0
  120. package/src/parser/rules/block/{horizontal-rule.ts → horizontal-rule/index.ts} +4 -21
  121. package/src/parser/rules/block/horizontal-rule/syntax.ts +21 -0
  122. package/src/parser/rules/block/html/body.ts +114 -0
  123. package/src/parser/rules/block/html/diagnostics.ts +11 -0
  124. package/src/parser/rules/block/html/index.ts +95 -0
  125. package/src/parser/rules/block/html/open.ts +36 -0
  126. package/src/parser/rules/block/iframe/attributes.ts +106 -0
  127. package/src/parser/rules/block/iframe/index.ts +73 -0
  128. package/src/parser/rules/block/iframe/open.ts +58 -0
  129. package/src/parser/rules/block/iframe/source.ts +24 -0
  130. package/src/parser/rules/block/iframe/url.ts +38 -0
  131. package/src/parser/rules/block/iftags/body.ts +48 -0
  132. package/src/parser/rules/block/iftags/condition.ts +24 -0
  133. package/src/parser/rules/block/{iftags.ts → iftags/index.ts} +16 -58
  134. package/src/parser/rules/block/include/arguments.ts +48 -0
  135. package/src/parser/rules/block/include/index.ts +75 -0
  136. package/src/parser/rules/block/include/location.ts +24 -0
  137. package/src/parser/rules/block/include/variables.ts +37 -0
  138. package/src/parser/rules/block/list/index.ts +73 -0
  139. package/src/parser/rules/block/list/line.ts +77 -0
  140. package/src/parser/rules/block/list/native.ts +89 -0
  141. package/src/parser/rules/block/math/content.ts +54 -0
  142. package/src/parser/rules/block/math/index.ts +106 -0
  143. package/src/parser/rules/block/math/name.ts +35 -0
  144. package/src/parser/rules/block/module/body.ts +92 -0
  145. package/src/parser/rules/block/module/element.ts +33 -0
  146. package/src/parser/rules/block/module/include/directive.ts +91 -0
  147. package/src/parser/rules/block/module/include/index.ts +11 -2
  148. package/src/parser/rules/block/module/include/references.ts +42 -0
  149. package/src/parser/rules/block/module/include/resolve/cache.ts +44 -0
  150. package/src/parser/rules/block/module/include/resolve/index.ts +106 -0
  151. package/src/parser/rules/block/module/include/resolve/iterate.ts +202 -0
  152. package/src/parser/rules/block/module/include/resolve/replace.ts +31 -0
  153. package/src/parser/rules/block/module/include/resolve/types.ts +105 -0
  154. package/src/parser/rules/block/module/include/scanner.ts +121 -0
  155. package/src/parser/rules/block/module/index.ts +14 -2
  156. package/src/parser/rules/block/module/listpages/compiler.ts +12 -392
  157. package/src/parser/rules/block/module/listpages/extract.ts +25 -359
  158. package/src/parser/rules/block/module/listpages/extraction/listpages.ts +42 -0
  159. package/src/parser/rules/block/module/listpages/extraction/listusers.ts +30 -0
  160. package/src/parser/rules/block/module/listpages/extraction/query.ts +51 -0
  161. package/src/parser/rules/block/module/listpages/extraction/result.ts +18 -0
  162. package/src/parser/rules/block/module/listpages/extraction/template.ts +96 -0
  163. package/src/parser/rules/block/module/listpages/extraction/variables.ts +58 -0
  164. package/src/parser/rules/block/module/listpages/normalization/date-selector.ts +53 -0
  165. package/src/parser/rules/block/module/listpages/normalization/numeric-selector.ts +32 -0
  166. package/src/parser/rules/block/module/listpages/normalization/order-parent.ts +82 -0
  167. package/src/parser/rules/block/module/listpages/normalization/selectors.ts +2 -0
  168. package/src/parser/rules/block/module/listpages/normalization/tags-category.ts +86 -0
  169. package/src/parser/rules/block/module/listpages/normalize.ts +8 -324
  170. package/src/parser/rules/block/module/listpages/resolution/items.ts +43 -0
  171. package/src/parser/rules/block/module/listpages/resolution/wrapper.ts +42 -0
  172. package/src/parser/rules/block/module/listpages/resolve.ts +5 -75
  173. package/src/parser/rules/block/module/listpages/template/format/content.ts +41 -0
  174. package/src/parser/rules/block/module/listpages/template/format/date.ts +116 -0
  175. package/src/parser/rules/block/module/listpages/template/format/index.ts +4 -0
  176. package/src/parser/rules/block/module/listpages/template/format/tags.ts +7 -0
  177. package/src/parser/rules/block/module/listpages/template/format/user.ts +9 -0
  178. package/src/parser/rules/block/module/listpages/template/getters/index.ts +36 -0
  179. package/src/parser/rules/block/module/listpages/template/getters/parameterized.ts +60 -0
  180. package/src/parser/rules/block/module/listpages/template/getters/simple.ts +65 -0
  181. package/src/parser/rules/block/module/listpages/template/getters/types.ts +3 -0
  182. package/src/parser/rules/block/module/listpages/template/syntax.ts +97 -0
  183. package/src/parser/rules/block/module/listpages/types/data-fetcher.ts +15 -0
  184. package/src/parser/rules/block/module/listpages/types/data-requirements.ts +52 -0
  185. package/src/parser/rules/block/module/listpages/types/external-data.ts +77 -0
  186. package/src/parser/rules/block/module/listpages/types/index.ts +17 -0
  187. package/src/parser/rules/block/module/listpages/types/normalized-query.ts +120 -0
  188. package/src/parser/rules/block/module/listpages/types/query.ts +67 -0
  189. package/src/parser/rules/block/module/listpages/types/template.ts +17 -0
  190. package/src/parser/rules/block/module/listpages/types/variables.ts +69 -0
  191. package/src/parser/rules/block/module/listpages/url-resolution/fields.ts +48 -0
  192. package/src/parser/rules/block/module/listpages/url-resolution/params.ts +19 -0
  193. package/src/parser/rules/block/module/listpages/url-resolution/query.ts +24 -0
  194. package/src/parser/rules/block/module/listpages/url-resolution/resolve.ts +53 -0
  195. package/src/parser/rules/block/module/listpages/url-resolution/value.ts +25 -0
  196. package/src/parser/rules/block/module/listpages/url-resolver.ts +3 -160
  197. package/src/parser/rules/block/module/listusers/compiler.ts +4 -25
  198. package/src/parser/rules/block/module/listusers/extract.ts +4 -9
  199. package/src/parser/rules/block/module/listusers/getters.ts +21 -0
  200. package/src/parser/rules/block/module/listusers/variables.ts +15 -0
  201. package/src/parser/rules/block/module/open.ts +57 -0
  202. package/src/parser/rules/block/module/resolution/contexts.ts +78 -0
  203. package/src/parser/rules/block/module/resolution/data-maps.ts +39 -0
  204. package/src/parser/rules/block/module/resolution/dynamic-modules.ts +93 -0
  205. package/src/parser/rules/block/module/resolution/styles.ts +53 -0
  206. package/src/parser/rules/block/module/resolution/walk-resolve.ts +107 -0
  207. package/src/parser/rules/block/module/resolve.ts +79 -292
  208. package/src/parser/rules/block/module/rule.ts +56 -0
  209. package/src/parser/rules/block/module/types-common.ts +11 -0
  210. package/src/parser/rules/block/module/walk/children.ts +35 -0
  211. package/src/parser/rules/block/module/walk/index.ts +9 -0
  212. package/src/parser/rules/block/module/walk/map/index.ts +2 -0
  213. package/src/parser/rules/block/module/walk/map/stateful-definition-list.ts +25 -0
  214. package/src/parser/rules/block/module/walk/map/stateful-list.ts +40 -0
  215. package/src/parser/rules/block/module/walk/map/stateful-table.ts +23 -0
  216. package/src/parser/rules/block/module/walk/map/stateful-tabs.ts +19 -0
  217. package/src/parser/rules/block/module/walk/map/stateful.ts +71 -0
  218. package/src/parser/rules/block/module/walk/map/stateless-definition-list.ts +12 -0
  219. package/src/parser/rules/block/module/walk/map/stateless-list.ts +29 -0
  220. package/src/parser/rules/block/module/walk/map/stateless-table.ts +11 -0
  221. package/src/parser/rules/block/module/walk/map/stateless-tabs.ts +5 -0
  222. package/src/parser/rules/block/module/walk/map/stateless.ts +51 -0
  223. package/src/parser/rules/block/module/walk/map/types.ts +6 -0
  224. package/src/parser/rules/block/module/walk/traverse.ts +65 -0
  225. package/src/parser/rules/block/orphan-li/content.ts +60 -0
  226. package/src/parser/rules/block/orphan-li/index.ts +75 -0
  227. package/src/parser/rules/block/orphan-li/open.ts +25 -0
  228. package/src/parser/rules/block/orphan-li/tags.ts +40 -0
  229. package/src/parser/rules/block/paragraph/content.ts +12 -0
  230. package/src/parser/rules/block/paragraph/index.ts +60 -0
  231. package/src/parser/rules/block/paragraph/normalize.ts +52 -0
  232. package/src/parser/rules/block/paragraph/span-markers.ts +52 -0
  233. package/src/parser/rules/block/parsing/attributes/index.ts +32 -0
  234. package/src/parser/rules/block/parsing/attributes/names.ts +93 -0
  235. package/src/parser/rules/block/parsing/attributes/scanner.ts +75 -0
  236. package/src/parser/rules/block/parsing/attributes/values.ts +26 -0
  237. package/src/parser/rules/block/parsing/block-item.ts +29 -0
  238. package/src/parser/rules/block/parsing/content.ts +127 -0
  239. package/src/parser/rules/block/parsing/end-condition.ts +51 -0
  240. package/src/parser/rules/block/parsing/inline-content.ts +105 -0
  241. package/src/parser/rules/block/parsing/inline-newline.ts +41 -0
  242. package/src/parser/rules/block/parsing/non-boundary.ts +24 -0
  243. package/src/parser/rules/block/parsing/rule-dispatch.ts +44 -0
  244. package/src/parser/rules/block/table/index.ts +80 -0
  245. package/src/parser/rules/block/table/pipe/cell-start.ts +69 -0
  246. package/src/parser/rules/block/table/pipe/cell.ts +106 -0
  247. package/src/parser/rules/block/table/pipe/index.ts +2 -0
  248. package/src/parser/rules/block/table/pipe/row.ts +88 -0
  249. package/src/parser/rules/block/table/pipe/tokens.ts +14 -0
  250. package/src/parser/rules/block/table/pipe/trim.ts +50 -0
  251. package/src/parser/rules/block/table-block/body.ts +79 -0
  252. package/src/parser/rules/block/table-block/cell-attributes.ts +33 -0
  253. package/src/parser/rules/block/table-block/cell-boundary.ts +99 -0
  254. package/src/parser/rules/block/table-block/cell-content/index.ts +88 -0
  255. package/src/parser/rules/block/table-block/cell-content/segments.ts +134 -0
  256. package/src/parser/rules/block/table-block/cell-newline.ts +47 -0
  257. package/src/parser/rules/block/table-block/cell.ts +64 -0
  258. package/src/parser/rules/block/table-block/index.ts +113 -0
  259. package/src/parser/rules/block/table-block/row-boundary.ts +75 -0
  260. package/src/parser/rules/block/table-block/structure.ts +80 -0
  261. package/src/parser/rules/block/tabview/body.ts +64 -0
  262. package/src/parser/rules/block/tabview/index.ts +90 -0
  263. package/src/parser/rules/block/tabview/open.ts +50 -0
  264. package/src/parser/rules/block/tabview/tab.ts +92 -0
  265. package/src/parser/rules/block/tabview/tags.ts +30 -0
  266. package/src/parser/rules/block/toc/element.ts +11 -0
  267. package/src/parser/rules/block/toc/index.ts +44 -0
  268. package/src/parser/rules/block/toc/open.ts +84 -0
  269. package/src/parser/rules/block/utils.ts +10 -610
  270. package/src/parser/rules/{utils.ts → common/attribute-safety.ts} +3 -49
  271. package/src/parser/rules/common/block-name.ts +33 -0
  272. package/src/parser/rules/common/index.ts +2 -0
  273. package/src/parser/rules/contracts/index.ts +3 -0
  274. package/src/parser/rules/contracts/parse-context.ts +38 -0
  275. package/src/parser/rules/contracts/rule.ts +43 -0
  276. package/src/parser/rules/contracts/scope.ts +31 -0
  277. package/src/parser/rules/inline/anchor/attributes.ts +54 -0
  278. package/src/parser/rules/inline/anchor/child.ts +26 -0
  279. package/src/parser/rules/inline/anchor/close.ts +34 -0
  280. package/src/parser/rules/inline/anchor/content.ts +59 -0
  281. package/src/parser/rules/inline/anchor/index.ts +103 -0
  282. package/src/parser/rules/inline/anchor/newline.ts +26 -0
  283. package/src/parser/rules/inline/anchor/open.ts +47 -0
  284. package/src/parser/rules/inline/anchor/paragraph-strip.ts +14 -0
  285. package/src/parser/rules/inline/anchor/syntax.ts +40 -0
  286. package/src/parser/rules/inline/anchor-name/index.ts +38 -0
  287. package/src/parser/rules/inline/anchor-name/name.ts +39 -0
  288. package/src/parser/rules/inline/anchor-name/syntax.ts +46 -0
  289. package/src/parser/rules/inline/bibcite/element.ts +14 -0
  290. package/src/parser/rules/inline/bibcite/index.ts +34 -0
  291. package/src/parser/rules/inline/bibcite/syntax.ts +64 -0
  292. package/src/parser/rules/inline/bold.ts +2 -39
  293. package/src/parser/rules/inline/color/index.ts +35 -0
  294. package/src/parser/rules/inline/color/syntax.ts +69 -0
  295. package/src/parser/rules/inline/comment/consume.ts +31 -0
  296. package/src/parser/rules/inline/{comment.ts → comment/index.ts} +10 -36
  297. package/src/parser/rules/inline/equation-ref/element.ts +8 -0
  298. package/src/parser/rules/inline/equation-ref/index.ts +34 -0
  299. package/src/parser/rules/inline/equation-ref/syntax.ts +45 -0
  300. package/src/parser/rules/inline/expr/branch.ts +104 -0
  301. package/src/parser/rules/inline/expr/conditional-branch.ts +27 -0
  302. package/src/parser/rules/inline/expr/conditional.ts +80 -0
  303. package/src/parser/rules/inline/expr/depth.ts +25 -0
  304. package/src/parser/rules/inline/expr/elements.ts +39 -0
  305. package/src/parser/rules/inline/expr/index.ts +84 -0
  306. package/src/parser/rules/inline/expr/syntax.ts +45 -0
  307. package/src/parser/rules/inline/footnote/child.ts +22 -0
  308. package/src/parser/rules/inline/footnote/close.ts +33 -0
  309. package/src/parser/rules/inline/footnote/content.ts +54 -0
  310. package/src/parser/rules/inline/footnote/elements.ts +38 -0
  311. package/src/parser/rules/inline/footnote/index.ts +54 -0
  312. package/src/parser/rules/inline/footnote/newline.ts +27 -0
  313. package/src/parser/rules/inline/footnote/open.ts +38 -0
  314. package/src/parser/rules/inline/formatting/container.ts +50 -0
  315. package/src/parser/rules/inline/{guillemet.ts → guillemet/index.ts} +5 -13
  316. package/src/parser/rules/inline/guillemet/text.ts +11 -0
  317. package/src/parser/rules/inline/html/gate.ts +64 -0
  318. package/src/parser/rules/inline/{html.ts → html/index.ts} +9 -60
  319. package/src/parser/rules/inline/html/open.ts +37 -0
  320. package/src/parser/rules/inline/image/attributes.ts +22 -0
  321. package/src/parser/rules/inline/image/body.ts +36 -0
  322. package/src/parser/rules/inline/image/index.ts +89 -0
  323. package/src/parser/rules/inline/image/open.ts +56 -0
  324. package/src/parser/rules/inline/image/source.ts +62 -0
  325. package/src/parser/rules/inline/image/syntax.ts +76 -0
  326. package/src/parser/rules/inline/italic.ts +2 -30
  327. package/src/parser/rules/inline/line-break/backslash.ts +58 -0
  328. package/src/parser/rules/inline/line-break/elements.ts +9 -0
  329. package/src/parser/rules/inline/line-break/index.ts +3 -0
  330. package/src/parser/rules/inline/line-break/newline.ts +82 -0
  331. package/src/parser/rules/inline/line-break/underscore.ts +45 -0
  332. package/src/parser/rules/inline/link-anchor.ts +6 -81
  333. package/src/parser/rules/inline/link-bracket/anchor.ts +3 -0
  334. package/src/parser/rules/inline/link-bracket/direct-url.ts +5 -0
  335. package/src/parser/rules/inline/link-bracket/parsed.ts +81 -0
  336. package/src/parser/rules/inline/link-bracket/parts.ts +64 -0
  337. package/src/parser/rules/inline/link-bracket/prefix.ts +15 -0
  338. package/src/parser/rules/inline/link-single.ts +7 -98
  339. package/src/parser/rules/inline/link-star.ts +7 -69
  340. package/src/parser/rules/inline/link-triple/fallback.ts +10 -0
  341. package/src/parser/rules/inline/link-triple/index.ts +62 -0
  342. package/src/parser/rules/inline/link-triple/interwiki.ts +11 -0
  343. package/src/parser/rules/inline/link-triple/label.ts +35 -0
  344. package/src/parser/rules/inline/link-triple/syntax.ts +72 -0
  345. package/src/parser/rules/inline/link-triple/target.ts +36 -0
  346. package/src/parser/rules/inline/math-inline/index.ts +40 -0
  347. package/src/parser/rules/inline/math-inline/syntax.ts +55 -0
  348. package/src/parser/rules/inline/monospace.ts +2 -30
  349. package/src/parser/rules/inline/parsing/block-boundary.ts +42 -0
  350. package/src/parser/rules/inline/parsing/block-start-predicates.ts +117 -0
  351. package/src/parser/rules/inline/parsing/collect.ts +23 -0
  352. package/src/parser/rules/inline/parsing/inline-content.ts +115 -0
  353. package/src/parser/rules/inline/parsing/paragraph-boundary.ts +47 -0
  354. package/src/parser/rules/inline/parsing/plain-text.ts +69 -0
  355. package/src/parser/rules/inline/parsing/preserved-line-break.ts +11 -0
  356. package/src/parser/rules/inline/parsing/rules.ts +34 -0
  357. package/src/parser/rules/inline/parsing/simple-token.ts +26 -0
  358. package/src/parser/rules/inline/raw/angle.ts +40 -0
  359. package/src/parser/rules/inline/raw/double-at.ts +78 -0
  360. package/src/parser/rules/inline/raw/index.ts +26 -0
  361. package/src/parser/rules/inline/raw/result.ts +26 -0
  362. package/src/parser/rules/inline/size/content.ts +65 -0
  363. package/src/parser/rules/inline/size/index.ts +55 -0
  364. package/src/parser/rules/inline/size/open.ts +43 -0
  365. package/src/parser/rules/inline/size/value.ts +45 -0
  366. package/src/parser/rules/inline/span/content.ts +97 -0
  367. package/src/parser/rules/inline/span/elements.ts +108 -0
  368. package/src/parser/rules/inline/span/index.ts +79 -0
  369. package/src/parser/rules/inline/span/newline.ts +50 -0
  370. package/src/parser/rules/inline/span/syntax.ts +70 -0
  371. package/src/parser/rules/inline/{strikethrough.ts → strikethrough/index.ts} +5 -60
  372. package/src/parser/rules/inline/strikethrough/parse.ts +14 -0
  373. package/src/parser/rules/inline/strikethrough/syntax.ts +24 -0
  374. package/src/parser/rules/inline/subscript.ts +2 -39
  375. package/src/parser/rules/inline/superscript.ts +4 -39
  376. package/src/parser/rules/inline/text/element.ts +5 -0
  377. package/src/parser/rules/inline/{text.ts → text/index.ts} +5 -4
  378. package/src/parser/rules/inline/underline/child.ts +26 -0
  379. package/src/parser/rules/inline/underline/content.ts +29 -0
  380. package/src/parser/rules/inline/{underline.ts → underline/index.ts} +6 -49
  381. package/src/parser/rules/inline/user/element.ts +11 -0
  382. package/src/parser/rules/inline/user/index.ts +34 -0
  383. package/src/parser/rules/inline/user/syntax.ts +67 -0
  384. package/src/parser/rules/inline/utils.ts +4 -344
  385. package/src/parser/rules/tokens.ts +106 -0
  386. package/src/parser/rules/types.ts +9 -252
  387. package/src/parser/depth.ts +0 -251
  388. package/src/parser/parse.ts +0 -315
  389. package/src/parser/postprocess/spanStrip.ts +0 -697
  390. package/src/parser/preprocess/expr.ts +0 -265
  391. package/src/parser/preprocess/utils.ts +0 -250
  392. package/src/parser/preprocess/whitespace.ts +0 -111
  393. package/src/parser/rules/block/align.ts +0 -282
  394. package/src/parser/rules/block/bibliography.ts +0 -359
  395. package/src/parser/rules/block/block-list.ts +0 -689
  396. package/src/parser/rules/block/blockquote.ts +0 -238
  397. package/src/parser/rules/block/code.ts +0 -187
  398. package/src/parser/rules/block/collapsible.ts +0 -337
  399. package/src/parser/rules/block/definition-list.ts +0 -270
  400. package/src/parser/rules/block/div.ts +0 -400
  401. package/src/parser/rules/block/embed-block.ts +0 -153
  402. package/src/parser/rules/block/footnoteblock.ts +0 -200
  403. package/src/parser/rules/block/heading.ts +0 -142
  404. package/src/parser/rules/block/html.ts +0 -222
  405. package/src/parser/rules/block/iframe.ts +0 -239
  406. package/src/parser/rules/block/include.ts +0 -179
  407. package/src/parser/rules/block/list.ts +0 -244
  408. package/src/parser/rules/block/math.ts +0 -183
  409. package/src/parser/rules/block/module/include/resolve.ts +0 -556
  410. package/src/parser/rules/block/module/listpages/types.ts +0 -513
  411. package/src/parser/rules/block/module/walk.ts +0 -380
  412. package/src/parser/rules/block/module.ts +0 -164
  413. package/src/parser/rules/block/orphan-li.ts +0 -177
  414. package/src/parser/rules/block/paragraph.ts +0 -157
  415. package/src/parser/rules/block/table-block.ts +0 -726
  416. package/src/parser/rules/block/table.ts +0 -441
  417. package/src/parser/rules/block/tabview.ts +0 -331
  418. package/src/parser/rules/block/toc.ts +0 -129
  419. package/src/parser/rules/inline/anchor-name.ts +0 -154
  420. package/src/parser/rules/inline/anchor.ts +0 -327
  421. package/src/parser/rules/inline/bibcite.ts +0 -153
  422. package/src/parser/rules/inline/color.ts +0 -140
  423. package/src/parser/rules/inline/equation-ref.ts +0 -115
  424. package/src/parser/rules/inline/expr.ts +0 -526
  425. package/src/parser/rules/inline/footnote.ts +0 -223
  426. package/src/parser/rules/inline/image.ts +0 -328
  427. package/src/parser/rules/inline/line-break.ts +0 -326
  428. package/src/parser/rules/inline/link-triple.ts +0 -267
  429. package/src/parser/rules/inline/math-inline.ts +0 -126
  430. package/src/parser/rules/inline/raw.ts +0 -262
  431. package/src/parser/rules/inline/size.ts +0 -244
  432. package/src/parser/rules/inline/span.ts +0 -424
  433. package/src/parser/rules/inline/user.ts +0 -147
@@ -20,78 +20,20 @@
20
20
  * @module
21
21
  */
22
22
 
23
- import type { SyntaxTree, Module } from "@wdprlib/ast";
24
- import type {
25
- DataRequirements,
26
- ListPagesQuery,
27
- ListPagesVariable,
28
- CompiledTemplate,
29
- } from "./types";
30
- import type { ListUsersCompiledTemplate } from "../listusers/types";
31
- import { compileTemplate } from "./compiler";
32
- import { extractListUsersVariables, compileListUsersTemplate } from "../listusers/extract";
23
+ import type { SyntaxTree } from "@wdprlib/ast";
33
24
  import { walkElements } from "../walk";
34
-
35
- /**
36
- * Type guard to narrow a Module union to the list-pages variant.
37
- *
38
- * @param module - A Module discriminated union value
39
- * @returns true if the module is a list-pages module
40
- */
41
- function isListPagesModule(module: Module): module is Extract<Module, { module: "list-pages" }> {
42
- return module.module === "list-pages";
43
- }
44
-
45
- /**
46
- * Regex pattern for matching ListPages template variables.
47
- *
48
- * Matches `%%name%%`, `%%name{param}%%`, `%%name(param)%%`, and `%%name|format%%`.
49
- * The captured groups are: [1] variable name, [2] brace parameter, [3] paren parameter,
50
- * [4] format/pipe parameter.
51
- */
52
- const VARIABLE_REGEX = /%%([a-z_]+)(?:\{([^}]+)\})?(?:\((\d+)\))?(?:\|([^%]+))?%%/gi;
53
-
54
- /**
55
- * Default template used when a ListPages module has no body specified.
56
- * This matches Wikidot's built-in default template that shows title, author, date, and summary.
57
- */
58
- const DEFAULT_BODY_TEMPLATE = `+ %%title_linked%%
59
-
60
- by %%created_by_linked%% %%created_at%%
61
-
62
- %%summary%%`;
63
-
64
- /**
65
- * Complete result of extracting data requirements from an AST.
66
- *
67
- * Contains everything needed to fetch external data and then resolve modules:
68
- * the data requirements tell the application what to fetch, and the pre-compiled
69
- * templates are used during the resolution phase to efficiently render results.
70
- */
71
- export interface ExtractionResult {
72
- /** Data requirements for external fetching */
73
- requirements: DataRequirements;
74
- /** Pre-compiled ListPages templates keyed by module id */
75
- compiledListPagesTemplates: Map<number, CompiledTemplate>;
76
- /** Pre-compiled ListUsers templates keyed by module id */
77
- compiledListUsersTemplates: Map<number, ListUsersCompiledTemplate>;
78
- }
79
-
80
- /**
81
- * Narrowed type for the list-pages variant of the Module union.
82
- * Used internally for type-safe access to list-pages-specific fields.
83
- */
84
- type ListPagesModuleData = Extract<Module, { module: "list-pages" }>;
85
-
86
- /**
87
- * Type guard to narrow a Module union to the list-users variant.
88
- *
89
- * @param module - A Module discriminated union value
90
- * @returns true if the module is a list-users module
91
- */
92
- function isListUsersModule(module: Module): module is Extract<Module, { module: "list-users" }> {
93
- return module.module === "list-users";
94
- }
25
+ import {
26
+ extractListPagesModule,
27
+ isListPagesModule,
28
+ type ListPagesExtractionState,
29
+ } from "./extraction/listpages";
30
+ import {
31
+ extractListUsersModule,
32
+ isListUsersModule,
33
+ type ListUsersExtractionState,
34
+ } from "./extraction/listusers";
35
+ import type { ExtractionResult } from "./extraction/result";
36
+ export type { ExtractionResult } from "./extraction/result";
95
37
 
96
38
  /**
97
39
  * Extract all data requirements from a parsed AST.
@@ -108,303 +50,27 @@ function isListUsersModule(module: Module): module is Extract<Module, { module:
108
50
  * @returns Extraction result containing requirements and compiled templates
109
51
  */
110
52
  export function extractDataRequirements(ast: SyntaxTree): ExtractionResult {
111
- const requirements: DataRequirements = {
112
- listPages: [],
113
- listUsers: [],
53
+ const result: ExtractionResult = {
54
+ requirements: {
55
+ listPages: [],
56
+ listUsers: [],
57
+ },
58
+ compiledListPagesTemplates: new Map(),
59
+ compiledListUsersTemplates: new Map(),
114
60
  };
115
- const compiledListPagesTemplates = new Map<number, CompiledTemplate>();
116
- const compiledListUsersTemplates = new Map<number, ListUsersCompiledTemplate>();
117
61
 
118
- let listPagesIdCounter = 0;
119
- let listUsersIdCounter = 0;
62
+ const listPagesState: ListPagesExtractionState = { nextId: 0 };
63
+ const listUsersState: ListUsersExtractionState = { nextId: 0 };
120
64
 
121
65
  walkElements(ast.elements, (element) => {
122
66
  if (element.element !== "module") return;
123
67
 
124
68
  if (isListPagesModule(element.data)) {
125
- const listPages = element.data;
126
- const id = listPagesIdCounter++;
127
-
128
- // Get body template (use Wikidot default when not specified)
129
- const body = listPages.body ?? DEFAULT_BODY_TEMPLATE;
130
-
131
- // Extract needed variables from template
132
- const extraction = extractVariablesFromTemplate(body);
133
-
134
- // Build query from module parameters
135
- const query = buildQuery(listPages);
136
-
137
- // Get urlAttrPrefix from parsed module data (kebab-case key)
138
- const urlAttrPrefix = listPages["url-attr-prefix"];
139
-
140
- // All raw attributes (for @URL resolution by external apps)
141
- const rawAttributes = listPages.attributes ?? {};
142
-
143
- requirements.listPages.push({
144
- id,
145
- query,
146
- neededVariables: extraction.variables,
147
- contentSectionIndices: extraction.contentIndices,
148
- previewLengths: extraction.previewLengths,
149
- formFields: extraction.formFields,
150
- tagsLinkPrefix: extraction.tagsLinkPrefix,
151
- hiddenTagsLinkPrefix: extraction.hiddenTagsLinkPrefix,
152
- urlAttrPrefix,
153
- rawAttributes,
154
- });
155
-
156
- // Compile template
157
- compiledListPagesTemplates.set(id, compileTemplate(body));
69
+ extractListPagesModule(element.data, listPagesState, result);
158
70
  } else if (isListUsersModule(element.data)) {
159
- const listUsers = element.data;
160
- const id = listUsersIdCounter++;
161
- const body = listUsers.body ?? "";
162
-
163
- const neededVariables = extractListUsersVariables(body);
164
-
165
- requirements.listUsers.push({
166
- id,
167
- users: listUsers.users,
168
- neededVariables,
169
- });
170
-
171
- compiledListUsersTemplates.set(id, compileListUsersTemplate(body));
71
+ extractListUsersModule(element.data, listUsersState, result);
172
72
  }
173
73
  });
174
74
 
175
- return { requirements, compiledListPagesTemplates, compiledListUsersTemplates };
176
- }
177
-
178
- /**
179
- * Build a ListPagesQuery from the parsed module attributes.
180
- *
181
- * Maps module attribute names (which use kebab-case in the AST) to the
182
- * query's camelCase property names. Also extracts data form fields
183
- * (attributes prefixed with `_`) into a separate record.
184
- *
185
- * @param module - Parsed list-pages module data from the AST
186
- * @returns Query parameters ready for normalization and external fetching
187
- */
188
- function buildQuery(module: ListPagesModuleData): ListPagesQuery {
189
- return {
190
- pagetype: module.pagetype as ListPagesQuery["pagetype"],
191
- category: module.category,
192
- tags: module.tags,
193
- parent: module.parent,
194
- linkTo: module["link-to"],
195
- createdAt: module["created-at"],
196
- updatedAt: module["updated-at"],
197
- createdBy: module["created-by"],
198
- rating: module.rating,
199
- votes: module.votes,
200
- name: module.name,
201
- fullname: module.fullname,
202
- range: module.range as ListPagesQuery["range"],
203
- order: module.order,
204
- offset: module.offset,
205
- limit: module.limit,
206
- perPage: module["per-page"],
207
- reverse: module.reverse,
208
- // dataFormFields is extracted from attributes prefixed with _
209
- dataFormFields: extractDataFormFields(module.attributes),
210
- };
211
- }
212
-
213
- /**
214
- * Extract data form field selectors from module attributes.
215
- *
216
- * Wikidot's ListPages supports filtering by data form fields using attribute
217
- * names prefixed with `_` (e.g., `_color="red"`). The prefix is stripped from
218
- * the key in the returned record.
219
- *
220
- * @param attributes - Raw module attributes
221
- * @returns Record of field name to value (without `_` prefix), or undefined if no fields found
222
- */
223
- function extractDataFormFields(
224
- attributes: Record<string, string>,
225
- ): Record<string, string> | undefined {
226
- const fields: Record<string, string> = {};
227
- let hasFields = false;
228
-
229
- for (const [key, value] of Object.entries(attributes)) {
230
- if (key.startsWith("_")) {
231
- fields[key.slice(1)] = value;
232
- hasFields = true;
233
- }
234
- }
235
-
236
- return hasFields ? fields : undefined;
237
- }
238
-
239
- /**
240
- * Internal result of analyzing a ListPages template string for variable usage.
241
- */
242
- interface TemplateExtraction {
243
- variables: ListPagesVariable[];
244
- contentIndices: number[];
245
- previewLengths: number[];
246
- formFields: string[];
247
- tagsLinkPrefix?: string;
248
- hiddenTagsLinkPrefix?: string;
249
- }
250
-
251
- /**
252
- * Extract all variable references from a ListPages template string.
253
- *
254
- * Scans the template for `%%variable%%` patterns and categorizes them:
255
- * - Simple variables (e.g., `%%title%%`, `%%created_at%%`)
256
- * - Parameterized variables (e.g., `%%content{2}%%`, `%%form_data{color}%%`)
257
- * - Preview with length (e.g., `%%preview(100)%%`)
258
- * - Tags with prefix (e.g., `%%tags_linked|/tag/%%`)
259
- *
260
- * @param template - The template string to analyze
261
- * @returns Structured extraction result with categorized variable information
262
- */
263
- function extractVariablesFromTemplate(template: string): TemplateExtraction {
264
- const variables = new Set<ListPagesVariable>();
265
- const contentIndices = new Set<number>();
266
- const previewLengths = new Set<number>();
267
- const formFields = new Set<string>();
268
- let tagsLinkPrefix: string | undefined;
269
- let hiddenTagsLinkPrefix: string | undefined;
270
-
271
- for (const match of template.matchAll(VARIABLE_REGEX)) {
272
- const [, name, braceParam, parenParam, format] = match;
273
- if (!name) continue;
274
- const varName = name.toLowerCase();
275
-
276
- // Handle parameterized variables
277
- if (braceParam !== undefined) {
278
- switch (varName) {
279
- case "content":
280
- contentIndices.add(Number(braceParam));
281
- variables.add("content_n");
282
- continue;
283
- case "form_data":
284
- formFields.add(braceParam);
285
- variables.add("form_data");
286
- continue;
287
- case "form_raw":
288
- formFields.add(braceParam);
289
- variables.add("form_raw");
290
- continue;
291
- case "form_label":
292
- formFields.add(braceParam);
293
- variables.add("form_label");
294
- continue;
295
- case "form_hint":
296
- formFields.add(braceParam);
297
- variables.add("form_hint");
298
- continue;
299
- }
300
- }
301
-
302
- if (parenParam !== undefined && varName === "preview") {
303
- previewLengths.add(Number(parenParam));
304
- variables.add("preview_n");
305
- continue;
306
- }
307
-
308
- // Handle tags_linked with prefix
309
- if (varName === "tags_linked") {
310
- if (format) tagsLinkPrefix = format;
311
- variables.add("tags_linked");
312
- continue;
313
- }
314
- if (varName === "_tags_linked") {
315
- if (format) hiddenTagsLinkPrefix = format;
316
- variables.add("_tags_linked");
317
- continue;
318
- }
319
-
320
- // Normalize and add variable
321
- const normalized = normalizeVariableName(varName);
322
- if (normalized) {
323
- variables.add(normalized);
324
- }
325
- }
326
-
327
- return {
328
- variables: Array.from(variables),
329
- contentIndices: Array.from(contentIndices).sort((a, b) => a - b),
330
- previewLengths: Array.from(previewLengths).sort((a, b) => a - b),
331
- formFields: Array.from(formFields).sort(),
332
- tagsLinkPrefix,
333
- hiddenTagsLinkPrefix,
334
- };
335
- }
336
-
337
- /**
338
- * Normalize a variable name to its canonical `ListPagesVariable` form.
339
- *
340
- * Only known variable names are accepted. Unknown names return null,
341
- * causing them to be silently ignored (matching Wikidot's behavior of
342
- * rendering unknown variables as empty strings).
343
- *
344
- * @param name - Lowercase variable name extracted from the template
345
- * @returns The canonical variable name, or null if not recognized
346
- */
347
- function normalizeVariableName(name: string): ListPagesVariable | null {
348
- // Direct mapping for known variables
349
- const knownVariables: ListPagesVariable[] = [
350
- // Lifecycle
351
- "created_at",
352
- "created_by",
353
- "created_by_unix",
354
- "created_by_id",
355
- "created_by_linked",
356
- "updated_at",
357
- "updated_by",
358
- "updated_by_unix",
359
- "updated_by_id",
360
- "updated_by_linked",
361
- "commented_at",
362
- "commented_by",
363
- "commented_by_unix",
364
- "commented_by_id",
365
- "commented_by_linked",
366
- // Structure
367
- "name",
368
- "category",
369
- "fullname",
370
- "title",
371
- "title_linked",
372
- "link",
373
- "parent_name",
374
- "parent_category",
375
- "parent_fullname",
376
- "parent_title",
377
- "parent_title_linked",
378
- // Content
379
- "content",
380
- "preview",
381
- "summary",
382
- "first_paragraph",
383
- // Tags
384
- "tags",
385
- "_tags",
386
- // Metrics
387
- "children",
388
- "comments",
389
- "size",
390
- "rating",
391
- "rating_votes",
392
- "rating_percent",
393
- "revisions",
394
- // Pagination
395
- "index",
396
- "total",
397
- "limit",
398
- "total_or_limit",
399
- // Site
400
- "site_title",
401
- "site_name",
402
- "site_domain",
403
- ];
404
-
405
- if (knownVariables.includes(name as ListPagesVariable)) {
406
- return name as ListPagesVariable;
407
- }
408
-
409
- return null;
75
+ return result;
410
76
  }
@@ -0,0 +1,42 @@
1
+ import type { Module } from "@wdprlib/ast";
2
+ import type { ListPagesQuery } from "../types";
3
+ import { compileTemplate } from "../compiler";
4
+ import { buildQuery } from "./query";
5
+ import { DEFAULT_BODY_TEMPLATE, extractVariablesFromTemplate } from "./template";
6
+ import type { ExtractionResult } from "./result";
7
+
8
+ export type ListPagesModuleForExtraction = Extract<Module, { module: "list-pages" }>;
9
+
10
+ export interface ListPagesExtractionState {
11
+ nextId: number;
12
+ }
13
+
14
+ export function isListPagesModule(module: Module): module is ListPagesModuleForExtraction {
15
+ return module.module === "list-pages";
16
+ }
17
+
18
+ export function extractListPagesModule(
19
+ listPages: ListPagesModuleForExtraction,
20
+ state: ListPagesExtractionState,
21
+ result: ExtractionResult,
22
+ ): void {
23
+ const id = state.nextId++;
24
+ const body = listPages.body ?? DEFAULT_BODY_TEMPLATE;
25
+ const extraction = extractVariablesFromTemplate(body);
26
+ const query: ListPagesQuery = buildQuery(listPages);
27
+
28
+ result.requirements.listPages.push({
29
+ id,
30
+ query,
31
+ neededVariables: extraction.variables,
32
+ contentSectionIndices: extraction.contentIndices,
33
+ previewLengths: extraction.previewLengths,
34
+ formFields: extraction.formFields,
35
+ tagsLinkPrefix: extraction.tagsLinkPrefix,
36
+ hiddenTagsLinkPrefix: extraction.hiddenTagsLinkPrefix,
37
+ urlAttrPrefix: listPages["url-attr-prefix"],
38
+ rawAttributes: listPages.attributes ?? {},
39
+ });
40
+
41
+ result.compiledListPagesTemplates.set(id, compileTemplate(body));
42
+ }
@@ -0,0 +1,30 @@
1
+ import type { Module } from "@wdprlib/ast";
2
+ import { compileListUsersTemplate, extractListUsersVariables } from "../../listusers/extract";
3
+ import type { ExtractionResult } from "./result";
4
+
5
+ export type ListUsersModuleForExtraction = Extract<Module, { module: "list-users" }>;
6
+
7
+ export interface ListUsersExtractionState {
8
+ nextId: number;
9
+ }
10
+
11
+ export function isListUsersModule(module: Module): module is ListUsersModuleForExtraction {
12
+ return module.module === "list-users";
13
+ }
14
+
15
+ export function extractListUsersModule(
16
+ listUsers: ListUsersModuleForExtraction,
17
+ state: ListUsersExtractionState,
18
+ result: ExtractionResult,
19
+ ): void {
20
+ const id = state.nextId++;
21
+ const body = listUsers.body ?? "";
22
+
23
+ result.requirements.listUsers.push({
24
+ id,
25
+ users: listUsers.users,
26
+ neededVariables: extractListUsersVariables(body),
27
+ });
28
+
29
+ result.compiledListUsersTemplates.set(id, compileListUsersTemplate(body));
30
+ }
@@ -0,0 +1,51 @@
1
+ import type { Module } from "@wdprlib/ast";
2
+ import type { ListPagesQuery } from "../types";
3
+
4
+ type ListPagesModuleData = Extract<Module, { module: "list-pages" }>;
5
+
6
+ /**
7
+ * Build a ListPagesQuery from the parsed module attributes.
8
+ *
9
+ * Maps module attribute names, which use kebab-case in the AST, to the query's
10
+ * camelCase property names. Data form fields prefixed with `_` are grouped under
11
+ * `dataFormFields`.
12
+ */
13
+ export function buildQuery(module: ListPagesModuleData): ListPagesQuery {
14
+ return {
15
+ pagetype: module.pagetype as ListPagesQuery["pagetype"],
16
+ category: module.category,
17
+ tags: module.tags,
18
+ parent: module.parent,
19
+ linkTo: module["link-to"],
20
+ createdAt: module["created-at"],
21
+ updatedAt: module["updated-at"],
22
+ createdBy: module["created-by"],
23
+ rating: module.rating,
24
+ votes: module.votes,
25
+ name: module.name,
26
+ fullname: module.fullname,
27
+ range: module.range as ListPagesQuery["range"],
28
+ order: module.order,
29
+ offset: module.offset,
30
+ limit: module.limit,
31
+ perPage: module["per-page"],
32
+ reverse: module.reverse,
33
+ dataFormFields: extractDataFormFields(module.attributes),
34
+ };
35
+ }
36
+
37
+ function extractDataFormFields(
38
+ attributes: Record<string, string>,
39
+ ): Record<string, string> | undefined {
40
+ const fields: Record<string, string> = {};
41
+ let hasFields = false;
42
+
43
+ for (const [key, value] of Object.entries(attributes)) {
44
+ if (key.startsWith("_")) {
45
+ fields[key.slice(1)] = value;
46
+ hasFields = true;
47
+ }
48
+ }
49
+
50
+ return hasFields ? fields : undefined;
51
+ }
@@ -0,0 +1,18 @@
1
+ import type { DataRequirements, CompiledTemplate } from "../types";
2
+ import type { ListUsersCompiledTemplate } from "../../listusers/types";
3
+
4
+ /**
5
+ * Complete result of extracting data requirements from an AST.
6
+ *
7
+ * Contains everything needed to fetch external data and then resolve modules:
8
+ * the data requirements tell the application what to fetch, and the pre-compiled
9
+ * templates are used during the resolution phase to efficiently render results.
10
+ */
11
+ export interface ExtractionResult {
12
+ /** Data requirements for external fetching */
13
+ requirements: DataRequirements;
14
+ /** Pre-compiled ListPages templates keyed by module id */
15
+ compiledListPagesTemplates: Map<number, CompiledTemplate>;
16
+ /** Pre-compiled ListUsers templates keyed by module id */
17
+ compiledListUsersTemplates: Map<number, ListUsersCompiledTemplate>;
18
+ }
@@ -0,0 +1,96 @@
1
+ import type { ListPagesVariable } from "../types";
2
+ import { scanTemplateVariables } from "../template/syntax";
3
+ import { normalizeVariableName } from "./variables";
4
+
5
+ /**
6
+ * Default template used when a ListPages module has no body specified.
7
+ */
8
+ export const DEFAULT_BODY_TEMPLATE = `+ %%title_linked%%
9
+
10
+ by %%created_by_linked%% %%created_at%%
11
+
12
+ %%summary%%`;
13
+
14
+ /**
15
+ * Internal result of analyzing a ListPages template string for variable usage.
16
+ */
17
+ export interface TemplateExtraction {
18
+ variables: ListPagesVariable[];
19
+ contentIndices: number[];
20
+ previewLengths: number[];
21
+ formFields: string[];
22
+ tagsLinkPrefix?: string;
23
+ hiddenTagsLinkPrefix?: string;
24
+ }
25
+
26
+ /**
27
+ * Extract all variable references from a ListPages template string.
28
+ */
29
+ export function extractVariablesFromTemplate(template: string): TemplateExtraction {
30
+ const variables = new Set<ListPagesVariable>();
31
+ const contentIndices = new Set<number>();
32
+ const previewLengths = new Set<number>();
33
+ const formFields = new Set<string>();
34
+ let tagsLinkPrefix: string | undefined;
35
+ let hiddenTagsLinkPrefix: string | undefined;
36
+
37
+ for (const match of scanTemplateVariables(template)) {
38
+ const varName = match.name.toLowerCase();
39
+
40
+ if (match.braceParam !== undefined) {
41
+ switch (varName) {
42
+ case "content":
43
+ contentIndices.add(Number(match.braceParam));
44
+ variables.add("content_n");
45
+ continue;
46
+ case "form_data":
47
+ formFields.add(match.braceParam);
48
+ variables.add("form_data");
49
+ continue;
50
+ case "form_raw":
51
+ formFields.add(match.braceParam);
52
+ variables.add("form_raw");
53
+ continue;
54
+ case "form_label":
55
+ formFields.add(match.braceParam);
56
+ variables.add("form_label");
57
+ continue;
58
+ case "form_hint":
59
+ formFields.add(match.braceParam);
60
+ variables.add("form_hint");
61
+ continue;
62
+ }
63
+ }
64
+
65
+ if (match.parenParam !== undefined && varName === "preview") {
66
+ previewLengths.add(Number(match.parenParam));
67
+ variables.add("preview_n");
68
+ continue;
69
+ }
70
+
71
+ if (varName === "tags_linked") {
72
+ if (match.format) tagsLinkPrefix = match.format;
73
+ variables.add("tags_linked");
74
+ continue;
75
+ }
76
+ if (varName === "_tags_linked") {
77
+ if (match.format) hiddenTagsLinkPrefix = match.format;
78
+ variables.add("_tags_linked");
79
+ continue;
80
+ }
81
+
82
+ const normalized = normalizeVariableName(varName);
83
+ if (normalized) {
84
+ variables.add(normalized);
85
+ }
86
+ }
87
+
88
+ return {
89
+ variables: Array.from(variables),
90
+ contentIndices: Array.from(contentIndices).sort((a, b) => a - b),
91
+ previewLengths: Array.from(previewLengths).sort((a, b) => a - b),
92
+ formFields: Array.from(formFields).sort(),
93
+ tagsLinkPrefix,
94
+ hiddenTagsLinkPrefix,
95
+ };
96
+ }