@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
|
@@ -1,726 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* Block rule for the explicit block-syntax table:
|
|
4
|
-
* `[[table]][[row]][[cell]]...[[/cell]][[/row]][[/table]]`.
|
|
5
|
-
*
|
|
6
|
-
* This is the structured alternative to the pipe-syntax table (`||`).
|
|
7
|
-
* Each element carries optional HTML attributes:
|
|
8
|
-
*
|
|
9
|
-
* ```
|
|
10
|
-
* [[table class="wiki-table"]]
|
|
11
|
-
* [[row]]
|
|
12
|
-
* [[hcell style="width: 50%"]]Header[[/hcell]]
|
|
13
|
-
* [[cell colspan="2"]]Data[[/cell]]
|
|
14
|
-
* [[/row]]
|
|
15
|
-
* [[/table]]
|
|
16
|
-
* ```
|
|
17
|
-
*
|
|
18
|
-
* Key details:
|
|
19
|
-
* - `[[hcell]]` produces header cells (`<th>`), `[[cell]]` produces data
|
|
20
|
-
* cells (`<td>`).
|
|
21
|
-
* - `colspan` is extracted from cell attributes and mapped to `column-span`.
|
|
22
|
-
* - Alignment can be derived from the `style` attribute's `text-align` value.
|
|
23
|
-
* - Cell content supports both block and inline elements, including nested
|
|
24
|
-
* tables. The custom `parseCellContent()` handles paragraph wrapping
|
|
25
|
-
* and block detection within cells.
|
|
26
|
-
* - Empty tables or tables with only empty rows fail the rule, falling
|
|
27
|
-
* back to text rendering.
|
|
28
|
-
* - The table element carries `_source: "block"` in attributes to
|
|
29
|
-
* distinguish it from pipe-syntax tables.
|
|
30
|
-
*
|
|
31
|
-
* @module
|
|
32
|
-
*/
|
|
33
|
-
import type { Element, TableData, TableRow, TableCell, Alignment } from "@wdprlib/ast";
|
|
34
|
-
import type { BlockRule, ParseContext, RuleResult } from "../types";
|
|
35
|
-
import { currentToken } from "../types";
|
|
36
|
-
import { parseBlockName, parseAttributes, canApplyBlockRule } from "./utils";
|
|
37
|
-
import { canApplyInlineRule } from "../inline/utils";
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Block rule for `[[table]]...[[/table]]` with `[[row]]` and
|
|
41
|
-
* `[[cell]]`/`[[hcell]]` children.
|
|
42
|
-
*/
|
|
43
|
-
export const tableBlockRule: BlockRule = {
|
|
44
|
-
name: "table-block",
|
|
45
|
-
startTokens: ["BLOCK_OPEN"],
|
|
46
|
-
requiresLineStart: false,
|
|
47
|
-
|
|
48
|
-
parse(ctx: ParseContext): RuleResult<Element> {
|
|
49
|
-
const openToken = currentToken(ctx);
|
|
50
|
-
if (openToken.type !== "BLOCK_OPEN") {
|
|
51
|
-
return { success: false };
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
let pos = ctx.pos + 1;
|
|
55
|
-
let consumed = 1;
|
|
56
|
-
|
|
57
|
-
// Parse block name
|
|
58
|
-
const nameResult = parseBlockName(ctx, pos);
|
|
59
|
-
if (!nameResult || nameResult.name !== "table") {
|
|
60
|
-
return { success: false };
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
pos += nameResult.consumed;
|
|
64
|
-
consumed += nameResult.consumed;
|
|
65
|
-
|
|
66
|
-
// Parse attributes
|
|
67
|
-
const attrResult = parseAttributes(ctx, pos);
|
|
68
|
-
pos += attrResult.consumed;
|
|
69
|
-
consumed += attrResult.consumed;
|
|
70
|
-
|
|
71
|
-
// Expect ]]
|
|
72
|
-
if (ctx.tokens[pos]?.type !== "BLOCK_CLOSE") {
|
|
73
|
-
return { success: false };
|
|
74
|
-
}
|
|
75
|
-
pos++;
|
|
76
|
-
consumed++;
|
|
77
|
-
|
|
78
|
-
// Skip optional newline after [[table]]
|
|
79
|
-
if (ctx.tokens[pos]?.type === "NEWLINE") {
|
|
80
|
-
pos++;
|
|
81
|
-
consumed++;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Parse rows
|
|
85
|
-
const rows: TableRow[] = [];
|
|
86
|
-
let foundTableClose = false;
|
|
87
|
-
|
|
88
|
-
while (pos < ctx.tokens.length) {
|
|
89
|
-
// Skip whitespace and newlines
|
|
90
|
-
while (ctx.tokens[pos]?.type === "WHITESPACE" || ctx.tokens[pos]?.type === "NEWLINE") {
|
|
91
|
-
pos++;
|
|
92
|
-
consumed++;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const token = ctx.tokens[pos];
|
|
96
|
-
if (!token || token.type === "EOF") {
|
|
97
|
-
break;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// Check for [[/table]]
|
|
101
|
-
if (token.type === "BLOCK_END_OPEN") {
|
|
102
|
-
const closeNameResult = parseBlockName(ctx, pos + 1);
|
|
103
|
-
if (closeNameResult?.name === "table") {
|
|
104
|
-
foundTableClose = true;
|
|
105
|
-
// Consume [[/table]]
|
|
106
|
-
pos++; // [[/
|
|
107
|
-
consumed++;
|
|
108
|
-
pos += closeNameResult.consumed; // table
|
|
109
|
-
consumed += closeNameResult.consumed;
|
|
110
|
-
if (ctx.tokens[pos]?.type === "BLOCK_CLOSE") {
|
|
111
|
-
pos++;
|
|
112
|
-
consumed++;
|
|
113
|
-
}
|
|
114
|
-
if (ctx.tokens[pos]?.type === "NEWLINE") {
|
|
115
|
-
pos++;
|
|
116
|
-
consumed++;
|
|
117
|
-
}
|
|
118
|
-
break;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// Check for [[row]]
|
|
123
|
-
if (token.type === "BLOCK_OPEN") {
|
|
124
|
-
const rowNameResult = parseBlockName(ctx, pos + 1);
|
|
125
|
-
if (rowNameResult?.name === "row") {
|
|
126
|
-
const rowResult = parseRow(ctx, pos);
|
|
127
|
-
if (rowResult) {
|
|
128
|
-
rows.push(rowResult.row);
|
|
129
|
-
pos += rowResult.consumed;
|
|
130
|
-
consumed += rowResult.consumed;
|
|
131
|
-
continue;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// Unknown token, skip to avoid infinite loop
|
|
137
|
-
pos++;
|
|
138
|
-
consumed++;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
if (!foundTableClose) {
|
|
142
|
-
ctx.diagnostics.push({
|
|
143
|
-
severity: "warning",
|
|
144
|
-
code: "unclosed-block",
|
|
145
|
-
message: "Missing closing tag [[/table]] for [[table]]",
|
|
146
|
-
position: openToken.position,
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Wikidot behavior: empty tables or tables with only empty rows are not parsed
|
|
151
|
-
// They should be treated as plain text instead
|
|
152
|
-
const hasValidContent = rows.some((row) => row.cells.length > 0);
|
|
153
|
-
if (!hasValidContent) {
|
|
154
|
-
return { success: false };
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
const tableData: TableData = {
|
|
158
|
-
attributes: { ...attrResult.attrs, _source: "block" },
|
|
159
|
-
rows,
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
return {
|
|
163
|
-
success: true,
|
|
164
|
-
elements: [
|
|
165
|
-
{
|
|
166
|
-
element: "table",
|
|
167
|
-
data: tableData,
|
|
168
|
-
},
|
|
169
|
-
],
|
|
170
|
-
consumed,
|
|
171
|
-
};
|
|
172
|
-
},
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Parses a `[[row ...]]...[[/row]]` block, collecting its child cells.
|
|
177
|
-
*
|
|
178
|
-
* Row attributes (e.g. `class`, `style`) are passed through to the AST.
|
|
179
|
-
* The function skips whitespace/newlines between cells and stops when
|
|
180
|
-
* `[[/row]]` is found or the token stream ends.
|
|
181
|
-
*
|
|
182
|
-
* @param ctx - Parse context.
|
|
183
|
-
* @param startPos - Token index at the `[[row]]` BLOCK_OPEN.
|
|
184
|
-
* @returns The parsed row and consumed count, or `null` on failure.
|
|
185
|
-
*/
|
|
186
|
-
function parseRow(ctx: ParseContext, startPos: number): { row: TableRow; consumed: number } | null {
|
|
187
|
-
let pos = startPos;
|
|
188
|
-
let consumed = 0;
|
|
189
|
-
|
|
190
|
-
// Expect [[row]]
|
|
191
|
-
if (ctx.tokens[pos]?.type !== "BLOCK_OPEN") {
|
|
192
|
-
return null;
|
|
193
|
-
}
|
|
194
|
-
pos++;
|
|
195
|
-
consumed++;
|
|
196
|
-
|
|
197
|
-
const nameResult = parseBlockName(ctx, pos);
|
|
198
|
-
if (!nameResult || nameResult.name !== "row") {
|
|
199
|
-
return null;
|
|
200
|
-
}
|
|
201
|
-
pos += nameResult.consumed;
|
|
202
|
-
consumed += nameResult.consumed;
|
|
203
|
-
|
|
204
|
-
// Parse row attributes
|
|
205
|
-
const attrResult = parseAttributes(ctx, pos);
|
|
206
|
-
pos += attrResult.consumed;
|
|
207
|
-
consumed += attrResult.consumed;
|
|
208
|
-
|
|
209
|
-
if (ctx.tokens[pos]?.type !== "BLOCK_CLOSE") {
|
|
210
|
-
return null;
|
|
211
|
-
}
|
|
212
|
-
pos++;
|
|
213
|
-
consumed++;
|
|
214
|
-
|
|
215
|
-
// Skip optional newline
|
|
216
|
-
if (ctx.tokens[pos]?.type === "NEWLINE") {
|
|
217
|
-
pos++;
|
|
218
|
-
consumed++;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
// Parse cells
|
|
222
|
-
const cells: TableCell[] = [];
|
|
223
|
-
let foundRowClose = false;
|
|
224
|
-
|
|
225
|
-
while (pos < ctx.tokens.length) {
|
|
226
|
-
// Skip whitespace and newlines
|
|
227
|
-
while (ctx.tokens[pos]?.type === "WHITESPACE" || ctx.tokens[pos]?.type === "NEWLINE") {
|
|
228
|
-
pos++;
|
|
229
|
-
consumed++;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
const token = ctx.tokens[pos];
|
|
233
|
-
if (!token || token.type === "EOF") {
|
|
234
|
-
break;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
// Check for [[/row]]
|
|
238
|
-
if (token.type === "BLOCK_END_OPEN") {
|
|
239
|
-
const closeNameResult = parseBlockName(ctx, pos + 1);
|
|
240
|
-
if (closeNameResult?.name === "row") {
|
|
241
|
-
foundRowClose = true;
|
|
242
|
-
// Consume [[/row]]
|
|
243
|
-
pos++;
|
|
244
|
-
consumed++;
|
|
245
|
-
pos += closeNameResult.consumed;
|
|
246
|
-
consumed += closeNameResult.consumed;
|
|
247
|
-
if (ctx.tokens[pos]?.type === "BLOCK_CLOSE") {
|
|
248
|
-
pos++;
|
|
249
|
-
consumed++;
|
|
250
|
-
}
|
|
251
|
-
if (ctx.tokens[pos]?.type === "NEWLINE") {
|
|
252
|
-
pos++;
|
|
253
|
-
consumed++;
|
|
254
|
-
}
|
|
255
|
-
break;
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
// Check for [[cell]] or [[hcell]]
|
|
260
|
-
if (token.type === "BLOCK_OPEN") {
|
|
261
|
-
const cellNameResult = parseBlockName(ctx, pos + 1);
|
|
262
|
-
if (cellNameResult?.name === "cell" || cellNameResult?.name === "hcell") {
|
|
263
|
-
const cellResult = parseCell(ctx, pos);
|
|
264
|
-
if (cellResult) {
|
|
265
|
-
cells.push(cellResult.cell);
|
|
266
|
-
pos += cellResult.consumed;
|
|
267
|
-
consumed += cellResult.consumed;
|
|
268
|
-
continue;
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
// Unknown token, skip
|
|
274
|
-
pos++;
|
|
275
|
-
consumed++;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
if (!foundRowClose) {
|
|
279
|
-
ctx.diagnostics.push({
|
|
280
|
-
severity: "warning",
|
|
281
|
-
code: "unclosed-block",
|
|
282
|
-
message: "Missing closing tag [[/row]] for [[row]]",
|
|
283
|
-
position: ctx.tokens[startPos]?.position ?? {
|
|
284
|
-
start: { line: 0, column: 0, offset: 0 },
|
|
285
|
-
end: { line: 0, column: 0, offset: 0 },
|
|
286
|
-
},
|
|
287
|
-
});
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
return {
|
|
291
|
-
row: {
|
|
292
|
-
attributes: attrResult.attrs,
|
|
293
|
-
cells,
|
|
294
|
-
},
|
|
295
|
-
consumed,
|
|
296
|
-
};
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
/**
|
|
300
|
-
* Parses a `[[cell ...]]...[[/cell]]` or `[[hcell ...]]...[[/hcell]]` block.
|
|
301
|
-
*
|
|
302
|
-
* Cell body content is parsed via `parseCellContent()`, which supports
|
|
303
|
-
* block elements (including nested tables), inline markup, and paragraph
|
|
304
|
-
* breaks. After parsing, simple single-paragraph content is unwrapped
|
|
305
|
-
* to match Wikidot's behaviour of not wrapping simple cells in `<p>`.
|
|
306
|
-
*
|
|
307
|
-
* The `colspan` attribute is extracted separately and mapped to
|
|
308
|
-
* `column-span` in the AST. Other attributes (rowspan, style, etc.) are
|
|
309
|
-
* kept in the attributes map for the renderer.
|
|
310
|
-
*
|
|
311
|
-
* @param ctx - Parse context.
|
|
312
|
-
* @param startPos - Token index at the `[[cell]]`/`[[hcell]]` BLOCK_OPEN.
|
|
313
|
-
* @returns The parsed cell and consumed count, or `null` on failure.
|
|
314
|
-
*/
|
|
315
|
-
function parseCell(
|
|
316
|
-
ctx: ParseContext,
|
|
317
|
-
startPos: number,
|
|
318
|
-
): { cell: TableCell; consumed: number } | null {
|
|
319
|
-
let pos = startPos;
|
|
320
|
-
let consumed = 0;
|
|
321
|
-
|
|
322
|
-
// Expect [[cell]] or [[hcell]]
|
|
323
|
-
if (ctx.tokens[pos]?.type !== "BLOCK_OPEN") {
|
|
324
|
-
return null;
|
|
325
|
-
}
|
|
326
|
-
pos++;
|
|
327
|
-
consumed++;
|
|
328
|
-
|
|
329
|
-
const nameResult = parseBlockName(ctx, pos);
|
|
330
|
-
if (!nameResult || (nameResult.name !== "cell" && nameResult.name !== "hcell")) {
|
|
331
|
-
return null;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
const isHeader = nameResult.name === "hcell";
|
|
335
|
-
pos += nameResult.consumed;
|
|
336
|
-
consumed += nameResult.consumed;
|
|
337
|
-
|
|
338
|
-
// Parse cell attributes
|
|
339
|
-
const attrResult = parseAttributes(ctx, pos);
|
|
340
|
-
pos += attrResult.consumed;
|
|
341
|
-
consumed += attrResult.consumed;
|
|
342
|
-
|
|
343
|
-
// Extract colspan from attributes (rowspan stays in attributes for renderer)
|
|
344
|
-
const colspan = attrResult.attrs.colspan ? parseInt(attrResult.attrs.colspan, 10) : 1;
|
|
345
|
-
|
|
346
|
-
// Extract alignment from style attribute
|
|
347
|
-
let align: Alignment | null = null;
|
|
348
|
-
const style = attrResult.attrs.style;
|
|
349
|
-
if (style) {
|
|
350
|
-
const alignMatch = style.match(/text-align:\s*(left|center|right)/i);
|
|
351
|
-
if (alignMatch) {
|
|
352
|
-
align = alignMatch[1]?.toLowerCase() as Alignment;
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
// Remove colspan from attributes (it's handled separately via column-span)
|
|
357
|
-
const cellAttrs = { ...attrResult.attrs };
|
|
358
|
-
delete cellAttrs.colspan;
|
|
359
|
-
|
|
360
|
-
if (ctx.tokens[pos]?.type !== "BLOCK_CLOSE") {
|
|
361
|
-
return null;
|
|
362
|
-
}
|
|
363
|
-
pos++;
|
|
364
|
-
consumed++;
|
|
365
|
-
|
|
366
|
-
// Skip optional newline after [[cell]]
|
|
367
|
-
if (ctx.tokens[pos]?.type === "NEWLINE") {
|
|
368
|
-
pos++;
|
|
369
|
-
consumed++;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
const closeName = isHeader ? "hcell" : "cell";
|
|
373
|
-
|
|
374
|
-
// Close condition for [[/cell]] or [[/hcell]]
|
|
375
|
-
const closeCondition = (checkCtx: ParseContext): boolean => {
|
|
376
|
-
const token = checkCtx.tokens[checkCtx.pos];
|
|
377
|
-
if (token?.type === "BLOCK_END_OPEN") {
|
|
378
|
-
const closeNameResult = parseBlockName(checkCtx, checkCtx.pos + 1);
|
|
379
|
-
if (closeNameResult?.name === closeName) {
|
|
380
|
-
return true;
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
return false;
|
|
384
|
-
};
|
|
385
|
-
|
|
386
|
-
// Parse cell content using parseCellContent (supports inline blocks like nested tables)
|
|
387
|
-
const bodyCtx: ParseContext = { ...ctx, pos };
|
|
388
|
-
const bodyResult = parseCellContent(bodyCtx, closeCondition);
|
|
389
|
-
consumed += bodyResult.consumed;
|
|
390
|
-
pos += bodyResult.consumed;
|
|
391
|
-
const hadParagraphBreaks = bodyResult.hadParagraphBreaks;
|
|
392
|
-
|
|
393
|
-
// Check for missing close tag
|
|
394
|
-
if (ctx.tokens[pos]?.type !== "BLOCK_END_OPEN") {
|
|
395
|
-
ctx.diagnostics.push({
|
|
396
|
-
severity: "warning",
|
|
397
|
-
code: "unclosed-block",
|
|
398
|
-
message: `Missing closing tag [[/${closeName}]] for [[${closeName}]]`,
|
|
399
|
-
position: ctx.tokens[startPos]?.position ?? {
|
|
400
|
-
start: { line: 0, column: 0, offset: 0 },
|
|
401
|
-
end: { line: 0, column: 0, offset: 0 },
|
|
402
|
-
},
|
|
403
|
-
});
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
// Consume [[/cell]] or [[/hcell]]
|
|
407
|
-
if (ctx.tokens[pos]?.type === "BLOCK_END_OPEN") {
|
|
408
|
-
pos++;
|
|
409
|
-
consumed++;
|
|
410
|
-
const closeNameResult = parseBlockName(ctx, pos);
|
|
411
|
-
if (closeNameResult) {
|
|
412
|
-
pos += closeNameResult.consumed;
|
|
413
|
-
consumed += closeNameResult.consumed;
|
|
414
|
-
}
|
|
415
|
-
if (ctx.tokens[pos]?.type === "BLOCK_CLOSE") {
|
|
416
|
-
pos++;
|
|
417
|
-
consumed++;
|
|
418
|
-
}
|
|
419
|
-
if (ctx.tokens[pos]?.type === "NEWLINE") {
|
|
420
|
-
pos++;
|
|
421
|
-
consumed++;
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
// Process cell elements: unwrap single paragraph if it contains only inline elements
|
|
426
|
-
// Wikidot behavior:
|
|
427
|
-
// - Simple inline content (no newlines/blank lines) → direct elements (no paragraph wrapper)
|
|
428
|
-
// - Content with blank lines or blocks → keep paragraph wrappers
|
|
429
|
-
const processedElements = hadParagraphBreaks
|
|
430
|
-
? bodyResult.elements
|
|
431
|
-
: unwrapSingleInlineParagraph(bodyResult.elements);
|
|
432
|
-
|
|
433
|
-
return {
|
|
434
|
-
cell: {
|
|
435
|
-
header: isHeader,
|
|
436
|
-
"column-span": colspan,
|
|
437
|
-
align,
|
|
438
|
-
attributes: cellAttrs,
|
|
439
|
-
elements: processedElements,
|
|
440
|
-
},
|
|
441
|
-
consumed,
|
|
442
|
-
};
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
/**
|
|
446
|
-
* Unwraps a single-paragraph cell body to match Wikidot's rendering.
|
|
447
|
-
*
|
|
448
|
-
* When a cell contains exactly one paragraph with no block-level children,
|
|
449
|
-
* the paragraph wrapper is removed and its inner elements are returned
|
|
450
|
-
* directly. This produces output like `<td>text</td>` instead of
|
|
451
|
-
* `<td><p>text</p></td>`.
|
|
452
|
-
*
|
|
453
|
-
* If there are multiple elements, block children, or non-paragraph content,
|
|
454
|
-
* the array is returned as-is.
|
|
455
|
-
*
|
|
456
|
-
* @param elements - The parsed cell body elements.
|
|
457
|
-
* @returns Elements with the single paragraph unwrapped, if applicable.
|
|
458
|
-
*/
|
|
459
|
-
function unwrapSingleInlineParagraph(elements: Element[]): Element[] {
|
|
460
|
-
// Only unwrap if there's exactly one element and it's a paragraph container
|
|
461
|
-
if (elements.length !== 1) {
|
|
462
|
-
return elements;
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
const first = elements[0];
|
|
466
|
-
if (
|
|
467
|
-
first?.element !== "container" ||
|
|
468
|
-
typeof first.data !== "object" ||
|
|
469
|
-
first.data === null ||
|
|
470
|
-
!("type" in first.data) ||
|
|
471
|
-
first.data.type !== "paragraph"
|
|
472
|
-
) {
|
|
473
|
-
return elements;
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
// Check if paragraph contains any block elements
|
|
477
|
-
// If it does, keep the paragraph wrapper
|
|
478
|
-
const paragraphData = first.data as { elements?: Element[] };
|
|
479
|
-
const innerElements = paragraphData.elements ?? [];
|
|
480
|
-
|
|
481
|
-
const hasBlockElement = innerElements.some((el) => isBlockElement(el));
|
|
482
|
-
if (hasBlockElement) {
|
|
483
|
-
return elements;
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
// Unwrap: return the paragraph's inner elements directly
|
|
487
|
-
return innerElements;
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
/**
|
|
491
|
-
* Determines whether an element is block-level.
|
|
492
|
-
*
|
|
493
|
-
* Block elements (tables, divs, blockquotes, code, etc.) prevent the
|
|
494
|
-
* single-paragraph unwrapping optimisation in {@link unwrapSingleInlineParagraph}.
|
|
495
|
-
*
|
|
496
|
-
* @param el - The element to test.
|
|
497
|
-
* @returns `true` if the element is block-level.
|
|
498
|
-
*/
|
|
499
|
-
function isBlockElement(el: Element): boolean {
|
|
500
|
-
// Block elements that should prevent unwrapping
|
|
501
|
-
const blockTypes = ["table", "div", "blockquote", "code", "list", "iframe", "image-block"];
|
|
502
|
-
|
|
503
|
-
if (blockTypes.includes(el.element)) {
|
|
504
|
-
return true;
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
// Also check for container types that are block-level
|
|
508
|
-
if (el.element === "container" && typeof el.data === "object" && el.data !== null) {
|
|
509
|
-
const data = el.data as { type?: string };
|
|
510
|
-
if (data.type === "paragraph" || data.type === "div" || data.type === "blockquote") {
|
|
511
|
-
return true;
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
return false;
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
/**
|
|
519
|
-
* Parses cell body content with support for both inline and block elements.
|
|
520
|
-
*
|
|
521
|
-
* Unlike the general {@link parseBlocksUntil}, this function recognises
|
|
522
|
-
* block elements (nested tables, divs, etc.) even when they do not appear
|
|
523
|
-
* at line start, because cell content inside `[[cell]]` is treated more
|
|
524
|
-
* permissively by Wikidot.
|
|
525
|
-
*
|
|
526
|
-
* Paragraph handling:
|
|
527
|
-
* - Simple inline content on a single line is NOT wrapped in a paragraph.
|
|
528
|
-
* - A blank line (double newline) creates a paragraph break.
|
|
529
|
-
* - Block elements flush the current inline segment into a paragraph
|
|
530
|
-
* and are emitted as standalone elements.
|
|
531
|
-
*
|
|
532
|
-
* The `hadParagraphBreaks` flag in the return value tells the caller
|
|
533
|
-
* whether any blank-line paragraph breaks occurred, which influences
|
|
534
|
-
* whether the final result keeps paragraph wrappers.
|
|
535
|
-
*
|
|
536
|
-
* @param ctx - Parse context.
|
|
537
|
-
* @param closeCondition - Predicate that returns `true` at the cell's
|
|
538
|
-
* closing tag (`[[/cell]]` or `[[/hcell]]`).
|
|
539
|
-
* @returns Parsed elements, consumed count, and paragraph-break flag.
|
|
540
|
-
*/
|
|
541
|
-
function parseCellContent(
|
|
542
|
-
ctx: ParseContext,
|
|
543
|
-
closeCondition: (ctx: ParseContext) => boolean,
|
|
544
|
-
): { elements: Element[]; consumed: number; hadParagraphBreaks: boolean } {
|
|
545
|
-
const elements: Element[] = [];
|
|
546
|
-
let consumed = 0;
|
|
547
|
-
let pos = ctx.pos;
|
|
548
|
-
|
|
549
|
-
// Collect inline content segments
|
|
550
|
-
let currentSegment: Element[] = [];
|
|
551
|
-
// Track if content spans multiple "parts" (blocks, blank lines, or newlines before blocks)
|
|
552
|
-
let hasMultipleParts = false;
|
|
553
|
-
// Track if we've added any block element
|
|
554
|
-
let hasBlockElement = false;
|
|
555
|
-
// Track if we've seen any blank line (paragraph break)
|
|
556
|
-
let hadParagraphBreaks = false;
|
|
557
|
-
|
|
558
|
-
const flushSegment = (wrapInParagraph: boolean) => {
|
|
559
|
-
if (currentSegment.length === 0) return;
|
|
560
|
-
|
|
561
|
-
// Trim trailing whitespace and line-breaks
|
|
562
|
-
while (currentSegment.length > 0) {
|
|
563
|
-
const last = currentSegment[currentSegment.length - 1];
|
|
564
|
-
if (last?.element === "text" && typeof last.data === "string" && last.data.trim() === "") {
|
|
565
|
-
currentSegment.pop();
|
|
566
|
-
} else if (last?.element === "line-break") {
|
|
567
|
-
currentSegment.pop();
|
|
568
|
-
} else {
|
|
569
|
-
break;
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
// Trim leading whitespace
|
|
574
|
-
while (currentSegment.length > 0) {
|
|
575
|
-
const first = currentSegment[0];
|
|
576
|
-
if (first?.element === "text" && typeof first.data === "string" && first.data.trim() === "") {
|
|
577
|
-
currentSegment.shift();
|
|
578
|
-
} else {
|
|
579
|
-
break;
|
|
580
|
-
}
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
if (currentSegment.length === 0) return;
|
|
584
|
-
|
|
585
|
-
if (wrapInParagraph) {
|
|
586
|
-
elements.push({
|
|
587
|
-
element: "container",
|
|
588
|
-
data: {
|
|
589
|
-
type: "paragraph",
|
|
590
|
-
attributes: {},
|
|
591
|
-
elements: [...currentSegment],
|
|
592
|
-
},
|
|
593
|
-
});
|
|
594
|
-
} else {
|
|
595
|
-
elements.push(...currentSegment);
|
|
596
|
-
}
|
|
597
|
-
currentSegment = [];
|
|
598
|
-
};
|
|
599
|
-
|
|
600
|
-
while (pos < ctx.tokens.length) {
|
|
601
|
-
const token = ctx.tokens[pos];
|
|
602
|
-
if (!token || token.type === "EOF") {
|
|
603
|
-
break;
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
-
// Check close condition
|
|
607
|
-
const checkCtx: ParseContext = { ...ctx, pos };
|
|
608
|
-
if (closeCondition(checkCtx)) {
|
|
609
|
-
break;
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
// Handle newlines
|
|
613
|
-
if (token.type === "NEWLINE") {
|
|
614
|
-
pos++;
|
|
615
|
-
consumed++;
|
|
616
|
-
|
|
617
|
-
// Check for blank line (paragraph break)
|
|
618
|
-
if (ctx.tokens[pos]?.type === "NEWLINE") {
|
|
619
|
-
// Skip additional newlines
|
|
620
|
-
while (ctx.tokens[pos]?.type === "NEWLINE") {
|
|
621
|
-
pos++;
|
|
622
|
-
consumed++;
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
// Flush current segment as paragraph
|
|
626
|
-
flushSegment(true);
|
|
627
|
-
// Blank line means all subsequent content should be in paragraphs
|
|
628
|
-
hasMultipleParts = true;
|
|
629
|
-
hadParagraphBreaks = true;
|
|
630
|
-
|
|
631
|
-
// Skip whitespace after blank line
|
|
632
|
-
while (ctx.tokens[pos]?.type === "WHITESPACE") {
|
|
633
|
-
pos++;
|
|
634
|
-
consumed++;
|
|
635
|
-
}
|
|
636
|
-
continue;
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
// Single newline - check if next is block start or close
|
|
640
|
-
const nextToken = ctx.tokens[pos];
|
|
641
|
-
if (!nextToken || nextToken.type === "BLOCK_END_OPEN" || nextToken.type === "EOF") {
|
|
642
|
-
continue;
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
// Check if next token would start a block
|
|
646
|
-
if (nextToken.type === "BLOCK_OPEN") {
|
|
647
|
-
// This newline separates text from block - flush as paragraph
|
|
648
|
-
flushSegment(true);
|
|
649
|
-
hasMultipleParts = true;
|
|
650
|
-
continue;
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
// If we have no content yet, this is just leading whitespace - skip
|
|
654
|
-
if (currentSegment.length === 0 && elements.length === 0) {
|
|
655
|
-
continue;
|
|
656
|
-
}
|
|
657
|
-
|
|
658
|
-
// Otherwise, treat as line break within same segment
|
|
659
|
-
currentSegment.push({ element: "line-break" });
|
|
660
|
-
continue;
|
|
661
|
-
}
|
|
662
|
-
|
|
663
|
-
// Skip whitespace at line start
|
|
664
|
-
if (token.type === "WHITESPACE" && token.lineStart) {
|
|
665
|
-
pos++;
|
|
666
|
-
consumed++;
|
|
667
|
-
continue;
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
// Try block rules first (for nested tables, divs, etc.)
|
|
671
|
-
let matched = false;
|
|
672
|
-
const blockCtx: ParseContext = { ...ctx, pos };
|
|
673
|
-
|
|
674
|
-
for (const rule of ctx.blockRules) {
|
|
675
|
-
if (canApplyBlockRule(rule, token)) {
|
|
676
|
-
const result = rule.parse(blockCtx);
|
|
677
|
-
if (result.success) {
|
|
678
|
-
// Flush current segment before adding block
|
|
679
|
-
if (currentSegment.length > 0) {
|
|
680
|
-
flushSegment(true);
|
|
681
|
-
hasMultipleParts = true;
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
elements.push(...result.elements);
|
|
685
|
-
hasBlockElement = true;
|
|
686
|
-
hasMultipleParts = true;
|
|
687
|
-
consumed += result.consumed;
|
|
688
|
-
pos += result.consumed;
|
|
689
|
-
matched = true;
|
|
690
|
-
break;
|
|
691
|
-
}
|
|
692
|
-
}
|
|
693
|
-
}
|
|
694
|
-
|
|
695
|
-
if (matched) continue;
|
|
696
|
-
|
|
697
|
-
// Try inline rules
|
|
698
|
-
const inlineCtx: ParseContext = { ...ctx, pos };
|
|
699
|
-
|
|
700
|
-
for (const rule of ctx.inlineRules) {
|
|
701
|
-
if (canApplyInlineRule(rule, token)) {
|
|
702
|
-
const result = rule.parse(inlineCtx);
|
|
703
|
-
if (result.success) {
|
|
704
|
-
currentSegment.push(...result.elements);
|
|
705
|
-
consumed += result.consumed;
|
|
706
|
-
pos += result.consumed;
|
|
707
|
-
matched = true;
|
|
708
|
-
break;
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
if (!matched) {
|
|
714
|
-
// Fallback to text
|
|
715
|
-
currentSegment.push({ element: "text", data: token.value });
|
|
716
|
-
consumed++;
|
|
717
|
-
pos++;
|
|
718
|
-
}
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
// Flush remaining segment
|
|
722
|
-
// Wrap in paragraph if we had multiple parts or block elements
|
|
723
|
-
flushSegment(hasMultipleParts || hasBlockElement);
|
|
724
|
-
|
|
725
|
-
return { elements, consumed, hadParagraphBreaks };
|
|
726
|
-
}
|