@wdprlib/parser 3.1.2 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (419) hide show
  1. package/dist/index.cjs +10456 -8230
  2. package/dist/index.d.cts +313 -337
  3. package/dist/index.d.ts +313 -337
  4. package/dist/index.js +10460 -8234
  5. package/package.json +5 -3
  6. package/src/index.ts +170 -0
  7. package/src/lexer/anchor.ts +48 -0
  8. package/src/lexer/index.ts +21 -0
  9. package/src/lexer/lexer.ts +201 -0
  10. package/src/lexer/options.ts +19 -0
  11. package/src/lexer/punctuation.ts +70 -0
  12. package/src/lexer/quoted-string.ts +16 -0
  13. package/src/lexer/runs.ts +85 -0
  14. package/src/lexer/spacing-actions.ts +24 -0
  15. package/src/lexer/state.ts +103 -0
  16. package/src/lexer/syntax-actions.ts +80 -0
  17. package/src/lexer/text-actions.ts +41 -0
  18. package/src/lexer/token-actions.ts +136 -0
  19. package/src/lexer/token-factory.ts +62 -0
  20. package/src/lexer/tokenize.ts +18 -0
  21. package/src/lexer/tokens.ts +141 -0
  22. package/src/parser/constants.ts +175 -0
  23. package/src/parser/depth/index.ts +111 -0
  24. package/src/parser/depth/stack.ts +82 -0
  25. package/src/parser/index.ts +18 -0
  26. package/src/parser/parse/block.ts +42 -0
  27. package/src/parser/parse/context.ts +26 -0
  28. package/src/parser/parse/footnotes.ts +25 -0
  29. package/src/parser/parse/index.ts +42 -0
  30. package/src/parser/parse/options.ts +34 -0
  31. package/src/parser/parse/parser.ts +79 -0
  32. package/src/parser/parse/plain-non-ascii.ts +129 -0
  33. package/src/parser/parse/result.ts +57 -0
  34. package/src/parser/parse/source.ts +11 -0
  35. package/src/parser/postprocess/divAdjacentParagraph.ts +76 -0
  36. package/src/parser/postprocess/index.ts +15 -0
  37. package/src/parser/postprocess/spanStrip/clean-element.ts +168 -0
  38. package/src/parser/postprocess/spanStrip/cleanup.ts +25 -0
  39. package/src/parser/postprocess/spanStrip/empty-spans.ts +36 -0
  40. package/src/parser/postprocess/spanStrip/escaped.ts +78 -0
  41. package/src/parser/postprocess/spanStrip/factory.ts +23 -0
  42. package/src/parser/postprocess/spanStrip/index.ts +8 -0
  43. package/src/parser/postprocess/spanStrip/merge.ts +117 -0
  44. package/src/parser/postprocess/spanStrip/predicates.ts +59 -0
  45. package/src/parser/postprocess/spanStrip/split.ts +67 -0
  46. package/src/parser/preprocess/expr/chars.ts +15 -0
  47. package/src/parser/preprocess/expr/evaluate.ts +22 -0
  48. package/src/parser/preprocess/expr/index.ts +45 -0
  49. package/src/parser/preprocess/expr/kind.ts +19 -0
  50. package/src/parser/preprocess/expr/parse.ts +103 -0
  51. package/src/parser/preprocess/expr/scan.ts +34 -0
  52. package/src/parser/preprocess/expr/types.ts +14 -0
  53. package/src/parser/preprocess/index.ts +38 -0
  54. package/src/parser/preprocess/typography.ts +132 -0
  55. package/src/parser/preprocess/utils/bracket-depths.ts +98 -0
  56. package/src/parser/preprocess/utils/index.ts +13 -0
  57. package/src/parser/preprocess/utils/raw-regions.ts +153 -0
  58. package/src/parser/preprocess/whitespace/detection.ts +39 -0
  59. package/src/parser/preprocess/whitespace/index.ts +79 -0
  60. package/src/parser/preprocess/whitespace/leading-spaces.ts +11 -0
  61. package/src/parser/preprocess/whitespace/patterns.ts +23 -0
  62. package/src/parser/rules/block/align/body.ts +46 -0
  63. package/src/parser/rules/block/align/element.ts +13 -0
  64. package/src/parser/rules/block/align/index.ts +90 -0
  65. package/src/parser/rules/block/align/syntax.ts +113 -0
  66. package/src/parser/rules/block/bibliography/body.ts +81 -0
  67. package/src/parser/rules/block/bibliography/entries.ts +49 -0
  68. package/src/parser/rules/block/bibliography/entry-content.ts +73 -0
  69. package/src/parser/rules/block/bibliography/entry-key.ts +83 -0
  70. package/src/parser/rules/block/bibliography/index.ts +90 -0
  71. package/src/parser/rules/block/bibliography/open.ts +53 -0
  72. package/src/parser/rules/block/block-list/bare-content.ts +105 -0
  73. package/src/parser/rules/block/block-list/bare-paragraph.ts +60 -0
  74. package/src/parser/rules/block/block-list/index.ts +51 -0
  75. package/src/parser/rules/block/block-list/item-content.ts +132 -0
  76. package/src/parser/rules/block/block-list/li-content.ts +107 -0
  77. package/src/parser/rules/block/block-list/li-item.ts +77 -0
  78. package/src/parser/rules/block/block-list/list-block.ts +100 -0
  79. package/src/parser/rules/block/block-list/open.ts +51 -0
  80. package/src/parser/rules/block/block-list/tags.ts +50 -0
  81. package/src/parser/rules/block/blockquote/build.ts +62 -0
  82. package/src/parser/rules/block/blockquote/index.ts +80 -0
  83. package/src/parser/rules/block/blockquote/line.ts +79 -0
  84. package/src/parser/rules/block/blockquote/lines.ts +39 -0
  85. package/src/parser/rules/block/center/index.ts +72 -0
  86. package/src/parser/rules/block/center/open.ts +27 -0
  87. package/src/parser/rules/block/clear-float/index.ts +51 -0
  88. package/src/parser/rules/block/clear-float/syntax.ts +43 -0
  89. package/src/parser/rules/block/code/attributes.ts +30 -0
  90. package/src/parser/rules/block/code/content.ts +57 -0
  91. package/src/parser/rules/block/code/index.ts +100 -0
  92. package/src/parser/rules/block/collapsible/attributes.ts +95 -0
  93. package/src/parser/rules/block/collapsible/body.ts +69 -0
  94. package/src/parser/rules/block/collapsible/index.ts +117 -0
  95. package/src/parser/rules/block/collapsible/open.ts +51 -0
  96. package/src/parser/rules/block/collapsible/orphans.ts +31 -0
  97. package/src/parser/rules/block/collapsible/tags.ts +17 -0
  98. package/src/parser/rules/block/comment/consume.ts +37 -0
  99. package/src/parser/rules/block/comment/index.ts +47 -0
  100. package/src/parser/rules/block/content-separator/index.ts +49 -0
  101. package/src/parser/rules/block/content-separator/syntax.ts +33 -0
  102. package/src/parser/rules/block/definition-list/collect.ts +40 -0
  103. package/src/parser/rules/block/definition-list/index.ts +63 -0
  104. package/src/parser/rules/block/definition-list/item-key.ts +95 -0
  105. package/src/parser/rules/block/definition-list/item-value.ts +56 -0
  106. package/src/parser/rules/block/definition-list/items.ts +54 -0
  107. package/src/parser/rules/block/div/body.ts +41 -0
  108. package/src/parser/rules/block/div/close.ts +41 -0
  109. package/src/parser/rules/block/div/failed.ts +117 -0
  110. package/src/parser/rules/block/div/index.ts +112 -0
  111. package/src/parser/rules/block/div/nesting.ts +37 -0
  112. package/src/parser/rules/block/div/open.ts +59 -0
  113. package/src/parser/rules/block/div/paragraph-strip.ts +44 -0
  114. package/src/parser/rules/block/embed-block/content.ts +53 -0
  115. package/src/parser/rules/block/embed-block/index.ts +91 -0
  116. package/src/parser/rules/block/embed-block/open.ts +52 -0
  117. package/src/parser/rules/block/embed-block/tags.ts +5 -0
  118. package/src/parser/rules/block/footnoteblock/attributes.ts +73 -0
  119. package/src/parser/rules/block/footnoteblock/index.ts +82 -0
  120. package/src/parser/rules/block/footnoteblock/open.ts +53 -0
  121. package/src/parser/rules/block/heading/index.ts +87 -0
  122. package/src/parser/rules/block/heading/open.ts +50 -0
  123. package/src/parser/rules/block/heading/toc-text.ts +26 -0
  124. package/src/parser/rules/block/horizontal-rule/index.ts +44 -0
  125. package/src/parser/rules/block/horizontal-rule/syntax.ts +21 -0
  126. package/src/parser/rules/block/html/body.ts +114 -0
  127. package/src/parser/rules/block/html/diagnostics.ts +11 -0
  128. package/src/parser/rules/block/html/index.ts +95 -0
  129. package/src/parser/rules/block/html/open.ts +36 -0
  130. package/src/parser/rules/block/iframe/attributes.ts +106 -0
  131. package/src/parser/rules/block/iframe/index.ts +73 -0
  132. package/src/parser/rules/block/iframe/open.ts +58 -0
  133. package/src/parser/rules/block/iframe/source.ts +24 -0
  134. package/src/parser/rules/block/iframe/url.ts +38 -0
  135. package/src/parser/rules/block/iftags/body.ts +48 -0
  136. package/src/parser/rules/block/iftags/condition.ts +24 -0
  137. package/src/parser/rules/block/iftags/index.ts +108 -0
  138. package/src/parser/rules/block/include/arguments.ts +48 -0
  139. package/src/parser/rules/block/include/index.ts +75 -0
  140. package/src/parser/rules/block/include/location.ts +24 -0
  141. package/src/parser/rules/block/include/variables.ts +37 -0
  142. package/src/parser/rules/block/index.ts +127 -0
  143. package/src/parser/rules/block/list/index.ts +73 -0
  144. package/src/parser/rules/block/list/line.ts +77 -0
  145. package/src/parser/rules/block/list/native.ts +89 -0
  146. package/src/parser/rules/block/math/content.ts +54 -0
  147. package/src/parser/rules/block/math/index.ts +106 -0
  148. package/src/parser/rules/block/math/name.ts +35 -0
  149. package/src/parser/rules/block/module/backlinks/index.ts +31 -0
  150. package/src/parser/rules/block/module/backlinks/types.ts +21 -0
  151. package/src/parser/rules/block/module/body.ts +92 -0
  152. package/src/parser/rules/block/module/categories/index.ts +34 -0
  153. package/src/parser/rules/block/module/categories/types.ts +21 -0
  154. package/src/parser/rules/block/module/css/index.ts +37 -0
  155. package/src/parser/rules/block/module/element.ts +33 -0
  156. package/src/parser/rules/block/module/iftags/condition.ts +109 -0
  157. package/src/parser/rules/block/module/iftags/index.ts +26 -0
  158. package/src/parser/rules/block/module/iftags/preprocess.ts +140 -0
  159. package/src/parser/rules/block/module/iftags/resolve.ts +73 -0
  160. package/src/parser/rules/block/module/iftags/types.ts +63 -0
  161. package/src/parser/rules/block/module/include/directive.ts +91 -0
  162. package/src/parser/rules/block/module/include/index.ts +29 -0
  163. package/src/parser/rules/block/module/include/references.ts +42 -0
  164. package/src/parser/rules/block/module/include/resolve/cache.ts +44 -0
  165. package/src/parser/rules/block/module/include/resolve/index.ts +106 -0
  166. package/src/parser/rules/block/module/include/resolve/iterate.ts +202 -0
  167. package/src/parser/rules/block/module/include/resolve/replace.ts +31 -0
  168. package/src/parser/rules/block/module/include/resolve/types.ts +105 -0
  169. package/src/parser/rules/block/module/include/scanner.ts +121 -0
  170. package/src/parser/rules/block/module/index.ts +134 -0
  171. package/src/parser/rules/block/module/join/index.ts +34 -0
  172. package/src/parser/rules/block/module/join/types.ts +23 -0
  173. package/src/parser/rules/block/module/listpages/compiler.ts +73 -0
  174. package/src/parser/rules/block/module/listpages/extract.ts +76 -0
  175. package/src/parser/rules/block/module/listpages/extraction/listpages.ts +42 -0
  176. package/src/parser/rules/block/module/listpages/extraction/listusers.ts +30 -0
  177. package/src/parser/rules/block/module/listpages/extraction/query.ts +51 -0
  178. package/src/parser/rules/block/module/listpages/extraction/result.ts +18 -0
  179. package/src/parser/rules/block/module/listpages/extraction/template.ts +96 -0
  180. package/src/parser/rules/block/module/listpages/extraction/variables.ts +58 -0
  181. package/src/parser/rules/block/module/listpages/index.ts +83 -0
  182. package/src/parser/rules/block/module/listpages/normalization/date-selector.ts +53 -0
  183. package/src/parser/rules/block/module/listpages/normalization/numeric-selector.ts +32 -0
  184. package/src/parser/rules/block/module/listpages/normalization/order-parent.ts +82 -0
  185. package/src/parser/rules/block/module/listpages/normalization/selectors.ts +2 -0
  186. package/src/parser/rules/block/module/listpages/normalization/tags-category.ts +86 -0
  187. package/src/parser/rules/block/module/listpages/normalize.ts +74 -0
  188. package/src/parser/rules/block/module/listpages/parser.ts +106 -0
  189. package/src/parser/rules/block/module/listpages/resolution/items.ts +43 -0
  190. package/src/parser/rules/block/module/listpages/resolution/wrapper.ts +42 -0
  191. package/src/parser/rules/block/module/listpages/resolve.ts +60 -0
  192. package/src/parser/rules/block/module/listpages/template/format/content.ts +41 -0
  193. package/src/parser/rules/block/module/listpages/template/format/date.ts +116 -0
  194. package/src/parser/rules/block/module/listpages/template/format/index.ts +4 -0
  195. package/src/parser/rules/block/module/listpages/template/format/tags.ts +7 -0
  196. package/src/parser/rules/block/module/listpages/template/format/user.ts +9 -0
  197. package/src/parser/rules/block/module/listpages/template/getters/index.ts +36 -0
  198. package/src/parser/rules/block/module/listpages/template/getters/parameterized.ts +60 -0
  199. package/src/parser/rules/block/module/listpages/template/getters/simple.ts +65 -0
  200. package/src/parser/rules/block/module/listpages/template/getters/types.ts +3 -0
  201. package/src/parser/rules/block/module/listpages/template/syntax.ts +97 -0
  202. package/src/parser/rules/block/module/listpages/types/data-fetcher.ts +15 -0
  203. package/src/parser/rules/block/module/listpages/types/data-requirements.ts +52 -0
  204. package/src/parser/rules/block/module/listpages/types/external-data.ts +77 -0
  205. package/src/parser/rules/block/module/listpages/types/index.ts +17 -0
  206. package/src/parser/rules/block/module/listpages/types/normalized-query.ts +120 -0
  207. package/src/parser/rules/block/module/listpages/types/query.ts +67 -0
  208. package/src/parser/rules/block/module/listpages/types/template.ts +17 -0
  209. package/src/parser/rules/block/module/listpages/types/variables.ts +69 -0
  210. package/src/parser/rules/block/module/listpages/url-resolution/fields.ts +48 -0
  211. package/src/parser/rules/block/module/listpages/url-resolution/params.ts +19 -0
  212. package/src/parser/rules/block/module/listpages/url-resolution/query.ts +24 -0
  213. package/src/parser/rules/block/module/listpages/url-resolution/resolve.ts +53 -0
  214. package/src/parser/rules/block/module/listpages/url-resolution/value.ts +25 -0
  215. package/src/parser/rules/block/module/listpages/url-resolver.ts +29 -0
  216. package/src/parser/rules/block/module/listusers/compiler.ts +56 -0
  217. package/src/parser/rules/block/module/listusers/extract.ts +40 -0
  218. package/src/parser/rules/block/module/listusers/getters.ts +21 -0
  219. package/src/parser/rules/block/module/listusers/index.ts +36 -0
  220. package/src/parser/rules/block/module/listusers/parser.ts +54 -0
  221. package/src/parser/rules/block/module/listusers/resolve.ts +58 -0
  222. package/src/parser/rules/block/module/listusers/types.ts +93 -0
  223. package/src/parser/rules/block/module/listusers/variables.ts +15 -0
  224. package/src/parser/rules/block/module/mapping.ts +61 -0
  225. package/src/parser/rules/block/module/open.ts +57 -0
  226. package/src/parser/rules/block/module/page-tree/index.ts +38 -0
  227. package/src/parser/rules/block/module/page-tree/types.ts +29 -0
  228. package/src/parser/rules/block/module/rate/index.ts +28 -0
  229. package/src/parser/rules/block/module/rate/types.ts +19 -0
  230. package/src/parser/rules/block/module/resolution/contexts.ts +78 -0
  231. package/src/parser/rules/block/module/resolution/data-maps.ts +39 -0
  232. package/src/parser/rules/block/module/resolution/dynamic-modules.ts +93 -0
  233. package/src/parser/rules/block/module/resolution/styles.ts +53 -0
  234. package/src/parser/rules/block/module/resolution/walk-resolve.ts +107 -0
  235. package/src/parser/rules/block/module/resolve.ts +198 -0
  236. package/src/parser/rules/block/module/rule.ts +56 -0
  237. package/src/parser/rules/block/module/types-common.ts +70 -0
  238. package/src/parser/rules/block/module/types.ts +61 -0
  239. package/src/parser/rules/block/module/utils.ts +43 -0
  240. package/src/parser/rules/block/module/walk/children.ts +35 -0
  241. package/src/parser/rules/block/module/walk/index.ts +9 -0
  242. package/src/parser/rules/block/module/walk/map/index.ts +2 -0
  243. package/src/parser/rules/block/module/walk/map/stateful-definition-list.ts +25 -0
  244. package/src/parser/rules/block/module/walk/map/stateful-list.ts +40 -0
  245. package/src/parser/rules/block/module/walk/map/stateful-table.ts +23 -0
  246. package/src/parser/rules/block/module/walk/map/stateful-tabs.ts +19 -0
  247. package/src/parser/rules/block/module/walk/map/stateful.ts +71 -0
  248. package/src/parser/rules/block/module/walk/map/stateless-definition-list.ts +12 -0
  249. package/src/parser/rules/block/module/walk/map/stateless-list.ts +29 -0
  250. package/src/parser/rules/block/module/walk/map/stateless-table.ts +11 -0
  251. package/src/parser/rules/block/module/walk/map/stateless-tabs.ts +5 -0
  252. package/src/parser/rules/block/module/walk/map/stateless.ts +51 -0
  253. package/src/parser/rules/block/module/walk/map/types.ts +6 -0
  254. package/src/parser/rules/block/module/walk/traverse.ts +65 -0
  255. package/src/parser/rules/block/orphan-li/content.ts +60 -0
  256. package/src/parser/rules/block/orphan-li/index.ts +75 -0
  257. package/src/parser/rules/block/orphan-li/open.ts +25 -0
  258. package/src/parser/rules/block/orphan-li/tags.ts +40 -0
  259. package/src/parser/rules/block/paragraph/content.ts +12 -0
  260. package/src/parser/rules/block/paragraph/index.ts +60 -0
  261. package/src/parser/rules/block/paragraph/normalize.ts +52 -0
  262. package/src/parser/rules/block/paragraph/span-markers.ts +52 -0
  263. package/src/parser/rules/block/parsing/attributes/index.ts +32 -0
  264. package/src/parser/rules/block/parsing/attributes/names.ts +93 -0
  265. package/src/parser/rules/block/parsing/attributes/scanner.ts +75 -0
  266. package/src/parser/rules/block/parsing/attributes/values.ts +26 -0
  267. package/src/parser/rules/block/parsing/block-item.ts +29 -0
  268. package/src/parser/rules/block/parsing/content.ts +127 -0
  269. package/src/parser/rules/block/parsing/end-condition.ts +51 -0
  270. package/src/parser/rules/block/parsing/inline-content.ts +105 -0
  271. package/src/parser/rules/block/parsing/inline-newline.ts +41 -0
  272. package/src/parser/rules/block/parsing/non-boundary.ts +24 -0
  273. package/src/parser/rules/block/parsing/rule-dispatch.ts +44 -0
  274. package/src/parser/rules/block/table/index.ts +80 -0
  275. package/src/parser/rules/block/table/pipe/cell-start.ts +69 -0
  276. package/src/parser/rules/block/table/pipe/cell.ts +106 -0
  277. package/src/parser/rules/block/table/pipe/index.ts +2 -0
  278. package/src/parser/rules/block/table/pipe/row.ts +88 -0
  279. package/src/parser/rules/block/table/pipe/tokens.ts +14 -0
  280. package/src/parser/rules/block/table/pipe/trim.ts +50 -0
  281. package/src/parser/rules/block/table-block/body.ts +79 -0
  282. package/src/parser/rules/block/table-block/cell-attributes.ts +33 -0
  283. package/src/parser/rules/block/table-block/cell-boundary.ts +99 -0
  284. package/src/parser/rules/block/table-block/cell-content/index.ts +88 -0
  285. package/src/parser/rules/block/table-block/cell-content/segments.ts +134 -0
  286. package/src/parser/rules/block/table-block/cell-newline.ts +47 -0
  287. package/src/parser/rules/block/table-block/cell.ts +64 -0
  288. package/src/parser/rules/block/table-block/index.ts +113 -0
  289. package/src/parser/rules/block/table-block/row-boundary.ts +75 -0
  290. package/src/parser/rules/block/table-block/structure.ts +80 -0
  291. package/src/parser/rules/block/tabview/body.ts +64 -0
  292. package/src/parser/rules/block/tabview/index.ts +90 -0
  293. package/src/parser/rules/block/tabview/open.ts +50 -0
  294. package/src/parser/rules/block/tabview/tab.ts +92 -0
  295. package/src/parser/rules/block/tabview/tags.ts +30 -0
  296. package/src/parser/rules/block/toc/element.ts +11 -0
  297. package/src/parser/rules/block/toc/index.ts +44 -0
  298. package/src/parser/rules/block/toc/open.ts +84 -0
  299. package/src/parser/rules/block/utils.ts +15 -0
  300. package/src/parser/rules/common/attribute-safety.ts +109 -0
  301. package/src/parser/rules/common/block-name.ts +33 -0
  302. package/src/parser/rules/common/index.ts +2 -0
  303. package/src/parser/rules/contracts/index.ts +3 -0
  304. package/src/parser/rules/contracts/parse-context.ts +38 -0
  305. package/src/parser/rules/contracts/rule.ts +43 -0
  306. package/src/parser/rules/contracts/scope.ts +31 -0
  307. package/src/parser/rules/index.ts +49 -0
  308. package/src/parser/rules/inline/anchor/attributes.ts +54 -0
  309. package/src/parser/rules/inline/anchor/child.ts +26 -0
  310. package/src/parser/rules/inline/anchor/close.ts +34 -0
  311. package/src/parser/rules/inline/anchor/content.ts +59 -0
  312. package/src/parser/rules/inline/anchor/index.ts +103 -0
  313. package/src/parser/rules/inline/anchor/newline.ts +26 -0
  314. package/src/parser/rules/inline/anchor/open.ts +47 -0
  315. package/src/parser/rules/inline/anchor/paragraph-strip.ts +14 -0
  316. package/src/parser/rules/inline/anchor/syntax.ts +40 -0
  317. package/src/parser/rules/inline/anchor-name/index.ts +38 -0
  318. package/src/parser/rules/inline/anchor-name/name.ts +39 -0
  319. package/src/parser/rules/inline/anchor-name/syntax.ts +46 -0
  320. package/src/parser/rules/inline/bibcite/element.ts +14 -0
  321. package/src/parser/rules/inline/bibcite/index.ts +34 -0
  322. package/src/parser/rules/inline/bibcite/syntax.ts +64 -0
  323. package/src/parser/rules/inline/bold.ts +49 -0
  324. package/src/parser/rules/inline/color/index.ts +35 -0
  325. package/src/parser/rules/inline/color/syntax.ts +69 -0
  326. package/src/parser/rules/inline/comment/consume.ts +31 -0
  327. package/src/parser/rules/inline/comment/index.ts +64 -0
  328. package/src/parser/rules/inline/equation-ref/element.ts +8 -0
  329. package/src/parser/rules/inline/equation-ref/index.ts +34 -0
  330. package/src/parser/rules/inline/equation-ref/syntax.ts +45 -0
  331. package/src/parser/rules/inline/expr/branch.ts +104 -0
  332. package/src/parser/rules/inline/expr/conditional-branch.ts +27 -0
  333. package/src/parser/rules/inline/expr/conditional.ts +80 -0
  334. package/src/parser/rules/inline/expr/depth.ts +25 -0
  335. package/src/parser/rules/inline/expr/elements.ts +39 -0
  336. package/src/parser/rules/inline/expr/index.ts +84 -0
  337. package/src/parser/rules/inline/expr/syntax.ts +45 -0
  338. package/src/parser/rules/inline/footnote/child.ts +22 -0
  339. package/src/parser/rules/inline/footnote/close.ts +33 -0
  340. package/src/parser/rules/inline/footnote/content.ts +54 -0
  341. package/src/parser/rules/inline/footnote/elements.ts +38 -0
  342. package/src/parser/rules/inline/footnote/index.ts +54 -0
  343. package/src/parser/rules/inline/footnote/newline.ts +27 -0
  344. package/src/parser/rules/inline/footnote/open.ts +38 -0
  345. package/src/parser/rules/inline/formatting/container.ts +50 -0
  346. package/src/parser/rules/inline/guillemet/index.ts +56 -0
  347. package/src/parser/rules/inline/guillemet/text.ts +11 -0
  348. package/src/parser/rules/inline/html/gate.ts +64 -0
  349. package/src/parser/rules/inline/html/index.ts +81 -0
  350. package/src/parser/rules/inline/html/open.ts +37 -0
  351. package/src/parser/rules/inline/image/attributes.ts +22 -0
  352. package/src/parser/rules/inline/image/body.ts +36 -0
  353. package/src/parser/rules/inline/image/index.ts +89 -0
  354. package/src/parser/rules/inline/image/open.ts +56 -0
  355. package/src/parser/rules/inline/image/source.ts +62 -0
  356. package/src/parser/rules/inline/image/syntax.ts +76 -0
  357. package/src/parser/rules/inline/index.ts +150 -0
  358. package/src/parser/rules/inline/italic.ts +46 -0
  359. package/src/parser/rules/inline/line-break/backslash.ts +58 -0
  360. package/src/parser/rules/inline/line-break/elements.ts +9 -0
  361. package/src/parser/rules/inline/line-break/index.ts +3 -0
  362. package/src/parser/rules/inline/line-break/newline.ts +82 -0
  363. package/src/parser/rules/inline/line-break/underscore.ts +45 -0
  364. package/src/parser/rules/inline/link-anchor.ts +72 -0
  365. package/src/parser/rules/inline/link-bracket/anchor.ts +3 -0
  366. package/src/parser/rules/inline/link-bracket/direct-url.ts +5 -0
  367. package/src/parser/rules/inline/link-bracket/parsed.ts +81 -0
  368. package/src/parser/rules/inline/link-bracket/parts.ts +64 -0
  369. package/src/parser/rules/inline/link-bracket/prefix.ts +15 -0
  370. package/src/parser/rules/inline/link-single.ts +73 -0
  371. package/src/parser/rules/inline/link-star.ts +72 -0
  372. package/src/parser/rules/inline/link-triple/fallback.ts +10 -0
  373. package/src/parser/rules/inline/link-triple/index.ts +62 -0
  374. package/src/parser/rules/inline/link-triple/interwiki.ts +11 -0
  375. package/src/parser/rules/inline/link-triple/label.ts +35 -0
  376. package/src/parser/rules/inline/link-triple/syntax.ts +72 -0
  377. package/src/parser/rules/inline/link-triple/target.ts +36 -0
  378. package/src/parser/rules/inline/math-inline/index.ts +40 -0
  379. package/src/parser/rules/inline/math-inline/syntax.ts +55 -0
  380. package/src/parser/rules/inline/monospace.ts +50 -0
  381. package/src/parser/rules/inline/parsing/block-boundary.ts +42 -0
  382. package/src/parser/rules/inline/parsing/block-start-predicates.ts +117 -0
  383. package/src/parser/rules/inline/parsing/collect.ts +23 -0
  384. package/src/parser/rules/inline/parsing/inline-content.ts +115 -0
  385. package/src/parser/rules/inline/parsing/paragraph-boundary.ts +47 -0
  386. package/src/parser/rules/inline/parsing/plain-text.ts +69 -0
  387. package/src/parser/rules/inline/parsing/preserved-line-break.ts +11 -0
  388. package/src/parser/rules/inline/parsing/rules.ts +34 -0
  389. package/src/parser/rules/inline/parsing/simple-token.ts +26 -0
  390. package/src/parser/rules/inline/raw/angle.ts +40 -0
  391. package/src/parser/rules/inline/raw/double-at.ts +78 -0
  392. package/src/parser/rules/inline/raw/index.ts +26 -0
  393. package/src/parser/rules/inline/raw/result.ts +26 -0
  394. package/src/parser/rules/inline/size/content.ts +65 -0
  395. package/src/parser/rules/inline/size/index.ts +55 -0
  396. package/src/parser/rules/inline/size/open.ts +43 -0
  397. package/src/parser/rules/inline/size/value.ts +45 -0
  398. package/src/parser/rules/inline/span/content.ts +97 -0
  399. package/src/parser/rules/inline/span/elements.ts +108 -0
  400. package/src/parser/rules/inline/span/index.ts +79 -0
  401. package/src/parser/rules/inline/span/newline.ts +50 -0
  402. package/src/parser/rules/inline/span/syntax.ts +70 -0
  403. package/src/parser/rules/inline/strikethrough/index.ts +60 -0
  404. package/src/parser/rules/inline/strikethrough/parse.ts +14 -0
  405. package/src/parser/rules/inline/strikethrough/syntax.ts +24 -0
  406. package/src/parser/rules/inline/subscript.ts +47 -0
  407. package/src/parser/rules/inline/superscript.ts +49 -0
  408. package/src/parser/rules/inline/text/element.ts +5 -0
  409. package/src/parser/rules/inline/text/index.ts +85 -0
  410. package/src/parser/rules/inline/underline/child.ts +26 -0
  411. package/src/parser/rules/inline/underline/content.ts +29 -0
  412. package/src/parser/rules/inline/underline/index.ts +84 -0
  413. package/src/parser/rules/inline/user/element.ts +11 -0
  414. package/src/parser/rules/inline/user/index.ts +34 -0
  415. package/src/parser/rules/inline/user/syntax.ts +67 -0
  416. package/src/parser/rules/inline/utils.ts +4 -0
  417. package/src/parser/rules/tokens.ts +106 -0
  418. package/src/parser/rules/types.ts +9 -0
  419. package/src/parser/toc.ts +130 -0
