pdf2md CLI Options Explained: `--json`, `--items-json`, `--compact`, `--pages`, and `--select-pages`

The pdf2md binary supports structured JSON output (--json, --items-json), compact Markdown formatting (--compact), and page-level control (--pages, --select-pages) to customize PDF-to-Markdown extraction.

The pdf2md command-line tool is the Rust binary distributed with firecrawl/pdf-inspector. It wraps the core pdf-inspector library and exposes extraction controls through a small set of well-defined flags. These options determine output format, verbosity, and which pages to process.

How pdf2md Parses CLI Flags

All option handling lives in src/bin/pdf2md.rs. The binary builds a PdfOptions struct from command-line arguments, then passes it to process_pdf_with_options in src/lib.rs. This keeps the CLI thin and decouples user-facing flags from the extraction engine.

The argument parser uses a simple iterative scan of std::env::args():

// From src/bin/pdf2md.rs — simplified pattern
let json_output = args.iter().any(|a| a == "--json");
let items_json = args.iter().any(|a| a == "--items-json");
let compact = args.iter().any(|a| a == "--compact");
let pages_only = args.iter().any(|a| a == "--pages");

Each flag sets a corresponding field on the options struct before the PDF is loaded.

Output Format Options

--json: Full Document as Structured JSON

The --json flag serializes the entire extraction result as a single JSON object. This includes:

  • Detected document structure (headings, paragraphs, lists)
  • Table metadata (rows, cells, headers)
  • Font and layout annotations
  • Bounding box coordinates

Use case: Integrating with downstream pipelines that consume structured data rather than Markdown text.

pdf2md report.pdf --json > report.json

Internally, this triggers PdfResult::as_json() in src/markdown/analysis.rs.

--items-json: Streaming JSON Lines

The --items-json flag emits each extracted item as a separate JSON line (newline-delimited JSON). Items include individual text lines, table cells, and images.

Use case: Streaming processors, incremental indexing, or tools like jq that work line-by-line.

pdf2md report.pdf --items-json > report.ndjson

This calls PdfResult::as_items_json(), which iterates over the internal Vec<PdfItem> and serializes each independently.

Markdown Formatting Options

--compact: Minified Markdown Output

The --compact flag enables a token-saving output profile. The extractor still produces valid Markdown, but with:

  • Collapsed consecutive whitespace
  • Omitted optional line breaks
  • Tighter heading and list formatting

Use case: LLM context windows where token count matters, or storage-constrained environments.

pdf2md report.pdf --compact > report_compact.md

The flag sets options.compact = true, which markdown::convert::render respects by skipping pretty-printing passes. The help string confirms this behavior: eprintln!(" --compact Output compact Markdown") at lines 226–236 of src/bin/pdf2md.rs.

Page Selection Options

--pages: List Extractable Pages

The --pages flag does not extract content. Instead, it outputs a JSON array of page numbers that contain at least one extractable text element.

Use case: Pre-flight checks to determine which pages merit full processing, especially for scanned documents with mixed content.

pdf2md report.pdf --pages

# Output: [1, 3, 4, 7, 12]

The implementation calls PdfResult::pages_json(), which gathers indices from the internal PdfDocument.page_items map.

--select-pages <spec>: Targeted Extraction

The --select-pages flag limits extraction to a specific page subset. The <spec> argument accepts:

  • Single pages: 5
  • Comma-separated lists: 1,3,7
  • Inclusive ranges: 10-20
  • Mixed: 1,3,5-10,15
pdf2md report.pdf --select-pages 1,3,5-10 --json > subset.json

The parser consumes the token following --select-pages and builds a PageSelection struct. The extractor then skips any page not in the selection set, reducing I/O and processing time for large documents.

Complete Command Reference

Flag Argument Effect
--json none Single JSON object with full structure
--items-json none One JSON line per extracted item
--compact none Minified Markdown without extra whitespace
--pages none JSON array of pages with extractable content
--select-pages <pagespec> Restrict extraction to specified pages
--raw none Plain text without Markdown formatting

Example Workflows

Structured data pipeline:

pdf2md invoice.pdf --json | jq '.tables[0].rows' > table_data.json

Incremental processing of a large document:

pdf2md textbook.pdf --items-json | head -1000 | jq -c 'select(.type == "heading")'

Token-optimized LLM ingestion:

pdf2md research_paper.pdf --compact --select-pages 1,5-8 > llm_context.md

Discover content distribution before full extraction:

pdf2md scanned_report.pdf --pages

# Then: pdf2md scanned_report.pdf --select-pages 2,7,12-15 --json

Summary

  • --json produces a single structured JSON object via PdfResult::as_json().
  • --items-json streams per-item JSON lines via PdfResult::as_items_json().
  • --compact trims whitespace in Markdown output through options.compact.
  • --pages returns a JSON array of extractable page numbers without processing content.
  • --select-pages restricts extraction to user-specified pages using the PageSelection parser.

All flags are defined in src/bin/pdf2md.rs and operate by configuring PdfOptions before calling process_pdf_with_options from src/lib.rs.

Frequently Asked Questions

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

--json outputs one complete JSON object containing the entire document structure—headings, paragraphs, tables, and metadata as nested fields. --items-json outputs each extracted element as its own JSON line, useful for streaming and line-oriented tools. Choose --json for document-level analysis and --items-json for item-level filtering.

Does --compact affect JSON output?

No. The --compact flag only affects Markdown generation in markdown::convert::render. JSON output from --json and --items-json is always minified (no extra whitespace) because the serializer uses default compact formatting. To pretty-print JSON, pipe through jq . or similar.

Can --select-pages and --pages be used together?

Yes, but it is usually redundant. --pages simply lists which pages contain text; --select-pages then extracts from a subset. A typical workflow runs --pages first to inspect the document, then runs --select-pages with specific values for the actual extraction.

How does pdf2md handle invalid page specifications?

The PageSelection parser in src/lib.rs validates the specification against the actual page count of the loaded PDF. Out-of-range pages are silently ignored. Malformed specifications (non-numeric characters, unclosed ranges) typically cause the CLI to print usage information and exit with a non-zero status.

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 →