@@ -93,61 +93,58 @@ for await (const chunk of streamFileMarkdown('paper.pdf')) {
9393}
9494```
9595
96- ### PDF / images: installing the ML models
96+ ### PDF / images: getting the ML models
9797
9898Declarative formats (Markdown, HTML, DOCX, XLSX, …) are pure Rust and need
9999nothing. The ** PDF/image** path needs native assets that are * not* bundled in the
100- addon — pdfium plus the ONNX models (layout, OCR, TableFormer) — the same way
101- Python docling downloads its models on first use. Converting a PDF/image/METS
102- input ** throws ** until they're installed :
100+ addon — pdfium plus the ONNX models (layout, OCR, TableFormer). Converting a
101+ PDF/image/METS input ** throws ** until they're on disk. Fetch them with a
102+ one-liner from your app's directory (where you'll ` npm install fleischwolf ` ) :
103103
104- ``` js
105- import { installDependencies , checkDependencies , convertFileAsync } from ' fleischwolf'
104+ ``` bash
105+ curl -fsSL https://raw.githubusercontent.com/artiz/fleischwolf/master/scripts/download_dependencies.sh | sh
106+ ```
106107
107- await convertFileAsync (' paper.pdf' ) // ❌ throws: "requires the PDF/ML dependencies … call installDependencies()"
108+ ``` js
109+ import { convertFileAsync } from ' fleischwolf'
108110
109- await installDependencies () // provisions everything, then:
110- await convertFileAsync (' paper.pdf' ) // ✅ works
111+ const res = await convertFileAsync (' paper.pdf' , { to: ' markdown' }) // ✅ works
111112```
112113
113- What ` installDependencies() ` fetches, into ` ~/.cache/fleischwolf ` (override with
114- ` dir ` or ` $FLEISCHWOLF_HOME ` ), wiring the matching ` DOCLING_* ` /
115- ` PDFIUM_DYNAMIC_LIB_PATH ` env vars in-process:
114+ ` scripts/download_dependencies.sh ` fetches everything from this repo's
115+ [ GitHub Releases] ( https://github.com/artiz/fleischwolf/releases ) straight into
116+ ` ./models ` and ` ./.pdfium ` — which this package (and the Rust CLI) look for by
117+ default, relative to the process's current directory, so no env vars or setup
118+ call are needed afterwards:
116119
117- | Asset | Source | Required for |
118- | --- | --- | --- |
119- | ** pdfium** | bblanchon prebuilt (auto, platform-detected) | PDF |
120- | ** OCR ** rec model + dictionary | HuggingFace / GitHub (auto ) | scanned pages |
121- | ** layout ** ( ` layout_heron.onnx ` ) | fleischwolf's hosted release (auto) | PDF ** and ** image |
122- | ** TableFormer** ( ` tableformer-* .onnx ` ) | fleischwolf's hosted release (auto) | tables (else geometric fallback) |
120+ | Asset | Destination |
121+ | --- | --- |
122+ | ** pdfium** | ` .pdfium/lib/libpdfium.so ` |
123+ | ** layout ** ( ` layout_heron.onnx ` ) | ` models/layout_heron.onnx ` |
124+ | ** OCR ** rec model + dictionary | ` models/ocr_rec.onnx ` , ` models/ppocr_keys_v1.txt ` |
125+ | ** TableFormer** | ` models/ tableformer/{encoder,decoder,bbox} .onnx` |
123126
124127> ** layout + TableFormer are PyTorch→ONNX exports**
125128> (` docling-project/docling-layout-heron ` , Apache-2.0;
126129> ` docling-project/docling-models ` , CDLA-Permissive-2.0/Apache-2.0 — see
127130> [ ` MODELS_NOTICE.md ` ] ( ../../MODELS_NOTICE.md ) for full attribution), not
128- > fleischwolf's own weights. ` installDependencies() ` fetches the export
129- > fleischwolf hosts as a GitHub Release by default — no configuration needed.
130- > Override with ` { modelsUrl } ` / ` FLEISCHWOLF_MODELS_URL ` to use your own
131- > export/host instead (serving ` layout_heron.onnx ` and, optionally,
132- > ` tableformer-{encoder,decoder,bbox}.onnx ` ), or export locally (repo
133- > ` scripts/export_layout.py ` , ` scripts/export_tableformer.py ` ) and set
134- > ` DOCLING_LAYOUT_ONNX ` / ` DOCLING_TABLEFORMER_* ` directly —
135- > ` installDependencies ` detects those as already installed and skips fetching.
131+ > fleischwolf's own weights — fleischwolf hosts the converted ` .onnx ` as a
132+ > GitHub Release purely so you don't need a local Python/torch toolchain.
133+ > pdfium and the OCR model are re-hosted, unmodified, from their own public
134+ > releases, on the same host for convenience.
136135>
137- > Pre-fetch everything ahead of time (e.g. in a container build step), from
138- > your app's directory:
136+ > Run it from wherever your app lives — the script only writes to ` ./models `
137+ > and ` ./.pdfium ` under the current directory, e.g. in a container build step :
139138> ``` bash
140- > curl -fsSL https://raw.githubusercontent.com/artiz/fleischwolf/master/scripts/setup_nodejs_dependencies .sh | bash
139+ > cd /path/to/your/app && curl -fsSL https://raw.githubusercontent.com/artiz/fleischwolf/master/scripts/download_dependencies .sh | sh
141140> ` ` `
141+ >
142+ > To use your own export/host instead, point the env vars at it directly:
143+ > ` DOCLING_LAYOUT_ONNX` , ` DOCLING_OCR_REC_ONNX` , ` DOCLING_OCR_DICT` ,
144+ > ` DOCLING_TABLEFORMER_{ENCODER,DECODER,BBOX}` , ` PDFIUM_DYNAMIC_LIB_PATH` — an
145+ > env var always wins over the ` ./models` / ` ./.pdfium` default.
142146
143147` ` ` js
144- await installDependencies({ onProgress: (m) => console.log(m) })
145-
146- // or, to use your own export/host instead of fleischwolf' s default:
147- await installDependencies({
148- modelsUrl: ' https://you.example/fleischwolf-models' , // serves layout_heron.onnx, tableformer-*.onnx
149- })
150-
151148checkDependencies () // { home, pdfium, layout, ocr, tableformer, ready, missing }
152149` ` `
153150
@@ -199,7 +196,6 @@ JSON output always embeds extracted images as data URIs.
199196| ` streamFileMarkdown(path, options? )` | ` AsyncGenerator< string> ` | Markdown chunks in document order. |
200197| ` supportedFormats()` | ` string[]` | Supported input format ids. |
201198| ` formatFromName(name)` | ` string \| null` | Detect a format id from a filename/extension. |
202- | `installDependencies(options?)` | `Promise<DependencyStatus>` | Download/validate the PDF/image models + pdfium. |
203199| ` checkDependencies(options? )` | ` DependencyStatus` | Report which PDF/image deps are present. |
204200
205201` Pipeline` is the reusable warm PDF/image converter: ` new Pipeline(converterOptions)`
@@ -246,12 +242,12 @@ cd examples
246242npm install
247243node node-basic.mjs # ESM: file, bytes, JSON, reuse
248244bun run bun-basic.ts # Bun + TypeScript: async + streaming
249- node pdf-pipeline.mjs # installDependencies + warm Pipeline for PDFs
245+ node pdf-pipeline.mjs # warm Pipeline for PDFs (run scripts/download_dependencies.sh first)
250246```
251247
252248- [`examples/node-basic.mjs`](examples/node-basic.mjs) — Node.js (ESM): file, bytes, JSON, reuse.
253249- [`examples/bun-basic.ts`](examples/bun-basic.ts) — Bun + TypeScript, with async and streaming.
254- - [` examples/pdf-pipeline.mjs` ](examples/pdf-pipeline.mjs) — ` installDependencies ` + warm ` Pipeline` for PDFs.
250+ - [`examples/pdf-pipeline.mjs`](examples/pdf-pipeline.mjs) — warm `Pipeline` for PDFs.
255251
256252The smoke test exercises the locally-built addon instead: `npm run build` once at
257253the package root, then `node test/smoke.mjs` (or `bun test/smoke.mjs`).
0 commit comments