/**
 * Block splitting for streaming markdown.
 *
 * The document is tokenised **once** by the same configured marked instance that renders
 * it (`render.ts`), and every top-level token becomes one block. While streaming only the
 * last block's source keeps changing, so the component re-renders that single block and
 * leaves every earlier block's DOM alone.
 *
 * Because the caller's parser knows about the math extensions, a `$$…$$` span is already a
 * single token here — there is no need to re-detect it in the text. The only regrouping
 * left is structural:
 *
 * - blank-line (`space`) tokens fold into the preceding block, so no empty block elements
 * - an HTML block whose tags are still open swallows the following tokens until they close
 *   (CommonMark ends an HTML block at a blank line, but `<div>` wrapping markdown has to
 *   stay one unit or each half would be parsed — and auto-closed — on its own)
 */
import type { Token, TokensList } from 'marked';
/** Top-level tokens that must be rendered and diffed as one unit. */
export type TokenGroup = Token[];
export declare const hasUnclosedTag: (html: string) => boolean;
export declare const splitTokens: (tokens: TokensList | Token[]) => TokenGroup[];
/**
 * Whether a fenced-code token's fence is still open. Only meaningful for a `code` token
 * (an indented code block has no fence and yields `false`), so callers gate on the token
 * type instead of scanning arbitrary text for something that looks like a fence.
 */
export declare const hasIncompleteCodeFence: (markdown: string) => boolean;
