Packages

Elixir bindings for anydoc, a local document-to-Markdown converter

Current section

Files

Jump to
ex_anydoc README.md
Raw

README.md

# ExAnydoc
[![Hex.pm](https://img.shields.io/hexpm/v/ex_anydoc.svg)](https://hex.pm/packages/ex_anydoc)
[![HexDocs](https://img.shields.io/badge/HexDocs-documentation-blue.svg)](https://hexdocs.pm/ex_anydoc)
[![License](https://img.shields.io/hexpm/l/ex_anydoc.svg)](https://github.com/franzinBr/ex_anydoc/blob/main/LICENSE)
[![Elixir](https://img.shields.io/badge/elixir-%3E%3D%201.15-4B275F.svg)](https://elixir-lang.org/)
Elixir bindings for [Firecrawl's `anydoc`](https://github.com/firecrawl/anydoc),
implemented as a Rust NIF with [Rustler](https://github.com/rusterlium/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:
```elixir
def deps do
[{:ex_anydoc, "~> 0.1.0"}]
end
```
The 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](https://rustup.rs/) if necessary,
then run:
```bash
mix deps.get
mix compile
```
## Usage
Convert a file:
```elixir
{:ok, markdown} = ExAnydoc.to_markdown("report.docx")
```
Convert bytes with automatic content detection:
```elixir
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:
```elixir
{:ok, markdown} = ExAnydoc.to_markdown_bytes("name,score\nAda,10\n", :csv)
```
Read the structured model, including embedded asset bytes:
```elixir
{:ok, %ExAnydoc.Document{blocks: blocks, notes: notes, assets: assets}} =
ExAnydoc.to_document(bytes)
```
See the [Getting Started](guides/getting-started.md) guide for a complete flow,
or browse the [documentation](https://hexdocs.pm/ex_anydoc) 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](guides/formats-and-conversion.md).
## 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](guides/errors-and-deployment.md) before deploying
the library or accepting untrusted documents.
## Acknowledgements
This is an independent wrapper around the [`anydoc`](https://crates.io/crates/anydoc)
crate created by [Firecrawl](https://github.com/firecrawl). It is not an
official Firecrawl package.
## License
ExAnydoc is released under the MIT License. The upstream project is also MIT
licensed.