Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ragaeeb/kokokor/llms.txt

Use this file to discover all available pages before exploring further.

Function Signature

export const mapObservationsToTextLines = (
  observations: Observation[],
  page: PageContext,
  opts?: Partial<MapObservationsToTextLinesOptions>
): TextBlock[]
Location: src/utils/paragraphs.ts:82

Description

Converts raw OCR observations into structured text lines with rich metadata. This is the first stage of the paragraph reconstruction pipeline. The function performs several operations:
  • Groups observations into lines based on vertical proximity
  • Detects centered text (titles, poetry)
  • Identifies headings (text within rectangles)
  • Detects footnotes (text below horizontal lines)
  • Performs poetry detection to preserve poetic formatting

Parameters

observations
Observation[]
required
Array of OCR text observations to process. Each observation contains:
  • text: The recognized text string
  • bbox: Bounding box with position (x, y) and dimensions (width, height)
page
PageContext
required
Page dimensions and DPI information:
  • width: Page width in pixels
  • height: Page height in pixels
  • dpiX: Horizontal DPI for coordinate normalization
  • dpiY: Vertical DPI for line grouping
opts
Partial<MapObservationsToTextLinesOptions>
Configuration options for text line processing.

Returns

return
TextBlock[]
Array of text blocks with metadata. Each TextBlock contains:
  • text: The merged text content of the line
  • bbox: Bounding box covering the entire line
  • isCentered: Whether the line is centered on the page
  • isHeading: Whether the line is within a rectangle (heading)
  • isFootnote: Whether the line appears below a horizontal line
  • isPoetic: Whether the line is identified as poetry/verse

Example

import { mapObservationsToTextLines } from 'kokokor';

const observations = [
  { text: 'The', bbox: { x: 50, y: 100, width: 30, height: 15 } },
  { text: 'quick', bbox: { x: 85, y: 100, width: 45, height: 15 } },
  { text: 'brown', bbox: { x: 135, y: 100, width: 50, height: 15 } },
  { text: 'fox', bbox: { x: 190, y: 100, width: 30, height: 15 } }
];

const page = {
  width: 612,
  height: 792,
  dpiX: 72,
  dpiY: 72
};

const lines = mapObservationsToTextLines(observations, page, {
  pixelTolerance: 5,
  centerToleranceRatio: 0.05,
  minMarginRatio: 0.1
});

console.log(lines);
// [
//   {
//     text: 'The quick brown fox',
//     bbox: { x: 50, y: 100, width: 170, height: 15 },
//     isCentered: false,
//     isHeading: false,
//     isFootnote: false,
//     isPoetic: false
//   }
// ]

Notes

  • Observations are preprocessed by filtering noise and normalizing coordinates
  • For RTL text, set isRTL: true to flip x-coordinates appropriately
  • Poetry detection uses multiple heuristics: paired hemistichs, word density, and centering
  • Lines marked as isPoetic will not be merged into paragraphs by mapTextLinesToParagraphs
  • The function automatically calculates adaptive line height if lineHeightFactor is not provided