Processing and Options

Copy Markdown View Source

The default call uses %ExPdfInspector.PdfOptions{} and runs the complete pipeline. Build option structs explicitly when you need lower latency, selected pages, a password, or different Markdown output.

Processing modes

Set ExPdfInspector.PdfOptions.mode to one of:

ModeDetectionLayout analysisMarkdown extraction
:detect_onlyyesnono
:analyzeyesyesno
:fullyesyesyes

For routing decisions where Markdown is not yet needed:

options = %ExPdfInspector.PdfOptions{mode: :detect_only}
{:ok, result} = ExPdfInspector.process_pdf("document.pdf", options)

The dedicated detect_pdf/1 and detect_pdf_bytes/1 functions are convenient shortcuts for detection without extraction.

Detection strategies

ExPdfInspector.DetectionOptions.strategy controls which pages are inspected:

StrategyBehavior
:early_exitStops after enough evidence is available.
:fullInspects every page.
{:sample, count}Inspects a sample of at most count pages.
{:pages, pages}Inspects only the specified page indexes.

The wrapper defaults to {:sample, 8}. Use :full when accurate classification of mixed documents matters more than minimizing inspection work:

alias ExPdfInspector.{DetectionOptions, PdfOptions}

options = %PdfOptions{
  mode: :detect_only,
  detection: %DetectionOptions{
    strategy: :full,
    min_text_ops_per_page: 3,
    text_page_ratio_threshold: 0.6
  }
}

min_text_ops_per_page is the minimum number of PDF text operations required for a page to count as text-based. text_page_ratio_threshold is the minimum ratio of text pages used during classification.

Page selection and encrypted PDFs

page_filter limits extraction to zero-based page indexes:

%ExPdfInspector.PdfOptions{page_filter: [0, 4, 9]}

Set password to open a password-protected PDF:

%ExPdfInspector.PdfOptions{password: "document-password"}

If no valid password is supplied, processing returns an error with the :encrypted code. Error codes are stable library-defined atoms suitable for pattern matching, while error messages remain strings.

Markdown profiles

ExPdfInspector.MarkdownOptions.profile accepts:

  • :fidelity — preserves more of the source document's detected structure;
  • :compact — favors simpler, more token-efficient output.
options = %ExPdfInspector.PdfOptions{
  markdown: %ExPdfInspector.MarkdownOptions{profile: :compact}
}

Fine-grained fields control detection and output:

FieldDefaultPurpose
detect_headerstrueDetect heading levels.
detect_liststrueDetect list structures.
detect_codetrueDetect code blocks.
base_font_sizenilOverride the inferred body font size.
remove_page_numberstrueRemove detected page numbers.
format_urlstrueFormat detected URLs as Markdown links.
fix_hyphenationtrueRejoin words split across lines.
detect_boldtruePreserve detected bold text.
detect_italictruePreserve detected italic text.
detect_underlinetruePreserve detected underlined text.
include_imagesfalseInclude image placeholders.
include_linkstrueInclude links.
include_page_numbersfalseInclude page-number markers in output.
strip_headers_footerstrueRemove recurring headers and footers.

For standalone conversion, to_markdown/2 accepts plain text and Markdown options:

ExPdfInspector.to_markdown(
  "TITLE\n\nDocument body",
  %ExPdfInspector.MarkdownOptions{profile: :compact}
)

The to_markdown_from_items/2 and to_markdown_from_items_with_rects/3 functions are useful when positioned items have already been extracted or produced by another pipeline.

Concurrency and deployment

The Rust functions are scheduled as dirty CPU NIFs. Callers can use them from regular Elixir processes without blocking a normal BEAM scheduler, but each document still consumes CPU and memory. Bound concurrency when processing large batches or untrusted documents.

The NIF is native code. Build releases on a platform compatible with the target runtime, or compile the dependency in the target build environment.