@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
@@ -20,20 +20,9 @@
20
20
  * @module
21
21
  */
22
22
 
23
- import type { CompiledTemplate, VariableContext, PageData, UserInfo } from "./types";
24
-
25
- /** Default character count for `%%preview%%` when no length is specified (Wikidot default). */
26
- const DEFAULT_PREVIEW_LENGTH = 200;
27
-
28
- /**
29
- * Regex pattern for matching ListPages template variables with all parameter variants.
30
- *
31
- * Captures: [1] variable name, [2] brace parameter, [3] paren parameter, [4] format string.
32
- * The format portion allows single `%` characters (for strftime tokens like `%Y`)
33
- * but stops at `%%` (which terminates the variable).
34
- */
35
- const VARIABLE_REGEX =
36
- /%%([a-z_]+)(?:\{([^}]+)\})?(?:\((\d+)\))?(?:\|([^%]*(?:%(?!%)[^%]*)*))?%%/gi;
23
+ import type { CompiledTemplate, VariableContext } from "./types";
24
+ import { createVariableGetter } from "./template/getters";
25
+ import { scanTemplateVariables } from "./template/syntax";
37
26
 
38
27
  /**
39
28
  * Compile a ListPages template string into an executable function.
@@ -50,19 +39,22 @@ export function compileTemplate(template: string): CompiledTemplate {
50
39
  let lastIndex = 0;
51
40
 
52
41
  // Split template into static and dynamic parts
53
- for (const match of template.matchAll(VARIABLE_REGEX)) {
42
+ for (const match of scanTemplateVariables(template)) {
54
43
  // Add static part before this match
55
- if (match.index !== undefined && match.index > lastIndex) {
44
+ if (match.index > lastIndex) {
56
45
  parts.push(template.slice(lastIndex, match.index));
57
46
  }
58
47
 
59
48
  // Convert variable to getter function
60
- const [, varName, braceParam, parenParam, format] = match;
61
- if (!varName) continue;
62
- const getter = createVariableGetter(varName.toLowerCase(), braceParam, parenParam, format);
49
+ const getter = createVariableGetter(
50
+ match.name.toLowerCase(),
51
+ match.braceParam,
52
+ match.parenParam,
53
+ match.format,
54
+ );
63
55
  parts.push(getter);
64
56
 
65
- lastIndex = match.index !== undefined ? match.index + match[0].length : lastIndex;
57
+ lastIndex = match.index + match.raw.length;
66
58
  }
67
59
 
68
60
  // Add remaining static part
@@ -79,375 +71,3 @@ export function compileTemplate(template: string): CompiledTemplate {
79
71
  return result;
80
72
  };
81
73
  }
82
-
83
- /**
84
- * Create a getter function for a specific template variable.
85
- *
86
- * Handles all variable variants: parameterized (`{param}`), parenthesized (`(param)`),
87
- * formatted (`|format`), and simple. Returns a function that extracts the appropriate
88
- * value from a `VariableContext`.
89
- *
90
- * Unknown variable names return a function that always returns an empty string,
91
- * matching Wikidot's behavior of silently ignoring unknown variables.
92
- *
93
- * @param name - Lowercase variable name
94
- * @param braceParam - Content inside `{...}`, if present
95
- * @param parenParam - Content inside `(...)`, if present
96
- * @param format - Content after `|`, if present
97
- * @returns A function that extracts the variable's value from a VariableContext
98
- */
99
- function createVariableGetter(
100
- name: string,
101
- braceParam?: string,
102
- parenParam?: string,
103
- format?: string,
104
- ): (ctx: VariableContext) => string {
105
- // Parameterized variables with {param}
106
- if (braceParam !== undefined) {
107
- switch (name) {
108
- case "content": {
109
- // %%content{n}%% - n is 1-indexed, split content by ==== on demand
110
- const idx = Number(braceParam) - 1;
111
- return (ctx) => {
112
- if (!ctx.page.content) return "";
113
- const sections = splitContentSections(ctx.page.content);
114
- return sections[idx] ?? "";
115
- };
116
- }
117
- case "form_data":
118
- return (ctx) => ctx.page.formData?.[braceParam] ?? "";
119
- case "form_raw":
120
- return (ctx) => ctx.page.formRaw?.[braceParam] ?? "";
121
- case "form_label":
122
- return (ctx) => ctx.page.formLabel?.[braceParam] ?? "";
123
- case "form_hint":
124
- return (ctx) => ctx.page.formHint?.[braceParam] ?? "";
125
- }
126
- }
127
-
128
- // Parameterized variables with (param)
129
- if (parenParam !== undefined && name === "preview") {
130
- const len = Number(parenParam);
131
- return (ctx) => (ctx.page.content ?? "").slice(0, len);
132
- }
133
-
134
- // Date variables with format
135
- if (format !== undefined) {
136
- switch (name) {
137
- case "created_at":
138
- return (ctx) => formatDate(ctx.page.createdAt, format);
139
- case "updated_at":
140
- return (ctx) => formatDate(ctx.page.updatedAt, format);
141
- case "commented_at":
142
- return (ctx) => (ctx.page.commentedAt ? formatDate(ctx.page.commentedAt, format) : "");
143
- }
144
- }
145
-
146
- // tags_linked with prefix
147
- if (name === "tags_linked") {
148
- const prefix = format ?? "/system:page-tags/tag/";
149
- return (ctx) => formatTagsLinked(ctx.page.tags, prefix);
150
- }
151
- if (name === "_tags_linked") {
152
- const prefix = format ?? "/system:page-tags/tag/";
153
- return (ctx) => formatTagsLinked(ctx.page.hiddenTags, prefix);
154
- }
155
-
156
- // Simple variables
157
- const getter = SIMPLE_GETTERS[name];
158
- if (getter) return getter;
159
-
160
- // Unknown variable - return empty string
161
- return () => "";
162
- }
163
-
164
- // =============================================================================
165
- // Simple Variable Getters
166
- // =============================================================================
167
-
168
- const SIMPLE_GETTERS: Record<string, (ctx: VariableContext) => string> = {
169
- // Lifecycle - created
170
- created_at: (ctx) => formatDate(ctx.page.createdAt),
171
- created_by: (ctx) => ctx.page.createdBy?.name ?? "Anonymous",
172
- created_by_unix: (ctx) => ctx.page.createdBy?.unixName ?? "",
173
- created_by_id: (ctx) => String(ctx.page.createdBy?.id ?? 0),
174
- created_by_linked: (ctx) => formatUserLinked(ctx.page.createdBy),
175
-
176
- // Lifecycle - updated
177
- updated_at: (ctx) => formatDate(ctx.page.updatedAt),
178
- updated_by: (ctx) => ctx.page.updatedBy?.name ?? "Anonymous",
179
- updated_by_unix: (ctx) => ctx.page.updatedBy?.unixName ?? "",
180
- updated_by_id: (ctx) => String(ctx.page.updatedBy?.id ?? 0),
181
- updated_by_linked: (ctx) => formatUserLinked(ctx.page.updatedBy),
182
-
183
- // Lifecycle - commented
184
- commented_at: (ctx) => (ctx.page.commentedAt ? formatDate(ctx.page.commentedAt) : ""),
185
- commented_by: (ctx) => ctx.page.commentedBy?.name ?? "",
186
- commented_by_unix: (ctx) => ctx.page.commentedBy?.unixName ?? "",
187
- commented_by_id: (ctx) => String(ctx.page.commentedBy?.id ?? 0),
188
- commented_by_linked: (ctx) => formatUserLinked(ctx.page.commentedBy),
189
-
190
- // Structure - page
191
- name: (ctx) => ctx.page.name,
192
- category: (ctx) => ctx.page.category,
193
- fullname: (ctx) => ctx.page.fullname,
194
- title: (ctx) => ctx.page.title,
195
- title_linked: (ctx) => `[[[${ctx.page.fullname} | ${ctx.page.title}]]]`,
196
- link: (ctx) => `https://${ctx.site.domain}/${ctx.page.fullname}`,
197
-
198
- // Structure - parent
199
- parent_name: (ctx) => ctx.page.parentName ?? "",
200
- parent_category: (ctx) => ctx.page.parentCategory ?? "",
201
- parent_fullname: (ctx) => ctx.page.parentFullname ?? "",
202
- parent_title: (ctx) => ctx.page.parentTitle ?? "",
203
- parent_title_linked: (ctx) =>
204
- ctx.page.parentFullname ? `[[[${ctx.page.parentFullname} | ${ctx.page.parentTitle}]]]` : "",
205
-
206
- // Content
207
- content: (ctx) => ctx.page.content ?? "",
208
- preview: (ctx) => (ctx.page.content ?? "").slice(0, DEFAULT_PREVIEW_LENGTH),
209
- summary: (ctx) => getSummary(ctx.page),
210
- first_paragraph: (ctx) => getFirstParagraph(ctx.page.content),
211
-
212
- // Tags
213
- tags: (ctx) => ctx.page.tags.join(" "),
214
- _tags: (ctx) => ctx.page.hiddenTags.join(" "),
215
-
216
- // Metrics
217
- children: (ctx) => String(ctx.page.children),
218
- comments: (ctx) => String(ctx.page.comments),
219
- size: (ctx) => String(ctx.page.size),
220
- rating: (ctx) => String(ctx.page.rating),
221
- rating_votes: (ctx) => String(ctx.page.ratingVotes),
222
- rating_percent: (ctx) => String(ctx.page.ratingPercent ?? 0),
223
- revisions: (ctx) => String(ctx.page.revisions),
224
-
225
- // Pagination
226
- index: (ctx) => String(ctx.index),
227
- total: (ctx) => String(ctx.total),
228
- limit: (ctx) => (ctx.limit !== undefined ? String(ctx.limit) : ""),
229
- total_or_limit: (ctx) =>
230
- String(ctx.limit !== undefined ? Math.min(ctx.total, ctx.limit) : ctx.total),
231
-
232
- // Site context
233
- site_title: (ctx) => ctx.site.title,
234
- site_name: (ctx) => ctx.site.name,
235
- site_domain: (ctx) => ctx.site.domain,
236
- };
237
-
238
- // =============================================================================
239
- // Helper Functions
240
- // =============================================================================
241
-
242
- /**
243
- * Format a Date object using an optional strftime-like format string.
244
- *
245
- * When no format is provided, returns the ISO 8601 string representation.
246
- *
247
- * @param date - The date to format
248
- * @param format - Optional strftime format string (e.g., `"%Y-%m-%d"`)
249
- * @returns Formatted date string
250
- */
251
- function formatDate(date: Date, format?: string): string {
252
- if (!format) {
253
- // Default ISO format
254
- return date.toISOString();
255
- }
256
- return strftime(date, format);
257
- }
258
-
259
- /**
260
- * Format a user as Wikidot's `[[*user name]]` inline syntax for linked display.
261
- *
262
- * @param user - User info, or undefined for anonymous display
263
- * @returns Wikidot user link syntax, or "Anonymous" if no user
264
- */
265
- function formatUserLinked(user?: UserInfo): string {
266
- if (!user) return "Anonymous";
267
- return `[[*user ${user.name}]]`;
268
- }
269
-
270
- /**
271
- * Format an array of tags as space-separated Wikidot link syntax.
272
- *
273
- * Each tag becomes `[prefix/tag tag]` where prefix defaults to
274
- * `/system:page-tags/tag/` unless overridden by the template's pipe format.
275
- *
276
- * @param tags - Array of tag names
277
- * @param prefix - URL prefix for tag links
278
- * @returns Space-separated string of Wikidot link syntax, or empty string if no tags
279
- */
280
- function formatTagsLinked(tags: string[], prefix: string): string {
281
- if (tags.length === 0) return "";
282
- return tags.map((tag) => `[${prefix}${tag} ${tag}]`).join(" ");
283
- }
284
-
285
- /**
286
- * Split content by ==== separators
287
- *
288
- * wikidot uses preg_split('/^([=]{4,})$/m', $source) to split content
289
- * %%content{n}%% references sections[n-1] (1-indexed)
290
- */
291
- function splitContentSections(content: string): string[] {
292
- return content.split(/^={4,}$/m).map((section) => section.trim());
293
- }
294
-
295
- /**
296
- * Extract a summary from page content.
297
- *
298
- * If the content contains `====` section separators, returns the first section
299
- * (equivalent to `%%content{1}%%`). Otherwise, returns the first paragraph.
300
- *
301
- * @param page - Page data containing content
302
- * @returns Summary text extracted from the page content
303
- */
304
- function getSummary(page: PageData): string {
305
- if (page.content) {
306
- const sections = splitContentSections(page.content);
307
- if (sections.length > 1) {
308
- return sections[0]?.trim() ?? "";
309
- }
310
- }
311
- return getFirstParagraph(page.content);
312
- }
313
-
314
- /**
315
- * Extract the first paragraph from wikitext content.
316
- *
317
- * Strips headings, TOC directives, div blocks, and module blocks before
318
- * splitting on double newlines to find the first content paragraph.
319
- *
320
- * @param content - Raw wikitext content, or undefined
321
- * @returns The first paragraph text, or empty string if no content
322
- */
323
- function getFirstParagraph(content?: string): string {
324
- if (!content) return "";
325
-
326
- // Remove headings, TOC, div, module blocks
327
- const s = content
328
- .replace(/^(\+{1,6}) (.*)/gm, "")
329
- .replace(/^\[\[toc(\s[^\]]+)?\]\]/gim, "")
330
- .replace(/^\[\[\/?div(\s[^\]]+)?\]\]/gim, "")
331
- .replace(/^\[\[\/?module(\s[^\]]+)?\]\]/gim, "")
332
- .trim();
333
-
334
- // Split by double newlines and take first
335
- const paragraphs = s.split(/\n{2,}/);
336
- return paragraphs[0]?.trim() ?? "";
337
- }
338
-
339
- /** Full month names for strftime `%B` token. Static to avoid per-call allocation. */
340
- const MONTHS = [
341
- "January",
342
- "February",
343
- "March",
344
- "April",
345
- "May",
346
- "June",
347
- "July",
348
- "August",
349
- "September",
350
- "October",
351
- "November",
352
- "December",
353
- ];
354
- /** Abbreviated month names for strftime `%b` token. */
355
- const MONTHS_SHORT = [
356
- "Jan",
357
- "Feb",
358
- "Mar",
359
- "Apr",
360
- "May",
361
- "Jun",
362
- "Jul",
363
- "Aug",
364
- "Sep",
365
- "Oct",
366
- "Nov",
367
- "Dec",
368
- ];
369
- /** Full day names for strftime `%A` token. */
370
- const DAYS = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
371
- /** Abbreviated day names for strftime `%a` token. */
372
- const DAYS_SHORT = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
373
-
374
- /** Pre-compiled regex matching strftime tokens (`%X` where X is a supported letter or `%`). */
375
- const STRFTIME_REGEX = /%([YymdHeHIMSpbBaAwjZz%])/g;
376
-
377
- /**
378
- * Minimal strftime implementation supporting common tokens.
379
- *
380
- * Uses a single-pass regex replace for O(n) performance. All dates are
381
- * treated as UTC to match Wikidot's server-side rendering behavior.
382
- *
383
- * Supported tokens: `%Y` (4-digit year), `%y` (2-digit year), `%m` (month),
384
- * `%d` (zero-padded day), `%e` (day), `%H` (24h hour), `%I` (12h hour),
385
- * `%M` (minute), `%S` (second), `%p` (AM/PM), `%b`/`%B` (month name),
386
- * `%a`/`%A` (day name), `%w` (weekday number), `%j` (day of year),
387
- * `%Z`/`%z` (timezone), `%%` (literal percent).
388
- *
389
- * @param date - The date to format
390
- * @param format - strftime format string
391
- * @returns Formatted date string
392
- */
393
- function strftime(date: Date, format: string): string {
394
- const pad = (n: number, len = 2) => String(n).padStart(len, "0");
395
-
396
- return format.replace(STRFTIME_REGEX, (_, token: string) => {
397
- switch (token) {
398
- case "Y":
399
- return String(date.getFullYear());
400
- case "y":
401
- return String(date.getFullYear()).slice(-2);
402
- case "m":
403
- return pad(date.getMonth() + 1);
404
- case "d":
405
- return pad(date.getDate());
406
- case "e":
407
- return String(date.getDate());
408
- case "H":
409
- return pad(date.getHours());
410
- case "I":
411
- return pad(date.getHours() % 12 || 12);
412
- case "M":
413
- return pad(date.getMinutes());
414
- case "S":
415
- return pad(date.getSeconds());
416
- case "p":
417
- return date.getHours() < 12 ? "AM" : "PM";
418
- case "b":
419
- return MONTHS_SHORT[date.getMonth()] ?? "";
420
- case "B":
421
- return MONTHS[date.getMonth()] ?? "";
422
- case "a":
423
- return DAYS_SHORT[date.getDay()] ?? "";
424
- case "A":
425
- return DAYS[date.getDay()] ?? "";
426
- case "w":
427
- return String(date.getDay());
428
- case "j":
429
- return pad(getDayOfYear(date), 3);
430
- case "Z":
431
- return "UTC";
432
- case "z":
433
- return "+0000";
434
- case "%":
435
- return "%";
436
- default:
437
- return `%${token}`;
438
- }
439
- });
440
- }
441
-
442
- /**
443
- * Calculate the day of year (1-366) for a given date.
444
- *
445
- * @param date - The date to calculate for
446
- * @returns Day of year as an integer (1 = January 1st)
447
- */
448
- function getDayOfYear(date: Date): number {
449
- const start = new Date(date.getFullYear(), 0, 0);
450
- const diff = date.getTime() - start.getTime();
451
- const oneDay = 1000 * 60 * 60 * 24;
452
- return Math.floor(diff / oneDay);
453
- }