/**
 * Represents a rectangular bounding box with position and dimensions.
 * Used to define the location and size of text elements and structural components
 * within a document coordinate system.
 *
 * The coordinate system typically uses:
 * - Origin (0,0) at the top-left corner of the document
 * - X-axis extending rightward (for LTR text) or leftward (for RTL text after normalization)
 * - Y-axis extending downward
 */
type BoundingBox = Size & {
    /**
     * The x-coordinate of the top-left corner of the bounding box in pixels.
     * This coordinate may be normalized depending on text direction:
     * - For LTR (left-to-right) text: represents distance from left edge
     * - For RTL (right-to-left) text: may be adjusted during processing
     */
    x: number;
    /**
     * The y-coordinate of the top-left corner of the bounding box in pixels.
     * Represents the distance from the top edge of the document.
     */
    y: number;
};
/**
 * Configuration options for determining if text content is centered on a page.
 * These settings control the tolerance and margin requirements for center detection,
 * which is important for identifying titles, headings, and poetic content.
 */
type CenteringOptions = {
    /**
     * The tolerance for center point alignment as a ratio of image width.
     * This determines how precisely text must be centered to be considered "centered".
     *
     * For example:
     * - 0.05 means the observation's center can be within 5% of the page width
     *   from the true center and still be considered centered
     * - 0.02 would require more precise centering (within 2%)
     * - 0.1 would allow looser centering requirements (within 10%)
     *
     * @default 0.05
     */
    readonly centerToleranceRatio: number;
    /**
     * The minimum margin required on each side as a ratio of image width.
     * This ensures that "centered" text has adequate whitespace around it.
     *
     * For example:
     * - 0.1 means there must be at least 10% of the page width as whitespace
     *   on both the left and right sides of the observation
     * - 0.2 would require larger margins (20% on each side)
     * - 0.05 would allow tighter margins (5% on each side)
     *
     * @default 0.1
     */
    readonly minMarginRatio: number;
};
/**
 * Configuration options for the main text line mapping function.
 *
 * This type combines all the configuration needed to process OCR observations
 * into structured text lines, including poetry detection, centering analysis,
 * and layout element detection.
 */
type MapObservationsToTextLinesOptions = CenteringOptions & {
    /**
     * Optional array of horizontal line elements detected in the document.
     * These are typically used to identify sections, headers, footers, or decorative elements.
     * When provided, text appearing below these lines may be classified as footnotes.
     */
    horizontalLines?: BoundingBox[];
    /**
     * Optional fixed line height factor for grouping observations into lines.
     * If not provided, the system will compute an adaptive factor based on document analysis.
     *
     * Typical values:
     * - 0.5: Very tight line grouping
     * - 1.0: Standard line height
     * - 1.5: Generous line spacing tolerance
     */
    lineHeightFactor?: number;
    /**
     * Optional logging function for debugging and monitoring the text processing pipeline.
     * When provided, the system will output detailed information about its decisions
     * and intermediate processing steps.
     *
     * @param message - Primary log message
     * @param args - Additional arguments for formatting or context
     */
    log?: (message: string, ...args: any[]) => void;
    /**
     * Additional vertical tolerance in pixels (at 72 DPI) for line grouping.
     * This value is automatically scaled based on the document's actual DPI.
     *
     * Higher values make line grouping more permissive (more text on same line).
     * Lower values make line grouping stricter (more separate lines).
     *
     * @default 5 pixels at 72 DPI
     */
    pixelTolerance?: number;
    /**
     * Configuration options for poetry detection algorithms.
     * If not provided, default poetry detection settings will be used.
     * Set to null or undefined to disable poetry detection entirely.
     */
    poetryDetectionOptions?: Partial<PoetryDetectionOptions>;
    /**
     * Optional array of rectangular elements detected in the document.
     * These are typically used to identify text boxes, highlighted sections, or headers.
     * When provided, text within these rectangles may be classified as headings.
     */
    rectangles?: BoundingBox[];
};
/**
 * Represents a basic text observation extracted from OCR processing.
 *
 * This is the fundamental unit of OCR output, containing both the recognized
 * text content and its precise location within the document. Observations
 * typically represent individual words or short phrases as identified by
 * the OCR engine.
 */
