@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
@@ -0,0 +1,107 @@
1
+ import type { Element } from "@wdprlib/ast";
2
+ import { mapElementChildrenWithState } from "../walk";
3
+ import { isIfTagsElement, resolveIfTags, type IfTagsData } from "../iftags/resolve";
4
+ import type { ListPagesContext, ListUsersContext } from "./contexts";
5
+ import { countDynamicModules, resolveDynamicModuleElement } from "./dynamic-modules";
6
+
7
+ /**
8
+ * Resolution context passed through AST traversal.
9
+ */
10
+ export interface WalkContext {
11
+ listPages: ListPagesContext | null;
12
+ listUsers: ListUsersContext | null;
13
+ /** Whether fetchListPages callback was provided, even if no data returned. */
14
+ fetchListPagesProvided: boolean;
15
+ /** Whether fetchListUsers callback was provided, even if no data returned. */
16
+ fetchListUsersProvided: boolean;
17
+ pageTags: string[] | null;
18
+ listPagesIdCounter: number;
19
+ listUsersIdCounter: number;
20
+ }
21
+
22
+ export interface WalkResult {
23
+ elements: Element[];
24
+ nextListPagesId: number;
25
+ nextListUsersId: number;
26
+ }
27
+
28
+ /**
29
+ * Walk AST and resolve modules/iftags.
30
+ */
31
+ export function walkAndResolve(elements: Element[], ctx: WalkContext): WalkResult {
32
+ const result: Element[] = [];
33
+ let listPagesId = ctx.listPagesIdCounter;
34
+ let listUsersId = ctx.listUsersIdCounter;
35
+
36
+ for (const element of elements) {
37
+ const dynamicModule = resolveDynamicModuleElement(element, ctx, { listPagesId, listUsersId });
38
+ if (dynamicModule.handled) {
39
+ result.push(...dynamicModule.elements);
40
+ listPagesId = dynamicModule.ids.listPagesId;
41
+ listUsersId = dynamicModule.ids.listUsersId;
42
+ continue;
43
+ }
44
+
45
+ if (isIfTagsElement(element)) {
46
+ const ifTagsData = element.data as IfTagsData;
47
+ const resolveResult = resolveIfTags(ifTagsData, ctx.pageTags);
48
+
49
+ if (resolveResult.evaluated) {
50
+ if (resolveResult.matched) {
51
+ const childResult = walkAndResolve(ifTagsData.elements, {
52
+ ...ctx,
53
+ listPagesIdCounter: listPagesId,
54
+ listUsersIdCounter: listUsersId,
55
+ });
56
+ result.push(...childResult.elements);
57
+ listPagesId = childResult.nextListPagesId;
58
+ listUsersId = childResult.nextListUsersId;
59
+ } else {
60
+ const counts = countDynamicModules(ifTagsData.elements);
61
+ listPagesId += counts.listPagesId;
62
+ listUsersId += counts.listUsersId;
63
+ }
64
+ } else {
65
+ const childResult = walkAndResolve(ifTagsData.elements, {
66
+ ...ctx,
67
+ listPagesIdCounter: listPagesId,
68
+ listUsersIdCounter: listUsersId,
69
+ });
70
+ result.push({
71
+ element: "if-tags",
72
+ data: {
73
+ ...ifTagsData,
74
+ elements: childResult.elements,
75
+ },
76
+ });
77
+ listPagesId = childResult.nextListPagesId;
78
+ listUsersId = childResult.nextListUsersId;
79
+ }
80
+ continue;
81
+ }
82
+
83
+ const mapped = mapElementChildrenWithState(
84
+ element,
85
+ { listPagesId, listUsersId },
86
+ (children, state) => {
87
+ const childResult = walkAndResolve(children, {
88
+ ...ctx,
89
+ listPagesIdCounter: state.listPagesId,
90
+ listUsersIdCounter: state.listUsersId,
91
+ });
92
+ return {
93
+ elements: childResult.elements,
94
+ state: {
95
+ listPagesId: childResult.nextListPagesId,
96
+ listUsersId: childResult.nextListUsersId,
97
+ },
98
+ };
99
+ },
100
+ );
101
+ result.push(mapped.element);
102
+ listPagesId = mapped.state.listPagesId;
103
+ listUsersId = mapped.state.listUsersId;
104
+ }
105
+
106
+ return { elements: result, nextListPagesId: listPagesId, nextListUsersId: listUsersId };
107
+ }
@@ -16,28 +16,35 @@
16
16
  * @module
