/**
 * OwlCoda Markdown-to-ANSI Renderer
 *
 * Lightweight terminal markdown rendering for LLM output.
 * Handles: bold, italic, code, code blocks, headers, lists,
 *          links, tables, task lists, blockquotes, status badges,
 *          and report-style key/value lines.
 * Uses TUI theme colors for consistent appearance.
 *
 * Design note: Strikethrough (~~text~~) is intentionally disabled.
 * LLMs frequently use `~` for approximation (e.g. ~100) which triggers
 * false positives. This keeps rendering predictable for the native terminal UI.
 */
import { type NormalizedLine } from './markdown-normalizer.js';
export declare function renderMarkdown(text: string): string;
/** Stateful renderer for a stream of NormalizedLine tokens, with the v1
 *  spacing rules applied at emit-time:
 *
 *  R1 (heading bracket): each # heading is a singleton block, so consecutive
 *     headings get blank between; entering/leaving any heading inserts blank.
 *  R2 (soft heading): a `text` token whose entire content is `**X**` or
 *     `**X**:` is treated as singleton — same bracketing as R1.
 *  R3 (table bracket): the boxed table block is one logical block; entering
 *     and leaving it inserts blank.
 *  R4 (code bracket): the fenced code block (open + lines + close) is one
 *     block; entering and leaving inserts blank.
 *  R5 (list compactness): consecutive list items share one block-id (no
 *     blanks between); list-to-non-list transitions insert blank.
 *  R6 (paragraph/report break): consecutive paragraph or kvLine rows share
 *     one block-id; crossing into a different text kind inserts blank.
 *  R7 (collapse): never emit two consecutive blanks; collapse to one.
 *  R8 (terminal cap): finalize() trims trailing blanks before returning.
 *
 *  Holds across calls (state):
 *   - codeLang: current fenced-code language for syntax highlighting
 *   - pendingTable: held until next non-table token, then flushed as boxed
 *   - prevKind / currentBlockId / blockCounter: drive spacing decisions
 */
export declare class TokenRenderer {
    private codeLang;
    private pendingTable;
    private prevKind;
    private currentBlockId;
    private blockCounter;
    private lastEmittedBlank;
    render(tokens: NormalizedLine[]): string[];
    finalize(): string[];
    reset(): void;
    /** Emit a rendered ANSI line tagged with a BlockKind. Inserts a boundary
     *  blank before if block-id changes; collapses consecutive blanks. */
    private emit;
    private flushTableTo;
    private handleToken;
}
/** One-shot token rendering — for full-pass renderMarkdown. */
export declare function renderTokens(tokens: NormalizedLine[]): string;
/** Reset ordered list state (call between renderMarkdown calls if needed). */
export declare function resetListState(): void;
/** Render inline markdown: bold, italic, code, links. */
export declare function renderInline(text: string): string;
/**
 * Streaming markdown renderer — buffers incoming text chunks and
 * emits ANSI-rendered output line-by-line as newlines arrive.
 *
 * Supports all block-level elements including code blocks and tables.
 *
 * Usage:
 *   const renderer = new StreamingMarkdownRenderer()
 *   onText(chunk) { const out = renderer.push(chunk); if (out) write(out) }
 *   onEnd()       { const out = renderer.flush(); if (out) write(out) }
 */
export declare class StreamingMarkdownRenderer {
    private buffer;
    private normalizer;
    private renderer;
    /**
     * Feed a text chunk. Returns rendered output for any complete lines.
     * If the buffer grows large without a newline, flushes partial content
     * to avoid the "wall of text with no line breaks" problem.
     *
     * Loops through ALL structural break patterns so that even if a single
     * chunk contains multiple list items, every item gets its own line.
     */
    push(chunk: string): string;
    /**
     * Try to find the EARLIEST structural break in the buffer.
     * Returns the rendered partial line if a break was found, or null.
     * Mutates this.buffer to remove the emitted portion.
     *
     * Uses non-greedy matching to find the FIRST break point, not the last.
     * Minimum thresholds are CJK-aware (8 chars ≈ 16 terminal columns).
     */
    private tryStructuralBreak;
    /** Flush remaining buffer (call at end of response).
     *
     * Drain order:
     *   1. Split any leftover in-flight buffer on no-newline structural
     *      patterns (concatenated list items, mid-line headings, etc.) and
     *      feed each segment through the normalizer + renderer.
     *   2. Drain the normalizer's pending line (if any) — emits as plain
     *      heading-or-text since there's no next line to lookahead at.
     *   3. Drain the renderer's pending table (if any).
     */
    flush(): string;
    /** Reset state for a new response. */
    reset(): void;
    /**
     * Find a suitable break point for CJK text.
     * CJK characters can break between any two characters, but prefer
     * breaking after punctuation (。！？，；：) or before list markers.
     */
    private findCJKBreakPoint;
    /** Process a single complete line through the normalizer + renderer.
     *  Returns null when the line is held (no output yet — pending lookahead
     *  in the normalizer or pendingTable accumulation in the renderer).
     *  Returns rendered text otherwise (may span multiple lines if the
     *  normalizer/renderer flushes a held block on this token). */
    private processLine;
}
