@wdprlib/parser 3.1.2 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +10456 -8230
- package/dist/index.d.cts +313 -337
- package/dist/index.d.ts +313 -337
- package/dist/index.js +10460 -8234
- package/package.json +5 -3
- package/src/index.ts +170 -0
- package/src/lexer/anchor.ts +48 -0
- package/src/lexer/index.ts +21 -0
- package/src/lexer/lexer.ts +201 -0
- package/src/lexer/options.ts +19 -0
- package/src/lexer/punctuation.ts +70 -0
- package/src/lexer/quoted-string.ts +16 -0
- package/src/lexer/runs.ts +85 -0
- package/src/lexer/spacing-actions.ts +24 -0
- package/src/lexer/state.ts +103 -0
- package/src/lexer/syntax-actions.ts +80 -0
- package/src/lexer/text-actions.ts +41 -0
- package/src/lexer/token-actions.ts +136 -0
- package/src/lexer/token-factory.ts +62 -0
- package/src/lexer/tokenize.ts +18 -0
- package/src/lexer/tokens.ts +141 -0
- package/src/parser/constants.ts +175 -0
- package/src/parser/depth/index.ts +111 -0
- package/src/parser/depth/stack.ts +82 -0
- package/src/parser/index.ts +18 -0
- package/src/parser/parse/block.ts +42 -0
- package/src/parser/parse/context.ts +26 -0
- package/src/parser/parse/footnotes.ts +25 -0
- package/src/parser/parse/index.ts +42 -0
- package/src/parser/parse/options.ts +34 -0
- package/src/parser/parse/parser.ts +79 -0
- package/src/parser/parse/plain-non-ascii.ts +129 -0
- package/src/parser/parse/result.ts +57 -0
- package/src/parser/parse/source.ts +11 -0
- package/src/parser/postprocess/divAdjacentParagraph.ts +76 -0
- package/src/parser/postprocess/index.ts +15 -0
- package/src/parser/postprocess/spanStrip/clean-element.ts +168 -0
- package/src/parser/postprocess/spanStrip/cleanup.ts +25 -0
- package/src/parser/postprocess/spanStrip/empty-spans.ts +36 -0
- package/src/parser/postprocess/spanStrip/escaped.ts +78 -0
- package/src/parser/postprocess/spanStrip/factory.ts +23 -0
- package/src/parser/postprocess/spanStrip/index.ts +8 -0
- package/src/parser/postprocess/spanStrip/merge.ts +117 -0
- package/src/parser/postprocess/spanStrip/predicates.ts +59 -0
- package/src/parser/postprocess/spanStrip/split.ts +67 -0
- package/src/parser/preprocess/expr/chars.ts +15 -0
- package/src/parser/preprocess/expr/evaluate.ts +22 -0
- package/src/parser/preprocess/expr/index.ts +45 -0
- package/src/parser/preprocess/expr/kind.ts +19 -0
- package/src/parser/preprocess/expr/parse.ts +103 -0
- package/src/parser/preprocess/expr/scan.ts +34 -0
- package/src/parser/preprocess/expr/types.ts +14 -0
- package/src/parser/preprocess/index.ts +38 -0
- package/src/parser/preprocess/typography.ts +132 -0
- package/src/parser/preprocess/utils/bracket-depths.ts +98 -0
- package/src/parser/preprocess/utils/index.ts +13 -0
- package/src/parser/preprocess/utils/raw-regions.ts +153 -0
- package/src/parser/preprocess/whitespace/detection.ts +39 -0
- package/src/parser/preprocess/whitespace/index.ts +79 -0
- package/src/parser/preprocess/whitespace/leading-spaces.ts +11 -0
- package/src/parser/preprocess/whitespace/patterns.ts +23 -0
- package/src/parser/rules/block/align/body.ts +46 -0
- package/src/parser/rules/block/align/element.ts +13 -0
- package/src/parser/rules/block/align/index.ts +90 -0
- package/src/parser/rules/block/align/syntax.ts +113 -0
- package/src/parser/rules/block/bibliography/body.ts +81 -0
- package/src/parser/rules/block/bibliography/entries.ts +49 -0
- package/src/parser/rules/block/bibliography/entry-content.ts +73 -0
- package/src/parser/rules/block/bibliography/entry-key.ts +83 -0
- package/src/parser/rules/block/bibliography/index.ts +90 -0
- package/src/parser/rules/block/bibliography/open.ts +53 -0
- package/src/parser/rules/block/block-list/bare-content.ts +105 -0
- package/src/parser/rules/block/block-list/bare-paragraph.ts +60 -0
- package/src/parser/rules/block/block-list/index.ts +51 -0
- package/src/parser/rules/block/block-list/item-content.ts +132 -0
- package/src/parser/rules/block/block-list/li-content.ts +107 -0
- package/src/parser/rules/block/block-list/li-item.ts +77 -0
- package/src/parser/rules/block/block-list/list-block.ts +100 -0
- package/src/parser/rules/block/block-list/open.ts +51 -0
- package/src/parser/rules/block/block-list/tags.ts +50 -0
- package/src/parser/rules/block/blockquote/build.ts +62 -0
- package/src/parser/rules/block/blockquote/index.ts +80 -0
- package/src/parser/rules/block/blockquote/line.ts +79 -0
- package/src/parser/rules/block/blockquote/lines.ts +39 -0
- package/src/parser/rules/block/center/index.ts +72 -0
- package/src/parser/rules/block/center/open.ts +27 -0
- package/src/parser/rules/block/clear-float/index.ts +51 -0
- package/src/parser/rules/block/clear-float/syntax.ts +43 -0
- package/src/parser/rules/block/code/attributes.ts +30 -0
- package/src/parser/rules/block/code/content.ts +57 -0
- package/src/parser/rules/block/code/index.ts +100 -0
- package/src/parser/rules/block/collapsible/attributes.ts +95 -0
- package/src/parser/rules/block/collapsible/body.ts +69 -0
- package/src/parser/rules/block/collapsible/index.ts +117 -0
- package/src/parser/rules/block/collapsible/open.ts +51 -0
- package/src/parser/rules/block/collapsible/orphans.ts +31 -0
- package/src/parser/rules/block/collapsible/tags.ts +17 -0
- package/src/parser/rules/block/comment/consume.ts +37 -0
- package/src/parser/rules/block/comment/index.ts +47 -0
- package/src/parser/rules/block/content-separator/index.ts +49 -0
- package/src/parser/rules/block/content-separator/syntax.ts +33 -0
- package/src/parser/rules/block/definition-list/collect.ts +40 -0
- package/src/parser/rules/block/definition-list/index.ts +63 -0
- package/src/parser/rules/block/definition-list/item-key.ts +95 -0
- package/src/parser/rules/block/definition-list/item-value.ts +56 -0
- package/src/parser/rules/block/definition-list/items.ts +54 -0
- package/src/parser/rules/block/div/body.ts +41 -0
- package/src/parser/rules/block/div/close.ts +41 -0
- package/src/parser/rules/block/div/failed.ts +117 -0
- package/src/parser/rules/block/div/index.ts +112 -0
- package/src/parser/rules/block/div/nesting.ts +37 -0
- package/src/parser/rules/block/div/open.ts +59 -0
- package/src/parser/rules/block/div/paragraph-strip.ts +44 -0
- package/src/parser/rules/block/embed-block/content.ts +53 -0
- package/src/parser/rules/block/embed-block/index.ts +91 -0
- package/src/parser/rules/block/embed-block/open.ts +52 -0
- package/src/parser/rules/block/embed-block/tags.ts +5 -0
- package/src/parser/rules/block/footnoteblock/attributes.ts +73 -0
- package/src/parser/rules/block/footnoteblock/index.ts +82 -0
- package/src/parser/rules/block/footnoteblock/open.ts +53 -0
- package/src/parser/rules/block/heading/index.ts +87 -0
- package/src/parser/rules/block/heading/open.ts +50 -0
- package/src/parser/rules/block/heading/toc-text.ts +26 -0
- package/src/parser/rules/block/horizontal-rule/index.ts +44 -0
- package/src/parser/rules/block/horizontal-rule/syntax.ts +21 -0
- package/src/parser/rules/block/html/body.ts +114 -0
- package/src/parser/rules/block/html/diagnostics.ts +11 -0
- package/src/parser/rules/block/html/index.ts +95 -0
- package/src/parser/rules/block/html/open.ts +36 -0
- package/src/parser/rules/block/iframe/attributes.ts +106 -0
- package/src/parser/rules/block/iframe/index.ts +73 -0
- package/src/parser/rules/block/iframe/open.ts +58 -0
- package/src/parser/rules/block/iframe/source.ts +24 -0
- package/src/parser/rules/block/iframe/url.ts +38 -0
- package/src/parser/rules/block/iftags/body.ts +48 -0
- package/src/parser/rules/block/iftags/condition.ts +24 -0
- package/src/parser/rules/block/iftags/index.ts +108 -0
- package/src/parser/rules/block/include/arguments.ts +48 -0
- package/src/parser/rules/block/include/index.ts +75 -0
- package/src/parser/rules/block/include/location.ts +24 -0
- package/src/parser/rules/block/include/variables.ts +37 -0
- package/src/parser/rules/block/index.ts +127 -0
- package/src/parser/rules/block/list/index.ts +73 -0
- package/src/parser/rules/block/list/line.ts +77 -0
- package/src/parser/rules/block/list/native.ts +89 -0
- package/src/parser/rules/block/math/content.ts +54 -0
- package/src/parser/rules/block/math/index.ts +106 -0
- package/src/parser/rules/block/math/name.ts +35 -0
- package/src/parser/rules/block/module/backlinks/index.ts +31 -0
- package/src/parser/rules/block/module/backlinks/types.ts +21 -0
- package/src/parser/rules/block/module/body.ts +92 -0
- package/src/parser/rules/block/module/categories/index.ts +34 -0
- package/src/parser/rules/block/module/categories/types.ts +21 -0
- package/src/parser/rules/block/module/css/index.ts +37 -0
- package/src/parser/rules/block/module/element.ts +33 -0
- package/src/parser/rules/block/module/iftags/condition.ts +109 -0
- package/src/parser/rules/block/module/iftags/index.ts +26 -0
- package/src/parser/rules/block/module/iftags/preprocess.ts +140 -0
- package/src/parser/rules/block/module/iftags/resolve.ts +73 -0
- package/src/parser/rules/block/module/iftags/types.ts +63 -0
- package/src/parser/rules/block/module/include/directive.ts +91 -0
- package/src/parser/rules/block/module/include/index.ts +29 -0
- package/src/parser/rules/block/module/include/references.ts +42 -0
- package/src/parser/rules/block/module/include/resolve/cache.ts +44 -0
- package/src/parser/rules/block/module/include/resolve/index.ts +106 -0
- package/src/parser/rules/block/module/include/resolve/iterate.ts +202 -0
- package/src/parser/rules/block/module/include/resolve/replace.ts +31 -0
- package/src/parser/rules/block/module/include/resolve/types.ts +105 -0
- package/src/parser/rules/block/module/include/scanner.ts +121 -0
- package/src/parser/rules/block/module/index.ts +134 -0
- package/src/parser/rules/block/module/join/index.ts +34 -0
- package/src/parser/rules/block/module/join/types.ts +23 -0
- package/src/parser/rules/block/module/listpages/compiler.ts +73 -0
- package/src/parser/rules/block/module/listpages/extract.ts +76 -0
- package/src/parser/rules/block/module/listpages/extraction/listpages.ts +42 -0
- package/src/parser/rules/block/module/listpages/extraction/listusers.ts +30 -0
- package/src/parser/rules/block/module/listpages/extraction/query.ts +51 -0
- package/src/parser/rules/block/module/listpages/extraction/result.ts +18 -0
- package/src/parser/rules/block/module/listpages/extraction/template.ts +96 -0
- package/src/parser/rules/block/module/listpages/extraction/variables.ts +58 -0
- package/src/parser/rules/block/module/listpages/index.ts +83 -0
- package/src/parser/rules/block/module/listpages/normalization/date-selector.ts +53 -0
- package/src/parser/rules/block/module/listpages/normalization/numeric-selector.ts +32 -0
- package/src/parser/rules/block/module/listpages/normalization/order-parent.ts +82 -0
- package/src/parser/rules/block/module/listpages/normalization/selectors.ts +2 -0
- package/src/parser/rules/block/module/listpages/normalization/tags-category.ts +86 -0
- package/src/parser/rules/block/module/listpages/normalize.ts +74 -0
- package/src/parser/rules/block/module/listpages/parser.ts +106 -0
- package/src/parser/rules/block/module/listpages/resolution/items.ts +43 -0
- package/src/parser/rules/block/module/listpages/resolution/wrapper.ts +42 -0
- package/src/parser/rules/block/module/listpages/resolve.ts +60 -0
- package/src/parser/rules/block/module/listpages/template/format/content.ts +41 -0
- package/src/parser/rules/block/module/listpages/template/format/date.ts +116 -0
- package/src/parser/rules/block/module/listpages/template/format/index.ts +4 -0
- package/src/parser/rules/block/module/listpages/template/format/tags.ts +7 -0
- package/src/parser/rules/block/module/listpages/template/format/user.ts +9 -0
- package/src/parser/rules/block/module/listpages/template/getters/index.ts +36 -0
- package/src/parser/rules/block/module/listpages/template/getters/parameterized.ts +60 -0
- package/src/parser/rules/block/module/listpages/template/getters/simple.ts +65 -0
- package/src/parser/rules/block/module/listpages/template/getters/types.ts +3 -0
- package/src/parser/rules/block/module/listpages/template/syntax.ts +97 -0
- package/src/parser/rules/block/module/listpages/types/data-fetcher.ts +15 -0
- package/src/parser/rules/block/module/listpages/types/data-requirements.ts +52 -0
- package/src/parser/rules/block/module/listpages/types/external-data.ts +77 -0
- package/src/parser/rules/block/module/listpages/types/index.ts +17 -0
- package/src/parser/rules/block/module/listpages/types/normalized-query.ts +120 -0
- package/src/parser/rules/block/module/listpages/types/query.ts +67 -0
- package/src/parser/rules/block/module/listpages/types/template.ts +17 -0
- package/src/parser/rules/block/module/listpages/types/variables.ts +69 -0
- package/src/parser/rules/block/module/listpages/url-resolution/fields.ts +48 -0
- package/src/parser/rules/block/module/listpages/url-resolution/params.ts +19 -0
- package/src/parser/rules/block/module/listpages/url-resolution/query.ts +24 -0
- package/src/parser/rules/block/module/listpages/url-resolution/resolve.ts +53 -0
- package/src/parser/rules/block/module/listpages/url-resolution/value.ts +25 -0
- package/src/parser/rules/block/module/listpages/url-resolver.ts +29 -0
- package/src/parser/rules/block/module/listusers/compiler.ts +56 -0
- package/src/parser/rules/block/module/listusers/extract.ts +40 -0
- package/src/parser/rules/block/module/listusers/getters.ts +21 -0
- package/src/parser/rules/block/module/listusers/index.ts +36 -0
- package/src/parser/rules/block/module/listusers/parser.ts +54 -0
- package/src/parser/rules/block/module/listusers/resolve.ts +58 -0
- package/src/parser/rules/block/module/listusers/types.ts +93 -0
- package/src/parser/rules/block/module/listusers/variables.ts +15 -0
- package/src/parser/rules/block/module/mapping.ts +61 -0
- package/src/parser/rules/block/module/open.ts +57 -0
- package/src/parser/rules/block/module/page-tree/index.ts +38 -0
- package/src/parser/rules/block/module/page-tree/types.ts +29 -0
- package/src/parser/rules/block/module/rate/index.ts +28 -0
- package/src/parser/rules/block/module/rate/types.ts +19 -0
- package/src/parser/rules/block/module/resolution/contexts.ts +78 -0
- package/src/parser/rules/block/module/resolution/data-maps.ts +39 -0
- package/src/parser/rules/block/module/resolution/dynamic-modules.ts +93 -0
- package/src/parser/rules/block/module/resolution/styles.ts +53 -0
- package/src/parser/rules/block/module/resolution/walk-resolve.ts +107 -0
- package/src/parser/rules/block/module/resolve.ts +198 -0
- package/src/parser/rules/block/module/rule.ts +56 -0
- package/src/parser/rules/block/module/types-common.ts +70 -0
- package/src/parser/rules/block/module/types.ts +61 -0
- package/src/parser/rules/block/module/utils.ts +43 -0
- package/src/parser/rules/block/module/walk/children.ts +35 -0
- package/src/parser/rules/block/module/walk/index.ts +9 -0
- package/src/parser/rules/block/module/walk/map/index.ts +2 -0
- package/src/parser/rules/block/module/walk/map/stateful-definition-list.ts +25 -0
- package/src/parser/rules/block/module/walk/map/stateful-list.ts +40 -0
- package/src/parser/rules/block/module/walk/map/stateful-table.ts +23 -0
- package/src/parser/rules/block/module/walk/map/stateful-tabs.ts +19 -0
- package/src/parser/rules/block/module/walk/map/stateful.ts +71 -0
- package/src/parser/rules/block/module/walk/map/stateless-definition-list.ts +12 -0
- package/src/parser/rules/block/module/walk/map/stateless-list.ts +29 -0
- package/src/parser/rules/block/module/walk/map/stateless-table.ts +11 -0
- package/src/parser/rules/block/module/walk/map/stateless-tabs.ts +5 -0
- package/src/parser/rules/block/module/walk/map/stateless.ts +51 -0
- package/src/parser/rules/block/module/walk/map/types.ts +6 -0
- package/src/parser/rules/block/module/walk/traverse.ts +65 -0
- package/src/parser/rules/block/orphan-li/content.ts +60 -0
- package/src/parser/rules/block/orphan-li/index.ts +75 -0
- package/src/parser/rules/block/orphan-li/open.ts +25 -0
- package/src/parser/rules/block/orphan-li/tags.ts +40 -0
- package/src/parser/rules/block/paragraph/content.ts +12 -0
- package/src/parser/rules/block/paragraph/index.ts +60 -0
- package/src/parser/rules/block/paragraph/normalize.ts +52 -0
- package/src/parser/rules/block/paragraph/span-markers.ts +52 -0
- package/src/parser/rules/block/parsing/attributes/index.ts +32 -0
- package/src/parser/rules/block/parsing/attributes/names.ts +93 -0
- package/src/parser/rules/block/parsing/attributes/scanner.ts +75 -0
- package/src/parser/rules/block/parsing/attributes/values.ts +26 -0
- package/src/parser/rules/block/parsing/block-item.ts +29 -0
- package/src/parser/rules/block/parsing/content.ts +127 -0
- package/src/parser/rules/block/parsing/end-condition.ts +51 -0
- package/src/parser/rules/block/parsing/inline-content.ts +105 -0
- package/src/parser/rules/block/parsing/inline-newline.ts +41 -0
- package/src/parser/rules/block/parsing/non-boundary.ts +24 -0
- package/src/parser/rules/block/parsing/rule-dispatch.ts +44 -0
- package/src/parser/rules/block/table/index.ts +80 -0
- package/src/parser/rules/block/table/pipe/cell-start.ts +69 -0
- package/src/parser/rules/block/table/pipe/cell.ts +106 -0
- package/src/parser/rules/block/table/pipe/index.ts +2 -0
- package/src/parser/rules/block/table/pipe/row.ts +88 -0
- package/src/parser/rules/block/table/pipe/tokens.ts +14 -0
- package/src/parser/rules/block/table/pipe/trim.ts +50 -0
- package/src/parser/rules/block/table-block/body.ts +79 -0
- package/src/parser/rules/block/table-block/cell-attributes.ts +33 -0
- package/src/parser/rules/block/table-block/cell-boundary.ts +99 -0
- package/src/parser/rules/block/table-block/cell-content/index.ts +88 -0
- package/src/parser/rules/block/table-block/cell-content/segments.ts +134 -0
- package/src/parser/rules/block/table-block/cell-newline.ts +47 -0
- package/src/parser/rules/block/table-block/cell.ts +64 -0
- package/src/parser/rules/block/table-block/index.ts +113 -0
- package/src/parser/rules/block/table-block/row-boundary.ts +75 -0
- package/src/parser/rules/block/table-block/structure.ts +80 -0
- package/src/parser/rules/block/tabview/body.ts +64 -0
- package/src/parser/rules/block/tabview/index.ts +90 -0
- package/src/parser/rules/block/tabview/open.ts +50 -0
- package/src/parser/rules/block/tabview/tab.ts +92 -0
- package/src/parser/rules/block/tabview/tags.ts +30 -0
- package/src/parser/rules/block/toc/element.ts +11 -0
- package/src/parser/rules/block/toc/index.ts +44 -0
- package/src/parser/rules/block/toc/open.ts +84 -0
- package/src/parser/rules/block/utils.ts +15 -0
- package/src/parser/rules/common/attribute-safety.ts +109 -0
- package/src/parser/rules/common/block-name.ts +33 -0
- package/src/parser/rules/common/index.ts +2 -0
- package/src/parser/rules/contracts/index.ts +3 -0
- package/src/parser/rules/contracts/parse-context.ts +38 -0
- package/src/parser/rules/contracts/rule.ts +43 -0
- package/src/parser/rules/contracts/scope.ts +31 -0
- package/src/parser/rules/index.ts +49 -0
- package/src/parser/rules/inline/anchor/attributes.ts +54 -0
- package/src/parser/rules/inline/anchor/child.ts +26 -0
- package/src/parser/rules/inline/anchor/close.ts +34 -0
- package/src/parser/rules/inline/anchor/content.ts +59 -0
- package/src/parser/rules/inline/anchor/index.ts +103 -0
- package/src/parser/rules/inline/anchor/newline.ts +26 -0
- package/src/parser/rules/inline/anchor/open.ts +47 -0
- package/src/parser/rules/inline/anchor/paragraph-strip.ts +14 -0
- package/src/parser/rules/inline/anchor/syntax.ts +40 -0
- package/src/parser/rules/inline/anchor-name/index.ts +38 -0
- package/src/parser/rules/inline/anchor-name/name.ts +39 -0
- package/src/parser/rules/inline/anchor-name/syntax.ts +46 -0
- package/src/parser/rules/inline/bibcite/element.ts +14 -0
- package/src/parser/rules/inline/bibcite/index.ts +34 -0
- package/src/parser/rules/inline/bibcite/syntax.ts +64 -0
- package/src/parser/rules/inline/bold.ts +49 -0
- package/src/parser/rules/inline/color/index.ts +35 -0
- package/src/parser/rules/inline/color/syntax.ts +69 -0
- package/src/parser/rules/inline/comment/consume.ts +31 -0
- package/src/parser/rules/inline/comment/index.ts +64 -0
- package/src/parser/rules/inline/equation-ref/element.ts +8 -0
- package/src/parser/rules/inline/equation-ref/index.ts +34 -0
- package/src/parser/rules/inline/equation-ref/syntax.ts +45 -0
- package/src/parser/rules/inline/expr/branch.ts +104 -0
- package/src/parser/rules/inline/expr/conditional-branch.ts +27 -0
- package/src/parser/rules/inline/expr/conditional.ts +80 -0
- package/src/parser/rules/inline/expr/depth.ts +25 -0
- package/src/parser/rules/inline/expr/elements.ts +39 -0
- package/src/parser/rules/inline/expr/index.ts +84 -0
- package/src/parser/rules/inline/expr/syntax.ts +45 -0
- package/src/parser/rules/inline/footnote/child.ts +22 -0
- package/src/parser/rules/inline/footnote/close.ts +33 -0
- package/src/parser/rules/inline/footnote/content.ts +54 -0
- package/src/parser/rules/inline/footnote/elements.ts +38 -0
- package/src/parser/rules/inline/footnote/index.ts +54 -0
- package/src/parser/rules/inline/footnote/newline.ts +27 -0
- package/src/parser/rules/inline/footnote/open.ts +38 -0
- package/src/parser/rules/inline/formatting/container.ts +50 -0
- package/src/parser/rules/inline/guillemet/index.ts +56 -0
- package/src/parser/rules/inline/guillemet/text.ts +11 -0
- package/src/parser/rules/inline/html/gate.ts +64 -0
- package/src/parser/rules/inline/html/index.ts +81 -0
- package/src/parser/rules/inline/html/open.ts +37 -0
- package/src/parser/rules/inline/image/attributes.ts +22 -0
- package/src/parser/rules/inline/image/body.ts +36 -0
- package/src/parser/rules/inline/image/index.ts +89 -0
- package/src/parser/rules/inline/image/open.ts +56 -0
- package/src/parser/rules/inline/image/source.ts +62 -0
- package/src/parser/rules/inline/image/syntax.ts +76 -0
- package/src/parser/rules/inline/index.ts +150 -0
- package/src/parser/rules/inline/italic.ts +46 -0
- package/src/parser/rules/inline/line-break/backslash.ts +58 -0
- package/src/parser/rules/inline/line-break/elements.ts +9 -0
- package/src/parser/rules/inline/line-break/index.ts +3 -0
- package/src/parser/rules/inline/line-break/newline.ts +82 -0
- package/src/parser/rules/inline/line-break/underscore.ts +45 -0
- package/src/parser/rules/inline/link-anchor.ts +72 -0
- package/src/parser/rules/inline/link-bracket/anchor.ts +3 -0
- package/src/parser/rules/inline/link-bracket/direct-url.ts +5 -0
- package/src/parser/rules/inline/link-bracket/parsed.ts +81 -0
- package/src/parser/rules/inline/link-bracket/parts.ts +64 -0
- package/src/parser/rules/inline/link-bracket/prefix.ts +15 -0
- package/src/parser/rules/inline/link-single.ts +73 -0
- package/src/parser/rules/inline/link-star.ts +72 -0
- package/src/parser/rules/inline/link-triple/fallback.ts +10 -0
- package/src/parser/rules/inline/link-triple/index.ts +62 -0
- package/src/parser/rules/inline/link-triple/interwiki.ts +11 -0
- package/src/parser/rules/inline/link-triple/label.ts +35 -0
- package/src/parser/rules/inline/link-triple/syntax.ts +72 -0
- package/src/parser/rules/inline/link-triple/target.ts +36 -0
- package/src/parser/rules/inline/math-inline/index.ts +40 -0
- package/src/parser/rules/inline/math-inline/syntax.ts +55 -0
- package/src/parser/rules/inline/monospace.ts +50 -0
- package/src/parser/rules/inline/parsing/block-boundary.ts +42 -0
- package/src/parser/rules/inline/parsing/block-start-predicates.ts +117 -0
- package/src/parser/rules/inline/parsing/collect.ts +23 -0
- package/src/parser/rules/inline/parsing/inline-content.ts +115 -0
- package/src/parser/rules/inline/parsing/paragraph-boundary.ts +47 -0
- package/src/parser/rules/inline/parsing/plain-text.ts +69 -0
- package/src/parser/rules/inline/parsing/preserved-line-break.ts +11 -0
- package/src/parser/rules/inline/parsing/rules.ts +34 -0
- package/src/parser/rules/inline/parsing/simple-token.ts +26 -0
- package/src/parser/rules/inline/raw/angle.ts +40 -0
- package/src/parser/rules/inline/raw/double-at.ts +78 -0
- package/src/parser/rules/inline/raw/index.ts +26 -0
- package/src/parser/rules/inline/raw/result.ts +26 -0
- package/src/parser/rules/inline/size/content.ts +65 -0
- package/src/parser/rules/inline/size/index.ts +55 -0
- package/src/parser/rules/inline/size/open.ts +43 -0
- package/src/parser/rules/inline/size/value.ts +45 -0
- package/src/parser/rules/inline/span/content.ts +97 -0
- package/src/parser/rules/inline/span/elements.ts +108 -0
- package/src/parser/rules/inline/span/index.ts +79 -0
- package/src/parser/rules/inline/span/newline.ts +50 -0
- package/src/parser/rules/inline/span/syntax.ts +70 -0
- package/src/parser/rules/inline/strikethrough/index.ts +60 -0
- package/src/parser/rules/inline/strikethrough/parse.ts +14 -0
- package/src/parser/rules/inline/strikethrough/syntax.ts +24 -0
- package/src/parser/rules/inline/subscript.ts +47 -0
- package/src/parser/rules/inline/superscript.ts +49 -0
- package/src/parser/rules/inline/text/element.ts +5 -0
- package/src/parser/rules/inline/text/index.ts +85 -0
- package/src/parser/rules/inline/underline/child.ts +26 -0
- package/src/parser/rules/inline/underline/content.ts +29 -0
- package/src/parser/rules/inline/underline/index.ts +84 -0
- package/src/parser/rules/inline/user/element.ts +11 -0
- package/src/parser/rules/inline/user/index.ts +34 -0
- package/src/parser/rules/inline/user/syntax.ts +67 -0
- package/src/parser/rules/inline/utils.ts +4 -0
- package/src/parser/rules/tokens.ts +106 -0
- package/src/parser/rules/types.ts +9 -0
- package/src/parser/toc.ts +130 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* Provides the two lowest-priority inline rules: `textRule` and `fallbackRule`.
|
|
4
|
+
*
|
|
5
|
+
* These rules act as catch-alls that convert unrecognized tokens into
|
|
6
|
+
* plain `"text"` AST elements, ensuring no token is ever silently dropped
|
|
7
|
+
* during inline parsing.
|
|
8
|
+
*
|
|
9
|
+
* `textRule` handles `TEXT` and `WHITESPACE` tokens specifically and is
|
|
10
|
+
* included in the main `inlineRules` array as the last entry before
|
|
11
|
+
* the fallback.
|
|
12
|
+
*
|
|
13
|
+
* `fallbackRule` has an empty `startTokens` array, which means it matches
|
|
14
|
+
* ANY token type. It is exported separately as `inlineFallbackRule` and
|
|
15
|
+
* is NOT included in the `inlineRules` array to prevent it from
|
|
16
|
+
* short-circuiting more specific rules. Instead, it is invoked explicitly
|
|
17
|
+
* by the parser when no other rule matches.
|
|
18
|
+
*
|
|
19
|
+
* @module
|
|
20
|
+
*/
|
|
21
|
+
import type { Element } from "@wdprlib/ast";
|
|
22
|
+
import type { InlineRule, ParseContext, RuleResult } from "../../types";
|
|
23
|
+
import { currentToken } from "../../types";
|
|
24
|
+
import { textElement } from "./element";
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Inline rule for plain text and whitespace tokens.
|
|
28
|
+
*
|
|
29
|
+
* Matches `TEXT` and `WHITESPACE` token types and converts them
|
|
30
|
+
* directly to `"text"` AST elements. This rule always succeeds.
|
|
31
|
+
*
|
|
32
|
+
* Placed last (before the fallback) in the inline rules array so
|
|
33
|
+
* that all formatting and structural rules are tried first.
|
|
34
|
+
*/
|
|
35
|
+
export const textRule: InlineRule = {
|
|
36
|
+
name: "text",
|
|
37
|
+
startTokens: ["TEXT", "WHITESPACE"],
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Converts a TEXT or WHITESPACE token into a text element.
|
|
41
|
+
*
|
|
42
|
+
* @param ctx - Parse context with token stream and current position
|
|
43
|
+
* @returns Always returns `{ success: true }` with a single `"text"` element
|
|
44
|
+
*/
|
|
45
|
+
parse(ctx: ParseContext): RuleResult<Element> {
|
|
46
|
+
const token = currentToken(ctx);
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
success: true,
|
|
50
|
+
elements: [textElement(token.value)],
|
|
51
|
+
consumed: 1,
|
|
52
|
+
};
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Universal fallback rule for any token type not matched by other rules.
|
|
58
|
+
*
|
|
59
|
+
* The empty `startTokens` array signals to the parser that this rule
|
|
60
|
+
* can match any token. It converts the token's value to a `"text"`
|
|
61
|
+
* element, ensuring no token is silently dropped.
|
|
62
|
+
*
|
|
63
|
+
* This rule is used as a last-resort handler and is intentionally
|
|
64
|
+
* excluded from the main `inlineRules` array.
|
|
65
|
+
*/
|
|
66
|
+
export const fallbackRule: InlineRule = {
|
|
67
|
+
name: "fallback",
|
|
68
|
+
startTokens: [], // matches anything not matched by other rules
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Converts any unrecognized token into a text element.
|
|
72
|
+
*
|
|
73
|
+
* @param ctx - Parse context with token stream and current position
|
|
74
|
+
* @returns Always returns `{ success: true }` with a single `"text"` element
|
|
75
|
+
*/
|
|
76
|
+
parse(ctx: ParseContext): RuleResult<Element> {
|
|
77
|
+
const token = currentToken(ctx);
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
success: true,
|
|
81
|
+
elements: [textElement(token.value)],
|
|
82
|
+
consumed: 1,
|
|
83
|
+
};
|
|
84
|
+
},
|
|
85
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Element } from "@wdprlib/ast";
|
|
2
|
+
import type { ParseContext } from "../../types";
|
|
3
|
+
import { parseInlineUntil } from "../utils";
|
|
4
|
+
|
|
5
|
+
export interface UnderlineChildResult {
|
|
6
|
+
elements: Element[];
|
|
7
|
+
consumed: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function parseUnderlineChild(ctx: ParseContext, pos: number): UnderlineChildResult {
|
|
11
|
+
const token = ctx.tokens[pos];
|
|
12
|
+
if (!token) {
|
|
13
|
+
return { elements: [], consumed: 0 };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (token.type === "NEWLINE") {
|
|
17
|
+
return { elements: [{ element: "line-break" }], consumed: 1 };
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const result = parseInlineUntil({ ...ctx, pos }, "UNDERLINE_MARKER");
|
|
21
|
+
if (result.elements.length > 0) {
|
|
22
|
+
return { elements: result.elements, consumed: result.consumed };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return { elements: [{ element: "text", data: token.value }], consumed: 1 };
|
|
26
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Element } from "@wdprlib/ast";
|
|
2
|
+
import type { ParseContext } from "../../types";
|
|
3
|
+
import { parseUnderlineChild } from "./child";
|
|
4
|
+
|
|
5
|
+
export function parseUnderlineContent(
|
|
6
|
+
ctx: ParseContext,
|
|
7
|
+
startPos: number,
|
|
8
|
+
): { children: Element[]; consumed: number } {
|
|
9
|
+
const children: Element[] = [];
|
|
10
|
+
let pos = startPos;
|
|
11
|
+
let consumed = 1;
|
|
12
|
+
|
|
13
|
+
while (pos < ctx.tokens.length) {
|
|
14
|
+
const token = ctx.tokens[pos];
|
|
15
|
+
if (!token || token.type === "EOF") break;
|
|
16
|
+
|
|
17
|
+
if (token.type === "UNDERLINE_MARKER") {
|
|
18
|
+
consumed++;
|
|
19
|
+
break;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const child = parseUnderlineChild(ctx, pos);
|
|
23
|
+
children.push(...child.elements);
|
|
24
|
+
pos += child.consumed;
|
|
25
|
+
consumed += child.consumed;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return { children, consumed };
|
|
29
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* Parses the Wikidot underline formatting syntax: `__text__`.
|
|
4
|
+
*
|
|
5
|
+
* Underline text is delimited by double underscores. Unlike most
|
|
6
|
+
* inline formatting markers (bold, italic, etc.) which require the
|
|
7
|
+
* closing marker on the same line, underline markers can span
|
|
8
|
+
* multiple lines within the same paragraph. The closing marker
|
|
9
|
+
* must appear before a paragraph break (blank line).
|
|
10
|
+
*
|
|
11
|
+
* Single newlines within underlined content are converted to
|
|
12
|
+
* `<br />` elements, matching Wikidot's multiline underline behavior.
|
|
13
|
+
*
|
|
14
|
+
* If no closing `__` is found before a paragraph break, the opening
|
|
15
|
+
* marker is emitted as literal text.
|
|
16
|
+
*
|
|
17
|
+
* Empty underline (`____`) is silently discarded by Wikidot (produces
|
|
18
|
+
* no output).
|
|
19
|
+
*
|
|
20
|
+
* Renders as a `<u>` element in HTML.
|
|
21
|
+
*
|
|
22
|
+
* Produces a `"container"` AST element with `type: "underline"`.
|
|
23
|
+
*
|
|
24
|
+
* @module
|
|
25
|
+
*/
|
|
26
|
+
import type { Element } from "@wdprlib/ast";
|
|
27
|
+
import type { InlineRule, ParseContext, RuleResult } from "../../types";
|
|
28
|
+
import { currentToken, hasClosingMarkerBeforeParagraphBreak } from "../../types";
|
|
29
|
+
import { createInlineContainer } from "../formatting/container";
|
|
30
|
+
import { parseUnderlineContent } from "./content";
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Inline rule for parsing `__underline__` formatting.
|
|
34
|
+
*
|
|
35
|
+
* Triggered by an `UNDERLINE_MARKER` token (`__`). Uses
|
|
36
|
+
* {@link hasClosingMarkerBeforeParagraphBreak} instead of the
|
|
37
|
+
* single-line variant because Wikidot allows underline to span
|
|
38
|
+
* multiple lines within a paragraph.
|
|
39
|
+
*
|
|
40
|
+
* When no closing marker is found before a paragraph break, the
|
|
41
|
+
* opening `__` is treated as literal text.
|
|
42
|
+
*/
|
|
43
|
+
export const underlineRule: InlineRule = {
|
|
44
|
+
name: "underline",
|
|
45
|
+
startTokens: ["UNDERLINE_MARKER"],
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Attempts to parse underline formatting at the current position.
|
|
49
|
+
*
|
|
50
|
+
* @param ctx - Parse context with token stream and current position
|
|
51
|
+
* @returns A successful result containing either a `"container"` element
|
|
52
|
+
* with `type: "underline"`, an empty array (for `____`), or a
|
|
53
|
+
* text fallback for unmatched markers
|
|
54
|
+
*/
|
|
55
|
+
parse(ctx: ParseContext): RuleResult<Element> {
|
|
56
|
+
const startToken = currentToken(ctx);
|
|
57
|
+
|
|
58
|
+
// Check if closing marker exists before paragraph break
|
|
59
|
+
if (!hasClosingMarkerBeforeParagraphBreak({ ...ctx, pos: ctx.pos + 1 }, "UNDERLINE_MARKER")) {
|
|
60
|
+
return {
|
|
61
|
+
success: true,
|
|
62
|
+
elements: [{ element: "text", data: startToken.value }],
|
|
63
|
+
consumed: 1,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const { children, consumed } = parseUnderlineContent(ctx, ctx.pos + 1);
|
|
68
|
+
|
|
69
|
+
// Empty underline (____) is discarded entirely in Wikidot
|
|
70
|
+
if (children.length === 0) {
|
|
71
|
+
return {
|
|
72
|
+
success: true,
|
|
73
|
+
elements: [],
|
|
74
|
+
consumed,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
success: true,
|
|
80
|
+
elements: [createInlineContainer("underline", children)],
|
|
81
|
+
consumed,
|
|
82
|
+
};
|
|
83
|
+
},
|
|
84
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* Parses the Wikidot user reference syntax: `[[user name]]` and `[[*user name]]`.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
import type { Element } from "@wdprlib/ast";
|
|
8
|
+
import type { InlineRule, ParseContext, RuleResult } from "../../types";
|
|
9
|
+
import { currentToken } from "../../types";
|
|
10
|
+
import { userElement } from "./element";
|
|
11
|
+
import { parseUserReference } from "./syntax";
|
|
12
|
+
|
|
13
|
+
export const userRule: InlineRule = {
|
|
14
|
+
name: "user",
|
|
15
|
+
startTokens: ["BLOCK_OPEN"],
|
|
16
|
+
|
|
17
|
+
parse(ctx: ParseContext): RuleResult<Element> {
|
|
18
|
+
const openToken = currentToken(ctx);
|
|
19
|
+
if (openToken.type !== "BLOCK_OPEN") {
|
|
20
|
+
return { success: false };
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const parsed = parseUserReference(ctx, ctx.pos + 1);
|
|
24
|
+
if (!parsed) {
|
|
25
|
+
return { success: false };
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
success: true,
|
|
30
|
+
elements: [userElement(parsed.name, parsed.showAvatar)],
|
|
31
|
+
consumed: 1 + parsed.consumed,
|
|
32
|
+
};
|
|
33
|
+
},
|
|
34
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { ParseContext } from "../../types";
|
|
2
|
+
|
|
3
|
+
export function parseUserReference(
|
|
4
|
+
ctx: ParseContext,
|
|
5
|
+
startPos: number,
|
|
6
|
+
): { name: string; showAvatar: boolean; consumed: number } | null {
|
|
7
|
+
let pos = startPos;
|
|
8
|
+
let consumed = 0;
|
|
9
|
+
|
|
10
|
+
if (ctx.tokens[pos]?.type === "WHITESPACE") {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let showAvatar = false;
|
|
15
|
+
if (ctx.tokens[pos]?.type === "STAR") {
|
|
16
|
+
showAvatar = true;
|
|
17
|
+
pos++;
|
|
18
|
+
consumed++;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
while (ctx.tokens[pos]?.type === "WHITESPACE") {
|
|
22
|
+
pos++;
|
|
23
|
+
consumed++;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const nameToken = ctx.tokens[pos];
|
|
27
|
+
if (!nameToken || (nameToken.type !== "TEXT" && nameToken.type !== "IDENTIFIER")) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
if (nameToken.value.toLowerCase() !== "user") {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
pos++;
|
|
34
|
+
consumed++;
|
|
35
|
+
|
|
36
|
+
while (ctx.tokens[pos]?.type === "WHITESPACE") {
|
|
37
|
+
pos++;
|
|
38
|
+
consumed++;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
let username = "";
|
|
42
|
+
while (pos < ctx.tokens.length) {
|
|
43
|
+
const token = ctx.tokens[pos];
|
|
44
|
+
if (
|
|
45
|
+
!token ||
|
|
46
|
+
token.type === "BLOCK_CLOSE" ||
|
|
47
|
+
token.type === "NEWLINE" ||
|
|
48
|
+
token.type === "EOF"
|
|
49
|
+
) {
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
username += token.value;
|
|
53
|
+
pos++;
|
|
54
|
+
consumed++;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
username = username.trim();
|
|
58
|
+
if (!username || ctx.tokens[pos]?.type !== "BLOCK_CLOSE") {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
name: username,
|
|
64
|
+
showAvatar,
|
|
65
|
+
consumed: consumed + 1,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import type { Token, TokenType } from "../../lexer";
|
|
2
|
+
import type { ParseContext } from "./contracts";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Helper to get current token
|
|
6
|
+
*/
|
|
7
|
+
export function currentToken(ctx: ParseContext): Token {
|
|
8
|
+
return ctx.tokens[ctx.pos] ?? eofToken();
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Helper to peek ahead
|
|
13
|
+
*/
|
|
14
|
+
export function peekToken(ctx: ParseContext, n = 1): Token {
|
|
15
|
+
return ctx.tokens[ctx.pos + n] ?? eofToken();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Helper to check token type
|
|
20
|
+
*/
|
|
21
|
+
export function checkToken(ctx: ParseContext, type: TokenType): boolean {
|
|
22
|
+
return currentToken(ctx).type === type;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Helper to check if at end
|
|
27
|
+
*/
|
|
28
|
+
export function isAtEnd(ctx: ParseContext): boolean {
|
|
29
|
+
return ctx.pos >= ctx.tokens.length || currentToken(ctx).type === "EOF";
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Create EOF token
|
|
34
|
+
*/
|
|
35
|
+
function eofToken(): Token {
|
|
36
|
+
return {
|
|
37
|
+
type: "EOF",
|
|
38
|
+
value: "",
|
|
39
|
+
position: { start: { line: 0, column: 0, offset: 0 }, end: { line: 0, column: 0, offset: 0 } },
|
|
40
|
+
lineStart: false,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Check if closing marker exists before newline.
|
|
46
|
+
* If markerValue is provided, also check that the token value matches.
|
|
47
|
+
*/
|
|
48
|
+
export function hasClosingMarkerBeforeNewline(
|
|
49
|
+
ctx: ParseContext,
|
|
50
|
+
markerType: TokenType,
|
|
51
|
+
markerValue?: string,
|
|
52
|
+
): boolean {
|
|
53
|
+
let pos = ctx.pos;
|
|
54
|
+
while (pos < ctx.tokens.length) {
|
|
55
|
+
const token = ctx.tokens[pos];
|
|
56
|
+
if (!token || token.type === "NEWLINE" || token.type === "EOF") {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
if (token.type === markerType) {
|
|
60
|
+
if (markerValue === undefined || token.value === markerValue) {
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
pos++;
|
|
65
|
+
}
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Check if closing marker exists before paragraph break (double newline).
|
|
71
|
+
* Allows inline formatting to span multiple lines within a paragraph.
|
|
72
|
+
*/
|
|
73
|
+
export function hasClosingMarkerBeforeParagraphBreak(
|
|
74
|
+
ctx: ParseContext,
|
|
75
|
+
markerType: TokenType,
|
|
76
|
+
markerValue?: string,
|
|
77
|
+
): boolean {
|
|
78
|
+
let pos = ctx.pos;
|
|
79
|
+
while (pos < ctx.tokens.length) {
|
|
80
|
+
const token = ctx.tokens[pos];
|
|
81
|
+
if (!token || token.type === "EOF") {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
// Check for paragraph break (NEWLINE followed by NEWLINE after optional whitespace)
|
|
85
|
+
if (token.type === "NEWLINE") {
|
|
86
|
+
let lookAhead = 1;
|
|
87
|
+
while (ctx.tokens[pos + lookAhead]?.type === "WHITESPACE") {
|
|
88
|
+
lookAhead++;
|
|
89
|
+
}
|
|
90
|
+
if (
|
|
91
|
+
ctx.tokens[pos + lookAhead]?.type === "NEWLINE" ||
|
|
92
|
+
ctx.tokens[pos + lookAhead]?.type === "EOF" ||
|
|
93
|
+
!ctx.tokens[pos + lookAhead]
|
|
94
|
+
) {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (token.type === markerType) {
|
|
99
|
+
if (markerValue === undefined || token.value === markerValue) {
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
pos++;
|
|
104
|
+
}
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* Table of Contents (TOC) generation for Wikidot markup.
|
|
4
|
+
*
|
|
5
|
+
* Converts a flat array of `TocEntry` items (collected from heading elements
|
|
6
|
+
* during parsing) into nested bullet-list `Element` nodes suitable for rendering
|
|
7
|
+
* as `[[toc]]`. Uses the depth module to transform flat heading levels (h1-h6)
|
|
8
|
+
* into a properly nested list hierarchy.
|
|
9
|
+
*
|
|
10
|
+
* Each TOC entry becomes an anchor link (`#toc0`, `#toc1`, ...) pointing to the
|
|
11
|
+
* corresponding heading in the rendered page, matching Wikidot's original
|
|
12
|
+
* anchor naming scheme.
|
|
13
|
+
*
|
|
14
|
+
* @module
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import type { Element, TocEntry, ListItem } from "@wdprlib/ast";
|
|
18
|
+
import { processDepths, type DepthList, type DepthItem } from "./depth";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Sequential counter for generating unique TOC anchor IDs.
|
|
22
|
+
*
|
|
23
|
+
* Wikidot assigns sequential `#toc0`, `#toc1`, ... anchors to headings in
|
|
24
|
+
* document order. This class maintains a monotonically increasing counter
|
|
25
|
+
* that is shared across all TOC trees to ensure globally unique anchors.
|
|
26
|
+
*/
|
|
27
|
+
class TocIndexer {
|
|
28
|
+
private index = 0;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Returns the next sequential index and advances the counter.
|
|
32
|
+
* @returns The current index value (0-based) before incrementing
|
|
33
|
+
*/
|
|
34
|
+
next(): number {
|
|
35
|
+
return this.index++;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Build a nested bullet-list Element from depth-processed TOC items.
|
|
41
|
+
*
|
|
42
|
+
* Each item in the depth list is converted to a `ListItem`, with nested lists
|
|
43
|
+
* becoming sub-list items and leaf items becoming anchor links.
|
|
44
|
+
*
|
|
45
|
+
* @param indexer - Shared counter for generating sequential `#tocN` anchors
|
|
46
|
+
* @param items - Depth-processed list of heading text strings
|
|
47
|
+
* @returns A `list` Element with type "bullet" containing the TOC hierarchy
|
|
48
|
+
*/
|
|
49
|
+
function buildTocList(indexer: TocIndexer, items: DepthList<null, string>): Element {
|
|
50
|
+
const listItems: ListItem[] = items.map((item) => buildTocListItem(indexer, item));
|
|
51
|
+
|
|
52
|
+
return {
|
|
53
|
+
element: "list",
|
|
54
|
+
data: {
|
|
55
|
+
type: "bullet",
|
|
56
|
+
attributes: {},
|
|
57
|
+
items: listItems,
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Build a single TOC list item from a depth item.
|
|
64
|
+
*
|
|
65
|
+
* For leaf items, creates an anchor link element with a `#tocN` href.
|
|
66
|
+
* For nested list items, recursively builds a sub-list.
|
|
67
|
+
*
|
|
68
|
+
* @param indexer - Shared counter for generating sequential `#tocN` anchors
|
|
69
|
+
* @param item - A single depth item (either a leaf heading or a nested list)
|
|
70
|
+
* @returns A `ListItem` for inclusion in the TOC list
|
|
71
|
+
*/
|
|
72
|
+
function buildTocListItem(indexer: TocIndexer, item: DepthItem<null, string>): ListItem {
|
|
73
|
+
if (item.kind === "list") {
|
|
74
|
+
return {
|
|
75
|
+
"item-type": "sub-list",
|
|
76
|
+
element: "list",
|
|
77
|
+
data: {
|
|
78
|
+
type: "bullet",
|
|
79
|
+
attributes: {},
|
|
80
|
+
items: item.children.map((child) => buildTocListItem(indexer, child)),
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// item.kind === "item"
|
|
86
|
+
const anchor = `#toc${indexer.next()}`;
|
|
87
|
+
const linkElement: Element = {
|
|
88
|
+
element: "link",
|
|
89
|
+
data: {
|
|
90
|
+
type: "table-of-contents",
|
|
91
|
+
link: anchor,
|
|
92
|
+
extra: null,
|
|
93
|
+
label: { text: item.value },
|
|
94
|
+
target: null,
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
return {
|
|
99
|
+
"item-type": "elements",
|
|
100
|
+
attributes: {},
|
|
101
|
+
elements: [linkElement],
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Convert flat TocEntry[] to nested List elements
|
|
107
|
+
*
|
|
108
|
+
* @param entries - Flat list of TOC entries with level and text
|
|
109
|
+
* @returns Array of List elements (usually one, but can be multiple if levels reset)
|
|
110
|
+
*/
|
|
111
|
+
export function buildTableOfContents(entries: TocEntry[]): Element[] {
|
|
112
|
+
if (entries.length === 0) {
|
|
113
|
+
return [];
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Convert entries to depth-annotated items
|
|
117
|
+
// level is 1-based (h1=1, h2=2, ...), convert to 0-based depth
|
|
118
|
+
const depthItems = entries.map((entry) => ({
|
|
119
|
+
depth: entry.level - 1,
|
|
120
|
+
ltype: null as null, // We don't differentiate list types for TOC
|
|
121
|
+
value: entry.text,
|
|
122
|
+
}));
|
|
123
|
+
|
|
124
|
+
// Process into nested structure
|
|
125
|
+
const trees = processDepths<null, string>(null, depthItems);
|
|
126
|
+
|
|
127
|
+
// Build List elements from each tree
|
|
128
|
+
const indexer = new TocIndexer();
|
|
129
|
+
return trees.map((tree) => buildTocList(indexer, tree.list));
|
|
130
|
+
}
|