17
17
  */
18
18
 
19
- import type { Element, SyntaxTree } from "@wdprlib/ast";
20
- import { STYLE_SLOT_PREFIX } from "@wdprlib/ast";
19
+ import type { SyntaxTree } from "@wdprlib/ast";
21
20
  import type { DataProvider } from "./types-common";
22
- import { walkElements, mapElementChildren, mapElementChildrenWithState } from "./walk";
23
- import type {
24
- ListPagesDataRequirement,
25
- ListPagesExternalData,
26
- CompiledTemplate,
27
- } from "./listpages/types";
28
- import type {
29
- ListUsersDataRequirement,
30
- ListUsersExternalData,
31
- ListUsersCompiledTemplate,
32
- } from "./listusers/types";
33
- import { isListPagesModule, resolveListPages, type ParseFunction } from "./listpages/resolve";
34
- import { isListUsersModule, resolveListUsers } from "./listusers/resolve";
35
- import { isIfTagsElement, resolveIfTags, type IfTagsData } from "./iftags/resolve";
36
- import { parseUrlParams, resolveAndNormalizeQuery } from "./listpages/url-resolver";
21
+ import { resolveIncludes } from "./include";
22
+ import type { ListPagesDataRequirement, CompiledTemplate } from "./listpages/types";
23
+ import type { ListUsersDataRequirement, ListUsersCompiledTemplate } from "./listusers/types";
24
+ import type { ParseFunction } from "./listpages/resolve";
25
+ import { buildListPagesContext, buildListUsersContext } from "./resolution/contexts";
26
+ import { walkAndResolve } from "./resolution/walk-resolve";
27
+ import { collectStyles } from "./resolution/styles";
28
+
29
+ const MODULE_SECONDARY_INCLUDE_MAX_ITERATIONS = 5;
37
30
 
38
31
  // Re-export from listpages/resolve for external use
39
32
  export type { ParseFunction } from "./listpages/resolve";
40
33
 
34
+ /**
35
+ * Transform module-generated wikitext before it is parsed back into AST nodes.
36
+ *
37
+ * Applications can use this hook to inject include resolution, parse caches, or
38
+ * diagnostics for ListPages/ListUsers secondary transformations.
39
+ *
40
+ * This hook receives the string after module variables such as `%%title%%` have
41
+ * already been substituted. Returning a different string changes what is parsed
42
+ * for that module item. When this hook is supplied it replaces the built-in
43
+ * secondary include pass, so callers that still need Wikidot-style secondary
44
+ * includes must call `resolveIncludes()` or equivalent logic from the hook.
45
+ */
46
+ export type ModuleSourceTransform = (source: string) => string;
47
+
41
48
  /**
42
49
  * Configuration for {@link resolveModules}.
43
50
  *
@@ -75,24 +82,28 @@ export interface ResolveOptions {
75
82
  * with the corresponding values from this path.
76
83
  */
77
84
  urlPath?: string;
78
- }
79
85
 
80
- /**
81
- * Context for ListPages resolution (internal)
82
- */
83
- interface ListPagesContext {
84
- dataMap: Map<number, ListPagesExternalData>;
85
- compiledTemplates: Map<number, CompiledTemplate>;
86
- parse: ParseFunction;
87
- }
86
+ /**
87
+ * Maximum include expansion iterations for secondary transformations inside
88
+ * modules such as ListPages/ListUsers. Defaults to Wikidot's observed
89
+ * secondary transformation limit.
90
+ */
91
+ includeMaxIterations?: number;
88
92
 
89
- /**
90
- * Context for ListUsers resolution (internal)
91
- */
92
- interface ListUsersContext {
93
- dataMap: Map<number, ListUsersExternalData>;
94
- compiledTemplates: Map<number, ListUsersCompiledTemplate>;
95
- parse: ParseFunction;
93
+ /**
94
+ * Transform module-generated wikitext before re-parsing it.
95
+ *
96
+ * When omitted, `resolveModules()` preserves the existing default: if
97
+ * `dataProvider.fetchInclude` is present, secondary `[[include]]` expansion
98
+ * is performed with `includeMaxIterations`; otherwise the source is parsed
99
+ * unchanged. When supplied, this hook owns the whole transformation.
100
+ *
101
+ * This is the extension point for application-level parse/include caches. The
102
+ * parser package does not persist cache entries itself because cache keys and
103
+ * invalidation depend on site/page revisions, tags, URL parameters, and user
104
+ * state outside wdpr.
105
+ */
106
+ transformModuleSource?: ModuleSourceTransform;
96
107
  }
