@wdprlib/parser 3.2.0 → 4.1.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 +10471 -8406
  2. package/dist/index.d.cts +313 -337
  3. package/dist/index.d.ts +313 -337
  4. package/dist/index.js +10457 -8392
  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 +30 -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 +62 -0
  195. package/src/parser/rules/block/module/listpages/url-resolution/value.ts +34 -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
@@ -1,331 +0,0 @@
1
- /**
2
- *
3
- * Block rule for Wikidot tabbed content: `[[tabview]]` (or `[[tabs]]`).
4
- *
5
- * A tabview contains one or more `[[tab Label]]...[[/tab]]` blocks:
6
- *
7
- * ```
8
- * [[tabview]]
9
- * [[tab First Tab]]
10
- * Content of the first tab.
11
- * [[/tab]]
12
- * [[tab Second Tab]]
13
- * Content of the second tab.
14
- * [[/tab]]
15
- * [[/tabview]]
16
- * ```
17
- *
18
- * Key behaviours:
19
- * - Both `[[tabview]]` and `[[tabs]]` are accepted as the outer wrapper.
20
- * - Any attributes or text after the block name on the opening tag are
21
- * silently ignored (Wikidot behaviour: `[[tabview Foo]]` is valid).
22
- * - If a tab has no label, it defaults to `"untitled"`.
23
- * - Tab body content is parsed as block-level markup.
24
- * - An empty tabview (no tabs) fails the rule, falling back to text.
25
- * - Non-tab content between tabs (other than whitespace/newlines) causes
26
- * the rule to fail.
27
- *
28
- * @module
29
- */
30
- import type { Element, TabData } from "@wdprlib/ast";
31
- import type { BlockRule, ParseContext, RuleResult } from "../types";
32
- import { currentToken } from "../types";
33
- import { parseBlockName, parseBlocksUntil } from "./utils";
34
-
35
- /**
36
- * Parses a single `[[tab Label]]...[[/tab]]` block within a tabview.
37
- *
38
- * The label is everything between the block name and `]]` (leading
39
- * whitespace is trimmed). An empty label defaults to `"untitled"`.
40
- * Newlines are not allowed in the label -- if one is encountered, the
41
- * parse fails.
42
- *
43
- * Body content is parsed as block-level markup via {@link parseBlocksUntil}.
44
- *
45
- * @param ctx - Parse context, positioned before the expected `[[tab ...]]`.
46
- * @returns The tab data and consumed count, or `null` on failure.
47
- */
48
- function parseTab(ctx: ParseContext): { tab: TabData; consumed: number } | null {
49
- let pos = ctx.pos;
50
- let consumed = 0;
51
-
52
- // Skip whitespace/newlines before tab
53
- while (ctx.tokens[pos]?.type === "WHITESPACE" || ctx.tokens[pos]?.type === "NEWLINE") {
54
- pos++;
55
- consumed++;
56
- }
57
-
58
- // Expect [[
59
- if (ctx.tokens[pos]?.type !== "BLOCK_OPEN") {
60
- return null;
61
- }
62
- pos++;
63
- consumed++;
64
-
65
- // Parse block name
66
- const nameResult = parseBlockName(ctx, pos);
67
- if (!nameResult || nameResult.name.toLowerCase() !== "tab") {
68
- return null;
69
- }
70
- pos += nameResult.consumed;
71
- consumed += nameResult.consumed;
72
-
73
- // Parse label (everything until ]])
74
- let label = "";
75
- while (pos < ctx.tokens.length) {
76
- const token = ctx.tokens[pos];
77
- if (!token) break;
78
- if (token.type === "BLOCK_CLOSE") {
79
- break;
80
- }
81
- if (token.type === "NEWLINE") {
82
- // No newline allowed in label
83
- return null;
84
- }
85
- // Skip leading whitespace in label
86
- if (label === "" && token.type === "WHITESPACE") {
87
- pos++;
88
- consumed++;
89
- continue;
90
- }
91
- label += token.value;
92
- pos++;
93
- consumed++;
94
- }
95
-
96
- // Expect ]]
97
- if (ctx.tokens[pos]?.type !== "BLOCK_CLOSE") {
98
- return null;
99
- }
100
- pos++;
101
- consumed++;
102
-
103
- // Skip newline after opening tag
104
- if (ctx.tokens[pos]?.type === "NEWLINE") {
105
- pos++;
106
- consumed++;
107
- }
108
-
109
- // Close condition for [[/tab]]
110
- const closeCondition = (checkCtx: ParseContext): boolean => {
111
- const token = checkCtx.tokens[checkCtx.pos];
112
- if (token?.type === "BLOCK_END_OPEN") {
113
- const closeNameResult = parseBlockName(checkCtx, checkCtx.pos + 1);
114
- if (closeNameResult?.name.toLowerCase() === "tab") {
115
- return true;
116
- }
117
- }
118
- return false;
119
- };
120
-
121
- // Parse body
122
- const bodyCtx: ParseContext = { ...ctx, pos };
123
- const bodyResult = parseBlocksUntil(bodyCtx, closeCondition);
124
- consumed += bodyResult.consumed;
125
- pos += bodyResult.consumed;
126
-
127
- // Check for missing close tag
128
- if (ctx.tokens[pos]?.type !== "BLOCK_END_OPEN") {
129
- ctx.diagnostics.push({
130
- severity: "warning",
131
- code: "unclosed-block",
132
- message: "Missing closing tag [[/tab]] for [[tab]]",
133
- position: ctx.tokens[ctx.pos]?.position ?? {
134
- start: { line: 0, column: 0, offset: 0 },
135
- end: { line: 0, column: 0, offset: 0 },
136
- },
137
- });
138
- }
139
-
140
- // Consume [[/tab]]
141
- if (ctx.tokens[pos]?.type === "BLOCK_END_OPEN") {
142
- pos++;
143
- consumed++;
144
- const closeNameResult = parseBlockName(ctx, pos);
145
- if (closeNameResult) {
146
- pos += closeNameResult.consumed;
147
- consumed += closeNameResult.consumed;
148
- }
149
- if (ctx.tokens[pos]?.type === "BLOCK_CLOSE") {
150
- pos++;
151
- consumed++;
152
- }
153
- // Skip trailing newline
154
- if (ctx.tokens[pos]?.type === "NEWLINE") {
155
- pos++;
156
- consumed++;
157
- }
158
- }
159
-
160
- // Default label if empty
161
- const finalLabel = label.trim() || "untitled";
162
-
163
- return {
164
- tab: {
165
- label: finalLabel,
166
- elements: bodyResult.elements,
167
- },
168
- consumed,
169
- };
170
- }
171
-
172
- /**
173
- * Block rule for `[[tabview]]`/`[[tabs]]` with `[[tab]]` children.
174
- *
175
- * Parsing strategy:
176
- * 1. Match BLOCK_OPEN + name "tabview" or "tabs" (case-insensitive).
177
- * 2. Skip any trailing text/attributes on the opening tag (ignored).
178
- * 3. Consume `]]` and optional newline.
179
- * 4. Repeatedly parse `[[tab Label]]...[[/tab]]` blocks via `parseTab()`.
180
- * 5. Whitespace and newlines between tabs are skipped; other content fails.
181
- * 6. Consume `[[/tabview]]` or `[[/tabs]]`.
182
- * 7. If no tabs were found, fail the rule.
183
- * 8. Emit a `tab-view` element containing the array of tab data.
184
- */
185
- export const tabviewRule: BlockRule = {
186
- name: "tabview",
187
- startTokens: ["BLOCK_OPEN"],
188
- requiresLineStart: false,
189
-
190
- parse(ctx: ParseContext): RuleResult<Element> {
191
- const openToken = currentToken(ctx);
192
- if (openToken.type !== "BLOCK_OPEN") {
193
- return { success: false };
194
- }
195
-
196
- let pos = ctx.pos + 1;
197
- let consumed = 1;
198
-
199
- // Parse block name
200
- const nameResult = parseBlockName(ctx, pos);
201
- if (!nameResult) {
202
- return { success: false };
203
- }
204
-
205
- const blockName = nameResult.name.toLowerCase();
206
- // Accept tabview or tabs
207
- if (blockName !== "tabview" && blockName !== "tabs") {
208
- return { success: false };
209
- }
210
-
211
- pos += nameResult.consumed;
212
- consumed += nameResult.consumed;
213
-
214
- // Skip any attributes/name (Wikidot ignores [[tabview Foo]])
215
- while (
216
- pos < ctx.tokens.length &&
217
- ctx.tokens[pos]?.type !== "BLOCK_CLOSE" &&
218
- ctx.tokens[pos]?.type !== "NEWLINE"
219
- ) {
220
- pos++;
221
- consumed++;
222
- }
223
-
224
- // Expect ]]
225
- if (ctx.tokens[pos]?.type !== "BLOCK_CLOSE") {
226
- return { success: false };
227
- }
228
- pos++;
229
- consumed++;
230
-
231
- // Skip newline after opening tag
232
- if (ctx.tokens[pos]?.type === "NEWLINE") {
233
- pos++;
234
- consumed++;
235
- }
236
-
237
- // Parse tabs
238
- const tabs: TabData[] = [];
239
- const tabCtx: ParseContext = { ...ctx, pos };
240
-
241
- while (pos < ctx.tokens.length) {
242
- // Check for EOF
243
- if (ctx.tokens[pos]?.type === "EOF") {
244
- break;
245
- }
246
-
247
- // Check for closing [[/tabview]] or [[/tabs]]
248
- if (ctx.tokens[pos]?.type === "BLOCK_END_OPEN") {
249
- const closeNameResult = parseBlockName(ctx, pos + 1);
250
- const closeName = closeNameResult?.name.toLowerCase();
251
- if (closeName === "tabview" || closeName === "tabs") {
252
- break;
253
- }
254
- }
255
-
256
- // Try to parse a tab
257
- const tabResult = parseTab({ ...tabCtx, pos });
258
- if (tabResult) {
259
- tabs.push(tabResult.tab);
260
- pos += tabResult.consumed;
261
- consumed += tabResult.consumed;
262
- } else {
263
- // Skip whitespace/newlines between tabs
264
- if (ctx.tokens[pos]?.type === "WHITESPACE" || ctx.tokens[pos]?.type === "NEWLINE") {
265
- pos++;
266
- consumed++;
267
- } else {
268
- // Non-tab content in tabview - fail
269
- return { success: false };
270
- }
271
- }
272
- }
273
-
274
- // Check for missing close tag
275
- const hasTabviewClose =
276
- ctx.tokens[pos]?.type === "BLOCK_END_OPEN" &&
277
- (() => {
278
- const n = parseBlockName(ctx, pos + 1);
279
- const name = n?.name.toLowerCase();
280
- return name === "tabview" || name === "tabs";
281
- })();
282
- if (!hasTabviewClose) {
283
- ctx.diagnostics.push({
284
- severity: "warning",
285
- code: "unclosed-block",
286
- message: `Missing closing tag [[/${blockName}]] for [[${blockName}]]`,
287
- position: openToken.position,
288
- });
289
- }
290
-
291
- // Consume [[/tabview]] or [[/tabs]]
292
- if (ctx.tokens[pos]?.type === "BLOCK_END_OPEN") {
293
- pos++;
294
- consumed++;
295
- const closeNameResult = parseBlockName(ctx, pos);
296
- if (closeNameResult) {
297
- pos += closeNameResult.consumed;
298
- consumed += closeNameResult.consumed;
299
- }
300
- if (ctx.tokens[pos]?.type === "BLOCK_CLOSE") {
301
- pos++;
302
- consumed++;
303
- }
304
- if (ctx.tokens[pos]?.type === "NEWLINE") {
305
- pos++;
306
- consumed++;
307
- }
308
- }
309
-
310
- // Empty tabview is invalid - return failure so it falls back to plain text.
311
- // Note: Ideally, a failed tabview like "EMPTY:\n[[tabview]]\n[[/tabview]]" should
312
- // render as a single paragraph with <br /> separators (matching original Wikidot).
313
- // Currently, the paragraph parser treats [[tabview]] as a block-start token and
314
- // splits it into separate paragraphs. We chose to wrap each in <p> tags instead
315
- // of implementing complex lookahead to detect invalid tabviews.
316
- if (tabs.length === 0) {
317
- return { success: false };
318
- }
319
-
320
- return {
321
- success: true,
322
- elements: [
323
- {
324
- element: "tab-view",
325
- data: tabs,
326
- },
327
- ],
328
- consumed,
329
- };
330
- },
331
- };
@@ -1,129 +0,0 @@
1
- /**
2
- * Table of contents rule: [[toc]], [[f<toc ...]], [[f>toc ...]]
3
- *
4
- * Variants:
5
- * - [[toc]] - basic TOC
6
- * - [[f<toc ...]] - float left
7
- * - [[f>toc ...]] - float right
8
- *
9
- * Note: Wikidot ignores attributes on [[toc]] (class, style, id are not applied)
10
- * [[>toc]] and [[<toc]] are invalid in Wikidot and not supported.
11
- */
12
- import type { Alignment, Element } from "@wdprlib/ast";
13
- import type { BlockRule, ParseContext, RuleResult } from "../types";
14
- import { currentToken } from "../types";
15
-
16
- /**
17
- * Skip tokens until BLOCK_CLOSE (Wikidot ignores toc attributes)
18
- */
19
- function skipUntilClose(ctx: ParseContext, startPos: number): number {
20
- let pos = startPos;
21
- while (pos < ctx.tokens.length) {
22
- const token = ctx.tokens[pos];
23
- if (
24
- !token ||
25
- token.type === "BLOCK_CLOSE" ||
26
- token.type === "NEWLINE" ||
27
- token.type === "EOF"
28
- ) {
29
- break;
30
- }
31
- pos++;
32
- }
33
- return pos;
34
- }
35
-
36
- export const tocRule: BlockRule = {
37
- name: "toc",
38
- startTokens: ["BLOCK_OPEN"],
39
- requiresLineStart: true,
40
-
41
- parse(ctx: ParseContext): RuleResult<Element> {
42
- const openToken = currentToken(ctx);
43
- if (openToken.type !== "BLOCK_OPEN") {
44
- return { success: false };
45
- }
46
-
47
- let pos = ctx.pos + 1;
48
- let align: Alignment | null = null;
49
-
50
- // Skip whitespace after [[
51
- while (ctx.tokens[pos]?.type === "WHITESPACE") {
52
- pos++;
53
- }
54
-
55
- const firstToken = ctx.tokens[pos];
56
- if (!firstToken || (firstToken.type !== "TEXT" && firstToken.type !== "IDENTIFIER")) {
57
- return { success: false };
58
- }
59
-
60
- const firstValue = firstToken.value.toLowerCase();
61
-
62
- if (firstValue === "toc") {
63
- // [[toc ...]]
64
- // Page syntax disabled (e.g., forum-post mode)
65
- if (!ctx.settings.enablePageSyntax) {
66
- return { success: false };
67
- }
68
- pos++;
69
- } else if (firstValue === "f") {
70
- // Possibly [[f<toc ...]] or [[f>toc ...]]
71
- pos++;
72
- const dirToken = ctx.tokens[pos];
73
- if (!dirToken) {
74
- return { success: false };
75
- }
76
-
77
- if (dirToken.type === "TEXT" && dirToken.value === "<") {
78
- align = "left";
79
- pos++;
80
- } else if (dirToken.type === "TEXT" && dirToken.value === ">") {
81
- align = "right";
82
- pos++;
83
- } else {
84
- return { success: false };
85
- }
86
-
87
- // Now expect "toc"
88
- const tocToken = ctx.tokens[pos];
89
- if (!tocToken || (tocToken.type !== "TEXT" && tocToken.type !== "IDENTIFIER")) {
90
- return { success: false };
91
- }
92
- if (tocToken.value.toLowerCase() !== "toc") {
93
- return { success: false };
94
- }
95
- // Page syntax disabled (e.g., forum-post mode)
96
- if (!ctx.settings.enablePageSyntax) {
97
- return { success: false };
98
- }
99
- pos++;
100
- } else {
101
- return { success: false };
102
- }
103
-
104
- // Skip any tokens until ]] (Wikidot ignores toc attributes)
105
- pos = skipUntilClose(ctx, pos);
106
-
107
- // Expect ]]
108
- if (ctx.tokens[pos]?.type !== "BLOCK_CLOSE") {
109
- return { success: false };
110
- }
111
- pos++;
112
-
113
- const consumed = pos - ctx.pos;
114
-
115
- return {
116
- success: true,
117
- elements: [
118
- {
119
- element: "table-of-contents",
120
- data: {
121
- attributes: {},
122
- align,
123
- },
124
- },
125
- ],
126
- consumed,
127
- };
128
- },
129
- };
@@ -1,154 +0,0 @@
1
- /**
2
- *
3
- * Parses the Wikidot named anchor syntax: `[[# name]]`.
4
- *
5
- * A named anchor creates an invisible anchor target (`<a id="name">`)
6
- * that can be referenced by page-internal links such as `[#name Label]`
7
- * or triple-bracket anchor links like `[[[#name]]]`.
8
- *
9
- * The anchor name must consist exclusively of the characters
10
- * `[-_A-Za-z0-9.%]` (matching the original Wikidot regex
11
- * `/(\[\[# )([-_A-Za-z0-9.%]+?)(\]\])/i`).
12
- *
13
- * A whitespace gap is required between the `#` and the name
14
- * (`[[# myAnchor]]` is valid; `[[#myAnchor]]` is not).
15
- *
16
- * Produces an `"anchor-name"` AST element whose `data` field contains
17
- * the raw anchor name string.
18
- *
19
- * @module
20
- */
21
- import type { Element } from "@wdprlib/ast";
22
- import type { InlineRule, ParseContext, RuleResult } from "../types";
23
- import { currentToken } from "../types";
24
-
25
- /**
26
- * Tests whether a single character is a valid anchor name character.
27
- *
28
- * Wikidot restricts anchor names to ASCII alphanumerics, hyphens,
29
- * underscores, dots, and percent signs.
30
- *
31
- * @param char - A single character to validate
32
- * @returns `true` if the character is allowed in an anchor name
33
- */
34
- function isValidAnchorChar(char: string): boolean {
35
- return /^[-_A-Za-z0-9.%]$/.test(char);
36
- }
37
-
38
- /**
39
- * Inline rule for parsing `[[# name]]` named anchor targets.
40
- *
41
- * Triggered by a `BLOCK_OPEN` (`[[`) token. The rule looks for the `#`
42
- * character followed by mandatory whitespace and then the anchor name.
43
- *
44
- * Parsing steps:
45
- * 1. Consume `[[` and optional leading whitespace
46
- * 2. Require a `#` token (HASH or TEXT `"#"`)
47
- * 3. Require at least one whitespace token after `#`
48
- * 4. Collect consecutive valid anchor-name characters as the name
49
- * 5. Require closing `]]`
50
- *
51
- * Fails if the anchor name is empty or if `]]` is not found.
52
- */
53
- export const anchorNameRule: InlineRule = {
54
- name: "anchorName",
55
- startTokens: ["BLOCK_OPEN"],
56
-
57
- /**
58
- * Attempts to parse a `[[# name]]` named anchor at the current position.
59
- *
60
- * @param ctx - Parse context with token stream and current position
61
- * @returns A successful result with an `"anchor-name"` element, or `{ success: false }`
62
- */
63
- parse(ctx: ParseContext): RuleResult<Element> {
64
- const openToken = currentToken(ctx);
65
- if (openToken.type !== "BLOCK_OPEN") {
66
- return { success: false };
67
- }
68
-
69
- let pos = ctx.pos + 1;
70
- let consumed = 1;
71
-
72
- // Skip whitespace
73
- while (ctx.tokens[pos]?.type === "WHITESPACE") {
74
- pos++;
75
- consumed++;
76
- }
77
-
78
- // Check for # (hash) - can be TEXT or HASH token
79
- const hashToken = ctx.tokens[pos];
80
- if (
81
- !hashToken ||
82
- (hashToken.type !== "HASH" && !(hashToken.type === "TEXT" && hashToken.value === "#"))
83
- ) {
84
- return { success: false };
85
- }
86
- pos++;
87
- consumed++;
88
-
89
- // Require whitespace after #
90
- if (ctx.tokens[pos]?.type !== "WHITESPACE") {
91
- return { success: false };
92
- }
93
- pos++;
94
- consumed++;
95
-
96
- // Skip additional whitespace
97
- while (ctx.tokens[pos]?.type === "WHITESPACE") {
98
- pos++;
99
- consumed++;
100
- }
101
-
102
- // Parse anchor name - collect valid characters until ]]
103
- let name = "";
104
- while (pos < ctx.tokens.length) {
105
- const token = ctx.tokens[pos];
106
- if (
107
- !token ||
108
- token.type === "BLOCK_CLOSE" ||
109
- token.type === "NEWLINE" ||
110
- token.type === "EOF"
111
- ) {
112
- break;
113
- }
114
- // Check if all characters in token are valid anchor chars
115
- const value = token.value;
116
- let allValid = true;
117
- for (const char of value) {
118
- if (!isValidAnchorChar(char)) {
119
- allValid = false;
120
- break;
121
- }
122
- }
123
- if (!allValid) {
124
- break;
125
- }
126
- name += value;
127
- pos++;
128
- consumed++;
129
- }
130
-
131
- // Anchor name is required
132
- if (!name) {
133
- return { success: false };
134
- }
135
-
136
- // Expect ]]
137
- if (ctx.tokens[pos]?.type !== "BLOCK_CLOSE") {
138
- return { success: false };
139
- }
140
- pos++;
141
- consumed++;
142
-
143
- return {
144
- success: true,
145
- elements: [
146
- {
147
- element: "anchor-name",
148
- data: name,
149
- },
150
- ],
151
- consumed,
152
- };
153
- },
154
- };