import { Printer } from "@herb-tools/printer";
import { ParseResult, Node, DocumentNode, HTMLOpenTagNode, HTMLCloseTagNode, HTMLElementNode, HTMLAttributeNode, HTMLAttributeValueNode, HTMLAttributeNameNode, HTMLTextNode, HTMLCommentNode, HTMLDoctypeNode, ERBContentNode, ERBBlockNode, ERBEndNode, ERBElseNode, ERBIfNode, ERBWhenNode, ERBCaseNode, ERBCaseMatchNode, ERBWhileNode, ERBUntilNode, ERBForNode, ERBRescueNode, ERBEnsureNode, ERBBeginNode, ERBUnlessNode, ERBYieldNode, ERBInNode, XMLDeclarationNode, CDATANode, Token } from "@herb-tools/core";
import type { ERBNode } from "@herb-tools/core";
import type { FormatOptions } from "./options.js";
/**
 * Printer traverses the Herb AST using the Visitor pattern
 * and emits a formatted string with proper indentation, line breaks, and attribute wrapping.
 */
export declare class FormatPrinter extends Printer {
    /**
     * @deprecated integrate indentWidth into this.options and update FormatOptions to extend from @herb-tools/printer options
     */
    private indentWidth;
    /**
     * @deprecated integrate maxLineLength into this.options and update FormatOptions to extend from @herb-tools/printer options
     */
    private maxLineLength;
    /**
     * @deprecated refactor to use @herb-tools/printer infrastructre (or rework printer use push and this.lines)
     */
    private lines;
    private indentLevel;
    private inlineMode;
    private currentAttributeName;
    private elementStack;
    private elementFormattingAnalysis;
    source: string;
    constructor(source: string, options: Required<FormatOptions>);
    print(input: Node | ParseResult | Token): string;
    /**
     * Get the current element (top of stack)
     */
    private get currentElement();
    /**
     * Get the current tag name from the current element context
     */
    private get currentTagName();
    /**
     * Append text to the last line instead of creating a new line
     */
    private pushToLastLine;
    /**
     * Capture output from a callback into a separate lines array
     * Useful for testing what output would be generated without affecting the main output
     */
    private capture;
    /**
     * Capture all nodes that would be visited during a callback
     * Returns a flat list of all nodes without generating any output
     */
    private captureNodes;
    /**
     * @deprecated refactor to use @herb-tools/printer infrastructre (or rework printer use push and this.lines)
     */
    private push;
    /**
     * @deprecated refactor to use @herb-tools/printer infrastructre (or rework printer use push and this.lines)
     */
    private pushWithIndent;
    private withIndent;
    private get indent();
    /**
     * Format ERB content with proper spacing around the inner content.
     * Returns empty string if content is empty, otherwise wraps content with single spaces.
     */
    private formatERBContent;
    /**
     * Count total attributes including those inside ERB conditionals
     */
    private getTotalAttributeCount;
    /**
     * Extract inline nodes (non-attribute, non-whitespace) from a list of nodes
     */
    private extractInlineNodes;
    /**
     * Determine if spacing should be added between sibling elements
     *
     * This implements the "rule of three" intelligent spacing system:
     * - Adds spacing between 3 or more meaningful siblings
     * - Respects semantic groupings (e.g., ul/li, nav/a stay tight)
     * - Groups comments with following elements
     * - Preserves user-added spacing
     *
     * @param parentElement - The parent element containing the siblings
     * @param siblings - Array of all sibling nodes
     * @param currentIndex - Index of the current node being evaluated
     * @param hasExistingSpacing - Whether user-added spacing already exists
     * @returns true if spacing should be added before the current element
     */
    private shouldAddSpacingBetweenSiblings;
    /**
     * Check if we're currently processing a token list attribute that needs spacing
     */
    private get isInTokenListAttribute();
    /**
     * Render attributes as a space-separated string
     */
    private renderAttributesString;
    /**
     * Determine if a tag should be rendered inline based on attribute count and other factors
     */
    private shouldRenderInline;
    private wouldClassAttributeBeMultiline;
    private getAttributeName;
    private getAttributeValue;
    private hasMultilineAttributes;
    private formatClassAttribute;
    private isFormattableAttribute;
    private formatMultilineAttribute;
    private formatMultilineAttributeValue;
    private breakTokensIntoLines;
    /**
     * Render multiline attributes for a tag
     */
    private renderMultilineAttributes;
    /**
     * Reconstruct the text representation of an ERB node
     * @param withFormatting - if true, format the content; if false, preserve original
     */
    private reconstructERBNode;
    /**
     * Print an ERB tag (<% %> or <%= %>) with single spaces around inner content.
     */
    printERBNode(node: ERBNode): void;
    visitDocumentNode(node: DocumentNode): void;
    visitHTMLElementNode(node: HTMLElementNode): void;
    visitHTMLElementBody(body: Node[], element: HTMLElementNode): void;
    /**
     * Visit element children with intelligent spacing logic
     */
    private visitElementChildren;
    visitHTMLOpenTagNode(node: HTMLOpenTagNode): void;
    visitHTMLCloseTagNode(node: HTMLCloseTagNode): void;
    visitHTMLTextNode(node: HTMLTextNode): void;
    visitHTMLAttributeNode(node: HTMLAttributeNode): void;
    visitHTMLAttributeNameNode(node: HTMLAttributeNameNode): void;
    visitHTMLAttributeValueNode(node: HTMLAttributeValueNode): void;
    visitHTMLCommentNode(node: HTMLCommentNode): void;
    visitERBCommentNode(node: ERBContentNode): void;
    visitHTMLDoctypeNode(node: HTMLDoctypeNode): void;
    visitXMLDeclarationNode(node: XMLDeclarationNode): void;
    visitCDATANode(node: CDATANode): void;
    visitERBContentNode(node: ERBContentNode): void;
    visitERBEndNode(node: ERBEndNode): void;
    visitERBYieldNode(node: ERBYieldNode): void;
    visitERBInNode(node: ERBInNode): void;
    visitERBCaseMatchNode(node: ERBCaseMatchNode): void;
    visitERBBlockNode(node: ERBBlockNode): void;
    visitERBIfNode(node: ERBIfNode): void;
    visitERBElseNode(node: ERBElseNode): void;
    visitERBWhenNode(node: ERBWhenNode): void;
    visitERBCaseNode(node: ERBCaseNode): void;
    visitERBBeginNode(node: ERBBeginNode): void;
    visitERBWhileNode(node: ERBWhileNode): void;
    visitERBUntilNode(node: ERBUntilNode): void;
    visitERBForNode(node: ERBForNode): void;
    visitERBRescueNode(node: ERBRescueNode): void;
    visitERBEnsureNode(node: ERBEnsureNode): void;
    visitERBUnlessNode(node: ERBUnlessNode): void;
    /**
     * Analyzes an HTMLElementNode and returns formatting decisions for all parts
     */
    private analyzeElementFormatting;
    /**
     * Determines if the open tag should be rendered inline
     */
    private shouldRenderOpenTagInline;
    /**
     * Determines if the element content should be rendered inline
     */
    private shouldRenderElementContentInline;
    /**
     * Determines if the close tag should be rendered inline (usually follows content decision)
     */
    private shouldRenderCloseTagInline;
    private formatFrontmatter;
    /**
     * Append a child node to the last output line
     */
    private appendChildToLastLine;
    /**
     * Visit children in a text flow context (mixed text and inline elements)
     * Handles word wrapping and keeps adjacent inline elements together
     */
    private visitTextFlowChildren;
    /**
     * Wrap remaining words that don't fit on the current line
     * Returns the wrapped lines with proper indentation
     */
    private wrapRemainingWords;
    /**
     * Try to merge text starting with punctuation to inline content
     * Returns object with merged content and whether processing should stop
     */
    private tryMergePunctuationText;
    /**
     * Render adjacent inline elements together on one line
     */
    private renderAdjacentInlineElements;
    /**
     * Render an inline element as a string
     */
    private renderInlineElementAsString;
    /**
     * Render an ERB node as a string
     */
    private renderERBAsString;
    /**
     * Visit remaining children after processing adjacent inline elements
     */
    private visitRemainingChildren;
    /**
     * Build words array from text/inline/ERB and wrap them
     */
    private buildAndWrapTextFlow;
    /**
     * Try to merge text that follows an atomic unit (ERB/inline) with no whitespace
     * Returns true if merge was performed
     */
    private tryMergeTextAfterAtomic;
    /**
     * Try to merge an atomic unit (ERB/inline) with preceding text that has no whitespace
     * Returns true if merge was performed
     */
    private tryMergeAtomicAfterText;
    /**
     * Check if there's whitespace between current node and last processed node
     */
    private hasWhitespaceBeforeNode;
    /**
     * Check if last unit in result ends with whitespace
     */
    private lastUnitEndsWithWhitespace;
    /**
     * Process a text node and add it to results (with potential merging)
     */
    private processTextNode;
    /**
     * Process an inline element and add it to results (with potential merging)
     */
    private processInlineElement;
    /**
     * Process an ERB content node and add it to results (with potential merging)
     */
    private processERBContentNode;
    /**
     * Convert AST nodes to content units with node references
     */
    private buildContentUnitsWithNodes;
    /**
     * Flush accumulated words to output with wrapping
     */
    private flushWords;
    /**
     * Wrap words to fit within line length and push to output
     * Handles punctuation spacing intelligently
     * Excludes herb:disable comments from line length calculations
     */
    private wrapAndPushWords;
    private isInTextFlowContext;
    private renderInlineOpen;
    renderAttribute(attribute: HTMLAttributeNode): string;
    /**
     * Try to render a complete element inline including opening tag, children, and closing tag
     */
    private tryRenderInlineFull;
    /**
     * Check if children contain a leading herb:disable comment (after optional whitespace)
     */
    private hasLeadingHerbDisable;
    /**
     * Try to render just the children inline (without tags)
     */
    private tryRenderChildrenInline;
    /**
     * Try to render children inline if they are simple enough.
     * Returns the inline string if possible, null otherwise.
     */
    private tryRenderInline;
    /**
     * Get filtered children, using smart herb:disable filtering if needed
     */
    private getFilteredChildren;
    private renderElementInline;
    private renderChildrenInline;
}
