@wdprlib/parser 3.2.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (433) hide show
  1. package/dist/index.cjs +10451 -8402
  2. package/dist/index.d.cts +313 -337
  3. package/dist/index.d.ts +313 -337
  4. package/dist/index.js +10438 -8389
  5. package/package.json +1 -1
  6. package/src/index.ts +7 -0
  7. package/src/lexer/anchor.ts +48 -0
  8. package/src/lexer/index.ts +3 -2
  9. package/src/lexer/lexer.ts +73 -559
  10. package/src/lexer/options.ts +19 -0
  11. package/src/lexer/punctuation.ts +70 -0
  12. package/src/lexer/quoted-string.ts +16 -0
  13. package/src/lexer/runs.ts +85 -0
  14. package/src/lexer/spacing-actions.ts +24 -0
  15. package/src/lexer/state.ts +103 -0
  16. package/src/lexer/syntax-actions.ts +80 -0
  17. package/src/lexer/text-actions.ts +41 -0
  18. package/src/lexer/token-actions.ts +136 -0
  19. package/src/lexer/token-factory.ts +62 -0
  20. package/src/lexer/tokenize.ts +18 -0
  21. package/src/parser/constants.ts +2 -0
  22. package/src/parser/depth/index.ts +111 -0
  23. package/src/parser/depth/stack.ts +82 -0
  24. package/src/parser/parse/block.ts +42 -0
  25. package/src/parser/parse/context.ts +26 -0
  26. package/src/parser/parse/footnotes.ts +25 -0
  27. package/src/parser/parse/index.ts +42 -0
  28. package/src/parser/parse/options.ts +34 -0
  29. package/src/parser/parse/parser.ts +79 -0
  30. package/src/parser/parse/plain-non-ascii.ts +129 -0
  31. package/src/parser/parse/result.ts +57 -0
  32. package/src/parser/parse/source.ts +11 -0
  33. package/src/parser/postprocess/divAdjacentParagraph.ts +1 -1
  34. package/src/parser/postprocess/spanStrip/clean-element.ts +168 -0
  35. package/src/parser/postprocess/spanStrip/cleanup.ts +25 -0
  36. package/src/parser/postprocess/spanStrip/empty-spans.ts +36 -0
  37. package/src/parser/postprocess/spanStrip/escaped.ts +78 -0
  38. package/src/parser/postprocess/spanStrip/factory.ts +23 -0
  39. package/src/parser/postprocess/spanStrip/index.ts +8 -0
  40. package/src/parser/postprocess/spanStrip/merge.ts +117 -0
  41. package/src/parser/postprocess/spanStrip/predicates.ts +59 -0
  42. package/src/parser/postprocess/spanStrip/split.ts +67 -0
  43. package/src/parser/preprocess/expr/chars.ts +15 -0
  44. package/src/parser/preprocess/expr/evaluate.ts +22 -0
  45. package/src/parser/preprocess/expr/index.ts +45 -0
  46. package/src/parser/preprocess/expr/kind.ts +19 -0
  47. package/src/parser/preprocess/expr/parse.ts +103 -0
  48. package/src/parser/preprocess/expr/scan.ts +34 -0
  49. package/src/parser/preprocess/expr/types.ts +14 -0
  50. package/src/parser/preprocess/typography.ts +70 -5
  51. package/src/parser/preprocess/utils/bracket-depths.ts +98 -0
  52. package/src/parser/preprocess/utils/index.ts +13 -0
  53. package/src/parser/preprocess/utils/raw-regions.ts +153 -0
  54. package/src/parser/preprocess/whitespace/detection.ts +39 -0
  55. package/src/parser/preprocess/whitespace/index.ts +79 -0
  56. package/src/parser/preprocess/whitespace/leading-spaces.ts +11 -0
  57. package/src/parser/preprocess/whitespace/patterns.ts +23 -0
  58. package/src/parser/rules/block/align/body.ts +46 -0
  59. package/src/parser/rules/block/align/element.ts +13 -0
  60. package/src/parser/rules/block/align/index.ts +90 -0
  61. package/src/parser/rules/block/align/syntax.ts +113 -0
  62. package/src/parser/rules/block/bibliography/body.ts +81 -0
  63. package/src/parser/rules/block/bibliography/entries.ts +49 -0
  64. package/src/parser/rules/block/bibliography/entry-content.ts +73 -0
  65. package/src/parser/rules/block/bibliography/entry-key.ts +83 -0
  66. package/src/parser/rules/block/bibliography/index.ts +90 -0
  67. package/src/parser/rules/block/bibliography/open.ts +53 -0
  68. package/src/parser/rules/block/block-list/bare-content.ts +105 -0
  69. package/src/parser/rules/block/block-list/bare-paragraph.ts +60 -0
  70. package/src/parser/rules/block/block-list/index.ts +51 -0
  71. package/src/parser/rules/block/block-list/item-content.ts +132 -0
  72. package/src/parser/rules/block/block-list/li-content.ts +107 -0
  73. package/src/parser/rules/block/block-list/li-item.ts +77 -0
  74. package/src/parser/rules/block/block-list/list-block.ts +100 -0
  75. package/src/parser/rules/block/block-list/open.ts +51 -0
  76. package/src/parser/rules/block/block-list/tags.ts +50 -0
  77. package/src/parser/rules/block/blockquote/build.ts +62 -0
  78. package/src/parser/rules/block/blockquote/index.ts +80 -0
  79. package/src/parser/rules/block/blockquote/line.ts +79 -0
  80. package/src/parser/rules/block/blockquote/lines.ts +39 -0
  81. package/src/parser/rules/block/{center.ts → center/index.ts} +7 -22
  82. package/src/parser/rules/block/center/open.ts +27 -0
  83. package/src/parser/rules/block/{clear-float.ts → clear-float/index.ts} +6 -30
  84. package/src/parser/rules/block/clear-float/syntax.ts +43 -0
  85. package/src/parser/rules/block/code/attributes.ts +30 -0
  86. package/src/parser/rules/block/code/content.ts +57 -0
  87. package/src/parser/rules/block/code/index.ts +100 -0
  88. package/src/parser/rules/block/collapsible/attributes.ts +95 -0
  89. package/src/parser/rules/block/collapsible/body.ts +69 -0
  90. package/src/parser/rules/block/collapsible/index.ts +117 -0
  91. package/src/parser/rules/block/collapsible/open.ts +51 -0
  92. package/src/parser/rules/block/collapsible/orphans.ts +31 -0
  93. package/src/parser/rules/block/collapsible/tags.ts +17 -0
  94. package/src/parser/rules/block/comment/consume.ts +37 -0
  95. package/src/parser/rules/block/{comment.ts → comment/index.ts} +12 -38
  96. package/src/parser/rules/block/{content-separator.ts → content-separator/index.ts} +5 -35
  97. package/src/parser/rules/block/content-separator/syntax.ts +33 -0
  98. package/src/parser/rules/block/definition-list/collect.ts +40 -0
  99. package/src/parser/rules/block/definition-list/index.ts +63 -0
  100. package/src/parser/rules/block/definition-list/item-key.ts +95 -0
  101. package/src/parser/rules/block/definition-list/item-value.ts +56 -0
  102. package/src/parser/rules/block/definition-list/items.ts +54 -0
  103. package/src/parser/rules/block/div/body.ts +41 -0
  104. package/src/parser/rules/block/div/close.ts +41 -0
  105. package/src/parser/rules/block/div/failed.ts +117 -0
  106. package/src/parser/rules/block/div/index.ts +112 -0
  107. package/src/parser/rules/block/div/nesting.ts +37 -0
  108. package/src/parser/rules/block/div/open.ts +59 -0
  109. package/src/parser/rules/block/div/paragraph-strip.ts +44 -0
  110. package/src/parser/rules/block/embed-block/content.ts +53 -0
  111. package/src/parser/rules/block/embed-block/index.ts +91 -0
  112. package/src/parser/rules/block/embed-block/open.ts +52 -0
  113. package/src/parser/rules/block/embed-block/tags.ts +5 -0
  114. package/src/parser/rules/block/footnoteblock/attributes.ts +73 -0
  115. package/src/parser/rules/block/footnoteblock/index.ts +82 -0
  116. package/src/parser/rules/block/footnoteblock/open.ts +53 -0
  117. package/src/parser/rules/block/heading/index.ts +87 -0
  118. package/src/parser/rules/block/heading/open.ts +50 -0
  119. package/src/parser/rules/block/heading/toc-text.ts +26 -0
  120. package/src/parser/rules/block/{horizontal-rule.ts → horizontal-rule/index.ts} +4 -21
  121. package/src/parser/rules/block/horizontal-rule/syntax.ts +21 -0
  122. package/src/parser/rules/block/html/body.ts +114 -0
  123. package/src/parser/rules/block/html/diagnostics.ts +11 -0
  124. package/src/parser/rules/block/html/index.ts +95 -0
  125. package/src/parser/rules/block/html/open.ts +36 -0
  126. package/src/parser/rules/block/iframe/attributes.ts +106 -0
  127. package/src/parser/rules/block/iframe/index.ts +73 -0
  128. package/src/parser/rules/block/iframe/open.ts +58 -0
  129. package/src/parser/rules/block/iframe/source.ts +24 -0
  130. package/src/parser/rules/block/iframe/url.ts +38 -0
  131. package/src/parser/rules/block/iftags/body.ts +48 -0
  132. package/src/parser/rules/block/iftags/condition.ts +24 -0
  133. package/src/parser/rules/block/{iftags.ts → iftags/index.ts} +16 -58
  134. package/src/parser/rules/block/include/arguments.ts +48 -0
  135. package/src/parser/rules/block/include/index.ts +75 -0
  136. package/src/parser/rules/block/include/location.ts +24 -0
  137. package/src/parser/rules/block/include/variables.ts +37 -0
  138. package/src/parser/rules/block/list/index.ts +73 -0
  139. package/src/parser/rules/block/list/line.ts +77 -0
  140. package/src/parser/rules/block/list/native.ts +89 -0
  141. package/src/parser/rules/block/math/content.ts +54 -0
  142. package/src/parser/rules/block/math/index.ts +106 -0
  143. package/src/parser/rules/block/math/name.ts +35 -0
  144. package/src/parser/rules/block/module/body.ts +92 -0
  145. package/src/parser/rules/block/module/element.ts +33 -0
  146. package/src/parser/rules/block/module/include/directive.ts +91 -0
  147. package/src/parser/rules/block/module/include/index.ts +11 -2
  148. package/src/parser/rules/block/module/include/references.ts +42 -0
  149. package/src/parser/rules/block/module/include/resolve/cache.ts +44 -0
  150. package/src/parser/rules/block/module/include/resolve/index.ts +106 -0
  151. package/src/parser/rules/block/module/include/resolve/iterate.ts +202 -0
  152. package/src/parser/rules/block/module/include/resolve/replace.ts +31 -0
  153. package/src/parser/rules/block/module/include/resolve/types.ts +105 -0
  154. package/src/parser/rules/block/module/include/scanner.ts +121 -0
  155. package/src/parser/rules/block/module/index.ts +14 -2
  156. package/src/parser/rules/block/module/listpages/compiler.ts +12 -392
  157. package/src/parser/rules/block/module/listpages/extract.ts +25 -359
  158. package/src/parser/rules/block/module/listpages/extraction/listpages.ts +42 -0
  159. package/src/parser/rules/block/module/listpages/extraction/listusers.ts +30 -0
  160. package/src/parser/rules/block/module/listpages/extraction/query.ts +51 -0
  161. package/src/parser/rules/block/module/listpages/extraction/result.ts +18 -0
  162. package/src/parser/rules/block/module/listpages/extraction/template.ts +96 -0
  163. package/src/parser/rules/block/module/listpages/extraction/variables.ts +58 -0
  164. package/src/parser/rules/block/module/listpages/normalization/date-selector.ts +53 -0
  165. package/src/parser/rules/block/module/listpages/normalization/numeric-selector.ts +32 -0
  166. package/src/parser/rules/block/module/listpages/normalization/order-parent.ts +82 -0
  167. package/src/parser/rules/block/module/listpages/normalization/selectors.ts +2 -0
  168. package/src/parser/rules/block/module/listpages/normalization/tags-category.ts +86 -0
  169. package/src/parser/rules/block/module/listpages/normalize.ts +8 -324
  170. package/src/parser/rules/block/module/listpages/resolution/items.ts +43 -0
  171. package/src/parser/rules/block/module/listpages/resolution/wrapper.ts +42 -0
  172. package/src/parser/rules/block/module/listpages/resolve.ts +5 -75
  173. package/src/parser/rules/block/module/listpages/template/format/content.ts +41 -0
  174. package/src/parser/rules/block/module/listpages/template/format/date.ts +116 -0
  175. package/src/parser/rules/block/module/listpages/template/format/index.ts +4 -0
  176. package/src/parser/rules/block/module/listpages/template/format/tags.ts +7 -0
  177. package/src/parser/rules/block/module/listpages/template/format/user.ts +9 -0
  178. package/src/parser/rules/block/module/listpages/template/getters/index.ts +36 -0
  179. package/src/parser/rules/block/module/listpages/template/getters/parameterized.ts +60 -0
  180. package/src/parser/rules/block/module/listpages/template/getters/simple.ts +65 -0
  181. package/src/parser/rules/block/module/listpages/template/getters/types.ts +3 -0
  182. package/src/parser/rules/block/module/listpages/template/syntax.ts +97 -0
  183. package/src/parser/rules/block/module/listpages/types/data-fetcher.ts +15 -0
  184. package/src/parser/rules/block/module/listpages/types/data-requirements.ts +52 -0
  185. package/src/parser/rules/block/module/listpages/types/external-data.ts +77 -0
  186. package/src/parser/rules/block/module/listpages/types/index.ts +17 -0
  187. package/src/parser/rules/block/module/listpages/types/normalized-query.ts +120 -0
  188. package/src/parser/rules/block/module/listpages/types/query.ts +67 -0
  189. package/src/parser/rules/block/module/listpages/types/template.ts +17 -0
  190. package/src/parser/rules/block/module/listpages/types/variables.ts +69 -0
  191. package/src/parser/rules/block/module/listpages/url-resolution/fields.ts +48 -0
  192. package/src/parser/rules/block/module/listpages/url-resolution/params.ts +19 -0
  193. package/src/parser/rules/block/module/listpages/url-resolution/query.ts +24 -0
  194. package/src/parser/rules/block/module/listpages/url-resolution/resolve.ts +53 -0
  195. package/src/parser/rules/block/module/listpages/url-resolution/value.ts +25 -0
  196. package/src/parser/rules/block/module/listpages/url-resolver.ts +3 -160
  197. package/src/parser/rules/block/module/listusers/compiler.ts +4 -25
  198. package/src/parser/rules/block/module/listusers/extract.ts +4 -9
  199. package/src/parser/rules/block/module/listusers/getters.ts +21 -0
  200. package/src/parser/rules/block/module/listusers/variables.ts +15 -0
  201. package/src/parser/rules/block/module/open.ts +57 -0
  202. package/src/parser/rules/block/module/resolution/contexts.ts +78 -0
  203. package/src/parser/rules/block/module/resolution/data-maps.ts +39 -0
  204. package/src/parser/rules/block/module/resolution/dynamic-modules.ts +93 -0
  205. package/src/parser/rules/block/module/resolution/styles.ts +53 -0
  206. package/src/parser/rules/block/module/resolution/walk-resolve.ts +107 -0
  207. package/src/parser/rules/block/module/resolve.ts +79 -292
  208. package/src/parser/rules/block/module/rule.ts +56 -0
  209. package/src/parser/rules/block/module/types-common.ts +11 -0
  210. package/src/parser/rules/block/module/walk/children.ts +35 -0
  211. package/src/parser/rules/block/module/walk/index.ts +9 -0
  212. package/src/parser/rules/block/module/walk/map/index.ts +2 -0
  213. package/src/parser/rules/block/module/walk/map/stateful-definition-list.ts +25 -0
  214. package/src/parser/rules/block/module/walk/map/stateful-list.ts +40 -0
  215. package/src/parser/rules/block/module/walk/map/stateful-table.ts +23 -0
  216. package/src/parser/rules/block/module/walk/map/stateful-tabs.ts +19 -0
  217. package/src/parser/rules/block/module/walk/map/stateful.ts +71 -0
  218. package/src/parser/rules/block/module/walk/map/stateless-definition-list.ts +12 -0
  219. package/src/parser/rules/block/module/walk/map/stateless-list.ts +29 -0
  220. package/src/parser/rules/block/module/walk/map/stateless-table.ts +11 -0
  221. package/src/parser/rules/block/module/walk/map/stateless-tabs.ts +5 -0
  222. package/src/parser/rules/block/module/walk/map/stateless.ts +51 -0
  223. package/src/parser/rules/block/module/walk/map/types.ts +6 -0
  224. package/src/parser/rules/block/module/walk/traverse.ts +65 -0
  225. package/src/parser/rules/block/orphan-li/content.ts +60 -0
  226. package/src/parser/rules/block/orphan-li/index.ts +75 -0
  227. package/src/parser/rules/block/orphan-li/open.ts +25 -0
  228. package/src/parser/rules/block/orphan-li/tags.ts +40 -0
  229. package/src/parser/rules/block/paragraph/content.ts +12 -0
  230. package/src/parser/rules/block/paragraph/index.ts +60 -0
  231. package/src/parser/rules/block/paragraph/normalize.ts +52 -0
  232. package/src/parser/rules/block/paragraph/span-markers.ts +52 -0
  233. package/src/parser/rules/block/parsing/attributes/index.ts +32 -0
  234. package/src/parser/rules/block/parsing/attributes/names.ts +93 -0
  235. package/src/parser/rules/block/parsing/attributes/scanner.ts +75 -0
  236. package/src/parser/rules/block/parsing/attributes/values.ts +26 -0
  237. package/src/parser/rules/block/parsing/block-item.ts +29 -0
  238. package/src/parser/rules/block/parsing/content.ts +127 -0
  239. package/src/parser/rules/block/parsing/end-condition.ts +51 -0
  240. package/src/parser/rules/block/parsing/inline-content.ts +105 -0
  241. package/src/parser/rules/block/parsing/inline-newline.ts +41 -0
  242. package/src/parser/rules/block/parsing/non-boundary.ts +24 -0
  243. package/src/parser/rules/block/parsing/rule-dispatch.ts +44 -0
  244. package/src/parser/rules/block/table/index.ts +80 -0
  245. package/src/parser/rules/block/table/pipe/cell-start.ts +69 -0
  246. package/src/parser/rules/block/table/pipe/cell.ts +106 -0
  247. package/src/parser/rules/block/table/pipe/index.ts +2 -0
  248. package/src/parser/rules/block/table/pipe/row.ts +88 -0
  249. package/src/parser/rules/block/table/pipe/tokens.ts +14 -0
  250. package/src/parser/rules/block/table/pipe/trim.ts +50 -0
  251. package/src/parser/rules/block/table-block/body.ts +79 -0
  252. package/src/parser/rules/block/table-block/cell-attributes.ts +33 -0
  253. package/src/parser/rules/block/table-block/cell-boundary.ts +99 -0
  254. package/src/parser/rules/block/table-block/cell-content/index.ts +88 -0
  255. package/src/parser/rules/block/table-block/cell-content/segments.ts +134 -0
  256. package/src/parser/rules/block/table-block/cell-newline.ts +47 -0
  257. package/src/parser/rules/block/table-block/cell.ts +64 -0
  258. package/src/parser/rules/block/table-block/index.ts +113 -0
  259. package/src/parser/rules/block/table-block/row-boundary.ts +75 -0
  260. package/src/parser/rules/block/table-block/structure.ts +80 -0
  261. package/src/parser/rules/block/tabview/body.ts +64 -0
  262. package/src/parser/rules/block/tabview/index.ts +90 -0
  263. package/src/parser/rules/block/tabview/open.ts +50 -0
  264. package/src/parser/rules/block/tabview/tab.ts +92 -0
  265. package/src/parser/rules/block/tabview/tags.ts +30 -0
  266. package/src/parser/rules/block/toc/element.ts +11 -0
  267. package/src/parser/rules/block/toc/index.ts +44 -0
  268. package/src/parser/rules/block/toc/open.ts +84 -0
  269. package/src/parser/rules/block/utils.ts +10 -610
  270. package/src/parser/rules/{utils.ts → common/attribute-safety.ts} +3 -49
  271. package/src/parser/rules/common/block-name.ts +33 -0
  272. package/src/parser/rules/common/index.ts +2 -0
  273. package/src/parser/rules/contracts/index.ts +3 -0
  274. package/src/parser/rules/contracts/parse-context.ts +38 -0
  275. package/src/parser/rules/contracts/rule.ts +43 -0
  276. package/src/parser/rules/contracts/scope.ts +31 -0
  277. package/src/parser/rules/inline/anchor/attributes.ts +54 -0
  278. package/src/parser/rules/inline/anchor/child.ts +26 -0
  279. package/src/parser/rules/inline/anchor/close.ts +34 -0
  280. package/src/parser/rules/inline/anchor/content.ts +59 -0
  281. package/src/parser/rules/inline/anchor/index.ts +103 -0
  282. package/src/parser/rules/inline/anchor/newline.ts +26 -0
  283. package/src/parser/rules/inline/anchor/open.ts +47 -0
  284. package/src/parser/rules/inline/anchor/paragraph-strip.ts +14 -0
  285. package/src/parser/rules/inline/anchor/syntax.ts +40 -0
  286. package/src/parser/rules/inline/anchor-name/index.ts +38 -0
  287. package/src/parser/rules/inline/anchor-name/name.ts +39 -0
  288. package/src/parser/rules/inline/anchor-name/syntax.ts +46 -0
  289. package/src/parser/rules/inline/bibcite/element.ts +14 -0
  290. package/src/parser/rules/inline/bibcite/index.ts +34 -0
  291. package/src/parser/rules/inline/bibcite/syntax.ts +64 -0
  292. package/src/parser/rules/inline/bold.ts +2 -39
  293. package/src/parser/rules/inline/color/index.ts +35 -0
  294. package/src/parser/rules/inline/color/syntax.ts +69 -0
  295. package/src/parser/rules/inline/comment/consume.ts +31 -0
  296. package/src/parser/rules/inline/{comment.ts → comment/index.ts} +10 -36
  297. package/src/parser/rules/inline/equation-ref/element.ts +8 -0
  298. package/src/parser/rules/inline/equation-ref/index.ts +34 -0
  299. package/src/parser/rules/inline/equation-ref/syntax.ts +45 -0
  300. package/src/parser/rules/inline/expr/branch.ts +104 -0
  301. package/src/parser/rules/inline/expr/conditional-branch.ts +27 -0
  302. package/src/parser/rules/inline/expr/conditional.ts +80 -0
  303. package/src/parser/rules/inline/expr/depth.ts +25 -0
  304. package/src/parser/rules/inline/expr/elements.ts +39 -0
  305. package/src/parser/rules/inline/expr/index.ts +84 -0
  306. package/src/parser/rules/inline/expr/syntax.ts +45 -0
  307. package/src/parser/rules/inline/footnote/child.ts +22 -0
  308. package/src/parser/rules/inline/footnote/close.ts +33 -0
  309. package/src/parser/rules/inline/footnote/content.ts +54 -0
  310. package/src/parser/rules/inline/footnote/elements.ts +38 -0
  311. package/src/parser/rules/inline/footnote/index.ts +54 -0
  312. package/src/parser/rules/inline/footnote/newline.ts +27 -0
  313. package/src/parser/rules/inline/footnote/open.ts +38 -0
  314. package/src/parser/rules/inline/formatting/container.ts +50 -0
  315. package/src/parser/rules/inline/{guillemet.ts → guillemet/index.ts} +5 -13
  316. package/src/parser/rules/inline/guillemet/text.ts +11 -0
  317. package/src/parser/rules/inline/html/gate.ts +64 -0
  318. package/src/parser/rules/inline/{html.ts → html/index.ts} +9 -60
  319. package/src/parser/rules/inline/html/open.ts +37 -0
  320. package/src/parser/rules/inline/image/attributes.ts +22 -0
  321. package/src/parser/rules/inline/image/body.ts +36 -0
  322. package/src/parser/rules/inline/image/index.ts +89 -0
  323. package/src/parser/rules/inline/image/open.ts +56 -0
  324. package/src/parser/rules/inline/image/source.ts +62 -0
  325. package/src/parser/rules/inline/image/syntax.ts +76 -0
  326. package/src/parser/rules/inline/italic.ts +2 -30
  327. package/src/parser/rules/inline/line-break/backslash.ts +58 -0
  328. package/src/parser/rules/inline/line-break/elements.ts +9 -0
  329. package/src/parser/rules/inline/line-break/index.ts +3 -0
  330. package/src/parser/rules/inline/line-break/newline.ts +82 -0
  331. package/src/parser/rules/inline/line-break/underscore.ts +45 -0
  332. package/src/parser/rules/inline/link-anchor.ts +6 -81
  333. package/src/parser/rules/inline/link-bracket/anchor.ts +3 -0
  334. package/src/parser/rules/inline/link-bracket/direct-url.ts +5 -0
  335. package/src/parser/rules/inline/link-bracket/parsed.ts +81 -0
  336. package/src/parser/rules/inline/link-bracket/parts.ts +64 -0
  337. package/src/parser/rules/inline/link-bracket/prefix.ts +15 -0
  338. package/src/parser/rules/inline/link-single.ts +7 -98
  339. package/src/parser/rules/inline/link-star.ts +7 -69
  340. package/src/parser/rules/inline/link-triple/fallback.ts +10 -0
  341. package/src/parser/rules/inline/link-triple/index.ts +62 -0
  342. package/src/parser/rules/inline/link-triple/interwiki.ts +11 -0
  343. package/src/parser/rules/inline/link-triple/label.ts +35 -0
  344. package/src/parser/rules/inline/link-triple/syntax.ts +72 -0
  345. package/src/parser/rules/inline/link-triple/target.ts +36 -0
  346. package/src/parser/rules/inline/math-inline/index.ts +40 -0
  347. package/src/parser/rules/inline/math-inline/syntax.ts +55 -0
  348. package/src/parser/rules/inline/monospace.ts +2 -30
  349. package/src/parser/rules/inline/parsing/block-boundary.ts +42 -0
  350. package/src/parser/rules/inline/parsing/block-start-predicates.ts +117 -0
  351. package/src/parser/rules/inline/parsing/collect.ts +23 -0
  352. package/src/parser/rules/inline/parsing/inline-content.ts +115 -0
  353. package/src/parser/rules/inline/parsing/paragraph-boundary.ts +47 -0
  354. package/src/parser/rules/inline/parsing/plain-text.ts +69 -0
  355. package/src/parser/rules/inline/parsing/preserved-line-break.ts +11 -0
  356. package/src/parser/rules/inline/parsing/rules.ts +34 -0
  357. package/src/parser/rules/inline/parsing/simple-token.ts +26 -0
  358. package/src/parser/rules/inline/raw/angle.ts +40 -0
  359. package/src/parser/rules/inline/raw/double-at.ts +78 -0
  360. package/src/parser/rules/inline/raw/index.ts +26 -0
  361. package/src/parser/rules/inline/raw/result.ts +26 -0
  362. package/src/parser/rules/inline/size/content.ts +65 -0
  363. package/src/parser/rules/inline/size/index.ts +55 -0
  364. package/src/parser/rules/inline/size/open.ts +43 -0
  365. package/src/parser/rules/inline/size/value.ts +45 -0
  366. package/src/parser/rules/inline/span/content.ts +97 -0
  367. package/src/parser/rules/inline/span/elements.ts +108 -0
  368. package/src/parser/rules/inline/span/index.ts +79 -0
  369. package/src/parser/rules/inline/span/newline.ts +50 -0
  370. package/src/parser/rules/inline/span/syntax.ts +70 -0
  371. package/src/parser/rules/inline/{strikethrough.ts → strikethrough/index.ts} +5 -60
  372. package/src/parser/rules/inline/strikethrough/parse.ts +14 -0
  373. package/src/parser/rules/inline/strikethrough/syntax.ts +24 -0
  374. package/src/parser/rules/inline/subscript.ts +2 -39
  375. package/src/parser/rules/inline/superscript.ts +4 -39
  376. package/src/parser/rules/inline/text/element.ts +5 -0
  377. package/src/parser/rules/inline/{text.ts → text/index.ts} +5 -4
  378. package/src/parser/rules/inline/underline/child.ts +26 -0
  379. package/src/parser/rules/inline/underline/content.ts +29 -0
  380. package/src/parser/rules/inline/{underline.ts → underline/index.ts} +6 -49
  381. package/src/parser/rules/inline/user/element.ts +11 -0
  382. package/src/parser/rules/inline/user/index.ts +34 -0
  383. package/src/parser/rules/inline/user/syntax.ts +67 -0
  384. package/src/parser/rules/inline/utils.ts +4 -344
  385. package/src/parser/rules/tokens.ts +106 -0
  386. package/src/parser/rules/types.ts +9 -252
  387. package/src/parser/depth.ts +0 -251
  388. package/src/parser/parse.ts +0 -315
  389. package/src/parser/postprocess/spanStrip.ts +0 -697
  390. package/src/parser/preprocess/expr.ts +0 -265
  391. package/src/parser/preprocess/utils.ts +0 -250
  392. package/src/parser/preprocess/whitespace.ts +0 -111
  393. package/src/parser/rules/block/align.ts +0 -282
  394. package/src/parser/rules/block/bibliography.ts +0 -359
  395. package/src/parser/rules/block/block-list.ts +0 -689
  396. package/src/parser/rules/block/blockquote.ts +0 -238
  397. package/src/parser/rules/block/code.ts +0 -187
  398. package/src/parser/rules/block/collapsible.ts +0 -337
  399. package/src/parser/rules/block/definition-list.ts +0 -270
  400. package/src/parser/rules/block/div.ts +0 -400
  401. package/src/parser/rules/block/embed-block.ts +0 -153
  402. package/src/parser/rules/block/footnoteblock.ts +0 -200
  403. package/src/parser/rules/block/heading.ts +0 -142
  404. package/src/parser/rules/block/html.ts +0 -222
  405. package/src/parser/rules/block/iframe.ts +0 -239
  406. package/src/parser/rules/block/include.ts +0 -179
  407. package/src/parser/rules/block/list.ts +0 -244
  408. package/src/parser/rules/block/math.ts +0 -183
  409. package/src/parser/rules/block/module/include/resolve.ts +0 -556
  410. package/src/parser/rules/block/module/listpages/types.ts +0 -513
  411. package/src/parser/rules/block/module/walk.ts +0 -380
  412. package/src/parser/rules/block/module.ts +0 -164
  413. package/src/parser/rules/block/orphan-li.ts +0 -177
  414. package/src/parser/rules/block/paragraph.ts +0 -157
  415. package/src/parser/rules/block/table-block.ts +0 -726
  416. package/src/parser/rules/block/table.ts +0 -441
  417. package/src/parser/rules/block/tabview.ts +0 -331
  418. package/src/parser/rules/block/toc.ts +0 -129
  419. package/src/parser/rules/inline/anchor-name.ts +0 -154
  420. package/src/parser/rules/inline/anchor.ts +0 -327
  421. package/src/parser/rules/inline/bibcite.ts +0 -153
  422. package/src/parser/rules/inline/color.ts +0 -140
  423. package/src/parser/rules/inline/equation-ref.ts +0 -115
  424. package/src/parser/rules/inline/expr.ts +0 -526
  425. package/src/parser/rules/inline/footnote.ts +0 -223
  426. package/src/parser/rules/inline/image.ts +0 -328
  427. package/src/parser/rules/inline/line-break.ts +0 -326
  428. package/src/parser/rules/inline/link-triple.ts +0 -267
  429. package/src/parser/rules/inline/math-inline.ts +0 -126
  430. package/src/parser/rules/inline/raw.ts +0 -262
  431. package/src/parser/rules/inline/size.ts +0 -244
  432. package/src/parser/rules/inline/span.ts +0 -424
  433. package/src/parser/rules/inline/user.ts +0 -147
