This release has been yanked by its maintainers, and will be ignored by installers, except when explicitly specified.
Consider using release 0.1.4 instead.
Reason given by maintainers: Superseded; contains adapters that are no longer distributed.
WolfPPT
WolfPPT is a Rust-native PowerPoint editing runtime for surgical, verified edits to existing decks.
Generating a new deck from scratch is easy. Safely editing the 90-slide deck a company already uses — without corrupting its charts, media, notes, links, or unknown internals — is a different problem, and it is the problem WolfPPT is built for.
- Lossless
.pptx/.pptmpackage preservation: parts you did not edit, including parts WolfPPT has no schema for, stay byte-for-byte identical. - Guarded text, shape, table, chart, and slide operations (edit, duplicate, delete, reorder) with mutation guards that refuse unsafe edits instead of writing them.
- Verification receipts, semantic diffs, and optional Open XML validation and render smoke, so every claimed edit is checked against the saved package, not assumed.
Those claims are not asserted; they are measured. The benchmark harness in this repository is the evidence system that proves them, and it stays a first-class part of the project.
Quickstart
Install from source:
pip install wolfppt
PyPI wheels cover CPython 3.11-3.14 on Linux x86_64/aarch64 and macOS arm64. Add the baseline extra (pip install wolfppt[baseline]) for the wolfppt-harness command, which needs python-pptx for adapter comparison lanes.
Then run the built-in demo:
wolfppt demo
It builds a deterministic deck, applies four surgical edits, reopens the saved package to verify every edit, and prints a verification receipt:
requested edits: 4
verified edits: 4
unrelated package parts changed: 0
reopen: passed
open xml validation: skipped (Open XML validation is optional and is not run by the demo.)
Basic usage:
from wolfppt import Presentation
prs = Presentation()
slide = prs.slides.add_slide(prs.slide_layouts[6])
prs.save("output.pptx")
Harness Shape
The harness is WolfPPT's evidence system. It generates a deterministic fixture corpus, records the expected package semantics, and pushes every adapter — including the native Rust engine behind the public API — through validation, package diffing, semantic diffing, and render smoke. Results append to an append-only evidence ledger and roll up into a generated compatibility matrix:
fixtures/*.pptx
|
v
semantic extractor -> expected/*.json
|
v
library adapters -> validation / package diff / semantic diff / render smoke
|
v
results/runs.jsonl -> generated compatibility matrix
Benchmark Suite
wolfppt-harness benchmark runs repeatable adapter benchmarks across the checked-in
fixture manifest. It records latency separately from correctness checks, so
semantic diffs, package diffs, and optional Open XML validation do not inflate
the measured adapter time. The default suite compares the stdlib semantic
extractor, python-pptx summary/round-trip baselines, the official .NET Open XML
SDK, a PptxGenJS generation-only lane, Apache POI, Aspose.Slides, and
Spire.Presentation round-trip lanes when their toolchains are installed, a
licensed Syncfusion .NET round-trip lane, an opt-in external command round-trip
lane for other SDKs, the Rust CLI bridge, and the native Rust Python binding
when those tools are available. Use
--validate-openxml for release-grade output validation and --write-results
to append samples to results/runs.jsonl. The PptxGenJS lane is a generated-deck
baseline, not evidence of existing-deck preservation; Open XML validation may
surface schema differences separately from generation speed.
Drop-in edit benchmarks are opt-in because they target specific public API
workflows instead of the whole fixture corpus. Use them to compare equivalent
python-pptx and WolfPPT facade edits, such as paragraph and table-cell updates.
For performance claims against Python libraries, build the native module in
release mode first; debug editable builds are useful for development but slower.
Use wolfppt-harness benchmark-profiles to list curated benchmark suites and
wolfppt-harness benchmark-profile <name> to run one. Profiles keep drop-in
comparisons on valid adapter/fixture pairs and add a python-pptx vs WolfPPT
speedup table when both sides pass. Use dev-smoke for fast edit-loop
feedback; it is not claim-grade evidence. Useful profiles include dev-smoke,
core-smoke, core-full, real-corpus, private-real-decks,
sdk-preservation, sdk-comparison, sdk-spire-reproducer, dropin-smoke,
dropin-full, release-smoke, and release-full. Core and release profiles use built-in
preservation adapters only; Apache POI claim gates belong in
sdk-preservation, commercial SDKs and custom external commands belong in
sdk-comparison, stricter all-commercial setup proof belongs in
sdk-comparison-strict, and uncommitted local or VPS-only decks belong in
private-real-decks via WOLFPPT_PRIVATE_DECKS_DIR.
Release profiles omit the generation-only PptxGenJS lane so --validate-openxml
stays strict for existing-deck edit and round-trip lanes.
Add --min-wolfppt-speedup 1.0 to turn passing python-pptx/WolfPPT pairs into a
performance gate for release evidence. The gate still reports every near miss,
but sub-threshold slowdowns of 0.100 ms or less are treated as timing noise
rather than material failures.
Add --require-adapter <name> when a comparison lane must be present rather
than skipped, for example when recording commercial SDK evidence.
For visual-oracle corpus evidence, pair run-corpus --include-powerpoint with
--require-lane powerpoint-render so a missing or skipped PowerPoint export
fails the run instead of being treated as optional. Add
--min-powerpoint-exported-slides <count> to gate the actual slide PNG sample
count.
See the compatibility matrix under docs/compatibility/ for the current
feature-coverage boundaries. As of the latest release-gate evidence,
release-full run 20260519T120111Z passes the full checked-in release gate
with 483 passing rows, 0 skips, 0 failures, 29 distinct fixtures, and 5,040
Open XML validation samples, plus fixture gates for 110 slides, 290 shapes, 25
charts, 16 fixtures
with tables, 16 with charts, 14 with media, and 17 with embedded objects. This
release gate was refreshed after adding the procurement vendor-risk pack and
the one-pass grouped-connector connection, slide-level connector-to-new-shape,
and nested-group OLE insertion paths, then refreshed again after coalescing
grouped connector attachments to newly added group children. It includes connector attachment edits through
begin_connect() and
end_connect() for newly added, existing deck, and grouped child shapes, grouped-shape child
adjustment edits, grouped existing-shape and grouped existing-child lanes,
table row-height and column-width edits,
bar/line/pie chart-add lanes, packaged native chart templates, batched
chart-template-family insertion, coalesced nested-group auto-shape insertion,
speaker-notes text, text-frame, background, paragraph/run, placeholder-clone,
and slide-name metadata
lanes, and Linux
fit_text coverage through a discovered compatible font file.
The latest evidence-backed
real-corpus run 20260527T121753Z passes 144/144 rows across sixteen
real-world-style fixtures, including the QoE diligence, customer success,
security compliance, revenue-operations forecast, product-launch readiness,
enterprise implementation, procurement vendor-risk, post-merger integration,
and earnings board appendix packs (workloads/post_merger_integration_pack
and workloads/earnings_board_appendix_pack), with 960 Open XML validation
samples and the 16-fixture gate plus slide, shape, table, chart, media, and
embedded-object complexity coverage. The report records Git metadata from the
remote launcher
environment for commit 3d6134b, so the raw benchmark report and detached job
point at the same code. New launcher runs also record whether the VPS mirror was
freshly synced before benchmarking. Local
PowerPoint visual-oracle run 20260519T053625Z passes the required
powerpoint-render lane across the current 29-fixture corpus and exports
110 slide PNGs. A redacted remote-host private-real-decks pressure run
20260518T050715Z passes on two distinct private decks with 16 slides, 135
shapes, 8 tables, 4 charts, 13 media parts, 120 Open XML validation samples,
and 0 raw-name/path leaks in the private report check. The latest remote-host
sdk-preservation run 20260519T034127Z passes 56/56 rows across python-pptx,
Open XML SDK, Apache POI, and WolfPPT native with 840 Open XML validation
samples, 42 SDK preservation comparisons, and 2.006-561.911x measured WolfPPT
speedups against those open-source baselines. These support checked-in corpus,
open-source SDK, and narrow private-pressure claims through those snapshots, but
not universal
"best in class" claims or first-of-kind claims.
Python-Compatible Facade
WolfPPT exposes a first python-pptx-style API for existing-deck edits:
from wolfppt import Presentation
from pptx.enum.text import PP_ALIGN
from pptx.enum.text import MSO_AUTO_SIZE
prs = Presentation("deck.pptx")
prs.slides[0].shapes.title.text = "Updated title"
prs.slides[0].shapes[1].text = "Updated body"
prs.slides[0].shapes[1].left = 914400
prs.slides[0].shapes[1].text_frame.paragraphs[0].text = "Updated paragraph"
prs.slides[0].shapes[1].text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER
prs.slides[0].shapes[1].text_frame.paragraphs[0].level = 1
prs.slides[0].shapes[1].text_frame.paragraphs[0].line_spacing = 1.25
prs.slides[0].shapes[1].text_frame.auto_size = MSO_AUTO_SIZE.TEXT_TO_FIT_SHAPE
prs.slides[0].shapes[1].text_frame.paragraphs[0].runs[0].text = "Updated run"
prs.slides[0].shapes[1].text_frame.paragraphs[0].runs[0].font.bold = True
prs.slides[0].shapes[1].text_frame.paragraphs[0].runs[0].font.italic = True
prs.slides[0].shapes[1].text_frame.paragraphs[0].runs[0].font.underline = True
prs.slides[0].shapes[1].text_frame.paragraphs[0].runs[0].font.size = 304800
prs.slides[0].shapes[1].text_frame.paragraphs[0].runs[0].font.name = "Aptos"
prs.slides[0].shapes[1].text_frame.paragraphs[0].runs[0].font.color.rgb = "123456"
prs.slides.add_slide(prs.slide_layouts[6])
prs.slides[0].shapes.add_textbox(914400, 2743200, 3657600, 914400).text = "New box"
prs.slides[0].shapes.add_shape(1, 914400, 3657600, 3657600, 914400).text = "New shape"
picture = prs.slides[0].shapes.add_picture("logo.png", 0, 0)
picture.crop_left = 0.125
prs.slides[0].shapes[0].table.cell(1, 1).text = "2"
prs.slides[0].shapes.add_table(2, 3, 0, 0, 2743200, 914400)
prs.save("updated.pptx")
The facade currently supports existing-deck open/save, slide and shape
iteration/indexing, common collection slicing, title placeholder lookup,
slide.placeholders, slide.shapes.placeholders, shape-tree helper flags, slide
layouts, read-only .part package metadata, read-only
.element XML inspection for common presentation, slide, layout, shape,
placeholder, and master objects, background fill reads and slide background
writes, existing notes slide/master reads,
slides.add_slide(layout), slides.move(...), slides.duplicate(slide) including chart, notes, OLE, comment, audio/video/media, and external-target relationship copy policies,
slides.remove(slide), del slides[index], and del slides[start:stop:step] for persisted and pending newly-added or duplicated slides,
slide_layouts.remove(...),
shapes.add_picture(...) with explicit or inferred bounds,
picture crop reads/writes, shapes.add_textbox(...), common shapes.add_shape(...)
preset shapes, table insertion, table cell text-frame/margin reads/writes, table row/column insert and remove, shapes.remove(...), group.shapes.remove(child) including any-depth nested group children and whole sub-groups, chart insertion, chart type/series/title/legend/axis
reads, chart title, legend, and axis-title edits, category/XY/bubble chart data replacement, text reads, shape.text assignment, shape
name, type, geometry, rotation, adjustment, and line XML helper reads/writes, solid/gradient fill, line RGB, and line width writes, shadow inheritance, external hyperlink, and target-slide reads/writes, paragraph/run text
assignment, text-run external hyperlinks, text-frame margin, word-wrap, vertical-anchor, auto-size, and fit-text reads/writes, paragraph alignment, level, and spacing reads/writes, run bold/italic/underline reads/writes,
run size/name/color reads/writes, paragraph/run appends,
shape.text_frame.clear(), and shape.text_frame.text assignment. Edited
saves go through the native Rust mutation engine; no-op saves preserve the
source package.
Commands
uv sync --extra dev
uv run pytest
uv run wolfppt-harness extract path/to/deck.pptx
uv run wolfppt-harness manifest path/to/deck.pptx
uv run wolfppt-harness diff before.pptx after.pptx
uv run --extra baseline wolfppt-harness python-pptx-summary path/to/deck.pptx
uv run --extra baseline wolfppt-harness python-pptx-roundtrip in.pptx out.pptx
uv run wolfppt-harness validate-openxml path/to/deck.pptx
uv run wolfppt-harness rust-inspect path/to/deck.pptx
uv run wolfppt-harness rust-roundtrip in.pptx out.pptx
uv run wolfppt-harness rust-add-slide in.pptx out.pptx 0
uv run wolfppt-harness rust-replace-text in.pptx out.pptx WolfPPT "WolfPPT Native"
uv run wolfppt-harness rust-replace-text in.pptx out.pptx WolfPPT "WolfPPT Native" --slide-index 0
uv run wolfppt-harness rust-replace-text-run in.pptx out.pptx 0 1 "Fast Native"
uv run wolfppt-harness rust-set-shape-text in.pptx out.pptx 0 1 "Fast Native"
uv run wolfppt-harness rust-set-paragraph-text in.pptx out.pptx 0 1 0 "Fast Native"
uv run wolfppt-harness rust-replace-image in.pptx out.pptx rId2 image.png
uv run wolfppt-harness rust-replace-image in.pptx out.pptx rId2 image.png --slide-index 0
uv run wolfppt-harness rust-add-image in.pptx out.pptx 0 image.png 0 0 914400 914400
uv run wolfppt-harness rust-replace-table-cell in.pptx out.pptx 0 0 1 1 "2"
uv run wolfppt-harness rust-add-table in.pptx out.pptx 0 2 3 0 0 2743200 914400
uv run wolfppt-harness native-inspect path/to/deck.pptx
uv run wolfppt-harness native-summary path/to/deck.pptx
uv run wolfppt-harness native-roundtrip in.pptx out.pptx
uv run wolfppt-harness native-add-slide in.pptx out.pptx 0
uv run wolfppt-harness native-replace-text in.pptx out.pptx WolfPPT "WolfPPT Native"
uv run wolfppt-harness native-replace-text in.pptx out.pptx WolfPPT "WolfPPT Native" --slide-index 0
uv run wolfppt-harness native-replace-text-run in.pptx out.pptx 0 1 "Fast Native"
uv run wolfppt-harness native-set-shape-text in.pptx out.pptx 0 1 "Fast Native"
uv run wolfppt-harness native-set-paragraph-text in.pptx out.pptx 0 1 0 "Fast Native"
uv run wolfppt-harness native-replace-image in.pptx out.pptx rId2 image.png
uv run wolfppt-harness native-replace-image in.pptx out.pptx rId2 image.png --slide-index 0
uv run wolfppt-harness native-add-image in.pptx out.pptx 0 image.png 0 0 914400 914400
uv run wolfppt-harness native-replace-table-cell in.pptx out.pptx 0 0 1 1 "2"
uv run wolfppt-harness native-add-table in.pptx out.pptx 0 2 3 0 0 2743200 914400
uv run wolfppt-harness render-libreoffice path/to/deck.pptx
uv run wolfppt-harness render-powerpoint path/to/deck.pptx
uv run --extra dev wolfppt-harness corpus
uv run wolfppt-harness python-api-surface --json --max-real-slides 999 --max-real-shapes 999 --min-fixtures 33 --min-representative-pairs 64 --min-real-pairs 1576 --write-report
uv run wolfppt-harness dropin-coverage --min-behaviors 149 --min-domains 9 --min-domain-behaviors charts=39,groups=31,media=16,notes=8,presentation=2 --min-domain-behaviors shapes=79,slides_layouts=18,tables=14,text=43 --min-fixture-scenarios 403 --min-adapter-fixture-rows 806
uv run wolfppt-harness run-corpus --write-report
uv run wolfppt-harness run-corpus --include-powerpoint --require-lane powerpoint-render --min-powerpoint-exported-slides 110 --write-report
npm install --prefix tools/pptxgenjs-generate
mvn -q -f tools/apache-poi-roundtrip/pom.xml -DskipTests compile
docker build -t wolfppt-aspose-slides:python3.11-bullseye examples/external-roundtrip/aspose-docker
uv run wolfppt-harness benchmark --iterations 5 --warmup 1 --write-report
uv run wolfppt-harness benchmark-profiles
scripts/verify-fast.sh tests/test_validation_ladder.py
scripts/verify-slice.sh tests/test_validation_ladder.py
scripts/verify-vps.sh --python-only -- tests/test_validation_ladder.py -q
scripts/verify-claims.sh
scripts/start-vps-claims.sh
scripts/start-vps-real-corpus.sh
scripts/start-vps-private-real-decks.sh --private-decks-dir /path/on/vps/private/decks
scripts/verify-sdk-comparison.sh
scripts/start-vps-sdk-comparison.sh
scripts/start-vps-sdk-comparison.sh --strict-commercial
scripts/vps-job-status.sh --active-only
uv run wolfppt-harness validate quick
uv run wolfppt-harness validate slice --json
uv run wolfppt-harness validate vps-pr
uv run wolfppt-harness validate real-corpus
uv run wolfppt-harness validate private-real-decks
uv run wolfppt-harness validate sdk-comparison
uv run wolfppt-harness validate sdk-comparison-strict
uv run wolfppt-harness validate release
uv run wolfppt-harness benchmark-profile dev-smoke --iterations 1 --warmup 0
uv run wolfppt-harness benchmark-profile release-smoke --iterations 5 --warmup 1 --validate-openxml --write-report
uv run wolfppt-harness benchmark-profile release-full --iterations 15 --warmup 2 --validate-openxml --progress --fail-fast --min-wolfppt-speedup 1.0 --min-distinct-fixtures 30 --min-fixture-total-slides 111 --min-fixture-total-shapes 291 --min-fixture-total-charts 26 --min-fixtures-with-tables 16 --min-fixtures-with-charts 16 --min-fixtures-with-media 14 --min-fixtures-with-embedded-objects 17 --min-openxml-samples 5010 --write-report
uv run wolfppt-harness benchmark-profile sdk-preservation --iterations 15 --warmup 2 --validate-openxml --min-native-roundtrip-speedup 1.0 --min-distinct-fixtures 16 --min-fixture-total-slides 106 --min-fixture-total-shapes 297 --min-fixture-total-tables 43 --min-fixture-total-charts 25 --min-fixture-total-media 15 --min-fixture-total-embedded-objects 36 --min-fixtures-with-tables 16 --min-fixtures-with-charts 16 --min-fixtures-with-media 15 --min-fixtures-with-embedded-objects 16 --min-sdk-preservation-rows 48 --min-openxml-samples 960 --require-adapter apache-poi-roundtrip --write-report
uv run wolfppt-harness benchmark-profile dropin-smoke --iterations 15 --warmup 2 --validate-openxml --min-wolfppt-speedup 1.0 --min-openxml-samples 20 --write-report
WOLFPPT_PRIVATE_DECKS_DIR=/path/to/private/decks uv run wolfppt-harness private-decks --json --min-count 5 --min-distinct-count 5 --min-total-slides 50 --min-total-shapes 100 --min-total-tables 1 --min-total-charts 1 --min-total-media 1 --min-total-embedded-objects 1 --min-decks-with-tables 1 --min-decks-with-charts 1 --min-decks-with-media 1 --min-decks-with-embedded-objects 1 --min-distinct-decks-with-tables 1 --min-distinct-decks-with-charts 1 --min-distinct-decks-with-media 1 --min-distinct-decks-with-embedded-objects 1 --min-slides-per-deck 3 --min-shapes-per-deck 10
WOLFPPT_PRIVATE_DECKS_DIR=/path/to/private/decks uv run wolfppt-harness benchmark-profile private-real-decks --iterations 15 --warmup 2 --min-private-decks 5 --min-distinct-private-decks 5 --min-private-total-slides 50 --min-private-total-shapes 100 --min-private-total-tables 1 --min-private-total-charts 1 --min-private-total-media 1 --min-private-total-embedded-objects 1 --min-private-decks-with-tables 1 --min-private-decks-with-charts 1 --min-private-decks-with-media 1 --min-private-decks-with-embedded-objects 1 --min-private-distinct-decks-with-tables 1 --min-private-distinct-decks-with-charts 1 --min-private-distinct-decks-with-media 1 --min-private-distinct-decks-with-embedded-objects 1 --min-private-slides-per-deck 3 --min-private-shapes-per-deck 10 --validate-openxml --progress --fail-fast --min-native-roundtrip-speedup 1.0 --min-distinct-fixtures 5 --min-openxml-samples 100 --write-report
WOLFPPT_PRIVATE_DECKS_DIR=/path/to/private/decks uv run wolfppt-harness private-report-check results/benchmarks/latest
SYNCFUSION_LICENSE_KEY='...' uv run wolfppt-harness benchmark --adapter syncfusion-roundtrip --fixture text_basic/title_body_bullets --validate-openxml --json
uv run wolfppt-harness benchmark --adapter aspose-docker-roundtrip --fixture text_basic/title_body_bullets --validate-openxml --json
uv run --with Spire.Presentation wolfppt-harness benchmark-profile sdk-spire-reproducer --iterations 3 --warmup 1 --validate-openxml --progress --write-report
uv run --with Spire.Presentation wolfppt-harness benchmark --adapter spire-presentation-roundtrip,native-rust-roundtrip --fixture workloads/mixed_real_world_deck --iterations 3 --warmup 1 --validate-openxml --write-report --json
WOLFPPT_EXTERNAL_ROUNDTRIP_SDK_NAME='Vendor Slides' WOLFPPT_EXTERNAL_ROUNDTRIP_SDK_VERSION='1.2.3' WOLFPPT_EXTERNAL_ROUNDTRIP_CMD='vendor-tool --input {input} --output {output}' uv run wolfppt-harness benchmark --adapter external-command-roundtrip --fixture text_basic/title_body_bullets --validate-openxml --json
WOLFPPT_EXTERNAL_ROUNDTRIP_SDK_NAME='copy-example' WOLFPPT_EXTERNAL_ROUNDTRIP_SDK_VERSION='0.0.0' WOLFPPT_EXTERNAL_ROUNDTRIP_CMD='python3 examples/external-roundtrip/external-command/copy_roundtrip.py --input {input} --output {output}' uv run wolfppt-harness benchmark --adapter external-command-roundtrip --fixture text_basic/title_body_bullets --validate-openxml --json
WOLFPPT_EXTERNAL_ROUNDTRIP_SDK_NAME='Vendor Slides' WOLFPPT_EXTERNAL_ROUNDTRIP_SDK_VERSION='1.2.3' WOLFPPT_EXTERNAL_ROUNDTRIP_CMD='vendor-tool --input {input} --output {output}' uv run wolfppt-harness benchmark-profile sdk-comparison --require-adapter external-command-roundtrip --validate-openxml --progress --write-report
uv run wolfppt-harness benchmark --adapter python-pptx-roundtrip,openxml-sdk-roundtrip,pptxgenjs-generate,apache-poi-roundtrip,native-rust-roundtrip --fixture charts/bar_chart --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-edit,wolfppt-facade-dropin-edit --fixture text_basic/title_body_bullets,tables/simple_table --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-file-like-edit,wolfppt-facade-dropin-file-like-edit --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-table-cell-text-frame-edit,wolfppt-facade-dropin-table-cell-text-frame-edit --fixture tables/simple_table --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-table-style-flags-edit,wolfppt-facade-dropin-table-style-flags-edit --fixture tables/simple_table --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-table-dimensions-edit,wolfppt-facade-dropin-table-dimensions-edit --fixture tables/simple_table --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-multi-edit,wolfppt-facade-dropin-multi-edit --fixture workloads/multi_edit_table --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-formatting-edit,wolfppt-facade-dropin-formatting-edit --fixture text_basic/title_body_bullets,workloads/multi_format_runs --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-add-run-formatting-edit,wolfppt-facade-dropin-add-run-formatting-edit --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-add-paragraph-run-formatting-edit,wolfppt-facade-dropin-add-paragraph-run-formatting-edit --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-replace-run-formatting-edit,wolfppt-facade-dropin-replace-run-formatting-edit --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-paragraph-format-edit,wolfppt-facade-dropin-paragraph-format-edit --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-paragraph-level-edit,wolfppt-facade-dropin-paragraph-level-edit --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-paragraph-spacing-edit,wolfppt-facade-dropin-paragraph-spacing-edit --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-paragraph-clear-edit,wolfppt-facade-dropin-paragraph-clear-edit --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-paragraph-line-break-edit,wolfppt-facade-dropin-paragraph-line-break-edit --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-paragraph-font-edit,wolfppt-facade-dropin-paragraph-font-edit --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-add-paragraph-format-edit,wolfppt-facade-dropin-add-paragraph-format-edit --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-add-picture,wolfppt-facade-dropin-add-picture --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-add-picture-auto-size,wolfppt-facade-dropin-add-picture-auto-size --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-add-picture-file-like,wolfppt-facade-dropin-add-picture-file-like --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-add-movie-file-like,wolfppt-facade-dropin-add-movie-file-like --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-add-ole-object-file-like,wolfppt-facade-dropin-add-ole-object-file-like --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-add-shape,wolfppt-facade-dropin-add-shape --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-add-textbox,wolfppt-facade-dropin-add-textbox --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-add-table,wolfppt-facade-dropin-add-table --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-add-slide,wolfppt-facade-dropin-add-slide --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-shape-adjustment-edit,wolfppt-facade-dropin-shape-adjustment-edit --fixture text_basic/title_body_bullets --validate-openxml --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-shape-line-element-edit,wolfppt-facade-dropin-shape-line-element-edit --fixture text_basic/title_body_bullets --validate-openxml --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-add-chart,wolfppt-facade-dropin-add-chart --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-add-bar-chart,wolfppt-facade-dropin-add-bar-chart --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-add-line-chart,wolfppt-facade-dropin-add-line-chart --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-add-pie-chart,wolfppt-facade-dropin-add-pie-chart --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-add-chart-template-family,wolfppt-facade-dropin-add-chart-template-family --fixture text_basic/title_body_bullets --validate-openxml --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-add-connector,wolfppt-facade-dropin-add-connector --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-existing-connector-connection-edit,wolfppt-facade-dropin-existing-connector-connection-edit --fixture text_basic/title_body_bullets --validate-openxml --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-connector-connection-edit,wolfppt-facade-dropin-connector-connection-edit --fixture text_basic/title_body_bullets --validate-openxml --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-group-connector-connection-edit,wolfppt-facade-dropin-group-connector-connection-edit --fixture shapes/grouped_shapes --validate-openxml --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-connector-line-style-edit,wolfppt-facade-dropin-connector-line-style-edit --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-picture-crop-edit,wolfppt-facade-dropin-picture-crop-edit --fixture media/png_picture,workloads/mixed_real_world_deck --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-shape-style-edit,wolfppt-facade-dropin-shape-style-edit --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-shape-theme-color-edit,wolfppt-facade-dropin-shape-theme-color-edit --fixture text_basic/title_body_bullets,shapes/grouped_shapes --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-shape-shadow-edit,wolfppt-facade-dropin-shape-shadow-edit --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-shape-hyperlink-edit,wolfppt-facade-dropin-shape-hyperlink-edit --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-shape-target-slide-edit,wolfppt-facade-dropin-shape-target-slide-edit --fixture slides/two_slide_text --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-shape-target-new-slide-edit,wolfppt-facade-dropin-shape-target-new-slide-edit --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-notes-text-edit,wolfppt-facade-dropin-notes-text-edit --fixture notes/speaker_notes --validate-openxml --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-notes-background-edit,wolfppt-facade-dropin-notes-background-edit --fixture notes/speaker_notes --validate-openxml --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-text-run-hyperlink-edit,wolfppt-facade-dropin-text-run-hyperlink-edit --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-shape-fill-solid-edit,wolfppt-facade-dropin-shape-fill-solid-edit --fixture text_basic/title_body_bullets,shapes/grouped_shapes --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-shape-line-fill-background-edit,wolfppt-facade-dropin-shape-line-fill-background-edit --fixture text_basic/title_body_bullets,shapes/grouped_shapes --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-shape-patterned-fill-edit,wolfppt-facade-dropin-shape-patterned-fill-edit --fixture text_basic/title_body_bullets,shapes/grouped_shapes --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-shape-gradient-fill-edit,wolfppt-facade-dropin-shape-gradient-fill-edit --fixture text_basic/title_body_bullets,shapes/grouped_shapes --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-shape-rotation-edit,wolfppt-facade-dropin-shape-rotation-edit --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-shape-name-edit,wolfppt-facade-dropin-shape-name-edit --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-font-language-edit,wolfppt-facade-dropin-font-language-edit --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-font-fill-edit,wolfppt-facade-dropin-font-fill-edit --fixture text_basic/title_body_bullets --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-text-frame-margin-edit,wolfppt-facade-dropin-text-frame-margin-edit --fixture text_basic/title_body_bullets,shapes/grouped_shapes --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-text-frame-word-wrap-edit,wolfppt-facade-dropin-text-frame-word-wrap-edit --fixture text_basic/title_body_bullets,shapes/grouped_shapes --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-text-frame-vertical-anchor-edit,wolfppt-facade-dropin-text-frame-vertical-anchor-edit --fixture text_basic/title_body_bullets,shapes/grouped_shapes --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-text-frame-auto-size-edit,wolfppt-facade-dropin-text-frame-auto-size-edit --fixture text_basic/title_body_bullets,shapes/grouped_shapes --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-text-frame-fit-text-edit,wolfppt-facade-dropin-text-frame-fit-text-edit --fixture text_basic/title_body_bullets,shapes/grouped_shapes --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-chart-read,wolfppt-facade-dropin-chart-read --fixture charts/bar_chart --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-chart-title-edit,wolfppt-facade-dropin-chart-title-edit --fixture charts/bar_chart --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-chart-legend-edit,wolfppt-facade-dropin-chart-legend-edit --fixture charts/bar_chart --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-chart-axis-title-edit,wolfppt-facade-dropin-chart-axis-title-edit --fixture charts/bar_chart --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-chart-axis-property-edit,wolfppt-facade-dropin-chart-axis-property-edit --fixture charts/bar_chart --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-chart-plot-property-edit,wolfppt-facade-dropin-chart-plot-property-edit --fixture charts/bar_chart --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-chart-data-label-edit,wolfppt-facade-dropin-chart-data-label-edit --fixture charts/bar_chart --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-chart-data-label-remove,wolfppt-facade-dropin-chart-data-label-remove --fixture charts/bar_chart --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-chart-point-data-label-edit,wolfppt-facade-dropin-chart-point-data-label-edit --fixture charts/bar_chart --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-chart-style-edit,wolfppt-facade-dropin-chart-style-edit --fixture charts/bar_chart --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-chart-format-edit,wolfppt-facade-dropin-chart-format-edit --fixture charts/bar_chart --json
uv run wolfppt-harness benchmark --adapter python-pptx-dropin-chart-data-edit,wolfppt-facade-dropin-chart-data-edit --fixture charts/bar_chart --json
uv run wolfppt-harness benchmark-adapters
uv run wolfppt-harness matrix
uv run wolfppt-harness tools
cargo test
cargo run -p wolfppt-cli -- inspect fixtures/pptx/text_basic/title_body_bullets.pptx
cargo run -p wolfppt-cli -- summary fixtures/pptx/text_basic/title_body_bullets.pptx
cargo run -p wolfppt-cli -- roundtrip fixtures/pptx/text_basic/title_body_bullets.pptx /tmp/title_body_bullets.pptx
cargo run -p wolfppt-cli -- add-slide fixtures/pptx/text_basic/title_body_bullets.pptx /tmp/add_slide.pptx 0
cargo run -p wolfppt-cli -- replace-text fixtures/pptx/text_basic/title_body_bullets.pptx /tmp/title_body_bullets.pptx WolfPPT "WolfPPT Native"
cargo run -p wolfppt-cli -- replace-text-in-slide fixtures/pptx/text_basic/title_body_bullets.pptx /tmp/title_body_bullets.pptx 0 WolfPPT "WolfPPT Native"
cargo run -p wolfppt-cli -- replace-text-run fixtures/pptx/text_basic/title_body_bullets.pptx /tmp/title_body_bullets.pptx 0 1 "Fast Native"
cargo run -p wolfppt-cli -- set-shape-text fixtures/pptx/text_basic/title_body_bullets.pptx /tmp/title_body_bullets.pptx 0 1 "Fast Native"
cargo run -p wolfppt-cli -- set-paragraph-text fixtures/pptx/text_basic/title_body_bullets.pptx /tmp/title_body_bullets.pptx 0 1 0 "Fast Native"
cargo run -p wolfppt-cli -- replace-image fixtures/pptx/media/png_picture.pptx /tmp/png_picture.pptx rId2 /tmp/image.png
cargo run -p wolfppt-cli -- replace-image-in-slide fixtures/pptx/media/png_picture.pptx /tmp/png_picture.pptx 0 rId2 /tmp/image.png
cargo run -p wolfppt-cli -- add-image fixtures/pptx/text_basic/title_body_bullets.pptx /tmp/add_image.pptx 0 /tmp/image.png 0 0 914400 914400
cargo run -p wolfppt-cli -- replace-table-cell fixtures/pptx/tables/simple_table.pptx /tmp/simple_table.pptx 0 0 1 1 "2"
cargo run -p wolfppt-cli -- add-table fixtures/pptx/text_basic/title_body_bullets.pptx /tmp/add_table.pptx 0 2 3 0 0 2743200 914400
uv run maturin develop --manifest-path crates/wolfppt-py/Cargo.toml
uv run maturin develop --release --manifest-path crates/wolfppt-py/Cargo.toml
For performance claims involving wolfppt_native, rebuild the PyO3 module with
uv run maturin develop --release --manifest-path crates/wolfppt-py/Cargo.toml
before running benchmarks. Debug native builds are useful for development, but
their timings are not benchmark evidence.
For private corpora with source-invalid decks, add
--min-source-invalid-preserved-samples N to the private-real-decks profile
alongside --validate-openxml before claiming that WolfPPT preserves those exact
validator failures.
Current Sprint
Built so far:
- compatibility spec source of truth in
docs/compatibility/_compat_spec.py - semantic extractor for PPTX package parts, relationships, slides, text, tables, pictures, charts, notes, and macro-package signals
- append-only result writer
- generated compatibility matrix renderer
- known-gaps sync tests
- deterministic Phase 1 fixture corpus generator using python-pptx-authored valid packages
- normalized package manifest and diff commands
- optional python-pptx baseline summary and round-trip commands
- Open XML SDK validator project and CLI wrapper
- LibreOffice PDF render smoke command
- corpus runner with semantic oracle, Open XML validation, optional python-pptx round-trip, optional LibreOffice render, Markdown/JSON reports, and append-only result rows
- repeatable benchmark runner with warmups, latency statistics, RSS snapshots, semantic/package correctness checks, JSON/Markdown reports, and append-only benchmark result rows
- Rust
wolfppt-corepackage-inspection crate for listing OOXML parts and detecting VBA packages - Rust
wolfppt-clibridge and Python adapter for invoking the Rust reader from the harness - optional Microsoft PowerPoint PNG export adapter for the gold visual oracle
- optional
wolfppt_nativePyO3 binding for direct Python access to the Rust package reader and corpus-run lane - typed Rust PresentationML summary for slide discovery, text runs, notes, tables, slide relationships, image/chart/comment/media/OLE relationship buckets, and transition/timing flags
- typed Rust and semantic-oracle extraction for shape trees, grouped shapes, child shapes, local transforms, and inherited effective transforms
- native Python access to the Rust typed presentation summary
- Rust-vs-Python semantic parity comparison for typed native summaries
- Rust CLI and native binding package round-trip lanes that prove part-level preservation with semantic and package diffs
- explicit OLE object fixture coverage for slide-level
oleObjectrelationships and embedded binary preservation - Rust CLI and native binding blank-slide append using either the first slide's layout relationship or a selected existing layout index, with editable placeholder materialization, corpus mutation lanes checking slide count, package delta, and Open XML validation when the validator is available
- Rust CLI and native binding exact slide-text replacement across all slides or scoped to a selected slide index, selected text-run replacement, and selected shape-level text setting with newline-separated text-frame paragraphs, plus selected paragraph text setting while preserving unrelated package parts
- Rust CLI and native binding replacement of an existing slide image relationship payload globally or scoped to a selected slide index while preserving package relationships, plus new PNG/JPEG/GIF picture-shape insertion with explicit EMU bounds
- Rust CLI and native binding basic empty-table insertion with explicit EMU bounds and table-cell text replacement by slide/table/row/column index while preserving unrelated package parts
- legacy comment fixture coverage with comment/comment-author parts preserved by Rust CLI/native round-trip package diffs
- chart fixture coverage with embedded workbook preservation verified by Rust CLI/native round-trip package diffs
- OLE object fixture coverage with embedded binary preservation verified by Rust CLI/native round-trip package diffs
- transition fixture coverage with Open XML validation and Rust CLI/native round-trip preservation
- animation timing-tree fixture coverage with Open XML validation and Rust CLI/native round-trip preservation
- grouped-shape fixture coverage with inherited transform semantics
- Rust-vs-Python semantic parity now compares shape tree facts, so grouped shape support is enforced in native summary corpus lanes
- public
wolfppt.Presentationfacade with python-pptx-style blank-deck construction, slide/shape iteration, andshape.textedits saved through the native Rust mutation path - dynamic public-surface ratchet comparing common WolfPPT facade objects and
all checked-in real-fixture shape objects against python-pptx public names
and public read access, exposed as
uv run wolfppt-harness python-api-surface --json; release-style runs can require minimum fixture/object-pair counts and write latest plus archived evidence underresults/api-surface/ - read-only python-pptx-style
.partmetadata for presentations, slide collections, slides, slide layouts, shape/placeholder collections, shapes, actions, text objects, charts, and tables, includingpartname,content_type,blob,part, andpackage Presentation.slide_widthandPresentation.slide_heightreads/writes with python-pptx parity, package-delta checks, and a dedicated slide-size benchmark lanePresentation.core_propertiesreads/writes for common document metadata, including title, subject, author, keywords, comments, revision, timestamps, and status fields, with changes isolated todocProps/core.xmland covered by a dedicated benchmark laneslide.slide_id,slide.slide_layout,slide.follow_master_background,slide.has_notes_slide,slides.get(...), andslide.namereads/writes with python-pptx parity, target-slide package-delta checks, and a dedicated drop-in slide-name benchmark lane- existing
slide.notes_slide,notes_slide.notes_text_frame, notes shapes/placeholders, andPresentation.notes_masterreads with python-pptx parity for packages that already contain notes parts notes_slide.notes_text_frame.text, paragraph, and run edits with dedicated drop-in benchmarks that change only the target notes-slide XML partnotes_slide.clone_master_placeholders(...)andnotes_slide.shapes.clone_placeholder(...)coverage with notes-placeholder metadata parity and changes isolated to the target notes-slide XML partslide.background, layout/background, slide-master/background, and notes-master/background reads for element metadata and fill state, plusslide.background.fill.solid(), layout/master.background.fill.solid(),.background(), and foreground RGB/theme-color/brightness edits isolated to the target XML partPresentation.slide_master,Presentation.slide_masters, slide-master layout, shape, and placeholder metadata, and unusedPresentation.slide_layouts.remove(...)for template cleanup workflows- empty
shape.text = ""andshape.text_frame.clear()keep python-pptx's one-empty-paragraph runtime semantics while saving through native Rust slide.shapes.title,slide.placeholders, andplaceholder_formatmetadata backed by Rust placeholder extraction and a python-pptx parity probeshape.left,shape.top,shape.width, andshape.heightreads/writes routed through native Rust with a python-pptx parity probeshape.text_frame.paragraphs[index].textrouted through native Rust with a python-pptx parity probe for paragraph-level text editsshape.text_frame.paragraphs[index].clear()removes paragraph content while preserving empty-paragraph positions and paragraph propertiesshape.text_frame.paragraphs[index].add_line_break()inserts DrawingML line breaks while preserving python-pptx's\vparagraph text semanticsshape.text_frame.fit_text(...)sets word-wrap, auto-size, and run font properties with python-pptx parity for stable font-file-backed casesshape.text_frame.paragraphs[index].fontexposes paragraph default run properties for bold, italic, underline, size, name, RGB color, fill, and language- paragraph alignment, level, and spacing reads/writes for existing and appended paragraphs with python-pptx parity probes and package-delta checks
shape.text_frame.paragraphs[index].runs[index].text,run.font.bold,run.font.italic,run.font.underline,run.font.size,run.font.name,run.font.color.rgb, richrun.font.fill, andrun.font.language_idreads/writes, including solid/background/patterned/gradient fill modes, paragraph appends, appended-paragraph run formatting, and run appends routed through native Rust plus slide XML patches with python-pptx parity probesPresentation.slide_layoutsandslides.add_slide(layout)routed through native Rust with a python-pptx parity probe for blank-slide insertionslide.shapes.add_textbox(...)routed through native Rust with a python-pptx parity probe for text box insertion, immediate shape IDs, and immediate text editsslide.shapes.add_shape(...)for common preset autoshapes routed through native Rust with python-pptx parity probes for immediate shape IDs, preset geometry, pending style defaults, and text editsshape.auto_shape_typereads for supported preset autoshapes, matching python-pptx's non-autoshape error behaviorshape.adjustmentsreads/writes for supported preset autoshapes at slide level and inside grouped shapes, including rounded-rectangle adjustment guide persistence with benchmark coverageshape.lnandshape.get_or_add_ln()line XML helpers for shape elements, matching python-pptx's low-level line-element surfaceshape.shape_typereads for text boxes and common shape classes, including python-pptx's TEXT_BOX vs AUTO_SHAPE distinctionshape.shadow.inheritreads/writes for shape shadow inheritance toggles with python-pptx parity probes and package-delta checksshape.click_action.hyperlink.addressreads/writes for external hyperlinks, changing only the target slide XML and slide relationship partshape.click_action.target_slidereads/writes for internal slide jumps, changing only the target slide XML and slide relationship partrun.hyperlink.addressreads/writes for external text-run hyperlinks, changing only the target slide XML and slide relationship partslide.shapes.add_picture(...)routed through native Rust with python-pptx parity probes for immediate shape IDs and explicit, native, or proportionally inferred picture boundsslide.shapes.add_connector(...)routed through native Rust with python-pptx parity probes for straight, elbow, and curve connector presets; connectorshape_id,begin_x,begin_y,end_x, andend_yreads match python-pptx, and slide-levelbegin_connect()/end_connect()attachments persist for saved and newly added target shapes with benchmark coverage- connector
line.color.rgb,line.width, andline.dash_stylereads/writes with python-pptx parity probes and package-delta checks - picture
crop_left,crop_right,crop_top, andcrop_bottomreads/writes for existing picture elements with python-pptx parity probes and package-delta checks shape.has_table,shape.table, andtable.cell(...).textrouted through native Rust with a python-pptx parity probe for table cell editstable.cell(...).text_frametext, paragraphs, add/clear, wrapping, autosize, fit XML, cell margins, and vertical anchors with parity/package-delta checkstable.cell(...).fillsolid/background fills and foreground RGB with python-pptx parity probes and package-delta checkstable.cell(...).merge(...),.split(), and span metadata with python-pptx parity probes and package-delta checks- table
first_row,first_col,last_row,last_col,horz_banding,vert_banding, anditer_cells()with python-pptx parity probes slide.shapes.add_table(...)routed through native Rust with a python-pptx parity probe for basic table insertion and immediate cell editsslide.shapes.add_chart(...)andgroup.shapes.add_chart(...)add common category chart families, including column, bar, line, and pie variants, by transplanting packaged chart templates into the original package with python-pptx parity and package-delta checks, including no-series, empty-series, sparse category, hierarchical category, and XY/bubble data, without importing python-pptx at save timeshape.chart.element,chart.plots,chart.chart_style, andchart.chart_title.has_text_frame, plus read-only chart/axis format, chart-font, major-gridline, tick-label, and category-axis type proxies with python-pptx parity and benchmark coverageshape.chart.replace_data(CategoryChartData/XyChartData/BubbleChartData)for category, XY scatter, and bubble charts, including series-count changes and sparse and hierarchical category data and uneven XY/bubble point counts, with python-pptx parity probes and package-delta checksshape.chart.has_titleandshape.chart.chart_title.text_frame.textfor chart title creation/removal with python-pptx parity probes and package-delta checksshape.chart.has_legend,shape.chart.legend.position, andshape.chart.legend.include_in_layoutfor chart legend creation/removal with python-pptx parity probes and package-delta checksshape.chart.category_axis.axis_title.text_frame.textandshape.chart.value_axis.axis_title.text_frame.textfor chart axis title creation/removal with python-pptx parity probes and package-delta checksshape.chart.category_axis/value_axisvisibility, gridline flags, tick marks, tick-label position, reverse-order, scale, and value-axis unit and crossing edits with python-pptx parity probes and package-delta checksshape.charttitle, axis-title, plot/series data-label, and point-label paragraph/run font fills cover solid, background, patterned, and gradient modes with python-pptx parity probes and benchmark coverageshape.fill.solid(),shape.fill.fore_color.rgb, andshape.fill.gradient()/shape.fill.gradient_angle/shape.fill.gradient_stops, plusshape.fill.background()/shape.fill.patterned()/shape.fill.pattern/shape.fill.back_color.rgb, plusshape.line.color.rgb/shape.line.fill.solid()/shape.line.fill.background()/shape.line.fill.patterned()/shape.line.fill.pattern/shape.line.fill.fore_color.rgb/shape.line.fill.back_color.rgb/shape.line.width/shape.line.dash_stylefor existing shape elements with python-pptx parity probes and package-delta checksshape.rotationfor existing shape elements with python-pptx parity probes, Open XML validation, and package-delta checksshape.namefor template-oriented shape identification workflows with python-pptx parity probes, Open XML validation, and package-delta checksshape.text_frame.margin_left/right/top/bottomfor text-box layout control with python-pptx parity probes, Open XML validation, and package-delta checksshape.text_frame.word_wrapfor text-box layout control with python-pptx parity probes, Open XML validation, and package-delta checksshape.text_frame.vertical_anchorfor text-box layout control with python-pptx parity probes, Open XML validation, and package-delta checks
Planned next:
See the WolfPPT Roadmap for the active dependency-ordered epics (Epics 0 through 5), north star principles, and development protocol.
Release readiness
Public releases are cut with the operator checklist in
docs/release/PUBLISH_CHECKLIST.md:
freeze the candidate commit, produce the platform evidence card with
wolfppt-harness release-candidate --strict, gate on a green detached
claims job at the exact frozen head, and only then publish. The checklist
defines the full gate order and the evidence to record at each step.
License
MIT — see LICENSE.
Security
See SECURITY.md. WolfPPT makes no network requests and
collects no telemetry. Macro-enabled .pptm packages are supported: VBA
projects are preserved byte-for-byte as opaque data and are never authored,
interpreted, or executed.
Metadata
Release files for wolfppt 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
Total release size: 52.0 MB
Release files / wolfppt-0.1.0-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl
| Download URL | wolfppt-0.1.0-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 2.6 MB |
| Tags | Linux glibc 2.28+ x86-64 PyPy 3.11 PyPy 3.11 7.3 |
|
SHA-256 checksum How to use checksums |
f04ce717f194b441b8ff343fe7bc803c2abf8ad29fd99f2b5f56382b68601781
|
|
BLAKE2b-256 checksum How to use checksums |
96fdb0054aab94b1306e68305aac91b0e7d34695cb97883d3f96655faa91ef6e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / wolfppt-0.1.0-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl
| Download URL | wolfppt-0.1.0-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl |
|---|---|
| Size | 2.6 MB |
| Tags | Linux glibc 2.28+ ARM64 PyPy 3.11 PyPy 3.11 7.3 |
|
SHA-256 checksum How to use checksums |
00566bf61ca4f2752b57d25e2ea53c66435cfec9e7caeced9ab5ad84645fd550
|
|
BLAKE2b-256 checksum How to use checksums |
690a4eef3fff6dadec1e6a9d13e637d98dc1dd06d6feea1a4dbebe31e320c32c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / wolfppt-0.1.0-cp315-cp315t-manylinux_2_28_x86_64.whl
| Download URL | wolfppt-0.1.0-cp315-cp315t-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 2.6 MB |
| Tags | CPython 3.15 CPython 3.15 free-threading Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
042b760e1f8bd21632d85cad22f3db9dd2e139abe80377100751db1d4935372a
|
|
BLAKE2b-256 checksum How to use checksums |
5441424c579351445f561b5cf9ff73854a51442ed3579744599c779aece5f23a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / wolfppt-0.1.0-cp315-cp315t-manylinux_2_28_aarch64.whl
| Download URL | wolfppt-0.1.0-cp315-cp315t-manylinux_2_28_aarch64.whl |
|---|---|
| Size | 2.6 MB |
| Tags | CPython 3.15 CPython 3.15 free-threading Linux glibc 2.28+ ARM64 |
|
SHA-256 checksum How to use checksums |
87e4634c38efd3e66fcc031b2c804f798ff1ac339b94c8e549474f94d7a4db62
|
|
BLAKE2b-256 checksum How to use checksums |
b86b7b3aee7ada85ec36e2a9354d09b603471f14b735190fee76d6f9a8a3386e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / wolfppt-0.1.0-cp315-cp315-manylinux_2_28_x86_64.whl
| Download URL | wolfppt-0.1.0-cp315-cp315-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 2.6 MB |
| Tags | CPython 3.15 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
b74a75ea8c05ecb17e41883cbfcd59ec55c6e4c4e23d3a336ea0c220aa91d637
|
|
BLAKE2b-256 checksum How to use checksums |
1c7c451c7ef5f9a8f70d6216abe8381b8c0e2616fa24b048ada21117af6cdf5c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / wolfppt-0.1.0-cp315-cp315-manylinux_2_28_aarch64.whl
| Download URL | wolfppt-0.1.0-cp315-cp315-manylinux_2_28_aarch64.whl |
|---|---|
| Size | 2.6 MB |
| Tags | CPython 3.15 Linux glibc 2.28+ ARM64 |
|
SHA-256 checksum How to use checksums |
19202150e5da396b3c338698aed2a4ef81e9ce28e0dfc58cdc2b475a19683a41
|
|
BLAKE2b-256 checksum How to use checksums |
b662e9818028f16f00dc16f7730469b9a5ea55cd8e6c7ff16990167d5b2eaef4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / wolfppt-0.1.0-cp314-cp314t-manylinux_2_28_x86_64.whl
| Download URL | wolfppt-0.1.0-cp314-cp314t-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 2.6 MB |
| Tags | CPython 3.14 CPython 3.14 free-threading Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
e6d019e1f7b0f5a77f70bc936ea2899d205cd448b48de44bbac078ee270ad7ff
|
|
BLAKE2b-256 checksum How to use checksums |
f37b6eb64e86eac0e82deae468ebb8b541dc3a844c77d5fa5256e8ad4997991d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / wolfppt-0.1.0-cp314-cp314t-manylinux_2_28_aarch64.whl
| Download URL | wolfppt-0.1.0-cp314-cp314t-manylinux_2_28_aarch64.whl |
|---|---|
| Size | 2.6 MB |
| Tags | CPython 3.14 CPython 3.14 free-threading Linux glibc 2.28+ ARM64 |
|
SHA-256 checksum How to use checksums |
6032807f9dccb75528eb0e755f691237723d168447c86da5b400fb43f8a834fc
|
|
BLAKE2b-256 checksum How to use checksums |
0f867903c4360e759064bdb2566994a765aa095a07b2e7e19b1f3f0162d744fd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / wolfppt-0.1.0-cp314-cp314-manylinux_2_28_x86_64.whl
| Download URL | wolfppt-0.1.0-cp314-cp314-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 2.6 MB |
| Tags | CPython 3.14 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
80b71e2c8f62f4c62509abb2333868773eb08c8205b7108b1192f382c4bd0bad
|
|
BLAKE2b-256 checksum How to use checksums |
6398241f3b1632708616a7b8a9e8963820a3564c67f55d3c1c89774bbfea5014
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / wolfppt-0.1.0-cp314-cp314-manylinux_2_28_aarch64.whl
| Download URL | wolfppt-0.1.0-cp314-cp314-manylinux_2_28_aarch64.whl |
|---|---|
| Size | 2.6 MB |
| Tags | CPython 3.14 Linux glibc 2.28+ ARM64 |
|
SHA-256 checksum How to use checksums |
a75f759f46193fb16417d04c21e02b958a7d9065e2d7acda3115552a7c32cfa4
|
|
BLAKE2b-256 checksum How to use checksums |
702a8ed44be8c512cf79e07b502fe052ff4ba449ac74446d54b510970398b317
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / wolfppt-0.1.0-cp314-cp314-macosx_11_0_arm64.whl
| Download URL | wolfppt-0.1.0-cp314-cp314-macosx_11_0_arm64.whl |
|---|---|
| Size | 2.5 MB |
| Tags | CPython 3.14 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
47953dbc2896ae57e1972e4081912e7936e806b324cc10f82b8f94cf5d0d74c8
|
|
BLAKE2b-256 checksum How to use checksums |
7f84eef923840565816c480781bfb20336e90994f90dca4b9062184e2d91888d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / wolfppt-0.1.0-cp313-cp313-manylinux_2_28_x86_64.whl
| Download URL | wolfppt-0.1.0-cp313-cp313-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 2.6 MB |
| Tags | CPython 3.13 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
a7db375404486dbd532d3148202999f159ff6a376c73c974244d1fcb37c7fdf5
|
|
BLAKE2b-256 checksum How to use checksums |
135e6b1faba6d2be178cdbe040fbc4840560dd31b95c187a8837ebefdf8f4d42
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / wolfppt-0.1.0-cp313-cp313-manylinux_2_28_aarch64.whl
| Download URL | wolfppt-0.1.0-cp313-cp313-manylinux_2_28_aarch64.whl |
|---|---|
| Size | 2.6 MB |
| Tags | CPython 3.13 Linux glibc 2.28+ ARM64 |
|
SHA-256 checksum How to use checksums |
c9b2d98ad2a64c4c30a5679839c0f043ed3a692dd9b9a3dd5fd3100f455e82d0
|
|
BLAKE2b-256 checksum How to use checksums |
35800c459b58e2f3edd51d396609bd61abb670863390b0daabd510ceaad31dba
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / wolfppt-0.1.0-cp313-cp313-macosx_11_0_arm64.whl
| Download URL | wolfppt-0.1.0-cp313-cp313-macosx_11_0_arm64.whl |
|---|---|
| Size | 2.5 MB |
| Tags | CPython 3.13 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
0e4f617fe98936b69c73186f0fdf79692c6197dc343a682fe59d0d02f7a21a92
|
|
BLAKE2b-256 checksum How to use checksums |
63512b453e06d39d0a75149782d7206a88d18d4b463762bf1043eed9a3eee2c7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / wolfppt-0.1.0-cp312-cp312-manylinux_2_28_x86_64.whl
| Download URL | wolfppt-0.1.0-cp312-cp312-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 2.6 MB |
| Tags | CPython 3.12 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
880ed424b07c09cb4d3769845c1522fc0223a038b9e5871997ca655bf1fa4839
|
|
BLAKE2b-256 checksum How to use checksums |
619af00a6651f5b641f07f5215a2f22a687b10eb14c7a49676221ce9fdfd35c7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / wolfppt-0.1.0-cp312-cp312-manylinux_2_28_aarch64.whl
| Download URL | wolfppt-0.1.0-cp312-cp312-manylinux_2_28_aarch64.whl |
|---|---|
| Size | 2.6 MB |
| Tags | CPython 3.12 Linux glibc 2.28+ ARM64 |
|
SHA-256 checksum How to use checksums |
70b38180dbec9dfedecfe453f96fa9a60784290dd5ca279e8c04e31d538a2952
|
|
BLAKE2b-256 checksum How to use checksums |
471e211e162aeeaee139f82e49cdfa16524b6ae7bd074fe47d646c93c23480cf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / wolfppt-0.1.0-cp312-cp312-macosx_11_0_arm64.whl
| Download URL | wolfppt-0.1.0-cp312-cp312-macosx_11_0_arm64.whl |
|---|---|
| Size | 2.5 MB |
| Tags | CPython 3.12 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
03ca805611a5d6878c23797dfb8f5481cedd707cf6a76a353a242e64578ce4f0
|
|
BLAKE2b-256 checksum How to use checksums |
be4a3cbe36021e46ec0739423a1685547fab4c1ccbbd9afdfa9e422c4bc89fc9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / wolfppt-0.1.0-cp311-cp311-manylinux_2_28_x86_64.whl
| Download URL | wolfppt-0.1.0-cp311-cp311-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 2.6 MB |
| Tags | CPython 3.11 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
f89795b030828083da93cbb513047e18d0e7741454a91dffab920ca67eb598a9
|
|
BLAKE2b-256 checksum How to use checksums |
b5e1fb080ad7ddaac84d22d1ad09c28ae8adf8249318e977fd4f117fc6a18b83
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / wolfppt-0.1.0-cp311-cp311-manylinux_2_28_aarch64.whl
| Download URL | wolfppt-0.1.0-cp311-cp311-manylinux_2_28_aarch64.whl |
|---|---|
| Size | 2.6 MB |
| Tags | CPython 3.11 Linux glibc 2.28+ ARM64 |
|
SHA-256 checksum How to use checksums |
d294cfbc255286ace22eef2cb31a7fb278f16ad1ff9508698b0606863e860df1
|
|
BLAKE2b-256 checksum How to use checksums |
f042b4e2302aabea92a9c36058a16c67a71bf4287f4bd13c81064a6c185ddf1b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / wolfppt-0.1.0-cp311-cp311-macosx_11_0_arm64.whl
| Download URL | wolfppt-0.1.0-cp311-cp311-macosx_11_0_arm64.whl |
|---|---|
| Size | 2.5 MB |
| Tags | CPython 3.11 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
da3cab4b2b09388fdf92695ec9b9dafe0f5ca444631c02ae2501f0b6b849bfe2
|
|
BLAKE2b-256 checksum How to use checksums |
70421bf09ad637a453b5dda0cedc2cbb213cd2de1f3f2b103b932b3454d1458c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|