@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,82 @@
1
+ import type { Element } from "@wdprlib/ast";
2
+ import type { TokenType } from "../../../../lexer";
3
+ import type { InlineRule, ParseContext, RuleResult } from "../../types";
4
+
5
+ export const newlineLineBreakRule: InlineRule = {
6
+ name: "newlineLineBreak",
7
+ startTokens: ["NEWLINE"],
8
+
9
+ parse(ctx: ParseContext): RuleResult<Element> {
10
+ const currentTok = ctx.tokens[ctx.pos];
11
+ if (!currentTok || currentTok.type !== "NEWLINE") {
12
+ return { success: false };
13
+ }
14
+
15
+ const lookAhead = skipWhitespace(ctx, ctx.pos + 1) - ctx.pos;
16
+ const nextMeaningfulToken = ctx.tokens[ctx.pos + lookAhead];
17
+ const suppressLineBreak =
18
+ !nextMeaningfulToken ||
19
+ nextMeaningfulToken.type === "EOF" ||
20
+ nextMeaningfulToken.type === "NEWLINE" ||
21
+ isValidBlockStartAfterNewline(ctx, ctx.pos + lookAhead) ||
22
+ hasBackslashBreakAfterNewline(ctx);
23
+
24
+ if (suppressLineBreak) {
25
+ return { success: true, elements: [], consumed: 1 };
26
+ }
27
+
28
+ return {
29
+ success: true,
30
+ elements: [{ element: "line-break" }],
31
+ consumed: 1,
32
+ };
33
+ },
34
+ };
35
+
36
+ function isBlockStartToken(type: TokenType | undefined): boolean {
37
+ switch (type) {
38
+ case "BLOCKQUOTE_MARKER":
39
+ case "LIST_BULLET":
40
+ case "LIST_NUMBER":
41
+ case "HEADING_MARKER":
42
+ case "HR_MARKER":
43
+ case "TABLE_MARKER":
44
+ return true;
45
+ default:
46
+ return false;
47
+ }
48
+ }
49
+
50
+ function isValidBlockStartAfterNewline(ctx: ParseContext, tokenPos: number): boolean {
51
+ const token = ctx.tokens[tokenPos];
52
+ if (!isBlockStartToken(token?.type) || !token?.lineStart) {
53
+ return false;
54
+ }
55
+
56
+ if (token.type !== "HEADING_MARKER") {
57
+ return true;
58
+ }
59
+
60
+ const markerLen = token.value.length;
61
+ const afterMarker = ctx.tokens[tokenPos + 1];
62
+ if (markerLen > 6) {
63
+ return false;
64
+ }
65
+ if (afterMarker?.type === "STAR") {
66
+ return ctx.tokens[tokenPos + 2]?.type === "WHITESPACE";
67
+ }
68
+ return afterMarker?.type === "WHITESPACE";
69
+ }
70
+
71
+ function hasBackslashBreakAfterNewline(ctx: ParseContext): boolean {
72
+ const nextPos = skipWhitespace(ctx, ctx.pos + 1);
73
+ return ctx.tokens[nextPos]?.type === "BACKSLASH_BREAK";
74
+ }
75
+
76
+ function skipWhitespace(ctx: ParseContext, startPos: number): number {
77
+ let pos = startPos;
78
+ while (ctx.tokens[pos]?.type === "WHITESPACE") {
79
+ pos++;
80
+ }
81
+ return pos;
82
+ }
@@ -0,0 +1,45 @@
1
+ import type { Element } from "@wdprlib/ast";
2
+ import type { InlineRule, ParseContext, RuleResult } from "../../types";
3
+ import { createPreservedLineBreak } from "./elements";
4
+
5
+ export const underscoreLineBreakRule: InlineRule = {
6
+ name: "underscoreLineBreak",
7
+ startTokens: ["WHITESPACE", "UNDERSCORE"],
8
+
9
+ parse(ctx: ParseContext): RuleResult<Element> {
10
+ const currentTok = ctx.tokens[ctx.pos];
11
+ if (!currentTok) {
12
+ return { success: false };
13
+ }
14
+
15
+ if (currentTok.type === "WHITESPACE") {
16
+ const nextTok = ctx.tokens[ctx.pos + 1];
17
+ const afterTok = ctx.tokens[ctx.pos + 2];
18
+
19
+ if (
20
+ nextTok?.type === "UNDERSCORE" &&
21
+ afterTok &&
22
+ (afterTok.type === "NEWLINE" || afterTok.type === "EOF")
23
+ ) {
24
+ return {
25
+ success: true,
26
+ elements: [createPreservedLineBreak()],
27
+ consumed: 3,
28
+ };
29
+ }
30
+ }
31
+
32
+ if (currentTok.type === "UNDERSCORE" && currentTok.lineStart) {
33
+ const nextTok = ctx.tokens[ctx.pos + 1];
34
+ if (nextTok && (nextTok.type === "NEWLINE" || nextTok.type === "EOF")) {
35
+ return {
36
+ success: true,
37
+ elements: [createPreservedLineBreak()],
38
+ consumed: 2,
39
+ };
40
+ }
41
+ }
42
+
43
+ return { success: false };
44
+ },
45
+ };
@@ -22,7 +22,7 @@
22
22
  */
