# pdf2md CLI Tool: How to Convert PDFs to Markdown with Custom Flags

> Easily convert PDFs to Markdown with the pdf2md CLI tool. Explore custom flags for JSON output page filtering password protection and layout analysis. Get started today.

- Repository: [Firecrawl/pdf-inspector](https://github.com/firecrawl/pdf-inspector)
- Tags: how-to-guide
- Published: 2026-08-08

---

**The `pdf2md` command-line tool converts PDF documents to Markdown format with support for JSON output, page filtering, password-protected files, and layout analysis modes.**

The `pdf2md` binary serves as the primary command-line interface for the **firecrawl/pdf-inspector** repository. This Rust-based tool transforms PDF documents into structured Markdown while providing granular control over extraction behavior through various CLI flags. Understanding how `pdf2md` processes arguments and handles different output modes enables developers to integrate PDF conversion efficiently into document processing pipelines.

## How pdf2md Works

The execution flow of `pdf2md` is implemented in [`src/bin/pdf2md.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/bin/pdf2md.rs), where the tool orchestrates argument parsing, option configuration, and result formatting.

### Argument Parsing and Validation

The program reads command-line arguments via `std::env::args()` and validates that at least one positional argument—the PDF file path—is provided. If no path is supplied, the tool prints a usage block (lines 24-30) and exits immediately.

### Flag Detection and Option Building

After validating the input path, `pdf2md` scans the argument vector to detect boolean flags and value-bearing options. The tool constructs a `PdfOptions` struct using `PdfOptions::new().mode(process_mode)` and modifies it according to detected flags between lines 103-119.

Key configuration mappings include:

- Setting `options.markdown.profile` to `MarkdownProfile::Compact` when `--compact` is detected
- Enabling `options.markdown.include_page_numbers` via the `--pages` flag
- Storing page filter specifications in `options.page_filter` from `--select-pages`
- Assigning password values to `options.password` for encrypted documents

### Core Processing Pipeline

The central API call occurs at line 120: `process_pdf_with_options(pdf_path, options)`. This function, defined in the library's public API ([`src/lib.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/lib.rs)), returns a `Result<ProcessingResult, PdfError>` containing the PDF type classification, extracted markdown content, layout information, and OCR requirements. The processing mode determines which components of the `ProcessingResult` populate with data.

### Output Formatting and Result Handling

Depending on the selected mode and output flags, `pdf2md` formats results differently:

- **Detection/Analysis modes** (lines 122-172): Print concise text reports or JSON objects describing PDF type, page count, OCR needs, and table/column detection
- **JSON envelope** (lines 174-187): Wraps markdown output with metadata when `--json` is specified
- **Raw output** (lines 188-195): Emits only the markdown body without diagnostics when using `--raw`
- **Verbose output** (lines 196-260): Displays extraction statistics, friendly headers, and optional file writing

Error handling (lines 260-267) emits either JSON error objects or plain `stderr` messages before exiting with non-zero status.

## Complete List of pdf2md Flags and Options

The `pdf2md` CLI supports several flags that control output format, processing scope, and content handling.

### Output Format Flags

- **`--json`**: Emits a JSON envelope containing metadata and the escaped markdown result string
- **`--items-json`**: Outputs a JSON array of positioned `TextItem` objects including underline metadata
- **`--raw`**: Prints only the markdown body without verbose headers or diagnostic information

### Processing Mode Flags

- **`--detect-only`**: Executes only the PDF-type detector without performing text extraction
- **`--analyze`**: Runs detection, extraction, and layout analysis (tables and columns) while omitting final markdown generation

### Content and Layout Flags

- **`--compact`**: Switches the Markdown profile to compact mode, collapsing token-heavy constructs such as dot leaders
- **`--pages`**: Inserts HTML comments `<!-- Page N -->` as page-break markers in the output

### Filtering and Security Options

- **`--select-pages <spec>`**: Restricts processing to specific pages using comma-separated lists or ranges (e.g., `1,3,5-10`). The specification is parsed by the `parse_page_spec` function (lines 69-102) into a `HashSet<u32>`
- **`--password <pw>`**: Supplies the decryption password for encrypted PDFs. The implementation locates the flag index and reads the subsequent argument (lines 57-65)

## Practical pdf2md Usage Examples

Basic conversion with default verbose output:

```bash
pdf2md report.pdf

```

JSON-encoded result for programmatic processing:

```bash
pdf2md report.pdf --json > result.json

```

Extracting positional text items with metadata:

```bash
pdf2md report.pdf --items-json > items.json

```

Generating compact markdown by collapsing dot leaders:

```bash
pdf2md report.pdf --compact > compact.md

```

Inserting page-break markers:

```bash
pdf2md report.pdf --pages > paged.md

```

Processing password-protected documents with page filtering:

```bash
pdf2md encrypted.pdf --select-pages 2,4-6 --password secret123

```

Running detection without extraction:

```bash
pdf2md report.pdf --detect-only --json

```

Performing layout analysis without markdown generation:

```bash
pdf2md report.pdf --analyze --json

```

## Summary

- The `pdf2md` tool in firecrawl/pdf-inspector provides a thin CLI wrapper around the library's PDF processing pipeline implemented in [`src/bin/pdf2md.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/bin/pdf2md.rs)
- The core workflow parses arguments, builds a `PdfOptions` configuration, and invokes `process_pdf_with_options(pdf_path, options)`
- Output flags (`--json`, `--raw`, `--items-json`) control serialization format while processing flags (`--detect-only`, `--analyze`) determine extraction depth
- The `--select-pages` flag enables partial document processing through the `parse_page_spec` parser
- Error handling supports both JSON and plain-text output modes with appropriate exit codes

## Frequently Asked Questions

### What is pdf2md and which repository maintains it?

The `pdf2md` command-line tool is the primary CLI binary for the **firecrawl/pdf-inspector** open-source repository. It converts PDF documents to Markdown format using Rust-based extraction logic defined in [`src/bin/pdf2md.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/bin/pdf2md.rs) and the underlying library API.

### How do I extract only specific pages from a PDF using pdf2md?

Use the `--select-pages` flag followed by a comma-separated list or range specification (e.g., `1,3,5-10`). According to the firecrawl/pdf-inspector source code, the tool parses this specification using the `parse_page_spec` function (lines 69-102) and stores the resulting `HashSet<u32>` in `options.page_filter` to restrict processing.

### What is the difference between --detect-only and --analyze flags?

The `--detect-only` flag runs only the PDF-type detector in [`src/detector.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/detector.rs) without extracting text, while `--analyze` performs detection plus extraction and layout analysis (identifying tables and columns) but omits the final markdown conversion step. Both modes respect the `--json` flag for structured output.

### How does the --compact flag modify markdown output?

When specified, `--compact` switches `options.markdown.profile` to `MarkdownProfile::Compact`, which triggers post-processing logic in [`src/markdown/postprocess.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/markdown/postprocess.rs) to collapse token-heavy constructs such as dot leaders and reduce vertical whitespace in the generated markdown.