@temelj/mdx 0.14.0 → 0.15.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 +468 -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 +185 -418
- 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.d.mts +15 -0
- package/dist/frontmatter.d.mts.map +1 -0
- package/dist/frontmatter.mjs +187 -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 +25 -9
- package/dist/mod.mjs +19 -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 +132 -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":"format.mjs","names":["exhaustive"],"sources":["../src/format.ts"],"sourcesContent":["import type {\n BlockQuoteNode,\n CodeBlockNode,\n DefinitionNode,\n FootnoteDefinitionNode,\n FootnoteReferenceNode,\n HeadingNode,\n ImageNode,\n ImageReferenceNode,\n LinkNode,\n LinkReferenceNode,\n ListItemNode,\n ListNode,\n MdxNode,\n ParagraphNode,\n} from \"./model.ts\";\n\nimport { encodeNumericCharacterReference } from \"./character-reference.ts\";\nimport {\n indentLines,\n longestRun,\n rootInfo,\n type FormatContext,\n type FormatInfo,\n type FormatOptions,\n} from \"./format-context.ts\";\nimport {\n formatContainerDirective,\n formatDirective,\n formatDirectiveLabel,\n containsDirective,\n} from \"./format-directive.ts\";\nimport { formatJsxFlowElement, formatJsxTextElement, indentExpression } from \"./format-jsx.ts\";\nimport { formatDisplayMath, formatInlineMath, mathFormats } from \"./format-math.ts\";\nimport {\n UNSAFE_PATTERNS,\n compileUnsafePattern,\n safeSource,\n type FormatConstruct,\n type FormatSafeInfo,\n type FormatSafetyState,\n type FormatUnsafePattern,\n} from \"./format-safe.ts\";\nimport { formatTable, formatTableCell, formatTableRow } from \"./format-table.ts\";\nimport { FormatTracker } from \"./format-track.ts\";\nimport { normalizeIdentifier } from \"./identifier.ts\";\nimport { mdxChildren } from \"./model.ts\";\nimport {\n frontmatterFence,\n resolveSyntaxOptions,\n type MathFormat,\n type ResolvedSyntaxOptions,\n} from \"./syntax-options.ts\";\n\n/** Formats a node as canonical MDX for the enabled syntax. */\nexport function formatMdx(node: MdxNode, options: FormatOptions = {}): string {\n return new Formatter(options, containsDirective(node), mathFormats(node)).format(node, rootInfo);\n}\n\nclass Formatter implements FormatSafetyState, FormatContext {\n public readonly stack: FormatConstruct[] = [];\n public readonly unsafe: readonly FormatUnsafePattern[];\n private readonly compiledPatterns = new Map<FormatUnsafePattern, RegExp>();\n public readonly options: FormatOptions;\n public readonly syntax: ResolvedSyntaxOptions;\n private bulletLastUsed: \"*\" | \"+\" | \"-\" | \".\" | \")\" | undefined;\n\n public constructor(\n options: FormatOptions,\n containsDirectives: boolean,\n nodeMathFormats: ReadonlySet<MathFormat>,\n ) {\n this.options = { ...options };\n this.syntax = resolveSyntaxOptions(options.syntax);\n this.unsafe = [\n ...UNSAFE_PATTERNS,\n { character: \"{\", inConstruct: \"phrasing\" },\n { atBreak: true, character: \"{\" },\n { character: \"<\", inConstruct: \"phrasing\" },\n { atBreak: true, character: \"<\" },\n ...(containsDirectives || this.syntax.directives\n ? ([\n {\n before: \"[^:]\",\n character: \":\",\n after: \"[A-Za-z]\",\n inConstruct: \"phrasing\",\n },\n { atBreak: true, character: \":\", after: \":\" },\n ] satisfies FormatUnsafePattern[])\n : []),\n ...(nodeMathFormats.has(\"dollar\") || this.syntax.math.includes(\"dollar\")\n ? ([\n {\n character: \"$\",\n inConstruct: \"phrasing\",\n },\n { character: \"$\", inConstruct: \"mathFlowMeta\" },\n { atBreak: true, character: \"$\", after: \"\\\\$\" },\n ] satisfies FormatUnsafePattern[])\n : []),\n ...this.syntax.frontmatter.map(\n (format) =>\n ({\n atBreak: true,\n character: frontmatterFence(format).charAt(0),\n after: escapeRegularExpression(frontmatterFence(format).slice(1)),\n }) satisfies FormatUnsafePattern,\n ),\n ];\n }\n\n public compilePattern(pattern: FormatUnsafePattern): RegExp {\n const cached = this.compiledPatterns.get(pattern);\n\n if (cached !== undefined) {\n return cached;\n }\n\n const expression = compileUnsafePattern(pattern);\n this.compiledPatterns.set(pattern, expression);\n\n return expression;\n }\n\n public format(node: MdxNode, info: FormatInfo): string {\n switch (node.kind) {\n case \"document\":\n return this.flow(node.children, info);\n case \"paragraph\":\n return this.paragraph(node, info);\n case \"heading\":\n return this.heading(node, info);\n case \"thematicBreak\":\n return this.thematicBreak();\n case \"codeBlock\":\n return this.codeBlock(node, info);\n case \"blockquote\":\n return this.blockQuote(node, info);\n case \"list\":\n return this.list(node, info);\n case \"listItem\":\n return this.flow(node.children, info, node.spread);\n case \"table\":\n return formatTable(this, node, info);\n case \"tableRow\":\n return formatTableRow(this, node, info);\n case \"tableCell\":\n return formatTableCell(this, node, info);\n case \"definition\":\n return this.definition(node, info);\n case \"footnoteDefinition\":\n return this.footnoteDefinition(node, info);\n case \"frontmatter\":\n return `${frontmatterFence(node.format)}${node.value.length === 0 ? \"\" : `\\n${node.value}`}\\n${frontmatterFence(node.format)}`;\n case \"directiveLabel\":\n return formatDirectiveLabel(this, node, info);\n case \"textDirective\":\n return formatDirective(this, node, info, \":\");\n case \"leafDirective\":\n return formatDirective(this, node, info, \"::\");\n case \"containerDirective\":\n return formatContainerDirective(this, node, info);\n case \"displayMath\":\n return formatDisplayMath(this, node, info);\n case \"rawHtmlBlock\":\n case \"rawHtmlInline\":\n return node.value;\n case \"text\":\n return this.safe(node.value, info);\n case \"emphasis\":\n return this.attention(\n node.children,\n info,\n this.attentionMarker(this.options.emphasis ?? \"*\", false),\n false,\n );\n case \"strong\":\n return this.attention(\n node.children,\n info,\n this.attentionMarker(this.options.strong ?? \"*\", true),\n true,\n );\n case \"delete\":\n return this.strikethrough(node.children, info);\n case \"inlineCode\":\n return this.stack.includes(\"tableCell\")\n ? formatInlineCode(node.value).replaceAll(\"|\", \"\\\\|\")\n : formatInlineCode(node.value);\n case \"inlineMath\":\n return formatInlineMath(this, node);\n case \"hardBreak\":\n return \"\\\\\\n\";\n case \"link\":\n return this.link(node, info);\n case \"image\":\n return this.image(node, info);\n case \"linkReference\":\n return this.linkReference(node, info);\n case \"imageReference\":\n return this.imageReference(node, info);\n case \"footnoteReference\":\n return this.footnoteReference(node);\n case \"inlineExpression\":\n case \"blockExpression\":\n return `{${indentExpression(node.code)}}`;\n case \"esm\":\n return node.code;\n case \"jsxTextElement\":\n return formatJsxTextElement(this, node, info);\n case \"jsxFlowElement\":\n return formatJsxFlowElement(this, node, info);\n default: {\n const exhaustive: never = node;\n\n return exhaustive;\n }\n }\n }\n\n public flow(nodes: readonly MdxNode[], info: FormatInfo, spread?: boolean): string {\n const tracker = new FormatTracker(info);\n const output: string[] = [];\n\n for (let index = 0; index < nodes.length; index++) {\n const node = nodes[index];\n output.push(\n tracker.move(this.format(node, { after: \"\\n\", before: \"\\n\", ...tracker.current() })),\n );\n const next = nodes[index + 1];\n\n if (next !== undefined) {\n output.push(tracker.move(this.join(node, next, spread)));\n }\n\n if (node.kind !== \"list\") {\n this.bulletLastUsed = undefined;\n }\n }\n\n return output.join(\"\");\n }\n\n private join(left: MdxNode, right: MdxNode, spread?: boolean): string {\n if (\n this.options.tightDefinitions === true &&\n left.kind === \"definition\" &&\n right.kind === \"definition\"\n ) {\n return \"\\n\";\n }\n\n if (spread !== undefined) {\n return spread ? \"\\n\\n\" : \"\\n\";\n }\n\n return \"\\n\\n\";\n }\n\n private paragraph(node: ParagraphNode, info: FormatInfo): string {\n const exit = this.enter(\"paragraph\");\n const exitPhrasing = this.enter(\"phrasing\");\n const value = this.phrasing(node.children, info);\n exitPhrasing();\n exit();\n\n return value;\n }\n\n public phrasing(nodes: readonly MdxNode[], info: FormatInfo): string {\n let tracker = new FormatTracker(info);\n const output: string[] = [];\n let before = info.before;\n\n for (let index = 0; index < nodes.length; index++) {\n const node = nodes[index];\n let nextIndex = index + 1;\n let text = node.kind === \"text\" ? node.value : undefined;\n let nextText = nodes.at(nextIndex);\n\n while (text !== undefined && nextText?.kind === \"text\") {\n text += nextText.value;\n nextIndex++;\n nextText = nodes.at(nextIndex);\n }\n\n const next = nodes[nextIndex];\n const after = next === undefined ? info.after : peek(next, this.options);\n\n if (\n output.length > 0 &&\n (before === \"\\r\" || before === \"\\n\") &&\n node.kind === \"rawHtmlInline\"\n ) {\n output[output.length - 1] = output[output.length - 1].replace(/(?:\\r\\n?|\\n)$/u, (ending) =>\n encodeLineEnding(ending),\n );\n before = \";\";\n tracker = new FormatTracker(info);\n tracker.move(output.join(\"\"));\n }\n\n let value =\n text === undefined\n ? this.format(node, { after, before, ...tracker.current() })\n : encodeBlankLineEndings(\n this.safe(text, {\n after,\n before,\n ...tracker.current(),\n }),\n );\n\n if (text !== undefined && after === \"[\" && value.endsWith(\"!\") && !value.endsWith(\"\\\\!\")) {\n value = `${value.slice(0, -1)}\\\\!`;\n }\n\n tracker.move(value);\n output.push(value);\n before = value.slice(-1);\n index = nextIndex - 1;\n }\n\n return output.join(\"\");\n }\n\n private heading(node: HeadingNode, info: FormatInfo): string {\n if (node.depth < 3 && node.children.some(containsLineEnding)) {\n const exit = this.enter(\"headingSetext\");\n const exitPhrasing = this.enter(\"phrasing\");\n const content = this.phrasing(node.children, { ...info, after: \"\\n\", before: \"\\n\" });\n exitPhrasing();\n exit();\n const lastLineStart = Math.max(content.lastIndexOf(\"\\r\"), content.lastIndexOf(\"\\n\")) + 1;\n\n return `${content}\\n${(node.depth === 1 ? \"=\" : \"-\").repeat(\n Math.max(1, content.length - lastLineStart),\n )}`;\n }\n\n const sequence = \"#\".repeat(node.depth);\n const exit = this.enter(\"headingAtx\");\n const exitPhrasing = this.enter(\"phrasing\");\n const tracker = new FormatTracker(info);\n tracker.move(`${sequence} `);\n\n let content = this.phrasing(node.children, {\n after: \"\\n\",\n before: \"# \",\n ...tracker.current(),\n });\n\n if (/^[\\t ]/u.test(content)) {\n content = encodeNumericCharacterReference(content.codePointAt(0) ?? 32) + content.slice(1);\n }\n\n if (content.endsWith(\"#\")) {\n content = `${content.slice(0, -1)}${encodeNumericCharacterReference(35)}`;\n }\n\n exitPhrasing();\n exit();\n\n if (content.length === 0) {\n return sequence;\n }\n\n return `${sequence} ${content}${this.options.closeAtx === true ? ` ${sequence}` : \"\"}`;\n }\n\n private thematicBreak(): string {\n const marker = this.options.rule ?? \"-\";\n const repetition = Math.max(3, this.options.ruleRepetition ?? 3);\n const value = `${marker}${this.options.ruleSpaces === true ? \" \" : \"\"}`.repeat(repetition);\n const rule = this.options.ruleSpaces === true ? value.slice(0, -1) : value;\n const frontmatterFences = new Set<string>(this.syntax.frontmatter.map(frontmatterFence));\n\n if (!frontmatterFences.has(rule)) {\n return rule;\n }\n\n let separator = \" \";\n let safeRule = Array.from({ length: repetition }, () => marker).join(separator);\n\n while (frontmatterFences.has(safeRule)) {\n separator += \" \";\n safeRule = Array.from({ length: repetition }, () => marker).join(separator);\n }\n\n return safeRule;\n }\n\n private codeBlock(node: CodeBlockNode, info: FormatInfo): string {\n const marker = this.options.fence ?? \"`\";\n const suffix = marker === \"`\" ? \"GraveAccent\" : \"Tilde\";\n const sequence = marker.repeat(Math.max(3, longestRun(node.value, marker) + 1));\n const tracker = new FormatTracker(info);\n let value = tracker.move(sequence);\n\n if (node.language !== undefined && node.language.length > 0) {\n const exitLanguage = this.enter(`codeFencedLang${suffix}`);\n value += tracker.move(this.safe(node.language, { after: \" \", before: value, encode: [\"`\"] }));\n exitLanguage();\n }\n\n if (node.meta !== undefined && node.meta.length > 0) {\n const exitMeta = this.enter(`codeFencedMeta${suffix}`);\n value += tracker.move(\n ` ${this.safe(node.meta, { after: \"\\n\", before: value, encode: [\"`\"] })}`,\n );\n exitMeta();\n }\n\n value += tracker.move(\"\\n\");\n\n if (node.value.length > 0) {\n value += tracker.move(`${node.value}\\n`);\n }\n\n return value + sequence;\n }\n\n private blockQuote(node: BlockQuoteNode, info: FormatInfo): string {\n const exit = this.enter(\"blockquote\");\n const tracker = new FormatTracker(info);\n tracker.move(\"> \");\n tracker.shift(2);\n\n const value = indentLines(\n this.flow(node.children, { after: \"\\n\", before: \"\\n\", ...tracker.current() }),\n (line, blank) => `>${blank ? \"\" : \" \"}${line}`,\n );\n\n exit();\n\n return value;\n }\n\n private list(node: ListNode, info: FormatInfo): string {\n const exit = this.enter(\"list\");\n\n let marker: \"*\" | \"+\" | \"-\" | \".\" | \")\" = node.ordered\n ? (this.options.bulletOrdered ?? \".\")\n : (this.options.bullet ?? \"-\");\n\n if (\n this.bulletLastUsed === marker ||\n (!node.ordered &&\n marker === (this.options.rule ?? \"-\") &&\n node.children.some((item) => item.children[0]?.kind === \"thematicBreak\"))\n ) {\n marker = alternateListMarker(marker);\n }\n\n const values = node.children.map((item, index) =>\n this.listItem(item, node, index, marker, info),\n );\n\n this.bulletLastUsed = marker;\n exit();\n\n return values.join(node.spread ? \"\\n\\n\" : \"\\n\");\n }\n\n private listItem(\n item: ListItemNode,\n parent: ListNode,\n index: number,\n listMarker: \"*\" | \"+\" | \"-\" | \".\" | \")\",\n info: FormatInfo,\n ): string {\n const marker = parent.ordered\n ? `${parent.start + (this.options.incrementListMarker === false ? 0 : index)}${listMarker}`\n : listMarker;\n\n let size = marker.length + 1;\n const indentation = this.options.listItemIndent ?? \"one\";\n\n if (indentation === \"tab\" || (indentation === \"mixed\" && (parent.spread || item.spread))) {\n size = Math.ceil(size / 4) * 4;\n }\n\n const prefix = `${marker}${\" \".repeat(size - marker.length)}`;\n const tracker = new FormatTracker(info);\n tracker.move(prefix);\n tracker.shift(size);\n const exit = this.enter(\"listItem\");\n\n let body = this.flow(\n item.children,\n { after: \"\\n\", before: \"\\n\", ...tracker.current() },\n parent.spread || item.spread,\n );\n\n if (item.checked !== undefined && item.children[0]?.kind === \"paragraph\") {\n body = `[${item.checked ? \"x\" : \" \"}] ${body}`;\n }\n\n const value = indentLines(body, (line, blank, lineIndex) =>\n lineIndex === 0\n ? `${blank ? marker : prefix}${line}`\n : `${blank ? \"\" : \" \".repeat(size)}${line}`,\n );\n\n exit();\n\n return value;\n }\n\n private definition(node: DefinitionNode, info: FormatInfo): string {\n const exit = this.enter(\"definition\");\n const tracker = new FormatTracker(info);\n const exitLabel = this.enter(\"label\");\n let value = tracker.move(\"[\");\n value += tracker.move(formatAssociationIdentifier(node.identifier));\n value += tracker.move(\"]: \");\n exitLabel();\n value += tracker.move(this.destination(node.url, value, node.title === undefined ? \"\\n\" : \" \"));\n\n if (node.title !== undefined) {\n value += tracker.move(this.title(node.title, value));\n }\n\n exit();\n\n return value;\n }\n\n private footnoteDefinition(node: FootnoteDefinitionNode, info: FormatInfo): string {\n const exit = this.enter(\"footnoteDefinition\");\n const tracker = new FormatTracker(info);\n const exitLabel = this.enter(\"label\");\n let value = tracker.move(\"[^\");\n value += tracker.move(this.safe(node.label, { before: value, after: \"]\" }));\n value += tracker.move(\"]:\");\n exitLabel();\n\n if (node.children.length > 0) {\n tracker.shift(4);\n\n const content = this.flow(node.children, {\n after: \"\\n\",\n before: \"\\n\",\n ...tracker.current(),\n });\n\n const blankFirst = this.options.footnoteFirstLineBlank === true;\n value +=\n (blankFirst ? \"\\n\" : \" \") +\n indentLines(content, (line, blank, lineIndex) =>\n !blankFirst && lineIndex === 0 ? line : `${blank ? \"\" : \" \"}${line}`,\n );\n }\n\n exit();\n\n return value;\n }\n\n private footnoteReference(node: FootnoteReferenceNode): string {\n const exit = this.enter(\"footnoteReference\");\n const exitReference = this.enter(\"reference\");\n const value = `[^${this.safe(node.label, { before: \"[^\", after: \"]\" })}]`;\n exitReference();\n exit();\n\n return value;\n }\n\n private attention(\n children: readonly MdxNode[],\n info: FormatInfo,\n marker: \"*\" | \"_\",\n strong: boolean,\n ): string {\n const sequence = strong ? marker + marker : marker;\n const exit = this.enter(strong ? \"strong\" : \"emphasis\");\n const tracker = new FormatTracker(info);\n const before = tracker.move(sequence);\n\n const content = tracker.move(\n this.phrasing(children, { after: marker, before, ...tracker.current() }),\n );\n\n exit();\n\n return before + content + sequence;\n }\n\n private attentionMarker(marker: \"*\" | \"_\", strong: boolean): \"*\" | \"_\" {\n return this.stack.includes(strong ? \"strong\" : \"emphasis\")\n ? marker === \"*\"\n ? \"_\"\n : \"*\"\n : marker;\n }\n\n private strikethrough(children: readonly MdxNode[], info: FormatInfo): string {\n const exit = this.enter(\"strikethrough\");\n const tracker = new FormatTracker(info);\n const before = tracker.move(\"~~\");\n\n const content = tracker.move(\n this.phrasing(children, { after: \"~\", before, ...tracker.current() }),\n );\n\n exit();\n\n return before + content + \"~~\";\n }\n\n private link(node: LinkNode, info: FormatInfo): string {\n const exit = this.enter(\"link\");\n const tracker = new FormatTracker(info);\n const exitLabel = this.enter(\"label\");\n let value = tracker.move(\"[\");\n value += tracker.move(\n this.phrasing(node.children, { after: \"]\", before: value, ...tracker.current() }),\n );\n value += tracker.move(\"](\");\n exitLabel();\n value += tracker.move(this.destination(node.url, value, node.title === undefined ? \")\" : \" \"));\n\n if (node.title !== undefined) {\n value += tracker.move(this.title(node.title, value));\n }\n\n exit();\n\n return value + \")\";\n }\n\n private image(node: ImageNode, info: FormatInfo): string {\n const exit = this.enter(\"image\");\n const tracker = new FormatTracker(info);\n const exitLabel = this.enter(\"label\");\n let value = tracker.move(\"![\");\n value += tracker.move(this.safe(node.alt, { before: value, after: \"]\" }));\n value += tracker.move(\"](\");\n exitLabel();\n value += tracker.move(this.destination(node.url, value, node.title === undefined ? \")\" : \" \"));\n\n if (node.title !== undefined) {\n value += tracker.move(this.title(node.title, value));\n }\n\n exit();\n\n return value + \")\";\n }\n\n private linkReference(node: LinkReferenceNode, info: FormatInfo): string {\n const exit = this.enter(\"linkReference\");\n const exitLabel = this.enter(\"label\");\n const label = this.phrasing(node.children, { ...info, before: \"[\", after: \"]\" });\n exitLabel();\n const value = `[${label}]${this.referenceSuffix(node.referenceKind, node.identifier, label)}`;\n exit();\n\n return value;\n }\n\n private imageReference(node: ImageReferenceNode, _info: FormatInfo): string {\n const exit = this.enter(\"imageReference\");\n const exitLabel = this.enter(\"label\");\n const alt = this.safe(node.alt, { before: \"![\", after: \"]\" });\n exitLabel();\n const value = `![${alt}]${this.referenceSuffix(node.referenceKind, node.identifier, alt)}`;\n exit();\n\n return value;\n }\n\n private referenceSuffix(\n kind: LinkReferenceNode[\"referenceKind\"],\n identifier: string,\n label: string,\n ): string {\n const reference = this.referenceIdentifier(identifier);\n\n if (label.length > 0 && normalizeIdentifier(label) === normalizeIdentifier(reference)) {\n if (kind === \"shortcut\") {\n return \"\";\n }\n\n if (kind === \"collapsed\") {\n return \"[]\";\n }\n }\n\n return `[${reference}]`;\n }\n\n private referenceIdentifier(identifier: string): string {\n return formatAssociationIdentifier(identifier);\n }\n\n private destination(value: string, before: string, after: string): string {\n if (value.length === 0 || /[\\0- \\u007F]/u.test(value)) {\n const exit = this.enter(\"destinationLiteral\");\n const result = `<${this.safe(value, { before: `${before}<`, after: \">\" })}>`;\n exit();\n\n return result;\n }\n\n const exit = this.enter(\"destinationRaw\");\n const result = this.safe(value, { before, after });\n exit();\n\n return result;\n }\n\n private title(value: string, before: string): string {\n const quote = this.options.quote ?? '\"';\n const exit = this.enter(quote === '\"' ? \"titleQuote\" : \"titleApostrophe\");\n const result = ` ${quote}${this.safe(value, { before: `${before} ${quote}`, after: quote })}${quote}`;\n exit();\n\n return result;\n }\n\n public safe(value: string, info: FormatSafeInfo): string {\n return safeSource(this, value, info);\n }\n\n public enter(construct: FormatConstruct): () => void {\n this.stack.push(construct);\n\n return (): void => {\n this.stack.pop();\n };\n }\n}\n\nfunction peek(node: MdxNode, options: FormatOptions): string {\n switch (node.kind) {\n case \"textDirective\":\n return \":\";\n case \"inlineMath\":\n return node.format === \"dollar\" ? \"$\" : \"\\\\\";\n case \"image\":\n case \"imageReference\":\n return \"!\";\n case \"footnoteReference\":\n case \"link\":\n case \"linkReference\":\n return \"[\";\n case \"emphasis\":\n return options.emphasis ?? \"*\";\n case \"strong\":\n return options.strong ?? \"*\";\n case \"delete\":\n return \"~\";\n case \"inlineCode\":\n return \"`\";\n case \"rawHtmlInline\":\n case \"jsxTextElement\":\n return \"<\";\n case \"hardBreak\":\n return \"\\\\\";\n case \"inlineExpression\":\n return \"{\";\n case \"text\":\n return node.value.charAt(0);\n default:\n return \"\";\n }\n}\n\nfunction formatInlineCode(input: string): string {\n const value = input.replace(/\\r\\n?|\\n/gu, \" \");\n let sequence = \"`\";\n\n while (new RegExp(`(^|[^\\`])${sequence}([^\\`]|$)`, \"u\").test(value)) {\n sequence += \"`\";\n }\n\n const padded =\n /[^ \\r\\n]/u.test(value) &&\n ((/^[ \\r\\n]/u.test(value) && /[ \\r\\n]$/u.test(value)) || /^`|`$/u.test(value))\n ? ` ${value} `\n : value;\n\n return `${sequence}${padded}${sequence}`;\n}\n\nfunction alternateListMarker(marker: \"*\" | \"+\" | \"-\" | \".\" | \")\"): \"*\" | \"-\" | \".\" | \")\" {\n if (marker === \".\") {\n return \")\";\n }\n\n if (marker === \")\") {\n return \".\";\n }\n\n return marker === \"*\" ? \"-\" : \"*\";\n}\n\nfunction containsLineEnding(node: MdxNode): boolean {\n if (node.kind === \"hardBreak\") {\n return true;\n }\n\n if ((node.kind === \"text\" || node.kind === \"rawHtmlInline\") && /\\r\\n?|\\n/u.test(node.value)) {\n return true;\n }\n\n return mdxChildren(node).some(containsLineEnding);\n}\n\nfunction encodeBlankLineEndings(value: string): string {\n return value.replace(/(?:(?:\\r\\n?|\\n)){2,}/gu, encodeLineEnding);\n}\n\nfunction encodeLineEnding(value: string): string {\n let result = \"\";\n\n for (const character of value) {\n result += encodeNumericCharacterReference(character.codePointAt(0) ?? 0);\n }\n\n return result;\n}\n\nfunction formatAssociationIdentifier(value: string): string {\n return value.replace(/[!-/:-@[-`{-~]/gu, \"\\\\$&\");\n}\n\nfunction escapeRegularExpression(value: string): string {\n return value.replace(/[|\\\\{}()[\\]^$+*?.]/gu, \"\\\\$&\");\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { FrontmatterFormat } from "./syntax-options.mjs";
|
|
2
|
+
import { FrontmatterObject } from "./model.mjs";
|
|
3
|
+
import { SourceSpan } from "./source.mjs";
|
|
4
|
+
import { DiagnosticReporter } from "./diagnostics.mjs";
|
|
5
|
+
//#region src/frontmatter.d.ts
|
|
6
|
+
interface DecodeOptions {
|
|
7
|
+
readonly diagnostics: DiagnosticReporter;
|
|
8
|
+
readonly format: FrontmatterFormat;
|
|
9
|
+
readonly source: string;
|
|
10
|
+
readonly span: SourceSpan;
|
|
11
|
+
}
|
|
12
|
+
export declare function decodeFrontmatter(options: DecodeOptions): FrontmatterObject | undefined;
|
|
13
|
+
//#endregion
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=frontmatter.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontmatter.d.mts","names":[],"sources":["../src/frontmatter.ts"],"mappings":";;;;;UAkBU;WACC,aAAa;WACb,QAAQ;WACR;WACA,MAAM;;wBAOD,kBAAkB,SAAS,gBAAgB"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { isBigInt, isBoolean, isFunction, isNumber, isObject, isPlainObject, isString, isSymbol } from "@temelj/value";
|
|
2
|
+
import { TomlDate, TomlError, parse } from "smol-toml";
|
|
3
|
+
import { parseDocument } from "yaml";
|
|
4
|
+
//#region src/frontmatter.ts
|
|
5
|
+
const maximumYamlAliases = 100;
|
|
6
|
+
const maximumTomlDepth = 256;
|
|
7
|
+
function decodeFrontmatter(options) {
|
|
8
|
+
return options.format === "yaml" ? decodeYaml(options) : decodeToml(options);
|
|
9
|
+
}
|
|
10
|
+
function decodeYaml(options) {
|
|
11
|
+
let document;
|
|
12
|
+
try {
|
|
13
|
+
document = parseDocument(options.source, {
|
|
14
|
+
customTags: [],
|
|
15
|
+
intAsBigInt: true,
|
|
16
|
+
logLevel: "silent",
|
|
17
|
+
prettyErrors: false,
|
|
18
|
+
resolveKnownTags: false,
|
|
19
|
+
schema: "core",
|
|
20
|
+
strict: true,
|
|
21
|
+
stringKeys: true,
|
|
22
|
+
uniqueKeys: true,
|
|
23
|
+
version: "1.2"
|
|
24
|
+
});
|
|
25
|
+
} catch (cause) {
|
|
26
|
+
addParserFailure(options, cause);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
for (const warning of document.warnings) options.diagnostics.add({
|
|
30
|
+
code: yamlCode(warning.code),
|
|
31
|
+
message: warning.message,
|
|
32
|
+
severity: "warning",
|
|
33
|
+
span: relativeSpan(options.span, warning.pos[0], warning.pos[1])
|
|
34
|
+
});
|
|
35
|
+
for (const error of document.errors) options.diagnostics.add({
|
|
36
|
+
code: yamlCode(error.code),
|
|
37
|
+
message: error.message,
|
|
38
|
+
severity: "error",
|
|
39
|
+
span: relativeSpan(options.span, error.pos[0], error.pos[1])
|
|
40
|
+
});
|
|
41
|
+
if (document.errors.length > 0) return;
|
|
42
|
+
let parsed;
|
|
43
|
+
try {
|
|
44
|
+
parsed = document.contents === null ? {} : document.toJS({ maxAliasCount: maximumYamlAliases });
|
|
45
|
+
} catch (cause) {
|
|
46
|
+
addParserFailure(options, cause);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
return convertRoot(parsed, options);
|
|
50
|
+
}
|
|
51
|
+
function decodeToml(options) {
|
|
52
|
+
let parsed;
|
|
53
|
+
try {
|
|
54
|
+
parsed = parse(options.source, {
|
|
55
|
+
integersAsBigInt: "asNeeded",
|
|
56
|
+
maxDepth: maximumTomlDepth
|
|
57
|
+
});
|
|
58
|
+
} catch (cause) {
|
|
59
|
+
if (cause instanceof TomlError) {
|
|
60
|
+
const offset = lineColumnOffset(options.source, cause.line, cause.column);
|
|
61
|
+
options.diagnostics.add({
|
|
62
|
+
code: "mdx.frontmatter.toml",
|
|
63
|
+
message: cause.message,
|
|
64
|
+
severity: "error",
|
|
65
|
+
span: relativeSpan(options.span, offset, offset + 1)
|
|
66
|
+
});
|
|
67
|
+
} else addParserFailure(options, cause);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
return convertRoot(parsed, options);
|
|
71
|
+
}
|
|
72
|
+
function convertRoot(value, options) {
|
|
73
|
+
if (!isPlainObject(value)) {
|
|
74
|
+
options.diagnostics.add({
|
|
75
|
+
code: "mdx.frontmatter.root",
|
|
76
|
+
message: "FrontmatterNode must contain a mapping at its root",
|
|
77
|
+
severity: "error",
|
|
78
|
+
span: options.span
|
|
79
|
+
});
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
return convertObject(value, options, "$", /* @__PURE__ */ new WeakSet());
|
|
83
|
+
}
|
|
84
|
+
function convertValue(value, options, path, active) {
|
|
85
|
+
if (value === null || isBoolean(value) || isNumber(value) || isString(value)) return value;
|
|
86
|
+
if (isBigInt(value)) return value >= BigInt(Number.MIN_SAFE_INTEGER) && value <= BigInt(Number.MAX_SAFE_INTEGER) ? Number(value) : value;
|
|
87
|
+
if (value instanceof TomlDate) return convertTemporal(value);
|
|
88
|
+
if (Array.isArray(value)) {
|
|
89
|
+
if (active.has(value)) return invalidValue(options, path, "cyclic alias");
|
|
90
|
+
active.add(value);
|
|
91
|
+
const converted = [];
|
|
92
|
+
for (const [index, item] of value.entries()) {
|
|
93
|
+
const result = convertValue(item, options, `${path}[${index}]`, active);
|
|
94
|
+
if (result === void 0) return;
|
|
95
|
+
converted.push(result);
|
|
96
|
+
}
|
|
97
|
+
active.delete(value);
|
|
98
|
+
Object.freeze(converted);
|
|
99
|
+
return converted;
|
|
100
|
+
}
|
|
101
|
+
if (isPlainObject(value)) return convertObject(value, options, path, active);
|
|
102
|
+
return invalidValue(options, path, describeValue(value));
|
|
103
|
+
}
|
|
104
|
+
function convertObject(value, options, path, active) {
|
|
105
|
+
if (active.has(value)) return invalidValue(options, path, "cyclic alias");
|
|
106
|
+
active.add(value);
|
|
107
|
+
const converted = {};
|
|
108
|
+
for (const [key, item] of Object.entries(value)) {
|
|
109
|
+
const result = convertValue(item, options, propertyPath(path, key), active);
|
|
110
|
+
if (result === void 0) return;
|
|
111
|
+
Object.defineProperty(converted, key, {
|
|
112
|
+
configurable: false,
|
|
113
|
+
enumerable: true,
|
|
114
|
+
value: result,
|
|
115
|
+
writable: false
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
active.delete(value);
|
|
119
|
+
Object.freeze(converted);
|
|
120
|
+
return converted;
|
|
121
|
+
}
|
|
122
|
+
function convertTemporal(value) {
|
|
123
|
+
const type = value.isDateTime() ? value.isLocal() ? "local-date-time" : "offset-date-time" : value.isDate() ? "local-date" : "local-time";
|
|
124
|
+
return Object.freeze({
|
|
125
|
+
kind: "temporal",
|
|
126
|
+
type,
|
|
127
|
+
value: value.toISOString()
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
function invalidValue(options, path, description) {
|
|
131
|
+
options.diagnostics.add({
|
|
132
|
+
code: "mdx.frontmatter.value",
|
|
133
|
+
message: `Unsupported frontmatter value at ${path}: ${description}`,
|
|
134
|
+
severity: "error",
|
|
135
|
+
span: options.span
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
function addParserFailure(options, cause) {
|
|
139
|
+
const message = cause instanceof Error ? cause.message : String(cause);
|
|
140
|
+
options.diagnostics.add({
|
|
141
|
+
code: `mdx.frontmatter.${options.format}`,
|
|
142
|
+
message,
|
|
143
|
+
severity: "error",
|
|
144
|
+
span: options.span
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
function yamlCode(code) {
|
|
148
|
+
return code === "RESOURCE_EXHAUSTION" ? "mdx.frontmatter.resource" : "mdx.frontmatter.yaml";
|
|
149
|
+
}
|
|
150
|
+
function relativeSpan(span, start, end) {
|
|
151
|
+
const length = span.end - span.start;
|
|
152
|
+
const relativeStart = Math.max(0, Math.min(start, length));
|
|
153
|
+
const relativeEnd = Math.max(relativeStart, Math.min(end, length));
|
|
154
|
+
return Object.freeze({
|
|
155
|
+
file: span.file,
|
|
156
|
+
start: span.start + relativeStart,
|
|
157
|
+
end: span.start + relativeEnd
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
function lineColumnOffset(source, line, column) {
|
|
161
|
+
const lineStart = lineStartOffsets(source)[Math.max(0, line - 1)] ?? source.length;
|
|
162
|
+
return Math.min(source.length, lineStart + Math.max(0, column - 1));
|
|
163
|
+
}
|
|
164
|
+
function propertyPath(path, key) {
|
|
165
|
+
return /^[A-Za-z_$][\w$]*$/u.test(key) ? `${path}.${key}` : `${path}[${JSON.stringify(key)}]`;
|
|
166
|
+
}
|
|
167
|
+
function describeValue(value) {
|
|
168
|
+
if (value === void 0) return "undefined";
|
|
169
|
+
if (isFunction(value)) return "function";
|
|
170
|
+
if (isSymbol(value)) return "symbol";
|
|
171
|
+
if (value instanceof Map) return "Map";
|
|
172
|
+
if (value instanceof Set) return "Set";
|
|
173
|
+
if (value instanceof Date) return "Date";
|
|
174
|
+
return isObject(value) ? value.constructor?.name ?? "object" : String(value);
|
|
175
|
+
}
|
|
176
|
+
function lineStartOffsets(source) {
|
|
177
|
+
const offsets = [0];
|
|
178
|
+
for (let index = 0; index < source.length; index++) if (source[index] === "\r") {
|
|
179
|
+
if (source[index + 1] === "\n") index++;
|
|
180
|
+
offsets.push(index + 1);
|
|
181
|
+
} else if (source[index] === "\n") offsets.push(index + 1);
|
|
182
|
+
return offsets;
|
|
183
|
+
}
|
|
184
|
+
//#endregion
|
|
185
|
+
export { decodeFrontmatter };
|
|
186
|
+
|
|
187
|
+
//# sourceMappingURL=frontmatter.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontmatter.mjs","names":["parseToml"],"sources":["../src/frontmatter.ts"],"sourcesContent":["import {\n isBoolean,\n isNumber,\n isString,\n isBigInt,\n isFunction,\n isSymbol,\n isObject,\n isPlainObject,\n} from \"@temelj/value\";\nimport { parse as parseToml, TomlDate, TomlError } from \"smol-toml\";\nimport { parseDocument } from \"yaml\";\n\nimport type { DiagnosticReporter } from \"./diagnostics.ts\";\nimport type { FrontmatterObject, FrontmatterTemporal, FrontmatterValue } from \"./model.ts\";\nimport type { SourceSpan } from \"./source.ts\";\nimport type { FrontmatterFormat } from \"./syntax-options.ts\";\n\ninterface DecodeOptions {\n readonly diagnostics: DiagnosticReporter;\n readonly format: FrontmatterFormat;\n readonly source: string;\n readonly span: SourceSpan;\n}\n\nconst maximumYamlAliases = 100;\n\nconst maximumTomlDepth = 256;\n\nexport function decodeFrontmatter(options: DecodeOptions): FrontmatterObject | undefined {\n return options.format === \"yaml\" ? decodeYaml(options) : decodeToml(options);\n}\n\nfunction decodeYaml(options: DecodeOptions): FrontmatterObject | undefined {\n let document: ReturnType<typeof parseDocument>;\n\n try {\n document = parseDocument(options.source, {\n customTags: [],\n intAsBigInt: true,\n logLevel: \"silent\",\n prettyErrors: false,\n resolveKnownTags: false,\n schema: \"core\",\n strict: true,\n stringKeys: true,\n uniqueKeys: true,\n version: \"1.2\",\n });\n } catch (cause) {\n addParserFailure(options, cause);\n\n return undefined;\n }\n\n for (const warning of document.warnings) {\n options.diagnostics.add({\n code: yamlCode(warning.code),\n message: warning.message,\n severity: \"warning\",\n span: relativeSpan(options.span, warning.pos[0], warning.pos[1]),\n });\n }\n\n for (const error of document.errors) {\n options.diagnostics.add({\n code: yamlCode(error.code),\n message: error.message,\n severity: \"error\",\n span: relativeSpan(options.span, error.pos[0], error.pos[1]),\n });\n }\n\n if (document.errors.length > 0) {\n return undefined;\n }\n\n let parsed: unknown;\n\n try {\n parsed = document.contents === null ? {} : document.toJS({ maxAliasCount: maximumYamlAliases });\n } catch (cause) {\n addParserFailure(options, cause);\n\n return undefined;\n }\n\n return convertRoot(parsed, options);\n}\n\nfunction decodeToml(options: DecodeOptions): FrontmatterObject | undefined {\n let parsed: unknown;\n\n try {\n parsed = parseToml(options.source, {\n integersAsBigInt: \"asNeeded\",\n maxDepth: maximumTomlDepth,\n });\n } catch (cause) {\n if (cause instanceof TomlError) {\n const offset = lineColumnOffset(options.source, cause.line, cause.column);\n options.diagnostics.add({\n code: \"mdx.frontmatter.toml\",\n message: cause.message,\n severity: \"error\",\n span: relativeSpan(options.span, offset, offset + 1),\n });\n } else {\n addParserFailure(options, cause);\n }\n\n return undefined;\n }\n\n return convertRoot(parsed, options);\n}\n\n// oxlint-disable-next-line anti-slop/no-unknown-parameters -- YAML/TOML root input is validated here.\nfunction convertRoot(value: unknown, options: DecodeOptions): FrontmatterObject | undefined {\n if (!isPlainObject(value)) {\n options.diagnostics.add({\n code: \"mdx.frontmatter.root\",\n message: \"FrontmatterNode must contain a mapping at its root\",\n severity: \"error\",\n span: options.span,\n });\n\n return undefined;\n }\n\n return convertObject(value, options, \"$\", new WeakSet<object>());\n}\n\nfunction convertValue(\n // oxlint-disable-next-line anti-slop/no-unknown-parameters -- Recursively validates parser values before producing FrontmatterValue.\n value: unknown,\n options: DecodeOptions,\n path: string,\n active: WeakSet<object>,\n): FrontmatterValue | undefined {\n if (value === null || isBoolean(value) || isNumber(value) || isString(value)) {\n return value;\n }\n\n if (isBigInt(value)) {\n return value >= BigInt(Number.MIN_SAFE_INTEGER) && value <= BigInt(Number.MAX_SAFE_INTEGER)\n ? Number(value)\n : value;\n }\n\n if (value instanceof TomlDate) {\n return convertTemporal(value);\n }\n\n if (Array.isArray(value)) {\n if (active.has(value)) {\n return invalidValue(options, path, \"cyclic alias\");\n }\n\n active.add(value);\n const converted: FrontmatterValue[] = [];\n\n for (const [index, item] of value.entries()) {\n const result = convertValue(item, options, `${path}[${index}]`, active);\n\n if (result === undefined) {\n return undefined;\n }\n\n converted.push(result);\n }\n\n active.delete(value);\n Object.freeze(converted);\n\n return converted;\n }\n\n if (isPlainObject(value)) {\n return convertObject(value, options, path, active);\n }\n\n return invalidValue(options, path, describeValue(value));\n}\n\nfunction convertObject(\n // oxlint-disable-next-line anti-slop/no-object-parameters -- YAML/TOML mapping boundary; every entry is converted to FrontmatterValue below.\n value: object,\n options: DecodeOptions,\n path: string,\n active: WeakSet<object>,\n): FrontmatterObject | undefined {\n if (active.has(value)) {\n return invalidValue(options, path, \"cyclic alias\");\n }\n\n active.add(value);\n const converted: Record<string, FrontmatterValue> = {};\n\n for (const [key, item] of Object.entries(value)) {\n const itemPath = propertyPath(path, key);\n const result = convertValue(item, options, itemPath, active);\n\n if (result === undefined) {\n return undefined;\n }\n\n Object.defineProperty(converted, key, {\n configurable: false,\n enumerable: true,\n value: result,\n writable: false,\n });\n }\n\n active.delete(value);\n Object.freeze(converted);\n\n return converted;\n}\n\nfunction convertTemporal(value: TomlDate): FrontmatterTemporal {\n const type = value.isDateTime()\n ? value.isLocal()\n ? \"local-date-time\"\n : \"offset-date-time\"\n : value.isDate()\n ? \"local-date\"\n : \"local-time\";\n\n return Object.freeze({ kind: \"temporal\", type, value: value.toISOString() });\n}\n\nfunction invalidValue(options: DecodeOptions, path: string, description: string): undefined {\n options.diagnostics.add({\n code: \"mdx.frontmatter.value\",\n message: `Unsupported frontmatter value at ${path}: ${description}`,\n severity: \"error\",\n span: options.span,\n });\n\n return undefined;\n}\n\nfunction addParserFailure(options: DecodeOptions, cause: unknown): void {\n const message = cause instanceof Error ? cause.message : String(cause);\n options.diagnostics.add({\n code: `mdx.frontmatter.${options.format}`,\n message,\n severity: \"error\",\n span: options.span,\n });\n}\n\nfunction yamlCode(code: string): string {\n return code === \"RESOURCE_EXHAUSTION\" ? \"mdx.frontmatter.resource\" : \"mdx.frontmatter.yaml\";\n}\n\nfunction relativeSpan(span: SourceSpan, start: number, end: number): SourceSpan {\n const length = span.end - span.start;\n const relativeStart = Math.max(0, Math.min(start, length));\n const relativeEnd = Math.max(relativeStart, Math.min(end, length));\n\n return Object.freeze({\n file: span.file,\n start: span.start + relativeStart,\n end: span.start + relativeEnd,\n });\n}\n\nfunction lineColumnOffset(source: string, line: number, column: number): number {\n const lineStart = lineStartOffsets(source)[Math.max(0, line - 1)] ?? source.length;\n\n return Math.min(source.length, lineStart + Math.max(0, column - 1));\n}\n\nfunction propertyPath(path: string, key: string): string {\n return /^[A-Za-z_$][\\w$]*$/u.test(key) ? `${path}.${key}` : `${path}[${JSON.stringify(key)}]`;\n}\n\n// oxlint-disable-next-line anti-slop/no-unknown-parameters -- Describes a rejected value at the YAML/TOML validation boundary.\nfunction describeValue(value: unknown): string {\n if (value === undefined) {\n return \"undefined\";\n }\n\n if (isFunction(value)) {\n return \"function\";\n }\n\n if (isSymbol(value)) {\n return \"symbol\";\n }\n\n if (value instanceof Map) {\n return \"Map\";\n }\n\n if (value instanceof Set) {\n return \"Set\";\n }\n\n if (value instanceof Date) {\n return \"Date\";\n }\n\n return isObject(value) ? (value.constructor?.name ?? \"object\") : String(value);\n}\n\nfunction lineStartOffsets(source: string): readonly number[] {\n const offsets = [0];\n\n for (let index = 0; index < source.length; index++) {\n if (source[index] === \"\\r\") {\n if (source[index + 1] === \"\\n\") {\n index++;\n }\n\n offsets.push(index + 1);\n } else if (source[index] === \"\\n\") {\n offsets.push(index + 1);\n }\n }\n\n return offsets;\n}\n"],"mappings":";;;;AAyBA,MAAM,qBAAqB;AAE3B,MAAM,mBAAmB;AAEzB,SAAgB,kBAAkB,SAAuD;CACvF,OAAO,QAAQ,WAAW,SAAS,WAAW,OAAO,IAAI,WAAW,OAAO;AAC7E;AAEA,SAAS,WAAW,SAAuD;CACzE,IAAI;CAEJ,IAAI;EACF,WAAW,cAAc,QAAQ,QAAQ;GACvC,YAAY,CAAC;GACb,aAAa;GACb,UAAU;GACV,cAAc;GACd,kBAAkB;GAClB,QAAQ;GACR,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,SAAS;EACX,CAAC;CACH,SAAS,OAAO;EACd,iBAAiB,SAAS,KAAK;EAE/B;CACF;CAEA,KAAK,MAAM,WAAW,SAAS,UAC7B,QAAQ,YAAY,IAAI;EACtB,MAAM,SAAS,QAAQ,IAAI;EAC3B,SAAS,QAAQ;EACjB,UAAU;EACV,MAAM,aAAa,QAAQ,MAAM,QAAQ,IAAI,IAAI,QAAQ,IAAI,EAAE;CACjE,CAAC;CAGH,KAAK,MAAM,SAAS,SAAS,QAC3B,QAAQ,YAAY,IAAI;EACtB,MAAM,SAAS,MAAM,IAAI;EACzB,SAAS,MAAM;EACf,UAAU;EACV,MAAM,aAAa,QAAQ,MAAM,MAAM,IAAI,IAAI,MAAM,IAAI,EAAE;CAC7D,CAAC;CAGH,IAAI,SAAS,OAAO,SAAS,GAC3B;CAGF,IAAI;CAEJ,IAAI;EACF,SAAS,SAAS,aAAa,OAAO,CAAC,IAAI,SAAS,KAAK,EAAE,eAAe,mBAAmB,CAAC;CAChG,SAAS,OAAO;EACd,iBAAiB,SAAS,KAAK;EAE/B;CACF;CAEA,OAAO,YAAY,QAAQ,OAAO;AACpC;AAEA,SAAS,WAAW,SAAuD;CACzE,IAAI;CAEJ,IAAI;EACF,SAASA,MAAU,QAAQ,QAAQ;GACjC,kBAAkB;GAClB,UAAU;EACZ,CAAC;CACH,SAAS,OAAO;EACd,IAAI,iBAAiB,WAAW;GAC9B,MAAM,SAAS,iBAAiB,QAAQ,QAAQ,MAAM,MAAM,MAAM,MAAM;GACxE,QAAQ,YAAY,IAAI;IACtB,MAAM;IACN,SAAS,MAAM;IACf,UAAU;IACV,MAAM,aAAa,QAAQ,MAAM,QAAQ,SAAS,CAAC;GACrD,CAAC;EACH,OACE,iBAAiB,SAAS,KAAK;EAGjC;CACF;CAEA,OAAO,YAAY,QAAQ,OAAO;AACpC;AAGA,SAAS,YAAY,OAAgB,SAAuD;CAC1F,IAAI,CAAC,cAAc,KAAK,GAAG;EACzB,QAAQ,YAAY,IAAI;GACtB,MAAM;GACN,SAAS;GACT,UAAU;GACV,MAAM,QAAQ;EAChB,CAAC;EAED;CACF;CAEA,OAAO,cAAc,OAAO,SAAS,qBAAK,IAAI,QAAgB,CAAC;AACjE;AAEA,SAAS,aAEP,OACA,SACA,MACA,QAC8B;CAC9B,IAAI,UAAU,QAAQ,UAAU,KAAK,KAAK,SAAS,KAAK,KAAK,SAAS,KAAK,GACzE,OAAO;CAGT,IAAI,SAAS,KAAK,GAChB,OAAO,SAAS,OAAO,OAAO,gBAAgB,KAAK,SAAS,OAAO,OAAO,gBAAgB,IACtF,OAAO,KAAK,IACZ;CAGN,IAAI,iBAAiB,UACnB,OAAO,gBAAgB,KAAK;CAG9B,IAAI,MAAM,QAAQ,KAAK,GAAG;EACxB,IAAI,OAAO,IAAI,KAAK,GAClB,OAAO,aAAa,SAAS,MAAM,cAAc;EAGnD,OAAO,IAAI,KAAK;EAChB,MAAM,YAAgC,CAAC;EAEvC,KAAK,MAAM,CAAC,OAAO,SAAS,MAAM,QAAQ,GAAG;GAC3C,MAAM,SAAS,aAAa,MAAM,SAAS,GAAG,KAAK,GAAG,MAAM,IAAI,MAAM;GAEtE,IAAI,WAAW,KAAA,GACb;GAGF,UAAU,KAAK,MAAM;EACvB;EAEA,OAAO,OAAO,KAAK;EACnB,OAAO,OAAO,SAAS;EAEvB,OAAO;CACT;CAEA,IAAI,cAAc,KAAK,GACrB,OAAO,cAAc,OAAO,SAAS,MAAM,MAAM;CAGnD,OAAO,aAAa,SAAS,MAAM,cAAc,KAAK,CAAC;AACzD;AAEA,SAAS,cAEP,OACA,SACA,MACA,QAC+B;CAC/B,IAAI,OAAO,IAAI,KAAK,GAClB,OAAO,aAAa,SAAS,MAAM,cAAc;CAGnD,OAAO,IAAI,KAAK;CAChB,MAAM,YAA8C,CAAC;CAErD,KAAK,MAAM,CAAC,KAAK,SAAS,OAAO,QAAQ,KAAK,GAAG;EAE/C,MAAM,SAAS,aAAa,MAAM,SADjB,aAAa,MAAM,GACc,GAAG,MAAM;EAE3D,IAAI,WAAW,KAAA,GACb;EAGF,OAAO,eAAe,WAAW,KAAK;GACpC,cAAc;GACd,YAAY;GACZ,OAAO;GACP,UAAU;EACZ,CAAC;CACH;CAEA,OAAO,OAAO,KAAK;CACnB,OAAO,OAAO,SAAS;CAEvB,OAAO;AACT;AAEA,SAAS,gBAAgB,OAAsC;CAC7D,MAAM,OAAO,MAAM,WAAW,IAC1B,MAAM,QAAQ,IACZ,oBACA,qBACF,MAAM,OAAO,IACX,eACA;CAEN,OAAO,OAAO,OAAO;EAAE,MAAM;EAAY;EAAM,OAAO,MAAM,YAAY;CAAE,CAAC;AAC7E;AAEA,SAAS,aAAa,SAAwB,MAAc,aAAgC;CAC1F,QAAQ,YAAY,IAAI;EACtB,MAAM;EACN,SAAS,oCAAoC,KAAK,IAAI;EACtD,UAAU;EACV,MAAM,QAAQ;CAChB,CAAC;AAGH;AAEA,SAAS,iBAAiB,SAAwB,OAAsB;CACtE,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;CACrE,QAAQ,YAAY,IAAI;EACtB,MAAM,mBAAmB,QAAQ;EACjC;EACA,UAAU;EACV,MAAM,QAAQ;CAChB,CAAC;AACH;AAEA,SAAS,SAAS,MAAsB;CACtC,OAAO,SAAS,wBAAwB,6BAA6B;AACvE;AAEA,SAAS,aAAa,MAAkB,OAAe,KAAyB;CAC9E,MAAM,SAAS,KAAK,MAAM,KAAK;CAC/B,MAAM,gBAAgB,KAAK,IAAI,GAAG,KAAK,IAAI,OAAO,MAAM,CAAC;CACzD,MAAM,cAAc,KAAK,IAAI,eAAe,KAAK,IAAI,KAAK,MAAM,CAAC;CAEjE,OAAO,OAAO,OAAO;EACnB,MAAM,KAAK;EACX,OAAO,KAAK,QAAQ;EACpB,KAAK,KAAK,QAAQ;CACpB,CAAC;AACH;AAEA,SAAS,iBAAiB,QAAgB,MAAc,QAAwB;CAC9E,MAAM,YAAY,iBAAiB,MAAM,CAAC,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,MAAM,OAAO;CAE5E,OAAO,KAAK,IAAI,OAAO,QAAQ,YAAY,KAAK,IAAI,GAAG,SAAS,CAAC,CAAC;AACpE;AAEA,SAAS,aAAa,MAAc,KAAqB;CACvD,OAAO,sBAAsB,KAAK,GAAG,IAAI,GAAG,KAAK,GAAG,QAAQ,GAAG,KAAK,GAAG,KAAK,UAAU,GAAG,EAAE;AAC7F;AAGA,SAAS,cAAc,OAAwB;CAC7C,IAAI,UAAU,KAAA,GACZ,OAAO;CAGT,IAAI,WAAW,KAAK,GAClB,OAAO;CAGT,IAAI,SAAS,KAAK,GAChB,OAAO;CAGT,IAAI,iBAAiB,KACnB,OAAO;CAGT,IAAI,iBAAiB,KACnB,OAAO;CAGT,IAAI,iBAAiB,MACnB,OAAO;CAGT,OAAO,SAAS,KAAK,IAAK,MAAM,aAAa,QAAQ,WAAY,OAAO,KAAK;AAC/E;AAEA,SAAS,iBAAiB,QAAmC;CAC3D,MAAM,UAAU,CAAC,CAAC;CAElB,KAAK,IAAI,QAAQ,GAAG,QAAQ,OAAO,QAAQ,SACzC,IAAI,OAAO,WAAW,MAAM;EAC1B,IAAI,OAAO,QAAQ,OAAO,MACxB;EAGF,QAAQ,KAAK,QAAQ,CAAC;CACxB,OAAO,IAAI,OAAO,WAAW,MAC3B,QAAQ,KAAK,QAAQ,CAAC;CAI1B,OAAO;AACT"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
//#region src/heading.d.ts
|
|
2
|
+
export type HeadingDepth = 1 | 2 | 3 | 4 | 5 | 6;
|
|
3
|
+
export declare function isHeadingDepth(value: unknown): value is HeadingDepth;
|
|
4
|
+
export declare function headingDepthForTag(tagName: string): HeadingDepth | undefined;
|
|
5
|
+
//#endregion
|
|
6
|
+
//# sourceMappingURL=heading.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heading.d.mts","names":[],"sources":["../src/heading.ts"],"mappings":";YAAY;wBAEI,eAAe,iBAAiB,SAAS;wBAIzC,mBAAmB,kBAAkB"}
|
package/dist/heading.mjs
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//#region src/heading.ts
|
|
2
|
+
function isHeadingDepth(value) {
|
|
3
|
+
return value === 1 || value === 2 || value === 3 || value === 4 || value === 5 || value === 6;
|
|
4
|
+
}
|
|
5
|
+
function headingDepthForTag(tagName) {
|
|
6
|
+
switch (tagName) {
|
|
7
|
+
case "h1": return 1;
|
|
8
|
+
case "h2": return 2;
|
|
9
|
+
case "h3": return 3;
|
|
10
|
+
case "h4": return 4;
|
|
11
|
+
case "h5": return 5;
|
|
12
|
+
case "h6": return 6;
|
|
13
|
+
default: return;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
export { headingDepthForTag, isHeadingDepth };
|
|
18
|
+
|
|
19
|
+
//# sourceMappingURL=heading.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heading.mjs","names":[],"sources":["../src/heading.ts"],"sourcesContent":["export type HeadingDepth = 1 | 2 | 3 | 4 | 5 | 6;\n\nexport function isHeadingDepth(value: unknown): value is HeadingDepth {\n return value === 1 || value === 2 || value === 3 || value === 4 || value === 5 || value === 6;\n}\n\nexport function headingDepthForTag(tagName: string): HeadingDepth | undefined {\n switch (tagName) {\n case \"h1\":\n return 1;\n case \"h2\":\n return 2;\n case \"h3\":\n return 3;\n case \"h4\":\n return 4;\n case \"h5\":\n return 5;\n case \"h6\":\n return 6;\n default:\n return undefined;\n }\n}\n"],"mappings":";AAEA,SAAgB,eAAe,OAAuC;CACpE,OAAO,UAAU,KAAK,UAAU,KAAK,UAAU,KAAK,UAAU,KAAK,UAAU,KAAK,UAAU;AAC9F;AAEA,SAAgB,mBAAmB,SAA2C;CAC5E,QAAQ,SAAR;EACE,KAAK,MACH,OAAO;EACT,KAAK,MACH,OAAO;EACT,KAAK,MACH,OAAO;EACT,KAAK,MACH,OAAO;EACT,KAAK,MACH,OAAO;EACT,KAAK,MACH,OAAO;EACT,SACE;CACJ;AACF"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { HtmlAttributes, HtmlNode } from "./html.mjs";
|
|
2
|
+
//#region src/html-format.d.ts
|
|
3
|
+
export interface HtmlFormatOptions {
|
|
4
|
+
readonly closeSelfClosing?: boolean;
|
|
5
|
+
readonly collapseEmptyAttributes?: boolean;
|
|
6
|
+
readonly preferUnquotedAttributes?: boolean;
|
|
7
|
+
readonly quote?: '"' | "'";
|
|
8
|
+
readonly quoteSmart?: boolean;
|
|
9
|
+
/** Raw HTML is escaped unless it is explicitly trusted. */
|
|
10
|
+
readonly rawHtml?: "escape" | "trusted";
|
|
11
|
+
readonly tightSelfClosing?: boolean;
|
|
12
|
+
readonly voidElements?: readonly string[];
|
|
13
|
+
}
|
|
14
|
+
/** Serializes an HTML tree. JSX renders as its escaped authored fallback. */
|
|
15
|
+
export declare function formatHtml(node: HtmlNode, options?: HtmlFormatOptions): string;
|
|
16
|
+
declare class HtmlFormatter {
|
|
17
|
+
private readonly options;
|
|
18
|
+
private readonly voids;
|
|
19
|
+
constructor(options: HtmlFormatOptions);
|
|
20
|
+
format(node: HtmlNode): string;
|
|
21
|
+
element(tagName: string, values: HtmlAttributes, content: string): string;
|
|
22
|
+
private children;
|
|
23
|
+
private attribute;
|
|
24
|
+
}
|
|
25
|
+
/** Internal formatter for immutable nodes owned by one stream. */
|
|
26
|
+
export declare class CachedHtmlFormatter extends HtmlFormatter {
|
|
27
|
+
#private;
|
|
28
|
+
format(node: HtmlNode): string;
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=html-format.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html-format.d.mts","names":[],"sources":["../src/html-format.ts"],"mappings":";;iBAQiB;WACN;WACA;WACA;WACA;WACA;;WAEA;WACA;WACA;;;wBAIK,WAAW,MAAM,UAAU,UAAS;cAmC9C;mBACa;mBACA;EAEjB,YAAmB,SAAS;EAQrB,OAAO,MAAM;EAiCb,QAAQ,iBAAiB,QAAQ,gBAAgB;UA8BhD;UAUA;;;qBA0CG,4BAA4B;;EAGvB,OAAO,MAAM"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { encodeNumericCharacterReference } from "./character-reference.mjs";
|
|
2
|
+
import { InputError } from "./errors.mjs";
|
|
3
|
+
import { htmlFallback, pendingFallback } from "./html.mjs";
|
|
4
|
+
import { isNumber } from "@temelj/value";
|
|
5
|
+
//#region src/html-format.ts
|
|
6
|
+
/** Serializes an HTML tree. JSX renders as its escaped authored fallback. */
|
|
7
|
+
function formatHtml(node, options = {}) {
|
|
8
|
+
return new HtmlFormatter(options).format(node);
|
|
9
|
+
}
|
|
10
|
+
const TAG_NAME_PATTERN = /^[A-Za-z][A-Za-z0-9:-]*$/u;
|
|
11
|
+
const ATTRIBUTE_NAME_PATTERN = /[\0\t\n\f\r "&'/<=>`]/gu;
|
|
12
|
+
const UNQUOTED_ATTRIBUTE_PATTERN = /[\0\t\n\f\r "&'<=>`]/gu;
|
|
13
|
+
const DOUBLE_QUOTED_ATTRIBUTE_PATTERN = /[\0"&]/gu;
|
|
14
|
+
const SINGE_QUOTED_ATTRIBUTE_PATTERN = /[\0'&]/gu;
|
|
15
|
+
const HTML_VOID_ELEMENTS = /* @__PURE__ */ new Set([
|
|
16
|
+
"area",
|
|
17
|
+
"base",
|
|
18
|
+
"basefont",
|
|
19
|
+
"bgsound",
|
|
20
|
+
"link",
|
|
21
|
+
"meta",
|
|
22
|
+
"input",
|
|
23
|
+
"embed",
|
|
24
|
+
"param",
|
|
25
|
+
"hr",
|
|
26
|
+
"image",
|
|
27
|
+
"img",
|
|
28
|
+
"br",
|
|
29
|
+
"wbr",
|
|
30
|
+
"col",
|
|
31
|
+
"source",
|
|
32
|
+
"track",
|
|
33
|
+
"keygen"
|
|
34
|
+
]);
|
|
35
|
+
var HtmlFormatter = class {
|
|
36
|
+
options;
|
|
37
|
+
voids;
|
|
38
|
+
constructor(options) {
|
|
39
|
+
this.options = options;
|
|
40
|
+
this.voids = options.voidElements === void 0 ? HTML_VOID_ELEMENTS : new Set(options.voidElements.map((name) => name.toLowerCase()));
|
|
41
|
+
}
|
|
42
|
+
format(node) {
|
|
43
|
+
switch (node.kind) {
|
|
44
|
+
case "jsx":
|
|
45
|
+
case "expression": return escapeHtmlText(node.fallback);
|
|
46
|
+
case "text": return escapeHtmlText(node.value);
|
|
47
|
+
case "raw": return this.options.rawHtml === "trusted" ? node.value : escapeHtmlText(node.value);
|
|
48
|
+
case "comment": return formatComment(node.value);
|
|
49
|
+
case "doctype": return "<!doctype html>";
|
|
50
|
+
case "element": return this.element(node.tagName, node.attributes, this.children(node.children));
|
|
51
|
+
case "root": return this.children(node.children);
|
|
52
|
+
case "codeBlock":
|
|
53
|
+
case "math":
|
|
54
|
+
case "footnoteReference":
|
|
55
|
+
case "footnoteSection": return this.format(htmlFallback(node));
|
|
56
|
+
case "pending":
|
|
57
|
+
case "unresolvedReference": return this.children(pendingFallback(node));
|
|
58
|
+
default: return node;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
element(tagName, values, content) {
|
|
62
|
+
if (!TAG_NAME_PATTERN.test(tagName)) throw InputError.invalidHtmlTagName(tagName);
|
|
63
|
+
let opening = `<${tagName}`;
|
|
64
|
+
for (const name in values) if (Object.hasOwn(values, name)) {
|
|
65
|
+
const attribute = this.attribute(name, values[name]);
|
|
66
|
+
if (attribute.length > 0) opening += ` ${attribute}`;
|
|
67
|
+
}
|
|
68
|
+
if (this.voids.has(tagName.toLowerCase()) && content.length === 0) {
|
|
69
|
+
if (this.options.closeSelfClosing !== true) return `${opening}>`;
|
|
70
|
+
return `${opening}${this.options.tightSelfClosing === true ? "/" : " /"}>`;
|
|
71
|
+
}
|
|
72
|
+
return `${opening}>${content}</${tagName}>`;
|
|
73
|
+
}
|
|
74
|
+
children(nodes) {
|
|
75
|
+
let content = "";
|
|
76
|
+
for (const node of nodes) content += this.format(node);
|
|
77
|
+
return content;
|
|
78
|
+
}
|
|
79
|
+
attribute(name, value) {
|
|
80
|
+
if (value === false || isNumber(value) && Number.isNaN(value)) return "";
|
|
81
|
+
const encodedName = escapeAttribute(name, ATTRIBUTE_NAME_PATTERN);
|
|
82
|
+
if (value === true) return encodedName;
|
|
83
|
+
const serialized = Array.isArray(value) ? value.join(" ") : String(value);
|
|
84
|
+
if (this.options.collapseEmptyAttributes === true && serialized.length === 0) return encodedName;
|
|
85
|
+
if (this.options.preferUnquotedAttributes === true && serialized.length > 0 && !/[\0\t\n\f\r "'`=<>]/u.test(serialized)) return `${encodedName}=${escapeAttribute(serialized, UNQUOTED_ATTRIBUTE_PATTERN)}`;
|
|
86
|
+
const preferred = this.options.quote ?? "\"";
|
|
87
|
+
const alternative = preferred === "\"" ? "'" : "\"";
|
|
88
|
+
const quote = this.options.quoteSmart === true && count(serialized, alternative) < count(serialized, preferred) ? alternative : preferred;
|
|
89
|
+
return `${encodedName}=${quote}${escapeAttribute(serialized, quote === "\"" ? DOUBLE_QUOTED_ATTRIBUTE_PATTERN : SINGE_QUOTED_ATTRIBUTE_PATTERN)}${quote}`;
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
/** Internal formatter for immutable nodes owned by one stream. */
|
|
93
|
+
var CachedHtmlFormatter = class extends HtmlFormatter {
|
|
94
|
+
#cache = /* @__PURE__ */ new WeakMap();
|
|
95
|
+
format(node) {
|
|
96
|
+
const hit = this.#cache.get(node);
|
|
97
|
+
if (hit !== void 0) return hit;
|
|
98
|
+
const html = super.format(node);
|
|
99
|
+
this.#cache.set(node, html);
|
|
100
|
+
return html;
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
function formatComment(value) {
|
|
104
|
+
return `<!--${value.replace(/^>|^->|<!--|-->|--!>|<!-$/gu, (match) => escapeComment(match))}-->`;
|
|
105
|
+
}
|
|
106
|
+
function escapeComment(value) {
|
|
107
|
+
return value.replace(/[<>]/gu, (character) => character === "<" ? "<" : ">");
|
|
108
|
+
}
|
|
109
|
+
function escapeHtmlText(value) {
|
|
110
|
+
return /[&<]/u.test(value) ? value.replace(/[&<]/gu, (character) => character === "&" ? "&" : "<") : value;
|
|
111
|
+
}
|
|
112
|
+
function escapeAttribute(value, pattern) {
|
|
113
|
+
pattern.lastIndex = 0;
|
|
114
|
+
return pattern.test(value) ? value.replace(pattern, encodeCharacterReference) : value;
|
|
115
|
+
}
|
|
116
|
+
function encodeCharacterReference(character) {
|
|
117
|
+
return character === "\0" ? "�" : encodeNumericCharacterReference(character.codePointAt(0) ?? 0);
|
|
118
|
+
}
|
|
119
|
+
function count(value, character) {
|
|
120
|
+
let result = 0;
|
|
121
|
+
for (const candidate of value) if (candidate === character) result++;
|
|
122
|
+
return result;
|
|
123
|
+
}
|
|
124
|
+
//#endregion
|
|
125
|
+
export { CachedHtmlFormatter, formatHtml };
|
|
126
|
+
|
|
127
|
+
//# sourceMappingURL=html-format.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html-format.mjs","names":["exhaustive"],"sources":["../src/html-format.ts"],"sourcesContent":["import { isNumber } from \"@temelj/value\";\n\nimport type { HtmlAttributes, HtmlAttributeValue, HtmlNode } from \"./html.ts\";\n\nimport { encodeNumericCharacterReference } from \"./character-reference.ts\";\nimport { InputError } from \"./errors.ts\";\nimport { htmlFallback, pendingFallback } from \"./html.ts\";\n\nexport interface HtmlFormatOptions {\n readonly closeSelfClosing?: boolean;\n readonly collapseEmptyAttributes?: boolean;\n readonly preferUnquotedAttributes?: boolean;\n readonly quote?: '\"' | \"'\";\n readonly quoteSmart?: boolean;\n /** Raw HTML is escaped unless it is explicitly trusted. */\n readonly rawHtml?: \"escape\" | \"trusted\";\n readonly tightSelfClosing?: boolean;\n readonly voidElements?: readonly string[];\n}\n\n/** Serializes an HTML tree. JSX renders as its escaped authored fallback. */\nexport function formatHtml(node: HtmlNode, options: HtmlFormatOptions = {}): string {\n return new HtmlFormatter(options).format(node);\n}\n\nconst TAG_NAME_PATTERN = /^[A-Za-z][A-Za-z0-9:-]*$/u;\n\nconst ATTRIBUTE_NAME_PATTERN = /[\\0\\t\\n\\f\\r \"&'/<=>`]/gu;\n\nconst UNQUOTED_ATTRIBUTE_PATTERN = /[\\0\\t\\n\\f\\r \"&'<=>`]/gu;\n\nconst DOUBLE_QUOTED_ATTRIBUTE_PATTERN = /[\\0\"&]/gu;\n\nconst SINGE_QUOTED_ATTRIBUTE_PATTERN = /[\\0'&]/gu;\n\nconst HTML_VOID_ELEMENTS: ReadonlySet<string> = new Set([\n \"area\",\n \"base\",\n \"basefont\",\n \"bgsound\",\n \"link\",\n \"meta\",\n \"input\",\n \"embed\",\n \"param\",\n \"hr\",\n \"image\",\n \"img\",\n \"br\",\n \"wbr\",\n \"col\",\n \"source\",\n \"track\",\n \"keygen\",\n]);\n\nclass HtmlFormatter {\n private readonly options: HtmlFormatOptions;\n private readonly voids: ReadonlySet<string>;\n\n public constructor(options: HtmlFormatOptions) {\n this.options = options;\n this.voids =\n options.voidElements === undefined\n ? HTML_VOID_ELEMENTS\n : new Set(options.voidElements.map((name) => name.toLowerCase()));\n }\n\n public format(node: HtmlNode): string {\n switch (node.kind) {\n case \"jsx\":\n case \"expression\":\n return escapeHtmlText(node.fallback);\n case \"text\":\n return escapeHtmlText(node.value);\n case \"raw\":\n return this.options.rawHtml === \"trusted\" ? node.value : escapeHtmlText(node.value);\n case \"comment\":\n return formatComment(node.value);\n case \"doctype\":\n return \"<!doctype html>\";\n case \"element\":\n return this.element(node.tagName, node.attributes, this.children(node.children));\n case \"root\":\n return this.children(node.children);\n case \"codeBlock\":\n case \"math\":\n case \"footnoteReference\":\n case \"footnoteSection\":\n return this.format(htmlFallback(node));\n case \"pending\":\n case \"unresolvedReference\":\n return this.children(pendingFallback(node));\n default: {\n const exhaustive: never = node;\n\n return exhaustive;\n }\n }\n }\n\n public element(tagName: string, values: HtmlAttributes, content: string): string {\n if (!TAG_NAME_PATTERN.test(tagName)) {\n throw InputError.invalidHtmlTagName(tagName);\n }\n\n let opening = `<${tagName}`;\n\n for (const name in values) {\n if (Object.hasOwn(values, name)) {\n const attribute = this.attribute(name, values[name]);\n\n if (attribute.length > 0) {\n opening += ` ${attribute}`;\n }\n }\n }\n\n const isVoid = this.voids.has(tagName.toLowerCase()) && content.length === 0;\n\n if (isVoid) {\n if (this.options.closeSelfClosing !== true) {\n return `${opening}>`;\n }\n\n return `${opening}${this.options.tightSelfClosing === true ? \"/\" : \" /\"}>`;\n }\n\n return `${opening}>${content}</${tagName}>`;\n }\n\n private children(nodes: readonly HtmlNode[]): string {\n let content = \"\";\n\n for (const node of nodes) {\n content += this.format(node);\n }\n\n return content;\n }\n\n private attribute(name: string, value: HtmlAttributeValue): string {\n if (value === false || (isNumber(value) && Number.isNaN(value))) {\n return \"\";\n }\n\n const encodedName = escapeAttribute(name, ATTRIBUTE_NAME_PATTERN);\n\n if (value === true) {\n return encodedName;\n }\n\n const serialized = Array.isArray(value) ? value.join(\" \") : String(value);\n\n if (this.options.collapseEmptyAttributes === true && serialized.length === 0) {\n return encodedName;\n }\n\n if (\n this.options.preferUnquotedAttributes === true &&\n serialized.length > 0 &&\n !/[\\0\\t\\n\\f\\r \"'`=<>]/u.test(serialized)\n ) {\n return `${encodedName}=${escapeAttribute(serialized, UNQUOTED_ATTRIBUTE_PATTERN)}`;\n }\n\n const preferred = this.options.quote ?? '\"';\n const alternative = preferred === '\"' ? \"'\" : '\"';\n\n const quote =\n this.options.quoteSmart === true &&\n count(serialized, alternative) < count(serialized, preferred)\n ? alternative\n : preferred;\n\n const pattern =\n quote === '\"' ? DOUBLE_QUOTED_ATTRIBUTE_PATTERN : SINGE_QUOTED_ATTRIBUTE_PATTERN;\n\n return `${encodedName}=${quote}${escapeAttribute(serialized, pattern)}${quote}`;\n }\n}\n\n/** Internal formatter for immutable nodes owned by one stream. */\nexport class CachedHtmlFormatter extends HtmlFormatter {\n readonly #cache = new WeakMap<HtmlNode, string>();\n\n public override format(node: HtmlNode): string {\n const hit = this.#cache.get(node);\n\n if (hit !== undefined) {\n return hit;\n }\n\n const html = super.format(node);\n\n this.#cache.set(node, html);\n\n return html;\n }\n}\n\nfunction formatComment(value: string): string {\n return `<!--${value.replace(/^>|^->|<!--|-->|--!>|<!-$/gu, (match) => escapeComment(match))}-->`;\n}\n\nfunction escapeComment(value: string): string {\n return value.replace(/[<>]/gu, (character) => (character === \"<\" ? \"<\" : \">\"));\n}\n\nfunction escapeHtmlText(value: string): string {\n return /[&<]/u.test(value)\n ? value.replace(/[&<]/gu, (character) => (character === \"&\" ? \"&\" : \"<\"))\n : value;\n}\n\nfunction escapeAttribute(value: string, pattern: RegExp): string {\n // Shared global patterns must start at the beginning for each attribute.\n pattern.lastIndex = 0;\n\n return pattern.test(value) ? value.replace(pattern, encodeCharacterReference) : value;\n}\n\nfunction encodeCharacterReference(character: string): string {\n return character === \"\\0\"\n ? \"�\"\n : encodeNumericCharacterReference(character.codePointAt(0) ?? 0);\n}\n\nfunction count(value: string, character: string): number {\n let result = 0;\n\n for (const candidate of value) {\n if (candidate === character) {\n result++;\n }\n }\n\n return result;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { FootnoteNumbering, FootnoteOccurrence } from "./footnote-numbering.mjs";
|
|
2
|
+
import { DefinitionNode, DocumentNode, FootnoteDefinitionNode, FootnoteReferenceNode, ListItemNode, MdxNode } from "./model.mjs";
|
|
3
|
+
import { HtmlFootnoteSectionNode, HtmlNode, HtmlRootNode } from "./html.mjs";
|
|
4
|
+
import { SourceFile } from "./source.mjs";
|
|
5
|
+
//#region src/html-lower.d.ts
|
|
6
|
+
export interface HtmlRenderOptions {
|
|
7
|
+
readonly allowUnsafeUrls?: boolean;
|
|
8
|
+
readonly clobberPrefix?: string;
|
|
9
|
+
readonly footnoteBackLabel?: string | ((referenceIndex: number, rereferenceIndex: number) => string);
|
|
10
|
+
readonly footnoteLabel?: string;
|
|
11
|
+
readonly footnoteLabelTagName?: string;
|
|
12
|
+
/** The file that node origins refer to. Inert fallbacks then keep authored text. */
|
|
13
|
+
readonly source?: SourceFile;
|
|
14
|
+
/**
|
|
15
|
+
* Rewrites link and image URLs. `sanitized` is the default policy result, or
|
|
16
|
+
* `undefined` when the default removes the URL; returning `undefined` removes it.
|
|
17
|
+
*/
|
|
18
|
+
readonly urlTransform?: (url: string, kind: "image" | "link", sanitized: string | undefined) => string | undefined;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Lowered HTML by node identity, separately for tight and loose list context. A
|
|
22
|
+
* cache is valid while link definitions are unchanged. Subtrees that depend on
|
|
23
|
+
* footnote numbering or a replacement are never cached.
|
|
24
|
+
*/
|
|
25
|
+
export interface HtmlLoweringCache {
|
|
26
|
+
readonly loose: WeakMap<MdxNode, LoweredHtml>;
|
|
27
|
+
readonly tight: WeakMap<MdxNode, LoweredHtml>;
|
|
28
|
+
/** A growing list's lowered children, by the item they end with. */
|
|
29
|
+
readonly lists: WeakMap<ListItemNode, ListPrefix>;
|
|
30
|
+
}
|
|
31
|
+
/** The wrapped children of a list's first `index + 1` items. */
|
|
32
|
+
interface ListPrefix {
|
|
33
|
+
readonly index: number;
|
|
34
|
+
readonly loose: boolean;
|
|
35
|
+
readonly spread: boolean;
|
|
36
|
+
readonly tasks: boolean;
|
|
37
|
+
readonly children: SequencePrefix;
|
|
38
|
+
}
|
|
39
|
+
export declare function createHtmlLoweringCache(): HtmlLoweringCache;
|
|
40
|
+
/**
|
|
41
|
+
* What lowering resolves against. Batch lowering derives a scope from one
|
|
42
|
+
* document; a stream assembles one from its settled blocks and open tail.
|
|
43
|
+
*/
|
|
44
|
+
export interface LoweringScope {
|
|
45
|
+
readonly definition: (identifier: string) => DefinitionNode | undefined;
|
|
46
|
+
readonly footnote: (identifier: string) => FootnoteDefinitionNode | undefined;
|
|
47
|
+
readonly options: HtmlRenderOptions;
|
|
48
|
+
/** The numbering of a reference to a defined footnote. */
|
|
49
|
+
readonly occurrence: (node: FootnoteReferenceNode) => FootnoteOccurrence | undefined;
|
|
50
|
+
/** Missing references lower to `unresolvedReference` nodes instead of authored text. */
|
|
51
|
+
readonly provisional?: boolean;
|
|
52
|
+
readonly cache?: HtmlLoweringCache;
|
|
53
|
+
/** Lowers one node differently, such as the open leaf of a stream. */
|
|
54
|
+
readonly replace?: (node: MdxNode) => readonly HtmlNode[] | undefined;
|
|
55
|
+
}
|
|
56
|
+
type LoweredHtml = HtmlNode | readonly HtmlNode[] | undefined;
|
|
57
|
+
export declare function lowerHtml(document: DocumentNode, options?: HtmlRenderOptions): HtmlRootNode;
|
|
58
|
+
/**
|
|
59
|
+
* Lowers sibling nodes in one scope. `previous` is the sibling before them,
|
|
60
|
+
* because text after a hard break drops its leading spaces.
|
|
61
|
+
*/
|
|
62
|
+
export declare function lowerNodes(nodes: readonly MdxNode[], scope: LoweringScope, previous?: MdxNode): HtmlNode[];
|
|
63
|
+
/** Separates top-level blocks with line endings, like a document root. */
|
|
64
|
+
export declare function joinBlocks(nodes: readonly HtmlNode[]): HtmlNode[];
|
|
65
|
+
/** Footnote reference nodes in document order. */
|
|
66
|
+
export declare function footnoteReferences(node: MdxNode): FootnoteReferenceNode[];
|
|
67
|
+
/** The generated section for the numbered footnotes, or `undefined` when none is referenced. */
|
|
68
|
+
export declare function lowerFootnoteSection(numbering: FootnoteNumbering, scope: LoweringScope): HtmlFootnoteSectionNode | undefined;
|
|
69
|
+
/** A prefix of a child sequence: full fragments, then the nodes after them. */
|
|
70
|
+
interface SequencePrefix {
|
|
71
|
+
readonly fragments: readonly HtmlRootNode[];
|
|
72
|
+
readonly rest: readonly HtmlNode[];
|
|
73
|
+
readonly size: number;
|
|
74
|
+
}
|
|
75
|
+
export declare function sanitizeUrl(value: string, options: HtmlRenderOptions, use: "image" | "link"): string | undefined;
|
|
76
|
+
//#endregion
|
|
77
|
+
export {};
|
|
78
|
+
//# sourceMappingURL=html-lower.d.mts.map
|