@wdprlib/parser 3.2.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (433) hide show
  1. package/dist/index.cjs +10451 -8402
  2. package/dist/index.d.cts +313 -337
  3. package/dist/index.d.ts +313 -337
  4. package/dist/index.js +10438 -8389
  5. package/package.json +1 -1
  6. package/src/index.ts +7 -0
  7. package/src/lexer/anchor.ts +48 -0
  8. package/src/lexer/index.ts +3 -2
  9. package/src/lexer/lexer.ts +73 -559
  10. package/src/lexer/options.ts +19 -0
  11. package/src/lexer/punctuation.ts +70 -0
  12. package/src/lexer/quoted-string.ts +16 -0
  13. package/src/lexer/runs.ts +85 -0
  14. package/src/lexer/spacing-actions.ts +24 -0
  15. package/src/lexer/state.ts +103 -0
  16. package/src/lexer/syntax-actions.ts +80 -0
  17. package/src/lexer/text-actions.ts +41 -0
  18. package/src/lexer/token-actions.ts +136 -0
  19. package/src/lexer/token-factory.ts +62 -0
  20. package/src/lexer/tokenize.ts +18 -0
  21. package/src/parser/constants.ts +2 -0
  22. package/src/parser/depth/index.ts +111 -0
  23. package/src/parser/depth/stack.ts +82 -0
  24. package/src/parser/parse/block.ts +42 -0
  25. package/src/parser/parse/context.ts +26 -0
  26. package/src/parser/parse/footnotes.ts +25 -0
  27. package/src/parser/parse/index.ts +42 -0
  28. package/src/parser/parse/options.ts +34 -0
  29. package/src/parser/parse/parser.ts +79 -0
  30. package/src/parser/parse/plain-non-ascii.ts +129 -0
  31. package/src/parser/parse/result.ts +57 -0
  32. package/src/parser/parse/source.ts +11 -0
  33. package/src/parser/postprocess/divAdjacentParagraph.ts +1 -1
  34. package/src/parser/postprocess/spanStrip/clean-element.ts +168 -0
  35. package/src/parser/postprocess/spanStrip/cleanup.ts +25 -0
  36. package/src/parser/postprocess/spanStrip/empty-spans.ts +36 -0
  37. package/src/parser/postprocess/spanStrip/escaped.ts +78 -0
  38. package/src/parser/postprocess/spanStrip/factory.ts +23 -0
  39. package/src/parser/postprocess/spanStrip/index.ts +8 -0
  40. package/src/parser/postprocess/spanStrip/merge.ts +117 -0
  41. package/src/parser/postprocess/spanStrip/predicates.ts +59 -0
  42. package/src/parser/postprocess/spanStrip/split.ts +67 -0
  43. package/src/parser/preprocess/expr/chars.ts +15 -0
  44. package/src/parser/preprocess/expr/evaluate.ts +22 -0
  45. package/src/parser/preprocess/expr/index.ts +45 -0
  46. package/src/parser/preprocess/expr/kind.ts +19 -0
  47. package/src/parser/preprocess/expr/parse.ts +103 -0
  48. package/src/parser/preprocess/expr/scan.ts +34 -0
  49. package/src/parser/preprocess/expr/types.ts +14 -0
  50. package/src/parser/preprocess/typography.ts +70 -5
  51. package/src/parser/preprocess/utils/bracket-depths.ts +98 -0
  52. package/src/parser/preprocess/utils/index.ts +13 -0
  53. package/src/parser/preprocess/utils/raw-regions.ts +153 -0
  54. package/src/parser/preprocess/whitespace/detection.ts +39 -0
  55. package/src/parser/preprocess/whitespace/index.ts +79 -0
  56. package/src/parser/preprocess/whitespace/leading-spaces.ts +11 -0
  57. package/src/parser/preprocess/whitespace/patterns.ts +23 -0
  58. package/src/parser/rules/block/align/body.ts +46 -0
  59. package/src/parser/rules/block/align/element.ts +13 -0
  60. package/src/parser/rules/block/align/index.ts +90 -0
  61. package/src/parser/rules/block/align/syntax.ts +113 -0
  62. package/src/parser/rules/block/bibliography/body.ts +81 -0
  63. package/src/parser/rules/block/bibliography/entries.ts +49 -0
  64. package/src/parser/rules/block/bibliography/entry-content.ts +73 -0
  65. package/src/parser/rules/block/bibliography/entry-key.ts +83 -0
  66. package/src/parser/rules/block/bibliography/index.ts +90 -0
  67. package/src/parser/rules/block/bibliography/open.ts +53 -0
  68. package/src/parser/rules/block/block-list/bare-content.ts +105 -0
  69. package/src/parser/rules/block/block-list/bare-paragraph.ts +60 -0
  70. package/src/parser/rules/block/block-list/index.ts +51 -0
  71. package/src/parser/rules/block/block-list/item-content.ts +132 -0
  72. package/src/parser/rules/block/block-list/li-content.ts +107 -0
  73. package/src/parser/rules/block/block-list/li-item.ts +77 -0
  74. package/src/parser/rules/block/block-list/list-block.ts +100 -0
  75. package/src/parser/rules/block/block-list/open.ts +51 -0
  76. package/src/parser/rules/block/block-list/tags.ts +50 -0
  77. package/src/parser/rules/block/blockquote/build.ts +62 -0
  78. package/src/parser/rules/block/blockquote/index.ts +80 -0
  79. package/src/parser/rules/block/blockquote/line.ts +79 -0
  80. package/src/parser/rules/block/blockquote/lines.ts +39 -0
  81. package/src/parser/rules/block/{center.ts → center/index.ts} +7 -22
  82. package/src/parser/rules/block/center/open.ts +27 -0
  83. package/src/parser/rules/block/{clear-float.ts → clear-float/index.ts} +6 -30
  84. package/src/parser/rules/block/clear-float/syntax.ts +43 -0
  85. package/src/parser/rules/block/code/attributes.ts +30 -0
  86. package/src/parser/rules/block/code/content.ts +57 -0
  87. package/src/parser/rules/block/code/index.ts +100 -0
  88. package/src/parser/rules/block/collapsible/attributes.ts +95 -0
  89. package/src/parser/rules/block/collapsible/body.ts +69 -0
  90. package/src/parser/rules/block/collapsible/index.ts +117 -0
  91. package/src/parser/rules/block/collapsible/open.ts +51 -0
  92. package/src/parser/rules/block/collapsible/orphans.ts +31 -0
  93. package/src/parser/rules/block/collapsible/tags.ts +17 -0
  94. package/src/parser/rules/block/comment/consume.ts +37 -0
  95. package/src/parser/rules/block/{comment.ts → comment/index.ts} +12 -38
  96. package/src/parser/rules/block/{content-separator.ts → content-separator/index.ts} +5 -35
  97. package/src/parser/rules/block/content-separator/syntax.ts +33 -0
  98. package/src/parser/rules/block/definition-list/collect.ts +40 -0
  99. package/src/parser/rules/block/definition-list/index.ts +63 -0
  100. package/src/parser/rules/block/definition-list/item-key.ts +95 -0
  101. package/src/parser/rules/block/definition-list/item-value.ts +56 -0
  102. package/src/parser/rules/block/definition-list/items.ts +54 -0
  103. package/src/parser/rules/block/div/body.ts +41 -0
  104. package/src/parser/rules/block/div/close.ts +41 -0
  105. package/src/parser/rules/block/div/failed.ts +117 -0
  106. package/src/parser/rules/block/div/index.ts +112 -0
  107. package/src/parser/rules/block/div/nesting.ts +37 -0
  108. package/src/parser/rules/block/div/open.ts +59 -0
  109. package/src/parser/rules/block/div/paragraph-strip.ts +44 -0
  110. package/src/parser/rules/block/embed-block/content.ts +53 -0
  111. package/src/parser/rules/block/embed-block/index.ts +91 -0
  112. package/src/parser/rules/block/embed-block/open.ts +52 -0
  113. package/src/parser/rules/block/embed-block/tags.ts +5 -0
  114. package/src/parser/rules/block/footnoteblock/attributes.ts +73 -0
  115. package/src/parser/rules/block/footnoteblock/index.ts +82 -0
  116. package/src/parser/rules/block/footnoteblock/open.ts +53 -0
  117. package/src/parser/rules/block/heading/index.ts +87 -0
  118. package/src/parser/rules/block/heading/open.ts +50 -0
  119. package/src/parser/rules/block/heading/toc-text.ts +26 -0
  120. package/src/parser/rules/block/{horizontal-rule.ts → horizontal-rule/index.ts} +4 -21
  121. package/src/parser/rules/block/horizontal-rule/syntax.ts +21 -0
  122. package/src/parser/rules/block/html/body.ts +114 -0
  123. package/src/parser/rules/block/html/diagnostics.ts +11 -0
  124. package/src/parser/rules/block/html/index.ts +95 -0
  125. package/src/parser/rules/block/html/open.ts +36 -0
  126. package/src/parser/rules/block/iframe/attributes.ts +106 -0
  127. package/src/parser/rules/block/iframe/index.ts +73 -0
  128. package/src/parser/rules/block/iframe/open.ts +58 -0
  129. package/src/parser/rules/block/iframe/source.ts +24 -0
  130. package/src/parser/rules/block/iframe/url.ts +38 -0
  131. package/src/parser/rules/block/iftags/body.ts +48 -0
  132. package/src/parser/rules/block/iftags/condition.ts +24 -0
  133. package/src/parser/rules/block/{iftags.ts → iftags/index.ts} +16 -58
  134. package/src/parser/rules/block/include/arguments.ts +48 -0
  135. package/src/parser/rules/block/include/index.ts +75 -0
  136. package/src/parser/rules/block/include/location.ts +24 -0
  137. package/src/parser/rules/block/include/variables.ts +37 -0
  138. package/src/parser/rules/block/list/index.ts +73 -0
  139. package/src/parser/rules/block/list/line.ts +77 -0
  140. package/src/parser/rules/block/list/native.ts +89 -0
  141. package/src/parser/rules/block/math/content.ts +54 -0
  142. package/src/parser/rules/block/math/index.ts +106 -0
  143. package/src/parser/rules/block/math/name.ts +35 -0
  144. package/src/parser/rules/block/module/body.ts +92 -0
  145. package/src/parser/rules/block/module/element.ts +33 -0
  146. package/src/parser/rules/block/module/include/directive.ts +91 -0
  147. package/src/parser/rules/block/module/include/index.ts +11 -2
  148. package/src/parser/rules/block/module/include/references.ts +42 -0
  149. package/src/parser/rules/block/module/include/resolve/cache.ts +44 -0
  150. package/src/parser/rules/block/module/include/resolve/index.ts +106 -0
  151. package/src/parser/rules/block/module/include/resolve/iterate.ts +202 -0
  152. package/src/parser/rules/block/module/include/resolve/replace.ts +31 -0
  153. package/src/parser/rules/block/module/include/resolve/types.ts +105 -0
  154. package/src/parser/rules/block/module/include/scanner.ts +121 -0
  155. package/src/parser/rules/block/module/index.ts +14 -2
  156. package/src/parser/rules/block/module/listpages/compiler.ts +12 -392
  157. package/src/parser/rules/block/module/listpages/extract.ts +25 -359
  158. package/src/parser/rules/block/module/listpages/extraction/listpages.ts +42 -0
  159. package/src/parser/rules/block/module/listpages/extraction/listusers.ts +30 -0
  160. package/src/parser/rules/block/module/listpages/extraction/query.ts +51 -0
  161. package/src/parser/rules/block/module/listpages/extraction/result.ts +18 -0
  162. package/src/parser/rules/block/module/listpages/extraction/template.ts +96 -0
  163. package/src/parser/rules/block/module/listpages/extraction/variables.ts +58 -0
  164. package/src/parser/rules/block/module/listpages/normalization/date-selector.ts +53 -0
  165. package/src/parser/rules/block/module/listpages/normalization/numeric-selector.ts +32 -0
  166. package/src/parser/rules/block/module/listpages/normalization/order-parent.ts +82 -0
  167. package/src/parser/rules/block/module/listpages/normalization/selectors.ts +2 -0
  168. package/src/parser/rules/block/module/listpages/normalization/tags-category.ts +86 -0
  169. package/src/parser/rules/block/module/listpages/normalize.ts +8 -324
  170. package/src/parser/rules/block/module/listpages/resolution/items.ts +43 -0
  171. package/src/parser/rules/block/module/listpages/resolution/wrapper.ts +42 -0
  172. package/src/parser/rules/block/module/listpages/resolve.ts +5 -75
  173. package/src/parser/rules/block/module/listpages/template/format/content.ts +41 -0
  174. package/src/parser/rules/block/module/listpages/template/format/date.ts +116 -0
  175. package/src/parser/rules/block/module/listpages/template/format/index.ts +4 -0
  176. package/src/parser/rules/block/module/listpages/template/format/tags.ts +7 -0
  177. package/src/parser/rules/block/module/listpages/template/format/user.ts +9 -0
  178. package/src/parser/rules/block/module/listpages/template/getters/index.ts +36 -0
  179. package/src/parser/rules/block/module/listpages/template/getters/parameterized.ts +60 -0
  180. package/src/parser/rules/block/module/listpages/template/getters/simple.ts +65 -0
  181. package/src/parser/rules/block/module/listpages/template/getters/types.ts +3 -0
  182. package/src/parser/rules/block/module/listpages/template/syntax.ts +97 -0
  183. package/src/parser/rules/block/module/listpages/types/data-fetcher.ts +15 -0
  184. package/src/parser/rules/block/module/listpages/types/data-requirements.ts +52 -0
  185. package/src/parser/rules/block/module/listpages/types/external-data.ts +77 -0
  186. package/src/parser/rules/block/module/listpages/types/index.ts +17 -0
  187. package/src/parser/rules/block/module/listpages/types/normalized-query.ts +120 -0
  188. package/src/parser/rules/block/module/listpages/types/query.ts +67 -0
  189. package/src/parser/rules/block/module/listpages/types/template.ts +17 -0
  190. package/src/parser/rules/block/module/listpages/types/variables.ts +69 -0
  191. package/src/parser/rules/block/module/listpages/url-resolution/fields.ts +48 -0
  192. package/src/parser/rules/block/module/listpages/url-resolution/params.ts +19 -0
  193. package/src/parser/rules/block/module/listpages/url-resolution/query.ts +24 -0
  194. package/src/parser/rules/block/module/listpages/url-resolution/resolve.ts +53 -0
  195. package/src/parser/rules/block/module/listpages/url-resolution/value.ts +25 -0
  196. package/src/parser/rules/block/module/listpages/url-resolver.ts +3 -160
  197. package/src/parser/rules/block/module/listusers/compiler.ts +4 -25
  198. package/src/parser/rules/block/module/listusers/extract.ts +4 -9
  199. package/src/parser/rules/block/module/listusers/getters.ts +21 -0
  200. package/src/parser/rules/block/module/listusers/variables.ts +15 -0
  201. package/src/parser/rules/block/module/open.ts +57 -0
  202. package/src/parser/rules/block/module/resolution/contexts.ts +78 -0
  203. package/src/parser/rules/block/module/resolution/data-maps.ts +39 -0
  204. package/src/parser/rules/block/module/resolution/dynamic-modules.ts +93 -0
  205. package/src/parser/rules/block/module/resolution/styles.ts +53 -0
  206. package/src/parser/rules/block/module/resolution/walk-resolve.ts +107 -0
  207. package/src/parser/rules/block/module/resolve.ts +79 -292
  208. package/src/parser/rules/block/module/rule.ts +56 -0
  209. package/src/parser/rules/block/module/types-common.ts +11 -0
  210. package/src/parser/rules/block/module/walk/children.ts +35 -0
  211. package/src/parser/rules/block/module/walk/index.ts +9 -0
  212. package/src/parser/rules/block/module/walk/map/index.ts +2 -0
  213. package/src/parser/rules/block/module/walk/map/stateful-definition-list.ts +25 -0
  214. package/src/parser/rules/block/module/walk/map/stateful-list.ts +40 -0
  215. package/src/parser/rules/block/module/walk/map/stateful-table.ts +23 -0
  216. package/src/parser/rules/block/module/walk/map/stateful-tabs.ts +19 -0
  217. package/src/parser/rules/block/module/walk/map/stateful.ts +71 -0
  218. package/src/parser/rules/block/module/walk/map/stateless-definition-list.ts +12 -0
  219. package/src/parser/rules/block/module/walk/map/stateless-list.ts +29 -0
  220. package/src/parser/rules/block/module/walk/map/stateless-table.ts +11 -0
  221. package/src/parser/rules/block/module/walk/map/stateless-tabs.ts +5 -0
  222. package/src/parser/rules/block/module/walk/map/stateless.ts +51 -0
  223. package/src/parser/rules/block/module/walk/map/types.ts +6 -0
  224. package/src/parser/rules/block/module/walk/traverse.ts +65 -0
  225. package/src/parser/rules/block/orphan-li/content.ts +60 -0
  226. package/src/parser/rules/block/orphan-li/index.ts +75 -0
  227. package/src/parser/rules/block/orphan-li/open.ts +25 -0
  228. package/src/parser/rules/block/orphan-li/tags.ts +40 -0
  229. package/src/parser/rules/block/paragraph/content.ts +12 -0
  230. package/src/parser/rules/block/paragraph/index.ts +60 -0
  231. package/src/parser/rules/block/paragraph/normalize.ts +52 -0
  232. package/src/parser/rules/block/paragraph/span-markers.ts +52 -0
  233. package/src/parser/rules/block/parsing/attributes/index.ts +32 -0
  234. package/src/parser/rules/block/parsing/attributes/names.ts +93 -0
  235. package/src/parser/rules/block/parsing/attributes/scanner.ts +75 -0
  236. package/src/parser/rules/block/parsing/attributes/values.ts +26 -0
  237. package/src/parser/rules/block/parsing/block-item.ts +29 -0
  238. package/src/parser/rules/block/parsing/content.ts +127 -0
  239. package/src/parser/rules/block/parsing/end-condition.ts +51 -0
  240. package/src/parser/rules/block/parsing/inline-content.ts +105 -0
  241. package/src/parser/rules/block/parsing/inline-newline.ts +41 -0
  242. package/src/parser/rules/block/parsing/non-boundary.ts +24 -0
  243. package/src/parser/rules/block/parsing/rule-dispatch.ts +44 -0
  244. package/src/parser/rules/block/table/index.ts +80 -0
  245. package/src/parser/rules/block/table/pipe/cell-start.ts +69 -0
  246. package/src/parser/rules/block/table/pipe/cell.ts +106 -0
  247. package/src/parser/rules/block/table/pipe/index.ts +2 -0
  248. package/src/parser/rules/block/table/pipe/row.ts +88 -0
  249. package/src/parser/rules/block/table/pipe/tokens.ts +14 -0
  250. package/src/parser/rules/block/table/pipe/trim.ts +50 -0
  251. package/src/parser/rules/block/table-block/body.ts +79 -0
  252. package/src/parser/rules/block/table-block/cell-attributes.ts +33 -0
  253. package/src/parser/rules/block/table-block/cell-boundary.ts +99 -0
  254. package/src/parser/rules/block/table-block/cell-content/index.ts +88 -0
  255. package/src/parser/rules/block/table-block/cell-content/segments.ts +134 -0
  256. package/src/parser/rules/block/table-block/cell-newline.ts +47 -0
  257. package/src/parser/rules/block/table-block/cell.ts +64 -0
  258. package/src/parser/rules/block/table-block/index.ts +113 -0
  259. package/src/parser/rules/block/table-block/row-boundary.ts +75 -0
  260. package/src/parser/rules/block/table-block/structure.ts +80 -0
  261. package/src/parser/rules/block/tabview/body.ts +64 -0
  262. package/src/parser/rules/block/tabview/index.ts +90 -0
  263. package/src/parser/rules/block/tabview/open.ts +50 -0
  264. package/src/parser/rules/block/tabview/tab.ts +92 -0
  265. package/src/parser/rules/block/tabview/tags.ts +30 -0
  266. package/src/parser/rules/block/toc/element.ts +11 -0
  267. package/src/parser/rules/block/toc/index.ts +44 -0
  268. package/src/parser/rules/block/toc/open.ts +84 -0
  269. package/src/parser/rules/block/utils.ts +10 -610
  270. package/src/parser/rules/{utils.ts → common/attribute-safety.ts} +3 -49
  271. package/src/parser/rules/common/block-name.ts +33 -0
  272. package/src/parser/rules/common/index.ts +2 -0
  273. package/src/parser/rules/contracts/index.ts +3 -0
  274. package/src/parser/rules/contracts/parse-context.ts +38 -0
  275. package/src/parser/rules/contracts/rule.ts +43 -0
  276. package/src/parser/rules/contracts/scope.ts +31 -0
  277. package/src/parser/rules/inline/anchor/attributes.ts +54 -0
  278. package/src/parser/rules/inline/anchor/child.ts +26 -0
  279. package/src/parser/rules/inline/anchor/close.ts +34 -0
  280. package/src/parser/rules/inline/anchor/content.ts +59 -0
  281. package/src/parser/rules/inline/anchor/index.ts +103 -0
  282. package/src/parser/rules/inline/anchor/newline.ts +26 -0
  283. package/src/parser/rules/inline/anchor/open.ts +47 -0
  284. package/src/parser/rules/inline/anchor/paragraph-strip.ts +14 -0
  285. package/src/parser/rules/inline/anchor/syntax.ts +40 -0
  286. package/src/parser/rules/inline/anchor-name/index.ts +38 -0
  287. package/src/parser/rules/inline/anchor-name/name.ts +39 -0
  288. package/src/parser/rules/inline/anchor-name/syntax.ts +46 -0
  289. package/src/parser/rules/inline/bibcite/element.ts +14 -0
  290. package/src/parser/rules/inline/bibcite/index.ts +34 -0
  291. package/src/parser/rules/inline/bibcite/syntax.ts +64 -0
  292. package/src/parser/rules/inline/bold.ts +2 -39
  293. package/src/parser/rules/inline/color/index.ts +35 -0
  294. package/src/parser/rules/inline/color/syntax.ts +69 -0
  295. package/src/parser/rules/inline/comment/consume.ts +31 -0
  296. package/src/parser/rules/inline/{comment.ts → comment/index.ts} +10 -36
  297. package/src/parser/rules/inline/equation-ref/element.ts +8 -0
  298. package/src/parser/rules/inline/equation-ref/index.ts +34 -0
  299. package/src/parser/rules/inline/equation-ref/syntax.ts +45 -0
  300. package/src/parser/rules/inline/expr/branch.ts +104 -0
  301. package/src/parser/rules/inline/expr/conditional-branch.ts +27 -0
  302. package/src/parser/rules/inline/expr/conditional.ts +80 -0
  303. package/src/parser/rules/inline/expr/depth.ts +25 -0
  304. package/src/parser/rules/inline/expr/elements.ts +39 -0
  305. package/src/parser/rules/inline/expr/index.ts +84 -0
  306. package/src/parser/rules/inline/expr/syntax.ts +45 -0
  307. package/src/parser/rules/inline/footnote/child.ts +22 -0
  308. package/src/parser/rules/inline/footnote/close.ts +33 -0
  309. package/src/parser/rules/inline/footnote/content.ts +54 -0
  310. package/src/parser/rules/inline/footnote/elements.ts +38 -0
  311. package/src/parser/rules/inline/footnote/index.ts +54 -0
  312. package/src/parser/rules/inline/footnote/newline.ts +27 -0
  313. package/src/parser/rules/inline/footnote/open.ts +38 -0
  314. package/src/parser/rules/inline/formatting/container.ts +50 -0
  315. package/src/parser/rules/inline/{guillemet.ts → guillemet/index.ts} +5 -13
  316. package/src/parser/rules/inline/guillemet/text.ts +11 -0
  317. package/src/parser/rules/inline/html/gate.ts +64 -0
  318. package/src/parser/rules/inline/{html.ts → html/index.ts} +9 -60
  319. package/src/parser/rules/inline/html/open.ts +37 -0
  320. package/src/parser/rules/inline/image/attributes.ts +22 -0
  321. package/src/parser/rules/inline/image/body.ts +36 -0
  322. package/src/parser/rules/inline/image/index.ts +89 -0
  323. package/src/parser/rules/inline/image/open.ts +56 -0
  324. package/src/parser/rules/inline/image/source.ts +62 -0
  325. package/src/parser/rules/inline/image/syntax.ts +76 -0
  326. package/src/parser/rules/inline/italic.ts +2 -30
  327. package/src/parser/rules/inline/line-break/backslash.ts +58 -0
  328. package/src/parser/rules/inline/line-break/elements.ts +9 -0
  329. package/src/parser/rules/inline/line-break/index.ts +3 -0
  330. package/src/parser/rules/inline/line-break/newline.ts +82 -0
  331. package/src/parser/rules/inline/line-break/underscore.ts +45 -0
  332. package/src/parser/rules/inline/link-anchor.ts +6 -81
  333. package/src/parser/rules/inline/link-bracket/anchor.ts +3 -0
  334. package/src/parser/rules/inline/link-bracket/direct-url.ts +5 -0
  335. package/src/parser/rules/inline/link-bracket/parsed.ts +81 -0
  336. package/src/parser/rules/inline/link-bracket/parts.ts +64 -0
  337. package/src/parser/rules/inline/link-bracket/prefix.ts +15 -0
  338. package/src/parser/rules/inline/link-single.ts +7 -98
  339. package/src/parser/rules/inline/link-star.ts +7 -69
  340. package/src/parser/rules/inline/link-triple/fallback.ts +10 -0
  341. package/src/parser/rules/inline/link-triple/index.ts +62 -0
  342. package/src/parser/rules/inline/link-triple/interwiki.ts +11 -0
  343. package/src/parser/rules/inline/link-triple/label.ts +35 -0
  344. package/src/parser/rules/inline/link-triple/syntax.ts +72 -0
  345. package/src/parser/rules/inline/link-triple/target.ts +36 -0
  346. package/src/parser/rules/inline/math-inline/index.ts +40 -0
  347. package/src/parser/rules/inline/math-inline/syntax.ts +55 -0
  348. package/src/parser/rules/inline/monospace.ts +2 -30
  349. package/src/parser/rules/inline/parsing/block-boundary.ts +42 -0
  350. package/src/parser/rules/inline/parsing/block-start-predicates.ts +117 -0
  351. package/src/parser/rules/inline/parsing/collect.ts +23 -0
  352. package/src/parser/rules/inline/parsing/inline-content.ts +115 -0
  353. package/src/parser/rules/inline/parsing/paragraph-boundary.ts +47 -0
  354. package/src/parser/rules/inline/parsing/plain-text.ts +69 -0
  355. package/src/parser/rules/inline/parsing/preserved-line-break.ts +11 -0
  356. package/src/parser/rules/inline/parsing/rules.ts +34 -0
  357. package/src/parser/rules/inline/parsing/simple-token.ts +26 -0
  358. package/src/parser/rules/inline/raw/angle.ts +40 -0
  359. package/src/parser/rules/inline/raw/double-at.ts +78 -0
  360. package/src/parser/rules/inline/raw/index.ts +26 -0
  361. package/src/parser/rules/inline/raw/result.ts +26 -0
  362. package/src/parser/rules/inline/size/content.ts +65 -0
  363. package/src/parser/rules/inline/size/index.ts +55 -0
  364. package/src/parser/rules/inline/size/open.ts +43 -0
  365. package/src/parser/rules/inline/size/value.ts +45 -0
  366. package/src/parser/rules/inline/span/content.ts +97 -0
  367. package/src/parser/rules/inline/span/elements.ts +108 -0
  368. package/src/parser/rules/inline/span/index.ts +79 -0
  369. package/src/parser/rules/inline/span/newline.ts +50 -0
  370. package/src/parser/rules/inline/span/syntax.ts +70 -0
  371. package/src/parser/rules/inline/{strikethrough.ts → strikethrough/index.ts} +5 -60
  372. package/src/parser/rules/inline/strikethrough/parse.ts +14 -0
  373. package/src/parser/rules/inline/strikethrough/syntax.ts +24 -0
  374. package/src/parser/rules/inline/subscript.ts +2 -39
  375. package/src/parser/rules/inline/superscript.ts +4 -39
  376. package/src/parser/rules/inline/text/element.ts +5 -0
  377. package/src/parser/rules/inline/{text.ts → text/index.ts} +5 -4
  378. package/src/parser/rules/inline/underline/child.ts +26 -0
  379. package/src/parser/rules/inline/underline/content.ts +29 -0
  380. package/src/parser/rules/inline/{underline.ts → underline/index.ts} +6 -49
  381. package/src/parser/rules/inline/user/element.ts +11 -0
  382. package/src/parser/rules/inline/user/index.ts +34 -0
  383. package/src/parser/rules/inline/user/syntax.ts +67 -0
  384. package/src/parser/rules/inline/utils.ts +4 -344
  385. package/src/parser/rules/tokens.ts +106 -0
  386. package/src/parser/rules/types.ts +9 -252
  387. package/src/parser/depth.ts +0 -251
  388. package/src/parser/parse.ts +0 -315
  389. package/src/parser/postprocess/spanStrip.ts +0 -697
  390. package/src/parser/preprocess/expr.ts +0 -265
  391. package/src/parser/preprocess/utils.ts +0 -250
  392. package/src/parser/preprocess/whitespace.ts +0 -111
  393. package/src/parser/rules/block/align.ts +0 -282
  394. package/src/parser/rules/block/bibliography.ts +0 -359
  395. package/src/parser/rules/block/block-list.ts +0 -689
  396. package/src/parser/rules/block/blockquote.ts +0 -238
  397. package/src/parser/rules/block/code.ts +0 -187
  398. package/src/parser/rules/block/collapsible.ts +0 -337
  399. package/src/parser/rules/block/definition-list.ts +0 -270
  400. package/src/parser/rules/block/div.ts +0 -400
  401. package/src/parser/rules/block/embed-block.ts +0 -153
  402. package/src/parser/rules/block/footnoteblock.ts +0 -200
  403. package/src/parser/rules/block/heading.ts +0 -142
  404. package/src/parser/rules/block/html.ts +0 -222
  405. package/src/parser/rules/block/iframe.ts +0 -239
  406. package/src/parser/rules/block/include.ts +0 -179
  407. package/src/parser/rules/block/list.ts +0 -244
  408. package/src/parser/rules/block/math.ts +0 -183
  409. package/src/parser/rules/block/module/include/resolve.ts +0 -556
  410. package/src/parser/rules/block/module/listpages/types.ts +0 -513
  411. package/src/parser/rules/block/module/walk.ts +0 -380
  412. package/src/parser/rules/block/module.ts +0 -164
  413. package/src/parser/rules/block/orphan-li.ts +0 -177
  414. package/src/parser/rules/block/paragraph.ts +0 -157
  415. package/src/parser/rules/block/table-block.ts +0 -726
  416. package/src/parser/rules/block/table.ts +0 -441
  417. package/src/parser/rules/block/tabview.ts +0 -331
  418. package/src/parser/rules/block/toc.ts +0 -129
  419. package/src/parser/rules/inline/anchor-name.ts +0 -154
  420. package/src/parser/rules/inline/anchor.ts +0 -327
  421. package/src/parser/rules/inline/bibcite.ts +0 -153
  422. package/src/parser/rules/inline/color.ts +0 -140
  423. package/src/parser/rules/inline/equation-ref.ts +0 -115
  424. package/src/parser/rules/inline/expr.ts +0 -526
  425. package/src/parser/rules/inline/footnote.ts +0 -223
  426. package/src/parser/rules/inline/image.ts +0 -328
  427. package/src/parser/rules/inline/line-break.ts +0 -326
  428. package/src/parser/rules/inline/link-triple.ts +0 -267
  429. package/src/parser/rules/inline/math-inline.ts +0 -126
  430. package/src/parser/rules/inline/raw.ts +0 -262
  431. package/src/parser/rules/inline/size.ts +0 -244
  432. package/src/parser/rules/inline/span.ts +0 -424
  433. package/src/parser/rules/inline/user.ts +0 -147
