Features
- High-Level Rendering API (#185, #190) — added
Pdf::render_page()to Rust, Python, and WASM. Supports rendering any page toImage(Png/Jpeg). Restored backward compatibility for Rust by maintaining the 1-argumentrender_pageand addingrender_page_with_options. - Word and Line Extraction (#185, #189) — added
extract_words()andextract_text_lines()to all bindings. Provides semantic grouping of characters with bounding boxes, font info, and styling (parity withpdfplumber). - Geometric Primitive Extraction (#185, #191) — added
extract_rects()andextract_lines()to identify vector graphics. - Hybrid Table Detection (#185, #192) — updated
SpatialTableDetectorto use vector lines as hints, significantly improving detection of "bordered" tables. - API Harmonization — implemented the fluent
.within(page, rect)pattern across Rust, Python, and WASM for scoped extraction. - Area Filtering — added optional
regionsupport to all extraction methods (extract_text,extract_chars, etc.) in Python and WASM, using backward-compatible signatures. - Deep Data Access — added
.charsproperty toTextWordandTextLineobjects in Python, enabling granular access to individual character metadata. - CLI Enhancements — added
pdf-oxide renderfor image generation andpdf-oxide pathsfor geometric JSON extraction. Integrated--areafiltering across all extraction commands.
Bug Fixes — Text Extraction (#193, #202, #204)
Reported by @MarcRene71 — AttributeError: 'builtins.PdfDocument' object has no attribute 'extract_text_ocr' when using the library without the OCR feature enabled.
- Improved Feature Gating Discovery (#204) — ensured that all optional features (OCR, Office, Rendering) are always visible in the Python API. If a feature is disabled at build time, calling its methods now returns a helpful
RuntimeErrorexplaining how to enable it (e.g.,pip install pdf_oxide[ocr]), instead of throwing anAttributeError. - Always-on Type Stubs (#204) — updated
.pyifiles to include all methods regardless of build features, providing full IDE autocompletion support for all capabilities.
Reported by @cole-dda — repeated calls to extract_texts() and extract_spans() return inconsistent results (empty lists on second/third calls).
- Fixed XObject span cache poisoning (#193) — resolved an issue where
extract_chars()(low-level API) would incorrectly populate the high-levelxobject_spans_cachewith empty results. Becauseextract_chars()does not collect spans, it was "poisoning" the cache for subsequentextract_spans()calls, causing them to return empty data for any content inside Form XObjects. - Improved extraction mode isolation (#193) — ensured that the text extractor explicitly separates character and span extraction paths. The span result cache is now only accessed and updated when in span extraction mode, and internal span buffers are cleared when entering character mode.
Reported by @vincenzopalazzo — extract_text() returns empty string for encrypted PDFs with CID TrueType Identity-H fonts.
- Support for V=4 Crypt Filters (#202) — fixed a bug in
EncryptDictwhere version 4 encryption was hardcoded to AES-128. It now correctly parses the/CFdictionary and/CFMentry to select between RC4-128 (/V2) and AES-128 (/AESV2), enabling support for PDFs produced by OpenPDF. - Encrypted CIDToGIDMap decryption (#202) — fixed a missing decryption step when loading
CIDToGIDMapstreams. Previously, the stream was decompressed but remained encrypted, causing invalid glyph mapping and failed text extraction. - Enhanced font diagnostic logging (#202) — replaced silent failures with descriptive warnings when ToUnicode CMaps or FontFile2 streams fail to load or decrypt, making it easier to diagnose complex extraction issues.
Refactoring
- Consolidated text decoding and positioning logic (#187) — unified the high-level
extract_text_spans()and low-levelextract_chars()paths into a single shared engine to prevent logic drift and ensure consistent character handling. - Fixed render_page for in-memory PDFs — ensured that PDFs created from bytes or strings can be rendered by automatically initializing a temporary editor if needed.
- Improved Clustering Accuracy — updated character clustering to use gap-based distance instead of center-to-center distance, ensuring accurate word grouping regardless of font size.
Community Contributors
Thank you to @MarcRene71 for identifying the critical API discoverability issue with OCR (#204). Your report led to a more robust "Pythonic" approach to feature gating, ensuring that users always see the full API and receive helpful guidance when features are disabled!
Thank you to @vincenzopalazzo for identifying and fixing the critical issues with encrypted CID fonts and V=4 crypt filters (#202). Your contribution of both the fix and the reproduction fixture was essential for ensuring PDFOxide handles professional PDFs from diverse producers!
Thank you to @ankursri494 (Ankur Srivastava) for the excellent proposal to bridge the gap between PdfPlumber's flexibility and PDFOxide's performance (#185). Your detailed breakdown of word-level and table extraction requirements was the roadmap for this release!
Thank you to @cole-dda for identifying the critical caching bug (#193). The detailed reproduction case was essential for pinpointing the interaction between the low-level character API and the document-level XObject caches.
Installation
Rust (crates.io)
cargo add pdf_oxidePython (PyPI)
pip install pdf_oxideJavaScript/WASM (npm)
npm install pdf-oxide-wasmCLI (Homebrew)
brew install yfedoseev/tap/pdf-oxideCLI (Scoop — Windows)
scoop bucket add pdf-oxide https://github.com/yfedoseev/scoop-pdf-oxide
scoop install pdf-oxideCLI (Shell installer)
curl -fsSL https://raw.githubusercontent.com/yfedoseev/pdf_oxide/main/install.sh | shCLI (cargo-binstall)
cargo binstall pdf_oxide_cliMCP Server (for AI assistants)
cargo install pdf_oxide_mcpPre-built Binaries
Download archives for Linux, macOS, and Windows from the assets below. Each archive includes both pdf-oxide (CLI) and pdf-oxide-mcp (MCP server).
Platform Support
| Platform | Architecture | Archive |
|---|---|---|
| Linux | x86_64 (glibc) | pdf_oxide-linux-x86_64-*.tar.gz
|
| Linux | x86_64 (musl) | pdf_oxide-linux-x86_64-musl-*.tar.gz
|
| Linux | ARM64 | pdf_oxide-linux-aarch64-*.tar.gz
|
| macOS | x86_64 (Intel) | pdf_oxide-macos-x86_64-*.tar.gz
|
| macOS | ARM64 (Apple Silicon) | pdf_oxide-macos-aarch64-*.tar.gz
|
| Windows | x86_64 | pdf_oxide-windows-x86_64-*.zip
|
Changelog
See CHANGELOG.md for full details.