23
23
  import type { Element, LinkLabel } from "@wdprlib/ast";
24
24
  import type { InlineRule, ParseContext, RuleResult } from "../types";
25
- import { hasClosingMarkerBeforeNewline } from "../types";
25
+ import { parseAnchorBracketLink } from "./link-bracket/parsed";
26
26
 
27
27
  /**
28
28
  * Inline rule for parsing `[#anchor Label]` anchor links.
@@ -47,72 +47,10 @@ export const linkAnchorRule: InlineRule = {
47
47
  * or `{ success: false }`
48
48
  */
49
49
  parse(ctx: ParseContext): RuleResult<Element> {
50
- // Check if closing bracket exists
51
- if (!hasClosingMarkerBeforeNewline({ ...ctx, pos: ctx.pos + 1 }, "BRACKET_CLOSE")) {
52
- return { success: false };
53
- }
50
+ const parsed = parseAnchorBracketLink(ctx);
51
+ if (!parsed) return { success: false };
54
52
 
55
- let pos = ctx.pos + 1;
56
- let consumed = 1; // [#
57
-
58
- // Collect anchor name (until whitespace)
59
- let anchor = "";
60
- while (pos < ctx.tokens.length) {
61
- const token = ctx.tokens[pos];
62
- if (
63
- !token ||
64
- token.type === "WHITESPACE" ||
65
- token.type === "BRACKET_CLOSE" ||
66
- token.type === "NEWLINE" ||
67
- token.type === "EOF"
68
- ) {
69
- break;
70
- }
71
- anchor += token.value;
72
- pos++;
73
- consumed++;
74
- }
75
-
76
- // Skip whitespace between anchor and label
77
- while (ctx.tokens[pos]?.type === "WHITESPACE") {
78
- pos++;
79
- consumed++;
80
- }
81
-
82
- // Collect label (until closing bracket)
83
- let label = "";
84
- while (pos < ctx.tokens.length) {
85
- const token = ctx.tokens[pos];
86
- if (
87
- !token ||
88
- token.type === "BRACKET_CLOSE" ||
89
- token.type === "NEWLINE" ||
90
- token.type === "EOF"
91
- ) {
92
- break;
93
- }
94
- label += token.value;
95
- pos++;
96
- consumed++;
97
- }
98
-
99
- // Consume closing bracket
100
- if (ctx.tokens[pos]?.type === "BRACKET_CLOSE") {
101
- pos++;
102
- consumed++;
103
- } else {
104
- return { success: false };
105
- }
106
-
107
- const trimmedLabel = label.trim();
108
- if (!trimmedLabel) {
109
- return { success: false };
110
- }
111
-
112
- // Determine target: if anchor is empty, use javascript:; (fake link)
113
- // Otherwise, normalize and prepend #
114
- const target = anchor.trim() ? `#${normalizeAnchor(anchor.trim())}` : "javascript:;";
115
- const linkLabel: LinkLabel = { text: trimmedLabel };
53
+ const linkLabel: LinkLabel = { text: parsed.labelText };
116
54
 
117
55
  return {
118
56
  success: true,
@@ -121,27 +59,14 @@ export const linkAnchorRule: InlineRule = {
121
59
  element: "link",
122
60
  data: {
123
61
  type: "anchor",
124
- link: target,
62
+ link: parsed.link,
125
63
  extra: null,
126
64
  label: linkLabel,
127
65
  target: null,
128
66
  },
129
67
  },
130
68
  ],
131
- consumed,
69
+ consumed: parsed.consumed,
132
70
  };
