ExPdfInspector
Elixir bindings for Firecrawl's pdf-inspector,
implemented as a Rust NIF with Rustler.
ExPdfInspector classifies PDFs as text-based, scanned, image-based, or mixed; identifies the pages that should be sent to OCR; extracts text and positional metadata; and converts native PDF text to Markdown. Processing is local: the library does not upload documents or call an external service, and it does not perform OCR itself.
Features
- Process a PDF from a file path or an in-memory binary.
- Classify documents and return a confidence score.
- Identify individual pages that need OCR and explain why.
- Extract plain text or positioned text items with font and style metadata.
- Produce Markdown for a whole document or selected pages.
- Configure detection, extraction, layout analysis, and Markdown generation.
- Handle password-protected PDFs when a password is supplied.
Installation
Add ex_pdf_inspector to your dependencies:
def deps do
[
{:ex_pdf_inspector, "~> 0.1.0"}
]
end
The NIF is compiled when the dependency is built. A working Rust toolchain with Cargo must therefore be available in the build environment. Install one from rustup.rs if necessary, then run:
mix deps.get
mix compile
Quick start
Process a file and use native extraction when possible:
case ExPdfInspector.process_pdf("document.pdf") do
{:ok, %{pdf_type: :text_based, markdown: markdown}} ->
markdown
{:ok, %{pages_needing_ocr: pages}} ->
{:send_to_ocr, pages}
{:error, %{code: code, message: message}} ->
{:error, {code, message}}
end
The same operation accepts PDF bytes:
pdf = File.read!("document.pdf")
{:ok, result} = ExPdfInspector.process_pdf_bytes(pdf)
Detection can be run without Markdown extraction:
{:ok, result} = ExPdfInspector.detect_pdf("document.pdf")
result.pdf_type
#=> :text_based
Customize the processing pipeline with option structs:
alias ExPdfInspector.{DetectionOptions, MarkdownOptions, PdfOptions}
options = %PdfOptions{
mode: :full,
page_filter: [0, 2],
detection: %DetectionOptions{strategy: :full},
markdown: %MarkdownOptions{profile: :compact}
}
{:ok, result} = ExPdfInspector.process_pdf("document.pdf", options)
Page indexes in page_filter and the page-extraction functions are zero-based.
The pages_needing_ocr field returned by the underlying library uses human-readable
page numbers. See the Getting Started and
Processing and Options guides for the complete
workflow and option reference.
Errors
Functions that read or process PDFs return {:ok, value} or
{:error, %{code: code, message: message}}. Codes are stable atoms defined by
the library (:io_error, :not_a_pdf, :invalid_structure, :parse_error, and
:encrypted), making them safe and convenient for pattern matching. Error
messages remain strings. For example:
case ExPdfInspector.process_pdf(path) do
{:error, %{code: :encrypted}} -> {:error, :password_required}
other -> other
end
Invalid Elixir argument types still raise an exception at the NIF boundary.
Safety and scheduling
PDF work runs on BEAM dirty CPU schedulers so it does not block regular schedulers. As with any native dependency, a defect in NIF code can affect the entire VM; validate untrusted input and apply resource limits appropriate to your application.
Documentation
The complete API reference is available on
HexDocs. Documentation for the Rust library
is maintained by Firecrawl in the
pdf-inspector repository.
Acknowledgements
This package is an independent Elixir NIF wrapper around the
pdf-inspector crate created and
maintained by Firecrawl. Firecrawl owns the
original Rust implementation and deserves credit for the PDF inspection and
extraction engine. ExPdfInspector is not an official Firecrawl package.
License
ExPdfInspector is released under the MIT License. The upstream
pdf-inspector project is also distributed under the MIT License; consult the
upstream project for its copyright and licensing details.