@@ -0,0 +1,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
+ }
@@ -0,0 +1,105 @@
1
+ import type { Element } from "@wdprlib/ast";
2
+ import type { ParseContext } from "../../types";
3
+ import { getCandidateInlineRules } from "../../inline/utils";
4
+ import type { BlockParseResult } from "./content";
5
+ import { consumeInlineContentNewlines, removeTrailingLineBreaks } from "./inline-newline";
6
+ import { getCandidateBlockRules } from "./rule-dispatch";
7
+
8
+ /**
9
+ * Parses mixed inline/block content until a close condition is met,
10
+ * WITHOUT paragraph wrapping.
11
+ *
12
+ * This is used for `div_` (paragraph strip mode) where newlines become
13
+ * `<br />` elements rather than paragraph separators. Blank lines
14
+ * (multiple consecutive newlines) are collapsed into a single `<br />`.
15
+ *
16
+ * Block-level elements (nested div, collapsible, etc.) are mixed directly
17
+ * into the inline element stream. Newlines immediately before a BLOCK_OPEN
18
+ * or BLOCK_END_OPEN are silently consumed (no `<br />` generated).
19
+ *
20
+ * Trailing line-break elements are stripped from the result.
21
+ *
22
+ * @param ctx - Parse context positioned at the start of the body.
23
+ * @param closeCondition - Predicate that signals the end of the content.
24
+ * @returns Parsed elements and total tokens consumed.
25
+ */
26
+ export function parseInlineContentUntil(
27
+ ctx: ParseContext,
28
+ closeCondition: (ctx: ParseContext) => boolean,
29
+ ): BlockParseResult {
30
+ const elements: Element[] = [];
31
+ let consumed = 0;
32
+ let pos = ctx.pos;
33
+
34
+ const { blockRules, inlineRules } = ctx;
35
+ const checkCtx: ParseContext = { ...ctx, pos };
36
+ const blockCtx: ParseContext = { ...ctx, pos };
37
+ const inlineCtx: ParseContext = { ...ctx, pos };
38
+
39
+ while (pos < ctx.tokens.length) {
40
+ const token = ctx.tokens[pos];
41
+ if (!token || token.type === "EOF") {
42
+ break;
43
+ }
44
+
45
+ checkCtx.pos = pos;
46
+ if (closeCondition(checkCtx)) {
47
+ break;
48
+ }
49
+
50
+ if (token.type === "WHITESPACE" && token.lineStart) {
51
+ pos++;
52
+ consumed++;
53
+ continue;
54
+ }
55
+
56
+ if (token.type === "NEWLINE") {
57
+ const newlineResult = consumeInlineContentNewlines(ctx, pos);
58
+ consumed += newlineResult.consumed;
59
+ pos += newlineResult.consumed;
60
+ if (newlineResult.addLineBreak) {
61
+ elements.push({ element: "line-break" });
62
+ }
63
+ continue;
64
+ }
65
+
66
+ let matched = false;
67
+ blockCtx.pos = pos;
68
+
69
+ for (const rule of getCandidateBlockRules(blockRules, token)) {
70
+ const result = rule.parse(blockCtx);
71
+ if (result.success) {
72
+ elements.push(...result.elements);
73
+ consumed += result.consumed;
74
+ pos += result.consumed;
75
+ matched = true;
76
+ break;
77
+ }
78
+ }
79
+
80
+ if (matched) continue;
81
+
82
+ inlineCtx.pos = pos;
83
+
84
+ for (const rule of getCandidateInlineRules(inlineRules, token.type)) {
85
+ const result = rule.parse(inlineCtx);
86
+ if (result.success) {
87
+ elements.push(...result.elements);
88
+ consumed += result.consumed;
89
+ pos += result.consumed;
90
+ matched = true;
91
+ break;
92
+ }
93
+ }
94
+
95
+ if (!matched) {
96
+ elements.push({ element: "text", data: token.value });
97
+ consumed++;
98
+ pos++;
99
+ }
100
+ }
101
+
102
+ removeTrailingLineBreaks(elements);
103
+
104
+ return { elements, consumed };
105
+ }
@@ -0,0 +1,41 @@
1
+ import type { Element } from "@wdprlib/ast";
2
+ import type { ParseContext } from "../../types";
3
+ import { isNonBoundaryBlockToken } from "./non-boundary";
4
+
5
+ export interface InlineNewlineResult {
6
+ consumed: number;
7
+ addLineBreak: boolean;
8
+ }
9
+
10
+ export function consumeInlineContentNewlines(
11
+ ctx: ParseContext,
12
+ startPos: number,
13
+ ): InlineNewlineResult {
14
+ let pos = startPos + 1;
15
+ let consumed = 1;
16
+
17
+ while (ctx.tokens[pos]?.type === "NEWLINE") {
18
+ pos++;
19
+ consumed++;
20
+ }
21
+
22
+ const nextToken = ctx.tokens[pos];
23
+ if (!nextToken || nextToken.type === "EOF") {
24
+ return { consumed, addLineBreak: false };
25
+ }
26
+
27
+ if (nextToken.type === "BLOCK_OPEN" || nextToken.type === "BLOCK_END_OPEN") {
28
+ const peekCtx: ParseContext = { ...ctx, pos };
29
+ if (!isNonBoundaryBlockToken(peekCtx, pos)) {
30
+ return { consumed, addLineBreak: false };
31
+ }
32
+ }
33
+
34
+ return { consumed, addLineBreak: true };
35
+ }
36
+
37
+ export function removeTrailingLineBreaks(elements: Element[]): void {
38
+ while (elements.length > 0 && elements[elements.length - 1]?.element === "line-break") {
39
+ elements.pop();
40
+ }
41
+ }
@@ -0,0 +1,24 @@
1
+ import type { ParseContext } from "../../types";
2
+ import { KNOWN_BLOCK_NAMES } from "../../../constants";
3
+ import { parseBlockName } from "../utils";
4
+
5
+ /**
6
+ * Whether the BLOCK_OPEN / BLOCK_END_OPEN token at `pos` opens a block name
7
+ * that should not end the surrounding paragraph / inline run.
8
+ */
9
+ export function isNonBoundaryBlockToken(ctx: ParseContext, pos: number): boolean {
10
+ const token = ctx.tokens[pos];
11
+ if (token?.type !== "BLOCK_OPEN" && token?.type !== "BLOCK_END_OPEN") {
12
+ return false;
13
+ }
14
+
15
+ const nameResult = parseBlockName(ctx, pos + 1);
16
+ if (nameResult === null) {
17
+ return ctx.tokens[pos + 1]?.type !== "EQUALS";
18
+ }
19
+
20
+ if (ctx.scope.excludedBlockNames?.has(nameResult.name)) {
21
+ return true;
22
+ }
23
+ return !KNOWN_BLOCK_NAMES.has(nameResult.name);
24
+ }