133
71
  },
134
72
  };
135
-
136
- /**
137
- * Normalizes an anchor name for use in a URL fragment.
138
- *
139
- * Converts to lowercase and replaces whitespace sequences with single
140
- * hyphens, matching Wikidot's anchor normalization behavior.
141
- *
142
- * @param anchor - The raw anchor name from the markup
143
- * @returns The normalized anchor name suitable for a URL fragment
144
- */
145
- function normalizeAnchor(anchor: string): string {
146
- return anchor.toLowerCase().replace(/\s+/g, "-");
147
- }
@@ -0,0 +1,3 @@
1
+ export function normalizeAnchor(anchor: string): string {
2
+ return anchor.toLowerCase().replace(/\s+/g, "-");
3
+ }
@@ -0,0 +1,5 @@
1
+ export function isDirectBracketUrl(url: string): boolean {
2
+ return (
3
+ url !== "" && (url.startsWith("/") || url.startsWith("http://") || url.startsWith("https://"))
4
+ );
5
+ }
@@ -0,0 +1,81 @@
1
+ import type { AnchorTarget } from "@wdprlib/ast";
2
+ import type { ParseContext } from "../../types";
3
+ import { normalizeAnchor } from "./anchor";
4
+ import { isDirectBracketUrl } from "./direct-url";
5
+ import { collectBracketLinkParts } from "./parts";
6
+ import { parseBracketLinkPrefix } from "./prefix";
7
+
8
+ export interface ParsedBracketLink {
9
+ link: string;
10
+ labelText: string;
11
+ target: AnchorTarget | null;
12
+ consumed: number;
13
+ }
14
+
15
+ export function parseSingleBracketLink(ctx: ParseContext): ParsedBracketLink | null {
16
+ const prefix = parseBracketLinkPrefix(ctx, ctx.pos + 1);
17
+ const parts = collectBracketLinkParts(ctx, prefix.bodyStart);
18
+ if (!parts) {
19
+ return null;
20
+ }
21
+
22
+ const link = parts.first.trim();
23
+ if (!isDirectBracketUrl(link)) {
24
+ return null;
25
+ }
26
+
27
+ const labelText = parts.label.trim();
28
+ if (!labelText) {
29
+ return null;
30
+ }
31
+
32
+ return {
33
+ link,
34
+ labelText,
35
+ target: prefix.target,
36
+ consumed: 1 + prefix.consumed + parts.consumed,
37
+ };
38
+ }
39
+
40
+ export function parseStarBracketLink(ctx: ParseContext): ParsedBracketLink | null {
41
+ const parts = collectBracketLinkParts(ctx, ctx.pos + 1);
42
+ if (!parts) {
43
+ return null;
44
+ }
45
+
46
+ const link = parts.first.trim();
47
+ if (!link) {
48
+ return null;
49
+ }
50
+
51
+ const labelText = parts.label.trim() || link;
52
+
53
+ return {
54
+ link,
55
+ labelText,
56
+ target: "new-tab",
57
+ consumed: 1 + parts.consumed,
58
+ };
59
+ }
60
+
61
+ export function parseAnchorBracketLink(
62
+ ctx: ParseContext,
63
+ ): Omit<ParsedBracketLink, "target"> | null {
64
+ const parts = collectBracketLinkParts(ctx, ctx.pos + 1);
65
+ if (!parts) {
66
+ return null;
67
+ }
68
+
69
+ const labelText = parts.label.trim();
70
+ if (!labelText) {
71
+ return null;
72
+ }
73
+
74
+ const anchor = parts.first.trim();
75
+
76
+ return {
77
+ link: anchor ? `#${normalizeAnchor(anchor)}` : "javascript:;",
78
+ labelText,
79
+ consumed: 1 + parts.consumed,
80
+ };
81
+ }
@@ -0,0 +1,64 @@
1
+ import type { ParseContext } from "../../types";
2
+ import { hasClosingMarkerBeforeNewline } from "../../types";
3
+
4
+ export interface BracketLinkParts {
5
+ first: string;
6
+ label: string;
7
+ consumed: number;
8
+ }
9
+
10
+ export function collectBracketLinkParts(
11
+ ctx: ParseContext,
12
+ startPos: number,
13
+ ): BracketLinkParts | null {
14
+ if (!hasClosingMarkerBeforeNewline({ ...ctx, pos: startPos }, "BRACKET_CLOSE")) {
15
+ return null;
16
+ }
17
+
18
+ let pos = startPos;
19
+ let consumed = 0;
20
+ let first = "";
21
+
22
+ while (pos < ctx.tokens.length) {
23
+ const token = ctx.tokens[pos];
24
+ if (
25
+ !token ||
26
+ token.type === "WHITESPACE" ||
27
+ token.type === "BRACKET_CLOSE" ||
28
+ token.type === "NEWLINE" ||
29
+ token.type === "EOF"
30
+ ) {
31
+ break;
32
+ }
33
+ first += token.value;
34
+ pos++;
35
+ consumed++;
36
+ }
37
+
38
+ while (ctx.tokens[pos]?.type === "WHITESPACE") {
39
+ pos++;
40
+ consumed++;
41
+ }
42
+
43
+ let label = "";
44
+ while (pos < ctx.tokens.length) {
45
+ const token = ctx.tokens[pos];
46
+ if (
47
+ !token ||
48
+ token.type === "BRACKET_CLOSE" ||
49
+ token.type === "NEWLINE" ||
50
+ token.type === "EOF"
51
+ ) {
52
+ break;
53
+ }
54
+ label += token.value;
55
+ pos++;
56
+ consumed++;
57
+ }
58
+
59
+ if (ctx.tokens[pos]?.type !== "BRACKET_CLOSE") {
60
+ return null;
61
+ }
62
+
63
+ return { first, label, consumed: consumed + 1 };
64
+ }
@@ -0,0 +1,15 @@
1
+ import type { ParseContext } from "../../types";
2
+
3
+ export interface BracketLinkPrefix {
4
+ target: "new-tab" | null;
5
+ bodyStart: number;
6
+ consumed: number;
7
+ }
8
+
9
+ export function parseBracketLinkPrefix(ctx: ParseContext, startPos: number): BracketLinkPrefix {
10
+ if (ctx.tokens[startPos]?.type === "STAR") {
11
+ return { target: "new-tab", bodyStart: startPos + 1, consumed: 1 };
12
+ }
13
+
14
+ return { target: null, bodyStart: startPos, consumed: 0 };
15
+ }
@@ -22,7 +22,7 @@
22
22
  */
