@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":"html-lower.mjs","names":["exhaustive"],"sources":["../src/html-lower.ts"],"sourcesContent":["import { isFunction } from \"@temelj/value\";\n\nimport type { FootnoteOccurrence } from \"./footnote-numbering.ts\";\nimport type {\n HtmlAttributes,\n HtmlElementNode,\n HtmlFootnoteSectionNode,\n HtmlNode,\n HtmlRootNode,\n HtmlTextNode,\n HtmlUnresolvedReferenceNode,\n} from \"./html.ts\";\nimport type {\n ContainerDirectiveNode,\n DirectiveAttribute,\n DefinitionNode,\n DocumentNode,\n FootnoteDefinitionNode,\n FootnoteReferenceNode,\n ImageReferenceNode,\n LeafDirectiveNode,\n LinkReferenceNode,\n ListItemNode,\n ListNode,\n MdxNode,\n TableAlignment,\n TableNode,\n TableRowNode,\n TextDirectiveNode,\n} from \"./model.ts\";\nimport type { SourceRange } from \"./ranges.ts\";\nimport type { SourceFile } from \"./source.ts\";\n\nimport { FootnoteNumbering } from \"./footnote-numbering.ts\";\nimport { formatMdx } from \"./format.ts\";\nimport { indexDocument, mdxChildren } from \"./model.ts\";\nimport { isUrlControlCharacter, normalizeUri } from \"./uri.ts\";\n\nexport interface HtmlRenderOptions {\n readonly allowUnsafeUrls?: boolean;\n readonly clobberPrefix?: string;\n readonly footnoteBackLabel?:\n | string\n | ((referenceIndex: number, rereferenceIndex: number) => string);\n readonly footnoteLabel?: string;\n readonly footnoteLabelTagName?: string;\n /** The file that node origins refer to. Inert fallbacks then keep authored text. */\n readonly source?: SourceFile;\n /**\n * Rewrites link and image URLs. `sanitized` is the default policy result, or\n * `undefined` when the default removes the URL; returning `undefined` removes it.\n */\n readonly urlTransform?: (\n url: string,\n kind: \"image\" | \"link\",\n sanitized: string | undefined,\n ) => string | undefined;\n}\n\n/**\n * Lowered HTML by node identity, separately for tight and loose list context. A\n * cache is valid while link definitions are unchanged. Subtrees that depend on\n * footnote numbering or a replacement are never cached.\n */\nexport interface HtmlLoweringCache {\n readonly loose: WeakMap<MdxNode, LoweredHtml>;\n readonly tight: WeakMap<MdxNode, LoweredHtml>;\n /** A growing list's lowered children, by the item they end with. */\n readonly lists: WeakMap<ListItemNode, ListPrefix>;\n}\n\n/** The wrapped children of a list's first `index + 1` items. */\ninterface ListPrefix {\n readonly index: number;\n readonly loose: boolean;\n readonly spread: boolean;\n readonly tasks: boolean;\n readonly children: SequencePrefix;\n}\n\nexport function createHtmlLoweringCache(): HtmlLoweringCache {\n return { loose: new WeakMap(), tight: new WeakMap(), lists: new WeakMap() };\n}\n\n/**\n * What lowering resolves against. Batch lowering derives a scope from one\n * document; a stream assembles one from its settled blocks and open tail.\n */\nexport interface LoweringScope {\n readonly definition: (identifier: string) => DefinitionNode | undefined;\n readonly footnote: (identifier: string) => FootnoteDefinitionNode | undefined;\n readonly options: HtmlRenderOptions;\n /** The numbering of a reference to a defined footnote. */\n readonly occurrence: (node: FootnoteReferenceNode) => FootnoteOccurrence | undefined;\n /** Missing references lower to `unresolvedReference` nodes instead of authored text. */\n readonly provisional?: boolean;\n readonly cache?: HtmlLoweringCache;\n /** Lowers one node differently, such as the open leaf of a stream. */\n readonly replace?: (node: MdxNode) => readonly HtmlNode[] | undefined;\n}\n\ninterface HtmlLoweringContext {\n readonly scope: LoweringScope;\n readonly listLoose: boolean;\n /** Counts lowered nodes whose output must not be cached. */\n readonly volatile: { count: number };\n}\n\ntype LoweredHtml = HtmlNode | readonly HtmlNode[] | undefined;\n\nconst percentEncodedByteLength = 2;\n\nconst hexadecimalRadix = 16;\n\nconst percentEncodedByte = /^[0-9A-Fa-f]{2}$/u;\n\nconst linkSchemes = new Set([\"http\", \"https\", \"irc\", \"ircs\", \"mailto\", \"xmpp\"]);\n\nconst imageSchemes = new Set([\"http\", \"https\"]);\n\nexport function lowerHtml(document: DocumentNode, options: HtmlRenderOptions = {}): HtmlRootNode {\n const index = indexDocument(document);\n const numbering = new FootnoteNumbering();\n const occurrences = new Map<FootnoteReferenceNode, FootnoteOccurrence>();\n\n for (const reference of footnoteReferences(document)) {\n if (index.footnotes.has(reference.identifier)) {\n occurrences.set(reference, numbering.reference(reference.identifier));\n }\n }\n\n const scope: LoweringScope = {\n definition: (identifier) => index.definitions.get(identifier),\n footnote: (identifier) => index.footnotes.get(identifier),\n options,\n occurrence: (node) => occurrences.get(node),\n };\n\n const children = lowerNodes(document.children, scope);\n const footnotes = lowerFootnoteSection(numbering, scope);\n\n if (footnotes !== undefined) {\n children.push(footnotes);\n }\n\n return { kind: \"root\", children: joinBlocks(children), origin: document.origin };\n}\n\n/**\n * Lowers sibling nodes in one scope. `previous` is the sibling before them,\n * because text after a hard break drops its leading spaces.\n */\nexport function lowerNodes(\n nodes: readonly MdxNode[],\n scope: LoweringScope,\n previous?: MdxNode,\n): HtmlNode[] {\n return lowerChildren(nodes, { scope, listLoose: false, volatile: { count: 0 } }, previous);\n}\n\n/** Separates top-level blocks with line endings, like a document root. */\nexport function joinBlocks(nodes: readonly HtmlNode[]): HtmlNode[] {\n return wrap(nodes, false);\n}\n\n/** Footnote reference nodes in document order. */\nexport function footnoteReferences(node: MdxNode): FootnoteReferenceNode[] {\n const result: FootnoteReferenceNode[] = [];\n\n const visit = (current: MdxNode): void => {\n if (current.kind === \"footnoteReference\") {\n result.push(current);\n }\n\n mdxChildren(current).forEach(visit);\n };\n\n visit(node);\n\n return result;\n}\n\nfunction lowerHtmlNode(node: MdxNode, context: HtmlLoweringContext): LoweredHtml {\n const replaced = context.scope.replace?.(node);\n\n if (replaced !== undefined) {\n context.volatile.count++;\n\n return replaced;\n }\n\n const cache = context.listLoose ? context.scope.cache?.loose : context.scope.cache?.tight;\n\n if (cache?.has(node) === true) {\n return cache.get(node);\n }\n\n const volatile = context.volatile.count;\n const lowered = lowerHtmlNodeCore(node, context);\n\n const result =\n lowered === undefined || node.origin === undefined\n ? lowered\n : isHtmlNodeArray(lowered)\n ? lowered.map((item) => withOrigin(item, node.origin))\n : withOrigin(lowered, node.origin);\n\n if (context.volatile.count === volatile) {\n cache?.set(node, result);\n }\n\n return result;\n}\n\nfunction isHtmlNodeArray(value: HtmlNode | readonly HtmlNode[]): value is readonly HtmlNode[] {\n return Array.isArray(value);\n}\n\nfunction withOrigin(node: HtmlNode, origin: SourceRange | undefined): HtmlNode {\n return origin === undefined || node.origin !== undefined ? node : { ...node, origin };\n}\n\n/** Authored source when the file is known, otherwise canonical MDX. */\nfunction authored(node: MdxNode, context: HtmlLoweringContext): string {\n const source = context.scope.options.source;\n\n return source !== undefined && node.origin !== undefined\n ? source.slice(node.origin)\n : formatMdx(node);\n}\n\nfunction lowerHtmlNodeCore(node: MdxNode, context: HtmlLoweringContext): LoweredHtml {\n switch (node.kind) {\n case \"text\":\n return text(node.value);\n case \"emphasis\":\n return htmlElement(\"em\", node.children, context);\n case \"strong\":\n return htmlElement(\"strong\", node.children, context);\n case \"delete\":\n return htmlElement(\"del\", node.children, context);\n case \"directiveLabel\":\n return lowerChildren(node.children, context);\n case \"textDirective\":\n return lowerTextDirective(node, context);\n case \"inlineCode\":\n return element(\"code\", {}, [text(node.value.replace(/\\r\\n?|\\n/gu, \" \"))]);\n case \"inlineMath\":\n return { kind: \"math\", source: node.value.replace(/\\r\\n?|\\n/gu, \" \"), style: \"inline\" };\n case \"hardBreak\":\n return [element(\"br\"), text(\"\\n\")];\n case \"link\":\n return lowerLink(node.url, node.title, node.children, context);\n case \"linkReference\": {\n const definition = context.scope.definition(node.identifier);\n\n if (definition !== undefined) {\n return lowerLink(definition.url, definition.title, node.children, context);\n }\n\n return context.scope.provisional === true\n ? unresolvedReference(\"link\", node, lowerChildren(node.children, context), context)\n : revertReference(node, context);\n }\n\n case \"image\":\n return lowerImage(node.url, node.alt, node.title, context);\n case \"imageReference\": {\n const definition = context.scope.definition(node.identifier);\n\n if (definition !== undefined) {\n return lowerImage(definition.url, node.alt, definition.title, context);\n }\n\n return context.scope.provisional === true\n ? unresolvedReference(\"image\", node, [text(node.alt)], context)\n : text(formatMdx(node));\n }\n\n case \"footnoteReference\": {\n context.volatile.count++;\n const occurrence = context.scope.occurrence(node);\n\n if (occurrence !== undefined) {\n return lowerFootnoteReference(node, occurrence, context.scope.options);\n }\n\n return context.scope.provisional === true\n ? unresolvedReference(\"footnote\", node, [], context)\n : text(formatMdx(node));\n }\n\n case \"definition\":\n case \"footnoteDefinition\":\n case \"frontmatter\":\n case \"esm\":\n return undefined;\n case \"leafDirective\":\n return lowerLeafDirective(node, context);\n case \"containerDirective\":\n return lowerContainerDirective(node, context);\n case \"rawHtmlBlock\":\n case \"rawHtmlInline\":\n return { kind: \"raw\", value: node.value };\n case \"inlineExpression\":\n case \"blockExpression\":\n return { kind: \"expression\", code: node.code, fallback: authored(node, context) };\n case \"jsxTextElement\":\n case \"jsxFlowElement\":\n return {\n kind: \"jsx\",\n state: \"complete\",\n element: node.kind === \"jsxFlowElement\" ? \"flow\" : \"text\",\n name: node.name,\n attributes: node.attributes,\n fallback: authored(node, context),\n children: lowerChildren(node.children, context),\n };\n case \"paragraph\":\n // Like MDX, a paragraph of only JSX and expressions does not produce a `p`.\n return node.children.every(isEmbeddedPhrasing) &&\n node.children.some((child) => child.kind !== \"text\")\n ? lowerChildren(node.children, context)\n : htmlElement(\"p\", node.children, context);\n case \"heading\":\n return htmlElement(`h${node.depth}`, node.children, context);\n case \"codeBlock\": {\n const language = node.language?.trim().split(/\\s+/u)[0];\n\n return language === undefined || language.length === 0\n ? element(\"pre\", {}, [\n element(\"code\", {}, [text(node.value.length === 0 ? \"\" : `${node.value}\\n`)]),\n ])\n : { kind: \"codeBlock\", code: node.value, language, meta: node.meta };\n }\n\n case \"displayMath\":\n return { kind: \"math\", source: node.value, style: \"display\", meta: node.meta };\n case \"thematicBreak\":\n return element(\"hr\");\n case \"list\":\n return lowerList(node, context);\n case \"listItem\":\n return lowerListItem(node, context);\n case \"table\":\n return lowerTable(node, context);\n case \"tableRow\":\n return lowerTableRow(node, undefined, false, context);\n case \"tableCell\":\n return htmlElement(\"td\", node.children, context);\n case \"blockquote\":\n return element(\"blockquote\", {}, wrap(lowerChildren(node.children, context), true));\n case \"document\":\n return wrap(lowerChildren(node.children, context), false);\n default: {\n const exhaustive: never = node;\n\n return exhaustive;\n }\n }\n}\n\nfunction isEmbeddedPhrasing(node: MdxNode): boolean {\n return (\n node.kind === \"jsxTextElement\" ||\n node.kind === \"inlineExpression\" ||\n (node.kind === \"text\" && node.value.trim() === \"\")\n );\n}\n\nfunction lowerTextDirective(\n node: TextDirectiveNode,\n context: HtmlLoweringContext,\n): HtmlElementNode {\n return element(\n \"span\",\n directiveHtmlAttributes(node.name, \"text\", node.attributes),\n node.label === undefined ? [] : lowerChildren(node.label.children, context),\n );\n}\n\nfunction lowerLeafDirective(\n node: LeafDirectiveNode,\n context: HtmlLoweringContext,\n): HtmlElementNode {\n return element(\n \"div\",\n directiveHtmlAttributes(node.name, \"leaf\", node.attributes),\n node.label === undefined ? [] : [directiveLabel(node, context)],\n );\n}\n\nfunction lowerContainerDirective(\n node: ContainerDirectiveNode,\n context: HtmlLoweringContext,\n): HtmlElementNode {\n const children: HtmlNode[] = [];\n\n if (node.label !== undefined) {\n children.push(directiveLabel(node, context));\n }\n\n children.push(...lowerChildren(node.children, context));\n\n return element(\n \"div\",\n directiveHtmlAttributes(node.name, \"container\", node.attributes),\n wrap(children, true),\n );\n}\n\nfunction directiveLabel(\n node: LeafDirectiveNode | ContainerDirectiveNode,\n context: HtmlLoweringContext,\n): HtmlElementNode {\n return element(\n \"span\",\n { \"data-directive-label\": \"\" },\n lowerChildren(node.label?.children ?? [], context),\n );\n}\n\nfunction directiveHtmlAttributes(\n name: string,\n kind: \"container\" | \"leaf\" | \"text\",\n entries: readonly DirectiveAttribute[],\n): HtmlAttributes {\n const attributes = { \"data-directive\": name, \"data-directive-kind\": kind };\n\n return entries.length === 0\n ? attributes\n : {\n ...attributes,\n \"data-directive-attributes\": JSON.stringify(\n entries.map((entry) => [entry.name, entry.value]),\n ),\n };\n}\n\nfunction unresolvedReference(\n reference: HtmlUnresolvedReferenceNode[\"reference\"],\n node: LinkReferenceNode | ImageReferenceNode | FootnoteReferenceNode,\n children: readonly HtmlNode[],\n context: HtmlLoweringContext,\n): HtmlUnresolvedReferenceNode {\n return {\n kind: \"unresolvedReference\",\n reference,\n identifier: node.identifier,\n source: authored(node, context),\n children,\n };\n}\n\nfunction lowerFootnoteReference(\n node: FootnoteReferenceNode,\n occurrence: FootnoteOccurrence,\n options: HtmlRenderOptions,\n): HtmlNode {\n const prefix = options.clobberPrefix ?? \"user-content-\";\n const identifier = normalizeUri(node.identifier.toLowerCase());\n const suffix = occurrence.occurrence > 1 ? `-${occurrence.occurrence}` : \"\";\n\n return {\n kind: \"footnoteReference\",\n identifier: node.identifier,\n occurrence: occurrence.occurrence,\n ordinal: occurrence.ordinal,\n children: [\n element(\n \"a\",\n {\n href: `#${prefix}fn-${identifier}`,\n id: `${prefix}fnref-${identifier}${suffix}`,\n \"data-footnote-ref\": \"\",\n \"aria-describedby\": \"footnote-label\",\n },\n [text(String(occurrence.ordinal))],\n ),\n ],\n };\n}\n\n/** The generated section for the numbered footnotes, or `undefined` when none is referenced. */\nexport function lowerFootnoteSection(\n numbering: FootnoteNumbering,\n scope: LoweringScope,\n): HtmlFootnoteSectionNode | undefined {\n const order = numbering.order;\n\n if (order.length === 0) {\n return undefined;\n }\n\n const context: HtmlLoweringContext = { scope, listLoose: false, volatile: { count: 0 } };\n const prefix = scope.options.clobberPrefix ?? \"user-content-\";\n const items: HtmlElementNode[] = [];\n\n for (let index = 0; index < order.length; index++) {\n const identifier = order[index];\n const definition = scope.footnote(identifier);\n\n if (definition === undefined) {\n continue;\n }\n\n const safeIdentifier = normalizeUri(identifier.toLowerCase());\n const blocks = lowerChildren(definition.children, context);\n\n const backreferences = footnoteBackreferences(\n safeIdentifier,\n index,\n numbering.count(identifier),\n prefix,\n scope.options,\n );\n\n const tail = blocks.at(-1);\n\n if (tail?.kind === \"element\" && tail.tagName === \"p\") {\n blocks[blocks.length - 1] = {\n ...tail,\n children: [\n ...tail.children,\n ...(tail.children.length === 0 ? [] : [text(\" \")]),\n ...backreferences,\n ],\n };\n } else {\n if (blocks.length > 0) {\n blocks.push(text(\"\\n\"));\n }\n\n blocks.push(...backreferences);\n }\n\n items.push(element(\"li\", { id: `${prefix}fn-${safeIdentifier}` }, wrap(blocks, true)));\n }\n\n const heading = element(\n scope.options.footnoteLabelTagName ?? \"h2\",\n { id: \"footnote-label\", class: [\"sr-only\"] },\n [text(scope.options.footnoteLabel ?? \"Footnotes\")],\n );\n\n return {\n kind: \"footnoteSection\",\n identifiers: [...order],\n children: wrap([heading, element(\"ol\", {}, wrap(items, true))], true),\n };\n}\n\nfunction footnoteBackreferences(\n identifier: string,\n referenceIndex: number,\n count: number,\n prefix: string,\n options: HtmlRenderOptions,\n): HtmlNode[] {\n const values: HtmlNode[] = [];\n\n for (let reuse = 1; reuse <= count; reuse++) {\n if (values.length > 0) {\n values.push(text(\" \"));\n }\n\n const configured = options.footnoteBackLabel;\n\n const label = isFunction(configured)\n ? configured(referenceIndex, reuse)\n : (configured ?? defaultFootnoteBackLabel(referenceIndex, reuse));\n\n values.push(\n element(\n \"a\",\n {\n href: `#${prefix}fnref-${identifier}${reuse > 1 ? `-${reuse}` : \"\"}`,\n \"data-footnote-backref\": \"\",\n \"aria-label\": label,\n class: [\"data-footnote-backref\"],\n },\n [text(\"↩\"), ...(reuse > 1 ? [element(\"sup\", {}, [text(String(reuse))])] : [])],\n ),\n );\n }\n\n return values;\n}\n\nfunction defaultFootnoteBackLabel(referenceIndex: number, reuse: number): string {\n return `Back to reference ${referenceIndex + 1}${reuse > 1 ? `-${reuse}` : \"\"}`;\n}\n\nfunction lowerTable(node: TableNode, context: HtmlLoweringContext): HtmlElementNode {\n const head = node.children[0];\n const children: HtmlNode[] = [];\n\n if (head !== undefined) {\n children.push(element(\"thead\", {}, [lowerTableRow(head, node.alignments, true, context)]));\n }\n\n if (node.children.length > 1) {\n children.push(\n element(\n \"tbody\",\n {},\n node.children.slice(1).map((row) => lowerTableRow(row, node.alignments, false, context)),\n ),\n );\n }\n\n return element(\"table\", {}, children);\n}\n\nfunction lowerTableRow(\n node: TableRowNode,\n alignments: readonly TableAlignment[] | undefined,\n heading: boolean,\n context: HtmlLoweringContext,\n): HtmlElementNode {\n const length = alignments?.length ?? node.children.length;\n const cells: HtmlElementNode[] = [];\n\n for (let index = 0; index < length; index++) {\n const cell = node.children.at(index);\n const alignment = alignments?.[index];\n cells.push(\n element(\n heading ? \"th\" : \"td\",\n alignment === undefined || alignment === \"none\" ? {} : { align: alignment },\n cell === undefined ? [] : lowerChildren(cell.children, context),\n ),\n );\n }\n\n return element(\"tr\", {}, cells);\n}\n\nfunction lowerLink(\n url: string,\n title: string | undefined,\n children: readonly MdxNode[],\n context: HtmlLoweringContext,\n): HtmlElementNode {\n const href = resolveUrl(url, \"link\", context.scope.options);\n\n const attributes: HtmlAttributes =\n href === undefined ? {} : title === undefined ? { href } : { href, title };\n\n return element(\"a\", attributes, lowerChildren(children, context));\n}\n\nfunction lowerImage(\n source: string,\n alt: string,\n title: string | undefined,\n context: HtmlLoweringContext,\n): HtmlNode {\n const src = resolveUrl(source, \"image\", context.scope.options);\n\n if (src === undefined) {\n return text(alt);\n }\n\n return element(\"img\", title === undefined ? { src, alt } : { src, alt, title });\n}\n\n/**\n * A list wraps its items in line endings. A growing list reuses the wrapped\n * children of its unchanged leading items, so an append lowers only new items.\n * Stream previews build long children from fixed fragments, so extending them\n * copies only the fragment list; strict output stays flat.\n */\nfunction lowerList(node: ListNode, context: HtmlLoweringContext): HtmlElementNode {\n const items = node.children;\n const prefix = listPrefix(items, context.scope.cache);\n const rest = items.slice((prefix?.index ?? -1) + 1);\n const spread = (prefix?.spread ?? false) || rest.some((item) => item.spread);\n const loose = node.spread || spread;\n const tasks = (prefix?.tasks ?? false) || rest.some((item) => item.checked !== undefined);\n const reused = prefix !== undefined && prefix.loose === loose ? prefix : undefined;\n const itemContext: HtmlLoweringContext = { ...context, listLoose: loose };\n const children = new ChildSequence(context.scope.provisional === true, reused?.children);\n\n if (reused === undefined) {\n children.push(newline);\n }\n\n let stable = true;\n let spreadSoFar = reused?.spread ?? false;\n let tasksSoFar = reused?.tasks ?? false;\n\n for (let index = (reused?.index ?? -1) + 1; index < items.length; index++) {\n spreadSoFar ||= items[index].spread;\n tasksSoFar ||= items[index].checked !== undefined;\n const volatile = context.volatile.count;\n const lowered = lowerHtmlNode(items[index], itemContext);\n\n for (const item of lowered === undefined\n ? []\n : isHtmlNodeArray(lowered)\n ? lowered\n : [lowered]) {\n if (children.size > 1) {\n children.push(newline);\n }\n\n children.push(item);\n }\n\n stable &&= context.volatile.count === volatile;\n\n // The last items can still close differently, so prefixes ending a few items back are kept.\n if (stable && index >= items.length - prefixWindow) {\n context.scope.cache?.lists.set(items[index], {\n index,\n loose,\n spread: spreadSoFar,\n tasks: tasksSoFar,\n children: children.prefix(),\n });\n }\n }\n\n const attributes: Record<string, number | readonly string[]> = {};\n\n if (node.ordered && node.start !== 1) {\n attributes.start = node.start;\n }\n\n if (tasks) {\n attributes.class = [\"contains-task-list\"];\n }\n\n if (children.size > 1) {\n children.push(newline);\n }\n\n return element(node.ordered ? \"ol\" : \"ul\", attributes, children.toArray());\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/** Children of a long sequence in fragments of this many nodes. */\nconst fragmentSize = 64;\n\n/** A prefix of a child sequence: full fragments, then the nodes after them. */\ninterface SequencePrefix {\n readonly fragments: readonly HtmlRootNode[];\n readonly rest: readonly HtmlNode[];\n readonly size: number;\n}\n\n/**\n * Children that grow at the end. With fragments, full groups of nodes become\n * frozen fragments that later prefixes share, so copying a prefix costs only\n * the fragment list and the partial group.\n */\nclass ChildSequence {\n readonly #fragmented: boolean;\n readonly #fragments: HtmlRootNode[];\n #rest: HtmlNode[];\n #size: number;\n\n public constructor(fragmented: boolean, prefix?: SequencePrefix) {\n this.#fragmented = fragmented;\n this.#fragments = prefix === undefined ? [] : [...prefix.fragments];\n this.#rest = prefix === undefined ? [] : [...prefix.rest];\n this.#size = prefix?.size ?? 0;\n }\n\n public get size(): number {\n return this.#size;\n }\n\n public push(node: HtmlNode): void {\n this.#rest.push(node);\n this.#size++;\n\n if (this.#fragmented && this.#rest.length === fragmentSize) {\n this.#fragments.push(Object.freeze({ kind: \"root\", children: this.#rest }));\n this.#rest = [];\n }\n }\n\n public prefix(): SequencePrefix {\n return { fragments: [...this.#fragments], rest: [...this.#rest], size: this.#size };\n }\n\n /** A short sequence stays flat, so fragments appear only where they save copying. */\n public toArray(): HtmlNode[] {\n if (this.#fragments.length < 2) {\n return [...this.#fragments.flatMap((fragment) => fragment.children), ...this.#rest];\n }\n\n return [...this.#fragments, ...this.#rest];\n }\n}\n\n/** The longest cached prefix of `items`, found from the end. */\nfunction listPrefix(\n items: readonly ListItemNode[],\n cache: HtmlLoweringCache | undefined,\n): ListPrefix | undefined {\n for (let index = items.length - 1; index >= Math.max(0, items.length - prefixWindow); index--) {\n const item = items[index];\n const prefix = item === undefined ? undefined : cache?.lists.get(item);\n\n if (prefix?.index === index) {\n return prefix;\n }\n }\n\n return undefined;\n}\n\nfunction lowerListItem(node: ListItemNode, context: HtmlLoweringContext): HtmlElementNode {\n const blocks = [...lowerChildren(node.children, context)];\n\n if (node.checked !== undefined) {\n const checkbox = element(\n \"input\",\n node.checked\n ? { type: \"checkbox\", disabled: true, checked: true }\n : { type: \"checkbox\", disabled: true },\n );\n\n const first = blocks[0];\n\n if (first?.kind === \"element\" && first.tagName === \"p\") {\n blocks[0] = {\n ...first,\n children: [\n checkbox,\n ...(first.children.length === 0 ? [] : [text(\" \")]),\n ...first.children,\n ],\n };\n } else {\n blocks.unshift(element(\"p\", {}, [checkbox]));\n }\n }\n\n const children: HtmlNode[] = [];\n\n for (let index = 0; index < blocks.length; index++) {\n const child = blocks[index];\n const paragraph = child.kind === \"element\" && child.tagName === \"p\";\n\n if (context.listLoose || index !== 0 || !paragraph) {\n children.push(text(\"\\n\"));\n }\n\n if (paragraph && !context.listLoose) {\n children.push(...child.children);\n } else {\n children.push(child);\n }\n }\n\n const tail = blocks.at(-1);\n\n if (\n tail !== undefined &&\n (context.listLoose || tail.kind !== \"element\" || tail.tagName !== \"p\")\n ) {\n children.push(text(\"\\n\"));\n }\n\n return element(\"li\", node.checked === undefined ? {} : { class: [\"task-list-item\"] }, children);\n}\n\nfunction revertReference(\n node: LinkReferenceNode,\n context: HtmlLoweringContext,\n): readonly HtmlNode[] {\n const children = lowerChildren(node.children, context);\n\n const suffix =\n node.referenceKind === \"shortcut\"\n ? \"]\"\n : node.referenceKind === \"collapsed\"\n ? \"][]\"\n : `][${node.identifier}]`;\n\n if (children.length === 0) {\n return [text(`[${suffix}`)];\n }\n\n const first = children[0];\n\n const result: HtmlNode[] =\n first.kind === \"text\"\n ? [text(`[${first.value}`), ...children.slice(1)]\n : [text(\"[\"), ...children];\n\n const last = result[result.length - 1];\n\n if (last.kind === \"text\") {\n result[result.length - 1] = text(last.value + suffix);\n } else {\n result.push(text(suffix));\n }\n\n return result;\n}\n\nfunction lowerChildren(\n children: readonly MdxNode[],\n context: HtmlLoweringContext,\n previous?: MdxNode,\n): HtmlNode[] {\n const values: HtmlNode[] = [];\n\n for (let index = 0; index < children.length; index++) {\n const child = children[index];\n const lowered = lowerHtmlNode(child, context);\n\n if (lowered === undefined) {\n continue;\n }\n\n const additions = isHtmlNodeArray(lowered) ? [...lowered] : [lowered];\n const before = index === 0 ? previous : children[index - 1];\n\n if (before?.kind === \"hardBreak\" && additions.length > 0) {\n additions[0] = trimSpaceStart(additions[0]);\n }\n\n values.push(...additions);\n }\n\n return values;\n}\n\nfunction htmlElement(\n tagName: string,\n children: readonly MdxNode[],\n context: HtmlLoweringContext,\n): HtmlElementNode {\n return element(tagName, {}, lowerChildren(children, context));\n}\n\nfunction element(\n tagName: string,\n attributes: HtmlAttributes = {},\n children: readonly HtmlNode[] = [],\n): HtmlElementNode {\n return { kind: \"element\", tagName, attributes, children };\n}\n\nfunction text(value: string): HtmlTextNode {\n return { kind: \"text\", value };\n}\n\nfunction trimSpaceStart(node: HtmlNode): HtmlNode {\n if (node.kind === \"text\") {\n return { ...node, value: node.value.replace(/^[\\t ]+/u, \"\") };\n }\n\n if (node.kind === \"element\") {\n const first = node.children[0];\n\n if (first?.kind === \"text\") {\n return {\n ...node,\n children: [\n { ...first, value: first.value.replace(/^[\\t ]+/u, \"\") },\n ...node.children.slice(1),\n ],\n };\n }\n }\n\n return node;\n}\n\n/** Line endings between blocks. Trees are immutable, so every separator shares one node. */\nconst newline: HtmlTextNode = Object.freeze({ kind: \"text\", value: \"\\n\" });\n\nfunction wrap(nodes: readonly HtmlNode[], loose: boolean): HtmlNode[] {\n const result: HtmlNode[] = [];\n\n if (loose) {\n result.push(newline);\n }\n\n nodes.forEach((node, index) => {\n if (index > 0) {\n result.push(newline);\n }\n\n result.push(node);\n });\n\n if (loose && nodes.length > 0) {\n result.push(newline);\n }\n\n return result;\n}\n\nfunction resolveUrl(\n url: string,\n kind: \"image\" | \"link\",\n options: HtmlRenderOptions,\n): string | undefined {\n const sanitized = sanitizeUrl(url, options, kind);\n\n return options.urlTransform === undefined\n ? sanitized\n : options.urlTransform(url, kind, sanitized);\n}\n\nexport function sanitizeUrl(\n value: string,\n options: HtmlRenderOptions,\n use: \"image\" | \"link\",\n): string | undefined {\n const decoded = decodeUrlForSchemeCheck(value);\n const colon = decoded.indexOf(\":\");\n const slash = decoded.indexOf(\"/\");\n const query = decoded.indexOf(\"?\");\n const hash = decoded.indexOf(\"#\");\n\n const hasScheme =\n colon >= 0 &&\n (slash < 0 || colon < slash) &&\n (query < 0 || colon < query) &&\n (hash < 0 || colon < hash);\n\n if (hasScheme && options.allowUnsafeUrls !== true) {\n const scheme = decoded.slice(0, colon).toLowerCase();\n\n if (use === \"image\" ? !imageSchemes.has(scheme) : !linkSchemes.has(scheme)) {\n return undefined;\n }\n }\n\n return normalizeUri(value);\n}\n\nfunction decodeUrlForSchemeCheck(value: string): string {\n const result: string[] = [];\n\n for (let index = 0; index < value.length; index++) {\n const character = value[index];\n\n const hexadecimal = value.slice(\n index + \"%\".length,\n index + \"%\".length + percentEncodedByteLength,\n );\n\n if (character === \"%\" && percentEncodedByte.test(hexadecimal)) {\n const decoded = String.fromCodePoint(Number.parseInt(hexadecimal, hexadecimalRadix));\n\n if (!isUrlControlCharacter(decoded)) {\n result.push(decoded);\n }\n\n index += hexadecimal.length;\n continue;\n }\n\n if (!isUrlControlCharacter(character)) {\n result.push(character);\n }\n }\n\n return result.join(\"\");\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { HtmlFormatOptions } from "./html-format.mjs";
|
|
2
|
+
import { MdxStream } from "./stream.mjs";
|
|
3
|
+
//#region src/html-stream.d.ts
|
|
4
|
+
/** Serializes one stream, reusing HTML for its immutable nodes across appends and edits. */
|
|
5
|
+
export declare class HtmlStreamRenderer {
|
|
6
|
+
#private;
|
|
7
|
+
/** Formatting options are captured at construction. */
|
|
8
|
+
constructor(stream: MdxStream, options?: HtmlFormatOptions);
|
|
9
|
+
/** The current preview, or the strict document after successful completion. */
|
|
10
|
+
render(): string;
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
//# sourceMappingURL=html-stream.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html-stream.d.mts","names":[],"sources":["../src/html-stream.ts"],"mappings":";;;;qBAQa;;;EAMX,YAAmB,QAAQ,WAAW,UAAS;;EAMxC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { lowerHtml } from "./html-lower.mjs";
|
|
2
|
+
import { CachedHtmlFormatter } from "./html-format.mjs";
|
|
3
|
+
import { previewDocument } from "./stream-events.mjs";
|
|
4
|
+
//#region src/html-stream.ts
|
|
5
|
+
/** Serializes one stream, reusing HTML for its immutable nodes across appends and edits. */
|
|
6
|
+
var HtmlStreamRenderer = class {
|
|
7
|
+
#stream;
|
|
8
|
+
#formatter;
|
|
9
|
+
#previous;
|
|
10
|
+
/** Formatting options are captured at construction. */
|
|
11
|
+
constructor(stream, options = {}) {
|
|
12
|
+
this.#stream = stream;
|
|
13
|
+
this.#formatter = new CachedHtmlFormatter({ ...options });
|
|
14
|
+
}
|
|
15
|
+
/** The current preview, or the strict document after successful completion. */
|
|
16
|
+
render() {
|
|
17
|
+
const snapshot = this.#stream.snapshot();
|
|
18
|
+
const previous = this.#previous;
|
|
19
|
+
if (previous !== void 0 && previous.snapshot === snapshot) return previous.html;
|
|
20
|
+
const tree = snapshot.kind === "preview" ? previewDocument(snapshot) : lowerHtml(snapshot.document, { source: snapshot.file });
|
|
21
|
+
const html = this.#formatter.format(tree);
|
|
22
|
+
this.#previous = {
|
|
23
|
+
snapshot,
|
|
24
|
+
html
|
|
25
|
+
};
|
|
26
|
+
return html;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
//#endregion
|
|
30
|
+
export { HtmlStreamRenderer };
|
|
31
|
+
|
|
32
|
+
//# sourceMappingURL=html-stream.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html-stream.mjs","names":[],"sources":["../src/html-stream.ts"],"sourcesContent":["import type { HtmlFormatOptions } from \"./html-format.ts\";\nimport type { MdxStream } from \"./stream.ts\";\n\nimport { CachedHtmlFormatter } from \"./html-format.ts\";\nimport { lowerHtml } from \"./html-lower.ts\";\nimport { previewDocument } from \"./stream-events.ts\";\n\n/** Serializes one stream, reusing HTML for its immutable nodes across appends and edits. */\nexport class HtmlStreamRenderer {\n readonly #stream: MdxStream;\n readonly #formatter: CachedHtmlFormatter;\n #previous: Readonly<{ snapshot: ReturnType<MdxStream[\"snapshot\"]>; html: string }> | undefined;\n\n /** Formatting options are captured at construction. */\n public constructor(stream: MdxStream, options: HtmlFormatOptions = {}) {\n this.#stream = stream;\n this.#formatter = new CachedHtmlFormatter({ ...options });\n }\n\n /** The current preview, or the strict document after successful completion. */\n public render(): string {\n const snapshot = this.#stream.snapshot();\n const previous = this.#previous;\n\n if (previous !== undefined && previous.snapshot === snapshot) {\n return previous.html;\n }\n\n const tree =\n snapshot.kind === \"preview\"\n ? previewDocument(snapshot)\n : lowerHtml(snapshot.document, { source: snapshot.file });\n\n const html = this.#formatter.format(tree);\n this.#previous = { snapshot, html };\n\n return html;\n }\n}\n"],"mappings":";;;;;AAQA,IAAa,qBAAb,MAAgC;CAC9B;CACA;CACA;;CAGA,YAAmB,QAAmB,UAA6B,CAAC,GAAG;EACrE,KAAK,UAAU;EACf,KAAK,aAAa,IAAI,oBAAoB,EAAE,GAAG,QAAQ,CAAC;CAC1D;;CAGA,SAAwB;EACtB,MAAM,WAAW,KAAK,QAAQ,SAAS;EACvC,MAAM,WAAW,KAAK;EAEtB,IAAI,aAAa,KAAA,KAAa,SAAS,aAAa,UAClD,OAAO,SAAS;EAGlB,MAAM,OACJ,SAAS,SAAS,YACd,gBAAgB,QAAQ,IACxB,UAAU,SAAS,UAAU,EAAE,QAAQ,SAAS,KAAK,CAAC;EAE5D,MAAM,OAAO,KAAK,WAAW,OAAO,IAAI;EACxC,KAAK,YAAY;GAAE;GAAU;EAAK;EAElC,OAAO;CACT;AACF"}
|
package/dist/html.d.mts
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { SourceRange } from "./ranges.mjs";
|
|
2
|
+
import { JsxAttributeLike } from "./model.mjs";
|
|
3
|
+
//#region src/html.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Lowered HTML is plain, readonly data. Semantic kinds such as `codeBlock` and
|
|
6
|
+
* `math` keep their inputs so a renderer or plugin can replace them; their
|
|
7
|
+
* default presentation comes from `htmlFallback`.
|
|
8
|
+
*/
|
|
9
|
+
interface HtmlNodeBase<TKind extends string> {
|
|
10
|
+
readonly kind: TKind;
|
|
11
|
+
readonly origin?: SourceRange;
|
|
12
|
+
}
|
|
13
|
+
export type HtmlAttributeList = readonly (number | string)[];
|
|
14
|
+
export type HtmlAttributeValue = boolean | number | string | HtmlAttributeList;
|
|
15
|
+
export type HtmlAttributes = Readonly<Record<string, HtmlAttributeValue>>;
|
|
16
|
+
export interface HtmlTextNode extends HtmlNodeBase<"text"> {
|
|
17
|
+
readonly value: string;
|
|
18
|
+
}
|
|
19
|
+
/** Authored raw HTML. `formatHtml` escapes it unless raw HTML is trusted. */
|
|
20
|
+
export interface HtmlRawNode extends HtmlNodeBase<"raw"> {
|
|
21
|
+
readonly value: string;
|
|
22
|
+
}
|
|
23
|
+
export interface HtmlCommentNode extends HtmlNodeBase<"comment"> {
|
|
24
|
+
readonly value: string;
|
|
25
|
+
}
|
|
26
|
+
export type HtmlDoctypeNode = HtmlNodeBase<"doctype">;
|
|
27
|
+
export interface HtmlElementNode extends HtmlNodeBase<"element"> {
|
|
28
|
+
readonly tagName: string;
|
|
29
|
+
readonly attributes: HtmlAttributes;
|
|
30
|
+
readonly children: readonly HtmlNode[];
|
|
31
|
+
}
|
|
32
|
+
export interface HtmlRootNode extends HtmlNodeBase<"root"> {
|
|
33
|
+
readonly children: readonly HtmlNode[];
|
|
34
|
+
}
|
|
35
|
+
/** A JavaScript expression that only a compiler evaluates. `fallback` is the authored source. */
|
|
36
|
+
export interface HtmlExpressionNode extends HtmlNodeBase<"expression"> {
|
|
37
|
+
readonly code: string;
|
|
38
|
+
readonly fallback: string;
|
|
39
|
+
}
|
|
40
|
+
/** A JSX element that a renderer may resolve. `fallback` is the authored source. */
|
|
41
|
+
export interface HtmlJsxNode extends HtmlNodeBase<"jsx"> {
|
|
42
|
+
/** `pending` while a stream has not closed the element; attributes are then the committed ones. */
|
|
43
|
+
readonly state: "complete" | "pending";
|
|
44
|
+
/** `flow` for block JSX, `text` for JSX inside a paragraph. */
|
|
45
|
+
readonly element: "flow" | "text";
|
|
46
|
+
/** Absent for fragments. */
|
|
47
|
+
readonly name?: string;
|
|
48
|
+
readonly attributes: readonly JsxAttributeLike[];
|
|
49
|
+
readonly fallback: string;
|
|
50
|
+
readonly children: readonly HtmlNode[];
|
|
51
|
+
}
|
|
52
|
+
export interface HtmlCodeBlockNode extends HtmlNodeBase<"codeBlock"> {
|
|
53
|
+
readonly code: string;
|
|
54
|
+
readonly language: string;
|
|
55
|
+
readonly meta?: string;
|
|
56
|
+
}
|
|
57
|
+
export type MathRenderStyle = "display" | "inline";
|
|
58
|
+
export interface HtmlMathNode extends HtmlNodeBase<"math"> {
|
|
59
|
+
readonly source: string;
|
|
60
|
+
readonly style: MathRenderStyle;
|
|
61
|
+
readonly meta?: string;
|
|
62
|
+
}
|
|
63
|
+
/** A footnote reference with its document-wide numbering. Children are the `sup` content. */
|
|
64
|
+
export interface HtmlFootnoteReferenceNode extends HtmlNodeBase<"footnoteReference"> {
|
|
65
|
+
readonly identifier: string;
|
|
66
|
+
readonly occurrence: number;
|
|
67
|
+
readonly ordinal: number;
|
|
68
|
+
readonly children: readonly HtmlNode[];
|
|
69
|
+
}
|
|
70
|
+
/** The generated footnote section. Children are the `section` content. */
|
|
71
|
+
export interface HtmlFootnoteSectionNode extends HtmlNodeBase<"footnoteSection"> {
|
|
72
|
+
readonly identifiers: readonly string[];
|
|
73
|
+
readonly children: readonly HtmlNode[];
|
|
74
|
+
}
|
|
75
|
+
/** Syntax that a stream opened but has not closed yet. */
|
|
76
|
+
export type HtmlPendingConstruct = "strong" | "emphasis" | "delete" | "link" | "image" | "code" | "inlineMath" | "displayMath" | "fence" | "expression" | "esm" | "jsx";
|
|
77
|
+
/**
|
|
78
|
+
* Open syntax at the end of a stream. `children` is the content so far as inert
|
|
79
|
+
* HTML, and `pendingFallback` gives its provisional presentation. Only stream
|
|
80
|
+
* previews contain pending nodes.
|
|
81
|
+
*/
|
|
82
|
+
export interface HtmlPendingNode extends HtmlNodeBase<"pending"> {
|
|
83
|
+
readonly construct: HtmlPendingConstruct;
|
|
84
|
+
/** Authored source of the construct so far. */
|
|
85
|
+
readonly source: string;
|
|
86
|
+
readonly children: readonly HtmlNode[];
|
|
87
|
+
/** The fence language, when a fence has an info string. */
|
|
88
|
+
readonly language?: string;
|
|
89
|
+
readonly meta?: string;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* A reference whose definition has not arrived. It renders its authored source
|
|
93
|
+
* until the definition resolves it. Only stream previews contain these nodes.
|
|
94
|
+
*/
|
|
95
|
+
export interface HtmlUnresolvedReferenceNode extends HtmlNodeBase<"unresolvedReference"> {
|
|
96
|
+
readonly reference: "footnote" | "image" | "link";
|
|
97
|
+
readonly identifier: string;
|
|
98
|
+
readonly source: string;
|
|
99
|
+
/** The label as inert HTML. */
|
|
100
|
+
readonly children: readonly HtmlNode[];
|
|
101
|
+
}
|
|
102
|
+
export type HtmlNode = HtmlCodeBlockNode | HtmlCommentNode | HtmlDoctypeNode | HtmlElementNode | HtmlExpressionNode | HtmlFootnoteReferenceNode | HtmlFootnoteSectionNode | HtmlJsxNode | HtmlMathNode | HtmlPendingNode | HtmlRawNode | HtmlRootNode | HtmlTextNode | HtmlUnresolvedReferenceNode;
|
|
103
|
+
export type HtmlKind = HtmlNode["kind"];
|
|
104
|
+
export type HtmlNodeForKind<TKind extends HtmlKind> = Extract<HtmlNode, {
|
|
105
|
+
readonly kind: TKind;
|
|
106
|
+
}>;
|
|
107
|
+
export type HtmlSemanticNode = HtmlCodeBlockNode | HtmlFootnoteReferenceNode | HtmlFootnoteSectionNode | HtmlMathNode;
|
|
108
|
+
export declare function htmlChildren(node: HtmlNode): readonly HtmlNode[];
|
|
109
|
+
/** The default element presentation of a semantic node. */
|
|
110
|
+
export declare function htmlFallback(node: HtmlSemanticNode): HtmlElementNode;
|
|
111
|
+
export declare function isHtmlAttributeList(value: HtmlAttributeValue): value is HtmlAttributeList;
|
|
112
|
+
/** Class names from a `class` attribute in either string or list form. */
|
|
113
|
+
export declare function htmlClassNames(node: HtmlElementNode): readonly string[];
|
|
114
|
+
/** The provisional presentation of open or unresolved stream syntax. */
|
|
115
|
+
export declare function pendingFallback(node: HtmlPendingNode | HtmlUnresolvedReferenceNode): readonly HtmlNode[];
|
|
116
|
+
/** Text content of a node, as a reader sees it. */
|
|
117
|
+
export declare function htmlText(node: HtmlNode): string;
|
|
118
|
+
//#endregion
|
|
119
|
+
export {};
|
|
120
|
+
//# sourceMappingURL=html.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html.d.mts","names":[],"sources":["../src/html.ts"],"mappings":";;;;;;;;UAUU,aAAa;WACZ,MAAM;WACN,SAAS;;YAGR;YAEA,iDAAiD;YAEjD,iBAAiB,SAAS,eAAe;iBAEpC,qBAAqB;WAC3B;;;iBAIM,oBAAoB;WAC1B;;iBAGM,wBAAwB;WAC9B;;YAGC,kBAAkB;iBAEb,wBAAwB;WAC9B;WACA,YAAY;WACZ,mBAAmB;;iBAGb,qBAAqB;WAC3B,mBAAmB;;;iBAIb,2BAA2B;WACjC;WACA;;;iBAIM,oBAAoB;;WAE1B;;WAEA;;WAEA;WACA,qBAAqB;WACrB;WACA,mBAAmB;;iBAGb,0BAA0B;WAChC;WACA;WACA;;YAGC;iBAEK,qBAAqB;WAC3B;WACA,OAAO;WACP;;;iBAIM,kCAAkC;WACxC;WACA;WACA;WACA,mBAAmB;;;iBAIb,gCAAgC;WACtC;WACA,mBAAmB;;;YAIlB;;;;;;iBAmBK,wBAAwB;WAC9B,WAAW;;WAEX;WACA,mBAAmB;;WAEnB;WACA;;;;;;iBAOM,oCAAoC;WAC1C;WACA;WACA;;WAEA,mBAAmB;;YAGlB,WACR,oBACA,kBACA,kBACA,kBACA,qBACA,4BACA,0BACA,cACA,eACA,kBACA,cACA,eACA,eACA;YAEQ,WAAW;YAEX,gBAAgB,cAAc,YAAY,QAAQ;WAAqB,MAAM;;YAE7E,mBACR,oBACA,4BACA,0BACA;wBAEY,aAAa,MAAM,oBAAoB;;wBAKvC,aAAa,MAAM,mBAAmB;wBAyBtC,oBAAoB,OAAO,qBAAqB,SAAS;;wBAKzD,eAAe,MAAM;;wBAWrB,gBACd,MAAM,kBAAkB,uCACd;;wBAwDI,SAAS,MAAM"}
|
package/dist/html.mjs
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { isNumber, isString } from "@temelj/value";
|
|
2
|
+
//#region src/html.ts
|
|
3
|
+
function htmlChildren(node) {
|
|
4
|
+
return "children" in node ? node.children : [];
|
|
5
|
+
}
|
|
6
|
+
/** The default element presentation of a semantic node. */
|
|
7
|
+
function htmlFallback(node) {
|
|
8
|
+
switch (node.kind) {
|
|
9
|
+
case "codeBlock": return element("pre", {}, [element("code", { class: [`language-${node.language}`] }, [text(node.code.length === 0 ? "" : `${node.code}\n`)])]);
|
|
10
|
+
case "math":
|
|
11
|
+
if (node.style === "inline") return element("code", { class: ["language-math", "math-inline"] }, [text(node.source)]);
|
|
12
|
+
return element("pre", node.meta === void 0 ? {} : { "data-math-meta": node.meta }, [element("code", { class: ["language-math", "math-display"] }, [text(node.source.length === 0 ? "" : `${node.source}\n`)])]);
|
|
13
|
+
case "footnoteReference": return element("sup", {}, node.children);
|
|
14
|
+
case "footnoteSection": return element("section", {
|
|
15
|
+
"data-footnotes": "",
|
|
16
|
+
class: ["footnotes"]
|
|
17
|
+
}, node.children);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function isHtmlAttributeList(value) {
|
|
21
|
+
return Array.isArray(value) && value.every((item) => isString(item) || isNumber(item));
|
|
22
|
+
}
|
|
23
|
+
/** Class names from a `class` attribute in either string or list form. */
|
|
24
|
+
function htmlClassNames(node) {
|
|
25
|
+
const value = node.attributes.class;
|
|
26
|
+
if (isString(value)) return value.split(/\s+/u).filter((item) => item.length > 0);
|
|
27
|
+
return Array.isArray(value) ? value.filter((item) => isString(item)) : [];
|
|
28
|
+
}
|
|
29
|
+
/** The provisional presentation of open or unresolved stream syntax. */
|
|
30
|
+
function pendingFallback(node) {
|
|
31
|
+
if (node.kind === "unresolvedReference") return [text(node.source)];
|
|
32
|
+
switch (node.construct) {
|
|
33
|
+
case "strong": return [element("strong", {}, node.children)];
|
|
34
|
+
case "emphasis": return [element("em", {}, node.children)];
|
|
35
|
+
case "delete": return [element("del", {}, node.children)];
|
|
36
|
+
case "link": return [element("span", {}, node.children)];
|
|
37
|
+
case "code": return [element("code", {}, node.children)];
|
|
38
|
+
case "inlineMath": return [text(node.source)];
|
|
39
|
+
case "displayMath": return [element("pre", {}, [element("code", { class: ["language-math", "math-display"] }, node.children)])];
|
|
40
|
+
case "fence": return [element("pre", {}, [element("code", node.language === void 0 ? {} : { class: [`language-${node.language}`] }, node.children)])];
|
|
41
|
+
case "image":
|
|
42
|
+
case "expression":
|
|
43
|
+
case "esm":
|
|
44
|
+
case "jsx": return node.children;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function element(tagName, attributes, children) {
|
|
48
|
+
return {
|
|
49
|
+
kind: "element",
|
|
50
|
+
tagName,
|
|
51
|
+
attributes,
|
|
52
|
+
children
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function text(value) {
|
|
56
|
+
return {
|
|
57
|
+
kind: "text",
|
|
58
|
+
value
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/** Text content of a node, as a reader sees it. */
|
|
62
|
+
function htmlText(node) {
|
|
63
|
+
switch (node.kind) {
|
|
64
|
+
case "text":
|
|
65
|
+
case "raw": return node.value;
|
|
66
|
+
case "jsx":
|
|
67
|
+
case "expression": return node.fallback;
|
|
68
|
+
case "unresolvedReference": return node.source;
|
|
69
|
+
case "codeBlock": return node.code;
|
|
70
|
+
case "math": return node.source;
|
|
71
|
+
default: return htmlChildren(node).map(htmlText).join("");
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//#endregion
|
|
75
|
+
export { htmlChildren, htmlClassNames, htmlFallback, htmlText, isHtmlAttributeList, pendingFallback };
|
|
76
|
+
|
|
77
|
+
//# sourceMappingURL=html.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html.mjs","names":[],"sources":["../src/html.ts"],"sourcesContent":["import { isNumber, isString } from \"@temelj/value\";\n\nimport type { JsxAttributeLike } from \"./model.ts\";\nimport type { SourceRange } from \"./ranges.ts\";\n\n/**\n * Lowered HTML is plain, readonly data. Semantic kinds such as `codeBlock` and\n * `math` keep their inputs so a renderer or plugin can replace them; their\n * default presentation comes from `htmlFallback`.\n */\ninterface HtmlNodeBase<TKind extends string> {\n readonly kind: TKind;\n readonly origin?: SourceRange;\n}\n\nexport type HtmlAttributeList = readonly (number | string)[];\n\nexport type HtmlAttributeValue = boolean | number | string | HtmlAttributeList;\n\nexport type HtmlAttributes = Readonly<Record<string, HtmlAttributeValue>>;\n\nexport interface HtmlTextNode extends HtmlNodeBase<\"text\"> {\n readonly value: string;\n}\n\n/** Authored raw HTML. `formatHtml` escapes it unless raw HTML is trusted. */\nexport interface HtmlRawNode extends HtmlNodeBase<\"raw\"> {\n readonly value: string;\n}\n\nexport interface HtmlCommentNode extends HtmlNodeBase<\"comment\"> {\n readonly value: string;\n}\n\nexport type HtmlDoctypeNode = HtmlNodeBase<\"doctype\">;\n\nexport interface HtmlElementNode extends HtmlNodeBase<\"element\"> {\n readonly tagName: string;\n readonly attributes: HtmlAttributes;\n readonly children: readonly HtmlNode[];\n}\n\nexport interface HtmlRootNode extends HtmlNodeBase<\"root\"> {\n readonly children: readonly HtmlNode[];\n}\n\n/** A JavaScript expression that only a compiler evaluates. `fallback` is the authored source. */\nexport interface HtmlExpressionNode extends HtmlNodeBase<\"expression\"> {\n readonly code: string;\n readonly fallback: string;\n}\n\n/** A JSX element that a renderer may resolve. `fallback` is the authored source. */\nexport interface HtmlJsxNode extends HtmlNodeBase<\"jsx\"> {\n /** `pending` while a stream has not closed the element; attributes are then the committed ones. */\n readonly state: \"complete\" | \"pending\";\n /** `flow` for block JSX, `text` for JSX inside a paragraph. */\n readonly element: \"flow\" | \"text\";\n /** Absent for fragments. */\n readonly name?: string;\n readonly attributes: readonly JsxAttributeLike[];\n readonly fallback: string;\n readonly children: readonly HtmlNode[];\n}\n\nexport interface HtmlCodeBlockNode extends HtmlNodeBase<\"codeBlock\"> {\n readonly code: string;\n readonly language: string;\n readonly meta?: string;\n}\n\nexport type MathRenderStyle = \"display\" | \"inline\";\n\nexport interface HtmlMathNode extends HtmlNodeBase<\"math\"> {\n readonly source: string;\n readonly style: MathRenderStyle;\n readonly meta?: string;\n}\n\n/** A footnote reference with its document-wide numbering. Children are the `sup` content. */\nexport interface HtmlFootnoteReferenceNode extends HtmlNodeBase<\"footnoteReference\"> {\n readonly identifier: string;\n readonly occurrence: number;\n readonly ordinal: number;\n readonly children: readonly HtmlNode[];\n}\n\n/** The generated footnote section. Children are the `section` content. */\nexport interface HtmlFootnoteSectionNode extends HtmlNodeBase<\"footnoteSection\"> {\n readonly identifiers: readonly string[];\n readonly children: readonly HtmlNode[];\n}\n\n/** Syntax that a stream opened but has not closed yet. */\nexport type HtmlPendingConstruct =\n | \"strong\"\n | \"emphasis\"\n | \"delete\"\n | \"link\"\n | \"image\"\n | \"code\"\n | \"inlineMath\"\n | \"displayMath\"\n | \"fence\"\n | \"expression\"\n | \"esm\"\n | \"jsx\";\n\n/**\n * Open syntax at the end of a stream. `children` is the content so far as inert\n * HTML, and `pendingFallback` gives its provisional presentation. Only stream\n * previews contain pending nodes.\n */\nexport interface HtmlPendingNode extends HtmlNodeBase<\"pending\"> {\n readonly construct: HtmlPendingConstruct;\n /** Authored source of the construct so far. */\n readonly source: string;\n readonly children: readonly HtmlNode[];\n /** The fence language, when a fence has an info string. */\n readonly language?: string;\n readonly meta?: string;\n}\n\n/**\n * A reference whose definition has not arrived. It renders its authored source\n * until the definition resolves it. Only stream previews contain these nodes.\n */\nexport interface HtmlUnresolvedReferenceNode extends HtmlNodeBase<\"unresolvedReference\"> {\n readonly reference: \"footnote\" | \"image\" | \"link\";\n readonly identifier: string;\n readonly source: string;\n /** The label as inert HTML. */\n readonly children: readonly HtmlNode[];\n}\n\nexport type HtmlNode =\n | HtmlCodeBlockNode\n | HtmlCommentNode\n | HtmlDoctypeNode\n | HtmlElementNode\n | HtmlExpressionNode\n | HtmlFootnoteReferenceNode\n | HtmlFootnoteSectionNode\n | HtmlJsxNode\n | HtmlMathNode\n | HtmlPendingNode\n | HtmlRawNode\n | HtmlRootNode\n | HtmlTextNode\n | HtmlUnresolvedReferenceNode;\n\nexport type HtmlKind = HtmlNode[\"kind\"];\n\nexport type HtmlNodeForKind<TKind extends HtmlKind> = Extract<HtmlNode, { readonly kind: TKind }>;\n\nexport type HtmlSemanticNode =\n | HtmlCodeBlockNode\n | HtmlFootnoteReferenceNode\n | HtmlFootnoteSectionNode\n | HtmlMathNode;\n\nexport function htmlChildren(node: HtmlNode): readonly HtmlNode[] {\n return \"children\" in node ? node.children : [];\n}\n\n/** The default element presentation of a semantic node. */\nexport function htmlFallback(node: HtmlSemanticNode): HtmlElementNode {\n switch (node.kind) {\n case \"codeBlock\":\n return element(\"pre\", {}, [\n element(\"code\", { class: [`language-${node.language}`] }, [\n text(node.code.length === 0 ? \"\" : `${node.code}\\n`),\n ]),\n ]);\n case \"math\":\n if (node.style === \"inline\") {\n return element(\"code\", { class: [\"language-math\", \"math-inline\"] }, [text(node.source)]);\n }\n\n return element(\"pre\", node.meta === undefined ? {} : { \"data-math-meta\": node.meta }, [\n element(\"code\", { class: [\"language-math\", \"math-display\"] }, [\n text(node.source.length === 0 ? \"\" : `${node.source}\\n`),\n ]),\n ]);\n case \"footnoteReference\":\n return element(\"sup\", {}, node.children);\n case \"footnoteSection\":\n return element(\"section\", { \"data-footnotes\": \"\", class: [\"footnotes\"] }, node.children);\n }\n}\n\nexport function isHtmlAttributeList(value: HtmlAttributeValue): value is HtmlAttributeList {\n return Array.isArray(value) && value.every((item) => isString(item) || isNumber(item));\n}\n\n/** Class names from a `class` attribute in either string or list form. */\nexport function htmlClassNames(node: HtmlElementNode): readonly string[] {\n const value = node.attributes.class;\n\n if (isString(value)) {\n return value.split(/\\s+/u).filter((item) => item.length > 0);\n }\n\n return Array.isArray(value) ? value.filter((item) => isString(item)) : [];\n}\n\n/** The provisional presentation of open or unresolved stream syntax. */\nexport function pendingFallback(\n node: HtmlPendingNode | HtmlUnresolvedReferenceNode,\n): readonly HtmlNode[] {\n if (node.kind === \"unresolvedReference\") {\n return [text(node.source)];\n }\n\n switch (node.construct) {\n case \"strong\":\n return [element(\"strong\", {}, node.children)];\n case \"emphasis\":\n return [element(\"em\", {}, node.children)];\n case \"delete\":\n return [element(\"del\", {}, node.children)];\n case \"link\":\n return [element(\"span\", {}, node.children)];\n case \"code\":\n return [element(\"code\", {}, node.children)];\n case \"inlineMath\":\n // A lone dollar sign is often currency, so open inline math stays authored text.\n return [text(node.source)];\n case \"displayMath\":\n return [\n element(\"pre\", {}, [\n element(\"code\", { class: [\"language-math\", \"math-display\"] }, node.children),\n ]),\n ];\n case \"fence\":\n return [\n element(\"pre\", {}, [\n element(\n \"code\",\n node.language === undefined ? {} : { class: [`language-${node.language}`] },\n node.children,\n ),\n ]),\n ];\n case \"image\":\n case \"expression\":\n case \"esm\":\n case \"jsx\":\n return node.children;\n }\n}\n\nfunction element(\n tagName: string,\n attributes: HtmlAttributes,\n children: readonly HtmlNode[],\n): HtmlElementNode {\n return { kind: \"element\", tagName, attributes, children };\n}\n\nfunction text(value: string): HtmlTextNode {\n return { kind: \"text\", value };\n}\n\n/** Text content of a node, as a reader sees it. */\nexport function htmlText(node: HtmlNode): string {\n switch (node.kind) {\n case \"text\":\n case \"raw\":\n return node.value;\n case \"jsx\":\n case \"expression\":\n return node.fallback;\n case \"unresolvedReference\":\n return node.source;\n case \"codeBlock\":\n return node.code;\n case \"math\":\n return node.source;\n default:\n return htmlChildren(node).map(htmlText).join(\"\");\n }\n}\n"],"mappings":";;AAiKA,SAAgB,aAAa,MAAqC;CAChE,OAAO,cAAc,OAAO,KAAK,WAAW,CAAC;AAC/C;;AAGA,SAAgB,aAAa,MAAyC;CACpE,QAAQ,KAAK,MAAb;EACE,KAAK,aACH,OAAO,QAAQ,OAAO,CAAC,GAAG,CACxB,QAAQ,QAAQ,EAAE,OAAO,CAAC,YAAY,KAAK,UAAU,EAAE,GAAG,CACxD,KAAK,KAAK,KAAK,WAAW,IAAI,KAAK,GAAG,KAAK,KAAK,GAAG,CACrD,CAAC,CACH,CAAC;EACH,KAAK;GACH,IAAI,KAAK,UAAU,UACjB,OAAO,QAAQ,QAAQ,EAAE,OAAO,CAAC,iBAAiB,aAAa,EAAE,GAAG,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC;GAGzF,OAAO,QAAQ,OAAO,KAAK,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,kBAAkB,KAAK,KAAK,GAAG,CACpF,QAAQ,QAAQ,EAAE,OAAO,CAAC,iBAAiB,cAAc,EAAE,GAAG,CAC5D,KAAK,KAAK,OAAO,WAAW,IAAI,KAAK,GAAG,KAAK,OAAO,GAAG,CACzD,CAAC,CACH,CAAC;EACH,KAAK,qBACH,OAAO,QAAQ,OAAO,CAAC,GAAG,KAAK,QAAQ;EACzC,KAAK,mBACH,OAAO,QAAQ,WAAW;GAAE,kBAAkB;GAAI,OAAO,CAAC,WAAW;EAAE,GAAG,KAAK,QAAQ;CAC3F;AACF;AAEA,SAAgB,oBAAoB,OAAuD;CACzF,OAAO,MAAM,QAAQ,KAAK,KAAK,MAAM,OAAO,SAAS,SAAS,IAAI,KAAK,SAAS,IAAI,CAAC;AACvF;;AAGA,SAAgB,eAAe,MAA0C;CACvE,MAAM,QAAQ,KAAK,WAAW;CAE9B,IAAI,SAAS,KAAK,GAChB,OAAO,MAAM,MAAM,MAAM,CAAC,CAAC,QAAQ,SAAS,KAAK,SAAS,CAAC;CAG7D,OAAO,MAAM,QAAQ,KAAK,IAAI,MAAM,QAAQ,SAAS,SAAS,IAAI,CAAC,IAAI,CAAC;AAC1E;;AAGA,SAAgB,gBACd,MACqB;CACrB,IAAI,KAAK,SAAS,uBAChB,OAAO,CAAC,KAAK,KAAK,MAAM,CAAC;CAG3B,QAAQ,KAAK,WAAb;EACE,KAAK,UACH,OAAO,CAAC,QAAQ,UAAU,CAAC,GAAG,KAAK,QAAQ,CAAC;EAC9C,KAAK,YACH,OAAO,CAAC,QAAQ,MAAM,CAAC,GAAG,KAAK,QAAQ,CAAC;EAC1C,KAAK,UACH,OAAO,CAAC,QAAQ,OAAO,CAAC,GAAG,KAAK,QAAQ,CAAC;EAC3C,KAAK,QACH,OAAO,CAAC,QAAQ,QAAQ,CAAC,GAAG,KAAK,QAAQ,CAAC;EAC5C,KAAK,QACH,OAAO,CAAC,QAAQ,QAAQ,CAAC,GAAG,KAAK,QAAQ,CAAC;EAC5C,KAAK,cAEH,OAAO,CAAC,KAAK,KAAK,MAAM,CAAC;EAC3B,KAAK,eACH,OAAO,CACL,QAAQ,OAAO,CAAC,GAAG,CACjB,QAAQ,QAAQ,EAAE,OAAO,CAAC,iBAAiB,cAAc,EAAE,GAAG,KAAK,QAAQ,CAC7E,CAAC,CACH;EACF,KAAK,SACH,OAAO,CACL,QAAQ,OAAO,CAAC,GAAG,CACjB,QACE,QACA,KAAK,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,CAAC,YAAY,KAAK,UAAU,EAAE,GAC1E,KAAK,QACP,CACF,CAAC,CACH;EACF,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,OACH,OAAO,KAAK;CAChB;AACF;AAEA,SAAS,QACP,SACA,YACA,UACiB;CACjB,OAAO;EAAE,MAAM;EAAW;EAAS;EAAY;CAAS;AAC1D;AAEA,SAAS,KAAK,OAA6B;CACzC,OAAO;EAAE,MAAM;EAAQ;CAAM;AAC/B;;AAGA,SAAgB,SAAS,MAAwB;CAC/C,QAAQ,KAAK,MAAb;EACE,KAAK;EACL,KAAK,OACH,OAAO,KAAK;EACd,KAAK;EACL,KAAK,cACH,OAAO,KAAK;EACd,KAAK,uBACH,OAAO,KAAK;EACd,KAAK,aACH,OAAO,KAAK;EACd,KAAK,QACH,OAAO,KAAK;EACd,SACE,OAAO,aAAa,IAAI,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,KAAK,EAAE;CACnD;AACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identifier.d.mts","names":[],"sources":["../src/identifier.ts"],"mappings":";wBAAgB,oBAAoB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identifier.mjs","names":[],"sources":["../src/identifier.ts"],"sourcesContent":["export function normalizeIdentifier(value: string): string {\n return value\n .replace(/[\\t\\n\\r ]+/gu, \" \")\n .replace(/^ | $/gu, \"\")\n .toLowerCase()\n .toUpperCase();\n}\n"],"mappings":";AAAA,SAAgB,oBAAoB,OAAuB;CACzD,OAAO,MACJ,QAAQ,gBAAgB,GAAG,CAAC,CAC5B,QAAQ,WAAW,EAAE,CAAC,CACtB,YAAY,CAAC,CACb,YAAY;AACjB"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//#region src/javascript-ast.d.ts
|
|
2
|
+
export interface JavaScriptNode {
|
|
3
|
+
readonly end: number;
|
|
4
|
+
readonly start: number;
|
|
5
|
+
readonly type: string;
|
|
6
|
+
}
|
|
7
|
+
export type JavaScriptField = JavaScriptNode | string | number | boolean | bigint | RegExp | null | undefined;
|
|
8
|
+
export declare function isJavaScriptNode(value: unknown): value is JavaScriptNode;
|
|
9
|
+
export declare function childNode(value: JavaScriptField): JavaScriptNode | undefined;
|
|
10
|
+
export declare function nodeValue(node: JavaScriptNode, key: string): JavaScriptField;
|
|
11
|
+
export declare function nodeArray(node: JavaScriptNode, key: string): JavaScriptNode[];
|
|
12
|
+
export declare function collectPatternNames(node: JavaScriptNode | undefined, names: Set<string>): void;
|
|
13
|
+
export declare function javascriptPropertyName(name: string): string;
|
|
14
|
+
export declare function javascriptChildren(node: JavaScriptNode): JavaScriptNode[];
|
|
15
|
+
//#endregion
|
|
16
|
+
//# sourceMappingURL=javascript-ast.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"javascript-ast.d.mts","names":[],"sources":["../src/javascript-ast.ts"],"mappings":";iBAEiB;WACN;WACA;WACA;;YAGC,kBACR,sDAKA;wBAIY,iBAAiB,iBAAiB,SAAS;wBAY3C,UAAU,OAAO,kBAAkB;wBAInC,UAAU,MAAM,gBAAgB,cAAc;wBAmB9C,UAAU,MAAM,gBAAgB,cAAc;wBAM9C,oBAAoB,MAAM,4BAA4B,OAAO;wBA6B7D,uBAAuB;wBAIvB,mBAAmB,MAAM,iBAAiB"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { isBigInt, isBoolean, isNumber, isObject, isString } from "@temelj/value";
|
|
2
|
+
//#region src/javascript-ast.ts
|
|
3
|
+
function isJavaScriptNode(value) {
|
|
4
|
+
return isObject(value) && "type" in value && isString(value.type) && "start" in value && isNumber(value.start) && "end" in value && isNumber(value.end);
|
|
5
|
+
}
|
|
6
|
+
function childNode(value) {
|
|
7
|
+
return isObject(value) && !(value instanceof RegExp) ? value : void 0;
|
|
8
|
+
}
|
|
9
|
+
function nodeValue(node, key) {
|
|
10
|
+
const value = Object.getOwnPropertyDescriptor(node, key)?.value;
|
|
11
|
+
if (value === null || value === void 0 || isJavaScriptNode(value) || isString(value) || isNumber(value) || isBoolean(value) || isBigInt(value) || value instanceof RegExp) return value;
|
|
12
|
+
}
|
|
13
|
+
function nodeArray(node, key) {
|
|
14
|
+
const value = Object.getOwnPropertyDescriptor(node, key)?.value;
|
|
15
|
+
return Array.isArray(value) ? value.filter(isJavaScriptNode) : [];
|
|
16
|
+
}
|
|
17
|
+
function collectPatternNames(node, names) {
|
|
18
|
+
if (node === void 0) return;
|
|
19
|
+
if (node.type === "Identifier") {
|
|
20
|
+
const name = nodeValue(node, "name");
|
|
21
|
+
if (isString(name)) names.add(name);
|
|
22
|
+
} else if (node.type === "RestElement") collectPatternNames(childNode(nodeValue(node, "argument")), names);
|
|
23
|
+
else if (node.type === "AssignmentPattern") collectPatternNames(childNode(nodeValue(node, "left")), names);
|
|
24
|
+
else if (node.type === "ArrayPattern") for (const element of nodeArray(node, "elements")) collectPatternNames(element, names);
|
|
25
|
+
else if (node.type === "ObjectPattern") for (const property of nodeArray(node, "properties")) collectPatternNames(childNode(nodeValue(property, "value")) ?? childNode(nodeValue(property, "argument")), names);
|
|
26
|
+
}
|
|
27
|
+
function javascriptPropertyName(name) {
|
|
28
|
+
return /^[$A-Z_a-z][$\w]*$/u.test(name) ? name : JSON.stringify(name);
|
|
29
|
+
}
|
|
30
|
+
function javascriptChildren(node) {
|
|
31
|
+
return nestedNodes(Object.values(node));
|
|
32
|
+
}
|
|
33
|
+
function nestedNodes(values) {
|
|
34
|
+
return values.flatMap((value) => Array.isArray(value) ? nestedNodes(value) : isJavaScriptNode(value) ? [value] : []);
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
export { childNode, collectPatternNames, isJavaScriptNode, javascriptChildren, javascriptPropertyName, nodeArray, nodeValue };
|
|
38
|
+
|
|
39
|
+
//# sourceMappingURL=javascript-ast.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"javascript-ast.mjs","names":[],"sources":["../src/javascript-ast.ts"],"sourcesContent":["import { isString, isNumber, isBoolean, isBigInt, isObject } from \"@temelj/value\";\n\nexport interface JavaScriptNode {\n readonly end: number;\n readonly start: number;\n readonly type: string;\n}\n\nexport type JavaScriptField =\n | JavaScriptNode\n | string\n | number\n | boolean\n | bigint\n | RegExp\n | null\n | undefined;\n\nexport function isJavaScriptNode(value: unknown): value is JavaScriptNode {\n return (\n isObject(value) &&\n \"type\" in value &&\n isString(value.type) &&\n \"start\" in value &&\n isNumber(value.start) &&\n \"end\" in value &&\n isNumber(value.end)\n );\n}\n\nexport function childNode(value: JavaScriptField): JavaScriptNode | undefined {\n return isObject(value) && !(value instanceof RegExp) ? value : undefined;\n}\n\nexport function nodeValue(node: JavaScriptNode, key: string): JavaScriptField {\n const value: unknown = Object.getOwnPropertyDescriptor(node, key)?.value;\n\n if (\n value === null ||\n value === undefined ||\n isJavaScriptNode(value) ||\n isString(value) ||\n isNumber(value) ||\n isBoolean(value) ||\n isBigInt(value) ||\n value instanceof RegExp\n ) {\n return value;\n }\n\n return undefined;\n}\n\nexport function nodeArray(node: JavaScriptNode, key: string): JavaScriptNode[] {\n const value: unknown = Object.getOwnPropertyDescriptor(node, key)?.value;\n\n return Array.isArray(value) ? value.filter(isJavaScriptNode) : [];\n}\n\nexport function collectPatternNames(node: JavaScriptNode | undefined, names: Set<string>): void {\n if (node === undefined) {\n return;\n }\n\n if (node.type === \"Identifier\") {\n const name = nodeValue(node, \"name\");\n\n if (isString(name)) {\n names.add(name);\n }\n } else if (node.type === \"RestElement\") {\n collectPatternNames(childNode(nodeValue(node, \"argument\")), names);\n } else if (node.type === \"AssignmentPattern\") {\n collectPatternNames(childNode(nodeValue(node, \"left\")), names);\n } else if (node.type === \"ArrayPattern\") {\n for (const element of nodeArray(node, \"elements\")) {\n collectPatternNames(element, names);\n }\n } else if (node.type === \"ObjectPattern\") {\n for (const property of nodeArray(node, \"properties\")) {\n collectPatternNames(\n childNode(nodeValue(property, \"value\")) ?? childNode(nodeValue(property, \"argument\")),\n names,\n );\n }\n }\n}\n\nexport function javascriptPropertyName(name: string): string {\n return /^[$A-Z_a-z][$\\w]*$/u.test(name) ? name : JSON.stringify(name);\n}\n\nexport function javascriptChildren(node: JavaScriptNode): JavaScriptNode[] {\n return nestedNodes(Object.values(node));\n}\n\nfunction nestedNodes(values: readonly unknown[]): JavaScriptNode[] {\n return values.flatMap((value) =>\n Array.isArray(value) ? nestedNodes(value) : isJavaScriptNode(value) ? [value] : [],\n );\n}\n"],"mappings":";;AAkBA,SAAgB,iBAAiB,OAAyC;CACxE,OACE,SAAS,KAAK,KACd,UAAU,SACV,SAAS,MAAM,IAAI,KACnB,WAAW,SACX,SAAS,MAAM,KAAK,KACpB,SAAS,SACT,SAAS,MAAM,GAAG;AAEtB;AAEA,SAAgB,UAAU,OAAoD;CAC5E,OAAO,SAAS,KAAK,KAAK,EAAE,iBAAiB,UAAU,QAAQ,KAAA;AACjE;AAEA,SAAgB,UAAU,MAAsB,KAA8B;CAC5E,MAAM,QAAiB,OAAO,yBAAyB,MAAM,GAAG,CAAC,EAAE;CAEnE,IACE,UAAU,QACV,UAAU,KAAA,KACV,iBAAiB,KAAK,KACtB,SAAS,KAAK,KACd,SAAS,KAAK,KACd,UAAU,KAAK,KACf,SAAS,KAAK,KACd,iBAAiB,QAEjB,OAAO;AAIX;AAEA,SAAgB,UAAU,MAAsB,KAA+B;CAC7E,MAAM,QAAiB,OAAO,yBAAyB,MAAM,GAAG,CAAC,EAAE;CAEnE,OAAO,MAAM,QAAQ,KAAK,IAAI,MAAM,OAAO,gBAAgB,IAAI,CAAC;AAClE;AAEA,SAAgB,oBAAoB,MAAkC,OAA0B;CAC9F,IAAI,SAAS,KAAA,GACX;CAGF,IAAI,KAAK,SAAS,cAAc;EAC9B,MAAM,OAAO,UAAU,MAAM,MAAM;EAEnC,IAAI,SAAS,IAAI,GACf,MAAM,IAAI,IAAI;CAElB,OAAO,IAAI,KAAK,SAAS,eACvB,oBAAoB,UAAU,UAAU,MAAM,UAAU,CAAC,GAAG,KAAK;MAC5D,IAAI,KAAK,SAAS,qBACvB,oBAAoB,UAAU,UAAU,MAAM,MAAM,CAAC,GAAG,KAAK;MACxD,IAAI,KAAK,SAAS,gBACvB,KAAK,MAAM,WAAW,UAAU,MAAM,UAAU,GAC9C,oBAAoB,SAAS,KAAK;MAE/B,IAAI,KAAK,SAAS,iBACvB,KAAK,MAAM,YAAY,UAAU,MAAM,YAAY,GACjD,oBACE,UAAU,UAAU,UAAU,OAAO,CAAC,KAAK,UAAU,UAAU,UAAU,UAAU,CAAC,GACpF,KACF;AAGN;AAEA,SAAgB,uBAAuB,MAAsB;CAC3D,OAAO,sBAAsB,KAAK,IAAI,IAAI,OAAO,KAAK,UAAU,IAAI;AACtE;AAEA,SAAgB,mBAAmB,MAAwC;CACzE,OAAO,YAAY,OAAO,OAAO,IAAI,CAAC;AACxC;AAEA,SAAS,YAAY,QAA8C;CACjE,OAAO,OAAO,SAAS,UACrB,MAAM,QAAQ,KAAK,IAAI,YAAY,KAAK,IAAI,iBAAiB,KAAK,IAAI,CAAC,KAAK,IAAI,CAAC,CACnF;AACF"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { SourceFile } from "./source.mjs";
|
|
2
|
+
import { JavaScriptNode } from "./javascript-ast.mjs";
|
|
3
|
+
import { CompileNames } from "./compile-names.mjs";
|
|
4
|
+
import { JsxReferenceContext } from "./jsx-reference.mjs";
|
|
5
|
+
//#region src/javascript-jsx.d.ts
|
|
6
|
+
export interface JavaScriptJsxContext extends JsxReferenceContext {
|
|
7
|
+
readonly development: boolean;
|
|
8
|
+
readonly names: CompileNames;
|
|
9
|
+
readonly sourceName: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function analyzeJavaScriptExpression(source: string, context: JavaScriptJsxContext): void;
|
|
12
|
+
export interface JavaScriptSourceOrigin {
|
|
13
|
+
readonly file: SourceFile;
|
|
14
|
+
readonly offset: number;
|
|
15
|
+
}
|
|
16
|
+
export declare function transformJavaScriptExpression(source: string, context: JavaScriptJsxContext, origin?: JavaScriptSourceOrigin): string;
|
|
17
|
+
/**
|
|
18
|
+
* Transforms JSX inside the nodes of one parsed program. Each call returns a
|
|
19
|
+
* node's source with its JSX replaced by runtime calls.
|
|
20
|
+
*/
|
|
21
|
+
export declare function programTransformer(source: string, program: JavaScriptNode, context: JavaScriptJsxContext, origin?: JavaScriptSourceOrigin): (node: JavaScriptNode) => string;
|
|
22
|
+
export declare function javascriptExpressionUsesAwait(source: string): boolean;
|
|
23
|
+
//#endregion
|
|
24
|
+
//# sourceMappingURL=javascript-jsx.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"javascript-jsx.d.mts","names":[],"sources":["../src/javascript-jsx.ts"],"mappings":";;;;;iBAkBiB,6BAA6B;WACnC;WACA,OAAO;WACP;;wBAGK,4BAA4B,gBAAgB,SAAS;iBAMpD;WACN,MAAM;WACN;;wBAGK,8BACd,gBACA,SAAS,sBACT,SAAS;;;;;wBAWK,mBACd,gBACA,SAAS,gBACT,SAAS,sBACT,SAAS,0BACP,MAAM;wBAMM,8BAA8B"}
|