type Observation = {
    /**
     * The bounding box defining the exact position and dimensions of the text
     * within the document coordinate system. This includes:
     * - Position (x, y) of the top-left corner
     * - Dimensions (width, height) of the text area
     */
    bbox: BoundingBox;
    /**
     * The recognized text content of the observation.
     * This is the actual text string extracted by the OCR engine,
     * which may include punctuation, numbers, or special characters.
     */
    text: string;
};
/**
 * Configuration options to fine-tune the poetry detection algorithm.
 *
 * Poetry detection uses multiple heuristics to identify poetic content:
 * 1. **Paired hemistichs**: Two short lines that appear to be halves of a verse
 * 2. **Merged lines**: Single lines with distinctive spacing/density characteristics
 * 3. **Centering**: Lines that are centered with appropriate margins
 *
 * These options allow fine-tuning of each heuristic to balance precision and recall
 * for different types of documents and poetry styles.
 */
type PoetryDetectionOptions = Partial<CenteringOptions> & {
    /**
     * Maximum allowed vertical gap between observations to be considered a poetry pair.
     * This controls how close two lines must be to be considered hemistichs (halves of a verse).
     *
     * The gap is measured as a ratio of the average height of the two observations:
     * - 2.0 means the gap can be up to 200% of the average line height
     * - 1.5 would require closer spacing (150% of average height)
     * - 3.0 would allow wider spacing (300% of average height)
     *
     * @default 2.0 (200% of average height)
     */
    maxVerticalGapRatio: number;
    /**
     * For merged lines heuristic: The minimum width a line must have to be considered.
     * This prevents very short lines (like page numbers) from being analyzed for poetry.
     *
     * Specified as a ratio of the image width:
     * - 0.6 means the line must span at least 60% of the page width
     * - 0.4 would include shorter lines (40% of page width)
     * - 0.8 would require longer lines (80% of page width)
     *
     * @default 0.6 (60% of image width)
     */
    minWidthRatioForMerged: null | number;
    /**
     * The minimum number of words a line must contain to be considered poetry.
     * This helps filter out noise like page numbers, single-word labels, or artifacts.
     *
     * Higher values reduce false positives but may miss short poetic lines.
     * Lower values increase sensitivity but may include more noise.
     *
     * @default 2
     */
    minWordCount: number;
    /**
     * For paired lines heuristic: How similar in width two hemistichs must be.
     * This determines whether two lines are balanced enough to be verse halves.
     *
     * The similarity check: `|width1 - width2| / average(width1, width2) < ratio`
     * - 0.4 means widths can differ by up to 40% of their average
     * - 0.2 would require more similar widths (20% difference)
     * - 0.6 would allow more variation (60% difference)
     *
     * @default 0.4 (40% width difference allowed)
     */
    pairWidthSimilarityRatio: number;
    /**
     * For paired lines heuristic: How similar in word count two hemistichs must be.
     * This ensures that verse halves have balanced content length.
     *
     * The similarity check: `|count1 - count2| / max(count1, count2) < ratio`
     * - 0.5 means word counts can differ by up to 50% of the larger count
     * - 0.3 would require more similar counts (30% difference)
     * - 0.7 would allow more variation (70% difference)
     *
     * @default 0.5 (50% word count difference allowed)
     */
    pairWordCountSimilarityRatio: number;
    /**
     * For merged lines heuristic: Word density threshold for identifying poetry.
     * Poetry typically has lower word density (more spacing) than prose.
     *
     * A line is considered poetic if its density (words per pixel) is less than
     * this ratio multiplied by the average prose density of the document.
     *
     * - 0.8 means poetic lines should have ≤80% of average prose density
     * - 0.9 would require density closer to prose (≤90%)
     * - 0.7 would require sparser text (≤70% of prose density)
     *
     * @default 0.8 (80% of average prose density)
     */
    wordDensityComparisonRatio: number;
};
/**
 * Represents the dimensions of a rectangular area.
 * Used as a base type for defining size properties in bounding boxes and other geometric shapes.
 */