23
23
  import type { Element, LinkLabel } from "@wdprlib/ast";
24
24
  import type { InlineRule, ParseContext, RuleResult } from "../types";
25
- import { hasClosingMarkerBeforeNewline } from "../types";
25
+ import { parseSingleBracketLink } from "./link-bracket/parsed";
26
26
 
27
27
  /**
28
28
  * Inline rule for parsing `[url label]` single-bracket links.
@@ -48,84 +48,10 @@ export const linkSingleRule: InlineRule = {
48
48
  * or `{ success: false }`
49
49
  */
50
50
  parse(ctx: ParseContext): RuleResult<Element> {
51
- // Check if closing bracket exists
52
- if (!hasClosingMarkerBeforeNewline({ ...ctx, pos: ctx.pos + 1 }, "BRACKET_CLOSE")) {
53
- return { success: false };
54
- }
51
+ const parsed = parseSingleBracketLink(ctx);
52
+ if (!parsed) return { success: false };
55
53
 
56
- let pos = ctx.pos + 1;
57
- let consumed = 1;
58
-
59
- // Check for new tab marker (*)
60
- let newTab = false;
61
- if (ctx.tokens[pos]?.type === "STAR") {
62
- newTab = true;
63
- pos++;
64
- consumed++;
65
- }
66
-
67
- // Collect URL (until whitespace)
68
- let url = "";
69
- while (pos < ctx.tokens.length) {
70
- const token = ctx.tokens[pos];
71
- if (
72
- !token ||
73
- token.type === "WHITESPACE" ||
74
- token.type === "BRACKET_CLOSE" ||
75
- token.type === "NEWLINE" ||
76
- token.type === "EOF"
77
- ) {
78
- break;
79
- }
80
- url += token.value;
81
- pos++;
82
- consumed++;
83
- }
84
-
85
- // URL must be valid (starts with http://, https://, or /)
86
- const trimmedUrl = url.trim();
87
- if (!isValidUrl(trimmedUrl)) {
88
- return { success: false };
89
- }
90
-
91
- // Skip whitespace between URL and label
92
- while (ctx.tokens[pos]?.type === "WHITESPACE") {
93
- pos++;
94
- consumed++;
95
- }
96
-
97
- // Collect label (until closing bracket)
98
- let label = "";
99
- while (pos < ctx.tokens.length) {
100
- const token = ctx.tokens[pos];
101
- if (
102
- !token ||
103
- token.type === "BRACKET_CLOSE" ||
104
- token.type === "NEWLINE" ||
105
- token.type === "EOF"
106
- ) {
107
- break;
108
- }
109
- label += token.value;
110
- pos++;
111
- consumed++;
112
- }
113
-
114
- // Consume closing bracket
115
- if (ctx.tokens[pos]?.type === "BRACKET_CLOSE") {
116
- pos++;
117
- consumed++;
118
- } else {
119
- // No closing bracket found
120
- return { success: false };
121
- }
122
-
123
- const trimmedLabel = label.trim();
124
- if (!trimmedLabel) {
125
- return { success: false };
126
- }
127
-
128
- const linkLabel: LinkLabel = { text: trimmedLabel };
54
+ const linkLabel: LinkLabel = { text: parsed.labelText };
129
55
 
130
56
  return {
131
57
  success: true,
@@ -134,31 +60,14 @@ export const linkSingleRule: InlineRule = {
134
60
  element: "link",
135
61
  data: {
136
62
  type: "direct",
137
- link: trimmedUrl,
63
+ link: parsed.link,
138
64
  extra: null,
139
65
  label: linkLabel,
140
- target: newTab ? "new-tab" : null,
66
+ target: parsed.target,
141
67
  },
142
68
  },
143
69
  ],
144
- consumed,
70
+ consumed: parsed.consumed,
145
71
  };
