Elixir bindings for Firecrawl's anydoc,
implemented as a Rust NIF with Rustler.
ExAnydoc converts Word, PowerPoint, Excel, OpenDocument, RTF, EPUB, CSV, and text-based PDF files into consistent GitHub-Flavored Markdown. Conversion is local and does not call an external service.
ExAnydoc is an independent wrapper and is not an official Firecrawl package.
Features
- Convert a file path or an in-memory binary to Markdown.
- Detect formats from content instead of trusting a filename.
- Parse non-PDF inputs into anydoc's information-preserving document model.
- Retain embedded assets and their original bytes in the document model.
- Return stable error atoms for pattern matching.
- Run parsing work on BEAM dirty CPU schedulers.
Installation
Add ex_anydoc to your dependencies:
def deps do
[{:ex_anydoc, "~> 0.1.0"}]
endThe NIF is compiled when the dependency is built. A working Rust toolchain with Cargo must therefore be available both in development and in production build environments. Install one from rustup.rs if necessary, then run:
mix deps.get
mix compile
Usage
Convert a file:
{:ok, markdown} = ExAnydoc.to_markdown("report.docx")Convert bytes with automatic content detection:
bytes = File.read!("slides.pptx")
{:ok, markdown} = ExAnydoc.to_markdown_bytes(bytes)CSV has no content signature and needs an explicit format when passed as bytes:
{:ok, markdown} = ExAnydoc.to_markdown_bytes("name,score\nAda,10\n", :csv)Read the structured model, including embedded asset bytes:
{:ok, %ExAnydoc.Document{blocks: blocks, notes: notes, assets: assets}} =
ExAnydoc.to_document(bytes)See the Getting Started guide for a complete flow, or browse the documentation for the API and all guides.
PDF conversion is supported only through the Markdown functions because the upstream PDF integration does not create an anydoc document model. Scanned or image-only PDFs require OCR and return an unsupported error.
Supported formats
| Family | Extensions | Format atom |
|---|---|---|
| Word | .doc, .docx, .docm | :doc, :docx |
| PowerPoint | .ppt, .pps, .pot, .pptx, .pptm, .ppsx, .ppsm | :ppt, :pptx |
| Excel | .xls, .xlsx, .xlsm, .xlsb | :excel |
| OpenDocument | .odt, .ods, .odp | :odt, :ods, :odp |
| Other | .rtf, .epub, .csv, .pdf | :rtf, :epub, :csv, :pdf |
For detection behavior, aliases, and format-specific limitations, see Formats and conversion.
Errors
Conversion functions return {:ok, value} or
{:error, %{code: code, message: message}}. Codes are :unsupported,
:malformed, :encrypted, :resource_limit, :missing_part, and :io_error.
Invalid argument types raise at the Elixir or NIF boundary.
Requirements and safety
Parsing runs on dirty CPU schedulers and the upstream library applies fixed limits to archive expansion, nesting, node counts, and retained asset bytes. As with every native dependency, validate untrusted input and apply suitable application-level time and memory limits.
- Elixir 1.15 or later
- Erlang/OTP compatible with the selected Elixir version
- Rust and Cargo available at compile time
See Errors and deployment before deploying the library or accepting untrusted documents.
Acknowledgements
This is an independent wrapper around the anydoc
crate created by Firecrawl. It is not an
official Firecrawl package.
License
ExAnydoc is released under the MIT License. The upstream project is also MIT licensed.