pith-pdf 0.1.0

PDF text extraction across classic xref, xref streams, cmap and CID fonts
Documentation
  • Coverage
  • 100%
    41 out of 41 items documented0 out of 7 items with examples
  • Size
  • Source code size: 461.9 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 1.1 MB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 2s Average build duration of successful builds.
  • all releases: 2s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • Homepage
  • pith-hash/pith-pdf
    0 0 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • n24q02m

What it does

Opens a PDF, resolves objects through the cross-reference (classic tables, xref streams with /W field widths and /Index runs, /Prev incremental-update chains, and /ObjStm object streams), walks the page tree and extracts text from content streams:

  • text operators Tj, TJ, ', " plus the positioning ops Td, TD, Tm, T*; Do recurses into Form XObjects;
  • font decoding: /ToUnicode CMaps (bfchar, bfrange incl. array destinations and surrogate pairs), the five predefined encodings plus /Differences (AGL names + uniXXXX/uXXXXXX), and CID-keyed fonts (/Type0, /Identity-H/-V and embedded CMap streams);
  • stream filters FlateDecode (zlib + raw-deflate fallback), ASCII85, ASCIIHex with /DecodeParms PNG/TIFF predictors.

Refusals, never guesses: encrypted documents refuse per page with object context, CID fonts without /ToUnicode refuse, unsupported stream filters refuse naming the filter, and a corrupt xref is rebuilt by scanning when possible (reported via Document::xref_was_rebuilt). Every page failure carries the page number; every object-level refusal carries the object.

The pith suite contract

pith-pdf is part of the pith suite (pith-hash). Every suite repository follows the same rules; CI enforces them mechanically:

  • Naming: a library is always pith-<domain> (pith-image, pith-audio, pith-zip, ...). The curator/repository of repositories is the bare pith-hash. Never invent a second naming scheme inside the suite.
  • Version pinning: cross-library dependencies pin ~0.1 (e.g. pith-image = { version = "~0.1", path = "../pith-image" }). The whole suite moves together inside 0.1.x; breaking changes require a suite-wide version bump, never a silent minor drift.
  • Zero third-party dependencies: every crate depends only on other pith-* crates plus std. scripts/check-zero-deps.py (run in CI) fails the build on any other crate, for normal, build and dev dependencies alike.
  • No unsafe: every crate root carries #![forbid(unsafe_code)].
  • Hex-exact vectors: reference.json at the repo root is the cross-language source of truth. The gen-reference binary regenerates it; CI verifies the committed copy is current (gen-reference verify), and CD ships the regenerated file with every SDK artifact. Python, Node and Go SDKs MUST test against the same bytes.

Repository layout

src/                the pith-pdf library (no_std + alloc)
tests/fixtures      generated PDF corpus with expected extractions (PROVENANCE.md)
tools/gen-reference the vector generator binary (bin name: gen-reference)
reference.json      hex-exact cross-SDK test vectors

Install

Rust (the core library):

cargo add pith-pdf

Python / Node / Go SDKs are published from the same cdylib on every release; see the release assets or the package registries for the matching version.

Quick start

let pdf = std::fs::read("document.pdf")?;
let text = pith_pdf::extract_text(&pdf)?;
// pages are joined by \x0c (form feed)
for (i, page) in text.split('\x0c').enumerate() {
    println!("--- page {} ---\n{}", i + 1, page);
}

Contributing

See CONTRIBUTING.md.

Security

See SECURITY.md.

License

MIT © pith-hash