@wdprlib/parser 3.1.2 → 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 (419) hide show
  1. package/dist/index.cjs +10456 -8230
  2. package/dist/index.d.cts +313 -337
  3. package/dist/index.d.ts +313 -337
  4. package/dist/index.js +10460 -8234
  5. package/package.json +5 -3
  6. package/src/index.ts +170 -0
  7. package/src/lexer/anchor.ts +48 -0
  8. package/src/lexer/index.ts +21 -0
  9. package/src/lexer/lexer.ts +201 -0
  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/lexer/tokens.ts +141 -0
  22. package/src/parser/constants.ts +175 -0
  23. package/src/parser/depth/index.ts +111 -0
  24. package/src/parser/depth/stack.ts +82 -0
  25. package/src/parser/index.ts +18 -0
  26. package/src/parser/parse/block.ts +42 -0
  27. package/src/parser/parse/context.ts +26 -0
  28. package/src/parser/parse/footnotes.ts +25 -0
  29. package/src/parser/parse/index.ts +42 -0
  30. package/src/parser/parse/options.ts +34 -0
  31. package/src/parser/parse/parser.ts +79 -0
  32. package/src/parser/parse/plain-non-ascii.ts +129 -0
  33. package/src/parser/parse/result.ts +57 -0
  34. package/src/parser/parse/source.ts +11 -0
  35. package/src/parser/postprocess/divAdjacentParagraph.ts +76 -0
  36. package/src/parser/postprocess/index.ts +15 -0
  37. package/src/parser/postprocess/spanStrip/clean-element.ts +168 -0
  38. package/src/parser/postprocess/spanStrip/cleanup.ts +25 -0
  39. package/src/parser/postprocess/spanStrip/empty-spans.ts +36 -0
  40. package/src/parser/postprocess/spanStrip/escaped.ts +78 -0
  41. package/src/parser/postprocess/spanStrip/factory.ts +23 -0
  42. package/src/parser/postprocess/spanStrip/index.ts +8 -0
  43. package/src/parser/postprocess/spanStrip/merge.ts +117 -0
  44. package/src/parser/postprocess/spanStrip/predicates.ts +59 -0
  45. package/src/parser/postprocess/spanStrip/split.ts +67 -0
  46. package/src/parser/preprocess/expr/chars.ts +15 -0
  47. package/src/parser/preprocess/expr/evaluate.ts +22 -0
  48. package/src/parser/preprocess/expr/index.ts +45 -0
  49. package/src/parser/preprocess/expr/kind.ts +19 -0
  50. package/src/parser/preprocess/expr/parse.ts +103 -0
  51. package/src/parser/preprocess/expr/scan.ts +34 -0
  52. package/src/parser/preprocess/expr/types.ts +14 -0
  53. package/src/parser/preprocess/index.ts +38 -0
  54. package/src/parser/preprocess/typography.ts +132 -0
  55. package/src/parser/preprocess/utils/bracket-depths.ts +98 -0
  56. package/src/parser/preprocess/utils/index.ts +13 -0
  57. package/src/parser/preprocess/utils/raw-regions.ts +153 -0
  58. package/src/parser/preprocess/whitespace/detection.ts +39 -0
  59. package/src/parser/preprocess/whitespace/index.ts +79 -0
  60. package/src/parser/preprocess/whitespace/leading-spaces.ts +11 -0
  61. package/src/parser/preprocess/whitespace/patterns.ts +23 -0
  62. package/src/parser/rules/block/align/body.ts +46 -0
  63. package/src/parser/rules/block/align/element.ts +13 -0
  64. package/src/parser/rules/block/align/index.ts +90 -0
  65. package/src/parser/rules/block/align/syntax.ts +113 -0
  66. package/src/parser/rules/block/bibliography/body.ts +81 -0
  67. package/src/parser/rules/block/bibliography/entries.ts +49 -0
  68. package/src/parser/rules/block/bibliography/entry-content.ts +73 -0
  69. package/src/parser/rules/block/bibliography/entry-key.ts +83 -0
  70. package/src/parser/rules/block/bibliography/index.ts +90 -0
  71. package/src/parser/rules/block/bibliography/open.ts +53 -0
  72. package/src/parser/rules/block/block-list/bare-content.ts +105 -0
  73. package/src/parser/rules/block/block-list/bare-paragraph.ts +60 -0
  74. package/src/parser/rules/block/block-list/index.ts +51 -0
  75. package/src/parser/rules/block/block-list/item-content.ts +132 -0
  76. package/src/parser/rules/block/block-list/li-content.ts +107 -0
  77. package/src/parser/rules/block/block-list/li-item.ts +77 -0
  78. package/src/parser/rules/block/block-list/list-block.ts +100 -0
  79. package/src/parser/rules/block/block-list/open.ts +51 -0
  80. package/src/parser/rules/block/block-list/tags.ts +50 -0
  81. package/src/parser/rules/block/blockquote/build.ts +62 -0
  82. package/src/parser/rules/block/blockquote/index.ts +80 -0
  83. package/src/parser/rules/block/blockquote/line.ts +79 -0
  84. package/src/parser/rules/block/blockquote/lines.ts +39 -0
  85. package/src/parser/rules/block/center/index.ts +72 -0
  86. package/src/parser/rules/block/center/open.ts +27 -0
  87. package/src/parser/rules/block/clear-float/index.ts +51 -0
  88. package/src/parser/rules/block/clear-float/syntax.ts +43 -0
  89. package/src/parser/rules/block/code/attributes.ts +30 -0
  90. package/src/parser/rules/block/code/content.ts +57 -0
  91. package/src/parser/rules/block/code/index.ts +100 -0
  92. package/src/parser/rules/block/collapsible/attributes.ts +95 -0
  93. package/src/parser/rules/block/collapsible/body.ts +69 -0
  94. package/src/parser/rules/block/collapsible/index.ts +117 -0
  95. package/src/parser/rules/block/collapsible/open.ts +51 -0
  96. package/src/parser/rules/block/collapsible/orphans.ts +31 -0
  97. package/src/parser/rules/block/collapsible/tags.ts +17 -0
  98. package/src/parser/rules/block/comment/consume.ts +37 -0
  99. package/src/parser/rules/block/comment/index.ts +47 -0
  100. package/src/parser/rules/block/content-separator/index.ts +49 -0
  101. package/src/parser/rules/block/content-separator/syntax.ts +33 -0
  102. package/src/parser/rules/block/definition-list/collect.ts +40 -0
  103. package/src/parser/rules/block/definition-list/index.ts +63 -0
  104. package/src/parser/rules/block/definition-list/item-key.ts +95 -0
  105. package/src/parser/rules/block/definition-list/item-value.ts +56 -0
  106. package/src/parser/rules/block/definition-list/items.ts +54 -0
  107. package/src/parser/rules/block/div/body.ts +41 -0
  108. package/src/parser/rules/block/div/close.ts +41 -0
  109. package/src/parser/rules/block/div/failed.ts +117 -0
  110. package/src/parser/rules/block/div/index.ts +112 -0
  111. package/src/parser/rules/block/div/nesting.ts +37 -0
  112. package/src/parser/rules/block/div/open.ts +59 -0
  113. package/src/parser/rules/block/div/paragraph-strip.ts +44 -0
  114. package/src/parser/rules/block/embed-block/content.ts +53 -0
  115. package/src/parser/rules/block/embed-block/index.ts +91 -0
  116. package/src/parser/rules/block/embed-block/open.ts +52 -0
  117. package/src/parser/rules/block/embed-block/tags.ts +5 -0
  118. package/src/parser/rules/block/footnoteblock/attributes.ts +73 -0
  119. package/src/parser/rules/block/footnoteblock/index.ts +82 -0
  120. package/src/parser/rules/block/footnoteblock/open.ts +53 -0
  121. package/src/parser/rules/block/heading/index.ts +87 -0
  122. package/src/parser/rules/block/heading/open.ts +50 -0
  123. package/src/parser/rules/block/heading/toc-text.ts +26 -0
  124. package/src/parser/rules/block/horizontal-rule/index.ts +44 -0
  125. package/src/parser/rules/block/horizontal-rule/syntax.ts +21 -0
  126. package/src/parser/rules/block/html/body.ts +114 -0
  127. package/src/parser/rules/block/html/diagnostics.ts +11 -0
  128. package/src/parser/rules/block/html/index.ts +95 -0
  129. package/src/parser/rules/block/html/open.ts +36 -0
  130. package/src/parser/rules/block/iframe/attributes.ts +106 -0
  131. package/src/parser/rules/block/iframe/index.ts +73 -0
  132. package/src/parser/rules/block/iframe/open.ts +58 -0
  133. package/src/parser/rules/block/iframe/source.ts +24 -0
  134. package/src/parser/rules/block/iframe/url.ts +38 -0
  135. package/src/parser/rules/block/iftags/body.ts +48 -0
  136. package/src/parser/rules/block/iftags/condition.ts +24 -0
  137. package/src/parser/rules/block/iftags/index.ts +108 -0
  138. package/src/parser/rules/block/include/arguments.ts +48 -0
  139. package/src/parser/rules/block/include/index.ts +75 -0
  140. package/src/parser/rules/block/include/location.ts +24 -0
  141. package/src/parser/rules/block/include/variables.ts +37 -0
  142. package/src/parser/rules/block/index.ts +127 -0
  143. package/src/parser/rules/block/list/index.ts +73 -0
  144. package/src/parser/rules/block/list/line.ts +77 -0
  145. package/src/parser/rules/block/list/native.ts +89 -0
  146. package/src/parser/rules/block/math/content.ts +54 -0
  147. package/src/parser/rules/block/math/index.ts +106 -0
  148. package/src/parser/rules/block/math/name.ts +35 -0
  149. package/src/parser/rules/block/module/backlinks/index.ts +31 -0
  150. package/src/parser/rules/block/module/backlinks/types.ts +21 -0
  151. package/src/parser/rules/block/module/body.ts +92 -0
  152. package/src/parser/rules/block/module/categories/index.ts +34 -0
  153. package/src/parser/rules/block/module/categories/types.ts +21 -0
  154. package/src/parser/rules/block/module/css/index.ts +37 -0
  155. package/src/parser/rules/block/module/element.ts +33 -0
  156. package/src/parser/rules/block/module/iftags/condition.ts +109 -0
  157. package/src/parser/rules/block/module/iftags/index.ts +26 -0
  158. package/src/parser/rules/block/module/iftags/preprocess.ts +140 -0
  159. package/src/parser/rules/block/module/iftags/resolve.ts +73 -0
  160. package/src/parser/rules/block/module/iftags/types.ts +63 -0
  161. package/src/parser/rules/block/module/include/directive.ts +91 -0
  162. package/src/parser/rules/block/module/include/index.ts +29 -0
  163. package/src/parser/rules/block/module/include/references.ts +42 -0
  164. package/src/parser/rules/block/module/include/resolve/cache.ts +44 -0
  165. package/src/parser/rules/block/module/include/resolve/index.ts +106 -0
  166. package/src/parser/rules/block/module/include/resolve/iterate.ts +202 -0
  167. package/src/parser/rules/block/module/include/resolve/replace.ts +31 -0
  168. package/src/parser/rules/block/module/include/resolve/types.ts +105 -0
  169. package/src/parser/rules/block/module/include/scanner.ts +121 -0
  170. package/src/parser/rules/block/module/index.ts +134 -0
  171. package/src/parser/rules/block/module/join/index.ts +34 -0
  172. package/src/parser/rules/block/module/join/types.ts +23 -0
  173. package/src/parser/rules/block/module/listpages/compiler.ts +73 -0
  174. package/src/parser/rules/block/module/listpages/extract.ts +76 -0
  175. package/src/parser/rules/block/module/listpages/extraction/listpages.ts +42 -0
  176. package/src/parser/rules/block/module/listpages/extraction/listusers.ts +30 -0
  177. package/src/parser/rules/block/module/listpages/extraction/query.ts +51 -0
  178. package/src/parser/rules/block/module/listpages/extraction/result.ts +18 -0
  179. package/src/parser/rules/block/module/listpages/extraction/template.ts +96 -0
  180. package/src/parser/rules/block/module/listpages/extraction/variables.ts +58 -0
  181. package/src/parser/rules/block/module/listpages/index.ts +83 -0
  182. package/src/parser/rules/block/module/listpages/normalization/date-selector.ts +53 -0
  183. package/src/parser/rules/block/module/listpages/normalization/numeric-selector.ts +32 -0
  184. package/src/parser/rules/block/module/listpages/normalization/order-parent.ts +82 -0
  185. package/src/parser/rules/block/module/listpages/normalization/selectors.ts +2 -0
  186. package/src/parser/rules/block/module/listpages/normalization/tags-category.ts +86 -0
  187. package/src/parser/rules/block/module/listpages/normalize.ts +74 -0
  188. package/src/parser/rules/block/module/listpages/parser.ts +106 -0
  189. package/src/parser/rules/block/module/listpages/resolution/items.ts +43 -0
  190. package/src/parser/rules/block/module/listpages/resolution/wrapper.ts +42 -0
  191. package/src/parser/rules/block/module/listpages/resolve.ts +60 -0
  192. package/src/parser/rules/block/module/listpages/template/format/content.ts +41 -0
  193. package/src/parser/rules/block/module/listpages/template/format/date.ts +116 -0
  194. package/src/parser/rules/block/module/listpages/template/format/index.ts +4 -0
  195. package/src/parser/rules/block/module/listpages/template/format/tags.ts +7 -0
  196. package/src/parser/rules/block/module/listpages/template/format/user.ts +9 -0
  197. package/src/parser/rules/block/module/listpages/template/getters/index.ts +36 -0
  198. package/src/parser/rules/block/module/listpages/template/getters/parameterized.ts +60 -0
  199. package/src/parser/rules/block/module/listpages/template/getters/simple.ts +65 -0
  200. package/src/parser/rules/block/module/listpages/template/getters/types.ts +3 -0
  201. package/src/parser/rules/block/module/listpages/template/syntax.ts +97 -0
  202. package/src/parser/rules/block/module/listpages/types/data-fetcher.ts +15 -0
  203. package/src/parser/rules/block/module/listpages/types/data-requirements.ts +52 -0
  204. package/src/parser/rules/block/module/listpages/types/external-data.ts +77 -0
  205. package/src/parser/rules/block/module/listpages/types/index.ts +17 -0
  206. package/src/parser/rules/block/module/listpages/types/normalized-query.ts +120 -0
  207. package/src/parser/rules/block/module/listpages/types/query.ts +67 -0
  208. package/src/parser/rules/block/module/listpages/types/template.ts +17 -0
  209. package/src/parser/rules/block/module/listpages/types/variables.ts +69 -0
  210. package/src/parser/rules/block/module/listpages/url-resolution/fields.ts +48 -0
  211. package/src/parser/rules/block/module/listpages/url-resolution/params.ts +19 -0
  212. package/src/parser/rules/block/module/listpages/url-resolution/query.ts +24 -0
  213. package/src/parser/rules/block/module/listpages/url-resolution/resolve.ts +53 -0
  214. package/src/parser/rules/block/module/listpages/url-resolution/value.ts +25 -0
  215. package/src/parser/rules/block/module/listpages/url-resolver.ts +29 -0
  216. package/src/parser/rules/block/module/listusers/compiler.ts +56 -0
  217. package/src/parser/rules/block/module/listusers/extract.ts +40 -0
  218. package/src/parser/rules/block/module/listusers/getters.ts +21 -0
  219. package/src/parser/rules/block/module/listusers/index.ts +36 -0
  220. package/src/parser/rules/block/module/listusers/parser.ts +54 -0
  221. package/src/parser/rules/block/module/listusers/resolve.ts +58 -0
  222. package/src/parser/rules/block/module/listusers/types.ts +93 -0
  223. package/src/parser/rules/block/module/listusers/variables.ts +15 -0
  224. package/src/parser/rules/block/module/mapping.ts +61 -0
  225. package/src/parser/rules/block/module/open.ts +57 -0
  226. package/src/parser/rules/block/module/page-tree/index.ts +38 -0
  227. package/src/parser/rules/block/module/page-tree/types.ts +29 -0
  228. package/src/parser/rules/block/module/rate/index.ts +28 -0
  229. package/src/parser/rules/block/module/rate/types.ts +19 -0
  230. package/src/parser/rules/block/module/resolution/contexts.ts +78 -0
  231. package/src/parser/rules/block/module/resolution/data-maps.ts +39 -0
  232. package/src/parser/rules/block/module/resolution/dynamic-modules.ts +93 -0
  233. package/src/parser/rules/block/module/resolution/styles.ts +53 -0
  234. package/src/parser/rules/block/module/resolution/walk-resolve.ts +107 -0
  235. package/src/parser/rules/block/module/resolve.ts +198 -0
  236. package/src/parser/rules/block/module/rule.ts +56 -0
  237. package/src/parser/rules/block/module/types-common.ts +70 -0
  238. package/src/parser/rules/block/module/types.ts +61 -0
  239. package/src/parser/rules/block/module/utils.ts +43 -0
  240. package/src/parser/rules/block/module/walk/children.ts +35 -0
  241. package/src/parser/rules/block/module/walk/index.ts +9 -0
  242. package/src/parser/rules/block/module/walk/map/index.ts +2 -0
  243. package/src/parser/rules/block/module/walk/map/stateful-definition-list.ts +25 -0
  244. package/src/parser/rules/block/module/walk/map/stateful-list.ts +40 -0
  245. package/src/parser/rules/block/module/walk/map/stateful-table.ts +23 -0
  246. package/src/parser/rules/block/module/walk/map/stateful-tabs.ts +19 -0
  247. package/src/parser/rules/block/module/walk/map/stateful.ts +71 -0
  248. package/src/parser/rules/block/module/walk/map/stateless-definition-list.ts +12 -0
  249. package/src/parser/rules/block/module/walk/map/stateless-list.ts +29 -0
  250. package/src/parser/rules/block/module/walk/map/stateless-table.ts +11 -0
  251. package/src/parser/rules/block/module/walk/map/stateless-tabs.ts +5 -0
  252. package/src/parser/rules/block/module/walk/map/stateless.ts +51 -0
  253. package/src/parser/rules/block/module/walk/map/types.ts +6 -0
  254. package/src/parser/rules/block/module/walk/traverse.ts +65 -0
  255. package/src/parser/rules/block/orphan-li/content.ts +60 -0
  256. package/src/parser/rules/block/orphan-li/index.ts +75 -0
  257. package/src/parser/rules/block/orphan-li/open.ts +25 -0
  258. package/src/parser/rules/block/orphan-li/tags.ts +40 -0
  259. package/src/parser/rules/block/paragraph/content.ts +12 -0
  260. package/src/parser/rules/block/paragraph/index.ts +60 -0
  261. package/src/parser/rules/block/paragraph/normalize.ts +52 -0
  262. package/src/parser/rules/block/paragraph/span-markers.ts +52 -0
  263. package/src/parser/rules/block/parsing/attributes/index.ts +32 -0
  264. package/src/parser/rules/block/parsing/attributes/names.ts +93 -0
  265. package/src/parser/rules/block/parsing/attributes/scanner.ts +75 -0
  266. package/src/parser/rules/block/parsing/attributes/values.ts +26 -0
  267. package/src/parser/rules/block/parsing/block-item.ts +29 -0
  268. package/src/parser/rules/block/parsing/content.ts +127 -0
  269. package/src/parser/rules/block/parsing/end-condition.ts +51 -0
  270. package/src/parser/rules/block/parsing/inline-content.ts +105 -0
  271. package/src/parser/rules/block/parsing/inline-newline.ts +41 -0
  272. package/src/parser/rules/block/parsing/non-boundary.ts +24 -0
  273. package/src/parser/rules/block/parsing/rule-dispatch.ts +44 -0
  274. package/src/parser/rules/block/table/index.ts +80 -0
  275. package/src/parser/rules/block/table/pipe/cell-start.ts +69 -0
  276. package/src/parser/rules/block/table/pipe/cell.ts +106 -0
  277. package/src/parser/rules/block/table/pipe/index.ts +2 -0
  278. package/src/parser/rules/block/table/pipe/row.ts +88 -0
  279. package/src/parser/rules/block/table/pipe/tokens.ts +14 -0
  280. package/src/parser/rules/block/table/pipe/trim.ts +50 -0
  281. package/src/parser/rules/block/table-block/body.ts +79 -0
  282. package/src/parser/rules/block/table-block/cell-attributes.ts +33 -0
  283. package/src/parser/rules/block/table-block/cell-boundary.ts +99 -0
  284. package/src/parser/rules/block/table-block/cell-content/index.ts +88 -0
  285. package/src/parser/rules/block/table-block/cell-content/segments.ts +134 -0
  286. package/src/parser/rules/block/table-block/cell-newline.ts +47 -0
  287. package/src/parser/rules/block/table-block/cell.ts +64 -0
  288. package/src/parser/rules/block/table-block/index.ts +113 -0
  289. package/src/parser/rules/block/table-block/row-boundary.ts +75 -0
  290. package/src/parser/rules/block/table-block/structure.ts +80 -0
  291. package/src/parser/rules/block/tabview/body.ts +64 -0
  292. package/src/parser/rules/block/tabview/index.ts +90 -0
  293. package/src/parser/rules/block/tabview/open.ts +50 -0
  294. package/src/parser/rules/block/tabview/tab.ts +92 -0
  295. package/src/parser/rules/block/tabview/tags.ts +30 -0
  296. package/src/parser/rules/block/toc/element.ts +11 -0
  297. package/src/parser/rules/block/toc/index.ts +44 -0
  298. package/src/parser/rules/block/toc/open.ts +84 -0
  299. package/src/parser/rules/block/utils.ts +15 -0
  300. package/src/parser/rules/common/attribute-safety.ts +109 -0
  301. package/src/parser/rules/common/block-name.ts +33 -0
  302. package/src/parser/rules/common/index.ts +2 -0
  303. package/src/parser/rules/contracts/index.ts +3 -0
  304. package/src/parser/rules/contracts/parse-context.ts +38 -0
  305. package/src/parser/rules/contracts/rule.ts +43 -0
  306. package/src/parser/rules/contracts/scope.ts +31 -0
  307. package/src/parser/rules/index.ts +49 -0
  308. package/src/parser/rules/inline/anchor/attributes.ts +54 -0
  309. package/src/parser/rules/inline/anchor/child.ts +26 -0
  310. package/src/parser/rules/inline/anchor/close.ts +34 -0
  311. package/src/parser/rules/inline/anchor/content.ts +59 -0
  312. package/src/parser/rules/inline/anchor/index.ts +103 -0
  313. package/src/parser/rules/inline/anchor/newline.ts +26 -0
  314. package/src/parser/rules/inline/anchor/open.ts +47 -0
  315. package/src/parser/rules/inline/anchor/paragraph-strip.ts +14 -0
  316. package/src/parser/rules/inline/anchor/syntax.ts +40 -0
  317. package/src/parser/rules/inline/anchor-name/index.ts +38 -0
  318. package/src/parser/rules/inline/anchor-name/name.ts +39 -0
  319. package/src/parser/rules/inline/anchor-name/syntax.ts +46 -0
  320. package/src/parser/rules/inline/bibcite/element.ts +14 -0
  321. package/src/parser/rules/inline/bibcite/index.ts +34 -0
  322. package/src/parser/rules/inline/bibcite/syntax.ts +64 -0
  323. package/src/parser/rules/inline/bold.ts +49 -0
  324. package/src/parser/rules/inline/color/index.ts +35 -0
  325. package/src/parser/rules/inline/color/syntax.ts +69 -0
  326. package/src/parser/rules/inline/comment/consume.ts +31 -0
  327. package/src/parser/rules/inline/comment/index.ts +64 -0
  328. package/src/parser/rules/inline/equation-ref/element.ts +8 -0
  329. package/src/parser/rules/inline/equation-ref/index.ts +34 -0
  330. package/src/parser/rules/inline/equation-ref/syntax.ts +45 -0
  331. package/src/parser/rules/inline/expr/branch.ts +104 -0
  332. package/src/parser/rules/inline/expr/conditional-branch.ts +27 -0
  333. package/src/parser/rules/inline/expr/conditional.ts +80 -0
  334. package/src/parser/rules/inline/expr/depth.ts +25 -0
  335. package/src/parser/rules/inline/expr/elements.ts +39 -0
  336. package/src/parser/rules/inline/expr/index.ts +84 -0
  337. package/src/parser/rules/inline/expr/syntax.ts +45 -0
  338. package/src/parser/rules/inline/footnote/child.ts +22 -0
  339. package/src/parser/rules/inline/footnote/close.ts +33 -0
  340. package/src/parser/rules/inline/footnote/content.ts +54 -0
  341. package/src/parser/rules/inline/footnote/elements.ts +38 -0
  342. package/src/parser/rules/inline/footnote/index.ts +54 -0
  343. package/src/parser/rules/inline/footnote/newline.ts +27 -0
  344. package/src/parser/rules/inline/footnote/open.ts +38 -0
  345. package/src/parser/rules/inline/formatting/container.ts +50 -0
  346. package/src/parser/rules/inline/guillemet/index.ts +56 -0
  347. package/src/parser/rules/inline/guillemet/text.ts +11 -0
  348. package/src/parser/rules/inline/html/gate.ts +64 -0
  349. package/src/parser/rules/inline/html/index.ts +81 -0
  350. package/src/parser/rules/inline/html/open.ts +37 -0
  351. package/src/parser/rules/inline/image/attributes.ts +22 -0
  352. package/src/parser/rules/inline/image/body.ts +36 -0
  353. package/src/parser/rules/inline/image/index.ts +89 -0
  354. package/src/parser/rules/inline/image/open.ts +56 -0
  355. package/src/parser/rules/inline/image/source.ts +62 -0
  356. package/src/parser/rules/inline/image/syntax.ts +76 -0
  357. package/src/parser/rules/inline/index.ts +150 -0
  358. package/src/parser/rules/inline/italic.ts +46 -0
  359. package/src/parser/rules/inline/line-break/backslash.ts +58 -0
  360. package/src/parser/rules/inline/line-break/elements.ts +9 -0
  361. package/src/parser/rules/inline/line-break/index.ts +3 -0
  362. package/src/parser/rules/inline/line-break/newline.ts +82 -0
  363. package/src/parser/rules/inline/line-break/underscore.ts +45 -0
  364. package/src/parser/rules/inline/link-anchor.ts +72 -0
  365. package/src/parser/rules/inline/link-bracket/anchor.ts +3 -0
  366. package/src/parser/rules/inline/link-bracket/direct-url.ts +5 -0
  367. package/src/parser/rules/inline/link-bracket/parsed.ts +81 -0
  368. package/src/parser/rules/inline/link-bracket/parts.ts +64 -0
  369. package/src/parser/rules/inline/link-bracket/prefix.ts +15 -0
  370. package/src/parser/rules/inline/link-single.ts +73 -0
  371. package/src/parser/rules/inline/link-star.ts +72 -0
  372. package/src/parser/rules/inline/link-triple/fallback.ts +10 -0
  373. package/src/parser/rules/inline/link-triple/index.ts +62 -0
  374. package/src/parser/rules/inline/link-triple/interwiki.ts +11 -0
  375. package/src/parser/rules/inline/link-triple/label.ts +35 -0
  376. package/src/parser/rules/inline/link-triple/syntax.ts +72 -0
  377. package/src/parser/rules/inline/link-triple/target.ts +36 -0
  378. package/src/parser/rules/inline/math-inline/index.ts +40 -0
  379. package/src/parser/rules/inline/math-inline/syntax.ts +55 -0
  380. package/src/parser/rules/inline/monospace.ts +50 -0
  381. package/src/parser/rules/inline/parsing/block-boundary.ts +42 -0
  382. package/src/parser/rules/inline/parsing/block-start-predicates.ts +117 -0
  383. package/src/parser/rules/inline/parsing/collect.ts +23 -0
  384. package/src/parser/rules/inline/parsing/inline-content.ts +115 -0
  385. package/src/parser/rules/inline/parsing/paragraph-boundary.ts +47 -0
  386. package/src/parser/rules/inline/parsing/plain-text.ts +69 -0
  387. package/src/parser/rules/inline/parsing/preserved-line-break.ts +11 -0
  388. package/src/parser/rules/inline/parsing/rules.ts +34 -0
  389. package/src/parser/rules/inline/parsing/simple-token.ts +26 -0
  390. package/src/parser/rules/inline/raw/angle.ts +40 -0
  391. package/src/parser/rules/inline/raw/double-at.ts +78 -0
  392. package/src/parser/rules/inline/raw/index.ts +26 -0
  393. package/src/parser/rules/inline/raw/result.ts +26 -0
  394. package/src/parser/rules/inline/size/content.ts +65 -0
  395. package/src/parser/rules/inline/size/index.ts +55 -0
  396. package/src/parser/rules/inline/size/open.ts +43 -0
  397. package/src/parser/rules/inline/size/value.ts +45 -0
  398. package/src/parser/rules/inline/span/content.ts +97 -0
  399. package/src/parser/rules/inline/span/elements.ts +108 -0
  400. package/src/parser/rules/inline/span/index.ts +79 -0
  401. package/src/parser/rules/inline/span/newline.ts +50 -0
  402. package/src/parser/rules/inline/span/syntax.ts +70 -0
  403. package/src/parser/rules/inline/strikethrough/index.ts +60 -0
  404. package/src/parser/rules/inline/strikethrough/parse.ts +14 -0
  405. package/src/parser/rules/inline/strikethrough/syntax.ts +24 -0
  406. package/src/parser/rules/inline/subscript.ts +47 -0
  407. package/src/parser/rules/inline/superscript.ts +49 -0
  408. package/src/parser/rules/inline/text/element.ts +5 -0
  409. package/src/parser/rules/inline/text/index.ts +85 -0
  410. package/src/parser/rules/inline/underline/child.ts +26 -0
  411. package/src/parser/rules/inline/underline/content.ts +29 -0
  412. package/src/parser/rules/inline/underline/index.ts +84 -0
  413. package/src/parser/rules/inline/user/element.ts +11 -0
  414. package/src/parser/rules/inline/user/index.ts +34 -0
  415. package/src/parser/rules/inline/user/syntax.ts +67 -0
  416. package/src/parser/rules/inline/utils.ts +4 -0
  417. package/src/parser/rules/tokens.ts +106 -0
  418. package/src/parser/rules/types.ts +9 -0
  419. package/src/parser/toc.ts +130 -0
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Paragraph rule
3
+ *
4
+ * Collects inline content until paragraph break (double newline) or end of input.
5
+ * Line breaks within paragraphs are handled by the newlineLineBreakRule.
6
+ */
7
+ import type { Element } from "@wdprlib/ast";
8
+ import type { BlockRule, ParseContext, RuleResult } from "../../types";
9
+ import { parseInlineContent } from "./content";
10
+ import { normalizeParagraphElements } from "./normalize";
11
+
12
+ /**
13
+ * Paragraph is the fallback block rule.
14
+ *
15
+ * Wikidot behavior:
16
+ * - Single newline -> <br> (handled by newlineLineBreakRule)
17
+ * - Blank line (double newline) -> new paragraph
18
+ */
19
+ export const paragraphRule: BlockRule = {
20
+ name: "paragraph",
21
+ startTokens: [],
22
+ requiresLineStart: false,
23
+
24
+ parse(ctx: ParseContext): RuleResult<Element> {
25
+ const result = parseInlineContent(ctx);
26
+ if (result.elements.length === 0) {
27
+ return { success: false };
28
+ }
29
+
30
+ const elements = normalizeParagraphElements(result.elements);
31
+ if (elements.length === 0) {
32
+ return { success: false };
33
+ }
34
+
35
+ const nextPos = ctx.pos + result.consumed;
36
+ const nextToken = ctx.tokens[nextPos];
37
+ if (nextToken?.type === "COLON" && nextToken.lineStart) {
38
+ return {
39
+ success: true,
40
+ elements: [...elements, { element: "line-break" }],
41
+ consumed: result.consumed,
42
+ };
43
+ }
44
+
45
+ return {
46
+ success: true,
47
+ elements: [
48
+ {
49
+ element: "container",
50
+ data: {
51
+ type: "paragraph",
52
+ attributes: {},
53
+ elements,
54
+ },
55
+ },
56
+ ],
57
+ consumed: result.consumed,
58
+ };
59
+ },
60
+ };
@@ -0,0 +1,52 @@
1
+ import type { Element } from "@wdprlib/ast";
2
+ import { processCloseSpanMarkers } from "./span-markers";
3
+
4
+ type PreservedLineBreak = Extract<Element, { element: "line-break" }> & {
5
+ _preservedTrailingBreak?: boolean;
6
+ };
7
+
8
+ export function normalizeParagraphElements(source: Element[]): Element[] {
9
+ let elements = processCloseSpanMarkers(source);
10
+
11
+ removeTrailingLineBreaks(elements);
12
+ removeTrailingWhitespaceText(elements);
13
+ elements = removeLeadingLineBreaks(elements);
14
+
15
+ return elements;
16
+ }
17
+
18
+ function removeTrailingLineBreaks(elements: Element[]): void {
19
+ while (elements.length > 0 && elements[elements.length - 1]?.element === "line-break") {
20
+ const lastEl = elements[elements.length - 1] as PreservedLineBreak;
21
+ if (lastEl._preservedTrailingBreak) {
22
+ delete lastEl._preservedTrailingBreak;
23
+ break;
24
+ }
25
+ elements.pop();
26
+ }
27
+ }
28
+
29
+ function removeTrailingWhitespaceText(elements: Element[]): void {
30
+ while (elements.length > 0) {
31
+ const last = elements[elements.length - 1];
32
+ if (
33
+ last?.element === "text" &&
34
+ "data" in last &&
35
+ typeof last.data === "string" &&
36
+ last.data.trim() === ""
37
+ ) {
38
+ elements.pop();
39
+ } else {
40
+ break;
41
+ }
42
+ }
43
+ }
44
+
45
+ function removeLeadingLineBreaks(elements: Element[]): Element[] {
46
+ let first = 0;
47
+ while (first < elements.length && elements[first]?.element === "line-break") {
48
+ first++;
49
+ }
50
+
51
+ return first > 0 ? elements.slice(first) : elements;
52
+ }
@@ -0,0 +1,52 @@
1
+ import type { Element } from "@wdprlib/ast";
2
+
3
+ /**
4
+ * Process closeSpan markers in inline content.
5
+ *
6
+ * When a `_closeSpan` marker is found, all preceding content is wrapped
7
+ * in a span and the marker itself is omitted.
8
+ */
9
+ export function processCloseSpanMarkers(elements: Element[]): Element[] {
10
+ let result: Element[] | null = null;
11
+
12
+ for (let i = 0; i < elements.length; i++) {
13
+ const elem = elements[i];
14
+ if (!elem) continue;
15
+
16
+ if (isCloseSpanMarker(elem)) {
17
+ if (result === null) {
18
+ result = elements.slice(0, i);
19
+ }
20
+ if (result.length > 0) {
21
+ const spanContent = [...result];
22
+ result.length = 0;
23
+ result.push({
24
+ element: "container",
25
+ data: {
26
+ type: "span",
27
+ attributes: {},
28
+ elements: spanContent,
29
+ },
30
+ });
31
+ }
32
+ } else {
33
+ result?.push(elem);
34
+ }
35
+ }
36
+
37
+ return result ?? elements;
38
+ }
39
+
40
+ function isCloseSpanMarker(elem: Element): boolean {
41
+ return (
42
+ elem.element === "container" &&
43
+ elem.data &&
44
+ typeof elem.data === "object" &&
45
+ "type" in elem.data &&
46
+ elem.data.type === "span" &&
47
+ "attributes" in elem.data &&
48
+ typeof elem.data.attributes === "object" &&
49
+ elem.data.attributes !== null &&
50
+ "_closeSpan" in elem.data.attributes
51
+ );
52
+ }
@@ -0,0 +1,32 @@
1
+ import type { ParseContext } from "../../../types";
2
+ import { filterUnsafeAttributes } from "../../../common";
3
+ import { scanAttributes, type AttributeParseResult } from "./scanner";
4
+
5
+ /**
6
+ * Parses HTML-style attributes from block opening tags.
7
+ *
8
+ * Supports quoted values, single-token unquoted values, boolean attributes,
9
+ * and hyphenated names like `data-paragraph` or `aria-label`.
10
+ *
11
+ * Attribute names are lowercased. The result is filtered through
12
+ * `filterUnsafeAttributes` to strip potentially dangerous HTML attributes.
13
+ */
14
+ export function parseAttributes(ctx: ParseContext, startPos: number): AttributeParseResult {
15
+ const result = scanAttributes(ctx, startPos, { hyphenatedNames: true, strikeHyphens: false });
16
+ return { attrs: filterUnsafeAttributes(result.attrs), consumed: result.consumed };
17
+ }
18
+
19
+ /**
20
+ * Parses attributes from block opening tags without safety filtering.
21
+ *
22
+ * Use this for block-specific parameters that are not emitted as HTML
23
+ * attributes. Hyphenated name handling is configurable for legacy parser
24
+ * contexts that need the first segment only.
25
+ */
26
+ export function parseAttributesRaw(
27
+ ctx: ParseContext,
28
+ startPos: number,
29
+ hyphenatedNames = true,
30
+ ): AttributeParseResult {
31
+ return scanAttributes(ctx, startPos, { hyphenatedNames, strikeHyphens: true });
32
+ }
@@ -0,0 +1,93 @@
1
+ import type { Token } from "../../../../../lexer";
2
+ import type { ParseContext } from "../../../types";
3
+
4
+ export interface AttributeNameOptions {
5
+ hyphenatedNames: boolean;
6
+ strikeHyphens: boolean;
7
+ }
8
+
9
+ export interface AttributeNameResult {
10
+ name: string;
11
+ pos: number;
12
+ consumed: number;
13
+ }
14
+
15
+ export function consumeAttributeName(
16
+ ctx: ParseContext,
17
+ startPos: number,
18
+ startConsumed: number,
19
+ startName: string,
20
+ options: AttributeNameOptions,
21
+ ): AttributeNameResult {
22
+ return options.strikeHyphens
23
+ ? consumeRawNameSuffix(ctx, startPos, startConsumed, startName, options.hyphenatedNames)
24
+ : consumeSafeNameSuffix(ctx, startPos, startConsumed, startName);
25
+ }
26
+
27
+ export function isAttributeNameToken(token: Token | undefined): token is Token {
28
+ return token?.type === "TEXT" || token?.type === "IDENTIFIER";
29
+ }
30
+
31
+ function consumeSafeNameSuffix(
32
+ ctx: ParseContext,
33
+ startPos: number,
34
+ startConsumed: number,
35
+ startName: string,
36
+ ): AttributeNameResult {
37
+ let name = startName;
38
+ let pos = startPos;
39
+ let consumed = startConsumed;
40
+
41
+ while (
42
+ ctx.tokens[pos]?.type === "TEXT" &&
43
+ ctx.tokens[pos]?.value === "-" &&
44
+ isAttributeNameToken(ctx.tokens[pos + 1])
45
+ ) {
46
+ name += "-";
47
+ pos++;
48
+ consumed++;
49
+ name += ctx.tokens[pos]?.value ?? "";
50
+ pos++;
51
+ consumed++;
52
+ }
53
+
54
+ return { name, pos, consumed };
55
+ }
56
+
57
+ function consumeRawNameSuffix(
58
+ ctx: ParseContext,
59
+ startPos: number,
60
+ startConsumed: number,
61
+ startName: string,
62
+ hyphenatedNames: boolean,
63
+ ): AttributeNameResult {
64
+ let name = startName;
65
+ let pos = startPos;
66
+ let consumed = startConsumed;
67
+
68
+ while (isHyphenToken(ctx.tokens[pos])) {
69
+ while (isHyphenToken(ctx.tokens[pos])) {
70
+ if (hyphenatedNames) {
71
+ name += ctx.tokens[pos]?.value ?? "-";
72
+ }
73
+ pos++;
74
+ consumed++;
75
+ }
76
+
77
+ if (!isAttributeNameToken(ctx.tokens[pos])) {
78
+ break;
79
+ }
80
+
81
+ if (hyphenatedNames) {
82
+ name += ctx.tokens[pos]?.value ?? "";
83
+ }
84
+ pos++;
85
+ consumed++;
86
+ }
87
+
88
+ return { name, pos, consumed };
89
+ }
90
+
91
+ function isHyphenToken(token: Token | undefined): boolean {
92
+ return (token?.type === "TEXT" && token.value === "-") || token?.type === "STRIKE_MARKER";
93
+ }
@@ -0,0 +1,75 @@
1
+ import type { Token } from "../../../../../lexer";
2
+ import type { ParseContext } from "../../../types";
3
+ import { consumeAttributeName, isAttributeNameToken } from "./names";
4
+ import { consumeAttributeValue } from "./values";
5
+
6
+ export interface AttributeParseResult {
7
+ attrs: Record<string, string>;
8
+ consumed: number;
9
+ }
10
+
11
+ interface AttributeScanOptions {
12
+ hyphenatedNames: boolean;
13
+ strikeHyphens: boolean;
14
+ }
15
+
16
+ export function scanAttributes(
17
+ ctx: ParseContext,
18
+ startPos: number,
19
+ options: AttributeScanOptions,
20
+ ): AttributeParseResult {
21
+ const attrs: Record<string, string> = {};
22
+ let pos = startPos;
23
+ let consumed = 0;
24
+
25
+ while (pos < ctx.tokens.length) {
26
+ const token = ctx.tokens[pos];
27
+ if (!token || isAttributeTerminator(token)) {
28
+ break;
29
+ }
30
+
31
+ if (token.type === "WHITESPACE") {
32
+ pos++;
33
+ consumed++;
34
+ continue;
35
+ }
36
+
37
+ if (!isAttributeNameToken(token)) {
38
+ pos++;
39
+ consumed++;
40
+ continue;
41
+ }
42
+
43
+ let name = token.value;
44
+ pos++;
45
+ consumed++;
46
+
47
+ const nameResult = consumeAttributeName(ctx, pos, consumed, name, options);
48
+ pos = nameResult.pos;
49
+ consumed = nameResult.consumed;
50
+ name = nameResult.name.toLowerCase();
51
+
52
+ if (ctx.tokens[pos]?.type !== "EQUALS") {
53
+ attrs[name] = "true";
54
+ continue;
55
+ }
56
+
57
+ pos++;
58
+ consumed++;
59
+
60
+ const valueResult = consumeAttributeValue(ctx.tokens[pos]);
61
+ if (!valueResult) {
62
+ continue;
63
+ }
64
+
65
+ attrs[name] = valueResult.value;
66
+ pos++;
67
+ consumed++;
68
+ }
69
+
70
+ return { attrs, consumed };
71
+ }
72
+
73
+ function isAttributeTerminator(token: Token): boolean {
74
+ return token.type === "BLOCK_CLOSE" || token.type === "NEWLINE" || token.type === "EOF";
75
+ }
@@ -0,0 +1,26 @@
1
+ import type { Token } from "../../../../../lexer";
2
+ import { isAttributeNameToken } from "./names";
3
+
4
+ export interface AttributeValueResult {
5
+ value: string;
6
+ }
7
+
8
+ export function consumeAttributeValue(token: Token | undefined): AttributeValueResult | null {
9
+ if (!token) {
10
+ return null;
11
+ }
12
+
13
+ if (token.type === "QUOTED_STRING") {
14
+ return { value: stripQuotes(token.value) };
15
+ }
16
+
17
+ if (isAttributeNameToken(token)) {
18
+ return { value: token.value };
19
+ }
20
+
21
+ return null;
22
+ }
23
+
24
+ function stripQuotes(value: string): string {
25
+ return value.startsWith('"') && value.endsWith('"') ? value.slice(1, -1) : value;
26
+ }
@@ -0,0 +1,29 @@
1
+ import type { Element } from "@wdprlib/ast";
2
+ import type { ParseContext } from "../../types";
3
+ import { getCandidateBlockRules } from "./rule-dispatch";
4
+
5
+ export interface BlockItemResult {
6
+ elements: Element[];
7
+ consumed: number;
8
+ }
9
+
10
+ export function parseBlockItem(ctx: ParseContext): BlockItemResult {
11
+ const token = ctx.tokens[ctx.pos];
12
+ if (!token) {
13
+ return { elements: [], consumed: 0 };
14
+ }
15
+
16
+ for (const rule of getCandidateBlockRules(ctx.blockRules, token)) {
17
+ const result = rule.parse(ctx);
18
+ if (result.success) {
19
+ return { elements: result.elements, consumed: result.consumed };
20
+ }
21
+ }
22
+
23
+ const fallback = ctx.blockFallbackRule.parse(ctx);
24
+ if (fallback.success && fallback.elements.length > 0) {
25
+ return { elements: fallback.elements, consumed: fallback.consumed };
26
+ }
27
+
28
+ return { elements: [], consumed: 1 };
29
+ }
@@ -0,0 +1,127 @@
1
+ import type { Element } from "@wdprlib/ast";
2
+ import type { ParseContext } from "../../types";
3
+ import { parseBlockItem } from "./block-item";
4
+
5
+ export interface BlockParseResult {
6
+ /** The parsed AST elements. */
7
+ elements: Element[];
8
+ /** Total number of tokens consumed from the stream. */
9
+ consumed: number;
10
+ }
11
+
12
+ const excludedBlockRulesCache = new WeakMap<
13
+ ParseContext["blockRules"],
14
+ WeakMap<ReadonlySet<string>, ParseContext["blockRules"]>
15
+ >();
16
+
17
+ /**
18
+ * Parses block-level elements from the token stream until a close
19
+ * condition is satisfied.
20
+ *
21
+ * This is the workhorse parser used by container blocks (div, collapsible,
22
+ * tabview, iftags, align, etc.) to parse their body content. It loops
23
+ * through tokens, trying each block rule in priority order, and falls back
24
+ * to the paragraph rule when nothing else matches.
25
+ *
26
+ * Whitespace and newline tokens between blocks are silently consumed.
27
+ * The close condition receives a ParseContext snapshot at the current
28
+ * position and should return `true` to stop parsing (the close tag
29
+ * itself is NOT consumed here -- the caller handles that).
30
+ *
31
+ * The close condition is also injected into `blockCloseCondition` on
32
+ * the context so that the paragraph parser can respect the enclosing
33
+ * block's boundary.
34
+ *
35
+ * @param ctx - Parse context positioned at the start of the body.
36
+ * @param closeCondition - Predicate that signals the end of the block body.
37
+ * @param options - Optional settings.
38
+ * @param options.excludedBlockNames - Block names that should be excluded
39
+ * from both rule dispatch and paragraph-boundary detection. The named
40
+ * rules are filtered out of `blockRules`, and the set is propagated to
41
+ * the inline parser via `ParseContext.excludedBlockNames` so that
42
+ * `BLOCK_OPEN` / `BLOCK_END_OPEN` tokens for these names do not trigger
43
+ * paragraph breaks.
44
+ * @returns Parsed elements and total tokens consumed.
45
+ */
46
+ export function parseBlocksUntil(
47
+ ctx: ParseContext,
48
+ closeCondition: (ctx: ParseContext) => boolean,
49
+ options?: { excludedBlockNames?: ReadonlySet<string> },
50
+ ): BlockParseResult {
51
+ const elements: Element[] = [];
52
+ let consumed = 0;
53
+ let pos = ctx.pos;
54
+
55
+ const excluded = options?.excludedBlockNames;
56
+ const blockRules = excluded ? getExcludedBlockRules(ctx.blockRules, excluded) : ctx.blockRules;
57
+ const blockScope = {
58
+ ...ctx.scope,
59
+ blockCloseCondition: closeCondition,
60
+ excludedBlockNames: excluded,
61
+ };
62
+ const checkCtx: ParseContext = { ...ctx, pos };
63
+ const blockCtx: ParseContext = {
64
+ ...ctx,
65
+ pos,
66
+ blockRules,
67
+ scope: blockScope,
68
+ };
69
+
70
+ while (pos < ctx.tokens.length) {
71
+ const token = ctx.tokens[pos];
72
+ if (!token || token.type === "EOF") {
73
+ break;
74
+ }
75
+
76
+ // Check close condition
77
+ checkCtx.pos = pos;
78
+ if (closeCondition(checkCtx)) {
79
+ break;
80
+ }
81
+
82
+ // Skip whitespace
83
+ if (token.type === "WHITESPACE") {
84
+ pos++;
85
+ consumed++;
86
+ continue;
87
+ }
88
+
89
+ // Skip newlines
90
+ if (token.type === "NEWLINE") {
91
+ pos++;
92
+ consumed++;
93
+ continue;
94
+ }
95
+
96
+ // Pass close condition and excluded names to context
97
+ blockCtx.pos = pos;
98
+ blockCtx.scope = blockScope;
99
+
100
+ const result = parseBlockItem(blockCtx);
101
+ elements.push(...result.elements);
102
+ consumed += result.consumed;
103
+ pos += result.consumed;
104
+ }
105
+
106
+ return { elements, consumed };
107
+ }
108
+
109
+ function getExcludedBlockRules(
110
+ blockRules: ParseContext["blockRules"],
111
+ excluded: ReadonlySet<string>,
112
+ ): ParseContext["blockRules"] {
113
+ let byExcluded = excludedBlockRulesCache.get(blockRules);
114
+ if (!byExcluded) {
115
+ byExcluded = new WeakMap();
116
+ excludedBlockRulesCache.set(blockRules, byExcluded);
117
+ }
118
+
119
+ const cached = byExcluded.get(excluded);
120
+ if (cached) {
121
+ return cached;
122
+ }
123
+
124
+ const filtered = blockRules.filter((rule) => !excluded.has(rule.name));
125
+ byExcluded.set(excluded, filtered);
126
+ return filtered;
127
+ }
@@ -0,0 +1,51 @@
1
+ import type { ParseContext } from "../../types";
2
+ import { parseBlockName } from "../utils";
3
+
4
+ /**
5
+ * Creates a reusable close-condition function that matches block end tags
6
+ * (`[[/name]]`) for one or more block names.
7
+ *
8
+ * The returned function inspects the tokens at `ctx.pos` and returns both
9
+ * whether a match was found and how many tokens the closing tag occupies
10
+ * (including the optional trailing NEWLINE).
11
+ *
12
+ * @param blockNames - Array of block names to match (e.g. `["div"]`).
13
+ * @returns A function suitable for use as a `closeCondition` argument,
14
+ * returning `{ matched, consumed }`.
15
+ */
16
+ export function createBlockEndCondition(
17
+ blockNames: string[],
18
+ ): (ctx: ParseContext) => { matched: boolean; consumed: number } {
19
+ return (ctx: ParseContext) => {
20
+ const token = ctx.tokens[ctx.pos];
21
+ if (token?.type !== "BLOCK_END_OPEN") {
22
+ return { matched: false, consumed: 0 };
23
+ }
24
+
25
+ const nameResult = parseBlockName(ctx, ctx.pos + 1);
26
+ if (!nameResult) {
27
+ return { matched: false, consumed: 0 };
28
+ }
29
+
30
+ if (!blockNames.includes(nameResult.name)) {
31
+ return { matched: false, consumed: 0 };
32
+ }
33
+
34
+ // Calculate consumed: [[/ + name + ]]
35
+ let consumed = 1 + nameResult.consumed;
36
+
37
+ // Check for closing ]]
38
+ const closePos = ctx.pos + 1 + nameResult.consumed;
39
+ if (ctx.tokens[closePos]?.type === "BLOCK_CLOSE") {
40
+ consumed++;
41
+ }
42
+
43
+ // Check for trailing newline
44
+ const newlinePos = closePos + 1;
45
+ if (ctx.tokens[newlinePos]?.type === "NEWLINE") {
46
+ consumed++;
47
+ }
48
+
49
+ return { matched: true, consumed };
50
+ };
51
+ }