97
108
 
98
109
  /**
@@ -114,58 +125,20 @@ export async function resolveModules(
114
125
  dataProvider: DataProvider,
115
126
  options: ResolveOptions,
116
127
  ): Promise<SyntaxTree> {
117
- // Build ListPages context if requirements provided
118
- let listPagesCtx: ListPagesContext | null = null;
119
- const listPagesReqs = options.requirements.listPages ?? [];
120
-
121
- if (listPagesReqs.length > 0 && dataProvider.fetchListPages) {
122
- const dataMap = new Map<number, ListPagesExternalData>();
123
-
124
- // Parse URL parameters once for all modules
125
- const urlParams = parseUrlParams(options.urlPath ?? "");
126
-
127
- for (const req of listPagesReqs) {
128
- // Resolve @URL parameters and normalize query
129
- const normalizedQuery = resolveAndNormalizeQuery(req, urlParams);
130
- const data = await dataProvider.fetchListPages(normalizedQuery, req);
131
- if (data) {
132
- dataMap.set(req.id, data);
133
- }
134
- }
135
-
136
- if (dataMap.size > 0) {
137
- listPagesCtx = {
138
- dataMap,
139
- compiledTemplates: options.compiledListPagesTemplates,
140
- parse: options.parse,
141
- };
142
- }
143
- }
144
-
145
- // Build ListUsers context if requirements provided
146
- let listUsersCtx: ListUsersContext | null = null;
147
- const listUsersReqs = options.requirements.listUsers ?? [];
148
-
149
- if (listUsersReqs.length > 0 && dataProvider.fetchListUsers) {
150
- const dataMap = new Map<number, ListUsersExternalData>();
151
-
152
- for (const req of listUsersReqs) {
153
- const data = await dataProvider.fetchListUsers(req);
154
- if (data) {
155
- dataMap.set(req.id, data);
156
- }
157
- }
158
-
159
- if (dataMap.size > 0) {
160
- listUsersCtx = {
161
- dataMap,
162
- compiledTemplates: options.compiledListUsersTemplates ?? new Map(),
163
- parse: options.parse,
164
- };
165
- }
166
- }
167
-
168
- // Get page tags if callback provided
128
+ const parse = createModuleParseFunction(options, dataProvider);
129
+ const listPagesCtx = await buildListPagesContext(
130
+ dataProvider,
131
+ options.requirements.listPages ?? [],
132
+ options.compiledListPagesTemplates,
133
+ parse,
134
+ options.urlPath,
135
+ );
136
+ const listUsersCtx = await buildListUsersContext(
137
+ dataProvider,
138
+ options.requirements.listUsers ?? [],
139
+ options.compiledListUsersTemplates,
140
+ parse,
141
+ );
169
142
  const pageTags = dataProvider.getPageTags?.() ?? null;
170
143
 
171
144
  // Resolve AST
@@ -194,218 +167,32 @@ export async function resolveModules(
194
167
  return result;
195
168
  }
196
169
 
197
- /**
198
- * Resolution context passed through AST traversal
199
- */
200
- interface WalkContext {
201
- listPages: ListPagesContext | null;
202
- listUsers: ListUsersContext | null;
203
- /** Whether fetchListPages callback was provided (even if no data returned) */
204
- fetchListPagesProvided: boolean;
205
- /** Whether fetchListUsers callback was provided (even if no data returned) */
206
- fetchListUsersProvided: boolean;
207
- pageTags: string[] | null;
208
- listPagesIdCounter: number;
209
- listUsersIdCounter: number;
210
- }
211
-
212
- interface WalkResult {
213
- elements: Element[];
214
- nextListPagesId: number;
215
- nextListUsersId: number;
216
- }
217
-
218
- /**
219
- * Walk AST and resolve modules/iftags
220
- */
221
- function walkAndResolve(elements: Element[], ctx: WalkContext): WalkResult {
222
- const result: Element[] = [];
223
- let listPagesId = ctx.listPagesIdCounter;
224
- let listUsersId = ctx.listUsersIdCounter;
225
-
226
- for (const element of elements) {
227
- // ListPages module
228
- if (element.element === "module" && isListPagesModule(element.data)) {
229
- if (ctx.listPages) {
230
- const moduleData = ctx.listPages.dataMap.get(listPagesId);
231
- const template = ctx.listPages.compiledTemplates.get(listPagesId);
232
-
233
- if (moduleData && template) {
234
- const resolved = resolveListPages(
235
- element.data,
236
- moduleData,
237
- template,
238
- ctx.listPages.parse,
239
- );
240
- result.push(...resolved);
241
- }
242
- } else if (!ctx.fetchListPagesProvided) {
243
- result.push(element);
244
- }
245
- listPagesId++;
246
- continue;
247
- }
248
-
249
- // ListUsers module
250
- if (element.element === "module" && isListUsersModule(element.data)) {
251
- if (ctx.listUsers) {
252
- const moduleData = ctx.listUsers.dataMap.get(listUsersId);
253
- const template = ctx.listUsers.compiledTemplates.get(listUsersId);
254
-
255
- if (moduleData && template) {
256
- const resolved = resolveListUsers(
257
- element.data,
258
- moduleData,
259
- template,
260
- ctx.listUsers.parse,
261
- );
262
- result.push(...resolved);
263
- }
264
- } else if (!ctx.fetchListUsersProvided) {
265
- result.push(element);
266
- }
267
- listUsersId++;
268
- continue;
269
- }
270
-
271
- // IfTags
272
- if (isIfTagsElement(element)) {
273
- const ifTagsData = element.data as IfTagsData;
274
- const resolveResult = resolveIfTags(ifTagsData, ctx.pageTags);
275
-
276
- if (resolveResult.evaluated) {
277
- if (resolveResult.matched) {
278
- const childResult = walkAndResolve(ifTagsData.elements, {
279
- ...ctx,
280
- listPagesIdCounter: listPagesId,
281
- listUsersIdCounter: listUsersId,
282
- });
283
- result.push(...childResult.elements);
284
- listPagesId = childResult.nextListPagesId;
285
- listUsersId = childResult.nextListUsersId;
286
- } else {
287
- const counts = countModulesInElements(ifTagsData.elements);
288
- listPagesId += counts.listPages;
289
- listUsersId += counts.listUsers;
290
- }
291
- } else {
292
- const childResult = walkAndResolve(ifTagsData.elements, {
293
- ...ctx,
294
- listPagesIdCounter: listPagesId,
295
- listUsersIdCounter: listUsersId,
296
- });
297
- result.push({
298
- element: "if-tags",
299
- data: {
300
- ...ifTagsData,
301
- elements: childResult.elements,
302
- },
303
- });
304
- listPagesId = childResult.nextListPagesId;
305
- listUsersId = childResult.nextListUsersId;
306
- }
307
- continue;
308
- }
309
-
310
- // Recurse into child elements (list, table, definition-list, tab-view, generic)
311
- const mapped = mapElementChildrenWithState(
312
- element,
313
- { listPagesId, listUsersId },
314
- (children, state) => {
315
- const childResult = walkAndResolve(children, {
316
- ...ctx,
317
- listPagesIdCounter: state.listPagesId,
318
- listUsersIdCounter: state.listUsersId,
319
- });
320
- return {
321
- elements: childResult.elements,
322
- state: {
323
- listPagesId: childResult.nextListPagesId,
324
- listUsersId: childResult.nextListUsersId,
325
- },
326
- };
327
- },
328
- );
329
- result.push(mapped.element);
330
- listPagesId = mapped.state.listPagesId;
331
- listUsersId = mapped.state.listUsersId;
170
+ function createModuleParseFunction(
171
+ options: ResolveOptions,
172
+ dataProvider: DataProvider,
173
+ ): ParseFunction {
174
+ const transform = createModuleSourceTransform(options, dataProvider);
175
+ if (!transform) {
176
+ return options.parse;
332
177
  }
333
178
 
334
- return { elements: result, nextListPagesId: listPagesId, nextListUsersId: listUsersId };
179
+ return (source: string) => options.parse(transform(source));
335
180
  }
336
181
 
337
- /**
338
- * Count resolved modules in elements without resolving them
339
- *
340
- * Used to advance ID counters without expensive resolution when
341
- * IfTags condition doesn't match (elements are skipped but IDs must sync)
342
- */
343
- function countModulesInElements(elements: Element[]): { listPages: number; listUsers: number } {
344
- let listPages = 0;
345
- let listUsers = 0;
346
- walkElements(elements, (element) => {
347
- if (element.element === "module") {
348
- if (isListPagesModule(element.data)) {
349
- listPages++;
350
- } else if (isListUsersModule(element.data)) {
351
- listUsers++;
352
- }
353
- }
354
- });
355
- return { listPages, listUsers };
356
- }
357
-
358
- /**
359
- * Collect and remove style elements from the AST.
360
- *
361
- * Walks the element tree recursively, extracting style elements
362
- * from any depth and returning them separately. Unresolved `if-tags`
363
- * elements are skipped — their internal styles remain in the AST and
364
- * are rendered inline at render time when the condition is evaluated.
365
- *
366
- * The order of collected styles reflects their appearance order in the AST.
367
- */
368
-
369
- function collectStyles(elements: Element[]): { elements: Element[]; styles: string[] } {
370
- const styles: string[] = [];
371
- const ctx = { nextSlotId: 0 };
372
- const filtered = collectStylesFromElements(elements, styles, ctx);
373
- return { elements: filtered, styles };
374
- }
375
-
376
- function collectStylesFromElements(
377
- elements: Element[],
378
- styles: string[],
379
- ctx: { nextSlotId: number },
380
- ): Element[] {
381
- const result: Element[] = [];
382
-
383
- for (const element of elements) {
384
- if (element.element === "style") {
385
- styles.push(element.data as string);
386
- continue;
387
- }
388
-
389
- // Unresolved iftags: insert a style-slot placeholder to preserve
390
- // source-order of styles relative to other collected styles.
391
- // The slot ID is attached to the element data so the renderer can
392
- // collect styles into the correct slot at render time.
393
- if (element.element === "if-tags") {
394
- const slotId = ctx.nextSlotId++;
395
- styles.push(`${STYLE_SLOT_PREFIX}${slotId}`);
396
- result.push({
397
- element: "if-tags",
398
- data: { ...(element.data as IfTagsData), _styleSlot: slotId },
399
- } as unknown as Element);
400
- continue;
401
- }
182
+ function createModuleSourceTransform(
183
+ options: ResolveOptions,
184
+ dataProvider: DataProvider,
185
+ ): ModuleSourceTransform | null {
186
+ if (options.transformModuleSource) {
187
+ return options.transformModuleSource;
188
+ }
402
189
 
403
- // Recurse into children using mapElementChildren
404
- const mapped = mapElementChildren(element, (children) =>
405
- collectStylesFromElements(children, styles, ctx),
406
- );
407
- result.push(mapped);
190
+ if (!dataProvider.fetchInclude) {
191
+ return null;
408
192
  }
409
193
 
410
- return result;
194
+ return (source: string) =>
195
+ resolveIncludes(source, dataProvider.fetchInclude!, {
196
+ maxIterations: options.includeMaxIterations ?? MODULE_SECONDARY_INCLUDE_MAX_ITERATIONS,
197
+ });
411
198
  }
@@ -0,0 +1,56 @@
1
+ import type { Element } from "@wdprlib/ast";
2
+ import type { BlockRule, ParseContext, RuleResult } from "../../types";
3
+ import { currentToken } from "../../types";
4
+ import { parseModuleBody } from "./body";
5
+ import { createUnknownModuleElement, moduleParseResultToElement } from "./element";
6
+ import { getModuleRuleByName } from "./mapping";
7
+ import { parseModuleOpen } from "./open";
8
+
9
+ export const moduleRule: BlockRule = {
10
+ name: "module",
11
+ startTokens: ["BLOCK_OPEN"],
12
+ requiresLineStart: false,
13
+
14
+ parse(ctx: ParseContext): RuleResult<Element> {
15
+ const openToken = currentToken(ctx);
16
+ if (openToken.type !== "BLOCK_OPEN") {
17
+ return { success: false };
18
+ }
19
+
20
+ const openResult = parseModuleOpen(ctx);
21
+ if (!openResult) {
22
+ return { success: false };
23
+ }
24
+
25
+ // Page syntax disabled (e.g., forum-post mode)
26
+ if (!ctx.settings.enablePageSyntax) {
27
+ return { success: false };
28
+ }
29
+
30
+ // Dispatch to specific module parser
31
+ const moduleParseRule = getModuleRuleByName(openResult.moduleName);
32
+
33
+ // Check for body based on module rule's hasBody flag
34
+ // For unknown modules, default to no body (they will be parsed as bodyless)
35
+ const bodyResult = parseModuleBody(ctx, openResult.pos, moduleParseRule?.hasBody ?? false);
36
+ const consumed = openResult.consumed + bodyResult.consumed;
37
+
38
+ if (moduleParseRule) {
39
+ const result = moduleParseRule.parse(ctx, bodyResult.pos, openResult.attrs, bodyResult.body);
40
+
41
+ return {
42
+ success: true,
43
+ elements: [moduleParseResultToElement(result)],
44
+ consumed,
45
+ };
46
+ }
47
+
48
+ return {
49
+ success: true,
50
+ elements: [
51
+ createUnknownModuleElement(openResult.moduleName, openResult.attrs, bodyResult.body),
52
+ ],
53
+ consumed,
54
+ };
55
+ },
56
+ };
@@ -15,6 +15,7 @@
15
15
  import type { ListPagesDataFetcher } from "./listpages/types";
16
16
  import type { ListUsersDataFetcher } from "./listusers/types";
17
17
  import type { IfTagsResolver } from "./iftags/types";
18
+ import type { IncludeFetcher } from "./include/resolve/types";
18
19
 
19
20
  /**
20
21
  * Callback bag for supplying external data during module resolution.
@@ -48,6 +49,16 @@ export interface DataProvider {
48
49
  */
49
50
  fetchListUsers?: ListUsersDataFetcher;
50
51
 
52
+ /**
53
+ * Fetch raw wikitext for `[[include]]` directives that are created during
54
+ * module secondary transformations such as ListPages/ListUsers item rendering.
55
+ *
56
+ * Top-level include expansion still uses `resolveIncludes()` directly before
57
+ * parsing. This callback is only for module-rendered wikitext that needs its
58
+ * own include pass before being parsed again.
59
+ */
60
+ fetchInclude?: IncludeFetcher;
61
+
51
62
  /**
52
63
  * Return the current page's tags for `[[iftags]]` evaluation.
53
64
  *
@@ -0,0 +1,35 @@
1
+ import type { Element, ElementOf, ListData } from "@wdprlib/ast";
2
+
3
+ export type ListElement = ElementOf<"list">;
4
+
5
+ export function listElement(data: ListData): ListElement {
6
+ return { element: "list", data };
7
+ }
8
+
9
+ export function getGenericElementChildren(element: Element): Element[] | null {
10
+ if (!("data" in element) || !element.data || typeof element.data !== "object") {
11
+ return null;
12
+ }
13
+
14
+ const data = element.data as Record<string, unknown>;
15
+ return Array.isArray(data.elements) ? (data.elements as Element[]) : null;
16
+ }
17
+
18
+ export function withGenericElementChildren(element: Element, children: Element[]): Element {
19
+ if (!("data" in element) || !element.data || typeof element.data !== "object") {
20
+ return element;
21
+ }
22
+
23
+ const data = element.data as Record<string, unknown>;
24
+ if (!Array.isArray(data.elements)) {
25
+ return element;
26
+ }
27
+
28
+ return {
29
+ ...element,
30
+ data: {
31
+ ...data,
32
+ elements: children,
33
+ },
34
+ } as Element;
35
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ *
3
+ * AST element traversal and transformation utilities.
4
+ *
5
+ * @module
6
+ */
7
+
8
+ export { walkElements } from "./traverse";
9
+ export { mapElementChildren, mapElementChildrenWithState } from "./map";
@@ -0,0 +1,2 @@
1
+ export { mapElementChildren } from "./stateless";
2
+ export { mapElementChildrenWithState } from "./stateful";
@@ -0,0 +1,25 @@
1
+ import type { DefinitionListItem, Element } from "@wdprlib/ast";
2
+ import type { StatefulTransformResult } from "./types";
3
+
4
+ export function mapDefinitionListItemsWithState<S>(
5
+ items: DefinitionListItem[],
6
+ state: S,
7
+ transform: (elements: Element[], state: S) => StatefulTransformResult<S>,
8
+ ): { items: DefinitionListItem[]; state: S } {
9
+ const newItems: DefinitionListItem[] = [];
10
+ let currentState = state;
11
+
12
+ for (const item of items) {
13
+ const keyResult = transform(item.key, currentState);
14
+ currentState = keyResult.state;
15
+ const valueResult = transform(item.value, currentState);
16
+ currentState = valueResult.state;
17
+ newItems.push({
18
+ key_string: item.key_string,
19
+ key: keyResult.elements,
20
+ value: valueResult.elements,
21
+ });
22
+ }
23
+
24
+ return { items: newItems, state: currentState };
25
+ }