/** * Raw-HTML block detection for the markdown preview. The shared `MarkdownText` * renders raw HTML as literal text (a chat-security stance), so a GitHub-style * README (`
` badge walls, `
` collapsibles with * markdown inside, table cells full of inline tags) previews as source soup. * This module's pure splitter lifts those HTML runs OUT of the markdown stream * before rendering: markdown runs keep flowing through `MarkdownText` (shiki / * KaTeX / GFM intact, mermaid chunk path unchanged) while HTML runs render as * sanitized DOM (see markdown-html.tsx). * * Splitting follows CommonMark's shape closely enough for real-world READMEs: * a line outside code fences that starts with a block-level tag (type-6 list * below) or ``). Inline-only tags (``, `
`, * ``…) never open a run — they stay in the markdown stream and are handled * by the inline pass instead. Unclosed block tags (`
` … markdown … * `
`) are surfaced by {@link analyzeHtmlSegment} as ordered parts so * the renderer can nest the in-between markdown inside the open element, the * way GitHub's linear HTML output nests. */ /** A run of raw HTML lines lifted out of the markdown stream. */ export interface HtmlSegment { kind: 'html'; text: string; } /** A run of markdown source (may contain non-mermaid fences, inline HTML…). */ export interface MarkdownHtmlSegment { kind: 'markdown'; text: string; } export type MdHtmlSegment = MarkdownHtmlSegment | HtmlSegment; /** The doc-wide analysis the preview consumes (all pure, unit-tested here). */ export interface AnalyzedMarkdownHtml { /** The document split into markdown / html runs (empty input → []). */ segments: MdHtmlSegment[]; /** True when at least one html run was lifted out. */ hasBlockHtml: boolean; /** True when the source contains any tag-like text (block OR inline). */ hasInlineHtml: boolean; /** Every reference definition found in the markdown runs (`[label]: dest` * lines), joined — appended to each markdown run so `[text][id]` keeps * resolving across the lifted HTML runs (first-match wins makes the * appended copy inert inside runs that already define it). */ referenceDefinitions: string; } /** * CommonMark HTML-block type-6 tag names (block-level elements), lowercased. * A line starting with one of these (open or close) outside a fence begins an * HTML run. `` is CommonMark-inline but intentionally included: it is * the idiomatic first child of a `
` run in GitHub-flavored READMEs. */ export declare const HTML_BLOCK_TAGS: ReadonlySet; /** One structural piece of a lifted HTML run, in document order. */ export type HtmlPart = { kind: 'html'; html: string; } | { kind: 'open'; tag: string; attrs: string; } | { kind: 'close'; tag: string; }; /** The run's structure relative to the surrounding document nesting. */ export interface HtmlSegmentShape { parts: HtmlPart[]; } /** * Reduce a lifted HTML run to ordered parts: balanced spans become `html` * leaves, unclosed open tags become `open` (a wrapper the renderer lowers * following markdown runs into), unmatched closes become `close` (pops one * wrapper level). A mismatched close pops through the matching open — the * HTML parser's implicit-close behavior. Runs with no structural tags reduce * to a single `html` part. */ export declare function analyzeHtmlSegment(source: string): HtmlSegmentShape; /** * Split markdown source into markdown / html runs (fence-aware: an HTML-looking * line inside any fenced code block is content, not a run start). Blank lines * terminate HTML runs and are dropped between segments (they carry no markdown * semantics the preview needs); everything else stays byte-identical. */ export declare function splitHtmlBlocks(text: string): MdHtmlSegment[]; /** * Collect the reference definitions of every markdown run (HTML runs cannot * define them), in document order, newline-joined for appending. */ export declare function collectReferenceDefinitions(segments: readonly MdHtmlSegment[]): string; /** * The whole-document gate + split the preview consumes. `hasInlineHtml` is a * cheap source-level regex (code-fence content may false-positive; the inline * pass skips rendered code blocks anyway, so a false positive only costs the * enhanced render path, never a behavior change). */ export declare function analyzeMarkdownHtml(text: string): AnalyzedMarkdownHtml;