@temelj/mdx 0.14.0 → 0.16.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/README.md +470 -82
- package/dist/character-entities.d.mts +4 -0
- package/dist/character-entities.d.mts.map +1 -0
- package/dist/character-entities.mjs +2132 -0
- package/dist/character-entities.mjs.map +1 -0
- package/dist/character-reference.d.mts +6 -0
- package/dist/character-reference.d.mts.map +1 -0
- package/dist/character-reference.mjs +18 -0
- package/dist/character-reference.mjs.map +1 -0
- package/dist/compile-analysis.d.mts +28 -0
- package/dist/compile-analysis.d.mts.map +1 -0
- package/dist/compile-analysis.mjs +74 -0
- package/dist/compile-analysis.mjs.map +1 -0
- package/dist/compile-emit.d.mts +9 -0
- package/dist/compile-emit.d.mts.map +1 -0
- package/dist/compile-emit.mjs +187 -0
- package/dist/compile-emit.mjs.map +1 -0
- package/dist/compile-esm.d.mts +34 -0
- package/dist/compile-esm.d.mts.map +1 -0
- package/dist/compile-esm.mjs +187 -0
- package/dist/compile-esm.mjs.map +1 -0
- package/dist/compile-names.d.mts +13 -0
- package/dist/compile-names.d.mts.map +1 -0
- package/dist/compile-names.mjs +32 -0
- package/dist/compile-names.mjs.map +1 -0
- package/dist/compiler.d.mts +69 -85
- package/dist/compiler.d.mts.map +1 -1
- package/dist/compiler.mjs +167 -420
- package/dist/compiler.mjs.map +1 -1
- package/dist/diagnostics.d.mts +37 -0
- package/dist/diagnostics.d.mts.map +1 -0
- package/dist/diagnostics.mjs +57 -0
- package/dist/diagnostics.mjs.map +1 -0
- package/dist/errors.d.mts +157 -0
- package/dist/errors.d.mts.map +1 -0
- package/dist/errors.mjs +263 -0
- package/dist/errors.mjs.map +1 -0
- package/dist/footnote-numbering.d.mts +27 -0
- package/dist/footnote-numbering.d.mts.map +1 -0
- package/dist/footnote-numbering.mjs +49 -0
- package/dist/footnote-numbering.mjs.map +1 -0
- package/dist/format-context.d.mts +46 -0
- package/dist/format-context.d.mts.map +1 -0
- package/dist/format-context.mjs +26 -0
- package/dist/format-context.mjs.map +1 -0
- package/dist/format-directive.d.mts +9 -0
- package/dist/format-directive.d.mts.map +1 -0
- package/dist/format-directive.mjs +99 -0
- package/dist/format-directive.mjs.map +1 -0
- package/dist/format-jsx.d.mts +8 -0
- package/dist/format-jsx.d.mts.map +1 -0
- package/dist/format-jsx.mjs +47 -0
- package/dist/format-jsx.mjs.map +1 -0
- package/dist/format-math.d.mts +9 -0
- package/dist/format-math.d.mts.map +1 -0
- package/dist/format-math.mjs +79 -0
- package/dist/format-math.mjs.map +1 -0
- package/dist/format-safe.d.mts +25 -0
- package/dist/format-safe.d.mts.map +1 -0
- package/dist/format-safe.mjs +366 -0
- package/dist/format-safe.mjs.map +1 -0
- package/dist/format-table.d.mts +8 -0
- package/dist/format-table.d.mts.map +1 -0
- package/dist/format-table.mjs +55 -0
- package/dist/format-table.mjs.map +1 -0
- package/dist/format-track.d.mts +18 -0
- package/dist/format-track.d.mts.map +1 -0
- package/dist/format-track.mjs +34 -0
- package/dist/format-track.mjs.map +1 -0
- package/dist/format.d.mts +7 -0
- package/dist/format.d.mts.map +1 -0
- package/dist/format.mjs +549 -0
- package/dist/format.mjs.map +1 -0
- package/dist/frontmatter-decode.d.mts +15 -0
- package/dist/frontmatter-decode.d.mts.map +1 -0
- package/dist/frontmatter-decode.mjs +187 -0
- package/dist/frontmatter-decode.mjs.map +1 -0
- package/dist/frontmatter-schema.d.mts +8 -0
- package/dist/frontmatter-schema.d.mts.map +1 -0
- package/dist/frontmatter-schema.mjs +28 -0
- package/dist/frontmatter-schema.mjs.map +1 -0
- package/dist/frontmatter.d.mts +40 -0
- package/dist/frontmatter.d.mts.map +1 -0
- package/dist/frontmatter.mjs +109 -0
- package/dist/frontmatter.mjs.map +1 -0
- package/dist/heading.d.mts +6 -0
- package/dist/heading.d.mts.map +1 -0
- package/dist/heading.mjs +19 -0
- package/dist/heading.mjs.map +1 -0
- package/dist/html-format.d.mts +32 -0
- package/dist/html-format.d.mts.map +1 -0
- package/dist/html-format.mjs +127 -0
- package/dist/html-format.mjs.map +1 -0
- package/dist/html-lower.d.mts +78 -0
- package/dist/html-lower.d.mts.map +1 -0
- package/dist/html-lower.mjs +583 -0
- package/dist/html-lower.mjs.map +1 -0
- package/dist/html-stream.d.mts +13 -0
- package/dist/html-stream.d.mts.map +1 -0
- package/dist/html-stream.mjs +32 -0
- package/dist/html-stream.mjs.map +1 -0
- package/dist/html.d.mts +120 -0
- package/dist/html.d.mts.map +1 -0
- package/dist/html.mjs +77 -0
- package/dist/html.mjs.map +1 -0
- package/dist/identifier.d.mts +4 -0
- package/dist/identifier.d.mts.map +1 -0
- package/dist/identifier.mjs +8 -0
- package/dist/identifier.mjs.map +1 -0
- package/dist/javascript-ast.d.mts +16 -0
- package/dist/javascript-ast.d.mts.map +1 -0
- package/dist/javascript-ast.mjs +39 -0
- package/dist/javascript-ast.mjs.map +1 -0
- package/dist/javascript-jsx.d.mts +24 -0
- package/dist/javascript-jsx.d.mts.map +1 -0
- package/dist/javascript-jsx.mjs +189 -0
- package/dist/javascript-jsx.mjs.map +1 -0
- package/dist/javascript.d.mts +9 -0
- package/dist/javascript.d.mts.map +1 -0
- package/dist/javascript.mjs +31 -0
- package/dist/javascript.mjs.map +1 -0
- package/dist/jsx-reference.d.mts +15 -0
- package/dist/jsx-reference.d.mts.map +1 -0
- package/dist/jsx-reference.mjs +31 -0
- package/dist/jsx-reference.mjs.map +1 -0
- package/dist/mod.d.mts +26 -9
- package/dist/mod.mjs +20 -8
- package/dist/model.d.mts +196 -0
- package/dist/model.d.mts.map +1 -0
- package/dist/model.mjs +113 -0
- package/dist/model.mjs.map +1 -0
- package/dist/parser/block-container-recognizers.d.mts +40 -0
- package/dist/parser/block-container-recognizers.d.mts.map +1 -0
- package/dist/parser/block-container-recognizers.mjs +90 -0
- package/dist/parser/block-container-recognizers.mjs.map +1 -0
- package/dist/parser/block-directive-recognizers.d.mts +22 -0
- package/dist/parser/block-directive-recognizers.d.mts.map +1 -0
- package/dist/parser/block-directive-recognizers.mjs +77 -0
- package/dist/parser/block-directive-recognizers.mjs.map +1 -0
- package/dist/parser/block-leaf-recognizers.d.mts +53 -0
- package/dist/parser/block-leaf-recognizers.d.mts.map +1 -0
- package/dist/parser/block-leaf-recognizers.mjs +386 -0
- package/dist/parser/block-leaf-recognizers.mjs.map +1 -0
- package/dist/parser/block-parser.d.mts +38 -0
- package/dist/parser/block-parser.d.mts.map +1 -0
- package/dist/parser/block-parser.mjs +895 -0
- package/dist/parser/block-parser.mjs.map +1 -0
- package/dist/parser/block-syntax.d.mts +240 -0
- package/dist/parser/block-syntax.d.mts.map +1 -0
- package/dist/parser/characters.d.mts +19 -0
- package/dist/parser/characters.d.mts.map +1 -0
- package/dist/parser/characters.mjs +52 -0
- package/dist/parser/characters.mjs.map +1 -0
- package/dist/parser/config.d.mts +16 -0
- package/dist/parser/config.d.mts.map +1 -0
- package/dist/parser/config.mjs +25 -0
- package/dist/parser/config.mjs.map +1 -0
- package/dist/parser/directive-attributes.d.mts +9 -0
- package/dist/parser/directive-attributes.d.mts.map +1 -0
- package/dist/parser/directive-attributes.mjs +24 -0
- package/dist/parser/directive-attributes.mjs.map +1 -0
- package/dist/parser/embedded-scanner.d.mts +18 -0
- package/dist/parser/embedded-scanner.d.mts.map +1 -0
- package/dist/parser/embedded-scanner.mjs +199 -0
- package/dist/parser/embedded-scanner.mjs.map +1 -0
- package/dist/parser/inline-autolink.d.mts +7 -0
- package/dist/parser/inline-autolink.d.mts.map +1 -0
- package/dist/parser/inline-autolink.mjs +42 -0
- package/dist/parser/inline-autolink.mjs.map +1 -0
- package/dist/parser/inline-character-reference.d.mts +7 -0
- package/dist/parser/inline-character-reference.d.mts.map +1 -0
- package/dist/parser/inline-character-reference.mjs +22 -0
- package/dist/parser/inline-character-reference.mjs.map +1 -0
- package/dist/parser/inline-code.d.mts +7 -0
- package/dist/parser/inline-code.d.mts.map +1 -0
- package/dist/parser/inline-code.mjs +29 -0
- package/dist/parser/inline-code.mjs.map +1 -0
- package/dist/parser/inline-directive.d.mts +9 -0
- package/dist/parser/inline-directive.d.mts.map +1 -0
- package/dist/parser/inline-directive.mjs +45 -0
- package/dist/parser/inline-directive.mjs.map +1 -0
- package/dist/parser/inline-embedded.d.mts +19 -0
- package/dist/parser/inline-embedded.d.mts.map +1 -0
- package/dist/parser/inline-embedded.mjs +92 -0
- package/dist/parser/inline-embedded.mjs.map +1 -0
- package/dist/parser/inline-emphasis.d.mts +11 -0
- package/dist/parser/inline-emphasis.d.mts.map +1 -0
- package/dist/parser/inline-emphasis.mjs +79 -0
- package/dist/parser/inline-emphasis.mjs.map +1 -0
- package/dist/parser/inline-input.d.mts +46 -0
- package/dist/parser/inline-input.d.mts.map +1 -0
- package/dist/parser/inline-input.mjs +137 -0
- package/dist/parser/inline-input.mjs.map +1 -0
- package/dist/parser/inline-link.d.mts +12 -0
- package/dist/parser/inline-link.d.mts.map +1 -0
- package/dist/parser/inline-link.mjs +187 -0
- package/dist/parser/inline-link.mjs.map +1 -0
- package/dist/parser/inline-math.d.mts +10 -0
- package/dist/parser/inline-math.d.mts.map +1 -0
- package/dist/parser/inline-math.mjs +46 -0
- package/dist/parser/inline-math.mjs.map +1 -0
- package/dist/parser/inline-output.d.mts +34 -0
- package/dist/parser/inline-output.d.mts.map +1 -0
- package/dist/parser/inline-output.mjs +62 -0
- package/dist/parser/inline-output.mjs.map +1 -0
- package/dist/parser/inline-parser.d.mts +14 -0
- package/dist/parser/inline-parser.d.mts.map +1 -0
- package/dist/parser/inline-parser.mjs +328 -0
- package/dist/parser/inline-parser.mjs.map +1 -0
- package/dist/parser/inline-pending.d.mts +23 -0
- package/dist/parser/inline-pending.d.mts.map +1 -0
- package/dist/parser/inline-pending.mjs +100 -0
- package/dist/parser/inline-pending.mjs.map +1 -0
- package/dist/parser/inline-syntax.d.mts +118 -0
- package/dist/parser/inline-syntax.d.mts.map +1 -0
- package/dist/parser/inline-syntax.mjs +1 -0
- package/dist/parser/javascript-boundary.d.mts +16 -0
- package/dist/parser/javascript-boundary.d.mts.map +1 -0
- package/dist/parser/javascript-boundary.mjs +42 -0
- package/dist/parser/javascript-boundary.mjs.map +1 -0
- package/dist/parser/javascript-scanner.d.mts +22 -0
- package/dist/parser/javascript-scanner.d.mts.map +1 -0
- package/dist/parser/javascript-scanner.mjs +122 -0
- package/dist/parser/javascript-scanner.mjs.map +1 -0
- package/dist/parser/materialize-cache.d.mts +34 -0
- package/dist/parser/materialize-cache.d.mts.map +1 -0
- package/dist/parser/materialize-cache.mjs +12 -0
- package/dist/parser/materialize-cache.mjs.map +1 -0
- package/dist/parser/materialize-jsx.d.mts +14 -0
- package/dist/parser/materialize-jsx.d.mts.map +1 -0
- package/dist/parser/materialize-jsx.mjs +76 -0
- package/dist/parser/materialize-jsx.mjs.map +1 -0
- package/dist/parser/materialize.d.mts +61 -0
- package/dist/parser/materialize.d.mts.map +1 -0
- package/dist/parser/materialize.mjs +736 -0
- package/dist/parser/materialize.mjs.map +1 -0
- package/dist/parser/recognizer.d.mts +20 -0
- package/dist/parser/recognizer.d.mts.map +1 -0
- package/dist/parser/recognizer.mjs +24 -0
- package/dist/parser/recognizer.mjs.map +1 -0
- package/dist/parser/session.d.mts +42 -0
- package/dist/parser/session.d.mts.map +1 -0
- package/dist/parser/session.mjs +89 -0
- package/dist/parser/session.mjs.map +1 -0
- package/dist/parser.d.mts +25 -0
- package/dist/parser.d.mts.map +1 -0
- package/dist/parser.mjs +37 -0
- package/dist/parser.mjs.map +1 -0
- package/dist/plugin-internal.d.mts +25 -0
- package/dist/plugin-internal.d.mts.map +1 -0
- package/dist/plugin-internal.mjs +99 -0
- package/dist/plugin-internal.mjs.map +1 -0
- package/dist/plugin.d.mts +37 -0
- package/dist/plugin.d.mts.map +1 -0
- package/dist/plugin.mjs +1 -0
- package/dist/plugins/code-block-metadata.d.mts +42 -0
- package/dist/plugins/code-block-metadata.d.mts.map +1 -0
- package/dist/plugins/code-block-metadata.mjs +133 -0
- package/dist/plugins/code-block-metadata.mjs.map +1 -0
- package/dist/plugins/heading-id.d.mts +15 -0
- package/dist/plugins/heading-id.d.mts.map +1 -0
- package/dist/plugins/heading-id.mjs +45 -0
- package/dist/plugins/heading-id.mjs.map +1 -0
- package/dist/plugins/lower-heading.d.mts +16 -0
- package/dist/plugins/lower-heading.d.mts.map +1 -0
- package/dist/plugins/lower-heading.mjs +28 -0
- package/dist/plugins/lower-heading.mjs.map +1 -0
- package/dist/plugins/math-render.d.mts +26 -0
- package/dist/plugins/math-render.d.mts.map +1 -0
- package/dist/plugins/math-render.mjs +51 -0
- package/dist/plugins/math-render.mjs.map +1 -0
- package/dist/plugins/mod.d.mts +9 -6
- package/dist/plugins/mod.mjs +8 -6
- package/dist/plugins/remove-esm.d.mts +10 -0
- package/dist/plugins/remove-esm.d.mts.map +1 -0
- package/dist/plugins/remove-esm.mjs +12 -0
- package/dist/plugins/remove-esm.mjs.map +1 -0
- package/dist/plugins/shiki.d.mts +21 -0
- package/dist/plugins/shiki.d.mts.map +1 -0
- package/dist/plugins/shiki.mjs +144 -0
- package/dist/plugins/shiki.mjs.map +1 -0
- package/dist/plugins/syntax-highlight.d.mts +38 -0
- package/dist/plugins/syntax-highlight.d.mts.map +1 -0
- package/dist/plugins/syntax-highlight.mjs +106 -0
- package/dist/plugins/syntax-highlight.mjs.map +1 -0
- package/dist/processor.d.mts +60 -0
- package/dist/processor.d.mts.map +1 -0
- package/dist/processor.mjs +106 -0
- package/dist/processor.mjs.map +1 -0
- package/dist/ranges.d.mts +10 -0
- package/dist/ranges.d.mts.map +1 -0
- package/dist/ranges.mjs +22 -0
- package/dist/ranges.mjs.map +1 -0
- package/dist/source-map.d.mts +28 -0
- package/dist/source-map.d.mts.map +1 -0
- package/dist/source-map.mjs +90 -0
- package/dist/source-map.mjs.map +1 -0
- package/dist/source-text.d.mts +35 -0
- package/dist/source-text.d.mts.map +1 -0
- package/dist/source-text.mjs +136 -0
- package/dist/source-text.mjs.map +1 -0
- package/dist/source.d.mts +86 -0
- package/dist/source.d.mts.map +1 -0
- package/dist/source.mjs +264 -0
- package/dist/source.mjs.map +1 -0
- package/dist/stream-events.d.mts +59 -0
- package/dist/stream-events.d.mts.map +1 -0
- package/dist/stream-events.mjs +115 -0
- package/dist/stream-events.mjs.map +1 -0
- package/dist/stream-session.d.mts +79 -0
- package/dist/stream-session.d.mts.map +1 -0
- package/dist/stream-session.mjs +904 -0
- package/dist/stream-session.mjs.map +1 -0
- package/dist/stream-tail.d.mts +84 -0
- package/dist/stream-tail.d.mts.map +1 -0
- package/dist/stream-tail.mjs +359 -0
- package/dist/stream-tail.mjs.map +1 -0
- package/dist/stream-types.d.mts +89 -0
- package/dist/stream-types.d.mts.map +1 -0
- package/dist/stream-types.mjs +1 -0
- package/dist/stream.d.mts +28 -0
- package/dist/stream.d.mts.map +1 -0
- package/dist/stream.mjs +68 -0
- package/dist/stream.mjs.map +1 -0
- package/dist/syntax-options.d.mts +21 -0
- package/dist/syntax-options.d.mts.map +1 -0
- package/dist/syntax-options.mjs +26 -0
- package/dist/syntax-options.mjs.map +1 -0
- package/dist/traversal.d.mts +25 -0
- package/dist/traversal.d.mts.map +1 -0
- package/dist/traversal.mjs +136 -0
- package/dist/traversal.mjs.map +1 -0
- package/dist/tree.d.mts +18 -0
- package/dist/tree.d.mts.map +1 -0
- package/dist/tree.mjs +43 -0
- package/dist/tree.mjs.map +1 -0
- package/dist/unified/adapter.d.mts +24 -0
- package/dist/unified/adapter.d.mts.map +1 -0
- package/dist/unified/adapter.mjs +44 -0
- package/dist/unified/adapter.mjs.map +1 -0
- package/dist/unified/mod.d.mts +2 -0
- package/dist/unified/mod.mjs +1 -0
- package/dist/unified/runtime.d.mts +10 -0
- package/dist/unified/runtime.d.mts.map +1 -0
- package/dist/unified/runtime.mjs +115 -0
- package/dist/unified/runtime.mjs.map +1 -0
- package/dist/unified/tree-bridge.d.mts +63 -0
- package/dist/unified/tree-bridge.d.mts.map +1 -0
- package/dist/unified/tree-bridge.mjs +876 -0
- package/dist/unified/tree-bridge.mjs.map +1 -0
- package/dist/uri.d.mts +5 -0
- package/dist/uri.d.mts.map +1 -0
- package/dist/uri.mjs +32 -0
- package/dist/uri.mjs.map +1 -0
- package/package.json +56 -30
- package/dist/plugins/heading-id/plugin.d.mts +0 -17
- package/dist/plugins/heading-id/plugin.d.mts.map +0 -1
- package/dist/plugins/heading-id/plugin.mjs +0 -23
- package/dist/plugins/heading-id/plugin.mjs.map +0 -1
- package/dist/plugins/katex/plugin.d.mts +0 -39
- package/dist/plugins/katex/plugin.d.mts.map +0 -1
- package/dist/plugins/katex/plugin.mjs +0 -107
- package/dist/plugins/katex/plugin.mjs.map +0 -1
- package/dist/plugins/remove-imports-exports.d.mts +0 -10
- package/dist/plugins/remove-imports-exports.d.mts.map +0 -1
- package/dist/plugins/remove-imports-exports.mjs +0 -15
- package/dist/plugins/remove-imports-exports.mjs.map +0 -1
- package/dist/plugins/syntax-highlight/code-meta.d.mts +0 -22
- package/dist/plugins/syntax-highlight/code-meta.d.mts.map +0 -1
- package/dist/plugins/syntax-highlight/code-meta.mjs +0 -38
- package/dist/plugins/syntax-highlight/code-meta.mjs.map +0 -1
- package/dist/plugins/syntax-highlight/plugin.d.mts +0 -57
- package/dist/plugins/syntax-highlight/plugin.d.mts.map +0 -1
- package/dist/plugins/syntax-highlight/plugin.mjs +0 -93
- package/dist/plugins/syntax-highlight/plugin.mjs.map +0 -1
- package/dist/plugins/tree-processor/plugin.d.mts +0 -19
- package/dist/plugins/tree-processor/plugin.d.mts.map +0 -1
- package/dist/plugins/tree-processor/plugin.mjs +0 -21
- package/dist/plugins/tree-processor/plugin.mjs.map +0 -1
- package/dist/types.d.mts +0 -2
- /package/dist/{types.mjs → parser/block-syntax.mjs} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"materialize.mjs","names":[],"sources":["../../src/parser/materialize.ts"],"sourcesContent":["import type { Diagnostic } from \"../diagnostics.ts\";\nimport type {\n DirectiveAttribute,\n DirectiveLabelNode,\n ListItemNode,\n DocumentNode,\n FlowContent,\n JsxTextElementNode,\n PhrasingContent,\n} from \"../model.ts\";\nimport type { SourceRange } from \"../ranges.ts\";\nimport type { SourceText } from \"../source-text.ts\";\nimport type { SourceFile, SourceSpan } from \"../source.ts\";\nimport type { ResolvedSyntaxOptions } from \"../syntax-options.ts\";\nimport type {\n BlockSyntax,\n DirectiveAttributeSyntax,\n ListItemSyntax,\n ListSyntax,\n JsxSyntax,\n} from \"./block-syntax.ts\";\nimport type { ResolvedParserLimits } from \"./config.ts\";\nimport type { DefinitionLookup, InlineSyntax } from \"./inline-syntax.ts\";\nimport type {\n CachedListPrefix,\n CachedMaterialization,\n MaterializeCache,\n} from \"./materialize-cache.ts\";\n\nimport { createDiagnostic, DiagnosticBag } from \"../diagnostics.ts\";\nimport { decodeFrontmatter } from \"../frontmatter-decode.ts\";\nimport { normalizeIdentifier } from \"../identifier.ts\";\nimport { nodeText } from \"../model.ts\";\nimport { sourceText } from \"../source.ts\";\nimport { parseFlowRange } from \"./block-parser.ts\";\nimport { InlineInput } from \"./inline-input.ts\";\nimport { parseInline } from \"./inline-parser.ts\";\nimport { isFlowJsxChildren, jsxParts, type JsxParts } from \"./materialize-jsx.ts\";\n\nexport interface MaterializedBlock {\n readonly references: readonly string[];\n readonly nodeCount: number;\n readonly node: FlowContent;\n}\n\nexport interface MaterializeOptions {\n /** Definitions already known to a stream, including definitions in other blocks. */\n readonly definitionLookup?: DefinitionLookup;\n /**\n * Keeps references whose definitions are missing, for a stream where the\n * definitions may still arrive. Otherwise they become authored text.\n */\n readonly keepReferences?: boolean;\n /** Open embedded syntax at the end of the source is inert instead of invalid. */\n readonly allowIncomplete?: boolean;\n readonly cache?: MaterializeCache;\n /**\n * The range of a stream's open leaf. A stream renders that leaf itself, so it\n * materializes as an empty placeholder with the same kind and origin.\n */\n readonly open?: SourceRange;\n}\n\nexport type StrictMaterializeResult =\n | Readonly<{\n kind: \"ok\";\n document: DocumentNode;\n blocks: readonly MaterializedBlock[];\n diagnostics: readonly Diagnostic[];\n }>\n | Readonly<{ kind: \"invalid\"; diagnostics: readonly [Diagnostic, ...Diagnostic[]] }>\n | Readonly<{\n kind: \"limitExceeded\";\n limit: \"maximumNestingDepth\" | \"maximumNodes\";\n diagnostics: readonly [Diagnostic, ...Diagnostic[]];\n }>;\n\ninterface PreparedFlowJsx {\n readonly parts: JsxParts;\n readonly children: readonly BlockSyntax[] | undefined;\n}\n\ninterface MaterializeContext {\n readonly definitionLookup: DefinitionLookup;\n references: Set<string>;\n readonly definitions: ReadonlySet<string>;\n readonly diagnostics: DiagnosticBag;\n readonly file: SourceFile;\n readonly footnotes: ReadonlySet<string>;\n readonly limits: ResolvedParserLimits;\n readonly syntax: ResolvedSyntaxOptions;\n readonly allowIncomplete: boolean;\n readonly keepReferences: boolean;\n readonly cache: MaterializeCache | undefined;\n readonly open: SourceRange | undefined;\n readonly flowJsx: Map<JsxSyntax, PreparedFlowJsx>;\n grammarSource: SourceText | undefined;\n maximumDepth: number;\n /** Leniency at the end of the source makes the result depend on later input. */\n usedEndOfInput: boolean;\n depth: number;\n nodes: number;\n authoredInvalid: boolean;\n limit: \"maximumNestingDepth\" | \"maximumNodes\" | undefined;\n}\n\nexport function materializeDocument(\n file: SourceFile,\n blocks: readonly BlockSyntax[],\n syntax: ResolvedSyntaxOptions,\n limits: ResolvedParserLimits,\n options: MaterializeOptions = {},\n): StrictMaterializeResult {\n const indexes: DependencyIndexes = { definitions: new Set(), footnotes: new Set() };\n const context = createContext(file, syntax, limits, options, indexes);\n\n // Index flow JSX before references are materialized; its parsed children are reused below.\n if (!context.keepReferences) {\n collectIndexes(blocks, context, indexes);\n }\n\n const children: FlowContent[] = [];\n const materializedBlocks: MaterializedBlock[] = [];\n\n for (const block of blocks) {\n if (context.limit !== undefined) {\n break;\n }\n\n const before = context.nodes;\n context.references = new Set();\n const child = materializeBlock(block, context);\n\n if (child !== undefined) {\n children.push(child);\n materializedBlocks.push(\n Object.freeze({\n node: child,\n nodeCount: context.nodes - before,\n references: [...context.references],\n }),\n );\n }\n }\n\n if (context.limit !== undefined) {\n const diagnostic = limitDiagnostic(file, context.limit);\n const diagnostics: readonly [Diagnostic] = Object.freeze([diagnostic]);\n\n return Object.freeze({\n kind: \"limitExceeded\",\n limit: context.limit,\n diagnostics,\n });\n }\n\n const diagnostics = context.diagnostics.snapshot();\n\n if (\n context.authoredInvalid ||\n diagnostics.some((diagnostic) => diagnostic.severity === \"error\")\n ) {\n const errors = diagnostics.filter((diagnostic) => diagnostic.severity === \"error\");\n\n if (errors.length === 0) {\n throw new Error(\"Invalid MDX draft did not produce an error diagnostic\");\n }\n\n const [first, ...rest] = errors;\n\n if (first === undefined) {\n throw new Error(\"Invalid MDX diagnostic collection changed unexpectedly\");\n }\n\n const invalidDiagnostics: readonly [Diagnostic, ...Diagnostic[]] = Object.freeze([\n first,\n ...rest,\n ]);\n\n return Object.freeze({\n kind: \"invalid\",\n diagnostics: invalidDiagnostics,\n });\n }\n\n const document = counted<DocumentNode>(context, {\n kind: \"document\",\n children,\n origin: range(0, file.length),\n });\n\n if (document === undefined || context.limit !== undefined) {\n const diagnostic = limitDiagnostic(file, \"maximumNodes\");\n const diagnostics: readonly [Diagnostic] = Object.freeze([diagnostic]);\n\n return Object.freeze({\n kind: \"limitExceeded\",\n limit: \"maximumNodes\",\n diagnostics,\n });\n }\n\n return Object.freeze({\n kind: \"ok\",\n document,\n blocks: Object.freeze(materializedBlocks),\n diagnostics,\n });\n}\n\nexport interface MaterializedPhrasing {\n readonly nodes: readonly PhrasingContent[];\n readonly nodeCount: number;\n}\n\n/** Materialized phrasing by inline syntax identity, valid while references are kept. */\nexport type PhrasingCache = WeakMap<InlineSyntax, MaterializedPhrasing>;\n\n/**\n * Materializes parsed inline syntax that a stream renders outside a block,\n * keeping references.\n */\nexport function materializePhrasing(\n file: SourceFile,\n nodes: readonly InlineSyntax[],\n syntax: ResolvedSyntaxOptions,\n limits: ResolvedParserLimits,\n): MaterializedPhrasing {\n const context = createContext(file, syntax, limits, {\n keepReferences: true,\n allowIncomplete: true,\n });\n\n const children: PhrasingContent[] = [];\n\n for (const node of nodes) {\n const child = materializeInlineNode(node, context);\n\n if (child !== undefined) {\n children.push(child);\n }\n }\n\n return { nodes: children, nodeCount: context.nodes };\n}\n\n/** Independent inline groups share one context while retaining their own node budgets. */\nexport function materializePhrasingGroups(\n file: SourceFile,\n nodes: readonly InlineSyntax[],\n syntax: ResolvedSyntaxOptions,\n limits: ResolvedParserLimits,\n cache: PhrasingCache,\n): readonly MaterializedPhrasing[] {\n const context = createContext(file, syntax, limits, {\n keepReferences: true,\n allowIncomplete: true,\n });\n\n return nodes.map((node) => {\n const hit = cache.get(node);\n\n if (hit !== undefined) {\n return hit;\n }\n\n context.nodes = 0;\n context.limit = undefined;\n context.usedEndOfInput = false;\n\n const child = materializeInlineNode(node, context);\n\n const materialized = {\n nodes: child === undefined ? [] : [child],\n nodeCount: context.nodes,\n };\n\n if (context.limit === undefined && !context.usedEndOfInput) {\n cache.set(node, materialized);\n }\n\n return materialized;\n });\n}\n\n/** Only whitespace and at most one line ending follow `offset`. */\nfunction reachesEndOfInput(file: SourceFile, offset: number): boolean {\n return /^[ \\t]*(?:\\r\\n?|\\n)?[ \\t]*$/u.test(file.slice({ start: offset, end: file.length }));\n}\n\nconst emptyIndexes: DependencyIndexes = { definitions: new Set(), footnotes: new Set() };\n\nfunction createContext(\n file: SourceFile,\n syntax: ResolvedSyntaxOptions,\n limits: ResolvedParserLimits,\n options: MaterializeOptions,\n indexes: DependencyIndexes = emptyIndexes,\n): MaterializeContext {\n return {\n definitions: indexes.definitions,\n definitionLookup: options.definitionLookup ?? indexes.definitions,\n references: new Set(),\n diagnostics: new DiagnosticBag(),\n file,\n footnotes: indexes.footnotes,\n limits,\n syntax,\n // Resolution depends on the definitions, so only reference-keeping output is cached.\n cache: options.keepReferences === true ? options.cache : undefined,\n flowJsx: new Map(),\n grammarSource: undefined,\n maximumDepth: 0,\n usedEndOfInput: false,\n allowIncomplete: options.allowIncomplete ?? false,\n keepReferences: options.keepReferences ?? false,\n open: options.open,\n depth: 0,\n nodes: 0,\n authoredInvalid: false,\n limit: undefined,\n };\n}\n\nfunction materializeBlock(\n block: BlockSyntax,\n context: MaterializeContext,\n): FlowContent | undefined {\n return cached(context.cache?.blocks, block, context, () =>\n materializeBlockContent(block, context),\n );\n}\n\n/**\n * Replays a cached subtree, or materializes and caches it. Subtrees with\n * diagnostics or input-dependent leniency are never cached.\n */\nfunction cached<TKey extends BlockSyntax | ListItemSyntax, TNode>(\n cache: WeakMap<TKey, CachedMaterialization<TNode>> | undefined,\n key: TKey,\n context: MaterializeContext,\n materialize: () => TNode | undefined,\n): TNode | undefined {\n if (cache === undefined) {\n return materialize();\n }\n\n const hit = cache.get(key);\n\n if (\n hit !== undefined &&\n context.depth + hit.depth <= context.limits.maximumNestingDepth &&\n context.nodes + hit.nodeCount <= context.limits.maximumNodes\n ) {\n for (const identifier of hit.references) {\n context.references.add(identifier);\n }\n\n context.nodes += hit.nodeCount;\n context.maximumDepth = Math.max(context.maximumDepth, context.depth + hit.depth);\n\n return hit.node;\n }\n\n const references = context.references;\n context.references = new Set();\n const nodes = context.nodes;\n const diagnostics = context.diagnostics.size;\n const outerDepth = context.maximumDepth;\n const outerEndOfInput = context.usedEndOfInput;\n context.maximumDepth = context.depth;\n context.usedEndOfInput = false;\n const node = materialize();\n\n if (\n node !== undefined &&\n context.diagnostics.size === diagnostics &&\n !context.authoredInvalid &&\n context.limit === undefined &&\n !context.usedEndOfInput\n ) {\n cache.set(key, {\n node,\n nodeCount: context.nodes - nodes,\n depth: context.maximumDepth - context.depth,\n references: [...context.references],\n });\n }\n\n for (const identifier of context.references) {\n references.add(identifier);\n }\n\n context.references = references;\n context.maximumDepth = Math.max(outerDepth, context.maximumDepth);\n context.usedEndOfInput ||= outerEndOfInput;\n\n return node;\n}\n\nfunction materializeBlockContent(\n block: BlockSyntax,\n context: MaterializeContext,\n): FlowContent | undefined {\n if (!enter(context)) {\n return;\n }\n\n try {\n const origin = range(block.range.start, block.range.end);\n\n if (isOpenLeaf(block, context)) {\n context.usedEndOfInput = true;\n\n return counted(context, openLeafPlaceholder(block, origin));\n }\n\n switch (block.kind) {\n case \"paragraph\":\n return counted(context, {\n kind: \"paragraph\",\n children: materializeInline(block.input, context),\n origin,\n });\n case \"heading\":\n return counted(context, {\n kind: \"heading\",\n depth: block.depth,\n children: materializeInline(block.input, context),\n origin,\n });\n case \"code\":\n return counted(context, {\n kind: \"codeBlock\",\n value: trimFinalLineEnding(inlineInputText(context.file, block.value)),\n language: sliceOptional(context.file, block.language),\n meta: sliceOptional(context.file, block.meta),\n origin,\n });\n case \"thematicBreak\":\n return counted(context, { kind: \"thematicBreak\", origin });\n case \"blockQuote\":\n return counted(context, {\n kind: \"blockquote\",\n children: materializeBlocks(block.children, context),\n origin,\n });\n case \"list\":\n return counted(context, {\n kind: \"list\",\n ordered: block.ordered,\n spread: block.spread,\n start: block.start ?? 1,\n children: materializeListItems(block, context),\n origin,\n });\n case \"definition\":\n return counted(context, {\n kind: \"definition\",\n identifier: normalizeIdentifier(block.identifier),\n url: context.file.semanticSlice(block.destination),\n title: semanticSliceOptional(context.file, block.title),\n origin,\n });\n case \"footnoteDefinition\":\n return counted(context, {\n kind: \"footnoteDefinition\",\n identifier: normalizeIdentifier(block.identifier),\n label: block.identifier,\n children: materializeBlocks(block.children, context),\n origin,\n });\n case \"rawHtml\":\n return counted(context, {\n kind: \"rawHtmlBlock\",\n value: context.file.semanticSlice(block.range),\n origin,\n });\n case \"frontmatter\": {\n const rawValue = trimFinalLineEnding(context.file.slice(block.value));\n const valueOrigin = range(block.value.start, block.value.start + rawValue.length);\n\n const data = decodeFrontmatter({\n diagnostics: context.diagnostics,\n format: block.format,\n source: rawValue,\n span: span(context.file, valueOrigin.start, valueOrigin.end),\n });\n\n return counted(context, {\n kind: \"frontmatter\",\n format: block.format,\n value: rawValue.replace(/\\r\\n?|\\n/gu, \"\\n\"),\n data,\n valueOrigin,\n origin,\n });\n }\n\n case \"directive\":\n return counted(context, {\n kind: \"containerDirective\",\n name: block.name,\n attributes: materializeDirectiveAttributes(block.attributes),\n label: materializeDirectiveLabel(block.label, context),\n children: materializeBlocks(block.children, context),\n origin,\n });\n case \"leafDirective\":\n return counted(context, {\n kind: \"leafDirective\",\n name: block.name,\n attributes: materializeDirectiveAttributes(block.attributes),\n label: materializeDirectiveLabel(block.label, context),\n origin,\n });\n case \"math\": {\n const value = trimFinalLineEnding(inlineInputText(context.file, block.value));\n\n return counted(\n context,\n block.format === \"tex\"\n ? { kind: \"displayMath\", value, format: \"tex\", origin }\n : {\n kind: \"displayMath\",\n value,\n format: \"dollar\",\n meta: sliceOptional(context.file, block.meta),\n origin,\n },\n );\n }\n\n case \"table\":\n return counted(context, {\n kind: \"table\",\n alignments: block.alignments,\n children: block.rows.map((row) => ({\n kind: \"tableRow\",\n children: row.cells.map((cell) => {\n const cellRange = inlineSegmentsRange(cell, row.range);\n\n return {\n kind: \"tableCell\",\n children: materializeInline(cell, context),\n origin: range(cellRange.start, cellRange.end),\n };\n }),\n origin: range(row.range.start, row.range.end),\n })),\n origin,\n });\n case \"expression\": {\n const authored = context.file.slice(block.range);\n\n return counted(context, {\n kind: \"blockExpression\",\n code: authored.slice(authored.indexOf(\"{\") + 1, authored.lastIndexOf(\"}\")),\n origin,\n });\n }\n\n case \"esm\":\n return counted(context, {\n kind: \"esm\",\n code: trimFinalLineEnding(context.file.slice(block.range)),\n origin,\n });\n case \"jsx\":\n return counted(context, materializeFlowJsx(block, context));\n case \"invalidMdx\":\n if (\n context.allowIncomplete &&\n block.state === \"incomplete\" &&\n reachesEndOfInput(context.file, block.range.end)\n ) {\n context.usedEndOfInput = true;\n\n return counted(context, {\n kind: \"rawHtmlBlock\",\n value: context.file.slice(block.range),\n origin,\n });\n }\n\n context.authoredInvalid = true;\n context.diagnostics.add({\n code: `mdx.${block.syntax}.invalid`,\n message: `Invalid or unfinished MDX ${block.syntax}`,\n severity: \"error\",\n span: span(context.file, origin.start, origin.end),\n });\n\n return;\n }\n } finally {\n context.depth--;\n }\n}\n\nfunction isOpenLeaf(block: BlockSyntax, context: MaterializeContext): boolean {\n return (\n context.open !== undefined &&\n block.range.start === context.open.start &&\n block.range.end === context.open.end &&\n (block.kind === \"paragraph\" ||\n block.kind === \"code\" ||\n block.kind === \"math\" ||\n block.kind === \"invalidMdx\")\n );\n}\n\nfunction openLeafPlaceholder(block: BlockSyntax, origin: SourceRange): FlowContent {\n switch (block.kind) {\n case \"paragraph\":\n return { kind: \"paragraph\", children: [], origin };\n case \"code\":\n return { kind: \"codeBlock\", value: \"\", origin };\n case \"math\":\n return { kind: \"displayMath\", value: \"\", format: \"dollar\", origin };\n default:\n return { kind: \"rawHtmlBlock\", value: \"\", origin };\n }\n}\n\n/**\n * Materializes list items. A growing list reuses its unchanged leading items\n * as one prefix, so an append materializes only the items after it. The list\n * that contains a stream's open leaf is rebuilt on every append and never\n * cached, so its children array is extended in place instead of copied.\n */\nfunction materializeListItems(list: ListSyntax, context: MaterializeContext): ListItemNode[] {\n const items = list.items;\n const closing = list.closing ?? [];\n const count = items.length + closing.length;\n const itemAt = (index: number): ListItemSyntax => items[index] ?? closing[index - items.length];\n const open = context.open !== undefined && containsRange(list.range, context.open);\n const cache = context.cache;\n const prefix = cache === undefined ? undefined : listPrefix(count, itemAt, cache.lists);\n\n const reused =\n prefix !== undefined &&\n context.depth + prefix.depth <= context.limits.maximumNestingDepth &&\n context.nodes + prefix.nodeCount <= context.limits.maximumNodes\n ? prefix\n : undefined;\n\n let children: ListItemNode[] = [];\n\n if (reused !== undefined && reused.live && open) {\n children = reused.nodes;\n children.length = reused.length;\n } else if (reused !== undefined) {\n children = reused.nodes.slice(0, reused.length);\n }\n\n let nodeCount = reused?.nodeCount ?? 0;\n let depth = reused?.depth ?? 0;\n let cacheable = true;\n const references = new Set(reused?.references);\n\n if (reused !== undefined) {\n for (const identifier of reused.references) {\n context.references.add(identifier);\n }\n\n context.nodes += reused.nodeCount;\n context.maximumDepth = Math.max(context.maximumDepth, context.depth + reused.depth);\n }\n\n for (let index = (reused?.index ?? -1) + 1; index < count; index++) {\n const item = itemAt(index);\n\n const node = cached(cache?.items, item, context, (): ListItemNode => ({\n kind: \"listItem\",\n checked: item.checked,\n spread: item.spread,\n children: materializeBlocks(item.children, context),\n origin: range(item.range.start, item.range.end),\n }));\n\n if (node !== undefined) {\n children.push(node);\n }\n\n // Items with diagnostics or end-of-input leniency are not cached, so prefixes stop there.\n const entry = cache?.items.get(item);\n cacheable &&= entry?.node === node;\n\n for (const identifier of entry?.references ?? []) {\n references.add(identifier);\n }\n\n nodeCount += entry?.nodeCount ?? 0;\n depth = Math.max(depth, entry?.depth ?? 0);\n\n // A prefix is the first \\`length\\` nodes of \\`children\\`, which only ever grows past them.\n if (cacheable && index >= count - prefixWindow) {\n cache?.lists.set(item, {\n index,\n nodes: children,\n length: children.length,\n live: open,\n references: [...references],\n nodeCount,\n depth,\n });\n }\n }\n\n return children;\n}\n\n/**\n * How far back a list prefix can end. The parser closes an item only when the\n * next line completes, so the last two items are rebuilt by each tail draft.\n */\nconst prefixWindow = 8;\n\n/** The cached prefix ending closest to the end of the list. Closing items can still change. */\nfunction listPrefix(\n count: number,\n itemAt: (index: number) => ListItemSyntax,\n lists: MaterializeCache[\"lists\"],\n): CachedListPrefix | undefined {\n for (let index = count - 1; index >= Math.max(0, count - prefixWindow); index--) {\n const prefix = lists.get(itemAt(index));\n\n if (prefix?.index === index) {\n return prefix;\n }\n }\n\n return undefined;\n}\n\nfunction containsRange(outer: SourceRange, inner: SourceRange): boolean {\n return outer.start <= inner.start && inner.end <= outer.end;\n}\n\nfunction materializeBlocks(\n blocks: readonly BlockSyntax[],\n context: MaterializeContext,\n): FlowContent[] {\n const children: FlowContent[] = [];\n\n for (const block of blocks) {\n const child = materializeBlock(block, context);\n\n if (child !== undefined) {\n children.push(child);\n }\n }\n\n return children;\n}\n\nfunction materializeInline(\n segments: Parameters<typeof inlineInputText>[1],\n context: MaterializeContext,\n): PhrasingContent[] {\n const result = parseInline(\n new InlineInput(context.file, segments),\n context.syntax,\n context.definitionLookup,\n );\n\n for (const identifier of result.references) {\n context.references.add(identifier);\n }\n\n for (const invalid of result.invalid) {\n // Streaming input can still close a construct that reaches the end of the source.\n if (\n context.allowIncomplete &&\n invalid.open &&\n reachesEndOfInput(context.file, invalid.range.end)\n ) {\n context.usedEndOfInput = true;\n continue;\n }\n\n context.authoredInvalid = true;\n context.diagnostics.add({\n code: `mdx.${invalid.syntax}.invalid`,\n message: `Invalid or unfinished MDX ${invalid.syntax}`,\n severity: \"error\",\n span: span(context.file, invalid.range.start, invalid.range.end),\n });\n }\n\n return materializeInlineNodes(result.nodes, context);\n}\n\nfunction materializeInlineNodes(\n nodes: readonly InlineSyntax[],\n context: MaterializeContext,\n): PhrasingContent[] {\n const children: PhrasingContent[] = [];\n\n for (const node of nodes) {\n const child = materializeInlineNode(node, context);\n\n if (child !== undefined) {\n children.push(child);\n }\n }\n\n return children;\n}\n\nfunction materializeInlineNode(\n node: InlineSyntax,\n context: MaterializeContext,\n): PhrasingContent | undefined {\n const origin = range(node.range.start, node.range.end);\n\n switch (node.kind) {\n case \"text\":\n return counted(context, { kind: \"text\", value: node.value, origin });\n case \"emphasis\":\n case \"strong\":\n case \"delete\":\n return counted(context, {\n kind: node.kind,\n children: materializeInlineNodes(node.children, context),\n origin,\n });\n case \"code\":\n return counted(context, { kind: \"inlineCode\", value: node.value, origin });\n case \"hardBreak\":\n return counted(context, { kind: \"hardBreak\", origin });\n case \"link\":\n return counted(context, {\n kind: \"link\",\n url: node.destination,\n title: node.title,\n children: materializeInlineNodes(node.children, context),\n origin,\n });\n case \"image\":\n return counted(context, {\n kind: \"image\",\n url: node.destination,\n alt: node.alt,\n title: node.title,\n origin,\n });\n case \"reference\": {\n const children = materializeInlineNodes(node.children, context);\n\n if (!context.keepReferences && !context.definitions.has(node.identifier)) {\n return counted(context, {\n kind: \"text\",\n value: context.file.slice(node.range),\n origin,\n });\n }\n\n const identifier = normalizeIdentifier(node.identifier);\n\n return counted(\n context,\n node.image\n ? {\n kind: \"imageReference\",\n identifier,\n alt: children.map(nodeText).join(\"\"),\n referenceKind: node.referenceKind,\n origin,\n }\n : {\n kind: \"linkReference\",\n identifier,\n referenceKind: node.referenceKind,\n children,\n origin,\n },\n );\n }\n\n case \"rawHtml\":\n return counted(context, { kind: \"rawHtmlInline\", value: node.value, origin });\n case \"expression\":\n return counted(context, { kind: \"inlineExpression\", code: node.value, origin });\n case \"jsx\":\n return counted(context, materializeTextJsx(node.value, origin, context));\n case \"math\":\n return counted(context, {\n kind: \"inlineMath\",\n value: node.value,\n format: node.format,\n origin,\n });\n case \"footnoteReference\":\n return context.keepReferences || context.footnotes.has(node.identifier)\n ? counted(context, {\n kind: \"footnoteReference\",\n identifier: normalizeIdentifier(node.identifier),\n label: node.identifier,\n origin,\n })\n : counted(context, { kind: \"text\", value: context.file.slice(node.range), origin });\n case \"directive\":\n return counted(context, {\n kind: \"textDirective\",\n name: node.name,\n attributes: materializeDirectiveAttributes(node.attributes),\n label: { kind: \"directiveLabel\", children: [], origin },\n origin,\n });\n }\n}\n\nfunction materializeDirectiveLabel(\n label: ConstructorParameters<typeof InlineInput>[1] | undefined,\n context: MaterializeContext,\n): DirectiveLabelNode | undefined {\n if (label === undefined) {\n return;\n }\n\n const labelRange = inlineSegmentsRange(label, { start: 0, end: 0 });\n\n return {\n kind: \"directiveLabel\",\n children: materializeInline(label, context),\n origin: range(labelRange.start, labelRange.end),\n };\n}\n\nfunction materializeDirectiveAttributes(\n attributes: readonly DirectiveAttributeSyntax[],\n): DirectiveAttribute[] {\n return attributes.map((attribute) => ({ name: attribute.name, value: attribute.value }));\n}\n\n/**\n * Children on following lines are Markdown flow content. Like MDX, children on\n * the same line are phrasing: the element is text JSX in a paragraph, which\n * lowering does not wrap in `p`.\n */\nfunction materializeFlowJsx(block: JsxSyntax, context: MaterializeContext): FlowContent {\n const prepared = prepareFlowJsx(block, context);\n const { parts, children } = prepared;\n const origin = range(block.range.start, block.range.end);\n\n if (\n parts.children !== undefined &&\n parts.children.start !== parts.children.end &&\n children === undefined\n ) {\n return {\n kind: \"paragraph\",\n children: [materializeTextJsx(context.file.slice(block.range), origin, context, parts)],\n origin,\n };\n }\n\n return {\n kind: \"jsxFlowElement\",\n name: parts.name,\n attributes: parts.attributes,\n children: children === undefined ? [] : materializeBlocks(children, context),\n origin,\n };\n}\n\nfunction prepareFlowJsx(block: JsxSyntax, context: MaterializeContext): PreparedFlowJsx {\n const cached = context.flowJsx.get(block);\n\n if (cached !== undefined) {\n return cached;\n }\n\n const parts = jsxParts(context.file.slice(block.range), block.range.start);\n const childRange = parts.children;\n\n const children =\n childRange === undefined ||\n childRange.start === childRange.end ||\n !isFlowJsxChildren(context.file, childRange)\n ? undefined\n : parseFlowRange(grammarSource(context), childRange, context.syntax);\n\n const prepared = { parts, children };\n context.flowJsx.set(block, prepared);\n\n return prepared;\n}\n\nfunction grammarSource(context: MaterializeContext): SourceText {\n context.grammarSource ??= sourceText(context.file).grammar();\n\n return context.grammarSource;\n}\n\nfunction materializeTextJsx(\n authored: string,\n jsxOrigin: SourceRange,\n context: MaterializeContext,\n parsed = jsxParts(authored, jsxOrigin.start),\n): JsxTextElementNode {\n return {\n kind: \"jsxTextElement\",\n name: parsed.name,\n attributes: parsed.attributes,\n children:\n parsed.children === undefined\n ? []\n : materializeInline([{ kind: \"source\", range: parsed.children }], context),\n origin: jsxOrigin,\n };\n}\n\ninterface DependencyIndexes {\n readonly definitions: Set<string>;\n readonly footnotes: Set<string>;\n}\n\nfunction collectIndexes(\n blocks: readonly BlockSyntax[],\n context: MaterializeContext,\n indexes: DependencyIndexes,\n): void {\n const { definitions, footnotes } = indexes;\n let nodes = 1;\n\n const visit = (block: BlockSyntax, depth: number): void => {\n if (context.limit !== undefined) {\n return;\n }\n\n if (depth > context.limits.maximumNestingDepth) {\n context.limit = \"maximumNestingDepth\";\n\n return;\n }\n\n nodes++;\n\n if (nodes > context.limits.maximumNodes) {\n context.limit = \"maximumNodes\";\n\n return;\n }\n\n if (block.kind === \"definition\") {\n definitions.add(normalizeIdentifier(block.identifier));\n } else if (block.kind === \"footnoteDefinition\") {\n footnotes.add(normalizeIdentifier(block.identifier));\n }\n\n if (\n block.kind === \"blockQuote\" ||\n block.kind === \"footnoteDefinition\" ||\n block.kind === \"directive\"\n ) {\n block.children.forEach((child) => visit(child, depth + 1));\n } else if (block.kind === \"list\") {\n for (const item of [...block.items, ...(block.closing ?? [])]) {\n item.children.forEach((child) => visit(child, depth + 1));\n }\n } else if (block.kind === \"jsx\") {\n prepareFlowJsx(block, context).children?.forEach((child) => visit(child, depth + 1));\n }\n };\n\n blocks.forEach((block) => visit(block, 1));\n}\n\nfunction inlineInputText(\n file: SourceFile,\n segments: ConstructorParameters<typeof InlineInput>[1],\n): string {\n return new InlineInput(file, segments).toString();\n}\n\nfunction inlineSegmentsRange(\n segments: ConstructorParameters<typeof InlineInput>[1],\n fallback: SourceRange,\n): SourceRange {\n const first = segments.find((segment) => segment.kind === \"source\");\n const last = segments.findLast((segment) => segment.kind === \"source\");\n\n return first?.kind === \"source\" && last?.kind === \"source\"\n ? { start: first.range.start, end: last.range.end }\n : fallback;\n}\n\nfunction sliceOptional(file: SourceFile, range: SourceRange | undefined): string | undefined {\n return range === undefined ? undefined : file.slice(range);\n}\n\nfunction semanticSliceOptional(\n file: SourceFile,\n range: SourceRange | undefined,\n): string | undefined {\n return range === undefined ? undefined : file.semanticSlice(range);\n}\n\nfunction trimFinalLineEnding(value: string): string {\n return value.endsWith(\"\\r\\n\")\n ? value.slice(0, -2)\n : value.endsWith(\"\\n\") || value.endsWith(\"\\r\")\n ? value.slice(0, -1)\n : value;\n}\n\nfunction span(file: SourceFile, start: number, end: number): SourceSpan {\n return { file, start, end };\n}\n\nfunction range(start: number, end: number): SourceRange {\n return { start, end };\n}\n\nfunction enter(context: MaterializeContext): boolean {\n context.depth++;\n context.maximumDepth = Math.max(context.maximumDepth, context.depth);\n\n if (context.depth > context.limits.maximumNestingDepth) {\n context.limit = \"maximumNestingDepth\";\n context.depth--;\n\n return false;\n }\n\n return true;\n}\n\nfunction counted<T>(context: MaterializeContext, node: T): T | undefined {\n context.nodes++;\n\n if (context.nodes > context.limits.maximumNodes) {\n context.limit = \"maximumNodes\";\n\n return;\n }\n\n return node;\n}\n\nfunction limitDiagnostic(\n file: SourceFile,\n limit: \"maximumNestingDepth\" | \"maximumNodes\",\n): Diagnostic {\n return createDiagnostic({\n code: `mdx.limit.${limit}`,\n message: `Parser limit ${limit} exceeded`,\n severity: \"error\",\n span: span(file, 0, file.length),\n });\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Diagnostic } from "../diagnostics.mjs";
|
|
2
|
+
//#region src/parser/recognizer.d.ts
|
|
3
|
+
export type RecognizerResult<TMatch> = Readonly<{
|
|
4
|
+
kind: "noMatch";
|
|
5
|
+
}> | Readonly<{
|
|
6
|
+
kind: "matched";
|
|
7
|
+
value: TMatch;
|
|
8
|
+
}> | Readonly<{
|
|
9
|
+
kind: "incompleteAtEof";
|
|
10
|
+
expected: string;
|
|
11
|
+
}> | Readonly<{
|
|
12
|
+
kind: "invalid";
|
|
13
|
+
diagnostics: readonly [Diagnostic, ...Diagnostic[]];
|
|
14
|
+
}>;
|
|
15
|
+
export declare const noMatch: RecognizerResult<never>;
|
|
16
|
+
export declare function matched<TMatch>(value: TMatch): RecognizerResult<TMatch>;
|
|
17
|
+
export declare function incompleteAtEof(expected: string): RecognizerResult<never>;
|
|
18
|
+
export declare function invalid(diagnostics: readonly [Diagnostic, ...Diagnostic[]]): RecognizerResult<never>;
|
|
19
|
+
//#endregion
|
|
20
|
+
//# sourceMappingURL=recognizer.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recognizer.d.mts","names":[],"sources":["../../src/parser/recognizer.ts"],"mappings":";;YAEY,iBAAiB,UACzB;EAAW;KACX;EAAW;EAAiB,OAAO;KACnC;EAAW;EAAyB;KACpC;EAAW;EAAiB,uBAAuB,eAAe;;qBAEzD,SAAS;wBAEN,QAAQ,QAAQ,OAAO,SAAS,iBAAiB;wBAIjD,gBAAgB,mBAAmB;wBAInC,QACd,uBAAuB,eAAe,gBACrC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
//#region src/parser/recognizer.ts
|
|
2
|
+
const noMatch = { kind: "noMatch" };
|
|
3
|
+
function matched(value) {
|
|
4
|
+
return {
|
|
5
|
+
kind: "matched",
|
|
6
|
+
value
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
function incompleteAtEof(expected) {
|
|
10
|
+
return {
|
|
11
|
+
kind: "incompleteAtEof",
|
|
12
|
+
expected
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function invalid(diagnostics) {
|
|
16
|
+
return {
|
|
17
|
+
kind: "invalid",
|
|
18
|
+
diagnostics
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
export { incompleteAtEof, invalid, matched, noMatch };
|
|
23
|
+
|
|
24
|
+
//# sourceMappingURL=recognizer.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recognizer.mjs","names":[],"sources":["../../src/parser/recognizer.ts"],"sourcesContent":["import type { Diagnostic } from \"../diagnostics.ts\";\n\nexport type RecognizerResult<TMatch> =\n | Readonly<{ kind: \"noMatch\" }>\n | Readonly<{ kind: \"matched\"; value: TMatch }>\n | Readonly<{ kind: \"incompleteAtEof\"; expected: string }>\n | Readonly<{ kind: \"invalid\"; diagnostics: readonly [Diagnostic, ...Diagnostic[]] }>;\n\nexport const noMatch: RecognizerResult<never> = { kind: \"noMatch\" };\n\nexport function matched<TMatch>(value: TMatch): RecognizerResult<TMatch> {\n return { kind: \"matched\", value };\n}\n\nexport function incompleteAtEof(expected: string): RecognizerResult<never> {\n return { kind: \"incompleteAtEof\", expected };\n}\n\nexport function invalid(\n diagnostics: readonly [Diagnostic, ...Diagnostic[]],\n): RecognizerResult<never> {\n return { kind: \"invalid\", diagnostics };\n}\n"],"mappings":";AAQA,MAAa,UAAmC,EAAE,MAAM,UAAU;AAElE,SAAgB,QAAgB,OAAyC;CACvE,OAAO;EAAE,MAAM;EAAW;CAAM;AAClC;AAEA,SAAgB,gBAAgB,UAA2C;CACzE,OAAO;EAAE,MAAM;EAAmB;CAAS;AAC7C;AAEA,SAAgB,QACd,aACyB;CACzB,OAAO;EAAE,MAAM;EAAW;CAAY;AACxC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { ResolvedSyntaxOptions, SyntaxOptions } from "../syntax-options.mjs";
|
|
2
|
+
import { SourceText } from "../source-text.mjs";
|
|
3
|
+
import { SourceFile } from "../source.mjs";
|
|
4
|
+
import { BlockSyntax, PendingBlockSyntax } from "./block-syntax.mjs";
|
|
5
|
+
import { SettledBlockListener } from "./block-parser.mjs";
|
|
6
|
+
//#region src/parser/session.d.ts
|
|
7
|
+
export interface ParserSessionOptions {
|
|
8
|
+
readonly source?: string | SourceFile;
|
|
9
|
+
readonly syntax?: SyntaxOptions;
|
|
10
|
+
/**
|
|
11
|
+
* Receives each top-level block once it settles. After an edit, blocks settle
|
|
12
|
+
* again from the first changed index.
|
|
13
|
+
*/
|
|
14
|
+
readonly onSettled?: SettledBlockListener;
|
|
15
|
+
}
|
|
16
|
+
/** The unsettled top-level blocks, finished as if the source ended here. */
|
|
17
|
+
export interface ParserTailDraft {
|
|
18
|
+
readonly blocks: readonly BlockSyntax[];
|
|
19
|
+
/** The leaf that was still open, which later input may extend. */
|
|
20
|
+
readonly pending?: PendingBlockSyntax;
|
|
21
|
+
}
|
|
22
|
+
export interface ParserSessionEdit {
|
|
23
|
+
readonly end: number;
|
|
24
|
+
readonly start: number;
|
|
25
|
+
readonly text: string;
|
|
26
|
+
}
|
|
27
|
+
/** Retained parser state for streaming previews and edits. */
|
|
28
|
+
export declare class ParserSession {
|
|
29
|
+
#private;
|
|
30
|
+
readonly syntax: ResolvedSyntaxOptions;
|
|
31
|
+
constructor(options?: ParserSessionOptions);
|
|
32
|
+
/** The number of top-level blocks that later input cannot change. */
|
|
33
|
+
get settledCount(): number;
|
|
34
|
+
/** `source` is the whole source after the append, when the caller already built it. */
|
|
35
|
+
append(text: string, source?: SourceText): void;
|
|
36
|
+
edit(edit: ParserSessionEdit): void;
|
|
37
|
+
/** Finishes a copy of the unsettled tail; the session itself stays open. */
|
|
38
|
+
tailDraft(): ParserTailDraft;
|
|
39
|
+
private writeLine;
|
|
40
|
+
}
|
|
41
|
+
//#endregion
|
|
42
|
+
//# sourceMappingURL=session.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.mts","names":[],"sources":["../../src/parser/session.ts"],"mappings":";;;;;;iBAeiB;WACN,kBAAkB;WAClB,SAAS;;;;;WAKT,YAAY;;;iBAIN;WACN,iBAAiB;;WAEjB,UAAU;;iBAGJ;WACN;WACA;WACA;;;qBAUE;;WAIF,QAAQ;EAIjB,YAAmB,UAAS;;MAkBjB;;EAKJ,OAAO,cAAc,SAAS;EAa9B,KAAK,MAAM;;EA+BX,aAAa;UAgBZ"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { InputError } from "../errors.mjs";
|
|
2
|
+
import { resolveSyntaxOptions } from "../syntax-options.mjs";
|
|
3
|
+
import { SourceText } from "../source-text.mjs";
|
|
4
|
+
import { PhysicalLineScanner, SourceFile, sourceText } from "../source.mjs";
|
|
5
|
+
import { BlockParser } from "./block-parser.mjs";
|
|
6
|
+
//#region src/parser/session.ts
|
|
7
|
+
/** Retained parser state for streaming previews and edits. */
|
|
8
|
+
var ParserSession = class {
|
|
9
|
+
#blockParser;
|
|
10
|
+
#checkpoints;
|
|
11
|
+
#lineScanner;
|
|
12
|
+
syntax;
|
|
13
|
+
#grammarSource = SourceText.of("");
|
|
14
|
+
#source = SourceText.of("");
|
|
15
|
+
constructor(options = {}) {
|
|
16
|
+
this.syntax = resolveSyntaxOptions(options.syntax);
|
|
17
|
+
this.#blockParser = new BlockParser(this.syntax, [], options.onSettled);
|
|
18
|
+
this.#lineScanner = new PhysicalLineScanner();
|
|
19
|
+
this.#checkpoints = [{
|
|
20
|
+
line: 1,
|
|
21
|
+
offset: 0,
|
|
22
|
+
parser: {
|
|
23
|
+
length: 0,
|
|
24
|
+
tail: void 0
|
|
25
|
+
}
|
|
26
|
+
}];
|
|
27
|
+
const source = options.source instanceof SourceFile ? options.source.text : options.source ?? "";
|
|
28
|
+
if (source !== "") this.append(source, options.source instanceof SourceFile ? sourceText(options.source) : void 0);
|
|
29
|
+
}
|
|
30
|
+
/** The number of top-level blocks that later input cannot change. */
|
|
31
|
+
get settledCount() {
|
|
32
|
+
return this.#blockParser.settledCount;
|
|
33
|
+
}
|
|
34
|
+
/** `source` is the whole source after the append, when the caller already built it. */
|
|
35
|
+
append(text, source) {
|
|
36
|
+
this.#source = source ?? this.#source.append(text);
|
|
37
|
+
this.#grammarSource = this.#source.plain ? this.#source : this.#grammarSource.append(text.replaceAll("\0", "�"));
|
|
38
|
+
for (const line of this.#lineScanner.append(text)) this.writeLine(line);
|
|
39
|
+
}
|
|
40
|
+
edit(edit) {
|
|
41
|
+
if (!Number.isSafeInteger(edit.start) || !Number.isSafeInteger(edit.end) || edit.start < 0 || edit.end < edit.start || edit.end > this.#source.length) throw InputError.replacementRangeOutsideSource(edit.start, edit.end, this.#source.length);
|
|
42
|
+
const nextSource = this.#source.slice(0, edit.start) + edit.text + this.#source.slice(edit.end);
|
|
43
|
+
const checkpointIndex = findCheckpoint(this.#checkpoints, edit.start);
|
|
44
|
+
const checkpoint = this.#checkpoints[checkpointIndex];
|
|
45
|
+
this.#source = SourceText.of(nextSource);
|
|
46
|
+
this.#grammarSource = this.#source.plain ? this.#source : SourceText.of(nextSource.replaceAll("\0", "�"));
|
|
47
|
+
this.#blockParser = this.#blockParser.fork(checkpoint.parser);
|
|
48
|
+
this.#lineScanner = new PhysicalLineScanner({
|
|
49
|
+
line: checkpoint.line,
|
|
50
|
+
offset: checkpoint.offset
|
|
51
|
+
});
|
|
52
|
+
this.#checkpoints.length = checkpointIndex + 1;
|
|
53
|
+
for (const line of this.#lineScanner.append(nextSource.slice(checkpoint.offset))) this.writeLine(line);
|
|
54
|
+
}
|
|
55
|
+
/** Finishes a copy of the unsettled tail; the session itself stays open. */
|
|
56
|
+
tailDraft() {
|
|
57
|
+
const scanner = this.#lineScanner.clone();
|
|
58
|
+
const parser = this.#blockParser.tail();
|
|
59
|
+
for (const line of scanner.complete()) if (line.range.start < line.range.end) parser.write(this.#grammarSource, line);
|
|
60
|
+
const pending = parser.pending();
|
|
61
|
+
return {
|
|
62
|
+
blocks: parser.finish(this.#grammarSource),
|
|
63
|
+
pending
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
writeLine(line) {
|
|
67
|
+
this.#blockParser.write(this.#grammarSource, line);
|
|
68
|
+
const parser = this.#blockParser.checkpoint();
|
|
69
|
+
if (parser !== void 0) this.#checkpoints.push({
|
|
70
|
+
line: line.line + 1,
|
|
71
|
+
offset: line.range.end,
|
|
72
|
+
parser
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
function findCheckpoint(checkpoints, editStart) {
|
|
77
|
+
let low = 0;
|
|
78
|
+
let high = checkpoints.length;
|
|
79
|
+
while (low + 1 < high) {
|
|
80
|
+
const middle = Math.floor((low + high) / 2);
|
|
81
|
+
if (checkpoints[middle].offset <= editStart) low = middle;
|
|
82
|
+
else high = middle;
|
|
83
|
+
}
|
|
84
|
+
return low;
|
|
85
|
+
}
|
|
86
|
+
//#endregion
|
|
87
|
+
export { ParserSession };
|
|
88
|
+
|
|
89
|
+
//# sourceMappingURL=session.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.mjs","names":[],"sources":["../../src/parser/session.ts"],"sourcesContent":["import type { PhysicalLine } from \"../source.ts\";\nimport type { BlockParserCheckpoint, SettledBlockListener } from \"./block-parser.ts\";\nimport type { BlockSyntax } from \"./block-syntax.ts\";\nimport type { PendingBlockSyntax } from \"./block-syntax.ts\";\n\nimport { InputError } from \"../errors.ts\";\nimport { SourceText } from \"../source-text.ts\";\nimport { PhysicalLineScanner, SourceFile, sourceText } from \"../source.ts\";\nimport {\n resolveSyntaxOptions,\n type ResolvedSyntaxOptions,\n type SyntaxOptions,\n} from \"../syntax-options.ts\";\nimport { BlockParser } from \"./block-parser.ts\";\n\nexport interface ParserSessionOptions {\n readonly source?: string | SourceFile;\n readonly syntax?: SyntaxOptions;\n /**\n * Receives each top-level block once it settles. After an edit, blocks settle\n * again from the first changed index.\n */\n readonly onSettled?: SettledBlockListener;\n}\n\n/** The unsettled top-level blocks, finished as if the source ended here. */\nexport interface ParserTailDraft {\n readonly blocks: readonly BlockSyntax[];\n /** The leaf that was still open, which later input may extend. */\n readonly pending?: PendingBlockSyntax;\n}\n\nexport interface ParserSessionEdit {\n readonly end: number;\n readonly start: number;\n readonly text: string;\n}\n\ninterface SessionCheckpoint {\n readonly line: number;\n readonly offset: number;\n readonly parser: BlockParserCheckpoint;\n}\n\n/** Retained parser state for streaming previews and edits. */\nexport class ParserSession {\n #blockParser: BlockParser;\n #checkpoints: SessionCheckpoint[];\n #lineScanner: PhysicalLineScanner;\n readonly syntax: ResolvedSyntaxOptions;\n #grammarSource = SourceText.of(\"\");\n #source = SourceText.of(\"\");\n\n public constructor(options: ParserSessionOptions = {}) {\n this.syntax = resolveSyntaxOptions(options.syntax);\n this.#blockParser = new BlockParser(this.syntax, [], options.onSettled);\n this.#lineScanner = new PhysicalLineScanner();\n this.#checkpoints = [{ line: 1, offset: 0, parser: { length: 0, tail: undefined } }];\n\n const source =\n options.source instanceof SourceFile ? options.source.text : (options.source ?? \"\");\n\n if (source !== \"\") {\n this.append(\n source,\n options.source instanceof SourceFile ? sourceText(options.source) : undefined,\n );\n }\n }\n\n /** The number of top-level blocks that later input cannot change. */\n public get settledCount(): number {\n return this.#blockParser.settledCount;\n }\n\n /** `source` is the whole source after the append, when the caller already built it. */\n public append(text: string, source?: SourceText): void {\n this.#source = source ?? this.#source.append(text);\n\n // Without NUL the grammar source is the source text itself.\n this.#grammarSource = this.#source.plain\n ? this.#source\n : this.#grammarSource.append(text.replaceAll(\"\\0\", \"\\uFFFD\"));\n\n for (const line of this.#lineScanner.append(text)) {\n this.writeLine(line);\n }\n }\n\n public edit(edit: ParserSessionEdit): void {\n if (\n !Number.isSafeInteger(edit.start) ||\n !Number.isSafeInteger(edit.end) ||\n edit.start < 0 ||\n edit.end < edit.start ||\n edit.end > this.#source.length\n ) {\n throw InputError.replacementRangeOutsideSource(edit.start, edit.end, this.#source.length);\n }\n\n const nextSource = this.#source.slice(0, edit.start) + edit.text + this.#source.slice(edit.end);\n const checkpointIndex = findCheckpoint(this.#checkpoints, edit.start);\n const checkpoint = this.#checkpoints[checkpointIndex];\n this.#source = SourceText.of(nextSource);\n this.#grammarSource = this.#source.plain\n ? this.#source\n : SourceText.of(nextSource.replaceAll(\"\\0\", \"\\uFFFD\"));\n this.#blockParser = this.#blockParser.fork(checkpoint.parser);\n this.#lineScanner = new PhysicalLineScanner({\n line: checkpoint.line,\n offset: checkpoint.offset,\n });\n this.#checkpoints.length = checkpointIndex + 1;\n\n for (const line of this.#lineScanner.append(nextSource.slice(checkpoint.offset))) {\n this.writeLine(line);\n }\n }\n\n /** Finishes a copy of the unsettled tail; the session itself stays open. */\n public tailDraft(): ParserTailDraft {\n const scanner = this.#lineScanner.clone();\n const parser = this.#blockParser.tail();\n\n for (const line of scanner.complete()) {\n // An empty last line is where input stopped, not a blank line that closes the open leaf.\n if (line.range.start < line.range.end) {\n parser.write(this.#grammarSource, line);\n }\n }\n\n const pending = parser.pending();\n\n return { blocks: parser.finish(this.#grammarSource), pending };\n }\n\n private writeLine(line: PhysicalLine): void {\n this.#blockParser.write(this.#grammarSource, line);\n const parser = this.#blockParser.checkpoint();\n\n if (parser !== undefined) {\n this.#checkpoints.push({ line: line.line + 1, offset: line.range.end, parser });\n }\n }\n}\n\nfunction findCheckpoint(checkpoints: readonly SessionCheckpoint[], editStart: number): number {\n let low = 0;\n let high = checkpoints.length;\n\n while (low + 1 < high) {\n const middle = Math.floor((low + high) / 2);\n\n if (checkpoints[middle].offset <= editStart) {\n low = middle;\n } else {\n high = middle;\n }\n }\n\n return low;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { SyntaxOptions } from "./syntax-options.mjs";
|
|
2
|
+
import { DocumentNode } from "./model.mjs";
|
|
3
|
+
import { SourceFile } from "./source.mjs";
|
|
4
|
+
import { Diagnostic } from "./diagnostics.mjs";
|
|
5
|
+
import { ParserLimit, ParserLimits, defaultParserLimits } from "./parser/config.mjs";
|
|
6
|
+
//#region src/parser.d.ts
|
|
7
|
+
export interface ParseOptions {
|
|
8
|
+
readonly limits?: ParserLimits;
|
|
9
|
+
readonly syntax?: SyntaxOptions;
|
|
10
|
+
}
|
|
11
|
+
export interface ParseResult {
|
|
12
|
+
readonly file: SourceFile;
|
|
13
|
+
readonly document: DocumentNode;
|
|
14
|
+
readonly diagnostics: readonly Diagnostic[];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Parses a complete document with the shared block and inline grammar.
|
|
18
|
+
* @throws {ParseError} Invalid authored syntax.
|
|
19
|
+
* @throws {LimitError} An exceeded parser limit.
|
|
20
|
+
* @throws {ConfigurationError} Invalid parser options.
|
|
21
|
+
*/
|
|
22
|
+
export declare function parse(input: string | SourceFile, options?: ParseOptions): ParseResult;
|
|
23
|
+
//#endregion
|
|
24
|
+
export { type ParserLimit, type ParserLimits, defaultParserLimits };
|
|
25
|
+
//# sourceMappingURL=parser.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.mts","names":[],"sources":["../src/parser.ts"],"mappings":";;;;;;iBAciB;WACN,SAAS;WACT,SAAS;;iBAGH;WACN,MAAM;WACN,UAAU;WACV,sBAAsB;;;;;;;;wBASjB,MAAM,gBAAgB,YAAY,UAAS,eAAoB"}
|
package/dist/parser.mjs
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { LimitError, ParseError } from "./errors.mjs";
|
|
2
|
+
import { resolveSyntaxOptions } from "./syntax-options.mjs";
|
|
3
|
+
import { PhysicalLineScanner, SourceFile, sourceText } from "./source.mjs";
|
|
4
|
+
import { defaultParserLimits, resolveParserLimits } from "./parser/config.mjs";
|
|
5
|
+
import { BlockParser } from "./parser/block-parser.mjs";
|
|
6
|
+
import { materializeDocument } from "./parser/materialize.mjs";
|
|
7
|
+
//#region src/parser.ts
|
|
8
|
+
/**
|
|
9
|
+
* Parses a complete document with the shared block and inline grammar.
|
|
10
|
+
* @throws {ParseError} Invalid authored syntax.
|
|
11
|
+
* @throws {LimitError} An exceeded parser limit.
|
|
12
|
+
* @throws {ConfigurationError} Invalid parser options.
|
|
13
|
+
*/
|
|
14
|
+
function parse(input, options = {}) {
|
|
15
|
+
const file = input instanceof SourceFile ? input : new SourceFile(input);
|
|
16
|
+
const limits = resolveParserLimits(options.limits);
|
|
17
|
+
if (file.length > limits.maximumSourceLength) throw LimitError.exceeded(file, "maximumSourceLength", limits.maximumSourceLength, void 0, file.length);
|
|
18
|
+
const syntax = resolveSyntaxOptions(options.syntax);
|
|
19
|
+
const text = file.text;
|
|
20
|
+
const source = sourceText(file).flatten().grammar();
|
|
21
|
+
const scanner = new PhysicalLineScanner();
|
|
22
|
+
const parser = new BlockParser(syntax);
|
|
23
|
+
for (const line of scanner.append(text)) parser.write(source, line);
|
|
24
|
+
for (const line of scanner.complete()) parser.write(source, line);
|
|
25
|
+
const materialized = materializeDocument(file, parser.finish(source), syntax, limits);
|
|
26
|
+
if (materialized.kind === "ok") return Object.freeze({
|
|
27
|
+
file,
|
|
28
|
+
document: materialized.document,
|
|
29
|
+
diagnostics: materialized.diagnostics
|
|
30
|
+
});
|
|
31
|
+
if (materialized.kind === "invalid") throw ParseError.invalidSyntax(file, materialized.diagnostics);
|
|
32
|
+
throw LimitError.exceeded(file, materialized.limit, limits[materialized.limit]);
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
export { defaultParserLimits, parse };
|
|
36
|
+
|
|
37
|
+
//# sourceMappingURL=parser.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.mjs","names":[],"sources":["../src/parser.ts"],"sourcesContent":["import type { Diagnostic } from \"./diagnostics.ts\";\nimport type { DocumentNode } from \"./model.ts\";\nimport type { ParserLimits } from \"./parser/config.ts\";\nimport type { SyntaxOptions } from \"./syntax-options.ts\";\n\nimport { LimitError, ParseError } from \"./errors.ts\";\nimport { BlockParser } from \"./parser/block-parser.ts\";\nimport { resolveParserLimits } from \"./parser/config.ts\";\nimport { materializeDocument } from \"./parser/materialize.ts\";\nimport { PhysicalLineScanner, SourceFile, sourceText } from \"./source.ts\";\nimport { resolveSyntaxOptions } from \"./syntax-options.ts\";\n\nexport { defaultParserLimits, type ParserLimit, type ParserLimits } from \"./parser/config.ts\";\n\nexport interface ParseOptions {\n readonly limits?: ParserLimits;\n readonly syntax?: SyntaxOptions;\n}\n\nexport interface ParseResult {\n readonly file: SourceFile;\n readonly document: DocumentNode;\n readonly diagnostics: readonly Diagnostic[];\n}\n\n/**\n * Parses a complete document with the shared block and inline grammar.\n * @throws {ParseError} Invalid authored syntax.\n * @throws {LimitError} An exceeded parser limit.\n * @throws {ConfigurationError} Invalid parser options.\n */\nexport function parse(input: string | SourceFile, options: ParseOptions = {}): ParseResult {\n const file = input instanceof SourceFile ? input : new SourceFile(input);\n const limits = resolveParserLimits(options.limits);\n\n if (file.length > limits.maximumSourceLength) {\n throw LimitError.exceeded(\n file,\n \"maximumSourceLength\",\n limits.maximumSourceLength,\n undefined,\n file.length,\n );\n }\n\n const syntax = resolveSyntaxOptions(options.syntax);\n const text = file.text;\n const source = sourceText(file).flatten().grammar();\n const scanner = new PhysicalLineScanner();\n const parser = new BlockParser(syntax);\n\n for (const line of scanner.append(text)) {\n parser.write(source, line);\n }\n\n for (const line of scanner.complete()) {\n parser.write(source, line);\n }\n\n const materialized = materializeDocument(file, parser.finish(source), syntax, limits);\n\n if (materialized.kind === \"ok\") {\n return Object.freeze({\n file,\n document: materialized.document,\n diagnostics: materialized.diagnostics,\n });\n }\n\n if (materialized.kind === \"invalid\") {\n throw ParseError.invalidSyntax(file, materialized.diagnostics);\n }\n\n throw LimitError.exceeded(file, materialized.limit, limits[materialized.limit]);\n}\n"],"mappings":";;;;;;;;;;;;;AA+BA,SAAgB,MAAM,OAA4B,UAAwB,CAAC,GAAgB;CACzF,MAAM,OAAO,iBAAiB,aAAa,QAAQ,IAAI,WAAW,KAAK;CACvE,MAAM,SAAS,oBAAoB,QAAQ,MAAM;CAEjD,IAAI,KAAK,SAAS,OAAO,qBACvB,MAAM,WAAW,SACf,MACA,uBACA,OAAO,qBACP,KAAA,GACA,KAAK,MACP;CAGF,MAAM,SAAS,qBAAqB,QAAQ,MAAM;CAClD,MAAM,OAAO,KAAK;CAClB,MAAM,SAAS,WAAW,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ;CAClD,MAAM,UAAU,IAAI,oBAAoB;CACxC,MAAM,SAAS,IAAI,YAAY,MAAM;CAErC,KAAK,MAAM,QAAQ,QAAQ,OAAO,IAAI,GACpC,OAAO,MAAM,QAAQ,IAAI;CAG3B,KAAK,MAAM,QAAQ,QAAQ,SAAS,GAClC,OAAO,MAAM,QAAQ,IAAI;CAG3B,MAAM,eAAe,oBAAoB,MAAM,OAAO,OAAO,MAAM,GAAG,QAAQ,MAAM;CAEpF,IAAI,aAAa,SAAS,MACxB,OAAO,OAAO,OAAO;EACnB;EACA,UAAU,aAAa;EACvB,aAAa,aAAa;CAC5B,CAAC;CAGH,IAAI,aAAa,SAAS,WACxB,MAAM,WAAW,cAAc,MAAM,aAAa,WAAW;CAG/D,MAAM,WAAW,SAAS,MAAM,aAAa,OAAO,OAAO,aAAa,MAAM;AAChF"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { SyntaxOptions } from "./syntax-options.mjs";
|
|
2
|
+
import { DocumentNode } from "./model.mjs";
|
|
3
|
+
import { HtmlNode, HtmlRootNode } from "./html.mjs";
|
|
4
|
+
import { SourceFile } from "./source.mjs";
|
|
5
|
+
import { DiagnosticBag } from "./diagnostics.mjs";
|
|
6
|
+
import { DocumentPlugin, HtmlPlugin } from "./plugin.mjs";
|
|
7
|
+
//#region src/plugin-internal.d.ts
|
|
8
|
+
export interface PluginRun {
|
|
9
|
+
readonly diagnostics: DiagnosticBag;
|
|
10
|
+
readonly file: SourceFile;
|
|
11
|
+
readonly signal?: AbortSignal;
|
|
12
|
+
readonly syntax: Readonly<SyntaxOptions>;
|
|
13
|
+
/** Rejects asynchronous plugin results. */
|
|
14
|
+
readonly synchronous: boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare function runDocumentPlugins(document: DocumentNode, plugins: readonly DocumentPlugin[], run: PluginRun): DocumentNode | Promise<DocumentNode>;
|
|
17
|
+
export declare function runHtmlPlugins(root: HtmlRootNode, plugins: readonly HtmlPlugin[], run: PluginRun): HtmlRootNode | Promise<HtmlRootNode>;
|
|
18
|
+
export type HtmlNodeReplacement = HtmlNode | null | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Replaces HTML nodes with possibly asynchronous results. `undefined` keeps a
|
|
21
|
+
* node and `null` removes it. Replaced nodes are not visited again.
|
|
22
|
+
*/
|
|
23
|
+
export declare function replaceHtmlNodes(root: HtmlRootNode, replace: (node: HtmlNode) => HtmlNodeReplacement | Promise<HtmlNodeReplacement>): HtmlRootNode | Promise<HtmlRootNode>;
|
|
24
|
+
//#endregion
|
|
25
|
+
//# sourceMappingURL=plugin-internal.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-internal.d.mts","names":[],"sources":["../src/plugin-internal.ts"],"mappings":";;;;;;;iBAiBiB;WACN,aAAa;WACb,MAAM;WACN,SAAS;WACT,QAAQ,SAAS;;WAEjB;;wBAGK,mBACd,UAAU,cACV,kBAAkB,kBAClB,KAAK,YACJ,eAAe,QAAQ;wBAWV,eACd,MAAM,cACN,kBAAkB,cAClB,KAAK,YACJ,eAAe,QAAQ;YA6Fd,sBAAsB;;;;;wBAMlB,iBACd,MAAM,cACN,UAAU,MAAM,aAAa,sBAAsB,QAAQ,uBAC1D,eAAe,QAAQ"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { ConfigurationError, TransformError } from "./errors.mjs";
|
|
2
|
+
import { rewriteHtml, rewriteMdx, walkHtml } from "./traversal.mjs";
|
|
3
|
+
import { isPromise } from "@temelj/value";
|
|
4
|
+
//#region src/plugin-internal.ts
|
|
5
|
+
function runDocumentPlugins(document, plugins, run) {
|
|
6
|
+
return runPlugins("document", document, plugins, run, (current) => ({
|
|
7
|
+
diagnostics: run.diagnostics,
|
|
8
|
+
document: current,
|
|
9
|
+
file: run.file,
|
|
10
|
+
signal: run.signal,
|
|
11
|
+
syntax: run.syntax,
|
|
12
|
+
rewrite: (handlers) => rewriteMdx(current, handlers)
|
|
13
|
+
}));
|
|
14
|
+
}
|
|
15
|
+
function runHtmlPlugins(root, plugins, run) {
|
|
16
|
+
return runPlugins("html", root, plugins, run, (current) => ({
|
|
17
|
+
diagnostics: run.diagnostics,
|
|
18
|
+
root: current,
|
|
19
|
+
file: run.file,
|
|
20
|
+
signal: run.signal,
|
|
21
|
+
syntax: run.syntax,
|
|
22
|
+
rewrite: (handlers) => rewriteHtml(current, handlers)
|
|
23
|
+
}));
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Runs plugins in order. Synchronous results continue in the same call; the
|
|
27
|
+
* first asynchronous result continues the remaining plugins after it settles.
|
|
28
|
+
*/
|
|
29
|
+
function runPlugins(stage, tree, plugins, run, context) {
|
|
30
|
+
let current = tree;
|
|
31
|
+
for (let index = 0; index < plugins.length; index++) {
|
|
32
|
+
run.signal?.throwIfAborted();
|
|
33
|
+
const plugin = plugins[index];
|
|
34
|
+
const diagnosticStart = run.diagnostics.size;
|
|
35
|
+
const accept = (result) => {
|
|
36
|
+
run.signal?.throwIfAborted();
|
|
37
|
+
if (run.diagnostics.hasErrorsSince(diagnosticStart)) throw TransformError.pluginReportedErrors(stage, plugin.name, run.file, run.diagnostics.snapshot());
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
const fail = (cause) => {
|
|
41
|
+
run.signal?.throwIfAborted();
|
|
42
|
+
if (cause instanceof ConfigurationError) throw cause;
|
|
43
|
+
throw TransformError.pluginTransformFailed(stage, plugin.name, run.file, run.diagnostics.snapshot(), cause);
|
|
44
|
+
};
|
|
45
|
+
let result;
|
|
46
|
+
try {
|
|
47
|
+
result = plugin.transform(context(current));
|
|
48
|
+
} catch (cause) {
|
|
49
|
+
return fail(cause);
|
|
50
|
+
}
|
|
51
|
+
if (isPromise(result)) {
|
|
52
|
+
if (run.synchronous) {
|
|
53
|
+
result.catch(() => {});
|
|
54
|
+
throw ConfigurationError.asynchronousPluginInSynchronousProcessor();
|
|
55
|
+
}
|
|
56
|
+
const remaining = plugins.slice(index + 1);
|
|
57
|
+
return result.then(accept, fail).then((next) => runPlugins(stage, next, remaining, run, context));
|
|
58
|
+
}
|
|
59
|
+
current = accept(result);
|
|
60
|
+
}
|
|
61
|
+
return current;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Replaces HTML nodes with possibly asynchronous results. `undefined` keeps a
|
|
65
|
+
* node and `null` removes it. Replaced nodes are not visited again.
|
|
66
|
+
*/
|
|
67
|
+
function replaceHtmlNodes(root, replace) {
|
|
68
|
+
const pending = [];
|
|
69
|
+
const replacements = /* @__PURE__ */ new Map();
|
|
70
|
+
for (const { node } of walkHtml(root)) {
|
|
71
|
+
const result = replace(node);
|
|
72
|
+
if (isPromise(result)) pending.push(result.then((value) => [node, value]));
|
|
73
|
+
else if (result !== void 0) replacements.set(node, result);
|
|
74
|
+
}
|
|
75
|
+
const lookup = ({ node }) => replacements.get(node);
|
|
76
|
+
const apply = () => rewriteHtml(root, {
|
|
77
|
+
codeBlock: lookup,
|
|
78
|
+
comment: lookup,
|
|
79
|
+
doctype: lookup,
|
|
80
|
+
element: lookup,
|
|
81
|
+
expression: lookup,
|
|
82
|
+
footnoteReference: lookup,
|
|
83
|
+
footnoteSection: lookup,
|
|
84
|
+
jsx: lookup,
|
|
85
|
+
math: lookup,
|
|
86
|
+
raw: lookup,
|
|
87
|
+
root: lookup,
|
|
88
|
+
text: lookup
|
|
89
|
+
});
|
|
90
|
+
if (pending.length === 0) return apply();
|
|
91
|
+
return Promise.all(pending).then((entries) => {
|
|
92
|
+
for (const [node, value] of entries) if (value !== void 0) replacements.set(node, value);
|
|
93
|
+
return apply();
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
//#endregion
|
|
97
|
+
export { replaceHtmlNodes, runDocumentPlugins, runHtmlPlugins };
|
|
98
|
+
|
|
99
|
+
//# sourceMappingURL=plugin-internal.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-internal.mjs","names":[],"sources":["../src/plugin-internal.ts"],"sourcesContent":["import { isPromise } from \"@temelj/value\";\n\nimport type { DiagnosticBag } from \"./diagnostics.ts\";\nimport type { HtmlNode, HtmlRootNode } from \"./html.ts\";\nimport type { DocumentNode } from \"./model.ts\";\nimport type {\n DocumentPlugin,\n DocumentPluginContext,\n HtmlPlugin,\n HtmlPluginContext,\n} from \"./plugin.ts\";\nimport type { SourceFile } from \"./source.ts\";\nimport type { SyntaxOptions } from \"./syntax-options.ts\";\n\nimport { ConfigurationError, TransformError } from \"./errors.ts\";\nimport { rewriteHtml, rewriteMdx, walkHtml } from \"./traversal.ts\";\n\nexport interface PluginRun {\n readonly diagnostics: DiagnosticBag;\n readonly file: SourceFile;\n readonly signal?: AbortSignal;\n readonly syntax: Readonly<SyntaxOptions>;\n /** Rejects asynchronous plugin results. */\n readonly synchronous: boolean;\n}\n\nexport function runDocumentPlugins(\n document: DocumentNode,\n plugins: readonly DocumentPlugin[],\n run: PluginRun,\n): DocumentNode | Promise<DocumentNode> {\n return runPlugins(\"document\", document, plugins, run, (current): DocumentPluginContext => ({\n diagnostics: run.diagnostics,\n document: current,\n file: run.file,\n signal: run.signal,\n syntax: run.syntax,\n rewrite: (handlers) => rewriteMdx(current, handlers),\n }));\n}\n\nexport function runHtmlPlugins(\n root: HtmlRootNode,\n plugins: readonly HtmlPlugin[],\n run: PluginRun,\n): HtmlRootNode | Promise<HtmlRootNode> {\n return runPlugins(\"html\", root, plugins, run, (current): HtmlPluginContext => ({\n diagnostics: run.diagnostics,\n root: current,\n file: run.file,\n signal: run.signal,\n syntax: run.syntax,\n rewrite: (handlers) => rewriteHtml(current, handlers),\n }));\n}\n\ninterface Plugin<TTree, TContext> {\n readonly name: string;\n\n transform(context: TContext): TTree | Promise<TTree>;\n}\n\n/**\n * Runs plugins in order. Synchronous results continue in the same call; the\n * first asynchronous result continues the remaining plugins after it settles.\n */\nfunction runPlugins<TTree, TContext>(\n stage: \"document\" | \"html\",\n tree: TTree,\n plugins: readonly Plugin<TTree, TContext>[],\n run: PluginRun,\n context: (tree: TTree) => TContext,\n): TTree | Promise<TTree> {\n let current = tree;\n\n for (let index = 0; index < plugins.length; index++) {\n run.signal?.throwIfAborted();\n const plugin = plugins[index];\n const diagnosticStart = run.diagnostics.size;\n\n const accept = (result: TTree): TTree => {\n run.signal?.throwIfAborted();\n\n if (run.diagnostics.hasErrorsSince(diagnosticStart)) {\n throw TransformError.pluginReportedErrors(\n stage,\n plugin.name,\n run.file,\n run.diagnostics.snapshot(),\n );\n }\n\n return result;\n };\n\n const fail = (cause: unknown): never => {\n run.signal?.throwIfAborted();\n\n if (cause instanceof ConfigurationError) {\n throw cause;\n }\n\n throw TransformError.pluginTransformFailed(\n stage,\n plugin.name,\n run.file,\n run.diagnostics.snapshot(),\n cause,\n );\n };\n\n let result: TTree | Promise<TTree>;\n\n try {\n result = plugin.transform(context(current));\n } catch (cause) {\n return fail(cause);\n }\n\n if (isPromise(result)) {\n if (run.synchronous) {\n void result.catch(() => {});\n throw ConfigurationError.asynchronousPluginInSynchronousProcessor();\n }\n\n const remaining = plugins.slice(index + 1);\n\n return result\n .then(accept, fail)\n .then((next) => runPlugins(stage, next, remaining, run, context));\n }\n\n current = accept(result);\n }\n\n return current;\n}\n\nexport type HtmlNodeReplacement = HtmlNode | null | undefined;\n\n/**\n * Replaces HTML nodes with possibly asynchronous results. `undefined` keeps a\n * node and `null` removes it. Replaced nodes are not visited again.\n */\nexport function replaceHtmlNodes(\n root: HtmlRootNode,\n replace: (node: HtmlNode) => HtmlNodeReplacement | Promise<HtmlNodeReplacement>,\n): HtmlRootNode | Promise<HtmlRootNode> {\n const pending: Array<Promise<readonly [HtmlNode, HtmlNodeReplacement]>> = [];\n const replacements = new Map<HtmlNode, HtmlNodeReplacement>();\n\n for (const { node } of walkHtml(root)) {\n const result = replace(node);\n\n if (isPromise(result)) {\n pending.push(result.then((value) => [node, value] as const));\n } else if (result !== undefined) {\n replacements.set(node, result);\n }\n }\n\n const lookup = ({ node }: { readonly node: HtmlNode }): HtmlNodeReplacement =>\n replacements.get(node);\n\n const apply = (): HtmlRootNode =>\n rewriteHtml(root, {\n codeBlock: lookup,\n comment: lookup,\n doctype: lookup,\n element: lookup,\n expression: lookup,\n footnoteReference: lookup,\n footnoteSection: lookup,\n jsx: lookup,\n math: lookup,\n raw: lookup,\n root: lookup,\n text: lookup,\n });\n\n if (pending.length === 0) {\n return apply();\n }\n\n return Promise.all(pending).then((entries) => {\n for (const [node, value] of entries) {\n if (value !== undefined) {\n replacements.set(node, value);\n }\n }\n\n return apply();\n });\n}\n"],"mappings":";;;;AA0BA,SAAgB,mBACd,UACA,SACA,KACsC;CACtC,OAAO,WAAW,YAAY,UAAU,SAAS,MAAM,aAAoC;EACzF,aAAa,IAAI;EACjB,UAAU;EACV,MAAM,IAAI;EACV,QAAQ,IAAI;EACZ,QAAQ,IAAI;EACZ,UAAU,aAAa,WAAW,SAAS,QAAQ;CACrD,EAAE;AACJ;AAEA,SAAgB,eACd,MACA,SACA,KACsC;CACtC,OAAO,WAAW,QAAQ,MAAM,SAAS,MAAM,aAAgC;EAC7E,aAAa,IAAI;EACjB,MAAM;EACN,MAAM,IAAI;EACV,QAAQ,IAAI;EACZ,QAAQ,IAAI;EACZ,UAAU,aAAa,YAAY,SAAS,QAAQ;CACtD,EAAE;AACJ;;;;;AAYA,SAAS,WACP,OACA,MACA,SACA,KACA,SACwB;CACxB,IAAI,UAAU;CAEd,KAAK,IAAI,QAAQ,GAAG,QAAQ,QAAQ,QAAQ,SAAS;EACnD,IAAI,QAAQ,eAAe;EAC3B,MAAM,SAAS,QAAQ;EACvB,MAAM,kBAAkB,IAAI,YAAY;EAExC,MAAM,UAAU,WAAyB;GACvC,IAAI,QAAQ,eAAe;GAE3B,IAAI,IAAI,YAAY,eAAe,eAAe,GAChD,MAAM,eAAe,qBACnB,OACA,OAAO,MACP,IAAI,MACJ,IAAI,YAAY,SAAS,CAC3B;GAGF,OAAO;EACT;EAEA,MAAM,QAAQ,UAA0B;GACtC,IAAI,QAAQ,eAAe;GAE3B,IAAI,iBAAiB,oBACnB,MAAM;GAGR,MAAM,eAAe,sBACnB,OACA,OAAO,MACP,IAAI,MACJ,IAAI,YAAY,SAAS,GACzB,KACF;EACF;EAEA,IAAI;EAEJ,IAAI;GACF,SAAS,OAAO,UAAU,QAAQ,OAAO,CAAC;EAC5C,SAAS,OAAO;GACd,OAAO,KAAK,KAAK;EACnB;EAEA,IAAI,UAAU,MAAM,GAAG;GACrB,IAAI,IAAI,aAAa;IACnB,OAAY,YAAY,CAAC,CAAC;IAC1B,MAAM,mBAAmB,yCAAyC;GACpE;GAEA,MAAM,YAAY,QAAQ,MAAM,QAAQ,CAAC;GAEzC,OAAO,OACJ,KAAK,QAAQ,IAAI,CAAC,CAClB,MAAM,SAAS,WAAW,OAAO,MAAM,WAAW,KAAK,OAAO,CAAC;EACpE;EAEA,UAAU,OAAO,MAAM;CACzB;CAEA,OAAO;AACT;;;;;AAQA,SAAgB,iBACd,MACA,SACsC;CACtC,MAAM,UAAoE,CAAC;CAC3E,MAAM,+BAAe,IAAI,IAAmC;CAE5D,KAAK,MAAM,EAAE,UAAU,SAAS,IAAI,GAAG;EACrC,MAAM,SAAS,QAAQ,IAAI;EAE3B,IAAI,UAAU,MAAM,GAClB,QAAQ,KAAK,OAAO,MAAM,UAAU,CAAC,MAAM,KAAK,CAAU,CAAC;OACtD,IAAI,WAAW,KAAA,GACpB,aAAa,IAAI,MAAM,MAAM;CAEjC;CAEA,MAAM,UAAU,EAAE,WAChB,aAAa,IAAI,IAAI;CAEvB,MAAM,cACJ,YAAY,MAAM;EAChB,WAAW;EACX,SAAS;EACT,SAAS;EACT,SAAS;EACT,YAAY;EACZ,mBAAmB;EACnB,iBAAiB;EACjB,KAAK;EACL,MAAM;EACN,KAAK;EACL,MAAM;EACN,MAAM;CACR,CAAC;CAEH,IAAI,QAAQ,WAAW,GACrB,OAAO,MAAM;CAGf,OAAO,QAAQ,IAAI,OAAO,CAAC,CAAC,MAAM,YAAY;EAC5C,KAAK,MAAM,CAAC,MAAM,UAAU,SAC1B,IAAI,UAAU,KAAA,GACZ,aAAa,IAAI,MAAM,KAAK;EAIhC,OAAO,MAAM;CACf,CAAC;AACH"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { SyntaxOptions } from "./syntax-options.mjs";
|
|
2
|
+
import { DocumentNode } from "./model.mjs";
|
|
3
|
+
import { HtmlRootNode } from "./html.mjs";
|
|
4
|
+
import { SourceFile } from "./source.mjs";
|
|
5
|
+
import { DiagnosticReporter } from "./diagnostics.mjs";
|
|
6
|
+
import { HtmlRewriteHandlers, MdxRewriteHandlers } from "./traversal.mjs";
|
|
7
|
+
//#region src/plugin.d.ts
|
|
8
|
+
interface PluginContextBase {
|
|
9
|
+
/** Error diagnostics added by a plugin discard that plugin's result. */
|
|
10
|
+
readonly diagnostics: DiagnosticReporter;
|
|
11
|
+
readonly file: SourceFile;
|
|
12
|
+
readonly signal?: AbortSignal;
|
|
13
|
+
readonly syntax: Readonly<SyntaxOptions>;
|
|
14
|
+
}
|
|
15
|
+
export interface DocumentPluginContext extends PluginContextBase {
|
|
16
|
+
readonly document: DocumentNode;
|
|
17
|
+
rewrite(handlers: MdxRewriteHandlers): DocumentNode;
|
|
18
|
+
}
|
|
19
|
+
export interface HtmlPluginContext extends PluginContextBase {
|
|
20
|
+
readonly root: HtmlRootNode;
|
|
21
|
+
rewrite(handlers: HtmlRewriteHandlers): HtmlRootNode;
|
|
22
|
+
}
|
|
23
|
+
/** Transforms the semantic document before HTML lowering or compilation. */
|
|
24
|
+
export interface DocumentPlugin {
|
|
25
|
+
readonly name: string;
|
|
26
|
+
transform(context: DocumentPluginContext): DocumentNode | Promise<DocumentNode>;
|
|
27
|
+
}
|
|
28
|
+
/** Transforms lowered HTML. HTML plugins do not run before compilation. */
|
|
29
|
+
export interface HtmlPlugin {
|
|
30
|
+
readonly name: string;
|
|
31
|
+
transform(context: HtmlPluginContext): HtmlRootNode | Promise<HtmlRootNode>;
|
|
32
|
+
}
|
|
33
|
+
/** Whether a plugin provider fails the pipeline or keeps the fallback with a warning. */
|
|
34
|
+
export type PluginFailureMode = "strict" | "tolerant";
|
|
35
|
+
//#endregion
|
|
36
|
+
export {};
|
|
37
|
+
//# sourceMappingURL=plugin.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.mts","names":[],"sources":["../src/plugin.ts"],"mappings":";;;;;;;UAOU;;WAEC,aAAa;WACb,MAAM;WACN,SAAS;WACT,QAAQ,SAAS;;iBAGX,8BAA8B;WACpC,UAAU;EAEnB,QAAQ,UAAU,qBAAqB;;iBAGxB,0BAA0B;WAChC,MAAM;EAEf,QAAQ,UAAU,sBAAsB;;;iBAIzB;WACN;EAET,UAAU,SAAS,wBAAwB,eAAe,QAAQ;;;iBAInD;WACN;EAET,UAAU,SAAS,oBAAoB,eAAe,QAAQ;;;YAIpD"}
|
package/dist/plugin.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|