@@ -0,0 +1,150 @@
1
+ /**
2
+ *
3
+ * Central registry and priority-ordered list of all inline parsing rules.
4
+ *
5
+ * This module imports every inline rule, re-exports them for individual use,
6
+ * and assembles them into the {@link inlineRules} array, which defines the
7
+ * order in which rules are attempted during inline parsing.
8
+ *
9
+ * Rule ordering matters: earlier rules take priority when multiple rules
10
+ * could match the same token. For example, formatting rules (bold, italic,
11
+ * etc.) are tried before link rules, and the text/fallback rules are
12
+ * placed last as catch-alls.
13
+ *
14
+ * The `fallbackRule` is exported separately as `inlineFallbackRule` because
15
+ * it matches any token type and is used as a last resort when no other rule
16
+ * succeeds. It is NOT included in the `inlineRules` array to prevent it
17
+ * from short-circuiting more specific rules.
18
+ *
19
+ * @module
20
+ */
21
+ import type { InlineRule } from "../types";
22
+ import { boldRule } from "./bold";
23
+ import { italicRule } from "./italic";
24
+ import { underlineRule } from "./underline";
25
+ import { strikethroughRule } from "./strikethrough";
26
+ import { superscriptRule } from "./superscript";
27
+ import { subscriptRule } from "./subscript";
28
+ import { monospaceRule } from "./monospace";
29
+ import { linkTripleRule } from "./link-triple";
30
+ import { linkSingleRule } from "./link-single";
31
+ import { linkAnchorRule } from "./link-anchor";
32
+ import { linkStarRule } from "./link-star";
33
+ import { colorRule } from "./color";
34
+ import {
35
+ backslashLineBreakRule,
36
+ newlineLineBreakRule,
37
+ underscoreLineBreakRule,
38
+ } from "./line-break";
39
+ import { commentRule } from "./comment";
40
+ import { htmlInlineRule } from "./html";
41
+ import { rawRule } from "./raw";
42
+ import { spanRule, closeSpanRule } from "./span";
43
+ import { sizeRule } from "./size";
44
+ import { footnoteRule } from "./footnote";
45
+ import { imageRule } from "./image";
46
+ import { guillemetRule } from "./guillemet";
47
+ import { userRule } from "./user";
48
+ import { anchorNameRule } from "./anchor-name";
49
+ import { anchorRule } from "./anchor";
50
+ import { mathInlineRule } from "./math-inline";
51
+ import { equationRefRule } from "./equation-ref";
52
+ import { exprRule, ifRule, ifExprRule } from "./expr";
53
+ import { bibciteRule } from "./bibcite";
54
+ import { textRule, fallbackRule } from "./text";
55
+
56
+ export { boldRule } from "./bold";
57
+ export { italicRule } from "./italic";
58
+ export { underlineRule } from "./underline";
59
+ export { strikethroughRule } from "./strikethrough";
60
+ export { superscriptRule } from "./superscript";
61
+ export { subscriptRule } from "./subscript";
62
+ export { monospaceRule } from "./monospace";
63
+ export { linkTripleRule } from "./link-triple";
64
+ export { linkSingleRule } from "./link-single";
65
+ export { linkAnchorRule } from "./link-anchor";
66
+ export { linkStarRule } from "./link-star";
67
+ export { colorRule } from "./color";
68
+ export {
69
+ backslashLineBreakRule,
70
+ newlineLineBreakRule,
71
+ underscoreLineBreakRule,
72
+ } from "./line-break";
73
+ export { commentRule } from "./comment";
74
+ export { htmlInlineRule } from "./html";
75
+ export { rawRule } from "./raw";
76
+ export { spanRule, closeSpanRule } from "./span";
77
+ export { sizeRule } from "./size";
78
+ export { footnoteRule } from "./footnote";
79
+ export { imageRule } from "./image";
80
+ export { guillemetRule } from "./guillemet";
81
+ export { userRule } from "./user";
82
+ export { anchorNameRule } from "./anchor-name";
83
+ export { anchorRule } from "./anchor";
84
+ export { mathInlineRule } from "./math-inline";
85
+ export { equationRefRule } from "./equation-ref";
86
+ export { exprRule, ifRule, ifExprRule } from "./expr";
87
+ export { bibciteRule } from "./bibcite";
88
+ export { textRule, fallbackRule } from "./text";
89
+
90
+ /**
91
+ * All inline rules in priority order.
92
+ *
93
+ * Rules are tried top-to-bottom against the current token. The first
94
+ * rule whose `startTokens` match the token type and whose `parse()`
95
+ * returns `{ success: true }` wins.
96
+ *
97
+ * Ordering rationale:
98
+ * 1. Paired formatting markers (bold, italic, underline, strikethrough,
99
+ * superscript, subscript, monospace) -- most common inline syntax
100
+ * 2. Link rules (triple, single, anchor, star) -- order matters because
101
+ * `[[[` must be tried before `[`
102
+ * 3. Color, line-break, and comment rules
103
+ * 4. Raw (verbatim) text
104
+ * 5. Block-open-triggered rules (image, size, footnote, span, user,
105
+ * expr/if/ifexpr, anchor-name, anchor, math-inline, equation-ref)
106
+ * 6. Bibcite (double-parenthesis syntax)
107
+ * 7. Guillemet (typographic angle quotes)
108
+ * 8. Text rule (catch-all for TEXT and WHITESPACE tokens)
109
+ *
110
+ * The `fallbackRule` is intentionally excluded; it is used as a
111
+ * separate last-resort handler.
112
+ */
113
+ export const inlineRules: InlineRule[] = [
114
+ boldRule,
115
+ italicRule,
116
+ underlineRule,
117
+ strikethroughRule,
118
+ superscriptRule,
119
+ subscriptRule,
120
+ monospaceRule,
121
+ linkTripleRule,
122
+ linkSingleRule,
123
+ linkAnchorRule,
124
+ linkStarRule,
125
+ colorRule,
126
+ backslashLineBreakRule,
127
+ underscoreLineBreakRule,
128
+ newlineLineBreakRule,
129
+ commentRule,
130
+ htmlInlineRule,
131
+ rawRule,
132
+ imageRule,
133
+ sizeRule,
134
+ footnoteRule,
135
+ spanRule,
136
+ closeSpanRule,
137
+ userRule,
138
+ exprRule,
139
+ ifRule,
140
+ ifExprRule,
141
+ anchorNameRule,
142
+ anchorRule,
143
+ mathInlineRule,
144
+ equationRefRule,
145
+ bibciteRule,
146
+ guillemetRule,
147
+ textRule,
148
+ ];
149
+
150
+ export { fallbackRule as inlineFallbackRule };
@@ -0,0 +1,46 @@
1
+ /**
2
+ *
3
+ * Parses the Wikidot italic formatting syntax: `//text//`.
4
+ *
5
+ * Italic text is delimited by double forward slashes. The opening and
6
+ * closing markers must appear on the same line. If no closing `//` is
7
+ * found before a newline, the opening marker is emitted as literal text.
8
+ *
9
+ * Unlike bold (which discards empty markers), italic markers with empty
10
+ * content (`////`) still produce an italic container, matching Wikidot's
11
+ * behavior.
12
+ *
13
+ * Italic may nest other inline formatting within its body.
14
+ *
15
+ * Produces a `"container"` AST element with `type: "italics"`.
16
+ *
17
+ * @module
18
+ */
19
+ import type { Element } from "@wdprlib/ast";
20
+ import type { InlineRule, ParseContext, RuleResult } from "../types";
21
+ import { parseSameLineDelimitedContainer } from "./formatting/container";
22
+
23
+ /**
24
+ * Inline rule for parsing `//italic//` formatting.
25
+ *
26
+ * Triggered by an `ITALIC_MARKER` token (`//`). Checks for a matching
27
+ * closing marker on the same line, then recursively parses inline content.
28
+ *
29
+ * When no closing marker is found, the opening `//` is treated as
30
+ * literal text.
31
+ */
32
+ export const italicRule: InlineRule = {
33
+ name: "italic",
34
+ startTokens: ["ITALIC_MARKER"],
35
+
36
+ /**
37
+ * Attempts to parse italic formatting at the current position.
38
+ *
39
+ * @param ctx - Parse context with token stream and current position
40
+ * @returns A successful result containing either a `"container"` element
41
+ * with `type: "italics"`, or a text fallback for unmatched markers
42
+ */
43
+ parse(ctx: ParseContext): RuleResult<Element> {
44
+ return parseSameLineDelimitedContainer(ctx, "ITALIC_MARKER", "italics");
45
+ },
46
+ };
@@ -0,0 +1,58 @@
1
+ import type { Element } from "@wdprlib/ast";
2
+ import type { InlineRule, ParseContext, RuleResult } from "../../types";
3
+ import { createPreservedLineBreak } from "./elements";
4
+
5
+ export const backslashLineBreakRule: InlineRule = {
6
+ name: "backslashLineBreak",
7
+ startTokens: ["WHITESPACE", "BACKSLASH_BREAK"],
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
+ if (nextTok?.type !== "BACKSLASH_BREAK") {
18
+ return { success: false };
19
+ }
20
+
21
+ if (isFollowedByUnderscoreBreak(ctx, ctx.pos + 2)) {
22
+ return {
23
+ success: true,
24
+ elements: [createPreservedLineBreak()],
25
+ consumed: 2,
26
+ };
27
+ }
28
+
29
+ return {
30
+ success: true,
31
+ elements: [createPreservedLineBreak(), { element: "text", data: " " }],
32
+ consumed: 2,
33
+ };
34
+ }
35
+
36
+ if (currentTok.type === "BACKSLASH_BREAK") {
37
+ return {
38
+ success: true,
39
+ elements: [createPreservedLineBreak()],
40
+ consumed: 1,
41
+ };
42
+ }
43
+
44
+ return { success: false };
45
+ },
46
+ };
47
+
48
+ function isFollowedByUnderscoreBreak(ctx: ParseContext, startPos: number): boolean {
49
+ const afterBreak = ctx.tokens[startPos];
50
+ const afterAfter = ctx.tokens[startPos + 1];
51
+ const afterAfterAfter = ctx.tokens[startPos + 2];
52
+
53
+ return (
54
+ afterBreak?.type === "WHITESPACE" &&
55
+ afterAfter?.type === "UNDERSCORE" &&
56
+ (afterAfterAfter?.type === "NEWLINE" || afterAfterAfter?.type === "EOF")
57
+ );
58
+ }
@@ -0,0 +1,9 @@
1
+ import type { Element } from "@wdprlib/ast";
2
+
3
+ export type PreservedLineBreak = Extract<Element, { element: "line-break" }> & {
4
+ _preservedTrailingBreak?: boolean;
5
+ };
6
+
7
+ export function createPreservedLineBreak(): PreservedLineBreak {
8
+ return { element: "line-break", _preservedTrailingBreak: true };
9
+ }
@@ -0,0 +1,3 @@
1
+ export { newlineLineBreakRule } from "./newline";
2
+ export { backslashLineBreakRule } from "./backslash";
3
+ export { underscoreLineBreakRule } from "./underscore";
@@ -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
+ };
@@ -0,0 +1,72 @@
1
+ /**
2
+ *
3
+ * Parses the Wikidot anchor link syntax: `[#anchor-name Label text]`
4
+ * and the "fake link" variant `[# Label text]`.
5
+ *
6
+ * An anchor link creates a hyperlink that targets a named anchor on
7
+ * the same page. The link's `href` is set to `#normalized-anchor-name`.
8
+ *
9
+ * The "fake link" variant (`[# Label]`) has no anchor name and generates
10
+ * a link with `href="javascript:;"`. This is used in Wikidot for
11
+ * interactive elements like collapsible blocks where the link serves
12
+ * as a click target rather than navigation.
13
+ *
14
+ * Anchor names are normalized to lowercase with spaces replaced by hyphens.
15
+ *
16
+ * The opening delimiter is tokenized as `BRACKET_ANCHOR` (`[#`) by the
17
+ * lexer, distinguishing it from regular bracket links.
18
+ *
19
+ * Produces a `"link"` AST element with `type: "anchor"`.
20
+ *
21
+ * @module
22
+ */
23
+ import type { Element, LinkLabel } from "@wdprlib/ast";
24
+ import type { InlineRule, ParseContext, RuleResult } from "../types";
25
+ import { parseAnchorBracketLink } from "./link-bracket/parsed";
26
+
27
+ /**
28
+ * Inline rule for parsing `[#anchor Label]` anchor links.
29
+ *
30
+ * Triggered by a `BRACKET_ANCHOR` (`[#`) token. Collects the optional
31
+ * anchor name, then the required label text, stopping at the closing
32
+ * `]` bracket.
33
+ *
34
+ * Fails if:
35
+ * - No closing `]` is found on the same line
36
+ * - The label text is empty
37
+ */
38
+ export const linkAnchorRule: InlineRule = {
39
+ name: "linkAnchor",
40
+ startTokens: ["BRACKET_ANCHOR"],
41
+
42
+ /**
43
+ * Attempts to parse an anchor link at the current position.
44
+ *
45
+ * @param ctx - Parse context with token stream and current position
46
+ * @returns A successful result with a `"link"` element of type `"anchor"`,
47
+ * or `{ success: false }`
48
+ */
49
+ parse(ctx: ParseContext): RuleResult<Element> {
50
+ const parsed = parseAnchorBracketLink(ctx);
51
+ if (!parsed) return { success: false };
52
+
53
+ const linkLabel: LinkLabel = { text: parsed.labelText };
54
+
55
+ return {
56
+ success: true,
57
+ elements: [
58
+ {
59
+ element: "link",
60
+ data: {
61
+ type: "anchor",
62
+ link: parsed.link,
63
+ extra: null,
64
+ label: linkLabel,
65
+ target: null,
66
+ },
67
+ },
68
+ ],
69
+ consumed: parsed.consumed,
70
+ };
71
+ },
72
+ };
@@ -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
+ }