@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
@@ -24,9 +24,10 @@
24
24
  * @module
25
25
  */
26
26
  import type { Element } from "@wdprlib/ast";
27
- import type { InlineRule, ParseContext, RuleResult } from "../types";
28
- import { currentToken, hasClosingMarkerBeforeParagraphBreak } from "../types";
29
- import { parseInlineUntil } from "./utils";
27
+ import type { InlineRule, ParseContext, RuleResult } from "../../types";
28
+ import { currentToken, hasClosingMarkerBeforeParagraphBreak } from "../../types";
29
+ import { createInlineContainer } from "../formatting/container";
30
+ import { parseUnderlineContent } from "./content";
30
31
 
31
32
  /**
32
33
  * Inline rule for parsing `__underline__` formatting.
@@ -63,42 +64,7 @@ export const underlineRule: InlineRule = {
63
64
  };
64
65
  }
65
66
 
66
- // Parse content between markers, handling newlines as line-breaks
67
- const children: Element[] = [];
68
- let pos = ctx.pos + 1;
69
- let consumed = 1; // opening marker
70
-
71
- while (pos < ctx.tokens.length) {
72
- const token = ctx.tokens[pos];
73
- if (!token || token.type === "EOF") break;
74
-
75
- // Found closing marker
76
- if (token.type === "UNDERLINE_MARKER") {
77
- consumed++;
78
- break;
79
- }
80
-
81
- // Handle newlines as line-breaks
82
- if (token.type === "NEWLINE") {
83
- children.push({ element: "line-break" });
84
- pos++;
85
- consumed++;
86
- continue;
87
- }
88
-
89
- // Parse inline content until NEWLINE or closing marker
90
- const inlineCtx = { ...ctx, pos };
91
- const result = parseInlineUntil(inlineCtx, "UNDERLINE_MARKER");
92
- if (result.elements.length > 0) {
93
- children.push(...result.elements);
94
- pos += result.consumed;
95
- consumed += result.consumed;
96
- } else {
97
- children.push({ element: "text", data: token.value });
98
- pos++;
99
- consumed++;
100
- }
101
- }
67
+ const { children, consumed } = parseUnderlineContent(ctx, ctx.pos + 1);
102
68
 
103
69
  // Empty underline (____) is discarded entirely in Wikidot
104
70
  if (children.length === 0) {
@@ -111,16 +77,7 @@ export const underlineRule: InlineRule = {
111
77
 
112
78
  return {
113
79
  success: true,
114
- elements: [
115
- {
116
- element: "container",
117
- data: {
118
- type: "underline",
119
- attributes: {},
120
- elements: children,
121
- },
122
- },
123
- ],
80
+ elements: [createInlineContainer("underline", children)],
124
81
  consumed,
125
82
  };
126
83
  },
@@ -0,0 +1,11 @@
1
+ import type { Element } from "@wdprlib/ast";
2
+
3
+ export function userElement(name: string, showAvatar: boolean): Element {
4
+ return {
5
+ element: "user",
6
+ data: {
7
+ name,
8
+ "show-avatar": showAvatar,
9
+ },
10
+ };
11
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ *
3
+ * Parses the Wikidot user reference syntax: `[[user name]]` and `[[*user name]]`.
4
+ *
5
+ * @module
6
+ */
7
+ import type { Element } from "@wdprlib/ast";
8
+ import type { InlineRule, ParseContext, RuleResult } from "../../types";
9
+ import { currentToken } from "../../types";
10
+ import { userElement } from "./element";
11
+ import { parseUserReference } from "./syntax";
12
+
13
+ export const userRule: InlineRule = {
14
+ name: "user",
15
+ startTokens: ["BLOCK_OPEN"],
16
+
17
+ parse(ctx: ParseContext): RuleResult<Element> {
18
+ const openToken = currentToken(ctx);
19
+ if (openToken.type !== "BLOCK_OPEN") {
20
+ return { success: false };
21
+ }
22
+
23
+ const parsed = parseUserReference(ctx, ctx.pos + 1);
24
+ if (!parsed) {
25
+ return { success: false };
26
+ }
27
+
28
+ return {
29
+ success: true,
30
+ elements: [userElement(parsed.name, parsed.showAvatar)],
31
+ consumed: 1 + parsed.consumed,
32
+ };
33
+ },
34
+ };
@@ -0,0 +1,67 @@
1
+ import type { ParseContext } from "../../types";
2
+
3
+ export function parseUserReference(
4
+ ctx: ParseContext,
5
+ startPos: number,
6
+ ): { name: string; showAvatar: boolean; consumed: number } | null {
7
+ let pos = startPos;
8
+ let consumed = 0;
9
+
10
+ if (ctx.tokens[pos]?.type === "WHITESPACE") {
11
+ return null;
12
+ }
13
+
14
+ let showAvatar = false;
15
+ if (ctx.tokens[pos]?.type === "STAR") {
16
+ showAvatar = true;
17
+ pos++;
18
+ consumed++;
19
+ }
20
+
21
+ while (ctx.tokens[pos]?.type === "WHITESPACE") {
22
+ pos++;
23
+ consumed++;
24
+ }
25
+
26
+ const nameToken = ctx.tokens[pos];
27
+ if (!nameToken || (nameToken.type !== "TEXT" && nameToken.type !== "IDENTIFIER")) {
28
+ return null;
29
+ }
30
+ if (nameToken.value.toLowerCase() !== "user") {
31
+ return null;
32
+ }
33
+ pos++;
34
+ consumed++;
35
+
36
+ while (ctx.tokens[pos]?.type === "WHITESPACE") {
37
+ pos++;
38
+ consumed++;
39
+ }
40
+
41
+ let username = "";
42
+ while (pos < ctx.tokens.length) {
43
+ const token = ctx.tokens[pos];
44
+ if (
45
+ !token ||
46
+ token.type === "BLOCK_CLOSE" ||
47
+ token.type === "NEWLINE" ||
48
+ token.type === "EOF"
49
+ ) {
50
+ break;
51
+ }
52
+ username += token.value;
53
+ pos++;
54
+ consumed++;
55
+ }
56
+
57
+ username = username.trim();
58
+ if (!username || ctx.tokens[pos]?.type !== "BLOCK_CLOSE") {
59
+ return null;
60
+ }
61
+
62
+ return {
63
+ name: username,
64
+ showAvatar,
65
+ consumed: consumed + 1,
66
+ };
67
+ }
@@ -1,344 +1,4 @@
1
- import type { TokenType, Token } from "../../../lexer";
2
- import type { Element } from "@wdprlib/ast";
3
- import type { ParseContext, InlineRule } from "../types";
4
- import {
5
- BLOCK_START_TOKENS,
6
- INDENT_ACCEPTING_BLOCK_NAMES,
7
- KNOWN_BLOCK_NAMES,
8
- } from "../../constants";
9
- import { parseBlockName } from "../utils";
10
-
11
- /**
12
- * Checks whether the block token at `tokenPos` (BLOCK_OPEN or BLOCK_END_OPEN)
13
- * names a block in the excluded set.
14
- */
15
- function isExcludedBlockToken(ctx: ParseContext, tokenPos: number): boolean {
16
- const excluded = ctx.scope.excludedBlockNames;
17
- if (!excluded?.size) return false;
18
- const token = ctx.tokens[tokenPos];
19
- if (token?.type !== "BLOCK_OPEN" && token?.type !== "BLOCK_END_OPEN") return false;
20
- const nameResult = parseBlockName(ctx, tokenPos + 1);
21
- return nameResult !== null && excluded.has(nameResult.name);
22
- }
23
-
24
- /**
25
- * Checks whether the block token at `tokenPos` names a block that no rule
26
- * recognizes (e.g. `[[foo]]`). Wikidot leaves such tokens inside paragraphs
27
- * rather than treating them as paragraph boundaries.
28
- *
29
- * Align blocks (`[[=]]`, `[[==]]`) are recognized as a special case: their
30
- * marker tokens are `EQUALS`, not `TEXT`/`IDENTIFIER`, so `parseBlockName`
31
- * cannot extract a name. They are still real block boundaries.
32
- */
33
- function isUnknownBlockToken(ctx: ParseContext, tokenPos: number): boolean {
34
- const token = ctx.tokens[tokenPos];
35
- if (token?.type !== "BLOCK_OPEN" && token?.type !== "BLOCK_END_OPEN") return false;
36
- const nameResult = parseBlockName(ctx, tokenPos + 1);
37
- if (nameResult === null) {
38
- // `[[=]]` / `[[==]]` align markers tokenize as EQUALS, not TEXT/IDENTIFIER.
39
- if (ctx.tokens[tokenPos + 1]?.type === "EQUALS") {
40
- return false;
41
- }
42
- // No recognizable identifier after [[ / [[/ — treat as inline.
43
- return true;
44
- }
45
- return !KNOWN_BLOCK_NAMES.has(nameResult.name);
46
- }
47
-
48
- /**
49
- * Checks whether the block token at `tokenPos` names a block whose rule
50
- * accepts leading whitespace before the opener (`requiresLineStart: false`).
51
- *
52
- * Used to decide whether a `\n<indent>[[name]]` sequence should end a
53
- * paragraph: only when the matching block rule would actually consume
54
- * the indented token. Otherwise the boundary check would split the
55
- * paragraph for tokens that the block dispatcher then refuses, leaving
56
- * literal `[[toc]]` text in a fresh paragraph.
57
- */
58
- function isIndentAcceptingBlock(ctx: ParseContext, tokenPos: number): boolean {
59
- const token = ctx.tokens[tokenPos];
60
- if (token?.type !== "BLOCK_OPEN" && token?.type !== "BLOCK_END_OPEN") return false;
61
- const nameResult = parseBlockName(ctx, tokenPos + 1);
62
- if (nameResult === null) return false;
63
- return INDENT_ACCEPTING_BLOCK_NAMES.has(nameResult.name);
64
- }
65
-
66
- /**
67
- * Result of parsing inline content
68
- */
69
- export interface InlineParseResult {
70
- elements: Element[];
71
- consumed: number;
72
- }
73
-
74
- /**
75
- * Check if an inline rule can be applied
76
- */
77
- export function canApplyInlineRule(rule: InlineRule, token: { type: TokenType }): boolean {
78
- if (rule.startTokens.length === 0) {
79
- return true; // fallback rule
80
- }
81
- return rule.startTokens.includes(token.type);
82
- }
83
-
84
- /**
85
- * Parse inline content until a specific token type
86
- *
87
- * When endType is "PARAGRAPH_BREAK", handles NEWLINEs and stops at:
88
- * - Double NEWLINE (paragraph break)
89
- * - NEWLINE followed by block-start token
90
- * - EOF
91
- */
92
- export function parseInlineUntil(ctx: ParseContext, endType: TokenType): InlineParseResult {
93
- const nodes: Element[] = [];
94
- let consumed = 0;
95
- let pos = ctx.pos;
96
-
97
- // Check if we're in paragraph mode (handle NEWLINEs inline)
98
- const paragraphMode = endType === ("PARAGRAPH_BREAK" as TokenType);
99
-
100
- const { inlineRules } = ctx;
101
-
102
- while (pos < ctx.tokens.length) {
103
- const token = ctx.tokens[pos];
104
- if (!token || token.type === "EOF") {
105
- break;
106
- }
107
-
108
- // Stop at block close condition if set in context
109
- // This allows paragraph parser to respect parent block's close condition
110
- if (paragraphMode && ctx.scope.blockCloseCondition) {
111
- const checkCtx: ParseContext = { ...ctx, pos };
112
- if (ctx.scope.blockCloseCondition(checkCtx)) {
113
- break;
114
- }
115
- }
116
-
117
- // Standard mode: stop at NEWLINE
118
- if (!paragraphMode && token.type === "NEWLINE") {
119
- break;
120
- }
121
-
122
- // Paragraph mode: check for paragraph break or block start
123
- if (paragraphMode && token.type === "NEWLINE") {
124
- // Look ahead to check what's after the newline
125
- let lookAhead = 1;
126
- while (ctx.tokens[pos + lookAhead]?.type === "WHITESPACE") {
127
- lookAhead++;
128
- }
129
- const nextMeaningfulToken = ctx.tokens[pos + lookAhead];
130
-
131
- // Check if this is [[/span]] - don't treat as block start, handle inline
132
- let isOrphanCloseSpan = false;
133
- if (nextMeaningfulToken?.type === "BLOCK_END_OPEN") {
134
- // Check if it's [[/span]]
135
- const namePos = pos + lookAhead + 1;
136
- let nameLookAhead = 0;
137
- while (ctx.tokens[namePos + nameLookAhead]?.type === "WHITESPACE") {
138
- nameLookAhead++;
139
- }
140
- const nameToken = ctx.tokens[namePos + nameLookAhead];
141
- if (nameToken?.type === "IDENTIFIER" && nameToken.value.toLowerCase() === "span") {
142
- isOrphanCloseSpan = true;
143
- }
144
- }
145
-
146
- // Check if this is [[# name]] - anchor name is inline, not block start
147
- let isAnchorName = false;
148
- if (nextMeaningfulToken?.type === "BLOCK_OPEN") {
149
- const namePos = pos + lookAhead + 1;
150
- let nameLookAhead = 0;
151
- while (ctx.tokens[namePos + nameLookAhead]?.type === "WHITESPACE") {
152
- nameLookAhead++;
153
- }
154
- const hashToken = ctx.tokens[namePos + nameLookAhead];
155
- if (hashToken?.type === "HASH" || (hashToken?.type === "TEXT" && hashToken.value === "#")) {
156
- isAnchorName = true;
157
- }
158
- }
159
-
160
- // Check if this is [[>X or [[<X (where X is not ]]) - not a valid block opener
161
- // [[>]] and [[<]] are valid align blocks, but [[>toc]] etc. are invalid
162
- let isInvalidBlockOpen = false;
163
- if (nextMeaningfulToken?.type === "BLOCK_OPEN") {
164
- const afterOpen = pos + lookAhead + 1;
165
- const firstAfter = ctx.tokens[afterOpen];
166
- if (firstAfter?.type === "TEXT" && (firstAfter.value === ">" || firstAfter.value === "<")) {
167
- const secondAfter = ctx.tokens[afterOpen + 1];
168
- if (secondAfter && secondAfter.type !== "BLOCK_CLOSE") {
169
- isInvalidBlockOpen = true;
170
- }
171
- }
172
- // Check if this is [[footnoteblock]] but already parsed (2nd+ occurrence)
173
- let skipWhitespace = 0;
174
- while (ctx.tokens[afterOpen + skipWhitespace]?.type === "WHITESPACE") {
175
- skipWhitespace++;
176
- }
177
- const blockNameToken = ctx.tokens[afterOpen + skipWhitespace];
178
- if (
179
- blockNameToken &&
180
- (blockNameToken.type === "TEXT" || blockNameToken.type === "IDENTIFIER") &&
181
- blockNameToken.value.toLowerCase() === "footnoteblock" &&
182
- ctx.scope.footnoteBlockParsed
183
- ) {
184
- isInvalidBlockOpen = true;
185
- }
186
- }
187
-
188
- // Check if HEADING_MARKER would actually succeed as a heading
189
- // Wikidot requires: 1-6 plus signs + whitespace. Otherwise it's plain text.
190
- let isInvalidHeading = false;
191
- if (nextMeaningfulToken?.type === "HEADING_MARKER") {
192
- const markerLen = nextMeaningfulToken.value.length;
193
- const afterMarkerPos = pos + lookAhead + 1;
194
- const afterMarker = ctx.tokens[afterMarkerPos];
195
- // Invalid if: 7+ plus signs, or no whitespace after marker (or after optional *)
196
- if (markerLen > 6) {
197
- isInvalidHeading = true;
198
- } else if (afterMarker?.type === "STAR") {
199
- // +* pattern - check whitespace after *
200
- const afterStar = ctx.tokens[afterMarkerPos + 1];
201
- if (afterStar?.type !== "WHITESPACE") {
202
- isInvalidHeading = true;
203
- }
204
- } else if (afterMarker?.type !== "WHITESPACE") {
205
- isInvalidHeading = true;
206
- }
207
- }
208
-
209
- // Check if this block token names an excluded block (e.g. nested collapsible)
210
- const isExcludedBlock =
211
- (nextMeaningfulToken?.type === "BLOCK_OPEN" ||
212
- nextMeaningfulToken?.type === "BLOCK_END_OPEN") &&
213
- isExcludedBlockToken(ctx, pos + lookAhead);
214
-
215
- // Wikidot treats `[[foo]]` (where `foo` is not a known block name) as
216
- // inline text rather than a paragraph-breaking block. Mirror that here.
217
- const isUnknownBlock =
218
- (nextMeaningfulToken?.type === "BLOCK_OPEN" ||
219
- nextMeaningfulToken?.type === "BLOCK_END_OPEN") &&
220
- isUnknownBlockToken(ctx, pos + lookAhead);
221
-
222
- // Stop at double NEWLINE, EOF, or block start token (at line start)
223
- // But don't stop at [[/span]], [[# name]], [[>/[[<, invalid headings,
224
- // excluded block names, or unrecognized block names.
225
- //
226
- // Most block-start tokens require the strict `lineStart` flag (no
227
- // leading whitespace at all): ` # one` is NOT a list item in
228
- // Wikidot, ` + Heading` is NOT a heading, etc. We preserve that.
229
- //
230
- // A subset of `[[...]]` block constructs is the exception:
231
- // their rules declare `requiresLineStart: false`, so Wikidot
232
- // accepts leading whitespace before them and `[[/<name>]]` at
233
- // arbitrary indentation also has to close such a block. The
234
- // `lookAhead` walk above already consumed the NEWLINE and any
235
- // leading WHITESPACE, so we know `nextMeaningfulToken` sits at
236
- // the semantic start of the next line. We relax the `lineStart`
237
- // check only when the block name's rule will actually accept the
238
- // indented opener ({@link INDENT_ACCEPTING_BLOCK_NAMES});
239
- // otherwise (e.g. `[[toc]]`, `[[footnoteblock]]`, align markers)
240
- // the dispatcher would reject the indented token anyway and we
241
- // would end up splitting the paragraph only to leave literal
242
- // `[[…]]` text behind.
243
- const isIndentedBlockOpener =
244
- nextMeaningfulToken &&
245
- (nextMeaningfulToken.type === "BLOCK_OPEN" ||
246
- nextMeaningfulToken.type === "BLOCK_END_OPEN") &&
247
- isIndentAcceptingBlock(ctx, pos + lookAhead);
248
- const isBlockStart =
249
- nextMeaningfulToken &&
250
- BLOCK_START_TOKENS.includes(nextMeaningfulToken.type) &&
251
- (nextMeaningfulToken.lineStart || isIndentedBlockOpener) &&
252
- !isOrphanCloseSpan &&
253
- !isAnchorName &&
254
- !isInvalidBlockOpen &&
255
- !isInvalidHeading &&
256
- !isExcludedBlock &&
257
- !isUnknownBlock;
258
- if (
259
- !nextMeaningfulToken ||
260
- nextMeaningfulToken.type === "NEWLINE" ||
261
- nextMeaningfulToken.type === "EOF" ||
262
- isBlockStart
263
- ) {
264
- // Check if a block rule with preservesPrecedingLineBreak matches at the next position.
265
- // Wikidot's Divalign expands content inline, so \n before it becomes <br />.
266
- // Other blocks (Code, Div, etc.) suppress this by prepending \n\n to their token.
267
- if (isBlockStart && nodes.length > 0) {
268
- const nextPos = pos + lookAhead;
269
- const shouldPreserve = ctx.blockRules.some(
270
- (rule) => rule.preservesPrecedingLineBreak && rule.isStartPattern?.(ctx, nextPos),
271
- );
272
- if (shouldPreserve) {
273
- const lb: any = { element: "line-break" };
274
- lb._preservedTrailingBreak = true;
275
- nodes.push(lb);
276
- }
277
- }
278
- // Consume the NEWLINE and stop
279
- consumed++;
280
- if (nextMeaningfulToken?.type === "NEWLINE") {
281
- consumed++; // Also consume second newline for paragraph break
282
- }
283
- break;
284
- }
285
- }
286
-
287
- if (token.type === endType) {
288
- break;
289
- }
290
-
291
- const inlineCtx: ParseContext = {
292
- ...ctx,
293
- pos,
294
- };
295
-
296
- let matched = false;
297
- for (const rule of inlineRules) {
298
- // Skip the rule that would match the end type to avoid infinite recursion
299
- if (rule.startTokens.includes(endType)) {
300
- continue;
301
- }
302
- if (canApplyInlineRule(rule, token)) {
303
- const result = rule.parse(inlineCtx);
304
- if (result.success) {
305
- nodes.push(...result.elements);
306
- consumed += result.consumed;
307
- pos += result.consumed;
308
- matched = true;
309
- break;
310
- }
311
- }
312
- }
313
-
314
- if (!matched) {
315
- // Fallback to text
316
- nodes.push({ element: "text", data: token.value });
317
- consumed++;
318
- pos++;
319
- }
320
- }
321
-
322
- return { elements: nodes, consumed };
323
- }
324
-
325
- /**
326
- * Collect tokens until newline or EOF
327
- */
328
- export function collectUntilNewline(ctx: ParseContext): { tokens: Token[]; consumed: number } {
329
- const tokens: Token[] = [];
330
- let consumed = 0;
331
- let pos = ctx.pos;
332
-
333
- while (pos < ctx.tokens.length) {
334
- const token = ctx.tokens[pos];
335
- if (!token || token.type === "NEWLINE" || token.type === "EOF") {
336
- break;
337
- }
338
- tokens.push(token);
339
- consumed++;
340
- pos++;
341
- }
342
-
343
- return { tokens, consumed };
344
- }
1
+ export { canApplyInlineRule } from "./parsing/rules";
2
+ export { collectUntilNewline } from "./parsing/collect";
3
+ export { getCandidateInlineRules } from "./parsing/rules";
4
+ export { parseInlineUntil, type InlineParseResult } from "./parsing/inline-content";
@@ -0,0 +1,106 @@
1
+ import type { Token, TokenType } from "../../lexer";
2
+ import type { ParseContext } from "./contracts";
3
+
4
+ /**
5
+ * Helper to get current token
6
+ */
7
+ export function currentToken(ctx: ParseContext): Token {
8
+ return ctx.tokens[ctx.pos] ?? eofToken();
9
+ }
10
+
11
+ /**
12
+ * Helper to peek ahead
13
+ */
14
+ export function peekToken(ctx: ParseContext, n = 1): Token {
15
+ return ctx.tokens[ctx.pos + n] ?? eofToken();
16
+ }
17
+
18
+ /**
19
+ * Helper to check token type
20
+ */
21
+ export function checkToken(ctx: ParseContext, type: TokenType): boolean {
22
+ return currentToken(ctx).type === type;
23
+ }
24
+
25
+ /**
26
+ * Helper to check if at end
27
+ */
28
+ export function isAtEnd(ctx: ParseContext): boolean {
29
+ return ctx.pos >= ctx.tokens.length || currentToken(ctx).type === "EOF";
30
+ }
31
+
32
+ /**
33
+ * Create EOF token
34
+ */
35
+ function eofToken(): Token {
36
+ return {
37
+ type: "EOF",
38
+ value: "",
39
+ position: { start: { line: 0, column: 0, offset: 0 }, end: { line: 0, column: 0, offset: 0 } },
40
+ lineStart: false,
41
+ };
42
+ }
43
+
44
+ /**
45
+ * Check if closing marker exists before newline.
46
+ * If markerValue is provided, also check that the token value matches.
47
+ */
48
+ export function hasClosingMarkerBeforeNewline(
49
+ ctx: ParseContext,
50
+ markerType: TokenType,
51
+ markerValue?: string,
52
+ ): boolean {
53
+ let pos = ctx.pos;
54
+ while (pos < ctx.tokens.length) {
55
+ const token = ctx.tokens[pos];
56
+ if (!token || token.type === "NEWLINE" || token.type === "EOF") {
57
+ return false;
58
+ }
59
+ if (token.type === markerType) {
60
+ if (markerValue === undefined || token.value === markerValue) {
61
+ return true;
62
+ }
63
+ }
64
+ pos++;
65
+ }
66
+ return false;
67
+ }
68
+
69
+ /**
70
+ * Check if closing marker exists before paragraph break (double newline).
71
+ * Allows inline formatting to span multiple lines within a paragraph.
72
+ */
73
+ export function hasClosingMarkerBeforeParagraphBreak(
74
+ ctx: ParseContext,
75
+ markerType: TokenType,
76
+ markerValue?: string,
77
+ ): boolean {
78
+ let pos = ctx.pos;
79
+ while (pos < ctx.tokens.length) {
80
+ const token = ctx.tokens[pos];
81
+ if (!token || token.type === "EOF") {
82
+ return false;
83
+ }
84
+ // Check for paragraph break (NEWLINE followed by NEWLINE after optional whitespace)
85
+ if (token.type === "NEWLINE") {
86
+ let lookAhead = 1;
87
+ while (ctx.tokens[pos + lookAhead]?.type === "WHITESPACE") {
88
+ lookAhead++;
89
+ }
90
+ if (
91
+ ctx.tokens[pos + lookAhead]?.type === "NEWLINE" ||
92
+ ctx.tokens[pos + lookAhead]?.type === "EOF" ||
93
+ !ctx.tokens[pos + lookAhead]
94
+ ) {
95
+ return false;
96
+ }
97
+ }
98
+ if (token.type === markerType) {
99
+ if (markerValue === undefined || token.value === markerValue) {
100
+ return true;
101
+ }
102
+ }
103
+ pos++;
104
+ }
105
+ return false;
106
+ }