@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
@@ -1,115 +0,0 @@
1
- /**
2
- *
3
- * Parses the Wikidot equation reference syntax: `[[eref name]]`.
4
- *
5
- * An equation reference creates a clickable link that points to a
6
- * named equation block defined elsewhere on the page (via
7
- * `[[equation name]]` block syntax in the block-level parser). The
8
- * reference is rendered as the equation's assigned number.
9
- *
10
- * Only the short form `eref` is recognized as a valid keyword.
11
- * The long form `[[equation name]]` is NOT supported by Wikidot for
12
- * inline references and is rendered as plain text.
13
- *
14
- * Produces an `"equation-reference"` AST element whose `data` field
15
- * contains the reference name string.
16
- *
17
- * Wikidot syntax example:
18
- * - `[[eref myEquation]]` -- references equation named "myEquation"
19
- *
20
- * @module
21
- */
22
- import type { Element } from "@wdprlib/ast";
23
- import type { InlineRule, ParseContext, RuleResult } from "../types";
24
- import { currentToken } from "../types";
25
- import { parseBlockName } from "../utils";
26
-
27
- /**
28
- * Inline rule for parsing `[[eref name]]` equation references.
29
- *
30
- * Triggered by a `BLOCK_OPEN` (`[[`) token. The rule verifies the
31
- * block name is `eref` (case-insensitive), then collects the
32
- * reference name until the closing `]]`.
33
- *
34
- * Fails if the block name is not `eref`, the reference name is empty,
35
- * or `]]` is not found.
36
- */
37
- export const equationRefRule: InlineRule = {
38
- name: "equation-ref",
39
- startTokens: ["BLOCK_OPEN"],
40
-
41
- /**
42
- * Attempts to parse an `[[eref name]]` reference at the current position.
43
- *
44
- * @param ctx - Parse context with token stream and current position
45
- * @returns A successful result with an `"equation-reference"` element,
46
- * or `{ success: false }`
47
- */
48
- parse(ctx: ParseContext): RuleResult<Element> {
49
- const openToken = currentToken(ctx);
50
- if (openToken.type !== "BLOCK_OPEN") {
51
- return { success: false };
52
- }
53
-
54
- let pos = ctx.pos + 1;
55
- let consumed = 1;
56
-
57
- // Parse block name
58
- const nameResult = parseBlockName(ctx, pos);
59
- if (!nameResult) {
60
- return { success: false };
61
- }
62
-
63
- const blockName = nameResult.name.toLowerCase();
64
- // Only "eref" is supported in Wikidot
65
- if (blockName !== "eref") {
66
- return { success: false };
67
- }
68
-
69
- pos += nameResult.consumed;
70
- consumed += nameResult.consumed;
71
-
72
- // Skip whitespace
73
- while (ctx.tokens[pos]?.type === "WHITESPACE") {
74
- pos++;
75
- consumed++;
76
- }
77
-
78
- // Parse reference name
79
- let refName = "";
80
- while (pos < ctx.tokens.length) {
81
- const token = ctx.tokens[pos];
82
- if (!token || token.type === "BLOCK_CLOSE" || token.type === "NEWLINE") {
83
- break;
84
- }
85
- refName += token.value;
86
- pos++;
87
- consumed++;
88
- }
89
-
90
- // Expect ]]
91
- if (ctx.tokens[pos]?.type !== "BLOCK_CLOSE") {
92
- return { success: false };
93
- }
94
- pos++;
95
- consumed++;
96
-
97
- refName = refName.trim();
98
-
99
- // Empty reference is invalid
100
- if (!refName) {
101
- return { success: false };
102
- }
103
-
104
- return {
105
- success: true,
106
- elements: [
107
- {
108
- element: "equation-reference",
109
- data: refName,
110
- },
111
- ],
112
- consumed,
113
- };
114
- },
115
- };
@@ -1,526 +0,0 @@
1
- /**
2
- *
3
- * Parses Wikidot's inline expression and conditional block syntax:
4
- *
5
- * - `[[#expr expression]]` -- evaluate a mathematical expression and display the result
6
- * - `[[#if value | then | else]]` -- simple truthy/falsy conditional
7
- * - `[[#ifexpr expression | then | else]]` -- expression-based conditional
8
- *
9
- * All three forms begin with `[[#` followed by the keyword. The `#`
10
- * prefix distinguishes these from regular `[[block]]` syntax.
11
- *
12
- * `[[#if]]` treats its condition as a string and considers these values
13
- * falsy: `"false"`, `"null"`, `""`, `"0"`. Everything else is truthy.
14
- *
15
- * `[[#ifexpr]]` evaluates its condition as a mathematical expression
16
- * and treats the numeric result as falsy when zero.
17
- *
18
- * Both conditional forms support an optional else branch: when only
19
- * one pipe-separated branch is provided, the else branch is empty.
20
- *
21
- * Expressions are limited to 256 characters (after trimming) to
22
- * prevent abuse.
23
- *
24
- * The pipe (`|`) delimiter is depth-aware: pipes inside nested `[[]]`
25
- * or `[[[]]]` blocks are not treated as branch separators.
26
- *
27
- * @module
28
- */
29
- import type { Element } from "@wdprlib/ast";
30
- import type { InlineRule, ParseContext, RuleResult } from "../types";
31
- import { currentToken } from "../types";
32
-
33
- /** Maximum allowed length for expression strings after trimming. */
34
- const MAX_EXPRESSION_LENGTH = 256;
35
-
36
- /**
37
- * Parses inline content for the then/else branches of `[[#if]]` and `[[#ifexpr]]`.
38
- *
39
- * Collects inline elements (by delegating to the registered inline rules) until
40
- * a top-level `PIPE` token or the enclosing `BLOCK_CLOSE` (`]]`) is reached.
41
- *
42
- * Nesting depth is tracked so that `PIPE` and `BLOCK_CLOSE` tokens inside
43
- * nested `[[...]]` or `[[[...]]]` blocks are not mistaken for branch
44
- * delimiters or the outer block's closing marker.
45
- *
46
- * @param ctx - The current parse context
47
- * @param startPos - Token index at which to begin scanning branch content
48
- * @returns An object containing the parsed elements, the number of tokens consumed,
49
- * and whether the branch ended with a `PIPE` (indicating an else branch follows)
50
- */
51
- function parseInlineBranch(
52
- ctx: ParseContext,
53
- startPos: number,
54
- ): { elements: Element[]; consumed: number; endedWithPipe: boolean } {
55
- const elements: Element[] = [];
56
- let consumed = 0;
57
- let pos = startPos;
58
- let depth = 0; // Track [[ ]] nesting depth
59
-
60
- const { inlineRules } = ctx;
61
-
62
- while (pos < ctx.tokens.length) {
63
- const token = ctx.tokens[pos];
64
- if (!token || token.type === "EOF" || token.type === "NEWLINE") {
65
- break;
66
- }
67
-
68
- // Track nesting (both [[...]] and [[[...]]] blocks)
69
- if (
70
- token.type === "BLOCK_OPEN" ||
71
- token.type === "BLOCK_END_OPEN" ||
72
- token.type === "LINK_OPEN"
73
- ) {
74
- depth++;
75
- } else if (token.type === "BLOCK_CLOSE" || token.type === "LINK_CLOSE") {
76
- if (depth === 0) {
77
- // End of the outer block
78
- break;
79
- }
80
- depth--;
81
- }
82
-
83
- // Stop at PIPE only at top level
84
- if (token.type === "PIPE" && depth === 0) {
85
- return { elements, consumed, endedWithPipe: true };
86
- }
87
-
88
- // Try inline rules
89
- const inlineCtx: ParseContext = { ...ctx, pos };
90
- let matched = false;
91
-
92
- for (const rule of inlineRules) {
93
- // Skip rules that would consume our delimiters
94
- if (rule.startTokens.includes("PIPE") || rule.startTokens.includes("BLOCK_CLOSE")) {
95
- continue;
96
- }
97
- if (rule.startTokens.length === 0 || rule.startTokens.includes(token.type)) {
98
- const result = rule.parse(inlineCtx);
99
- if (result.success) {
100
- elements.push(...result.elements);
101
- consumed += result.consumed;
102
- pos += result.consumed;
103
- matched = true;
104
- break;
105
- }
106
- }
107
- }
108
-
109
- if (!matched) {
110
- // Fallback to text
111
- elements.push({ element: "text", data: token.value });
112
- consumed++;
113
- pos++;
114
- }
115
- }
116
-
117
- return { elements, consumed, endedWithPipe: false };
118
- }
119
-
120
- /**
121
- * Collects raw text for the expression or condition portion of `[[#expr]]`,
122
- * `[[#if]]`, and `[[#ifexpr]]` blocks.
123
- *
124
- * Unlike {@link parseInlineBranch}, this function collects raw token values
125
- * as a concatenated string rather than parsing them as inline elements.
126
- * This is appropriate for expressions and conditions that are evaluated
127
- * at runtime rather than rendered as markup.
128
- *
129
- * Tracks nesting depth to correctly handle `PIPE` tokens that appear
130
- * inside nested `[[...]]` or `[[[...]]]` blocks.
131
- *
132
- * @param ctx - The current parse context
133
- * @param startPos - Token index at which to begin collecting text
134
- * @returns An object containing the trimmed expression text, the number of tokens
135
- * consumed, and whether collection ended at a `PIPE` (vs. `BLOCK_CLOSE`)
136
- */
137
- function collectExpressionText(
138
- ctx: ParseContext,
139
- startPos: number,
140
- ): { text: string; consumed: number; endedWithPipe: boolean } {
141
- let text = "";
142
- let consumed = 0;
143
- let pos = startPos;
144
- let depth = 0;
145
-
146
- while (pos < ctx.tokens.length) {
147
- const token = ctx.tokens[pos];
148
- if (!token || token.type === "EOF" || token.type === "NEWLINE") {
149
- break;
150
- }
151
-
152
- // Track nesting (both [[...]] and [[[...]]] blocks)
153
- if (
154
- token.type === "BLOCK_OPEN" ||
155
- token.type === "BLOCK_END_OPEN" ||
156
- token.type === "LINK_OPEN"
157
- ) {
158
- depth++;
159
- } else if (token.type === "BLOCK_CLOSE" || token.type === "LINK_CLOSE") {
160
- if (depth === 0) {
161
- break;
162
- }
163
- depth--;
164
- }
165
-
166
- // Stop at PIPE only at top level
167
- if (token.type === "PIPE" && depth === 0) {
168
- return { text: text.trim(), consumed, endedWithPipe: true };
169
- }
170
-
171
- text += token.value;
172
- consumed++;
173
- pos++;
174
- }
175
-
176
- return { text: text.trim(), consumed, endedWithPipe: false };
177
- }
178
-
179
- /**
180
- * Inline rule for parsing `[[#expr expression]]`.
181
- *
182
- * Evaluates the given mathematical expression at runtime and displays
183
- * the result inline. The expression is case-sensitive and must use
184
- * lowercase `expr`.
185
- *
186
- * Produces an `"expr"` AST element whose `data.expression` field
187
- * contains the raw expression string for later evaluation.
188
- */
189
- export const exprRule: InlineRule = {
190
- name: "expr",
191
- startTokens: ["BLOCK_OPEN"],
192
-
193
- /**
194
- * Attempts to parse a `[[#expr expression]]` block at the current position.
195
- *
196
- * @param ctx - Parse context with token stream and current position
197
- * @returns A successful result with an `"expr"` element, or `{ success: false }`
198
- */
199
- parse(ctx: ParseContext): RuleResult<Element> {
200
- const openToken = currentToken(ctx);
201
- if (openToken.type !== "BLOCK_OPEN") {
202
- return { success: false };
203
- }
204
-
205
- let pos = ctx.pos + 1;
206
- let consumed = 1;
207
-
208
- // Expect # immediately after [[
209
- const hashToken = ctx.tokens[pos];
210
- if (!hashToken || hashToken.type !== "HASH") {
211
- return { success: false };
212
- }
213
- pos++;
214
- consumed++;
215
-
216
- // Expect identifier "expr" (case-sensitive - Wikidot only supports lowercase)
217
- const idToken = ctx.tokens[pos];
218
- if (!idToken || idToken.type !== "IDENTIFIER" || idToken.value !== "expr") {
219
- return { success: false };
220
- }
221
- pos++;
222
- consumed++;
223
-
224
- // Skip whitespace
225
- while (ctx.tokens[pos]?.type === "WHITESPACE") {
226
- pos++;
227
- consumed++;
228
- }
229
-
230
- // Collect expression until ]]
231
- const exprResult = collectExpressionText(ctx, pos);
232
- const expression = exprResult.text;
233
- pos += exprResult.consumed;
234
- consumed += exprResult.consumed;
235
-
236
- // Validate expression length
237
- if (expression.length > MAX_EXPRESSION_LENGTH) {
238
- return { success: false };
239
- }
240
-
241
- // Expect ]]
242
- if (ctx.tokens[pos]?.type !== "BLOCK_CLOSE") {
243
- return { success: false };
244
- }
245
- pos++;
246
- consumed++;
247
-
248
- return {
249
- success: true,
250
- elements: [
251
- {
252
- element: "expr",
253
- data: { expression },
254
- },
255
- ],
256
- consumed,
257
- };
258
- },
259
- };
260
-
261
- /**
262
- * Inline rule for parsing `[[#if value | then | else]]`.
263
- *
264
- * Performs a simple truthy/falsy check on a string value. The value
265
- * is treated as false when it matches `"false"`, `"null"`, `""`,
266
- * or `"0"` (case-insensitive); all other values are truthy.
267
- *
268
- * The then branch is required (separated from the condition by `|`).
269
- * The else branch is optional (separated from the then branch by
270
- * another `|`).
271
- *
272
- * Produces an `"if"` AST element with `condition`, `then`, and
273
- * `else` fields.
274
- */
275
- export const ifRule: InlineRule = {
276
- name: "if",
277
- startTokens: ["BLOCK_OPEN"],
278
-
279
- /**
280
- * Attempts to parse a `[[#if value | then | else]]` block at the current position.
281
- *
282
- * @param ctx - Parse context with token stream and current position
283
- * @returns A successful result with an `"if"` element, or `{ success: false }`
284
- */
285
- parse(ctx: ParseContext): RuleResult<Element> {
286
- const openToken = currentToken(ctx);
287
- if (openToken.type !== "BLOCK_OPEN") {
288
- return { success: false };
289
- }
290
-
291
- let pos = ctx.pos + 1;
292
- let consumed = 1;
293
-
294
- // Expect # immediately after [[
295
- const hashToken = ctx.tokens[pos];
296
- if (!hashToken || hashToken.type !== "HASH") {
297
- return { success: false };
298
- }
299
- pos++;
300
- consumed++;
301
-
302
- // Expect identifier "if" (case-sensitive - Wikidot only supports lowercase)
303
- const idToken = ctx.tokens[pos];
304
- if (!idToken || idToken.type !== "IDENTIFIER" || idToken.value !== "if") {
305
- return { success: false };
306
- }
307
- pos++;
308
- consumed++;
309
-
310
- // Skip whitespace
311
- while (ctx.tokens[pos]?.type === "WHITESPACE") {
312
- pos++;
313
- consumed++;
314
- }
315
-
316
- // Collect condition until first |
317
- const condResult = collectExpressionText(ctx, pos);
318
- if (!condResult.endedWithPipe) {
319
- return { success: false }; // Must have | separator
320
- }
321
- const condition = condResult.text;
322
- pos += condResult.consumed;
323
- consumed += condResult.consumed;
324
-
325
- // Validate condition length
326
- if (condition.length > MAX_EXPRESSION_LENGTH) {
327
- return { success: false };
328
- }
329
-
330
- // Skip the PIPE
331
- if (ctx.tokens[pos]?.type !== "PIPE") {
332
- return { success: false };
333
- }
334
- pos++;
335
- consumed++;
336
-
337
- // Skip whitespace after |
338
- while (ctx.tokens[pos]?.type === "WHITESPACE") {
339
- pos++;
340
- consumed++;
341
- }
342
-
343
- // Parse "then" branch until next |
344
- const thenResult = parseInlineBranch(ctx, pos);
345
- pos += thenResult.consumed;
346
- consumed += thenResult.consumed;
347
-
348
- let elseElements: Element[] = [];
349
-
350
- if (thenResult.endedWithPipe) {
351
- // Skip the PIPE
352
- if (ctx.tokens[pos]?.type !== "PIPE") {
353
- return { success: false };
354
- }
355
- pos++;
356
- consumed++;
357
-
358
- // Skip whitespace after |
359
- while (ctx.tokens[pos]?.type === "WHITESPACE") {
360
- pos++;
361
- consumed++;
362
- }
363
-
364
- // Parse "else" branch until ]]
365
- const elseResult = parseInlineBranch(ctx, pos);
366
- elseElements = elseResult.elements;
367
- pos += elseResult.consumed;
368
- consumed += elseResult.consumed;
369
- }
370
-
371
- // Expect ]]
372
- if (ctx.tokens[pos]?.type !== "BLOCK_CLOSE") {
373
- return { success: false };
374
- }
375
- pos++;
376
- consumed++;
377
-
378
- return {
379
- success: true,
380
- elements: [
381
- {
382
- element: "if",
383
- data: {
384
- condition,
385
- then: thenResult.elements,
386
- else: elseElements,
387
- },
388
- },
389
- ],
390
- consumed,
391
- };
392
- },
393
- };
394
-
395
- /**
396
- * Inline rule for parsing `[[#ifexpr expression | then | else]]`.
397
- *
398
- * Evaluates a mathematical expression and uses the result to choose
399
- * between the then and else branches. A zero result selects the else
400
- * branch; any non-zero result selects the then branch.
401
- *
402
- * Like `[[#if]]`, the then branch is required and the else branch
403
- * is optional.
404
- *
405
- * Produces an `"ifexpr"` AST element with `expression`, `then`, and
406
- * `else` fields.
407
- */
408
- export const ifExprRule: InlineRule = {
409
- name: "ifexpr",
410
- startTokens: ["BLOCK_OPEN"],
411
-
412
- /**
413
- * Attempts to parse a `[[#ifexpr expression | then | else]]` block at the current position.
414
- *
415
- * @param ctx - Parse context with token stream and current position
416
- * @returns A successful result with an `"ifexpr"` element, or `{ success: false }`
417
- */
418
- parse(ctx: ParseContext): RuleResult<Element> {
419
- const openToken = currentToken(ctx);
420
- if (openToken.type !== "BLOCK_OPEN") {
421
- return { success: false };
422
- }
423
-
424
- let pos = ctx.pos + 1;
425
- let consumed = 1;
426
-
427
- // Expect # immediately after [[
428
- const hashToken = ctx.tokens[pos];
429
- if (!hashToken || hashToken.type !== "HASH") {
430
- return { success: false };
431
- }
432
- pos++;
433
- consumed++;
434
-
435
- // Expect identifier "ifexpr" (case-sensitive - Wikidot only supports lowercase)
436
- const idToken = ctx.tokens[pos];
437
- if (!idToken || idToken.type !== "IDENTIFIER" || idToken.value !== "ifexpr") {
438
- return { success: false };
439
- }
440
- pos++;
441
- consumed++;
442
-
443
- // Skip whitespace
444
- while (ctx.tokens[pos]?.type === "WHITESPACE") {
445
- pos++;
446
- consumed++;
447
- }
448
-
449
- // Collect expression until first |
450
- const exprResult = collectExpressionText(ctx, pos);
451
- if (!exprResult.endedWithPipe) {
452
- return { success: false }; // Must have | separator
453
- }
454
- const expression = exprResult.text;
455
- pos += exprResult.consumed;
456
- consumed += exprResult.consumed;
457
-
458
- // Validate expression length
459
- if (expression.length > MAX_EXPRESSION_LENGTH) {
460
- return { success: false };
461
- }
462
-
463
- // Skip the PIPE
464
- if (ctx.tokens[pos]?.type !== "PIPE") {
465
- return { success: false };
466
- }
467
- pos++;
468
- consumed++;
469
-
470
- // Skip whitespace after |
471
- while (ctx.tokens[pos]?.type === "WHITESPACE") {
472
- pos++;
473
- consumed++;
474
- }
475
-
476
- // Parse "then" branch until next |
477
- const thenResult = parseInlineBranch(ctx, pos);
478
- pos += thenResult.consumed;
479
- consumed += thenResult.consumed;
480
-
481
- let elseElements: Element[] = [];
482
-
483
- if (thenResult.endedWithPipe) {
484
- // Skip the PIPE
485
- if (ctx.tokens[pos]?.type !== "PIPE") {
486
- return { success: false };
487
- }
488
- pos++;
489
- consumed++;
490
-
491
- // Skip whitespace after |
492
- while (ctx.tokens[pos]?.type === "WHITESPACE") {
493
- pos++;
494
- consumed++;
495
- }
496
-
497
- // Parse "else" branch until ]]
498
- const elseResult = parseInlineBranch(ctx, pos);
499
- elseElements = elseResult.elements;
500
- pos += elseResult.consumed;
501
- consumed += elseResult.consumed;
502
- }
503
-
504
- // Expect ]]
505
- if (ctx.tokens[pos]?.type !== "BLOCK_CLOSE") {
506
- return { success: false };
507
- }
508
- pos++;
509
- consumed++;
510
-
511
- return {
512
- success: true,
513
- elements: [
514
- {
515
- element: "ifexpr",
516
- data: {
517
- expression,
518
- then: thenResult.elements,
519
- else: elseElements,
520
- },
521
- },
522
- ],
523
- consumed,
524
- };
525
- },
526
- };