@wdprlib/parser 3.2.0 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +10471 -8406
- package/dist/index.d.cts +313 -337
- package/dist/index.d.ts +313 -337
- package/dist/index.js +10457 -8392
- package/package.json +1 -1
- package/src/index.ts +7 -0
- package/src/lexer/anchor.ts +48 -0
- package/src/lexer/index.ts +3 -2
- package/src/lexer/lexer.ts +73 -559
- 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/parser/constants.ts +2 -0
- package/src/parser/depth/index.ts +111 -0
- package/src/parser/depth/stack.ts +82 -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 +1 -1
- 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/typography.ts +70 -5
- 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.ts → center/index.ts} +7 -22
- package/src/parser/rules/block/center/open.ts +27 -0
- package/src/parser/rules/block/{clear-float.ts → clear-float/index.ts} +6 -30
- 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.ts → comment/index.ts} +12 -38
- package/src/parser/rules/block/{content-separator.ts → content-separator/index.ts} +5 -35
- 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.ts → horizontal-rule/index.ts} +4 -21
- 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.ts → iftags/index.ts} +16 -58
- 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/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/body.ts +92 -0
- package/src/parser/rules/block/module/element.ts +33 -0
- package/src/parser/rules/block/module/include/directive.ts +91 -0
- package/src/parser/rules/block/module/include/index.ts +11 -2
- 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 +14 -2
- package/src/parser/rules/block/module/listpages/compiler.ts +12 -392
- package/src/parser/rules/block/module/listpages/extract.ts +25 -359
- 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/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 +8 -324
- 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 +5 -75
- 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 +30 -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 +62 -0
- package/src/parser/rules/block/module/listpages/url-resolution/value.ts +34 -0
- package/src/parser/rules/block/module/listpages/url-resolver.ts +3 -160
- package/src/parser/rules/block/module/listusers/compiler.ts +4 -25
- package/src/parser/rules/block/module/listusers/extract.ts +4 -9
- package/src/parser/rules/block/module/listusers/getters.ts +21 -0
- package/src/parser/rules/block/module/listusers/variables.ts +15 -0
- package/src/parser/rules/block/module/open.ts +57 -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 +79 -292
- package/src/parser/rules/block/module/rule.ts +56 -0
- package/src/parser/rules/block/module/types-common.ts +11 -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 +10 -610
- package/src/parser/rules/{utils.ts → common/attribute-safety.ts} +3 -49
- 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/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 +2 -39
- 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.ts → comment/index.ts} +10 -36
- 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.ts → guillemet/index.ts} +5 -13
- 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.ts → html/index.ts} +9 -60
- 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/italic.ts +2 -30
- 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 +6 -81
- 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 +7 -98
- package/src/parser/rules/inline/link-star.ts +7 -69
- 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 +2 -30
- 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.ts → strikethrough/index.ts} +5 -60
- 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 +2 -39
- package/src/parser/rules/inline/superscript.ts +4 -39
- package/src/parser/rules/inline/text/element.ts +5 -0
- package/src/parser/rules/inline/{text.ts → text/index.ts} +5 -4
- 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.ts → underline/index.ts} +6 -49
- 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 -344
- package/src/parser/rules/tokens.ts +106 -0
- package/src/parser/rules/types.ts +9 -252
- package/src/parser/depth.ts +0 -251
- package/src/parser/parse.ts +0 -315
- package/src/parser/postprocess/spanStrip.ts +0 -697
- package/src/parser/preprocess/expr.ts +0 -265
- package/src/parser/preprocess/utils.ts +0 -250
- package/src/parser/preprocess/whitespace.ts +0 -111
- package/src/parser/rules/block/align.ts +0 -282
- package/src/parser/rules/block/bibliography.ts +0 -359
- package/src/parser/rules/block/block-list.ts +0 -689
- package/src/parser/rules/block/blockquote.ts +0 -238
- package/src/parser/rules/block/code.ts +0 -187
- package/src/parser/rules/block/collapsible.ts +0 -337
- package/src/parser/rules/block/definition-list.ts +0 -270
- package/src/parser/rules/block/div.ts +0 -400
- package/src/parser/rules/block/embed-block.ts +0 -153
- package/src/parser/rules/block/footnoteblock.ts +0 -200
- package/src/parser/rules/block/heading.ts +0 -142
- package/src/parser/rules/block/html.ts +0 -222
- package/src/parser/rules/block/iframe.ts +0 -239
- package/src/parser/rules/block/include.ts +0 -179
- package/src/parser/rules/block/list.ts +0 -244
- package/src/parser/rules/block/math.ts +0 -183
- package/src/parser/rules/block/module/include/resolve.ts +0 -556
- package/src/parser/rules/block/module/listpages/types.ts +0 -513
- package/src/parser/rules/block/module/walk.ts +0 -380
- package/src/parser/rules/block/module.ts +0 -164
- package/src/parser/rules/block/orphan-li.ts +0 -177
- package/src/parser/rules/block/paragraph.ts +0 -157
- package/src/parser/rules/block/table-block.ts +0 -726
- package/src/parser/rules/block/table.ts +0 -441
- package/src/parser/rules/block/tabview.ts +0 -331
- package/src/parser/rules/block/toc.ts +0 -129
- package/src/parser/rules/inline/anchor-name.ts +0 -154
- package/src/parser/rules/inline/anchor.ts +0 -327
- package/src/parser/rules/inline/bibcite.ts +0 -153
- package/src/parser/rules/inline/color.ts +0 -140
- package/src/parser/rules/inline/equation-ref.ts +0 -115
- package/src/parser/rules/inline/expr.ts +0 -526
- package/src/parser/rules/inline/footnote.ts +0 -223
- package/src/parser/rules/inline/image.ts +0 -328
- package/src/parser/rules/inline/line-break.ts +0 -326
- package/src/parser/rules/inline/link-triple.ts +0 -267
- package/src/parser/rules/inline/math-inline.ts +0 -126
- package/src/parser/rules/inline/raw.ts +0 -262
- package/src/parser/rules/inline/size.ts +0 -244
- package/src/parser/rules/inline/span.ts +0 -424
- package/src/parser/rules/inline/user.ts +0 -147
|
@@ -1,327 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* Parses the Wikidot anchor inline block syntax: `[[a]]...[[/a]]`.
|
|
4
|
-
*
|
|
5
|
-
* An anchor wraps inline content in an HTML `<a>` element, allowing
|
|
6
|
-
* href, target, and other HTML attributes to be specified.
|
|
7
|
-
*
|
|
8
|
-
* Wikidot syntax variants:
|
|
9
|
-
* - `[[a href="url"]]text[[/a]]` -- basic anchor with href
|
|
10
|
-
* - `[[a_ href="url"]]text[[/a]]` -- paragraph strip mode (trailing underscore)
|
|
11
|
-
*
|
|
12
|
-
* Paragraph strip mode (`[[a_]]`) suppresses newlines within the anchor
|
|
13
|
-
* body and strips at most one trailing newline after the closing tag
|
|
14
|
-
* (preserving double newlines as paragraph breaks). This prevents
|
|
15
|
-
* unwanted `<br>` elements when consecutive anchor blocks are placed on
|
|
16
|
-
* separate lines.
|
|
17
|
-
*
|
|
18
|
-
* The `target` attribute is extracted and mapped to a semantic enum value
|
|
19
|
-
* (`"new-tab"`, `"parent"`, `"top"`, `"same"`), while the remaining
|
|
20
|
-
* attributes (including `href`) are passed through after URL sanitization.
|
|
21
|
-
*
|
|
22
|
-
* @module
|
|
23
|
-
*/
|
|
24
|
-
import type { Element } from "@wdprlib/ast";
|
|
25
|
-
import type { InlineRule, ParseContext, RuleResult } from "../types";
|
|
26
|
-
import { currentToken } from "../types";
|
|
27
|
-
import { inlineRules } from "../index";
|
|
28
|
-
import { sanitizeUrl as braintreeSanitizeUrl } from "@braintree/sanitize-url";
|
|
29
|
-
import { parseAttributes } from "../block/utils";
|
|
30
|
-
import { canApplyInlineRule } from "./utils";
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Sanitizes a URL to prevent XSS attacks via dangerous URI schemes.
|
|
34
|
-
*
|
|
35
|
-
* Applies two layers of protection:
|
|
36
|
-
* 1. Pre-checks the whitespace-normalized URL against known dangerous schemes
|
|
37
|
-
* (`javascript:`, `data:`, `vbscript:`), catching evasion attempts like
|
|
38
|
-
* `"java script:"` with embedded whitespace.
|
|
39
|
-
* 2. Delegates to `@braintree/sanitize-url` for additional validation.
|
|
40
|
-
*
|
|
41
|
-
* Returns the original URL (not the normalized form) to avoid unintended
|
|
42
|
-
* modifications such as trailing-slash addition.
|
|
43
|
-
*
|
|
44
|
-
* @param url - The raw URL string to sanitize
|
|
45
|
-
* @returns The original URL if safe, or `"#invalid-url"` if the URL is deemed dangerous
|
|
46
|
-
*/
|
|
47
|
-
function sanitizeUrl(url: string): string {
|
|
48
|
-
// Pre-process: normalize whitespace to catch evasion attempts like "java script:"
|
|
49
|
-
const normalizedForCheck = url.replace(/[\s\u0000-\u001f]/g, "").toLowerCase();
|
|
50
|
-
|
|
51
|
-
// Check for dangerous schemes after whitespace normalization
|
|
52
|
-
const dangerousSchemes = ["javascript:", "data:", "vbscript:"];
|
|
53
|
-
for (const scheme of dangerousSchemes) {
|
|
54
|
-
if (normalizedForCheck.startsWith(scheme)) {
|
|
55
|
-
return "#invalid-url";
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Use library for additional checks
|
|
60
|
-
const sanitized = braintreeSanitizeUrl(url);
|
|
61
|
-
if (sanitized === "about:blank") {
|
|
62
|
-
return "#invalid-url";
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// Return original URL to avoid unwanted normalization (e.g., trailing slash addition)
|
|
66
|
-
return url;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Parses the block name portion of an anchor open/close tag, handling the
|
|
71
|
-
* optional underscore suffix that activates paragraph strip mode.
|
|
72
|
-
*
|
|
73
|
-
* Recognizes `a`, `anchor`, `a_`, and `anchor_` (case-insensitive).
|
|
74
|
-
* The underscore suffix is reported via the `score` field so the caller
|
|
75
|
-
* can decide how to handle newlines inside the anchor body.
|
|
76
|
-
*
|
|
77
|
-
* @param ctx - The current parse context containing the token stream
|
|
78
|
-
* @param startPos - Token index at which to begin scanning
|
|
79
|
-
* @returns An object with the lowercased name (including trailing `_` if present),
|
|
80
|
-
* a `score` boolean indicating paragraph strip mode, and the number of
|
|
81
|
-
* tokens consumed -- or `null` if no valid anchor block name was found
|
|
82
|
-
*/
|
|
83
|
-
function parseAnchorBlockName(
|
|
84
|
-
ctx: ParseContext,
|
|
85
|
-
startPos: number,
|
|
86
|
-
): { name: string; score: boolean; consumed: number } | null {
|
|
87
|
-
let pos = startPos;
|
|
88
|
-
let consumed = 0;
|
|
89
|
-
|
|
90
|
-
// Skip whitespace
|
|
91
|
-
while (ctx.tokens[pos]?.type === "WHITESPACE") {
|
|
92
|
-
pos++;
|
|
93
|
-
consumed++;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const token = ctx.tokens[pos];
|
|
97
|
-
if (!token || (token.type !== "TEXT" && token.type !== "IDENTIFIER")) {
|
|
98
|
-
return null;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
let name = token.value.toLowerCase();
|
|
102
|
-
consumed++;
|
|
103
|
-
pos++;
|
|
104
|
-
|
|
105
|
-
// Check for underscore suffix (paragraph strip)
|
|
106
|
-
let score = false;
|
|
107
|
-
if (ctx.tokens[pos]?.type === "UNDERSCORE") {
|
|
108
|
-
score = true;
|
|
109
|
-
name += "_";
|
|
110
|
-
consumed++;
|
|
111
|
-
pos++;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
return { name, score, consumed };
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Inline rule for parsing `[[a]]...[[/a]]` blocks.
|
|
119
|
-
*
|
|
120
|
-
* Triggered by a `BLOCK_OPEN` (`[[`) token. The rule verifies the block name
|
|
121
|
-
* is `a` or `anchor` (optionally with `_` suffix), parses HTML attributes,
|
|
122
|
-
* then recursively parses inline content until the matching closing tag.
|
|
123
|
-
*
|
|
124
|
-
* Produces an `"anchor"` AST element containing the parsed children, a
|
|
125
|
-
* semantic `target` value, and the sanitized attribute map.
|
|
126
|
-
*
|
|
127
|
-
* Edge cases:
|
|
128
|
-
* - If no matching closing tag is found, the rule fails (returns `{ success: false }`),
|
|
129
|
-
* allowing the tokens to fall through to other rules or the text fallback.
|
|
130
|
-
* - In paragraph strip mode, newlines within the body are consumed silently
|
|
131
|
-
* rather than converted to line-break elements. After the closing tag,
|
|
132
|
-
* at most one trailing newline is consumed to prevent a line-break between
|
|
133
|
-
* consecutive `[[a_]]` blocks, but double newlines are preserved as
|
|
134
|
-
* paragraph breaks.
|
|
135
|
-
* - The `href` attribute is sanitized to block `javascript:`, `data:`, and
|
|
136
|
-
* `vbscript:` schemes.
|
|
137
|
-
*/
|
|
138
|
-
export const anchorRule: InlineRule = {
|
|
139
|
-
name: "anchor",
|
|
140
|
-
startTokens: ["BLOCK_OPEN"],
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Attempts to parse an anchor block starting at the current position.
|
|
144
|
-
*
|
|
145
|
-
* @param ctx - Parse context with token stream and current position
|
|
146
|
-
* @returns A successful result with an `"anchor"` element, or `{ success: false }`
|
|
147
|
-
*/
|
|
148
|
-
parse(ctx: ParseContext): RuleResult<Element> {
|
|
149
|
-
const openToken = currentToken(ctx);
|
|
150
|
-
if (openToken.type !== "BLOCK_OPEN") {
|
|
151
|
-
return { success: false };
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
let pos = ctx.pos + 1;
|
|
155
|
-
let consumed = 1;
|
|
156
|
-
|
|
157
|
-
// Parse block name with flags
|
|
158
|
-
const nameResult = parseAnchorBlockName(ctx, pos);
|
|
159
|
-
if (!nameResult) {
|
|
160
|
-
return { success: false };
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
const baseName = nameResult.name.replace(/_$/, "");
|
|
164
|
-
if (baseName !== "a" && baseName !== "anchor") {
|
|
165
|
-
return { success: false };
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
const paragraphStrip = nameResult.score;
|
|
169
|
-
|
|
170
|
-
pos += nameResult.consumed;
|
|
171
|
-
consumed += nameResult.consumed;
|
|
172
|
-
|
|
173
|
-
// Parse attributes
|
|
174
|
-
const attrResult = parseAttributes(ctx, pos);
|
|
175
|
-
pos += attrResult.consumed;
|
|
176
|
-
consumed += attrResult.consumed;
|
|
177
|
-
|
|
178
|
-
// Expect ]]
|
|
179
|
-
if (ctx.tokens[pos]?.type !== "BLOCK_CLOSE") {
|
|
180
|
-
return { success: false };
|
|
181
|
-
}
|
|
182
|
-
pos++;
|
|
183
|
-
consumed++;
|
|
184
|
-
|
|
185
|
-
// Parse content until [[/a]] or [[/anchor]]
|
|
186
|
-
const children: Element[] = [];
|
|
187
|
-
let foundClose = false;
|
|
188
|
-
|
|
189
|
-
while (pos < ctx.tokens.length) {
|
|
190
|
-
const token = ctx.tokens[pos];
|
|
191
|
-
if (!token || token.type === "EOF") {
|
|
192
|
-
break;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
// Check for closing tag
|
|
196
|
-
if (token.type === "BLOCK_END_OPEN") {
|
|
197
|
-
const closeNameResult = parseAnchorBlockName(ctx, pos + 1);
|
|
198
|
-
const closeBaseName = closeNameResult?.name.replace(/_$/, "");
|
|
199
|
-
if (closeNameResult && (closeBaseName === "a" || closeBaseName === "anchor")) {
|
|
200
|
-
pos++; // [[/
|
|
201
|
-
consumed++;
|
|
202
|
-
pos += closeNameResult.consumed;
|
|
203
|
-
consumed += closeNameResult.consumed;
|
|
204
|
-
if (ctx.tokens[pos]?.type === "BLOCK_CLOSE") {
|
|
205
|
-
pos++;
|
|
206
|
-
consumed++;
|
|
207
|
-
}
|
|
208
|
-
foundClose = true;
|
|
209
|
-
|
|
210
|
-
// In paragraph strip mode, consume one trailing newline after close tag
|
|
211
|
-
// This prevents a line-break between consecutive [[a_]] blocks
|
|
212
|
-
// but preserves paragraph breaks (double newlines)
|
|
213
|
-
if (
|
|
214
|
-
paragraphStrip &&
|
|
215
|
-
ctx.tokens[pos]?.type === "NEWLINE" &&
|
|
216
|
-
ctx.tokens[pos + 1]?.type !== "NEWLINE"
|
|
217
|
-
) {
|
|
218
|
-
pos++;
|
|
219
|
-
consumed++;
|
|
220
|
-
}
|
|
221
|
-
break;
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// Handle NEWLINE
|
|
226
|
-
if (token.type === "NEWLINE") {
|
|
227
|
-
if (paragraphStrip) {
|
|
228
|
-
// Skip newlines in paragraph strip mode
|
|
229
|
-
pos++;
|
|
230
|
-
consumed++;
|
|
231
|
-
continue;
|
|
232
|
-
}
|
|
233
|
-
// Convert to line-break
|
|
234
|
-
children.push({ element: "line-break" });
|
|
235
|
-
pos++;
|
|
236
|
-
consumed++;
|
|
237
|
-
// Skip leading whitespace after newline
|
|
238
|
-
while (ctx.tokens[pos]?.type === "WHITESPACE" && ctx.tokens[pos]?.lineStart) {
|
|
239
|
-
pos++;
|
|
240
|
-
consumed++;
|
|
241
|
-
}
|
|
242
|
-
continue;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
// Skip whitespace at line start
|
|
246
|
-
if (token.type === "WHITESPACE" && token.lineStart) {
|
|
247
|
-
pos++;
|
|
248
|
-
consumed++;
|
|
249
|
-
continue;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
// Try each inline rule
|
|
253
|
-
let matched = false;
|
|
254
|
-
const inlineCtx: ParseContext = { ...ctx, pos };
|
|
255
|
-
|
|
256
|
-
for (const rule of inlineRules) {
|
|
257
|
-
if (canApplyInlineRule(rule, token)) {
|
|
258
|
-
const result = rule.parse(inlineCtx);
|
|
259
|
-
if (result.success) {
|
|
260
|
-
children.push(...result.elements);
|
|
261
|
-
pos += result.consumed;
|
|
262
|
-
consumed += result.consumed;
|
|
263
|
-
matched = true;
|
|
264
|
-
break;
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
if (!matched) {
|
|
270
|
-
children.push({ element: "text", data: token.value });
|
|
271
|
-
pos++;
|
|
272
|
-
consumed++;
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
if (!foundClose) {
|
|
277
|
-
ctx.diagnostics.push({
|
|
278
|
-
severity: "warning",
|
|
279
|
-
code: "unclosed-block",
|
|
280
|
-
message: `Missing closing tag [[/a]] for [[${nameResult.name}]]`,
|
|
281
|
-
position: openToken.position,
|
|
282
|
-
});
|
|
283
|
-
return { success: false };
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
// Clean up children - remove leading/trailing line breaks if paragraph strip
|
|
287
|
-
if (paragraphStrip) {
|
|
288
|
-
while (children.length > 0 && children[0]?.element === "line-break") {
|
|
289
|
-
children.shift();
|
|
290
|
-
}
|
|
291
|
-
while (children.length > 0 && children[children.length - 1]?.element === "line-break") {
|
|
292
|
-
children.pop();
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
// Determine target from attributes
|
|
297
|
-
let target: "new-tab" | "parent" | "top" | "same" | null = null;
|
|
298
|
-
const targetAttr = attrResult.attrs.target;
|
|
299
|
-
if (targetAttr === "_blank") target = "new-tab";
|
|
300
|
-
else if (targetAttr === "_parent") target = "parent";
|
|
301
|
-
else if (targetAttr === "_top") target = "top";
|
|
302
|
-
else if (targetAttr === "_self") target = "same";
|
|
303
|
-
|
|
304
|
-
// Remove target from attributes (href stays in attributes)
|
|
305
|
-
const { target: _t, ...cleanAttrs } = attrResult.attrs;
|
|
306
|
-
|
|
307
|
-
// Sanitize href to prevent XSS
|
|
308
|
-
if (cleanAttrs.href) {
|
|
309
|
-
cleanAttrs.href = sanitizeUrl(cleanAttrs.href);
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
return {
|
|
313
|
-
success: true,
|
|
314
|
-
elements: [
|
|
315
|
-
{
|
|
316
|
-
element: "anchor",
|
|
317
|
-
data: {
|
|
318
|
-
target,
|
|
319
|
-
attributes: cleanAttrs,
|
|
320
|
-
elements: children,
|
|
321
|
-
},
|
|
322
|
-
},
|
|
323
|
-
],
|
|
324
|
-
consumed,
|
|
325
|
-
};
|
|
326
|
-
},
|
|
327
|
-
};
|
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* Parses the Wikidot bibliography citation syntax: `((bibcite label))`.
|
|
4
|
-
*
|
|
5
|
-
* A bibcite creates a numbered inline reference (similar to footnotes)
|
|
6
|
-
* that links to a corresponding entry in a `[[bibliography]]` block
|
|
7
|
-
* elsewhere on the page. The `label` string is used to match the
|
|
8
|
-
* citation with its bibliography entry.
|
|
9
|
-
*
|
|
10
|
-
* Unlike most inline blocks that start with `[[`, bibcite uses double
|
|
11
|
-
* parentheses `((...))` as delimiters. The keyword `bibcite` must
|
|
12
|
-
* appear (case-insensitive) between the opening `((` and the label.
|
|
13
|
-
*
|
|
14
|
-
* Produces a `"bibliography-cite"` AST element. The label is also
|
|
15
|
-
* pushed into `ctx.bibcites` so the renderer can later resolve
|
|
16
|
-
* citation numbers.
|
|
17
|
-
*
|
|
18
|
-
* Wikidot syntax examples:
|
|
19
|
-
* - `((bibcite author2024))` -- cite with label "author2024"
|
|
20
|
-
* - `((bibcite my-source))` -- cite with label "my-source"
|
|
21
|
-
*
|
|
22
|
-
* @module
|
|
23
|
-
*/
|
|
24
|
-
import type { Element } from "@wdprlib/ast";
|
|
25
|
-
import type { InlineRule, ParseContext, RuleResult } from "../types";
|
|
26
|
-
import { currentToken } from "../types";
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Inline rule for parsing `((bibcite label))` bibliography citations.
|
|
30
|
-
*
|
|
31
|
-
* Triggered by a `TEXT` token (specifically the `(` character). The parser
|
|
32
|
-
* looks for two consecutive `(` tokens, the keyword `bibcite`, the label
|
|
33
|
-
* text, and then two consecutive `)` tokens.
|
|
34
|
-
*
|
|
35
|
-
* The label may span multiple tokens and is trimmed of surrounding whitespace.
|
|
36
|
-
* Parsing fails if the label is empty or if a newline/EOF is encountered
|
|
37
|
-
* before the closing `))`.
|
|
38
|
-
*
|
|
39
|
-
* Side effect: pushes the label into `ctx.bibcites` for later resolution
|
|
40
|
-
* during rendering.
|
|
41
|
-
*/
|
|
42
|
-
export const bibciteRule: InlineRule = {
|
|
43
|
-
name: "bibcite",
|
|
44
|
-
startTokens: ["TEXT"],
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Attempts to parse a `((bibcite label))` citation at the current position.
|
|
48
|
-
*
|
|
49
|
-
* @param ctx - Parse context with token stream and current position
|
|
50
|
-
* @returns A successful result with a `"bibliography-cite"` element, or `{ success: false }`
|
|
51
|
-
*/
|
|
52
|
-
parse(ctx: ParseContext): RuleResult<Element> {
|
|
53
|
-
const token = currentToken(ctx);
|
|
54
|
-
|
|
55
|
-
// Must start with (
|
|
56
|
-
if (token.type !== "TEXT" || token.value !== "(") {
|
|
57
|
-
return { success: false };
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Check for second (
|
|
61
|
-
const nextToken = ctx.tokens[ctx.pos + 1];
|
|
62
|
-
if (!nextToken || nextToken.type !== "TEXT" || nextToken.value !== "(") {
|
|
63
|
-
return { success: false };
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Check for "bibcite" identifier
|
|
67
|
-
let pos = ctx.pos + 2;
|
|
68
|
-
let consumed = 2;
|
|
69
|
-
|
|
70
|
-
// Skip whitespace
|
|
71
|
-
while (ctx.tokens[pos]?.type === "WHITESPACE") {
|
|
72
|
-
pos++;
|
|
73
|
-
consumed++;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const nameToken = ctx.tokens[pos];
|
|
77
|
-
if (
|
|
78
|
-
!nameToken ||
|
|
79
|
-
nameToken.type !== "IDENTIFIER" ||
|
|
80
|
-
nameToken.value.toLowerCase() !== "bibcite"
|
|
81
|
-
) {
|
|
82
|
-
return { success: false };
|
|
83
|
-
}
|
|
84
|
-
pos++;
|
|
85
|
-
consumed++;
|
|
86
|
-
|
|
87
|
-
// Skip whitespace
|
|
88
|
-
while (ctx.tokens[pos]?.type === "WHITESPACE") {
|
|
89
|
-
pos++;
|
|
90
|
-
consumed++;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// Parse label (identifier or text)
|
|
94
|
-
const labelToken = ctx.tokens[pos];
|
|
95
|
-
if (!labelToken || (labelToken.type !== "IDENTIFIER" && labelToken.type !== "TEXT")) {
|
|
96
|
-
return { success: false };
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// Collect label (may span multiple tokens until ))
|
|
100
|
-
let label = "";
|
|
101
|
-
let foundClose = false;
|
|
102
|
-
while (pos < ctx.tokens.length) {
|
|
103
|
-
const t = ctx.tokens[pos];
|
|
104
|
-
if (!t) break;
|
|
105
|
-
|
|
106
|
-
// Check for ))
|
|
107
|
-
if (t.type === "TEXT" && t.value === ")") {
|
|
108
|
-
const nextT = ctx.tokens[pos + 1];
|
|
109
|
-
if (nextT?.type === "TEXT" && nextT.value === ")") {
|
|
110
|
-
// Found closing ))
|
|
111
|
-
consumed += 2;
|
|
112
|
-
foundClose = true;
|
|
113
|
-
break;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// Stop at newline or EOF
|
|
118
|
-
if (t.type === "NEWLINE" || t.type === "EOF") {
|
|
119
|
-
return { success: false };
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
label += t.value;
|
|
123
|
-
pos++;
|
|
124
|
-
consumed++;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
if (!foundClose) {
|
|
128
|
-
return { success: false };
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
label = label.trim();
|
|
132
|
-
if (!label) {
|
|
133
|
-
return { success: false };
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// Store bibcite reference in context for later resolution
|
|
137
|
-
ctx.bibcites.push(label);
|
|
138
|
-
|
|
139
|
-
return {
|
|
140
|
-
success: true,
|
|
141
|
-
elements: [
|
|
142
|
-
{
|
|
143
|
-
element: "bibliography-cite",
|
|
144
|
-
data: {
|
|
145
|
-
label,
|
|
146
|
-
brackets: false, // Wikidot adds brackets in output but they're not in the AST
|
|
147
|
-
},
|
|
148
|
-
},
|
|
149
|
-
],
|
|
150
|
-
consumed,
|
|
151
|
-
};
|
|
152
|
-
},
|
|
153
|
-
};
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* Parses the Wikidot inline color syntax: `##color|text##`.
|
|
4
|
-
*
|
|
5
|
-
* This syntax applies a CSS color to inline text. The color specifier
|
|
6
|
-
* and the text content are separated by a pipe (`|`). Both parts are
|
|
7
|
-
* required; an empty color or empty content causes the parse to fail.
|
|
8
|
-
*
|
|
9
|
-
* Supported color formats:
|
|
10
|
-
* - 3-digit hex (e.g. `c00`) -- automatically prefixed with `#`
|
|
11
|
-
* - 6-digit hex (e.g. `cc0000`) -- automatically prefixed with `#`
|
|
12
|
-
* - Named CSS colors (e.g. `blue`, `red`)
|
|
13
|
-
* - CSS color functions (e.g. `rgb(255,0,0)`)
|
|
14
|
-
*
|
|
15
|
-
* Wikidot syntax examples:
|
|
16
|
-
* - `##c00|Apple##` -- red text reading "Apple"
|
|
17
|
-
* - `##blue|Ocean##` -- blue text reading "Ocean"
|
|
18
|
-
* - `##rgb(0,128,0)|Green text##` -- CSS function color
|
|
19
|
-
*
|
|
20
|
-
* Produces a `"color"` AST element with the resolved color value and
|
|
21
|
-
* nested inline elements.
|
|
22
|
-
*
|
|
23
|
-
* @module
|
|
24
|
-
*/
|
|
25
|
-
import type { Element } from "@wdprlib/ast";
|
|
26
|
-
import type { InlineRule, ParseContext, RuleResult } from "../types";
|
|
27
|
-
import { hasClosingMarkerBeforeNewline } from "../types";
|
|
28
|
-
import { parseInlineUntil } from "./utils";
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Inline rule for parsing `##color|text##` color formatting.
|
|
32
|
-
*
|
|
33
|
-
* Triggered by a `COLOR_MARKER` token (`##`). The rule collects the
|
|
34
|
-
* color specifier until a `PIPE` token, then recursively parses inline
|
|
35
|
-
* content until the closing `##`.
|
|
36
|
-
*
|
|
37
|
-
* Fails if:
|
|
38
|
-
* - No closing `##` is found on the same line
|
|
39
|
-
* - No pipe separator is present
|
|
40
|
-
* - The color specifier or content is empty
|
|
41
|
-
*/
|
|
42
|
-
export const colorRule: InlineRule = {
|
|
43
|
-
name: "color",
|
|
44
|
-
startTokens: ["COLOR_MARKER"],
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Attempts to parse color formatting at the current position.
|
|
48
|
-
*
|
|
49
|
-
* @param ctx - Parse context with token stream and current position
|
|
50
|
-
* @returns A successful result with a `"color"` element, or `{ success: false }`
|
|
51
|
-
*/
|
|
52
|
-
parse(ctx: ParseContext): RuleResult<Element> {
|
|
53
|
-
// Check if closing marker exists
|
|
54
|
-
if (!hasClosingMarkerBeforeNewline({ ...ctx, pos: ctx.pos + 1 }, "COLOR_MARKER")) {
|
|
55
|
-
return { success: false };
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
let pos = ctx.pos + 1;
|
|
59
|
-
let consumed = 1; // ##
|
|
60
|
-
|
|
61
|
-
// Collect color specification until PIPE
|
|
62
|
-
let colorSpec = "";
|
|
63
|
-
while (pos < ctx.tokens.length) {
|
|
64
|
-
const token = ctx.tokens[pos];
|
|
65
|
-
if (
|
|
66
|
-
!token ||
|
|
67
|
-
token.type === "PIPE" ||
|
|
68
|
-
token.type === "COLOR_MARKER" ||
|
|
69
|
-
token.type === "NEWLINE" ||
|
|
70
|
-
token.type === "EOF"
|
|
71
|
-
) {
|
|
72
|
-
break;
|
|
73
|
-
}
|
|
74
|
-
colorSpec += token.value;
|
|
75
|
-
pos++;
|
|
76
|
-
consumed++;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Must have a PIPE separator
|
|
80
|
-
if (ctx.tokens[pos]?.type !== "PIPE") {
|
|
81
|
-
return { success: false };
|
|
82
|
-
}
|
|
83
|
-
pos++;
|
|
84
|
-
consumed++;
|
|
85
|
-
|
|
86
|
-
// Parse inline content until closing ##
|
|
87
|
-
const contentResult = parseInlineUntil({ ...ctx, pos }, "COLOR_MARKER");
|
|
88
|
-
pos += contentResult.consumed;
|
|
89
|
-
consumed += contentResult.consumed;
|
|
90
|
-
|
|
91
|
-
// Consume closing ##
|
|
92
|
-
if (ctx.tokens[pos]?.type === "COLOR_MARKER") {
|
|
93
|
-
pos++;
|
|
94
|
-
consumed++;
|
|
95
|
-
} else {
|
|
96
|
-
return { success: false };
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
const textChildren = contentResult.elements;
|
|
100
|
-
|
|
101
|
-
const trimmedColor = colorSpec.trim();
|
|
102
|
-
|
|
103
|
-
// Wikidot requires non-empty color spec and non-empty content
|
|
104
|
-
if (trimmedColor === "" || textChildren.length === 0) {
|
|
105
|
-
return { success: false };
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
return {
|
|
109
|
-
success: true,
|
|
110
|
-
elements: [
|
|
111
|
-
{
|
|
112
|
-
element: "color",
|
|
113
|
-
data: {
|
|
114
|
-
color: hexifyColor(trimmedColor),
|
|
115
|
-
elements: textChildren,
|
|
116
|
-
},
|
|
117
|
-
},
|
|
118
|
-
],
|
|
119
|
-
consumed,
|
|
120
|
-
};
|
|
121
|
-
},
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Normalizes shorthand hex color values by prepending a `#` sign.
|
|
126
|
-
*
|
|
127
|
-
* Wikidot allows users to write hex colors without the `#` prefix
|
|
128
|
-
* (e.g. `c00` or `ff0000`). This function detects 3- or 6-character
|
|
129
|
-
* hex strings and adds the prefix. Non-hex color values (named colors,
|
|
130
|
-
* CSS functions) are returned unchanged.
|
|
131
|
-
*
|
|
132
|
-
* @param color - The trimmed color string from the markup
|
|
133
|
-
* @returns The color string, with `#` prepended if it was a bare hex value
|
|
134
|
-
*/
|
|
135
|
-
function hexifyColor(color: string): string {
|
|
136
|
-
if (/^[a-fA-F0-9]{3}$/.test(color) || /^[a-fA-F0-9]{6}$/.test(color)) {
|
|
137
|
-
return `#${color}`;
|
|
138
|
-
}
|
|
139
|
-
return color;
|
|
140
|
-
}
|