type Size = {
    /**
     * The height of the rectangular area in pixels.
     */
    readonly height: number;
    /**
     * The width of the rectangular area in pixels.
     */
    readonly width: number;
};
/**
 * A processed text block reconstructed from raw OCR observations.
 *
 * TextBlock represents a higher-level text unit (typically a line or paragraph)
 * that has been assembled from individual OCR observations and enriched with
 * semantic information about its role and characteristics within the document.
 *
 * This type extends the basic Observation with additional metadata that helps
 * in document structure analysis, formatting preservation, and content classification.
 */
type TextBlock = Observation & {
    /**
     * Indicates whether the text is centered on the page.
     *
     * This is determined by analyzing the text's position relative to page margins
     * and ensuring adequate whitespace on both sides. Centered text often indicates:
     * - Document titles and headings
     * - Poetry or verse content
     * - Section headers
     * - Epigraphs or quotes
     *
     * The centering detection uses configurable tolerance and margin ratios
     * to account for slight misalignments and varying document layouts.
     */
    isCentered?: boolean;
    /**
     * Indicates whether this text is identified as a footnote.
     *
     * Footnotes are typically detected by their position relative to horizontal
     * line elements in the document. Text appearing below the last significant
     * horizontal line is often classified as footnote content. This classification
     * helps in:
     * - Separating main content from supplementary information
     * - Proper document structure reconstruction
     * - Academic and formal document processing
     */
    isFootnote?: boolean;
    /**
     * Indicates whether the text represents a heading or title.
     *
     * Headings are often identified by their visual presentation, such as:
     * - Being enclosed within rectangular borders or boxes
     * - Having distinctive spacing or positioning
     * - Being centered or specially formatted
     *
     * This classification helps in:
     * - Document outline generation
     * - Hierarchical content structuring
     * - Navigation and indexing
     */
    isHeading?: boolean;
    /**
     * Indicates whether this text is identified as a line of poetry or verse.
     *
     * Poetic content is detected using multiple heuristics including:
     * - Line length and spacing patterns
     * - Word density analysis
     * - Centering and alignment characteristics
     * - Paired hemistich detection
     *
     * Poetic lines receive special treatment during processing:
     * - They are not merged into standard paragraphs
     * - Line breaks are preserved as semantically significant
     * - Spacing and formatting are maintained more strictly
     *
     * This is crucial for preserving the artistic and structural integrity
     * of poems, verses, and other formatted literary content.
     */
    isPoetic?: boolean;
};

/**
 * Filters out horizontal lines that are contained within any of the provided rectangles.
 *
 * This is useful for removing header/footer lines that appear within document sections
 * while preserving lines that mark true document boundaries or section separators.
 *
 * @param rectangles - Array of rectangles to check containment against
 * @param horizontalLines - Array of horizontal lines to filter
 * @param tolerance - Pixel tolerance for boundary checking (default: 5)
 * @returns Array of horizontal lines that are NOT contained within any rectangle
 */
declare const filterHorizontalLinesOutsideRectangles: (rectangles: BoundingBox[], horizontalLines: BoundingBox[], tolerance?: number) => BoundingBox[];
/**
 * Converts bounding box coordinates from array format to object format.
 * Transforms [x1, y1, x2, y2] coordinates to {x, y, width, height} format.
 *
 * @param box - Array containing [x1, y1, x2, y2] coordinates where (x1,y1) is top-left and (x2,y2) is bottom-right
 * @returns Bounding box object with x, y, width, and height properties
 */
