How to Use the `detect-pdf` CLI for PDF Classification

The detect-pdf CLI classifies PDFs into TextBased, Scanned, or Mixed categories using heuristics that measure extractable text versus image content.

The detect-pdf command-line tool is part of the firecrawl/pdf-inspector repository, a Rust-based library for analyzing PDF documents. This guide explains how to install, run, and integrate the tool for reliable PDF classification.

What detect-pdf Does

The tool categorizes any PDF into one of three classifications based on content analysis:

Classification Description
TextBased PDF contains extractable, machine-readable text (e.g., exported from Word or generated from HTML)
Scanned PDF consists primarily of page images with minimal or no extractable text
Mixed PDF contains both extractable text layers and scanned image content

This classification helps downstream tools decide whether to apply OCR, direct text extraction, or hybrid processing pipelines.

Installation and Basic Usage

Build from source

git clone https://github.com/firecrawl/pdf-inspector.git
cd pdf-inspector
cargo build --release --bin detect-pdf

The binary will be available at target/release/detect-pdf.

Basic classification command

detect-pdf path/to/document.pdf

Example output:


TextBased

CLI Options and Output Formats

JSON output (--json)

Add --json to receive structured output suitable for scripting:

detect-pdf --json path/to/document.pdf

Example output:

{
  "classification": "Mixed",
  "confidence": 0.87,
  "details": {}
}

Detailed analysis (--analyze)

Add --analyze to include diagnostic details about how the classification was determined:

detect-pdf --analyze --json path/to/document.pdf

Example output:

{
  "classification": "Scanned",
  "confidence": 0.95,
  "details": {
    "image_pages": 12,
    "text_ratio": 0.03,
    "tiled_scan": true,
    "garbage_text_upgrade": true
  }
}

The tiled_scan flag indicates the detector found evidence of tiled scanning patterns common in digitized documents. The garbage_text_upgrade flag shows when low-quality extracted text triggered a promotion from Mixed to Scanned.

Architecture and Source Code

Understanding the implementation helps debug unexpected classifications and extend the tool.

Entry point: src/bin/detect_pdf.rs

The CLI binary lives in src/bin/detect_pdf.rs. It:

  • Parses arguments using clap
  • Calls process_pdf_with_options from the library
  • Formats results as plain text or JSON

Core detection: src/detector.rs

The src/detector.rs module implements the classification heuristics:

  • Text extraction rate: Measures how much alphanumeric text can be extracted from content streams
  • Image analysis: Inspects page objects for raster images and detects tiled-scan patterns
  • Mixed-mode logic: Combines signals and applies a garbage-text upgrade rule that promotes Mixed to Scanned when extracted text falls below 50% alphanumeric

Public API: src/lib.rs

The src/lib.rs file exposes process_pdf_with_options(), the same function the CLI uses. This design allows embedding the classifier in other Rust projects or FFI bindings.

Supporting modules

File Purpose
src/text_quality.rs Computes alphanumeric ratios and text quality metrics
src/extractor/* Low-level PDF parsing for fonts, content streams, and image objects

Programmatic Usage in Rust

Import pdf-inspector as a library for custom workflows:

use pdf_inspector::process_pdf_with_options;
use pdf_inspector::ProcessOptions;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let opts = ProcessOptions {
        json: true,
        analyze: true,
        ..Default::default()
    };

    let result = process_pdf_with_options("path/to/document.pdf", opts)?;
    println!("{}", result);
    Ok(())
}

The ProcessOptions struct mirrors CLI flags:

Field Type Description
json bool Emit JSON instead of plain text
analyze bool Include detailed diagnostic fields

Integration with pdf2md

The detect-pdf tool shares its core library with the pdf2md binary in the same repository. Classification results drive processing strategy:

  • TextBased → Direct text extraction without OCR
  • Scanned → Full OCR pipeline
  • Mixed → Hybrid approach extracting text layers and OCR-ing image regions

This architecture prevents wasted computation on already-readable documents.

Summary

  • The detect-pdf CLI provides fast, accurate PDF classification into TextBased, Scanned, or Mixed categories
  • Use --json for programmatic consumption and --analyze for debugging classification decisions
  • The underlying Rust library (src/lib.rs) exposes process_pdf_with_options() for custom integrations
  • Detection heuristics in src/detector.rs combine text ratio, image analysis, and tiled-scan detection
  • Source files: src/bin/detect_pdf.rs (CLI), src/detector.rs (logic), src/text_quality.rs (metrics)

Frequently Asked Questions

What Rust version is required to build detect-pdf?

The firecrawl/pdf-inspector repository uses Rust 2021 edition features. Build with Rust 1.70 or later to ensure compatibility with dependencies such as pdf-extract and tesseract bindings.

Can detect-pdf handle password-protected PDFs?

No. The tool does not implement decryption logic. Pre-process encrypted PDFs with qpdf --decrypt or similar tools before classification, as the underlying src/extractor/* modules expect readable content streams.

How accurate is the Mixed vs. Scanned distinction?

The garbage-text upgrade rule in src/detector.rs promotes borderline cases to Scanned when alphanumeric content falls below 50%. This conservative approach reduces false positives for OCR pipelines but may over-classify low-quality text PDFs. Use --analyze to review the text_ratio field and tune thresholds if you fork the detector.

Is there a Python or Node.js binding available?

Not officially. The repository provides only Rust APIs. Community bindings would need to wrap process_pdf_with_options() via PyO3 or napi-rs. For Python workflows, consider shelling out to the CLI or using the classification output to conditionally invoke Python OCR libraries.

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 →