146
72
  },
147
73
  };
148
-
149
- /**
150
- * Validates whether a URL is acceptable for single-bracket links.
151
- *
152
- * Only absolute HTTP(S) URLs and site-relative paths (starting with `/`)
153
- * are accepted. Page names, interwiki prefixes, and other formats require
154
- * triple-bracket syntax instead.
155
- *
156
- * @param url - The trimmed URL string to validate
157
- * @returns `true` if the URL starts with `http://`, `https://`, or `/`
158
- */
159
- function isValidUrl(url: string): boolean {
160
- if (!url) return false;
161
- if (url.startsWith("/")) return true;
162
- if (url.startsWith("http://") || url.startsWith("https://")) return true;
163
- return false;
164
- }
@@ -23,7 +23,7 @@
23
23
  */
24
24
  import type { Element, LinkLabel } from "@wdprlib/ast";
25
25
  import type { InlineRule, ParseContext, RuleResult } from "../types";
26
- import { hasClosingMarkerBeforeNewline } from "../types";
26
+ import { parseStarBracketLink } from "./link-bracket/parsed";
27
27
 
28
28
  /**
29
29
  * Inline rule for parsing `[*url label]` star links.
@@ -47,72 +47,10 @@ export const linkStarRule: InlineRule = {
47
47
  * @returns A successful result with a `"link"` element, or `{ success: false }`
48
48
  */
49
49
  parse(ctx: ParseContext): RuleResult<Element> {
50
- // Check if closing bracket exists
51
- if (!hasClosingMarkerBeforeNewline({ ...ctx, pos: ctx.pos + 1 }, "BRACKET_CLOSE")) {
52
- return { success: false };
53
- }
50
+ const parsed = parseStarBracketLink(ctx);
51
+ if (!parsed) return { success: false };
54
52
 
55
- let pos = ctx.pos + 1;
56
- let consumed = 1; // [*
57
-
58
- // Collect URL (until whitespace)
59
- let url = "";
60
- while (pos < ctx.tokens.length) {
61
- const token = ctx.tokens[pos];
62
- if (
63
- !token ||
64
- token.type === "WHITESPACE" ||
65
- token.type === "BRACKET_CLOSE" ||
66
- token.type === "NEWLINE" ||
67
- token.type === "EOF"
68
- ) {
69
- break;
70
- }
71
- url += token.value;
72
- pos++;
73
- consumed++;
74
- }
75
-
76
- const trimmedUrl = url.trim();
77
- if (!trimmedUrl) {
78
- return { success: false };
79
- }
80
-
81
- // Skip whitespace between URL and label
82
- while (ctx.tokens[pos]?.type === "WHITESPACE") {
83
- pos++;
84
- consumed++;
85
- }
86
-
87
- // Collect label (until closing bracket)
88
- let label = "";
89
- while (pos < ctx.tokens.length) {
90
- const token = ctx.tokens[pos];
91
- if (
92
- !token ||
93
- token.type === "BRACKET_CLOSE" ||
94
- token.type === "NEWLINE" ||
95
- token.type === "EOF"
96
- ) {
97
- break;
98
- }
99
- label += token.value;
100
- pos++;
101
- consumed++;
102
- }
103
-
104
- // Consume closing bracket
105
- if (ctx.tokens[pos]?.type === "BRACKET_CLOSE") {
106
- pos++;
107
- consumed++;
108
- } else {
109
- return { success: false };
110
- }
111
-
112
- const trimmedLabel = label.trim();
113
- // If no label, use URL as label
114
- const displayLabel = trimmedLabel || trimmedUrl;
115
- const linkLabel: LinkLabel = { text: displayLabel };
53
+ const linkLabel: LinkLabel = { text: parsed.labelText };
116
54
 
117
55
  return {
118
56
  success: true,
@@ -121,14 +59,14 @@ export const linkStarRule: InlineRule = {
121
59
  element: "link",
122
60
  data: {
123
61
  type: "direct",
124
- link: trimmedUrl,
62
+ link: parsed.link,
125
63
  extra: null,
126
64
  label: linkLabel,
127
- target: "new-tab",
65
+ target: parsed.target,
128
66
  },
129
67
  },
130
68
  ],
131
- consumed,
69
+ consumed: parsed.consumed,
132
70
  };
133
71
  },
134
72
  };
@@ -0,0 +1,10 @@
1
+ import type { Element } from "@wdprlib/ast";
2
+ import type { RuleResult } from "../../types";
3
+
4
+ export function literalOpenLink(value: string): RuleResult<Element> {
5
+ return {
6
+ success: true,
7
+ elements: [{ element: "text", data: value }],
8
+ consumed: 1,
9
+ };
10
+ }