declare const mapMatrixToBoundingBox: (box: [number, number, number, number]) => {
    height: number;
    width: number;
    x: number;
    y: number;
};

/**
 * Calculates the DPI (dots per inch) based on image dimensions and original PDF size.
 *
 * This utility function helps determine the resolution at which a PDF was rasterized
 * by comparing the resulting image dimensions with the original PDF page dimensions.
 * The DPI values are essential for proper scaling of pixel-based tolerances and
 * measurements throughout the document processing pipeline.
 *
 * @param imageSize - Dimensions of the rasterized image in pixels
 * @param pdfSize - Original dimensions of the PDF page in points (1/72 inch)
 * @returns Object containing x and y DPI values
 *
 * @example
 * ```typescript
 * const imageSize = { width: 2480, height: 3508 };
 * const pdfSize = { width: 595, height: 842 }; // A4 page in points
 * const dpi = calculateDPI(imageSize, pdfSize);
 * // Result: { x: 300, y: 300 } for a 300 DPI scan
 * ```
 */
declare const calculateDPI: (imageSize: Size, pdfSize: Size) => {
    x: number;
    y: number;
};

/**
 * Preprocesses observations by filtering noise, flipping coordinates for RTL text,
 * and normalizing x-coordinates for proper alignment.
 *
 * @param observations - Array of text observations to preprocess
 * @param imageWidth - Total width of the document/image in pixels
 * @param dpiX - Horizontal DPI for coordinate normalization
 * @param options - Optional logging configuration
 * @returns Preprocessed observations ready for line grouping
 */
declare const flipAndAlignObservations: (observations: Observation[], imageWidth: number, dpiX: number, options?: Pick<MapObservationsToTextLinesOptions, "log">) => Observation[];
/**
 * Converts OCR observations into structured text lines with metadata.
 *
 * Groups observations into lines based on vertical proximity, applies centering detection,
 * identifies headings (text within rectangles), footnotes (text below horizontal lines),
 * and poetic content. Also performs poetry detection to preserve poetic formatting.
 *
 * @param observations - Array of OCR text observations
 * @param dpi - Document DPI information including width and height
 * @param opts - Configuration options for text line processing
 * @returns Array of text blocks with metadata (centering, headings, footnotes, poetry)
 */
declare const mapObservationsToTextLines: (observations: Observation[], dpi: BoundingBox, opts?: Partial<MapObservationsToTextLinesOptions>) => TextBlock[];
/**
 * Groups text lines into coherent paragraphs, handling both prose and poetry.
 *
 * Prose lines are grouped into paragraphs based on vertical spacing and line width patterns.
 * Poetic lines are preserved individually to maintain their formatting.
 * Processes body content and footnotes separately.
 *
 * @param textLines - Array of text lines to group into paragraphs
 * @param verticalJumpFactor - Factor for detecting paragraph breaks based on vertical spacing (default: 2)
 * @param widthTolerance - Threshold for identifying "short" lines that indicate paragraph breaks (default: 0.85)
 * @returns Array of text blocks representing complete paragraphs
 */
declare const mapTextLinesToParagraphs: (textLines: TextBlock[], verticalJumpFactor?: number, widthTolerance?: number) => TextBlock[];

/**
 * Formats an array of text blocks into a readable string with proper paragraph breaks.
 *
 * @param textBlocks - Array of text blocks to format
 * @param footerSymbol - Optional symbol to insert before the first footnote
 * @returns Formatted text string with proper line breaks and spacing
 */
declare const formatTextBlocks: (textBlocks: TextBlock[], footerSymbol?: string) => string;

export { type BoundingBox, type CenteringOptions, type MapObservationsToTextLinesOptions, type Observation, type PoetryDetectionOptions, type Size, type TextBlock, calculateDPI, filterHorizontalLinesOutsideRectangles, flipAndAlignObservations, formatTextBlocks, mapMatrixToBoundingBox, mapObservationsToTextLines, mapTextLinesToParagraphs };
