@temelj/mdx 0.15.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 +2 -0
- package/dist/compiler.mjs +2 -22
- package/dist/compiler.mjs.map +1 -1
- 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 +35 -10
- package/dist/frontmatter.d.mts.map +1 -1
- package/dist/frontmatter.mjs +97 -175
- package/dist/frontmatter.mjs.map +1 -1
- package/dist/mod.d.mts +2 -1
- package/dist/mod.mjs +3 -2
- package/dist/parser/materialize.mjs +1 -1
- package/dist/parser/materialize.mjs.map +1 -1
- package/dist/source-text.d.mts +2 -2
- package/dist/source-text.d.mts.map +1 -1
- package/dist/source-text.mjs +9 -5
- package/dist/source-text.mjs.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"materialize.mjs","names":[],"sources":["../../src/parser/materialize.ts"],"sourcesContent":["import type { Diagnostic } from \"../diagnostics.ts\";\nimport type {\n DirectiveAttribute,\n DirectiveLabelNode,\n ListItemNode,\n DocumentNode,\n FlowContent,\n JsxTextElementNode,\n PhrasingContent,\n} from \"../model.ts\";\nimport type { SourceRange } from \"../ranges.ts\";\nimport type { SourceText } from \"../source-text.ts\";\nimport type { SourceFile, SourceSpan } from \"../source.ts\";\nimport type { ResolvedSyntaxOptions } from \"../syntax-options.ts\";\nimport type {\n BlockSyntax,\n DirectiveAttributeSyntax,\n ListItemSyntax,\n ListSyntax,\n JsxSyntax,\n} from \"./block-syntax.ts\";\nimport type { ResolvedParserLimits } from \"./config.ts\";\nimport type { DefinitionLookup, InlineSyntax } from \"./inline-syntax.ts\";\nimport type {\n CachedListPrefix,\n CachedMaterialization,\n MaterializeCache,\n} from \"./materialize-cache.ts\";\n\nimport { createDiagnostic, DiagnosticBag } from \"../diagnostics.ts\";\nimport { decodeFrontmatter } from \"../frontmatter.ts\";\nimport { normalizeIdentifier } from \"../identifier.ts\";\nimport { nodeText } from \"../model.ts\";\nimport { sourceText } from \"../source.ts\";\nimport { parseFlowRange } from \"./block-parser.ts\";\nimport { InlineInput } from \"./inline-input.ts\";\nimport { parseInline } from \"./inline-parser.ts\";\nimport { isFlowJsxChildren, jsxParts, type JsxParts } from \"./materialize-jsx.ts\";\n\nexport interface MaterializedBlock {\n readonly references: readonly string[];\n readonly nodeCount: number;\n readonly node: FlowContent;\n}\n\nexport interface MaterializeOptions {\n /** Definitions already known to a stream, including definitions in other blocks. */\n readonly definitionLookup?: DefinitionLookup;\n /**\n * Keeps references whose definitions are missing, for a stream where the\n * definitions may still arrive. Otherwise they become authored text.\n */\n readonly keepReferences?: boolean;\n /** Open embedded syntax at the end of the source is inert instead of invalid. */\n readonly allowIncomplete?: boolean;\n readonly cache?: MaterializeCache;\n /**\n * The range of a stream's open leaf. A stream renders that leaf itself, so it\n * materializes as an empty placeholder with the same kind and origin.\n */\n readonly open?: SourceRange;\n}\n\nexport type StrictMaterializeResult =\n | Readonly<{\n kind: \"ok\";\n document: DocumentNode;\n blocks: readonly MaterializedBlock[];\n diagnostics: readonly Diagnostic[];\n }>\n | Readonly<{ kind: \"invalid\"; diagnostics: readonly [Diagnostic, ...Diagnostic[]] }>\n | Readonly<{\n kind: \"limitExceeded\";\n limit: \"maximumNestingDepth\" | \"maximumNodes\";\n diagnostics: readonly [Diagnostic, ...Diagnostic[]];\n }>;\n\ninterface PreparedFlowJsx {\n readonly parts: JsxParts;\n readonly children: readonly BlockSyntax[] | undefined;\n}\n\ninterface MaterializeContext {\n readonly definitionLookup: DefinitionLookup;\n references: Set<string>;\n readonly definitions: ReadonlySet<string>;\n readonly diagnostics: DiagnosticBag;\n readonly file: SourceFile;\n readonly footnotes: ReadonlySet<string>;\n readonly limits: ResolvedParserLimits;\n readonly syntax: ResolvedSyntaxOptions;\n readonly allowIncomplete: boolean;\n readonly keepReferences: boolean;\n readonly cache: MaterializeCache | undefined;\n readonly open: SourceRange | undefined;\n readonly flowJsx: Map<JsxSyntax, PreparedFlowJsx>;\n grammarSource: SourceText | undefined;\n maximumDepth: number;\n /** Leniency at the end of the source makes the result depend on later input. */\n usedEndOfInput: boolean;\n depth: number;\n nodes: number;\n authoredInvalid: boolean;\n limit: \"maximumNestingDepth\" | \"maximumNodes\" | undefined;\n}\n\nexport function materializeDocument(\n file: SourceFile,\n blocks: readonly BlockSyntax[],\n syntax: ResolvedSyntaxOptions,\n limits: ResolvedParserLimits,\n options: MaterializeOptions = {},\n): StrictMaterializeResult {\n const indexes: DependencyIndexes = { definitions: new Set(), footnotes: new Set() };\n const context = createContext(file, syntax, limits, options, indexes);\n\n // Index flow JSX before references are materialized; its parsed children are reused below.\n if (!context.keepReferences) {\n collectIndexes(blocks, context, indexes);\n }\n\n const children: FlowContent[] = [];\n const materializedBlocks: MaterializedBlock[] = [];\n\n for (const block of blocks) {\n if (context.limit !== undefined) {\n break;\n }\n\n const before = context.nodes;\n context.references = new Set();\n const child = materializeBlock(block, context);\n\n if (child !== undefined) {\n children.push(child);\n materializedBlocks.push(\n Object.freeze({\n node: child,\n nodeCount: context.nodes - before,\n references: [...context.references],\n }),\n );\n }\n }\n\n if (context.limit !== undefined) {\n const diagnostic = limitDiagnostic(file, context.limit);\n const diagnostics: readonly [Diagnostic] = Object.freeze([diagnostic]);\n\n return Object.freeze({\n kind: \"limitExceeded\",\n limit: context.limit,\n diagnostics,\n });\n }\n\n const diagnostics = context.diagnostics.snapshot();\n\n if (\n context.authoredInvalid ||\n diagnostics.some((diagnostic) => diagnostic.severity === \"error\")\n ) {\n const errors = diagnostics.filter((diagnostic) => diagnostic.severity === \"error\");\n\n if (errors.length === 0) {\n throw new Error(\"Invalid MDX draft did not produce an error diagnostic\");\n }\n\n const [first, ...rest] = errors;\n\n if (first === undefined) {\n throw new Error(\"Invalid MDX diagnostic collection changed unexpectedly\");\n }\n\n const invalidDiagnostics: readonly [Diagnostic, ...Diagnostic[]] = Object.freeze([\n first,\n ...rest,\n ]);\n\n return Object.freeze({\n kind: \"invalid\",\n diagnostics: invalidDiagnostics,\n });\n }\n\n const document = counted<DocumentNode>(context, {\n kind: \"document\",\n children,\n origin: range(0, file.length),\n });\n\n if (document === undefined || context.limit !== undefined) {\n const diagnostic = limitDiagnostic(file, \"maximumNodes\");\n const diagnostics: readonly [Diagnostic] = Object.freeze([diagnostic]);\n\n return Object.freeze({\n kind: \"limitExceeded\",\n limit: \"maximumNodes\",\n diagnostics,\n });\n }\n\n return Object.freeze({\n kind: \"ok\",\n document,\n blocks: Object.freeze(materializedBlocks),\n diagnostics,\n });\n}\n\nexport interface MaterializedPhrasing {\n readonly nodes: readonly PhrasingContent[];\n readonly nodeCount: number;\n}\n\n/** Materialized phrasing by inline syntax identity, valid while references are kept. */\nexport type PhrasingCache = WeakMap<InlineSyntax, MaterializedPhrasing>;\n\n/**\n * Materializes parsed inline syntax that a stream renders outside a block,\n * keeping references.\n */\nexport function materializePhrasing(\n file: SourceFile,\n nodes: readonly InlineSyntax[],\n syntax: ResolvedSyntaxOptions,\n limits: ResolvedParserLimits,\n): MaterializedPhrasing {\n const context = createContext(file, syntax, limits, {\n keepReferences: true,\n allowIncomplete: true,\n });\n\n const children: PhrasingContent[] = [];\n\n for (const node of nodes) {\n const child = materializeInlineNode(node, context);\n\n if (child !== undefined) {\n children.push(child);\n }\n }\n\n return { nodes: children, nodeCount: context.nodes };\n}\n\n/** Independent inline groups share one context while retaining their own node budgets. */\nexport function materializePhrasingGroups(\n file: SourceFile,\n nodes: readonly InlineSyntax[],\n syntax: ResolvedSyntaxOptions,\n limits: ResolvedParserLimits,\n cache: PhrasingCache,\n): readonly MaterializedPhrasing[] {\n const context = createContext(file, syntax, limits, {\n keepReferences: true,\n allowIncomplete: true,\n });\n\n return nodes.map((node) => {\n const hit = cache.get(node);\n\n if (hit !== undefined) {\n return hit;\n }\n\n context.nodes = 0;\n context.limit = undefined;\n context.usedEndOfInput = false;\n\n const child = materializeInlineNode(node, context);\n\n const materialized = {\n nodes: child === undefined ? [] : [child],\n nodeCount: context.nodes,\n };\n\n if (context.limit === undefined && !context.usedEndOfInput) {\n cache.set(node, materialized);\n }\n\n return materialized;\n });\n}\n\n/** Only whitespace and at most one line ending follow `offset`. */\nfunction reachesEndOfInput(file: SourceFile, offset: number): boolean {\n return /^[ \\t]*(?:\\r\\n?|\\n)?[ \\t]*$/u.test(file.slice({ start: offset, end: file.length }));\n}\n\nconst emptyIndexes: DependencyIndexes = { definitions: new Set(), footnotes: new Set() };\n\nfunction createContext(\n file: SourceFile,\n syntax: ResolvedSyntaxOptions,\n limits: ResolvedParserLimits,\n options: MaterializeOptions,\n indexes: DependencyIndexes = emptyIndexes,\n): MaterializeContext {\n return {\n definitions: indexes.definitions,\n definitionLookup: options.definitionLookup ?? indexes.definitions,\n references: new Set(),\n diagnostics: new DiagnosticBag(),\n file,\n footnotes: indexes.footnotes,\n limits,\n syntax,\n // Resolution depends on the definitions, so only reference-keeping output is cached.\n cache: options.keepReferences === true ? options.cache : undefined,\n flowJsx: new Map(),\n grammarSource: undefined,\n maximumDepth: 0,\n usedEndOfInput: false,\n allowIncomplete: options.allowIncomplete ?? false,\n keepReferences: options.keepReferences ?? false,\n open: options.open,\n depth: 0,\n nodes: 0,\n authoredInvalid: false,\n limit: undefined,\n };\n}\n\nfunction materializeBlock(\n block: BlockSyntax,\n context: MaterializeContext,\n): FlowContent | undefined {\n return cached(context.cache?.blocks, block, context, () =>\n materializeBlockContent(block, context),\n );\n}\n\n/**\n * Replays a cached subtree, or materializes and caches it. Subtrees with\n * diagnostics or input-dependent leniency are never cached.\n */\nfunction cached<TKey extends BlockSyntax | ListItemSyntax, TNode>(\n cache: WeakMap<TKey, CachedMaterialization<TNode>> | undefined,\n key: TKey,\n context: MaterializeContext,\n materialize: () => TNode | undefined,\n): TNode | undefined {\n if (cache === undefined) {\n return materialize();\n }\n\n const hit = cache.get(key);\n\n if (\n hit !== undefined &&\n context.depth + hit.depth <= context.limits.maximumNestingDepth &&\n context.nodes + hit.nodeCount <= context.limits.maximumNodes\n ) {\n for (const identifier of hit.references) {\n context.references.add(identifier);\n }\n\n context.nodes += hit.nodeCount;\n context.maximumDepth = Math.max(context.maximumDepth, context.depth + hit.depth);\n\n return hit.node;\n }\n\n const references = context.references;\n context.references = new Set();\n const nodes = context.nodes;\n const diagnostics = context.diagnostics.size;\n const outerDepth = context.maximumDepth;\n const outerEndOfInput = context.usedEndOfInput;\n context.maximumDepth = context.depth;\n context.usedEndOfInput = false;\n const node = materialize();\n\n if (\n node !== undefined &&\n context.diagnostics.size === diagnostics &&\n !context.authoredInvalid &&\n context.limit === undefined &&\n !context.usedEndOfInput\n ) {\n cache.set(key, {\n node,\n nodeCount: context.nodes - nodes,\n depth: context.maximumDepth - context.depth,\n references: [...context.references],\n });\n }\n\n for (const identifier of context.references) {\n references.add(identifier);\n }\n\n context.references = references;\n context.maximumDepth = Math.max(outerDepth, context.maximumDepth);\n context.usedEndOfInput ||= outerEndOfInput;\n\n return node;\n}\n\nfunction materializeBlockContent(\n block: BlockSyntax,\n context: MaterializeContext,\n): FlowContent | undefined {\n if (!enter(context)) {\n return;\n }\n\n try {\n const origin = range(block.range.start, block.range.end);\n\n if (isOpenLeaf(block, context)) {\n context.usedEndOfInput = true;\n\n return counted(context, openLeafPlaceholder(block, origin));\n }\n\n switch (block.kind) {\n case \"paragraph\":\n return counted(context, {\n kind: \"paragraph\",\n children: materializeInline(block.input, context),\n origin,\n });\n case \"heading\":\n return counted(context, {\n kind: \"heading\",\n depth: block.depth,\n children: materializeInline(block.input, context),\n origin,\n });\n case \"code\":\n return counted(context, {\n kind: \"codeBlock\",\n value: trimFinalLineEnding(inlineInputText(context.file, block.value)),\n language: sliceOptional(context.file, block.language),\n meta: sliceOptional(context.file, block.meta),\n origin,\n });\n case \"thematicBreak\":\n return counted(context, { kind: \"thematicBreak\", origin });\n case \"blockQuote\":\n return counted(context, {\n kind: \"blockquote\",\n children: materializeBlocks(block.children, context),\n origin,\n });\n case \"list\":\n return counted(context, {\n kind: \"list\",\n ordered: block.ordered,\n spread: block.spread,\n start: block.start ?? 1,\n children: materializeListItems(block, context),\n origin,\n });\n case \"definition\":\n return counted(context, {\n kind: \"definition\",\n identifier: normalizeIdentifier(block.identifier),\n url: context.file.semanticSlice(block.destination),\n title: semanticSliceOptional(context.file, block.title),\n origin,\n });\n case \"footnoteDefinition\":\n return counted(context, {\n kind: \"footnoteDefinition\",\n identifier: normalizeIdentifier(block.identifier),\n label: block.identifier,\n children: materializeBlocks(block.children, context),\n origin,\n });\n case \"rawHtml\":\n return counted(context, {\n kind: \"rawHtmlBlock\",\n value: context.file.semanticSlice(block.range),\n origin,\n });\n case \"frontmatter\": {\n const rawValue = trimFinalLineEnding(context.file.slice(block.value));\n const valueOrigin = range(block.value.start, block.value.start + rawValue.length);\n\n const data = decodeFrontmatter({\n diagnostics: context.diagnostics,\n format: block.format,\n source: rawValue,\n span: span(context.file, valueOrigin.start, valueOrigin.end),\n });\n\n return counted(context, {\n kind: \"frontmatter\",\n format: block.format,\n value: rawValue.replace(/\\r\\n?|\\n/gu, \"\\n\"),\n data,\n valueOrigin,\n origin,\n });\n }\n\n case \"directive\":\n return counted(context, {\n kind: \"containerDirective\",\n name: block.name,\n attributes: materializeDirectiveAttributes(block.attributes),\n label: materializeDirectiveLabel(block.label, context),\n children: materializeBlocks(block.children, context),\n origin,\n });\n case \"leafDirective\":\n return counted(context, {\n kind: \"leafDirective\",\n name: block.name,\n attributes: materializeDirectiveAttributes(block.attributes),\n label: materializeDirectiveLabel(block.label, context),\n origin,\n });\n case \"math\": {\n const value = trimFinalLineEnding(inlineInputText(context.file, block.value));\n\n return counted(\n context,\n block.format === \"tex\"\n ? { kind: \"displayMath\", value, format: \"tex\", origin }\n : {\n kind: \"displayMath\",\n value,\n format: \"dollar\",\n meta: sliceOptional(context.file, block.meta),\n origin,\n },\n );\n }\n\n case \"table\":\n return counted(context, {\n kind: \"table\",\n alignments: block.alignments,\n children: block.rows.map((row) => ({\n kind: \"tableRow\",\n children: row.cells.map((cell) => {\n const cellRange = inlineSegmentsRange(cell, row.range);\n\n return {\n kind: \"tableCell\",\n children: materializeInline(cell, context),\n origin: range(cellRange.start, cellRange.end),\n };\n }),\n origin: range(row.range.start, row.range.end),\n })),\n origin,\n });\n case \"expression\": {\n const authored = context.file.slice(block.range);\n\n return counted(context, {\n kind: \"blockExpression\",\n code: authored.slice(authored.indexOf(\"{\") + 1, authored.lastIndexOf(\"}\")),\n origin,\n });\n }\n\n case \"esm\":\n return counted(context, {\n kind: \"esm\",\n code: trimFinalLineEnding(context.file.slice(block.range)),\n origin,\n });\n case \"jsx\":\n return counted(context, materializeFlowJsx(block, context));\n case \"invalidMdx\":\n if (\n context.allowIncomplete &&\n block.state === \"incomplete\" &&\n reachesEndOfInput(context.file, block.range.end)\n ) {\n context.usedEndOfInput = true;\n\n return counted(context, {\n kind: \"rawHtmlBlock\",\n value: context.file.slice(block.range),\n origin,\n });\n }\n\n context.authoredInvalid = true;\n context.diagnostics.add({\n code: `mdx.${block.syntax}.invalid`,\n message: `Invalid or unfinished MDX ${block.syntax}`,\n severity: \"error\",\n span: span(context.file, origin.start, origin.end),\n });\n\n return;\n }\n } finally {\n context.depth--;\n }\n}\n\nfunction isOpenLeaf(block: BlockSyntax, context: MaterializeContext): boolean {\n return (\n context.open !== undefined &&\n block.range.start === context.open.start &&\n block.range.end === context.open.end &&\n (block.kind === \"paragraph\" ||\n block.kind === \"code\" ||\n block.kind === \"math\" ||\n block.kind === \"invalidMdx\")\n );\n}\n\nfunction openLeafPlaceholder(block: BlockSyntax, origin: SourceRange): FlowContent {\n switch (block.kind) {\n case \"paragraph\":\n return { kind: \"paragraph\", children: [], origin };\n case \"code\":\n return { kind: \"codeBlock\", value: \"\", origin };\n case \"math\":\n return { kind: \"displayMath\", value: \"\", format: \"dollar\", origin };\n default:\n return { kind: \"rawHtmlBlock\", value: \"\", origin };\n }\n}\n\n/**\n * Materializes list items. A growing list reuses its unchanged leading items\n * as one prefix, so an append materializes only the items after it. The list\n * that contains a stream's open leaf is rebuilt on every append and never\n * cached, so its children array is extended in place instead of copied.\n */\nfunction materializeListItems(list: ListSyntax, context: MaterializeContext): ListItemNode[] {\n const items = list.items;\n const closing = list.closing ?? [];\n const count = items.length + closing.length;\n const itemAt = (index: number): ListItemSyntax => items[index] ?? closing[index - items.length];\n const open = context.open !== undefined && containsRange(list.range, context.open);\n const cache = context.cache;\n const prefix = cache === undefined ? undefined : listPrefix(count, itemAt, cache.lists);\n\n const reused =\n prefix !== undefined &&\n context.depth + prefix.depth <= context.limits.maximumNestingDepth &&\n context.nodes + prefix.nodeCount <= context.limits.maximumNodes\n ? prefix\n : undefined;\n\n let children: ListItemNode[] = [];\n\n if (reused !== undefined && reused.live && open) {\n children = reused.nodes;\n children.length = reused.length;\n } else if (reused !== undefined) {\n children = reused.nodes.slice(0, reused.length);\n }\n\n let nodeCount = reused?.nodeCount ?? 0;\n let depth = reused?.depth ?? 0;\n let cacheable = true;\n const references = new Set(reused?.references);\n\n if (reused !== undefined) {\n for (const identifier of reused.references) {\n context.references.add(identifier);\n }\n\n context.nodes += reused.nodeCount;\n context.maximumDepth = Math.max(context.maximumDepth, context.depth + reused.depth);\n }\n\n for (let index = (reused?.index ?? -1) + 1; index < count; index++) {\n const item = itemAt(index);\n\n const node = cached(cache?.items, item, context, (): ListItemNode => ({\n kind: \"listItem\",\n checked: item.checked,\n spread: item.spread,\n children: materializeBlocks(item.children, context),\n origin: range(item.range.start, item.range.end),\n }));\n\n if (node !== undefined) {\n children.push(node);\n }\n\n // Items with diagnostics or end-of-input leniency are not cached, so prefixes stop there.\n const entry = cache?.items.get(item);\n cacheable &&= entry?.node === node;\n\n for (const identifier of entry?.references ?? []) {\n references.add(identifier);\n }\n\n nodeCount += entry?.nodeCount ?? 0;\n depth = Math.max(depth, entry?.depth ?? 0);\n\n // A prefix is the first \\`length\\` nodes of \\`children\\`, which only ever grows past them.\n if (cacheable && index >= count - prefixWindow) {\n cache?.lists.set(item, {\n index,\n nodes: children,\n length: children.length,\n live: open,\n references: [...references],\n nodeCount,\n depth,\n });\n }\n }\n\n return children;\n}\n\n/**\n * How far back a list prefix can end. The parser closes an item only when the\n * next line completes, so the last two items are rebuilt by each tail draft.\n */\nconst prefixWindow = 8;\n\n/** The cached prefix ending closest to the end of the list. Closing items can still change. */\nfunction listPrefix(\n count: number,\n itemAt: (index: number) => ListItemSyntax,\n lists: MaterializeCache[\"lists\"],\n): CachedListPrefix | undefined {\n for (let index = count - 1; index >= Math.max(0, count - prefixWindow); index--) {\n const prefix = lists.get(itemAt(index));\n\n if (prefix?.index === index) {\n return prefix;\n }\n }\n\n return undefined;\n}\n\nfunction containsRange(outer: SourceRange, inner: SourceRange): boolean {\n return outer.start <= inner.start && inner.end <= outer.end;\n}\n\nfunction materializeBlocks(\n blocks: readonly BlockSyntax[],\n context: MaterializeContext,\n): FlowContent[] {\n const children: FlowContent[] = [];\n\n for (const block of blocks) {\n const child = materializeBlock(block, context);\n\n if (child !== undefined) {\n children.push(child);\n }\n }\n\n return children;\n}\n\nfunction materializeInline(\n segments: Parameters<typeof inlineInputText>[1],\n context: MaterializeContext,\n): PhrasingContent[] {\n const result = parseInline(\n new InlineInput(context.file, segments),\n context.syntax,\n context.definitionLookup,\n );\n\n for (const identifier of result.references) {\n context.references.add(identifier);\n }\n\n for (const invalid of result.invalid) {\n // Streaming input can still close a construct that reaches the end of the source.\n if (\n context.allowIncomplete &&\n invalid.open &&\n reachesEndOfInput(context.file, invalid.range.end)\n ) {\n context.usedEndOfInput = true;\n continue;\n }\n\n context.authoredInvalid = true;\n context.diagnostics.add({\n code: `mdx.${invalid.syntax}.invalid`,\n message: `Invalid or unfinished MDX ${invalid.syntax}`,\n severity: \"error\",\n span: span(context.file, invalid.range.start, invalid.range.end),\n });\n }\n\n return materializeInlineNodes(result.nodes, context);\n}\n\nfunction materializeInlineNodes(\n nodes: readonly InlineSyntax[],\n context: MaterializeContext,\n): PhrasingContent[] {\n const children: PhrasingContent[] = [];\n\n for (const node of nodes) {\n const child = materializeInlineNode(node, context);\n\n if (child !== undefined) {\n children.push(child);\n }\n }\n\n return children;\n}\n\nfunction materializeInlineNode(\n node: InlineSyntax,\n context: MaterializeContext,\n): PhrasingContent | undefined {\n const origin = range(node.range.start, node.range.end);\n\n switch (node.kind) {\n case \"text\":\n return counted(context, { kind: \"text\", value: node.value, origin });\n case \"emphasis\":\n case \"strong\":\n case \"delete\":\n return counted(context, {\n kind: node.kind,\n children: materializeInlineNodes(node.children, context),\n origin,\n });\n case \"code\":\n return counted(context, { kind: \"inlineCode\", value: node.value, origin });\n case \"hardBreak\":\n return counted(context, { kind: \"hardBreak\", origin });\n case \"link\":\n return counted(context, {\n kind: \"link\",\n url: node.destination,\n title: node.title,\n children: materializeInlineNodes(node.children, context),\n origin,\n });\n case \"image\":\n return counted(context, {\n kind: \"image\",\n url: node.destination,\n alt: node.alt,\n title: node.title,\n origin,\n });\n case \"reference\": {\n const children = materializeInlineNodes(node.children, context);\n\n if (!context.keepReferences && !context.definitions.has(node.identifier)) {\n return counted(context, {\n kind: \"text\",\n value: context.file.slice(node.range),\n origin,\n });\n }\n\n const identifier = normalizeIdentifier(node.identifier);\n\n return counted(\n context,\n node.image\n ? {\n kind: \"imageReference\",\n identifier,\n alt: children.map(nodeText).join(\"\"),\n referenceKind: node.referenceKind,\n origin,\n }\n : {\n kind: \"linkReference\",\n identifier,\n referenceKind: node.referenceKind,\n children,\n origin,\n },\n );\n }\n\n case \"rawHtml\":\n return counted(context, { kind: \"rawHtmlInline\", value: node.value, origin });\n case \"expression\":\n return counted(context, { kind: \"inlineExpression\", code: node.value, origin });\n case \"jsx\":\n return counted(context, materializeTextJsx(node.value, origin, context));\n case \"math\":\n return counted(context, {\n kind: \"inlineMath\",\n value: node.value,\n format: node.format,\n origin,\n });\n case \"footnoteReference\":\n return context.keepReferences || context.footnotes.has(node.identifier)\n ? counted(context, {\n kind: \"footnoteReference\",\n identifier: normalizeIdentifier(node.identifier),\n label: node.identifier,\n origin,\n })\n : counted(context, { kind: \"text\", value: context.file.slice(node.range), origin });\n case \"directive\":\n return counted(context, {\n kind: \"textDirective\",\n name: node.name,\n attributes: materializeDirectiveAttributes(node.attributes),\n label: { kind: \"directiveLabel\", children: [], origin },\n origin,\n });\n }\n}\n\nfunction materializeDirectiveLabel(\n label: ConstructorParameters<typeof InlineInput>[1] | undefined,\n context: MaterializeContext,\n): DirectiveLabelNode | undefined {\n if (label === undefined) {\n return;\n }\n\n const labelRange = inlineSegmentsRange(label, { start: 0, end: 0 });\n\n return {\n kind: \"directiveLabel\",\n children: materializeInline(label, context),\n origin: range(labelRange.start, labelRange.end),\n };\n}\n\nfunction materializeDirectiveAttributes(\n attributes: readonly DirectiveAttributeSyntax[],\n): DirectiveAttribute[] {\n return attributes.map((attribute) => ({ name: attribute.name, value: attribute.value }));\n}\n\n/**\n * Children on following lines are Markdown flow content. Like MDX, children on\n * the same line are phrasing: the element is text JSX in a paragraph, which\n * lowering does not wrap in `p`.\n */\nfunction materializeFlowJsx(block: JsxSyntax, context: MaterializeContext): FlowContent {\n const prepared = prepareFlowJsx(block, context);\n const { parts, children } = prepared;\n const origin = range(block.range.start, block.range.end);\n\n if (\n parts.children !== undefined &&\n parts.children.start !== parts.children.end &&\n children === undefined\n ) {\n return {\n kind: \"paragraph\",\n children: [materializeTextJsx(context.file.slice(block.range), origin, context, parts)],\n origin,\n };\n }\n\n return {\n kind: \"jsxFlowElement\",\n name: parts.name,\n attributes: parts.attributes,\n children: children === undefined ? [] : materializeBlocks(children, context),\n origin,\n };\n}\n\nfunction prepareFlowJsx(block: JsxSyntax, context: MaterializeContext): PreparedFlowJsx {\n const cached = context.flowJsx.get(block);\n\n if (cached !== undefined) {\n return cached;\n }\n\n const parts = jsxParts(context.file.slice(block.range), block.range.start);\n const childRange = parts.children;\n\n const children =\n childRange === undefined ||\n childRange.start === childRange.end ||\n !isFlowJsxChildren(context.file, childRange)\n ? undefined\n : parseFlowRange(grammarSource(context), childRange, context.syntax);\n\n const prepared = { parts, children };\n context.flowJsx.set(block, prepared);\n\n return prepared;\n}\n\nfunction grammarSource(context: MaterializeContext): SourceText {\n context.grammarSource ??= sourceText(context.file).grammar();\n\n return context.grammarSource;\n}\n\nfunction materializeTextJsx(\n authored: string,\n jsxOrigin: SourceRange,\n context: MaterializeContext,\n parsed = jsxParts(authored, jsxOrigin.start),\n): JsxTextElementNode {\n return {\n kind: \"jsxTextElement\",\n name: parsed.name,\n attributes: parsed.attributes,\n children:\n parsed.children === undefined\n ? []\n : materializeInline([{ kind: \"source\", range: parsed.children }], context),\n origin: jsxOrigin,\n };\n}\n\ninterface DependencyIndexes {\n readonly definitions: Set<string>;\n readonly footnotes: Set<string>;\n}\n\nfunction collectIndexes(\n blocks: readonly BlockSyntax[],\n context: MaterializeContext,\n indexes: DependencyIndexes,\n): void {\n const { definitions, footnotes } = indexes;\n let nodes = 1;\n\n const visit = (block: BlockSyntax, depth: number): void => {\n if (context.limit !== undefined) {\n return;\n }\n\n if (depth > context.limits.maximumNestingDepth) {\n context.limit = \"maximumNestingDepth\";\n\n return;\n }\n\n nodes++;\n\n if (nodes > context.limits.maximumNodes) {\n context.limit = \"maximumNodes\";\n\n return;\n }\n\n if (block.kind === \"definition\") {\n definitions.add(normalizeIdentifier(block.identifier));\n } else if (block.kind === \"footnoteDefinition\") {\n footnotes.add(normalizeIdentifier(block.identifier));\n }\n\n if (\n block.kind === \"blockQuote\" ||\n block.kind === \"footnoteDefinition\" ||\n block.kind === \"directive\"\n ) {\n block.children.forEach((child) => visit(child, depth + 1));\n } else if (block.kind === \"list\") {\n for (const item of [...block.items, ...(block.closing ?? [])]) {\n item.children.forEach((child) => visit(child, depth + 1));\n }\n } else if (block.kind === \"jsx\") {\n prepareFlowJsx(block, context).children?.forEach((child) => visit(child, depth + 1));\n }\n };\n\n blocks.forEach((block) => visit(block, 1));\n}\n\nfunction inlineInputText(\n file: SourceFile,\n segments: ConstructorParameters<typeof InlineInput>[1],\n): string {\n return new InlineInput(file, segments).toString();\n}\n\nfunction inlineSegmentsRange(\n segments: ConstructorParameters<typeof InlineInput>[1],\n fallback: SourceRange,\n): SourceRange {\n const first = segments.find((segment) => segment.kind === \"source\");\n const last = segments.findLast((segment) => segment.kind === \"source\");\n\n return first?.kind === \"source\" && last?.kind === \"source\"\n ? { start: first.range.start, end: last.range.end }\n : fallback;\n}\n\nfunction sliceOptional(file: SourceFile, range: SourceRange | undefined): string | undefined {\n return range === undefined ? undefined : file.slice(range);\n}\n\nfunction semanticSliceOptional(\n file: SourceFile,\n range: SourceRange | undefined,\n): string | undefined {\n return range === undefined ? undefined : file.semanticSlice(range);\n}\n\nfunction trimFinalLineEnding(value: string): string {\n return value.endsWith(\"\\r\\n\")\n ? value.slice(0, -2)\n : value.endsWith(\"\\n\") || value.endsWith(\"\\r\")\n ? value.slice(0, -1)\n : value;\n}\n\nfunction span(file: SourceFile, start: number, end: number): SourceSpan {\n return { file, start, end };\n}\n\nfunction range(start: number, end: number): SourceRange {\n return { start, end };\n}\n\nfunction enter(context: MaterializeContext): boolean {\n context.depth++;\n context.maximumDepth = Math.max(context.maximumDepth, context.depth);\n\n if (context.depth > context.limits.maximumNestingDepth) {\n context.limit = \"maximumNestingDepth\";\n context.depth--;\n\n return false;\n }\n\n return true;\n}\n\nfunction counted<T>(context: MaterializeContext, node: T): T | undefined {\n context.nodes++;\n\n if (context.nodes > context.limits.maximumNodes) {\n context.limit = \"maximumNodes\";\n\n return;\n }\n\n return node;\n}\n\nfunction limitDiagnostic(\n file: SourceFile,\n limit: \"maximumNestingDepth\" | \"maximumNodes\",\n): Diagnostic {\n return createDiagnostic({\n code: `mdx.limit.${limit}`,\n message: `Parser limit ${limit} exceeded`,\n severity: \"error\",\n span: span(file, 0, file.length),\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"materialize.mjs","names":[],"sources":["../../src/parser/materialize.ts"],"sourcesContent":["import type { Diagnostic } from \"../diagnostics.ts\";\nimport type {\n DirectiveAttribute,\n DirectiveLabelNode,\n ListItemNode,\n DocumentNode,\n FlowContent,\n JsxTextElementNode,\n PhrasingContent,\n} from \"../model.ts\";\nimport type { SourceRange } from \"../ranges.ts\";\nimport type { SourceText } from \"../source-text.ts\";\nimport type { SourceFile, SourceSpan } from \"../source.ts\";\nimport type { ResolvedSyntaxOptions } from \"../syntax-options.ts\";\nimport type {\n BlockSyntax,\n DirectiveAttributeSyntax,\n ListItemSyntax,\n ListSyntax,\n JsxSyntax,\n} from \"./block-syntax.ts\";\nimport type { ResolvedParserLimits } from \"./config.ts\";\nimport type { DefinitionLookup, InlineSyntax } from \"./inline-syntax.ts\";\nimport type {\n CachedListPrefix,\n CachedMaterialization,\n MaterializeCache,\n} from \"./materialize-cache.ts\";\n\nimport { createDiagnostic, DiagnosticBag } from \"../diagnostics.ts\";\nimport { decodeFrontmatter } from \"../frontmatter-decode.ts\";\nimport { normalizeIdentifier } from \"../identifier.ts\";\nimport { nodeText } from \"../model.ts\";\nimport { sourceText } from \"../source.ts\";\nimport { parseFlowRange } from \"./block-parser.ts\";\nimport { InlineInput } from \"./inline-input.ts\";\nimport { parseInline } from \"./inline-parser.ts\";\nimport { isFlowJsxChildren, jsxParts, type JsxParts } from \"./materialize-jsx.ts\";\n\nexport interface MaterializedBlock {\n readonly references: readonly string[];\n readonly nodeCount: number;\n readonly node: FlowContent;\n}\n\nexport interface MaterializeOptions {\n /** Definitions already known to a stream, including definitions in other blocks. */\n readonly definitionLookup?: DefinitionLookup;\n /**\n * Keeps references whose definitions are missing, for a stream where the\n * definitions may still arrive. Otherwise they become authored text.\n */\n readonly keepReferences?: boolean;\n /** Open embedded syntax at the end of the source is inert instead of invalid. */\n readonly allowIncomplete?: boolean;\n readonly cache?: MaterializeCache;\n /**\n * The range of a stream's open leaf. A stream renders that leaf itself, so it\n * materializes as an empty placeholder with the same kind and origin.\n */\n readonly open?: SourceRange;\n}\n\nexport type StrictMaterializeResult =\n | Readonly<{\n kind: \"ok\";\n document: DocumentNode;\n blocks: readonly MaterializedBlock[];\n diagnostics: readonly Diagnostic[];\n }>\n | Readonly<{ kind: \"invalid\"; diagnostics: readonly [Diagnostic, ...Diagnostic[]] }>\n | Readonly<{\n kind: \"limitExceeded\";\n limit: \"maximumNestingDepth\" | \"maximumNodes\";\n diagnostics: readonly [Diagnostic, ...Diagnostic[]];\n }>;\n\ninterface PreparedFlowJsx {\n readonly parts: JsxParts;\n readonly children: readonly BlockSyntax[] | undefined;\n}\n\ninterface MaterializeContext {\n readonly definitionLookup: DefinitionLookup;\n references: Set<string>;\n readonly definitions: ReadonlySet<string>;\n readonly diagnostics: DiagnosticBag;\n readonly file: SourceFile;\n readonly footnotes: ReadonlySet<string>;\n readonly limits: ResolvedParserLimits;\n readonly syntax: ResolvedSyntaxOptions;\n readonly allowIncomplete: boolean;\n readonly keepReferences: boolean;\n readonly cache: MaterializeCache | undefined;\n readonly open: SourceRange | undefined;\n readonly flowJsx: Map<JsxSyntax, PreparedFlowJsx>;\n grammarSource: SourceText | undefined;\n maximumDepth: number;\n /** Leniency at the end of the source makes the result depend on later input. */\n usedEndOfInput: boolean;\n depth: number;\n nodes: number;\n authoredInvalid: boolean;\n limit: \"maximumNestingDepth\" | \"maximumNodes\" | undefined;\n}\n\nexport function materializeDocument(\n file: SourceFile,\n blocks: readonly BlockSyntax[],\n syntax: ResolvedSyntaxOptions,\n limits: ResolvedParserLimits,\n options: MaterializeOptions = {},\n): StrictMaterializeResult {\n const indexes: DependencyIndexes = { definitions: new Set(), footnotes: new Set() };\n const context = createContext(file, syntax, limits, options, indexes);\n\n // Index flow JSX before references are materialized; its parsed children are reused below.\n if (!context.keepReferences) {\n collectIndexes(blocks, context, indexes);\n }\n\n const children: FlowContent[] = [];\n const materializedBlocks: MaterializedBlock[] = [];\n\n for (const block of blocks) {\n if (context.limit !== undefined) {\n break;\n }\n\n const before = context.nodes;\n context.references = new Set();\n const child = materializeBlock(block, context);\n\n if (child !== undefined) {\n children.push(child);\n materializedBlocks.push(\n Object.freeze({\n node: child,\n nodeCount: context.nodes - before,\n references: [...context.references],\n }),\n );\n }\n }\n\n if (context.limit !== undefined) {\n const diagnostic = limitDiagnostic(file, context.limit);\n const diagnostics: readonly [Diagnostic] = Object.freeze([diagnostic]);\n\n return Object.freeze({\n kind: \"limitExceeded\",\n limit: context.limit,\n diagnostics,\n });\n }\n\n const diagnostics = context.diagnostics.snapshot();\n\n if (\n context.authoredInvalid ||\n diagnostics.some((diagnostic) => diagnostic.severity === \"error\")\n ) {\n const errors = diagnostics.filter((diagnostic) => diagnostic.severity === \"error\");\n\n if (errors.length === 0) {\n throw new Error(\"Invalid MDX draft did not produce an error diagnostic\");\n }\n\n const [first, ...rest] = errors;\n\n if (first === undefined) {\n throw new Error(\"Invalid MDX diagnostic collection changed unexpectedly\");\n }\n\n const invalidDiagnostics: readonly [Diagnostic, ...Diagnostic[]] = Object.freeze([\n first,\n ...rest,\n ]);\n\n return Object.freeze({\n kind: \"invalid\",\n diagnostics: invalidDiagnostics,\n });\n }\n\n const document = counted<DocumentNode>(context, {\n kind: \"document\",\n children,\n origin: range(0, file.length),\n });\n\n if (document === undefined || context.limit !== undefined) {\n const diagnostic = limitDiagnostic(file, \"maximumNodes\");\n const diagnostics: readonly [Diagnostic] = Object.freeze([diagnostic]);\n\n return Object.freeze({\n kind: \"limitExceeded\",\n limit: \"maximumNodes\",\n diagnostics,\n });\n }\n\n return Object.freeze({\n kind: \"ok\",\n document,\n blocks: Object.freeze(materializedBlocks),\n diagnostics,\n });\n}\n\nexport interface MaterializedPhrasing {\n readonly nodes: readonly PhrasingContent[];\n readonly nodeCount: number;\n}\n\n/** Materialized phrasing by inline syntax identity, valid while references are kept. */\nexport type PhrasingCache = WeakMap<InlineSyntax, MaterializedPhrasing>;\n\n/**\n * Materializes parsed inline syntax that a stream renders outside a block,\n * keeping references.\n */\nexport function materializePhrasing(\n file: SourceFile,\n nodes: readonly InlineSyntax[],\n syntax: ResolvedSyntaxOptions,\n limits: ResolvedParserLimits,\n): MaterializedPhrasing {\n const context = createContext(file, syntax, limits, {\n keepReferences: true,\n allowIncomplete: true,\n });\n\n const children: PhrasingContent[] = [];\n\n for (const node of nodes) {\n const child = materializeInlineNode(node, context);\n\n if (child !== undefined) {\n children.push(child);\n }\n }\n\n return { nodes: children, nodeCount: context.nodes };\n}\n\n/** Independent inline groups share one context while retaining their own node budgets. */\nexport function materializePhrasingGroups(\n file: SourceFile,\n nodes: readonly InlineSyntax[],\n syntax: ResolvedSyntaxOptions,\n limits: ResolvedParserLimits,\n cache: PhrasingCache,\n): readonly MaterializedPhrasing[] {\n const context = createContext(file, syntax, limits, {\n keepReferences: true,\n allowIncomplete: true,\n });\n\n return nodes.map((node) => {\n const hit = cache.get(node);\n\n if (hit !== undefined) {\n return hit;\n }\n\n context.nodes = 0;\n context.limit = undefined;\n context.usedEndOfInput = false;\n\n const child = materializeInlineNode(node, context);\n\n const materialized = {\n nodes: child === undefined ? [] : [child],\n nodeCount: context.nodes,\n };\n\n if (context.limit === undefined && !context.usedEndOfInput) {\n cache.set(node, materialized);\n }\n\n return materialized;\n });\n}\n\n/** Only whitespace and at most one line ending follow `offset`. */\nfunction reachesEndOfInput(file: SourceFile, offset: number): boolean {\n return /^[ \\t]*(?:\\r\\n?|\\n)?[ \\t]*$/u.test(file.slice({ start: offset, end: file.length }));\n}\n\nconst emptyIndexes: DependencyIndexes = { definitions: new Set(), footnotes: new Set() };\n\nfunction createContext(\n file: SourceFile,\n syntax: ResolvedSyntaxOptions,\n limits: ResolvedParserLimits,\n options: MaterializeOptions,\n indexes: DependencyIndexes = emptyIndexes,\n): MaterializeContext {\n return {\n definitions: indexes.definitions,\n definitionLookup: options.definitionLookup ?? indexes.definitions,\n references: new Set(),\n diagnostics: new DiagnosticBag(),\n file,\n footnotes: indexes.footnotes,\n limits,\n syntax,\n // Resolution depends on the definitions, so only reference-keeping output is cached.\n cache: options.keepReferences === true ? options.cache : undefined,\n flowJsx: new Map(),\n grammarSource: undefined,\n maximumDepth: 0,\n usedEndOfInput: false,\n allowIncomplete: options.allowIncomplete ?? false,\n keepReferences: options.keepReferences ?? false,\n open: options.open,\n depth: 0,\n nodes: 0,\n authoredInvalid: false,\n limit: undefined,\n };\n}\n\nfunction materializeBlock(\n block: BlockSyntax,\n context: MaterializeContext,\n): FlowContent | undefined {\n return cached(context.cache?.blocks, block, context, () =>\n materializeBlockContent(block, context),\n );\n}\n\n/**\n * Replays a cached subtree, or materializes and caches it. Subtrees with\n * diagnostics or input-dependent leniency are never cached.\n */\nfunction cached<TKey extends BlockSyntax | ListItemSyntax, TNode>(\n cache: WeakMap<TKey, CachedMaterialization<TNode>> | undefined,\n key: TKey,\n context: MaterializeContext,\n materialize: () => TNode | undefined,\n): TNode | undefined {\n if (cache === undefined) {\n return materialize();\n }\n\n const hit = cache.get(key);\n\n if (\n hit !== undefined &&\n context.depth + hit.depth <= context.limits.maximumNestingDepth &&\n context.nodes + hit.nodeCount <= context.limits.maximumNodes\n ) {\n for (const identifier of hit.references) {\n context.references.add(identifier);\n }\n\n context.nodes += hit.nodeCount;\n context.maximumDepth = Math.max(context.maximumDepth, context.depth + hit.depth);\n\n return hit.node;\n }\n\n const references = context.references;\n context.references = new Set();\n const nodes = context.nodes;\n const diagnostics = context.diagnostics.size;\n const outerDepth = context.maximumDepth;\n const outerEndOfInput = context.usedEndOfInput;\n context.maximumDepth = context.depth;\n context.usedEndOfInput = false;\n const node = materialize();\n\n if (\n node !== undefined &&\n context.diagnostics.size === diagnostics &&\n !context.authoredInvalid &&\n context.limit === undefined &&\n !context.usedEndOfInput\n ) {\n cache.set(key, {\n node,\n nodeCount: context.nodes - nodes,\n depth: context.maximumDepth - context.depth,\n references: [...context.references],\n });\n }\n\n for (const identifier of context.references) {\n references.add(identifier);\n }\n\n context.references = references;\n context.maximumDepth = Math.max(outerDepth, context.maximumDepth);\n context.usedEndOfInput ||= outerEndOfInput;\n\n return node;\n}\n\nfunction materializeBlockContent(\n block: BlockSyntax,\n context: MaterializeContext,\n): FlowContent | undefined {\n if (!enter(context)) {\n return;\n }\n\n try {\n const origin = range(block.range.start, block.range.end);\n\n if (isOpenLeaf(block, context)) {\n context.usedEndOfInput = true;\n\n return counted(context, openLeafPlaceholder(block, origin));\n }\n\n switch (block.kind) {\n case \"paragraph\":\n return counted(context, {\n kind: \"paragraph\",\n children: materializeInline(block.input, context),\n origin,\n });\n case \"heading\":\n return counted(context, {\n kind: \"heading\",\n depth: block.depth,\n children: materializeInline(block.input, context),\n origin,\n });\n case \"code\":\n return counted(context, {\n kind: \"codeBlock\",\n value: trimFinalLineEnding(inlineInputText(context.file, block.value)),\n language: sliceOptional(context.file, block.language),\n meta: sliceOptional(context.file, block.meta),\n origin,\n });\n case \"thematicBreak\":\n return counted(context, { kind: \"thematicBreak\", origin });\n case \"blockQuote\":\n return counted(context, {\n kind: \"blockquote\",\n children: materializeBlocks(block.children, context),\n origin,\n });\n case \"list\":\n return counted(context, {\n kind: \"list\",\n ordered: block.ordered,\n spread: block.spread,\n start: block.start ?? 1,\n children: materializeListItems(block, context),\n origin,\n });\n case \"definition\":\n return counted(context, {\n kind: \"definition\",\n identifier: normalizeIdentifier(block.identifier),\n url: context.file.semanticSlice(block.destination),\n title: semanticSliceOptional(context.file, block.title),\n origin,\n });\n case \"footnoteDefinition\":\n return counted(context, {\n kind: \"footnoteDefinition\",\n identifier: normalizeIdentifier(block.identifier),\n label: block.identifier,\n children: materializeBlocks(block.children, context),\n origin,\n });\n case \"rawHtml\":\n return counted(context, {\n kind: \"rawHtmlBlock\",\n value: context.file.semanticSlice(block.range),\n origin,\n });\n case \"frontmatter\": {\n const rawValue = trimFinalLineEnding(context.file.slice(block.value));\n const valueOrigin = range(block.value.start, block.value.start + rawValue.length);\n\n const data = decodeFrontmatter({\n diagnostics: context.diagnostics,\n format: block.format,\n source: rawValue,\n span: span(context.file, valueOrigin.start, valueOrigin.end),\n });\n\n return counted(context, {\n kind: \"frontmatter\",\n format: block.format,\n value: rawValue.replace(/\\r\\n?|\\n/gu, \"\\n\"),\n data,\n valueOrigin,\n origin,\n });\n }\n\n case \"directive\":\n return counted(context, {\n kind: \"containerDirective\",\n name: block.name,\n attributes: materializeDirectiveAttributes(block.attributes),\n label: materializeDirectiveLabel(block.label, context),\n children: materializeBlocks(block.children, context),\n origin,\n });\n case \"leafDirective\":\n return counted(context, {\n kind: \"leafDirective\",\n name: block.name,\n attributes: materializeDirectiveAttributes(block.attributes),\n label: materializeDirectiveLabel(block.label, context),\n origin,\n });\n case \"math\": {\n const value = trimFinalLineEnding(inlineInputText(context.file, block.value));\n\n return counted(\n context,\n block.format === \"tex\"\n ? { kind: \"displayMath\", value, format: \"tex\", origin }\n : {\n kind: \"displayMath\",\n value,\n format: \"dollar\",\n meta: sliceOptional(context.file, block.meta),\n origin,\n },\n );\n }\n\n case \"table\":\n return counted(context, {\n kind: \"table\",\n alignments: block.alignments,\n children: block.rows.map((row) => ({\n kind: \"tableRow\",\n children: row.cells.map((cell) => {\n const cellRange = inlineSegmentsRange(cell, row.range);\n\n return {\n kind: \"tableCell\",\n children: materializeInline(cell, context),\n origin: range(cellRange.start, cellRange.end),\n };\n }),\n origin: range(row.range.start, row.range.end),\n })),\n origin,\n });\n case \"expression\": {\n const authored = context.file.slice(block.range);\n\n return counted(context, {\n kind: \"blockExpression\",\n code: authored.slice(authored.indexOf(\"{\") + 1, authored.lastIndexOf(\"}\")),\n origin,\n });\n }\n\n case \"esm\":\n return counted(context, {\n kind: \"esm\",\n code: trimFinalLineEnding(context.file.slice(block.range)),\n origin,\n });\n case \"jsx\":\n return counted(context, materializeFlowJsx(block, context));\n case \"invalidMdx\":\n if (\n context.allowIncomplete &&\n block.state === \"incomplete\" &&\n reachesEndOfInput(context.file, block.range.end)\n ) {\n context.usedEndOfInput = true;\n\n return counted(context, {\n kind: \"rawHtmlBlock\",\n value: context.file.slice(block.range),\n origin,\n });\n }\n\n context.authoredInvalid = true;\n context.diagnostics.add({\n code: `mdx.${block.syntax}.invalid`,\n message: `Invalid or unfinished MDX ${block.syntax}`,\n severity: \"error\",\n span: span(context.file, origin.start, origin.end),\n });\n\n return;\n }\n } finally {\n context.depth--;\n }\n}\n\nfunction isOpenLeaf(block: BlockSyntax, context: MaterializeContext): boolean {\n return (\n context.open !== undefined &&\n block.range.start === context.open.start &&\n block.range.end === context.open.end &&\n (block.kind === \"paragraph\" ||\n block.kind === \"code\" ||\n block.kind === \"math\" ||\n block.kind === \"invalidMdx\")\n );\n}\n\nfunction openLeafPlaceholder(block: BlockSyntax, origin: SourceRange): FlowContent {\n switch (block.kind) {\n case \"paragraph\":\n return { kind: \"paragraph\", children: [], origin };\n case \"code\":\n return { kind: \"codeBlock\", value: \"\", origin };\n case \"math\":\n return { kind: \"displayMath\", value: \"\", format: \"dollar\", origin };\n default:\n return { kind: \"rawHtmlBlock\", value: \"\", origin };\n }\n}\n\n/**\n * Materializes list items. A growing list reuses its unchanged leading items\n * as one prefix, so an append materializes only the items after it. The list\n * that contains a stream's open leaf is rebuilt on every append and never\n * cached, so its children array is extended in place instead of copied.\n */\nfunction materializeListItems(list: ListSyntax, context: MaterializeContext): ListItemNode[] {\n const items = list.items;\n const closing = list.closing ?? [];\n const count = items.length + closing.length;\n const itemAt = (index: number): ListItemSyntax => items[index] ?? closing[index - items.length];\n const open = context.open !== undefined && containsRange(list.range, context.open);\n const cache = context.cache;\n const prefix = cache === undefined ? undefined : listPrefix(count, itemAt, cache.lists);\n\n const reused =\n prefix !== undefined &&\n context.depth + prefix.depth <= context.limits.maximumNestingDepth &&\n context.nodes + prefix.nodeCount <= context.limits.maximumNodes\n ? prefix\n : undefined;\n\n let children: ListItemNode[] = [];\n\n if (reused !== undefined && reused.live && open) {\n children = reused.nodes;\n children.length = reused.length;\n } else if (reused !== undefined) {\n children = reused.nodes.slice(0, reused.length);\n }\n\n let nodeCount = reused?.nodeCount ?? 0;\n let depth = reused?.depth ?? 0;\n let cacheable = true;\n const references = new Set(reused?.references);\n\n if (reused !== undefined) {\n for (const identifier of reused.references) {\n context.references.add(identifier);\n }\n\n context.nodes += reused.nodeCount;\n context.maximumDepth = Math.max(context.maximumDepth, context.depth + reused.depth);\n }\n\n for (let index = (reused?.index ?? -1) + 1; index < count; index++) {\n const item = itemAt(index);\n\n const node = cached(cache?.items, item, context, (): ListItemNode => ({\n kind: \"listItem\",\n checked: item.checked,\n spread: item.spread,\n children: materializeBlocks(item.children, context),\n origin: range(item.range.start, item.range.end),\n }));\n\n if (node !== undefined) {\n children.push(node);\n }\n\n // Items with diagnostics or end-of-input leniency are not cached, so prefixes stop there.\n const entry = cache?.items.get(item);\n cacheable &&= entry?.node === node;\n\n for (const identifier of entry?.references ?? []) {\n references.add(identifier);\n }\n\n nodeCount += entry?.nodeCount ?? 0;\n depth = Math.max(depth, entry?.depth ?? 0);\n\n // A prefix is the first \\`length\\` nodes of \\`children\\`, which only ever grows past them.\n if (cacheable && index >= count - prefixWindow) {\n cache?.lists.set(item, {\n index,\n nodes: children,\n length: children.length,\n live: open,\n references: [...references],\n nodeCount,\n depth,\n });\n }\n }\n\n return children;\n}\n\n/**\n * How far back a list prefix can end. The parser closes an item only when the\n * next line completes, so the last two items are rebuilt by each tail draft.\n */\nconst prefixWindow = 8;\n\n/** The cached prefix ending closest to the end of the list. Closing items can still change. */\nfunction listPrefix(\n count: number,\n itemAt: (index: number) => ListItemSyntax,\n lists: MaterializeCache[\"lists\"],\n): CachedListPrefix | undefined {\n for (let index = count - 1; index >= Math.max(0, count - prefixWindow); index--) {\n const prefix = lists.get(itemAt(index));\n\n if (prefix?.index === index) {\n return prefix;\n }\n }\n\n return undefined;\n}\n\nfunction containsRange(outer: SourceRange, inner: SourceRange): boolean {\n return outer.start <= inner.start && inner.end <= outer.end;\n}\n\nfunction materializeBlocks(\n blocks: readonly BlockSyntax[],\n context: MaterializeContext,\n): FlowContent[] {\n const children: FlowContent[] = [];\n\n for (const block of blocks) {\n const child = materializeBlock(block, context);\n\n if (child !== undefined) {\n children.push(child);\n }\n }\n\n return children;\n}\n\nfunction materializeInline(\n segments: Parameters<typeof inlineInputText>[1],\n context: MaterializeContext,\n): PhrasingContent[] {\n const result = parseInline(\n new InlineInput(context.file, segments),\n context.syntax,\n context.definitionLookup,\n );\n\n for (const identifier of result.references) {\n context.references.add(identifier);\n }\n\n for (const invalid of result.invalid) {\n // Streaming input can still close a construct that reaches the end of the source.\n if (\n context.allowIncomplete &&\n invalid.open &&\n reachesEndOfInput(context.file, invalid.range.end)\n ) {\n context.usedEndOfInput = true;\n continue;\n }\n\n context.authoredInvalid = true;\n context.diagnostics.add({\n code: `mdx.${invalid.syntax}.invalid`,\n message: `Invalid or unfinished MDX ${invalid.syntax}`,\n severity: \"error\",\n span: span(context.file, invalid.range.start, invalid.range.end),\n });\n }\n\n return materializeInlineNodes(result.nodes, context);\n}\n\nfunction materializeInlineNodes(\n nodes: readonly InlineSyntax[],\n context: MaterializeContext,\n): PhrasingContent[] {\n const children: PhrasingContent[] = [];\n\n for (const node of nodes) {\n const child = materializeInlineNode(node, context);\n\n if (child !== undefined) {\n children.push(child);\n }\n }\n\n return children;\n}\n\nfunction materializeInlineNode(\n node: InlineSyntax,\n context: MaterializeContext,\n): PhrasingContent | undefined {\n const origin = range(node.range.start, node.range.end);\n\n switch (node.kind) {\n case \"text\":\n return counted(context, { kind: \"text\", value: node.value, origin });\n case \"emphasis\":\n case \"strong\":\n case \"delete\":\n return counted(context, {\n kind: node.kind,\n children: materializeInlineNodes(node.children, context),\n origin,\n });\n case \"code\":\n return counted(context, { kind: \"inlineCode\", value: node.value, origin });\n case \"hardBreak\":\n return counted(context, { kind: \"hardBreak\", origin });\n case \"link\":\n return counted(context, {\n kind: \"link\",\n url: node.destination,\n title: node.title,\n children: materializeInlineNodes(node.children, context),\n origin,\n });\n case \"image\":\n return counted(context, {\n kind: \"image\",\n url: node.destination,\n alt: node.alt,\n title: node.title,\n origin,\n });\n case \"reference\": {\n const children = materializeInlineNodes(node.children, context);\n\n if (!context.keepReferences && !context.definitions.has(node.identifier)) {\n return counted(context, {\n kind: \"text\",\n value: context.file.slice(node.range),\n origin,\n });\n }\n\n const identifier = normalizeIdentifier(node.identifier);\n\n return counted(\n context,\n node.image\n ? {\n kind: \"imageReference\",\n identifier,\n alt: children.map(nodeText).join(\"\"),\n referenceKind: node.referenceKind,\n origin,\n }\n : {\n kind: \"linkReference\",\n identifier,\n referenceKind: node.referenceKind,\n children,\n origin,\n },\n );\n }\n\n case \"rawHtml\":\n return counted(context, { kind: \"rawHtmlInline\", value: node.value, origin });\n case \"expression\":\n return counted(context, { kind: \"inlineExpression\", code: node.value, origin });\n case \"jsx\":\n return counted(context, materializeTextJsx(node.value, origin, context));\n case \"math\":\n return counted(context, {\n kind: \"inlineMath\",\n value: node.value,\n format: node.format,\n origin,\n });\n case \"footnoteReference\":\n return context.keepReferences || context.footnotes.has(node.identifier)\n ? counted(context, {\n kind: \"footnoteReference\",\n identifier: normalizeIdentifier(node.identifier),\n label: node.identifier,\n origin,\n })\n : counted(context, { kind: \"text\", value: context.file.slice(node.range), origin });\n case \"directive\":\n return counted(context, {\n kind: \"textDirective\",\n name: node.name,\n attributes: materializeDirectiveAttributes(node.attributes),\n label: { kind: \"directiveLabel\", children: [], origin },\n origin,\n });\n }\n}\n\nfunction materializeDirectiveLabel(\n label: ConstructorParameters<typeof InlineInput>[1] | undefined,\n context: MaterializeContext,\n): DirectiveLabelNode | undefined {\n if (label === undefined) {\n return;\n }\n\n const labelRange = inlineSegmentsRange(label, { start: 0, end: 0 });\n\n return {\n kind: \"directiveLabel\",\n children: materializeInline(label, context),\n origin: range(labelRange.start, labelRange.end),\n };\n}\n\nfunction materializeDirectiveAttributes(\n attributes: readonly DirectiveAttributeSyntax[],\n): DirectiveAttribute[] {\n return attributes.map((attribute) => ({ name: attribute.name, value: attribute.value }));\n}\n\n/**\n * Children on following lines are Markdown flow content. Like MDX, children on\n * the same line are phrasing: the element is text JSX in a paragraph, which\n * lowering does not wrap in `p`.\n */\nfunction materializeFlowJsx(block: JsxSyntax, context: MaterializeContext): FlowContent {\n const prepared = prepareFlowJsx(block, context);\n const { parts, children } = prepared;\n const origin = range(block.range.start, block.range.end);\n\n if (\n parts.children !== undefined &&\n parts.children.start !== parts.children.end &&\n children === undefined\n ) {\n return {\n kind: \"paragraph\",\n children: [materializeTextJsx(context.file.slice(block.range), origin, context, parts)],\n origin,\n };\n }\n\n return {\n kind: \"jsxFlowElement\",\n name: parts.name,\n attributes: parts.attributes,\n children: children === undefined ? [] : materializeBlocks(children, context),\n origin,\n };\n}\n\nfunction prepareFlowJsx(block: JsxSyntax, context: MaterializeContext): PreparedFlowJsx {\n const cached = context.flowJsx.get(block);\n\n if (cached !== undefined) {\n return cached;\n }\n\n const parts = jsxParts(context.file.slice(block.range), block.range.start);\n const childRange = parts.children;\n\n const children =\n childRange === undefined ||\n childRange.start === childRange.end ||\n !isFlowJsxChildren(context.file, childRange)\n ? undefined\n : parseFlowRange(grammarSource(context), childRange, context.syntax);\n\n const prepared = { parts, children };\n context.flowJsx.set(block, prepared);\n\n return prepared;\n}\n\nfunction grammarSource(context: MaterializeContext): SourceText {\n context.grammarSource ??= sourceText(context.file).grammar();\n\n return context.grammarSource;\n}\n\nfunction materializeTextJsx(\n authored: string,\n jsxOrigin: SourceRange,\n context: MaterializeContext,\n parsed = jsxParts(authored, jsxOrigin.start),\n): JsxTextElementNode {\n return {\n kind: \"jsxTextElement\",\n name: parsed.name,\n attributes: parsed.attributes,\n children:\n parsed.children === undefined\n ? []\n : materializeInline([{ kind: \"source\", range: parsed.children }], context),\n origin: jsxOrigin,\n };\n}\n\ninterface DependencyIndexes {\n readonly definitions: Set<string>;\n readonly footnotes: Set<string>;\n}\n\nfunction collectIndexes(\n blocks: readonly BlockSyntax[],\n context: MaterializeContext,\n indexes: DependencyIndexes,\n): void {\n const { definitions, footnotes } = indexes;\n let nodes = 1;\n\n const visit = (block: BlockSyntax, depth: number): void => {\n if (context.limit !== undefined) {\n return;\n }\n\n if (depth > context.limits.maximumNestingDepth) {\n context.limit = \"maximumNestingDepth\";\n\n return;\n }\n\n nodes++;\n\n if (nodes > context.limits.maximumNodes) {\n context.limit = \"maximumNodes\";\n\n return;\n }\n\n if (block.kind === \"definition\") {\n definitions.add(normalizeIdentifier(block.identifier));\n } else if (block.kind === \"footnoteDefinition\") {\n footnotes.add(normalizeIdentifier(block.identifier));\n }\n\n if (\n block.kind === \"blockQuote\" ||\n block.kind === \"footnoteDefinition\" ||\n block.kind === \"directive\"\n ) {\n block.children.forEach((child) => visit(child, depth + 1));\n } else if (block.kind === \"list\") {\n for (const item of [...block.items, ...(block.closing ?? [])]) {\n item.children.forEach((child) => visit(child, depth + 1));\n }\n } else if (block.kind === \"jsx\") {\n prepareFlowJsx(block, context).children?.forEach((child) => visit(child, depth + 1));\n }\n };\n\n blocks.forEach((block) => visit(block, 1));\n}\n\nfunction inlineInputText(\n file: SourceFile,\n segments: ConstructorParameters<typeof InlineInput>[1],\n): string {\n return new InlineInput(file, segments).toString();\n}\n\nfunction inlineSegmentsRange(\n segments: ConstructorParameters<typeof InlineInput>[1],\n fallback: SourceRange,\n): SourceRange {\n const first = segments.find((segment) => segment.kind === \"source\");\n const last = segments.findLast((segment) => segment.kind === \"source\");\n\n return first?.kind === \"source\" && last?.kind === \"source\"\n ? { start: first.range.start, end: last.range.end }\n : fallback;\n}\n\nfunction sliceOptional(file: SourceFile, range: SourceRange | undefined): string | undefined {\n return range === undefined ? undefined : file.slice(range);\n}\n\nfunction semanticSliceOptional(\n file: SourceFile,\n range: SourceRange | undefined,\n): string | undefined {\n return range === undefined ? undefined : file.semanticSlice(range);\n}\n\nfunction trimFinalLineEnding(value: string): string {\n return value.endsWith(\"\\r\\n\")\n ? value.slice(0, -2)\n : value.endsWith(\"\\n\") || value.endsWith(\"\\r\")\n ? value.slice(0, -1)\n : value;\n}\n\nfunction span(file: SourceFile, start: number, end: number): SourceSpan {\n return { file, start, end };\n}\n\nfunction range(start: number, end: number): SourceRange {\n return { start, end };\n}\n\nfunction enter(context: MaterializeContext): boolean {\n context.depth++;\n context.maximumDepth = Math.max(context.maximumDepth, context.depth);\n\n if (context.depth > context.limits.maximumNestingDepth) {\n context.limit = \"maximumNestingDepth\";\n context.depth--;\n\n return false;\n }\n\n return true;\n}\n\nfunction counted<T>(context: MaterializeContext, node: T): T | undefined {\n context.nodes++;\n\n if (context.nodes > context.limits.maximumNodes) {\n context.limit = \"maximumNodes\";\n\n return;\n }\n\n return node;\n}\n\nfunction limitDiagnostic(\n file: SourceFile,\n limit: \"maximumNestingDepth\" | \"maximumNodes\",\n): Diagnostic {\n return createDiagnostic({\n code: `mdx.limit.${limit}`,\n message: `Parser limit ${limit} exceeded`,\n severity: \"error\",\n span: span(file, 0, file.length),\n });\n}\n"],"mappings":"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"}
|
package/dist/source-text.d.mts
CHANGED
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
export declare class SourceText {
|
|
9
9
|
#private;
|
|
10
10
|
readonly length: number;
|
|
11
|
-
/** The text has no NUL, so the parser reads it as it is. */
|
|
12
|
-
readonly plain: boolean;
|
|
13
11
|
private constructor();
|
|
14
12
|
static of(this: void, text: string): SourceText;
|
|
13
|
+
/** Lazily checks for NUL only when a consumer needs normalized grammar text. */
|
|
14
|
+
get plain(): boolean;
|
|
15
15
|
/** The text the parser reads: NUL becomes U+FFFD. */
|
|
16
16
|
grammar(): SourceText;
|
|
17
17
|
/** The same text in one chunk, for complete-document reads. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source-text.d.mts","names":[],"sources":["../src/source-text.ts"],"mappings":";;;;;;;qBAMa;;WAGK
|
|
1
|
+
{"version":3,"file":"source-text.d.mts","names":[],"sources":["../src/source-text.ts"],"mappings":";;;;;;;qBAMa;;WAGK;UAOT;SAaO,GAAG,YAAY,eAAe;;MAOjC;;EAOJ,WAAW;;EAKX,WAAW;EAMX,OAAO,eAAe;;EA4BtB,KAAK;EAeL,MAAM,eAAe;;EA8BrB,QAAQ,gBAAgB;;EAsBxB,cAAc,SAAS,QAAQ;;EAe/B,YAAY;EAeZ,WAAW,gBAAgB;;EAK3B;UAQC"}
|
package/dist/source-text.mjs
CHANGED
|
@@ -9,8 +9,7 @@ var SourceText = class SourceText {
|
|
|
9
9
|
#chunks;
|
|
10
10
|
#starts;
|
|
11
11
|
length;
|
|
12
|
-
|
|
13
|
-
plain;
|
|
12
|
+
#plain;
|
|
14
13
|
#joined;
|
|
15
14
|
#single;
|
|
16
15
|
/** The chunk of the last read, since reads cluster around one offset. */
|
|
@@ -20,10 +19,15 @@ var SourceText = class SourceText {
|
|
|
20
19
|
this.#starts = starts;
|
|
21
20
|
this.#single = chunks.length === 1 ? chunks[0] : void 0;
|
|
22
21
|
this.length = length;
|
|
23
|
-
this
|
|
22
|
+
this.#plain = plain;
|
|
24
23
|
}
|
|
25
24
|
static of(text) {
|
|
26
|
-
return text.length === 0 ? new SourceText([], [], 0, true) : new SourceText([text], [0], text.length,
|
|
25
|
+
return text.length === 0 ? new SourceText([], [], 0, true) : new SourceText([text], [0], text.length, void 0);
|
|
26
|
+
}
|
|
27
|
+
/** Lazily checks for NUL only when a consumer needs normalized grammar text. */
|
|
28
|
+
get plain() {
|
|
29
|
+
this.#plain ??= this.#chunks.every((chunk) => !chunk.includes("\0"));
|
|
30
|
+
return this.#plain;
|
|
27
31
|
}
|
|
28
32
|
/** The text the parser reads: NUL becomes U+FFFD. */
|
|
29
33
|
grammar() {
|
|
@@ -31,7 +35,7 @@ var SourceText = class SourceText {
|
|
|
31
35
|
}
|
|
32
36
|
/** The same text in one chunk, for complete-document reads. */
|
|
33
37
|
flatten() {
|
|
34
|
-
return this.#chunks.length <= 1 ? this : new SourceText([this.toString()], [0], this.length, this
|
|
38
|
+
return this.#chunks.length <= 1 ? this : new SourceText([this.toString()], [0], this.length, this.#plain);
|
|
35
39
|
}
|
|
36
40
|
append(text) {
|
|
37
41
|
if (text.length === 0) return this;
|
package/dist/source-text.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source-text.mjs","names":[],"sources":["../src/source-text.ts"],"sourcesContent":["/**\n * Immutable text in a few flat chunks, read by absolute offset. Appending makes\n * a new text that shares the chunks before it, so a growing document is never\n * copied whole. Chunks merge like a binary counter, so a text has O(log n)\n * chunks and each character is copied O(log n) times in total.\n */\nexport class SourceText {\n readonly #chunks: readonly string[];\n readonly #starts: readonly number[];\n public readonly length: number;\n /** The text has no NUL, so the parser reads it as it is. */\n public readonly plain: boolean;\n #joined: string | undefined;\n readonly #single: string | undefined;\n /** The chunk of the last read, since reads cluster around one offset. */\n #hint = 0;\n\n private constructor(\n chunks: readonly string[],\n starts: readonly number[],\n length: number,\n plain: boolean,\n ) {\n this.#chunks = chunks;\n this.#starts = starts;\n this.#single = chunks.length === 1 ? chunks[0] : undefined;\n this.length = length;\n this.plain = plain;\n }\n\n public static of(this: void, text: string): SourceText {\n return text.length === 0\n ? new SourceText([], [], 0, true)\n : new SourceText([text], [0], text.length, !text.includes(\"\\0\"));\n }\n\n /** The text the parser reads: NUL becomes U+FFFD. */\n public grammar(): SourceText {\n return this.plain ? this : SourceText.of(this.toString().replaceAll(\"\\0\", \"\\uFFFD\"));\n }\n\n /** The same text in one chunk, for complete-document reads. */\n public flatten(): SourceText {\n return this.#chunks.length <= 1\n ? this\n : new SourceText([this.toString()], [0], this.length, this.plain);\n }\n\n public append(text: string): SourceText {\n if (text.length === 0) {\n return this;\n }\n\n const chunks = [...this.#chunks, text];\n const starts = [...this.#starts, this.length];\n\n // Like a binary counter, a chunk merges into the one before it once it is as large.\n while (\n chunks.length > 1 &&\n chunks[chunks.length - 2].length <= chunks[chunks.length - 1].length\n ) {\n const last = chunks[chunks.length - 1];\n chunks.length--;\n starts.length--;\n chunks[chunks.length - 1] = flat(chunks[chunks.length - 1] + last);\n }\n\n return new SourceText(\n chunks,\n starts,\n this.length + text.length,\n this.plain && !text.includes(\"\\0\"),\n );\n }\n\n /** The character at `offset`, or `undefined` outside the text. */\n public char(offset: number): string | undefined {\n // A complete document is one chunk, so batch parsing reads it like a string.\n if (this.#single !== undefined) {\n return this.#single[offset];\n }\n\n if (offset < 0 || offset >= this.length) {\n return undefined;\n }\n\n const index = this.chunkAt(offset);\n\n return this.#chunks[index][offset - this.#starts[index]];\n }\n\n public slice(start: number, end: number = this.length): string {\n if (this.#single !== undefined) {\n return this.#single.slice(start, end);\n }\n\n const from = Math.max(0, Math.min(start, this.length));\n const to = Math.max(from, Math.min(end, this.length));\n\n if (from === to) {\n return \"\";\n }\n\n let index = this.chunkAt(from);\n let result = \"\";\n\n // Concatenation builds a rope, so a slice costs its chunk count until it is read.\n while (index < this.#chunks.length && this.#starts[index] < to) {\n const chunk = this.#chunks[index];\n const chunkStart = this.#starts[index];\n result += chunk.slice(\n Math.max(0, from - chunkStart),\n Math.min(chunk.length, to - chunkStart),\n );\n index++;\n }\n\n return result;\n }\n\n /** The first `search` at or after `from`, scanning chunk by chunk. */\n public indexOf(search: string, from = 0): number {\n const begin = Math.max(0, from);\n\n if (begin >= this.length) {\n return search.length === 0 ? this.length : -1;\n }\n\n for (let index = this.chunkAt(begin); index < this.#chunks.length; index++) {\n const start = Math.max(begin, this.#starts[index]);\n // Reach into the next chunk, so a match across the boundary is found.\n const end = this.#starts[index] + this.#chunks[index].length + search.length - 1;\n const found = this.slice(start, end).indexOf(search);\n\n if (found !== -1) {\n return start + found;\n }\n }\n\n return -1;\n }\n\n /** Finds one matching code unit without joining the chunks. The pattern must be global. */\n public findCharacter(pattern: RegExp, from: number): number {\n for (let index = this.chunkAt(from); index < this.#chunks.length; index++) {\n const start = this.#starts[index];\n // RegExp clamps a negative cursor to zero for later chunks.\n pattern.lastIndex = from - start;\n\n if (pattern.test(this.#chunks[index])) {\n return start + pattern.lastIndex - 1;\n }\n }\n\n return this.length;\n }\n\n /** The last `search`, scanning chunks from the end. Matches may span chunks. */\n public lastIndexOf(search: string): number {\n for (let index = this.#chunks.length - 1; index >= 0; index--) {\n const start = this.#starts[index];\n // Include the end of the previous chunk, so a match across the boundary is found.\n const from = Math.max(0, start - search.length + 1);\n const found = this.slice(from, start + this.#chunks[index].length).lastIndexOf(search);\n\n if (found !== -1) {\n return from + found;\n }\n }\n\n return -1;\n }\n\n public startsWith(search: string, position = 0): boolean {\n return this.slice(position, position + search.length) === search;\n }\n\n /** The whole text. A text in several chunks joins them once. */\n public toString(): string {\n if (this.#joined === undefined) {\n this.#joined = this.#chunks.length === 1 ? this.#chunks[0] : flat(this.#chunks.join(\"\"));\n }\n\n return this.#joined;\n }\n\n private chunkAt(offset: number): number {\n const starts = this.#starts;\n const hint = this.#hint;\n\n if (starts[hint] <= offset && (starts[hint + 1] ?? Infinity) > offset) {\n return hint;\n }\n\n let low = 0;\n let high = starts.length - 1;\n\n while (low < high) {\n const middle = (low + high + 1) >> 1;\n\n if (starts[middle] <= offset) {\n low = middle;\n } else {\n high = middle - 1;\n }\n }\n\n this.#hint = low;\n\n return low;\n }\n}\n\n/** Reading one character makes the engine store a concatenated string flat. */\nfunction flat(value: string): string {\n void value.charCodeAt(0);\n\n return value;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"source-text.mjs","names":[],"sources":["../src/source-text.ts"],"sourcesContent":["/**\n * Immutable text in a few flat chunks, read by absolute offset. Appending makes\n * a new text that shares the chunks before it, so a growing document is never\n * copied whole. Chunks merge like a binary counter, so a text has O(log n)\n * chunks and each character is copied O(log n) times in total.\n */\nexport class SourceText {\n readonly #chunks: readonly string[];\n readonly #starts: readonly number[];\n public readonly length: number;\n #plain: boolean | undefined;\n #joined: string | undefined;\n readonly #single: string | undefined;\n /** The chunk of the last read, since reads cluster around one offset. */\n #hint = 0;\n\n private constructor(\n chunks: readonly string[],\n starts: readonly number[],\n length: number,\n plain: boolean | undefined,\n ) {\n this.#chunks = chunks;\n this.#starts = starts;\n this.#single = chunks.length === 1 ? chunks[0] : undefined;\n this.length = length;\n this.#plain = plain;\n }\n\n public static of(this: void, text: string): SourceText {\n return text.length === 0\n ? new SourceText([], [], 0, true)\n : new SourceText([text], [0], text.length, undefined);\n }\n\n /** Lazily checks for NUL only when a consumer needs normalized grammar text. */\n public get plain(): boolean {\n this.#plain ??= this.#chunks.every((chunk) => !chunk.includes(\"\\0\"));\n\n return this.#plain;\n }\n\n /** The text the parser reads: NUL becomes U+FFFD. */\n public grammar(): SourceText {\n return this.plain ? this : SourceText.of(this.toString().replaceAll(\"\\0\", \"\\uFFFD\"));\n }\n\n /** The same text in one chunk, for complete-document reads. */\n public flatten(): SourceText {\n return this.#chunks.length <= 1\n ? this\n : new SourceText([this.toString()], [0], this.length, this.#plain);\n }\n\n public append(text: string): SourceText {\n if (text.length === 0) {\n return this;\n }\n\n const chunks = [...this.#chunks, text];\n const starts = [...this.#starts, this.length];\n\n // Like a binary counter, a chunk merges into the one before it once it is as large.\n while (\n chunks.length > 1 &&\n chunks[chunks.length - 2].length <= chunks[chunks.length - 1].length\n ) {\n const last = chunks[chunks.length - 1];\n chunks.length--;\n starts.length--;\n chunks[chunks.length - 1] = flat(chunks[chunks.length - 1] + last);\n }\n\n return new SourceText(\n chunks,\n starts,\n this.length + text.length,\n this.plain && !text.includes(\"\\0\"),\n );\n }\n\n /** The character at `offset`, or `undefined` outside the text. */\n public char(offset: number): string | undefined {\n // A complete document is one chunk, so batch parsing reads it like a string.\n if (this.#single !== undefined) {\n return this.#single[offset];\n }\n\n if (offset < 0 || offset >= this.length) {\n return undefined;\n }\n\n const index = this.chunkAt(offset);\n\n return this.#chunks[index][offset - this.#starts[index]];\n }\n\n public slice(start: number, end: number = this.length): string {\n if (this.#single !== undefined) {\n return this.#single.slice(start, end);\n }\n\n const from = Math.max(0, Math.min(start, this.length));\n const to = Math.max(from, Math.min(end, this.length));\n\n if (from === to) {\n return \"\";\n }\n\n let index = this.chunkAt(from);\n let result = \"\";\n\n // Concatenation builds a rope, so a slice costs its chunk count until it is read.\n while (index < this.#chunks.length && this.#starts[index] < to) {\n const chunk = this.#chunks[index];\n const chunkStart = this.#starts[index];\n result += chunk.slice(\n Math.max(0, from - chunkStart),\n Math.min(chunk.length, to - chunkStart),\n );\n index++;\n }\n\n return result;\n }\n\n /** The first `search` at or after `from`, scanning chunk by chunk. */\n public indexOf(search: string, from = 0): number {\n const begin = Math.max(0, from);\n\n if (begin >= this.length) {\n return search.length === 0 ? this.length : -1;\n }\n\n for (let index = this.chunkAt(begin); index < this.#chunks.length; index++) {\n const start = Math.max(begin, this.#starts[index]);\n // Reach into the next chunk, so a match across the boundary is found.\n const end = this.#starts[index] + this.#chunks[index].length + search.length - 1;\n const found = this.slice(start, end).indexOf(search);\n\n if (found !== -1) {\n return start + found;\n }\n }\n\n return -1;\n }\n\n /** Finds one matching code unit without joining the chunks. The pattern must be global. */\n public findCharacter(pattern: RegExp, from: number): number {\n for (let index = this.chunkAt(from); index < this.#chunks.length; index++) {\n const start = this.#starts[index];\n // RegExp clamps a negative cursor to zero for later chunks.\n pattern.lastIndex = from - start;\n\n if (pattern.test(this.#chunks[index])) {\n return start + pattern.lastIndex - 1;\n }\n }\n\n return this.length;\n }\n\n /** The last `search`, scanning chunks from the end. Matches may span chunks. */\n public lastIndexOf(search: string): number {\n for (let index = this.#chunks.length - 1; index >= 0; index--) {\n const start = this.#starts[index];\n // Include the end of the previous chunk, so a match across the boundary is found.\n const from = Math.max(0, start - search.length + 1);\n const found = this.slice(from, start + this.#chunks[index].length).lastIndexOf(search);\n\n if (found !== -1) {\n return from + found;\n }\n }\n\n return -1;\n }\n\n public startsWith(search: string, position = 0): boolean {\n return this.slice(position, position + search.length) === search;\n }\n\n /** The whole text. A text in several chunks joins them once. */\n public toString(): string {\n if (this.#joined === undefined) {\n this.#joined = this.#chunks.length === 1 ? this.#chunks[0] : flat(this.#chunks.join(\"\"));\n }\n\n return this.#joined;\n }\n\n private chunkAt(offset: number): number {\n const starts = this.#starts;\n const hint = this.#hint;\n\n if (starts[hint] <= offset && (starts[hint + 1] ?? Infinity) > offset) {\n return hint;\n }\n\n let low = 0;\n let high = starts.length - 1;\n\n while (low < high) {\n const middle = (low + high + 1) >> 1;\n\n if (starts[middle] <= offset) {\n low = middle;\n } else {\n high = middle - 1;\n }\n }\n\n this.#hint = low;\n\n return low;\n }\n}\n\n/** Reading one character makes the engine store a concatenated string flat. */\nfunction flat(value: string): string {\n void value.charCodeAt(0);\n\n return value;\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@temelj/mdx",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "MDX parsing, formatting, compilation, safe rendering, and streaming.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"markdown",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
}
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@temelj/standard-schema": "0.
|
|
37
|
+
"@temelj/standard-schema": "0.2.0",
|
|
38
38
|
"@temelj/string": "0.15.0",
|
|
39
39
|
"@temelj/value": "0.15.0",
|
|
40
40
|
"acorn": "8.19.0",
|