//#region src/types.d.ts
/**
 * 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[]; /** Are the coordinates from a RTL language? If it is we would flip the x-axis. */
  isRTL?: boolean;
  /**
   * 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>;
  /**
   * Delimiter used when merging a detected poetry pair (hemistichs) into a single line.
   *
   * Example: `" ... "` formats a pair as `صدر ... عجز`.
   *
   * @default " "
   */
  poetryPairDelimiter?: string;
  /**
   * 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[];
};
/**
 * Options for grouping text lines into paragraphs.
 *
 * These options replace positional arguments with named fields so callers can
 * tune behavior without relying on parameter ordering.
 */
type ParagraphOptions = {
  /**
   * Factor for detecting paragraph breaks based on vertical spacing.
   *
   * Higher values make break detection stricter.
   *
   * @default 2
   */
  verticalJumpFactor?: number;
  /**
   * Threshold for identifying short lines that indicate paragraph endings.
   *
   * Lower values mark fewer lines as "short".
   *
   * @default 0.85
   */
  widthTolerance?: number;
};
/**
 * 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;
};
/**
 * Canonical page metadata required for reconstruction.
 */
type PageContext = {
  /**
   * Page width in pixels.
   */
  width: number;
  /**
   * Page height in pixels.
   */
  height: number;
  /**
   * Horizontal DPI.
   */
  dpiX: number;
  /**
   * Vertical DPI.
   */
  dpiY: number;
};
/**
 * Optional layout primitives extracted from a page.
 */
type LayoutElements = {
  /**
   * Horizontal separators used for footnote boundary detection.
   */
  horizontalLines?: BoundingBox[];
  /**
   * Rectangles used for heading/boxed-content detection.
   */
  rectangles?: BoundingBox[];
};
/**
 * Input payload for one-shot paragraph reconstruction.
 */
type ReconstructInput = {
  /**
   * OCR observations to reconstruct.
   */
  observations: Observation[];
  /**
   * Page geometry and DPI context.
   */
  page: PageContext;
  /**
   * Optional structural layout hints.
   */
  layout?: LayoutElements;
};
/**
 * Optional knobs for one-shot paragraph reconstruction.
 */
type ReconstructOptions = {
  /**
   * Line-detection options.
   */
  line?: Partial<MapObservationsToTextLinesOptions>;
  /**
   * Paragraph-detection options.
   */
  paragraph?: ParagraphOptions;
  /**
   * Text formatting options.
   */
  format?: {
    /**
     * Optional symbol to insert before first footnote.
     */
    footerSymbol?: 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;
};
/**
 * Output payload from one-shot paragraph reconstruction.
 */
type ReconstructResult = {
  /**
   * Intermediate line-level blocks.
   */
  lines: TextBlock[];
  /**
   * Final paragraph-level blocks.
   */
  paragraphs: TextBlock[];
  /**
   * Formatted plain text output.
   */
  text: string;
};
//#endregion
//#region src/utils/grouping.d.ts
/**
 * Merges the group of observations into a single one.
 * @param group The group of observations to merge.
 * @param delimiter Text delimiter used when concatenating observations.
 * @returns A single observation with the text of the group concatenated as well as the bounding box adjusted to fit all of the contents.
 */
declare const mergeObservations: <T extends Observation>(group: T[], delimiter?: string) => T;
//#endregion
//#region src/utils/layout.d.ts
/**
 * 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;
};
//#endregion
//#region src/utils/marking.d.ts
/**
 * 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;
};
//#endregion
//#region src/utils/options.d.ts
/**
 * Resolves optional overrides against a default options object.
 *
 * This is a shallow merge helper intended for option bags where
 * top-level keys are merged and nested objects are handled explicitly
 * by the caller when needed.
 */
declare const resolveWithDefaults: <T extends object>(defaults: T, overrides?: Partial<T>) => T;
//#endregion
//#region src/utils/paragraphs.d.ts
/**
 * 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?: Partial<Pick<MapObservationsToTextLinesOptions, "isRTL" | "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 page - Page dimensions and DPI information.
 * @param opts - Configuration options for text line processing
 * @returns Array of text blocks with metadata (centering, headings, footnotes, poetry)
 */
declare const mapObservationsToTextLines: (observations: Observation[], page: PageContext, 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 options - Object-based paragraph detection settings.
 * @returns Array of text blocks representing complete paragraphs
 */
declare const mapTextLinesToParagraphs: (textLines: TextBlock[], options?: ParagraphOptions) => TextBlock[];
//#endregion
//#region src/index.d.ts
/**
 * 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;
/**
 * One-shot API for OCR paragraph reconstruction.
 *
 * Converts observations into lines, groups lines into paragraphs, then formats text.
 */
declare const reconstructParagraphs: (input: ReconstructInput, options?: ReconstructOptions) => ReconstructResult;
//#endregion
export { BoundingBox, CenteringOptions, LayoutElements, MapObservationsToTextLinesOptions, Observation, PageContext, ParagraphOptions, PoetryDetectionOptions, ReconstructInput, ReconstructOptions, ReconstructResult, Size, TextBlock, calculateDPI, filterHorizontalLinesOutsideRectangles, flipAndAlignObservations, formatTextBlocks, mapMatrixToBoundingBox, mapObservationsToTextLines, mapTextLinesToParagraphs, mergeObservations, reconstructParagraphs, resolveWithDefaults };
//# sourceMappingURL=index.d.ts.map