Skip to content

v0.3.14 | Parity in API & Bug Fixing (Issue #185, #193, #202)

Choose a tag to compare

@github-actions github-actions released this 04 Mar 16:01
· 1175 commits to main since this release

Features

  • High-Level Rendering API (#185, #190) — added Pdf::render_page() to Rust, Python, and WASM. Supports rendering any page to Image (Png/Jpeg). Restored backward compatibility for Rust by maintaining the 1-argument render_page and adding render_page_with_options.
  • Word and Line Extraction (#185, #189) — added extract_words() and extract_text_lines() to all bindings. Provides semantic grouping of characters with bounding boxes, font info, and styling (parity with pdfplumber).
  • Geometric Primitive Extraction (#185, #191) — added extract_rects() and extract_lines() to identify vector graphics.
  • Hybrid Table Detection (#185, #192) — updated SpatialTableDetector to 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 region support to all extraction methods (extract_text, extract_chars, etc.) in Python and WASM, using backward-compatible signatures.
  • Deep Data Access — added .chars property to TextWord and TextLine objects in Python, enabling granular access to individual character metadata.
  • CLI Enhancements — added pdf-oxide render for image generation and pdf-oxide paths for geometric JSON extraction. Integrated --area filtering across all extraction commands.

Bug Fixes — Text Extraction (#193, #202, #204)

Reported by @MarcRene71AttributeError: '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 RuntimeError explaining how to enable it (e.g., pip install pdf_oxide[ocr]), instead of throwing an AttributeError.
  • Always-on Type Stubs (#204) — updated .pyi files 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-level xobject_spans_cache with empty results. Because extract_chars() does not collect spans, it was "poisoning" the cache for subsequent extract_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 @vincenzopalazzoextract_text() returns empty string for encrypted PDFs with CID TrueType Identity-H fonts.

  • Support for V=4 Crypt Filters (#202) — fixed a bug in EncryptDict where version 4 encryption was hardcoded to AES-128. It now correctly parses the /CF dictionary and /CFM entry 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 CIDToGIDMap streams. 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-level extract_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_oxide

Python (PyPI)

pip install pdf_oxide

JavaScript/WASM (npm)

npm install pdf-oxide-wasm

CLI (Homebrew)

brew install yfedoseev/tap/pdf-oxide

CLI (Scoop — Windows)

scoop bucket add pdf-oxide https://github.com/yfedoseev/scoop-pdf-oxide
scoop install pdf-oxide

CLI (Shell installer)

curl -fsSL https://raw.githubusercontent.com/yfedoseev/pdf_oxide/main/install.sh | sh

CLI (cargo-binstall)

cargo binstall pdf_oxide_cli

MCP Server (for AI assistants)

cargo install pdf_oxide_mcp

Pre-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.