How pdf-inspector Detects Tables in PDFs: A Three-Stage Strategy

pdf-inspector uses a tiered pipeline that attempts rectangle-based detection first, falls back to line-based analysis, and finally applies text-flow heuristics to identify tabular structures in PDF documents.

The firecrawl/pdf-inspector repository implements a sophisticated table detection system written in Rust that processes PDF documents through three distinct algorithms. Each strategy targets different structural cues—ranging from explicit graphics to implicit text patterns—to maximize extraction accuracy across diverse PDF formats. This article examines the technical implementation of these table detection strategies, including source file locations and optimization logic.

The Three-Stage Detection Pipeline

pdf-inspector orchestrates table detection through a fixed priority order defined in src/tables/mod.rs. The pipeline invokes rectangle-based detection first, proceeds to line-based detection if no tables are found, and finally attempts heuristic detection as a fallback. This approach stops as soon as any method yields a valid table layout, ensuring that the most reliable graphics-based methods take precedence over text inference.

The public API in src/tables/mod.rs exposes the three detectors:

pub use detect_rects::{detect_tables_from_rects, RectHintRegion};
pub use detect_lines::{detect_tables_from_lines};
pub use detect_heuristic::{detect_tables_heuristically};

During PDF processing, the process_pdf_with_options function in src/lib.rs executes this logic sequentially, checking for empty results between each stage.

Rectangle-Based Detection with Union-Find Clustering

The most reliable method analyzes PDF drawing rectangles to reconstruct table grids. Implemented in src/tables/detect_rects.rs, this strategy collects filled boxes, cell backgrounds, and rule lines from the page content stream. It then applies a union-find algorithm to cluster these rectangles into coherent cell boundaries.

This method excels when PDFs encode table structure explicitly as vector graphics or background fills. The detect_tables_from_rects function accepts tolerance parameters for rectangle clustering, allowing fine-tuning for documents with slight misalignments.

Line-Based Detection Using H/V Grid Analysis

When rectangle detection returns empty results, pdf-inspector falls back to line-based detection in src/tables/detect_lines.rs. This strategy scans the page for horizontal and vertical line operators, building an H/V line grid from the intersection points. Cell boundaries are inferred where these lines cross, making this approach effective for PDFs that draw tables with straight rules but lack filled backgrounds.

The detect_tables_from_lines function constructs this grid without requiring explicit rectangle objects, capturing tables defined purely by stroked paths.

Heuristic Detection via Text Flow Analysis

The final fallback method, implemented in src/tables/detect_heuristic.rs, operates entirely on text properties when no graphics cues exist. This strategy analyzes gap-histograms between text items, monitors font size variations, and clusters content by body-font characteristics to infer tabular structures.

detect_tables_heuristically handles PDFs where tables exist only as aligned text columns without visible borders. While less precise than graphics-based methods, this ensures pdf-inspector can extract data from scanned documents or minimally formatted reports.

Orchestrating the Detection Pipeline

The integration logic resides in the main processing flow within src/lib.rs. Rather than running all three detectors simultaneously, pdf-inspector implements a short-circuit evaluation:

  1. Call detect_tables_from_rects with page geometry data
  2. If results are empty, invoke detect_tables_from_lines
  3. If still empty, execute detect_tables_heuristically

This tiered approach balances accuracy with performance, avoiding the computational overhead of heuristic analysis when graphical table markers are present.

Usage Examples

Command-Line Interface

The CLI automatically runs the full detection pipeline during Markdown conversion:


# Extract PDF to Markdown with automatic table detection

pdf2md my-report.pdf > my-report.md

# Output structured JSON including detected table cells

pdf2md --json my-report.pdf > my-report.json

Direct Library Integration

For programmatic control, import the table detection modules directly:

use pdf_inspector::lib::process_pdf_with_options;
use pdf_inspector::tables::{detect_rects, detect_lines, detect_heuristic};

fn main() -> anyhow::Result<()> {
    let pdf = pdf_inspector::pdf::PdfDocument::load("my-report.pdf")?;
    
    // Full pipeline with automatic table detection
    let markdown = process_pdf_with_options(&pdf, Default::default())?;
    
    // Manual pipeline control for custom logic
    let page_rects = pdf.page_rects(0)?;
    let rect_tables = detect_rects::detect_tables_from_rects(&page_rects, 3.0, 6)?;
    
    if rect_tables.is_empty() {
        let line_tables = detect_lines::detect_tables_from_lines(&page_rects)?;
        if line_tables.is_empty() {
            let heuristic_tables = detect_heuristic::detect_tables_heuristically(&page_rects)?;
        }
    }
    Ok(())
}

Summary

  • pdf-inspector implements three distinct table detection algorithms in separate Rust modules: rectangle-based, line-based, and heuristic.
  • Detection priority follows a fixed order: rectangles first (most reliable), then lines, then text heuristics (fallback).
  • Rectangle detection (src/tables/detect_rects.rs) uses union-find clustering on PDF drawing operations.
  • Line detection (src/tables/detect_lines.rs) builds grids from horizontal and vertical line operators.
  • Heuristic detection (src/tables/detect_heuristic.rs) analyzes text gaps and font sizes when graphics cues are absent.
  • The pipeline short-circuits at the first successful detection to optimize performance.

Frequently Asked Questions

What order does pdf-inspector try table detection methods?

pdf-inspector attempts detection in the following order: rectangle-based detection first, line-based detection second, and heuristic detection last. This sequence is hardcoded in the pipeline logic to prioritize methods with higher structural certainty over inference-based approaches.

Which method works best for PDFs with visible borders?

Rectangle-based detection yields the most accurate results for PDFs containing explicit borders, filled cell backgrounds, or rule lines. This method analyzes the actual PDF drawing commands rather than inferring structure from text positioning.

How does pdf-inspector handle tables without visible lines?

When neither rectangles nor lines are detected, pdf-inspector falls back to heuristic detection in src/tables/detect_heuristic.rs. This method examines text flow patterns, gap distributions between text elements, and font size clustering to identify columnar data structures.

Can I use a specific detection method instead of the full pipeline?

Yes. While process_pdf_with_options runs the complete pipeline, you can import individual detectors from src/tables/mod.rs and invoke detect_tables_from_rects, detect_tables_from_lines, or detect_tables_heuristically directly on page geometry data for custom extraction logic.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →