How to Get Structured JSON Output from pdf2md: A Complete Guide

Use the --json flag to export the complete extraction metadata or --items-json to retrieve only the positioned text items when converting PDFs with pdf2md.

The pdf2md CLI tool from the firecrawl/pdf-inspector repository converts PDF documents into Markdown format. While default output is human-readable Markdown, the tool supports structured JSON serialization that exposes underlying layout data, font metadata, and processing statistics for downstream automation.

JSON Output Modes

pdf2md provides two distinct JSON serialization strategies controlled via command-line flags:

--json – Returns the complete ProcessResult struct containing the rendered Markdown string, PDF type classification (text-based vs. scanned), OCR routing decisions, confidence scores, warnings, and the full array of extracted TextItem objects.

--items-json – Returns only the extracted TextItem array as a JSON list. This mode provides granular layout data—including coordinates, font metadata, and text content—without the rendered Markdown wrapper, making it ideal for custom layout analysis or database ingestion.

Implementation in the Source Code

The argument parsing and serialization logic resides in src/bin/pdf2md.rs at lines 396–425. The CLI parser detects the literal strings "--json" or "--items-json", sets the corresponding output mode enum, and then serializes either the ProcessResult struct or the raw items vector to stdout using Rust’s JSON serializer.

The core API that produces these data structures is implemented in src/lib.rs, where the process_pdf function returns a ProcessResult. This struct aggregates data from the extraction pipeline, including:

  • markdown – The final rendered Markdown string
  • pdf_type – Classification as "text_based" or "ocr_scanned"
  • pages_routed_to_ocr – Array of page numbers sent to OCR processing
  • items – Vector of TextItem structs containing positional and typographic data

Practical Usage Examples

Extract standard Markdown to stdout:

pdf2md mydoc.pdf

Export the full structured result to a JSON file:

pdf2md mydoc.pdf --json > result.json

Extract only the positioned text items for layout analysis:

pdf2md mydoc.pdf --items-json > items.json

Combine --raw with --json to exclude page headers and dividers from the Markdown output while retaining the JSON structure:

pdf2md mydoc.pdf --raw --json > raw.json

Sample JSON Output

When using --json, the output includes comprehensive metadata:

{
  "pdf_type": "text_based",
  "markdown": "# Title\n\nLorem ipsum dolor sit amet...",

  "pages_routed_to_ocr": [],
  "warnings": [],
  "items": [
    {
      "text": "Title",
      "x": 72.0,
      "y": 50.5,
      "font_name": "Helvetica-Bold",
      "font_size": 24,
      "is_underline": false
    }
  ]
}

When using --items-json, the output is a direct array of these objects without the wrapper metadata.

Key Source Files in the Pipeline

The JSON-producing pipeline spans four critical modules in the firecrawl/pdf-inspector repository:

  • src/bin/pdf2md.rs – The CLI entry point that parses --json and --items-json flags and handles the final serialization to stdout.
  • src/lib.rs – Defines the process_pdf function and the ProcessResult struct that serves as the API boundary for JSON output.
  • src/extractor/mod.rs – Orchestrates font analysis, content-stream parsing, and layout extraction that populate the items array with positional data.
  • src/markdown/convert.rs – Transforms the internal TextItem vectors into Markdown strings included in the JSON payload under the markdown key.

Summary

  • --json exports the complete ProcessResult including rendered Markdown, PDF classification, and extraction metadata.
  • --items-json exports only the TextItem array for applications requiring raw layout coordinates and font data.
  • The serialization logic is implemented in src/bin/pdf2md.rs, which interfaces with the core API in src/lib.rs.
  • Combine --raw with JSON flags to suppress page headers in the Markdown output while maintaining structured data.

Frequently Asked Questions

What is the difference between --json and --items-json in pdf2md?

The --json flag returns a complete wrapper object containing the rendered Markdown, PDF type classification, OCR routing history, and the full items array. The --items-json flag returns only the items array as a flat JSON list, providing just the positioned text elements without the Markdown rendering or document-level metadata.

How can I get raw Markdown content without page headers in the JSON output?

Append the --raw flag alongside --json (e.g., pdf2md doc.pdf --raw --json). This removes page break indicators and document headers from the markdown field in the JSON output while preserving all other structured data in the ProcessResult.

What specific data does each TextItem contain in the JSON output?

Each TextItem object includes the text string, exact X and Y coordinates on the page, font_name (e.g., "Helvetica-Bold"), font_size in points, and boolean flags such as is_underline. These structures are defined in the extraction pipeline and serialized directly from the internal Rust structs.

Where is the JSON serialization logic implemented in the pdf2md source code?

The serialization occurs in src/bin/pdf2md.rs between lines 396 and 425, where the CLI argument parser detects the JSON flags and calls the JSON serializer on either the ProcessResult struct (for --json) or the Vec<TextItem> (for --items-json) before writing to stdout.

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 →