@@ -1,223 +0,0 @@
1
- /**
2
- *
3
- * Parses the Wikidot footnote syntax: `[[footnote]]content[[/footnote]]`.
4
- *
5
- * Footnotes work in two parts: the inline `[[footnote]]` block produces
6
- * a numbered superscript reference marker at the point of use, while the
7
- * actual footnote content is collected separately and rendered by a
8
- * `[[footnoteblock]]` element (typically at the bottom of the page).
9
- *
10
- * Footnote content supports multiple paragraphs:
11
- * - The first paragraph is rendered as inline content (no wrapping `<p>` tag)
12
- * - Subsequent paragraphs (separated by blank lines) are each wrapped
13
- * in `<p>` tags, matching Wikidot's rendering behavior
14
- * - Single newlines within a paragraph become `<br />` elements
15
- *
16
- * The parsed footnote content is pushed into `ctx.footnotes` (an array
17
- * of Element arrays) so the renderer can later assign sequential numbers
18
- * and generate the footnote block.
19
- *
20
- * Produces a simple `"footnote"` AST element (a marker with no data)
21
- * at the inline reference point.
22
- *
23
- * @module
24
- */
25
- import type { Element } from "@wdprlib/ast";
26
- import type { InlineRule, ParseContext, RuleResult } from "../types";
27
- import { currentToken } from "../types";
28
- import { parseBlockName } from "../utils";
29
- import { parseInlineUntil } from "./utils";
30
-
31
- /**
32
- * Inline rule for parsing `[[footnote]]content[[/footnote]]`.
33
- *
34
- * Triggered by a `BLOCK_OPEN` (`[[`) token. Verifies the block name
35
- * is `footnote`, then parses multiline inline content until the matching
36
- * `[[/footnote]]` closing tag is found.
37
- *
38
- * Side effect: appends the parsed footnote content to `ctx.footnotes`.
39
- */
40
- export const footnoteRule: InlineRule = {
41
- name: "footnote",
42
- startTokens: ["BLOCK_OPEN"],
43
-
44
- /**
45
- * Attempts to parse a footnote block at the current position.
46
- *
47
- * @param ctx - Parse context with token stream and current position
48
- * @returns A successful result with a `"footnote"` marker element,
49
- * or `{ success: false }` if this is not a valid footnote
50
- */
51
- parse(ctx: ParseContext): RuleResult<Element> {
52
- const openToken = currentToken(ctx);
53
- if (openToken.type !== "BLOCK_OPEN") {
54
- return { success: false };
55
- }
56
-
57
- let pos = ctx.pos + 1;
58
- let consumed = 1;
59
-
60
- // Parse block name
61
- const nameResult = parseBlockName(ctx, pos);
62
- if (!nameResult) {
63
- return { success: false };
64
- }
65
-
66
- const blockName = nameResult.name;
67
- if (blockName !== "footnote") {
68
- return { success: false };
69
- }
70
-
71
- pos += nameResult.consumed;
72
- consumed += nameResult.consumed;
73
-
74
- // Expect ]]
75
- while (ctx.tokens[pos]?.type === "WHITESPACE") {
76
- pos++;
77
- consumed++;
78
- }
79
- if (ctx.tokens[pos]?.type !== "BLOCK_CLOSE") {
80
- return { success: false };
81
- }
82
- pos++;
83
- consumed++;
84
-
85
- // Parse content until [[/footnote]]
86
- // Wikidot footnote behavior:
87
- // - First paragraph: inline content (no <p> tag)
88
- // - After blank line: content wrapped in <p> tag
89
- const paragraphs: Element[][] = [[]];
90
- let currentParagraph = 0;
91
- let foundClose = false;
92
-
93
- while (pos < ctx.tokens.length) {
94
- const token = ctx.tokens[pos];
95
- if (!token || token.type === "EOF") {
96
- break;
97
- }
98
-
99
- // Check for [[/footnote]]
100
- if (token.type === "BLOCK_END_OPEN") {
101
- const closeNameResult = parseBlockName(ctx, pos + 1);
102
- if (closeNameResult && closeNameResult.name === "footnote") {
103
- foundClose = true;
104
- // Skip [[/footnote]]
105
- pos++; // [[/
106
- consumed++;
107
- pos += closeNameResult.consumed; // footnote
108
- consumed += closeNameResult.consumed;
109
- // Skip whitespace
110
- while (ctx.tokens[pos]?.type === "WHITESPACE") {
111
- pos++;
112
- consumed++;
113
- }
114
- // Skip ]]
115
- if (ctx.tokens[pos]?.type === "BLOCK_CLOSE") {
116
- pos++;
117
- consumed++;
118
- }
119
- break;
120
- }
121
- }
122
-
123
- // Handle NEWLINE - check if it's a paragraph break (blank line)
124
- if (token.type === "NEWLINE") {
125
- pos++;
126
- consumed++;
127
- // Peek ahead: skip whitespace to check for blank line (e.g. "\n \n")
128
- let peekPos = pos;
129
- let peekConsumed = 0;
130
- while (ctx.tokens[peekPos]?.type === "WHITESPACE") {
131
- peekPos++;
132
- peekConsumed++;
133
- }
134
- // Look ahead for another NEWLINE (blank line = paragraph break)
135
- if (ctx.tokens[peekPos]?.type === "NEWLINE") {
136
- // Commit the whitespace skip
137
- pos = peekPos;
138
- consumed += peekConsumed;
139
- // Skip all consecutive newlines
140
- while (ctx.tokens[pos]?.type === "NEWLINE") {
141
- pos++;
142
- consumed++;
143
- }
144
- // Start new paragraph
145
- currentParagraph++;
146
- paragraphs[currentParagraph] = [];
147
- } else {
148
- // Single newline - just continue (becomes space or line-break)
149
- // For Wikidot compatibility, single newlines in footnotes become <br />
150
- paragraphs[currentParagraph]!.push({ element: "line-break" });
151
- }
152
- continue;
153
- }
154
-
155
- // Parse inline content (including newlines for multiline footnotes)
156
- const inlineCtx: ParseContext = { ...ctx, pos };
157
- const inlineResult = parseInlineUntil(inlineCtx, "BLOCK_END_OPEN");
158
- if (inlineResult.elements.length > 0) {
159
- paragraphs[currentParagraph]!.push(...inlineResult.elements);
160
- pos += inlineResult.consumed;
161
- consumed += inlineResult.consumed;
162
- } else {
163
- // Fallback: just add as text
164
- paragraphs[currentParagraph]!.push({ element: "text", data: token.value });
165
- pos++;
166
- consumed++;
167
- }
168
- }
169
-
170
- // Build children: first paragraph inline, subsequent paragraphs wrapped in <p>
171
- const children: Element[] = [];
172
- for (let i = 0; i < paragraphs.length; i++) {
173
- const para = paragraphs[i]!;
174
- if (para.length === 0) continue;
175
- // Remove leading/trailing line-breaks
176
- while (para.length > 0 && para[0]?.element === "line-break") {
177
- para.shift();
178
- }
179
- while (para.length > 0 && para[para.length - 1]?.element === "line-break") {
180
- para.pop();
181
- }
182
- if (para.length === 0) continue;
183
-
184
- if (i === 0) {
185
- // First paragraph: inline
186
- children.push(...para);
187
- } else {
188
- // Subsequent paragraphs: wrapped in <p>
189
- children.push({
190
- element: "container",
191
- data: {
192
- type: "paragraph",
193
- attributes: {},
194
- elements: para,
195
- },
196
- });
197
- }
198
- }
199
-
200
- if (!foundClose) {
201
- ctx.diagnostics.push({
202
- severity: "warning",
203
- code: "unclosed-block",
204
- message: "Missing closing tag [[/footnote]] for [[footnote]]",
205
- position: openToken.position,
206
- });
207
- }
208
-
209
- // Store footnote content in context
210
- ctx.footnotes.push(children);
211
-
212
- // Return simple footnote marker
213
- return {
214
- success: true,
215
- elements: [
216
- {
217
- element: "footnote",
218
- },
219
- ],
220
- consumed,
221
- };
222
- },
223
- };
@@ -1,328 +0,0 @@
1
- /**
2
- *
3
- * Parses the Wikidot image block syntax: `[[image source attributes]]`.
4
- *
5
- * Images support several alignment/float prefixes that modify how the
6
- * image is positioned on the page:
7
- * - `[[image src]]` -- default (no alignment)
8
- * - `[[=image src]]` -- centered
9
- * - `[[<image src]]` -- left-aligned
10
- * - `[[>image src]]` -- right-aligned
11
- * - `[[f<image src]]` -- float left
12
- * - `[[f>image src]]` -- float right
13
- * - `[[f=image src]]` -- float center
14
- *
15
- * Image sources can be:
16
- * - Full URLs (`http://...`, `https://...`, `/path`)
17
- * - Local file references in three formats:
18
- * - `file.ext` (file on current page, type `file1`)
19
- * - `page/file.ext` (file on another page, type `file2`)
20
- * - `site:page/file.ext` or `site/page/file.ext` (cross-site file, type `file3`)
21
- *
22
- * Optional attributes follow the source (e.g. `alt`, `title`, `width`,
23
- * `height`, `style`, `class`, `link`). The `link` attribute is treated
24
- * specially: it wraps the image in a hyperlink rather than being applied
25
- * as an HTML attribute. Unsafe attributes are filtered out.
26
- *
27
- * Produces an `"image"` AST element with source, alignment, link, and
28
- * attribute data.
29
- *
30
- * @module
31
- */
32
- import type { Element, ImageSource, FloatAlignment, Alignment, AttributeMap } from "@wdprlib/ast";
33
- import type { InlineRule, ParseContext, RuleResult } from "../types";
34
- import { currentToken } from "../types";
35
- import { filterUnsafeAttributes } from "../utils";
36
- import { parseAttributesRaw } from "../block/utils";
37
-
38
- /**
39
- * Parses the block name portion of an image tag, including alignment
40
- * prefix characters.
41
- *
42
- * The alignment prefix may consist of `=`, `<`, `>`, `f<`, `f>`, or `f=`,
43
- * each tokenized differently depending on the lexer's context (e.g. `>`
44
- * may appear as either a `TEXT` token or a `BLOCKQUOTE_MARKER`).
45
- *
46
- * @param ctx - The current parse context
47
- * @param startPos - Token index at which to begin scanning
48
- * @returns An object with the combined lowercased name (prefix + "image")
49
- * and the number of tokens consumed, or `null` if no valid image
50
- * block name was found
51
- */
52
- function parseImageBlockName(
53
- ctx: ParseContext,
54
- startPos: number,
55
- ): { name: string; consumed: number } | null {
56
- let pos = startPos;
57
- let consumed = 0;
58
-
59
- while (ctx.tokens[pos]?.type === "WHITESPACE") {
60
- pos++;
61
- consumed++;
62
- }
63
-
64
- let prefix = "";
65
- const token = ctx.tokens[pos];
66
-
67
- // Handle prefix characters for image variants: =image, <image, >image, f<image, f>image
68
- // These are tokenized as separate tokens: EQUALS/TEXT + IDENTIFIER
69
- if (token?.type === "EQUALS") {
70
- // =image (center)
71
- prefix = "=";
72
- pos++;
73
- consumed++;
74
- } else if (token?.type === "TEXT" && token.value === "<") {
75
- // <image (left align)
76
- prefix = "<";
77
- pos++;
78
- consumed++;
79
- } else if (token?.type === "TEXT" && token.value === ">") {
80
- // >image (right align)
81
- prefix = ">";
82
- pos++;
83
- consumed++;
84
- } else if (token?.type === "BLOCKQUOTE_MARKER" && token.value === ">") {
85
- // >image (right align) - may also be tokenized as BLOCKQUOTE_MARKER
86
- prefix = ">";
87
- pos++;
88
- consumed++;
89
- } else if (token?.type === "IDENTIFIER" && token.value.toLowerCase() === "f") {
90
- // Check for f<, f>, or f=
91
- const nextToken = ctx.tokens[pos + 1];
92
- if (nextToken?.type === "TEXT" && nextToken.value === "<") {
93
- prefix = "f<";
94
- pos += 2;
95
- consumed += 2;
96
- } else if (nextToken?.type === "TEXT" && nextToken.value === ">") {
97
- prefix = "f>";
98
- pos += 2;
99
- consumed += 2;
100
- } else if (nextToken?.type === "BLOCKQUOTE_MARKER" && nextToken.value === ">") {
101
- prefix = "f>";
102
- pos += 2;
103
- consumed += 2;
104
- } else if (nextToken?.type === "EQUALS") {
105
- // f=image (float center)
106
- prefix = "f=";
107
- pos += 2;
108
- consumed += 2;
109
- }
110
- }
111
-
112
- const nameToken = ctx.tokens[pos];
113
- if (!nameToken || (nameToken.type !== "TEXT" && nameToken.type !== "IDENTIFIER")) {
114
- return null;
115
- }
116
-
117
- return { name: prefix + nameToken.value.toLowerCase(), consumed: consumed + 1 };
118
- }
119
-
120
- /**
121
- * Determines the {@link ImageSource} type and data from a raw source string.
122
- *
123
- * Classification logic:
124
- * - Strings starting with `http://`, `https://`, or `/` are URL sources.
125
- * - Strings containing a colon before a slash (e.g. `site:page/file`) are
126
- * `file3` (cross-site) references.
127
- * - Strings with 2+ slashes (e.g. `site/page/file`) are also `file3`.
128
- * - Strings with exactly 1 slash (e.g. `page/file`) are `file2` references.
129
- * - Strings with no slashes are `file1` (current-page file) references.
130
- *
131
- * @param src - The raw image source string from the markup
132
- * @returns An {@link ImageSource} object describing the source type and data
133
- */
134
- function parseImageSource(src: string): ImageSource {
135
- // URL sources
136
- if (src.startsWith("http://") || src.startsWith("https://") || src.startsWith("/")) {
137
- return { type: "url", data: src };
138
- }
139
-
140
- // File references - determine type based on format
141
- // file3: site:page/file or site/page/file (2+ slashes)
142
- // file2: page/file (1 slash)
143
- // file1: file (no slash)
144
- const colonIdx = src.indexOf(":");
145
- const slashIdx = src.indexOf("/");
146
-
147
- if (colonIdx > 0 && slashIdx > colonIdx) {
148
- // site:page/file format (colon-based)
149
- const site = src.substring(0, colonIdx);
150
- const rest = src.substring(colonIdx + 1);
151
- const lastSlash = rest.lastIndexOf("/");
152
- const page = rest.substring(0, lastSlash);
153
- const file = rest.substring(lastSlash + 1);
154
- return { type: "file3", data: { site, page, file } };
155
- }
156
-
157
- // Count slashes to determine format
158
- const slashes = src.split("/").length - 1;
159
- if (slashes >= 2) {
160
- // site/page/file format (2+ slashes = file3)
161
- const firstSlash = src.indexOf("/");
162
- const lastSlash = src.lastIndexOf("/");
163
- const site = src.substring(0, firstSlash);
164
- const page = src.substring(firstSlash + 1, lastSlash);
165
- const file = src.substring(lastSlash + 1);
166
- return { type: "file3", data: { site, page, file } };
167
- }
168
- if (slashIdx > 0) {
169
- // page/file format (1 slash = file2)
170
- const page = src.substring(0, slashIdx);
171
- const file = src.substring(slashIdx + 1);
172
- return { type: "file2", data: { page, file } };
173
- }
174
-
175
- // Just file
176
- return { type: "file1", data: { file: src } };
177
- }
178
-
179
- /**
180
- * Converts the image block name (including its alignment prefix) into a
181
- * {@link FloatAlignment} descriptor.
182
- *
183
- * The prefix portion of the block name determines both the alignment
184
- * direction and whether the image should float. A plain `"image"` name
185
- * (no prefix) returns `null`, indicating no explicit alignment.
186
- *
187
- * @param blockName - The lowercased block name (e.g. `"f>image"`, `"=image"`, `"image"`)
188
- * @returns A {@link FloatAlignment} object with `align` and `float` fields,
189
- * or `null` for the unprefixed `"image"` form
190
- */
191
- function parseAlignment(blockName: string): FloatAlignment | null {
192
- let align: Alignment = "left";
193
- let float = false;
194
-
195
- if (blockName === "=image") {
196
- align = "center";
197
- } else if (blockName === "<image") {
198
- align = "left";
199
- } else if (blockName === ">image") {
200
- align = "right";
201
- } else if (blockName === "f<image") {
202
- align = "left";
203
- float = true;
204
- } else if (blockName === "f>image") {
205
- align = "right";
206
- float = true;
207
- } else if (blockName === "f=image") {
208
- align = "center";
209
- float = true;
210
- } else if (blockName === "image") {
211
- return null;
212
- }
213
-
214
- return { align, float };
215
- }
216
-
217
- /**
218
- * Inline rule for parsing `[[image source attributes]]` and its alignment variants.
219
- *
220
- * Triggered by a `BLOCK_OPEN` (`[[`) token. The rule identifies the image
221
- * block name (with optional alignment prefix), extracts the image source,
222
- * parses remaining attributes, filters unsafe attributes, and extracts the
223
- * `link` attribute for special handling.
224
- *
225
- * Fails if the block name is not an image variant, if no source is provided,
226
- * or if `]]` is not found.
227
- */
228
- export const imageRule: InlineRule = {
229
- name: "image",
230
- startTokens: ["BLOCK_OPEN"],
231
-
232
- /**
233
- * Attempts to parse an image block at the current position.
234
- *
235
- * @param ctx - Parse context with token stream and current position
236
- * @returns A successful result with an `"image"` element, or `{ success: false }`
237
- */
238
- parse(ctx: ParseContext): RuleResult<Element> {
239
- const openToken = currentToken(ctx);
240
- if (openToken.type !== "BLOCK_OPEN") {
241
- return { success: false };
242
- }
243
-
244
- let pos = ctx.pos + 1;
245
- let consumed = 1;
246
-
247
- const nameResult = parseImageBlockName(ctx, pos);
248
- if (!nameResult) {
249
- return { success: false };
250
- }
251
-
252
- // Check for image, =image, <image, >image, f<image, f>image, f=image
253
- const blockName = nameResult.name;
254
- const imageNames = ["image", "=image", "<image", ">image", "f<image", "f>image", "f=image"];
255
- if (!imageNames.includes(blockName)) {
256
- return { success: false };
257
- }
258
-
259
- pos += nameResult.consumed;
260
- consumed += nameResult.consumed;
261
-
262
- // Skip whitespace
263
- while (ctx.tokens[pos]?.type === "WHITESPACE") {
264
- pos++;
265
- consumed++;
266
- }
267
-
268
- // Get image source (collect tokens until whitespace or ]])
269
- let src = "";
270
- while (pos < ctx.tokens.length) {
271
- const srcToken = ctx.tokens[pos];
272
- if (
273
- !srcToken ||
274
- srcToken.type === "WHITESPACE" ||
275
- srcToken.type === "BLOCK_CLOSE" ||
276
- srcToken.type === "NEWLINE" ||
277
- srcToken.type === "EOF"
278
- ) {
279
- break;
280
- }
281
- src += srcToken.value;
282
- pos++;
283
- consumed++;
284
- }
285
-
286
- // Parse remaining attributes (raw, before safety filtering)
287
- const attrResultRaw = parseAttributesRaw(ctx, pos, false);
288
- pos += attrResultRaw.consumed;
289
- consumed += attrResultRaw.consumed;
290
-
291
- // Expect ]]
292
- if (ctx.tokens[pos]?.type !== "BLOCK_CLOSE") {
293
- return { success: false };
294
- }
295
- pos++;
296
- consumed++;
297
-
298
- // Wikidot requires image source - [[image]] without source fails
299
- if (!src) {
300
- return { success: false };
301
- }
302
-
303
- // Parse source and alignment
304
- const source = parseImageSource(src);
305
- const alignment = parseAlignment(blockName);
306
-
307
- // Extract link before filtering (link is image-specific, not an HTML attribute)
308
- const linkUrl = attrResultRaw.attrs.link;
309
- const { link: _link, ...restAttrs } = attrResultRaw.attrs;
310
- const cleanAttrs = filterUnsafeAttributes(restAttrs);
311
-
312
- return {
313
- success: true,
314
- elements: [
315
- {
316
- element: "image",
317
- data: {
318
- source,
319
- link: linkUrl ?? null,
320
- alignment,
321
- attributes: cleanAttrs as AttributeMap,
322
- },
323
- },
324
- ],
325
- consumed,
326
- };
327
- },
328
- };