How to Use the pdf2md CLI for Fast PDF Text Extraction
The pdf2md CLI tool converts PDF documents to Markdown or structured JSON, handling both native text and scanned documents through automatic OCR detection.
The pdf2md CLI is the primary command-line interface provided by the firecrawl/pdf-inspector repository. Built in Rust and optimized for speed, this tool extracts content from PDF files and emits clean Markdown or machine-readable JSON. Whether processing text-based reports or image-heavy scanned documents, the pdf2md CLI automatically detects document types and applies the appropriate extraction strategy.
Basic Markdown Extraction
To extract text from a PDF and save it as a Markdown file, pass the file path as the first argument.
pdf2md my-document.pdf > output.md
This command reads the entire PDF and outputs formatted Markdown to stdout. The tool handles font resolution, reading order reconstruction, and layout analysis automatically.
Structured JSON Output
For downstream processing pipelines that require bounding boxes, semantic roles, or table structures, use the --json flag.
pdf2md --json my-document.pdf > output.json
According to the source code in src/markdown/convert.rs, the JSON schema includes hierarchical text items, table structures, and semantic classifications. This structured format preserves positional data and document hierarchy that plain Markdown flattens.
Extracting Specific Page Ranges
Limit extraction to specific pages using the --pages flag with 1-based indexing.
# Extract pages 5 through 10
pdf2md --pages 5-10 my-document.pdf > selected_pages.md
# Extract from page 7 to the end
pdf2md --pages 7- my-document.pdf > from_page_seven.md
The range syntax supports single pages (5), inclusive ranges (5-10), and open-ended ranges (7-).
How pdf2md Processes PDFs Internally
Understanding the extraction pipeline helps optimize usage. The implementation in src/bin/pdf2md.rs orchestrates six distinct phases, utilizing the public API exposed in src/lib.rs.
PDF Loading and Parsing
The CLI uses the lopdf crate to open files and read page objects. This low-level parsing handles the PDF document structure, xref tables, and object streams before content extraction begins.
Document Type Detection
Before extraction, the detector module at src/detector.rs classifies the document as TextBased, Scanned, Mixed, or ImageBased. This classification determines whether the pipeline triggers OCR processing for scanned content or proceeds with direct text extraction.
Content Stream Extraction
The extractor orchestrator in src/extractor/mod.rs walks content streams, resolves fonts via src/extractor/fonts.rs, and collects text items defined in src/types.rs. This phase captures raw text with precise positional metadata and font information.
Layout Reconstruction
Complex layouts require sophisticated analysis. The modules in src/markdown/* perform column detection, table detection, and reading-order reconstruction. The preprocessor at src/markdown/preprocess.rs merges drop caps and heading lines, while src/markdown/postprocess.rs cleans hyphenation, removes dot leaders, and formats URLs.
Markdown Generation
The convert.rs module transforms internal line representations into clean Markdown. This phase applies heading detection, list formatting, and structural heuristics to produce human-readable output.
Optional JSON Serialization
When --json is specified, the same internal representation serializes to JSON, including bounding boxes and semantic classifications as defined in the conversion module.
Debugging Extraction Layout
To inspect layout decisions and troubleshoot formatting issues, enable Rust logging for the extractor layout module.
RUST_LOG=pdf_inspector::extractor::layout=debug pdf2md my-document.pdf
This environment variable configuration reveals debug information about column detection, text ordering, and structural classification during the extraction process.
Summary
- The
pdf2mdCLI provides fast Rust-based PDF extraction with automatic OCR detection for scanned documents. - Basic extraction converts full PDFs to Markdown via
pdf2md file.pdf. - Structured data is available through the
--jsonflag, returning bounding boxes and semantic roles fromsrc/markdown/convert.rs. - Page ranges use 1-based indexing with syntax like
--pages 5-10to limit processing scope. - Internal pipeline spans from
src/bin/pdf2md.rsentry point throughsrc/detector.rs,src/extractor/mod.rs, and thesrc/markdown/*processing modules.
Frequently Asked Questions
How does pdf2md handle scanned PDFs versus text-based PDFs?
The tool calls the detector module in src/detector.rs to classify documents as TextBased, Scanned, Mixed, or ImageBased. Scanned documents trigger OCR processing automatically, while text-based PDFs extract directly from content streams without optical recognition, as implemented in the extractor orchestrator at src/extractor/mod.rs.
What is the difference between Markdown and JSON output modes?
Markdown output provides human-readable text with formatting preserved, generated by src/markdown/convert.rs. JSON output (--json) returns a structured object containing text items, bounding boxes, table structures, and semantic classifications suitable for programmatic processing and downstream analysis pipelines.
Can I extract text from only specific pages using pdf2md?
Yes. Use the --pages flag with 1-based indexing. Specify single pages (--pages 5), inclusive ranges (--pages 5-10), or open-ended ranges (--pages 7-) to limit extraction to the desired content without processing the entire document.
How do I troubleshoot layout issues when text appears in the wrong order?
Set the environment variable RUST_LOG=pdf_inspector::extractor::layout=debug before running the command. This enables debug logging for the layout reconstruction phase in src/extractor/mod.rs, revealing how the tool interprets columns, reading order, and structural heuristics during processing.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →