@wdprlib/parser 3.2.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +10451 -8402
- package/dist/index.d.cts +313 -337
- package/dist/index.d.ts +313 -337
- package/dist/index.js +10438 -8389
- 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 +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 +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
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { Element } from "@wdprlib/ast";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Process closeSpan markers in inline content.
|
|
5
|
+
*
|
|
6
|
+
* When a `_closeSpan` marker is found, all preceding content is wrapped
|
|
7
|
+
* in a span and the marker itself is omitted.
|
|
8
|
+
*/
|
|
9
|
+
export function processCloseSpanMarkers(elements: Element[]): Element[] {
|
|
10
|
+
let result: Element[] | null = null;
|
|
11
|
+
|
|
12
|
+
for (let i = 0; i < elements.length; i++) {
|
|
13
|
+
const elem = elements[i];
|
|
14
|
+
if (!elem) continue;
|
|
15
|
+
|
|
16
|
+
if (isCloseSpanMarker(elem)) {
|
|
17
|
+
if (result === null) {
|
|
18
|
+
result = elements.slice(0, i);
|
|
19
|
+
}
|
|
20
|
+
if (result.length > 0) {
|
|
21
|
+
const spanContent = [...result];
|
|
22
|
+
result.length = 0;
|
|
23
|
+
result.push({
|
|
24
|
+
element: "container",
|
|
25
|
+
data: {
|
|
26
|
+
type: "span",
|
|
27
|
+
attributes: {},
|
|
28
|
+
elements: spanContent,
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
} else {
|
|
33
|
+
result?.push(elem);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return result ?? elements;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function isCloseSpanMarker(elem: Element): boolean {
|
|
41
|
+
return (
|
|
42
|
+
elem.element === "container" &&
|
|
43
|
+
elem.data &&
|
|
44
|
+
typeof elem.data === "object" &&
|
|
45
|
+
"type" in elem.data &&
|
|
46
|
+
elem.data.type === "span" &&
|
|
47
|
+
"attributes" in elem.data &&
|
|
48
|
+
typeof elem.data.attributes === "object" &&
|
|
49
|
+
elem.data.attributes !== null &&
|
|
50
|
+
"_closeSpan" in elem.data.attributes
|
|
51
|
+
);
|
|
52
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { ParseContext } from "../../../types";
|
|
2
|
+
import { filterUnsafeAttributes } from "../../../common";
|
|
3
|
+
import { scanAttributes, type AttributeParseResult } from "./scanner";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Parses HTML-style attributes from block opening tags.
|
|
7
|
+
*
|
|
8
|
+
* Supports quoted values, single-token unquoted values, boolean attributes,
|
|
9
|
+
* and hyphenated names like `data-paragraph` or `aria-label`.
|
|
10
|
+
*
|
|
11
|
+
* Attribute names are lowercased. The result is filtered through
|
|
12
|
+
* `filterUnsafeAttributes` to strip potentially dangerous HTML attributes.
|
|
13
|
+
*/
|
|
14
|
+
export function parseAttributes(ctx: ParseContext, startPos: number): AttributeParseResult {
|
|
15
|
+
const result = scanAttributes(ctx, startPos, { hyphenatedNames: true, strikeHyphens: false });
|
|
16
|
+
return { attrs: filterUnsafeAttributes(result.attrs), consumed: result.consumed };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Parses attributes from block opening tags without safety filtering.
|
|
21
|
+
*
|
|
22
|
+
* Use this for block-specific parameters that are not emitted as HTML
|
|
23
|
+
* attributes. Hyphenated name handling is configurable for legacy parser
|
|
24
|
+
* contexts that need the first segment only.
|
|
25
|
+
*/
|
|
26
|
+
export function parseAttributesRaw(
|
|
27
|
+
ctx: ParseContext,
|
|
28
|
+
startPos: number,
|
|
29
|
+
hyphenatedNames = true,
|
|
30
|
+
): AttributeParseResult {
|
|
31
|
+
return scanAttributes(ctx, startPos, { hyphenatedNames, strikeHyphens: true });
|
|
32
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { Token } from "../../../../../lexer";
|
|
2
|
+
import type { ParseContext } from "../../../types";
|
|
3
|
+
|
|
4
|
+
export interface AttributeNameOptions {
|
|
5
|
+
hyphenatedNames: boolean;
|
|
6
|
+
strikeHyphens: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface AttributeNameResult {
|
|
10
|
+
name: string;
|
|
11
|
+
pos: number;
|
|
12
|
+
consumed: number;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function consumeAttributeName(
|
|
16
|
+
ctx: ParseContext,
|
|
17
|
+
startPos: number,
|
|
18
|
+
startConsumed: number,
|
|
19
|
+
startName: string,
|
|
20
|
+
options: AttributeNameOptions,
|
|
21
|
+
): AttributeNameResult {
|
|
22
|
+
return options.strikeHyphens
|
|
23
|
+
? consumeRawNameSuffix(ctx, startPos, startConsumed, startName, options.hyphenatedNames)
|
|
24
|
+
: consumeSafeNameSuffix(ctx, startPos, startConsumed, startName);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function isAttributeNameToken(token: Token | undefined): token is Token {
|
|
28
|
+
return token?.type === "TEXT" || token?.type === "IDENTIFIER";
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function consumeSafeNameSuffix(
|
|
32
|
+
ctx: ParseContext,
|
|
33
|
+
startPos: number,
|
|
34
|
+
startConsumed: number,
|
|
35
|
+
startName: string,
|
|
36
|
+
): AttributeNameResult {
|
|
37
|
+
let name = startName;
|
|
38
|
+
let pos = startPos;
|
|
39
|
+
let consumed = startConsumed;
|
|
40
|
+
|
|
41
|
+
while (
|
|
42
|
+
ctx.tokens[pos]?.type === "TEXT" &&
|
|
43
|
+
ctx.tokens[pos]?.value === "-" &&
|
|
44
|
+
isAttributeNameToken(ctx.tokens[pos + 1])
|
|
45
|
+
) {
|
|
46
|
+
name += "-";
|
|
47
|
+
pos++;
|
|
48
|
+
consumed++;
|
|
49
|
+
name += ctx.tokens[pos]?.value ?? "";
|
|
50
|
+
pos++;
|
|
51
|
+
consumed++;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return { name, pos, consumed };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function consumeRawNameSuffix(
|
|
58
|
+
ctx: ParseContext,
|
|
59
|
+
startPos: number,
|
|
60
|
+
startConsumed: number,
|
|
61
|
+
startName: string,
|
|
62
|
+
hyphenatedNames: boolean,
|
|
63
|
+
): AttributeNameResult {
|
|
64
|
+
let name = startName;
|
|
65
|
+
let pos = startPos;
|
|
66
|
+
let consumed = startConsumed;
|
|
67
|
+
|
|
68
|
+
while (isHyphenToken(ctx.tokens[pos])) {
|
|
69
|
+
while (isHyphenToken(ctx.tokens[pos])) {
|
|
70
|
+
if (hyphenatedNames) {
|
|
71
|
+
name += ctx.tokens[pos]?.value ?? "-";
|
|
72
|
+
}
|
|
73
|
+
pos++;
|
|
74
|
+
consumed++;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (!isAttributeNameToken(ctx.tokens[pos])) {
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (hyphenatedNames) {
|
|
82
|
+
name += ctx.tokens[pos]?.value ?? "";
|
|
83
|
+
}
|
|
84
|
+
pos++;
|
|
85
|
+
consumed++;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return { name, pos, consumed };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function isHyphenToken(token: Token | undefined): boolean {
|
|
92
|
+
return (token?.type === "TEXT" && token.value === "-") || token?.type === "STRIKE_MARKER";
|
|
93
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { Token } from "../../../../../lexer";
|
|
2
|
+
import type { ParseContext } from "../../../types";
|
|
3
|
+
import { consumeAttributeName, isAttributeNameToken } from "./names";
|
|
4
|
+
import { consumeAttributeValue } from "./values";
|
|
5
|
+
|
|
6
|
+
export interface AttributeParseResult {
|
|
7
|
+
attrs: Record<string, string>;
|
|
8
|
+
consumed: number;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface AttributeScanOptions {
|
|
12
|
+
hyphenatedNames: boolean;
|
|
13
|
+
strikeHyphens: boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function scanAttributes(
|
|
17
|
+
ctx: ParseContext,
|
|
18
|
+
startPos: number,
|
|
19
|
+
options: AttributeScanOptions,
|
|
20
|
+
): AttributeParseResult {
|
|
21
|
+
const attrs: Record<string, string> = {};
|
|
22
|
+
let pos = startPos;
|
|
23
|
+
let consumed = 0;
|
|
24
|
+
|
|
25
|
+
while (pos < ctx.tokens.length) {
|
|
26
|
+
const token = ctx.tokens[pos];
|
|
27
|
+
if (!token || isAttributeTerminator(token)) {
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (token.type === "WHITESPACE") {
|
|
32
|
+
pos++;
|
|
33
|
+
consumed++;
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (!isAttributeNameToken(token)) {
|
|
38
|
+
pos++;
|
|
39
|
+
consumed++;
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
let name = token.value;
|
|
44
|
+
pos++;
|
|
45
|
+
consumed++;
|
|
46
|
+
|
|
47
|
+
const nameResult = consumeAttributeName(ctx, pos, consumed, name, options);
|
|
48
|
+
pos = nameResult.pos;
|
|
49
|
+
consumed = nameResult.consumed;
|
|
50
|
+
name = nameResult.name.toLowerCase();
|
|
51
|
+
|
|
52
|
+
if (ctx.tokens[pos]?.type !== "EQUALS") {
|
|
53
|
+
attrs[name] = "true";
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
pos++;
|
|
58
|
+
consumed++;
|
|
59
|
+
|
|
60
|
+
const valueResult = consumeAttributeValue(ctx.tokens[pos]);
|
|
61
|
+
if (!valueResult) {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
attrs[name] = valueResult.value;
|
|
66
|
+
pos++;
|
|
67
|
+
consumed++;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return { attrs, consumed };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function isAttributeTerminator(token: Token): boolean {
|
|
74
|
+
return token.type === "BLOCK_CLOSE" || token.type === "NEWLINE" || token.type === "EOF";
|
|
75
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Token } from "../../../../../lexer";
|
|
2
|
+
import { isAttributeNameToken } from "./names";
|
|
3
|
+
|
|
4
|
+
export interface AttributeValueResult {
|
|
5
|
+
value: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function consumeAttributeValue(token: Token | undefined): AttributeValueResult | null {
|
|
9
|
+
if (!token) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (token.type === "QUOTED_STRING") {
|
|
14
|
+
return { value: stripQuotes(token.value) };
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (isAttributeNameToken(token)) {
|
|
18
|
+
return { value: token.value };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function stripQuotes(value: string): string {
|
|
25
|
+
return value.startsWith('"') && value.endsWith('"') ? value.slice(1, -1) : value;
|
|
26
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Element } from "@wdprlib/ast";
|
|
2
|
+
import type { ParseContext } from "../../types";
|
|
3
|
+
import { getCandidateBlockRules } from "./rule-dispatch";
|
|
4
|
+
|
|
5
|
+
export interface BlockItemResult {
|
|
6
|
+
elements: Element[];
|
|
7
|
+
consumed: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function parseBlockItem(ctx: ParseContext): BlockItemResult {
|
|
11
|
+
const token = ctx.tokens[ctx.pos];
|
|
12
|
+
if (!token) {
|
|
13
|
+
return { elements: [], consumed: 0 };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
for (const rule of getCandidateBlockRules(ctx.blockRules, token)) {
|
|
17
|
+
const result = rule.parse(ctx);
|
|
18
|
+
if (result.success) {
|
|
19
|
+
return { elements: result.elements, consumed: result.consumed };
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const fallback = ctx.blockFallbackRule.parse(ctx);
|
|
24
|
+
if (fallback.success && fallback.elements.length > 0) {
|
|
25
|
+
return { elements: fallback.elements, consumed: fallback.consumed };
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return { elements: [], consumed: 1 };
|
|
29
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import type { Element } from "@wdprlib/ast";
|
|
2
|
+
import type { ParseContext } from "../../types";
|
|
3
|
+
import { parseBlockItem } from "./block-item";
|
|
4
|
+
|
|
5
|
+
export interface BlockParseResult {
|
|
6
|
+
/** The parsed AST elements. */
|
|
7
|
+
elements: Element[];
|
|
8
|
+
/** Total number of tokens consumed from the stream. */
|
|
9
|
+
consumed: number;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const excludedBlockRulesCache = new WeakMap<
|
|
13
|
+
ParseContext["blockRules"],
|
|
14
|
+
WeakMap<ReadonlySet<string>, ParseContext["blockRules"]>
|
|
15
|
+
>();
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Parses block-level elements from the token stream until a close
|
|
19
|
+
* condition is satisfied.
|
|
20
|
+
*
|
|
21
|
+
* This is the workhorse parser used by container blocks (div, collapsible,
|
|
22
|
+
* tabview, iftags, align, etc.) to parse their body content. It loops
|
|
23
|
+
* through tokens, trying each block rule in priority order, and falls back
|
|
24
|
+
* to the paragraph rule when nothing else matches.
|
|
25
|
+
*
|
|
26
|
+
* Whitespace and newline tokens between blocks are silently consumed.
|
|
27
|
+
* The close condition receives a ParseContext snapshot at the current
|
|
28
|
+
* position and should return `true` to stop parsing (the close tag
|
|
29
|
+
* itself is NOT consumed here -- the caller handles that).
|
|
30
|
+
*
|
|
31
|
+
* The close condition is also injected into `blockCloseCondition` on
|
|
32
|
+
* the context so that the paragraph parser can respect the enclosing
|
|
33
|
+
* block's boundary.
|
|
34
|
+
*
|
|
35
|
+
* @param ctx - Parse context positioned at the start of the body.
|
|
36
|
+
* @param closeCondition - Predicate that signals the end of the block body.
|
|
37
|
+
* @param options - Optional settings.
|
|
38
|
+
* @param options.excludedBlockNames - Block names that should be excluded
|
|
39
|
+
* from both rule dispatch and paragraph-boundary detection. The named
|
|
40
|
+
* rules are filtered out of `blockRules`, and the set is propagated to
|
|
41
|
+
* the inline parser via `ParseContext.excludedBlockNames` so that
|
|
42
|
+
* `BLOCK_OPEN` / `BLOCK_END_OPEN` tokens for these names do not trigger
|
|
43
|
+
* paragraph breaks.
|
|
44
|
+
* @returns Parsed elements and total tokens consumed.
|
|
45
|
+
*/
|
|
46
|
+
export function parseBlocksUntil(
|
|
47
|
+
ctx: ParseContext,
|
|
48
|
+
closeCondition: (ctx: ParseContext) => boolean,
|
|
49
|
+
options?: { excludedBlockNames?: ReadonlySet<string> },
|
|
50
|
+
): BlockParseResult {
|
|
51
|
+
const elements: Element[] = [];
|
|
52
|
+
let consumed = 0;
|
|
53
|
+
let pos = ctx.pos;
|
|
54
|
+
|
|
55
|
+
const excluded = options?.excludedBlockNames;
|
|
56
|
+
const blockRules = excluded ? getExcludedBlockRules(ctx.blockRules, excluded) : ctx.blockRules;
|
|
57
|
+
const blockScope = {
|
|
58
|
+
...ctx.scope,
|
|
59
|
+
blockCloseCondition: closeCondition,
|
|
60
|
+
excludedBlockNames: excluded,
|
|
61
|
+
};
|
|
62
|
+
const checkCtx: ParseContext = { ...ctx, pos };
|
|
63
|
+
const blockCtx: ParseContext = {
|
|
64
|
+
...ctx,
|
|
65
|
+
pos,
|
|
66
|
+
blockRules,
|
|
67
|
+
scope: blockScope,
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
while (pos < ctx.tokens.length) {
|
|
71
|
+
const token = ctx.tokens[pos];
|
|
72
|
+
if (!token || token.type === "EOF") {
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Check close condition
|
|
77
|
+
checkCtx.pos = pos;
|
|
78
|
+
if (closeCondition(checkCtx)) {
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Skip whitespace
|
|
83
|
+
if (token.type === "WHITESPACE") {
|
|
84
|
+
pos++;
|
|
85
|
+
consumed++;
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Skip newlines
|
|
90
|
+
if (token.type === "NEWLINE") {
|
|
91
|
+
pos++;
|
|
92
|
+
consumed++;
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Pass close condition and excluded names to context
|
|
97
|
+
blockCtx.pos = pos;
|
|
98
|
+
blockCtx.scope = blockScope;
|
|
99
|
+
|
|
100
|
+
const result = parseBlockItem(blockCtx);
|
|
101
|
+
elements.push(...result.elements);
|
|
102
|
+
consumed += result.consumed;
|
|
103
|
+
pos += result.consumed;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return { elements, consumed };
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function getExcludedBlockRules(
|
|
110
|
+
blockRules: ParseContext["blockRules"],
|
|
111
|
+
excluded: ReadonlySet<string>,
|
|
112
|
+
): ParseContext["blockRules"] {
|
|
113
|
+
let byExcluded = excludedBlockRulesCache.get(blockRules);
|
|
114
|
+
if (!byExcluded) {
|
|
115
|
+
byExcluded = new WeakMap();
|
|
116
|
+
excludedBlockRulesCache.set(blockRules, byExcluded);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const cached = byExcluded.get(excluded);
|
|
120
|
+
if (cached) {
|
|
121
|
+
return cached;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const filtered = blockRules.filter((rule) => !excluded.has(rule.name));
|
|
125
|
+
byExcluded.set(excluded, filtered);
|
|
126
|
+
return filtered;
|
|
127
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { ParseContext } from "../../types";
|
|
2
|
+
import { parseBlockName } from "../utils";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Creates a reusable close-condition function that matches block end tags
|
|
6
|
+
* (`[[/name]]`) for one or more block names.
|
|
7
|
+
*
|
|
8
|
+
* The returned function inspects the tokens at `ctx.pos` and returns both
|
|
9
|
+
* whether a match was found and how many tokens the closing tag occupies
|
|
10
|
+
* (including the optional trailing NEWLINE).
|
|
11
|
+
*
|
|
12
|
+
* @param blockNames - Array of block names to match (e.g. `["div"]`).
|
|
13
|
+
* @returns A function suitable for use as a `closeCondition` argument,
|
|
14
|
+
* returning `{ matched, consumed }`.
|
|
15
|
+
*/
|
|
16
|
+
export function createBlockEndCondition(
|
|
17
|
+
blockNames: string[],
|
|
18
|
+
): (ctx: ParseContext) => { matched: boolean; consumed: number } {
|
|
19
|
+
return (ctx: ParseContext) => {
|
|
20
|
+
const token = ctx.tokens[ctx.pos];
|
|
21
|
+
if (token?.type !== "BLOCK_END_OPEN") {
|
|
22
|
+
return { matched: false, consumed: 0 };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const nameResult = parseBlockName(ctx, ctx.pos + 1);
|
|
26
|
+
if (!nameResult) {
|
|
27
|
+
return { matched: false, consumed: 0 };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (!blockNames.includes(nameResult.name)) {
|
|
31
|
+
return { matched: false, consumed: 0 };
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Calculate consumed: [[/ + name + ]]
|
|
35
|
+
let consumed = 1 + nameResult.consumed;
|
|
36
|
+
|
|
37
|
+
// Check for closing ]]
|
|
38
|
+
const closePos = ctx.pos + 1 + nameResult.consumed;
|
|
39
|
+
if (ctx.tokens[closePos]?.type === "BLOCK_CLOSE") {
|
|
40
|
+
consumed++;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Check for trailing newline
|
|
44
|
+
const newlinePos = closePos + 1;
|
|
45
|
+
if (ctx.tokens[newlinePos]?.type === "NEWLINE") {
|
|
46
|
+
consumed++;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return { matched: true, consumed };
|
|
50
|
+
};
|
|
51
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import type { Element } from "@wdprlib/ast";
|
|
2
|
+
import type { ParseContext } from "../../types";
|
|
3
|
+
import { getCandidateInlineRules } from "../../inline/utils";
|
|
4
|
+
import type { BlockParseResult } from "./content";
|
|
5
|
+
import { consumeInlineContentNewlines, removeTrailingLineBreaks } from "./inline-newline";
|
|
6
|
+
import { getCandidateBlockRules } from "./rule-dispatch";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Parses mixed inline/block content until a close condition is met,
|
|
10
|
+
* WITHOUT paragraph wrapping.
|
|
11
|
+
*
|
|
12
|
+
* This is used for `div_` (paragraph strip mode) where newlines become
|
|
13
|
+
* `<br />` elements rather than paragraph separators. Blank lines
|
|
14
|
+
* (multiple consecutive newlines) are collapsed into a single `<br />`.
|
|
15
|
+
*
|
|
16
|
+
* Block-level elements (nested div, collapsible, etc.) are mixed directly
|
|
17
|
+
* into the inline element stream. Newlines immediately before a BLOCK_OPEN
|
|
18
|
+
* or BLOCK_END_OPEN are silently consumed (no `<br />` generated).
|
|
19
|
+
*
|
|
20
|
+
* Trailing line-break elements are stripped from the result.
|
|
21
|
+
*
|
|
22
|
+
* @param ctx - Parse context positioned at the start of the body.
|
|
23
|
+
* @param closeCondition - Predicate that signals the end of the content.
|
|
24
|
+
* @returns Parsed elements and total tokens consumed.
|
|
25
|
+
*/
|
|
26
|
+
export function parseInlineContentUntil(
|
|
27
|
+
ctx: ParseContext,
|
|
28
|
+
closeCondition: (ctx: ParseContext) => boolean,
|
|
29
|
+
): BlockParseResult {
|
|
30
|
+
const elements: Element[] = [];
|
|
31
|
+
let consumed = 0;
|
|
32
|
+
let pos = ctx.pos;
|
|
33
|
+
|
|
34
|
+
const { blockRules, inlineRules } = ctx;
|
|
35
|
+
const checkCtx: ParseContext = { ...ctx, pos };
|
|
36
|
+
const blockCtx: ParseContext = { ...ctx, pos };
|
|
37
|
+
const inlineCtx: ParseContext = { ...ctx, pos };
|
|
38
|
+
|
|
39
|
+
while (pos < ctx.tokens.length) {
|
|
40
|
+
const token = ctx.tokens[pos];
|
|
41
|
+
if (!token || token.type === "EOF") {
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
checkCtx.pos = pos;
|
|
46
|
+
if (closeCondition(checkCtx)) {
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (token.type === "WHITESPACE" && token.lineStart) {
|
|
51
|
+
pos++;
|
|
52
|
+
consumed++;
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (token.type === "NEWLINE") {
|
|
57
|
+
const newlineResult = consumeInlineContentNewlines(ctx, pos);
|
|
58
|
+
consumed += newlineResult.consumed;
|
|
59
|
+
pos += newlineResult.consumed;
|
|
60
|
+
if (newlineResult.addLineBreak) {
|
|
61
|
+
elements.push({ element: "line-break" });
|
|
62
|
+
}
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
let matched = false;
|
|
67
|
+
blockCtx.pos = pos;
|
|
68
|
+
|
|
69
|
+
for (const rule of getCandidateBlockRules(blockRules, token)) {
|
|
70
|
+
const result = rule.parse(blockCtx);
|
|
71
|
+
if (result.success) {
|
|
72
|
+
elements.push(...result.elements);
|
|
73
|
+
consumed += result.consumed;
|
|
74
|
+
pos += result.consumed;
|
|
75
|
+
matched = true;
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (matched) continue;
|
|
81
|
+
|
|
82
|
+
inlineCtx.pos = pos;
|
|
83
|
+
|
|
84
|
+
for (const rule of getCandidateInlineRules(inlineRules, token.type)) {
|
|
85
|
+
const result = rule.parse(inlineCtx);
|
|
86
|
+
if (result.success) {
|
|
87
|
+
elements.push(...result.elements);
|
|
88
|
+
consumed += result.consumed;
|
|
89
|
+
pos += result.consumed;
|
|
90
|
+
matched = true;
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (!matched) {
|
|
96
|
+
elements.push({ element: "text", data: token.value });
|
|
97
|
+
consumed++;
|
|
98
|
+
pos++;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
removeTrailingLineBreaks(elements);
|
|
103
|
+
|
|
104
|
+
return { elements, consumed };
|
|
105
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Element } from "@wdprlib/ast";
|
|
2
|
+
import type { ParseContext } from "../../types";
|
|
3
|
+
import { isNonBoundaryBlockToken } from "./non-boundary";
|
|
4
|
+
|
|
5
|
+
export interface InlineNewlineResult {
|
|
6
|
+
consumed: number;
|
|
7
|
+
addLineBreak: boolean;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function consumeInlineContentNewlines(
|
|
11
|
+
ctx: ParseContext,
|
|
12
|
+
startPos: number,
|
|
13
|
+
): InlineNewlineResult {
|
|
14
|
+
let pos = startPos + 1;
|
|
15
|
+
let consumed = 1;
|
|
16
|
+
|
|
17
|
+
while (ctx.tokens[pos]?.type === "NEWLINE") {
|
|
18
|
+
pos++;
|
|
19
|
+
consumed++;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const nextToken = ctx.tokens[pos];
|
|
23
|
+
if (!nextToken || nextToken.type === "EOF") {
|
|
24
|
+
return { consumed, addLineBreak: false };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (nextToken.type === "BLOCK_OPEN" || nextToken.type === "BLOCK_END_OPEN") {
|
|
28
|
+
const peekCtx: ParseContext = { ...ctx, pos };
|
|
29
|
+
if (!isNonBoundaryBlockToken(peekCtx, pos)) {
|
|
30
|
+
return { consumed, addLineBreak: false };
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return { consumed, addLineBreak: true };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function removeTrailingLineBreaks(elements: Element[]): void {
|
|
38
|
+
while (elements.length > 0 && elements[elements.length - 1]?.element === "line-break") {
|
|
39
|
+
elements.pop();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ParseContext } from "../../types";
|
|
2
|
+
import { KNOWN_BLOCK_NAMES } from "../../../constants";
|
|
3
|
+
import { parseBlockName } from "../utils";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Whether the BLOCK_OPEN / BLOCK_END_OPEN token at `pos` opens a block name
|
|
7
|
+
* that should not end the surrounding paragraph / inline run.
|
|
8
|
+
*/
|
|
9
|
+
export function isNonBoundaryBlockToken(ctx: ParseContext, pos: number): boolean {
|
|
10
|
+
const token = ctx.tokens[pos];
|
|
11
|
+
if (token?.type !== "BLOCK_OPEN" && token?.type !== "BLOCK_END_OPEN") {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const nameResult = parseBlockName(ctx, pos + 1);
|
|
16
|
+
if (nameResult === null) {
|
|
17
|
+
return ctx.tokens[pos + 1]?.type !== "EQUALS";
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (ctx.scope.excludedBlockNames?.has(nameResult.name)) {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
return !KNOWN_BLOCK_NAMES.has(nameResult.name);
|
|
24
|
+
}
|