Pure-Rust PowerPoint (.pptx / OOXML) structural parser with local image OCR, via PyO3.
Project description
pptspine
A pure-Rust PowerPoint (.pptx) parser with Python bindings (PyO3 / maturin,
abi3-py311). A .pptx file is OOXML — a zip archive of XML parts — and pptspine
walks that XML directly to produce a structured, information-preserving model:
slides, text frames (paragraphs + styled runs), tables (cells, merges, fills),
pictures, and autoshapes. Embedded images can additionally be OCR'd locally,
offline, and deterministically via the sibling ocrspine crate
(PP-OCRv5 through tract-onnx — no cloud, no network).
Capabilities
| Area | Status |
|---|---|
| Slides + slide size | parsed |
| Text frames: paragraphs, runs, text | parsed |
| Run styling: font, size, bold, italic, solid-fill color | parsed |
| Paragraph level + alignment | parsed |
| Tables: rows, cells, cell text | parsed |
Table merges: gridSpan / rowSpan / hMerge / vMerge |
parsed |
| Cell solid-fill color | parsed |
Pictures: r:embed rel → media name + raw bytes |
parsed |
| Autoshapes: geometry name, fill, stroke, optional text | parsed (best-effort) |
Groups (p:grpSp): recursive |
parsed |
| Image OCR (embedded pictures → words + boxes) | working (ocr_image) |
| Image-table geometry reconstruction from OCR boxes | deferred (stub) |
Parsing is tolerant: unknown elements are skipped, missing attributes become
None, and malformed input yields a typed PptError rather than a panic.
Build (from the package root)
uv venv .venv
VIRTUAL_ENV="$(pwd)/.venv" uv pip install maturin pytest
# Structural parsing needs no models. The OCR path resolves models from
# ../ocrspine/models by default (or set OCRSPINE_MODELS).
OCRSPINE_MODELS="$(cd ../ocrspine && pwd)/models" \
VIRTUAL_ENV="$(pwd)/.venv" .venv/bin/maturin develop --release
Use from Python
import pptspine
pres = pptspine.open("deck.pptx")
print(pres.slide_count, pres.slide_size) # e.g. 2 (9144000, 6858000) # EMU
for slide in pres.slides():
for shape in slide.shapes(): # list[dict], introspectable
if shape["kind"] == "text":
for para in shape["paragraphs"]:
for run in para["runs"]:
print(run["text"], run["bold"], run["color"])
elif shape["kind"] == "table":
for row in shape["rows"]:
print([cell["text"] for cell in row])
elif shape["kind"] == "picture":
print("image:", shape["media"])
# Run OCR on raw image bytes (PNG/JPEG), offline:
items = pptspine.ocr_image(open("scan.png", "rb").read())
print(" ".join(i["text"] for i in items))
Rust workspace
crates/
ppt-core domain model + geometry (EMU) + typed PptError. No IO/zip/XML.
ppt-parse OOXML reader: zip extract + quick-xml walk -> Presentation.
ppt-ocr image-OCR bridge over ocrspine (PaddleOcr).
py-bindings PyO3 _core extension (the FFI chokepoint).
Deferred / follow-up
- Image-table geometry reconstruction from OCR boxes
(
ppt_ocr::reconstruct_table_from_image, currently a typedUnsupportedstub). - Bundling the PP-OCRv5 ONNX weights into the published wheel (a CI task).
- Richer color models (theme/scheme colors, gradients), hyperlinks, charts, SmartArt, notes/comments.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pptspine-0.1.0.tar.gz.
File metadata
- Download URL: pptspine-0.1.0.tar.gz
- Upload date:
- Size: 45.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4da9bfb7a360ddc670e554a7d09d26693172f238655051bae9b59f2db5330f66
|
|
| MD5 |
a36758d6afb8541e6ebc55f5c806668a
|
|
| BLAKE2b-256 |
8a7cb21e1bc2e45cc795c5c0c5fde0b3044361d56563cf53b0a732dd4725761e
|
File details
Details for the file pptspine-0.1.0-cp311-abi3-win_amd64.whl.
File metadata
- Download URL: pptspine-0.1.0-cp311-abi3-win_amd64.whl
- Upload date:
- Size: 6.1 MB
- Tags: CPython 3.11+, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0e4f52a3895e1c8c02affb988171a52a2fb586552aa4e6c3b32bf87da527ae3b
|
|
| MD5 |
9daa3756181d71d3c954fbd5a00822e8
|
|
| BLAKE2b-256 |
d9b58438df56ac5f7c4b93cffe605b0f0b71c4338fc08efbd70bf43ba019d013
|
File details
Details for the file pptspine-0.1.0-cp311-abi3-manylinux_2_28_aarch64.whl.
File metadata
- Download URL: pptspine-0.1.0-cp311-abi3-manylinux_2_28_aarch64.whl
- Upload date:
- Size: 5.2 MB
- Tags: CPython 3.11+, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
edf5e90979907b6f03ba952a721faa94c802e44aa146b0527f4074800b995bd0
|
|
| MD5 |
a0cda32bfbe8f3a836e0fa3186676578
|
|
| BLAKE2b-256 |
7f513e74404b20709b12c3ed6e9cdb3a2b29d732416227bda128ed635c4e981b
|
File details
Details for the file pptspine-0.1.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: pptspine-0.1.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 6.1 MB
- Tags: CPython 3.11+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b0d661cf511a8767eae9ade0a00a2f6ac69c112971279449ab9dbcf3c44c54f3
|
|
| MD5 |
7b805dba19fff462d033b9cd90a1662d
|
|
| BLAKE2b-256 |
6ed58cb71f61d2f0def72407d71bbf4e2767f2ce102b1217355107660a06d732
|
File details
Details for the file pptspine-0.1.0-cp311-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: pptspine-0.1.0-cp311-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 4.9 MB
- Tags: CPython 3.11+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b5b08a4b26f80f85d3e4cab055e9597661fbb616ab03d422d4bfe4f7c5c66829
|
|
| MD5 |
533069cce6414dbd2c66ec64f1b09bbe
|
|
| BLAKE2b-256 |
b9a7a4935b6658374f38c09da2491ebbbfd231c11b57124123f85517b1a43ecd
|