Template-bound PowerPoint generation for enterprise decks.
pptx turns a real .pptx template into a machine-readable manifest, then generates slides and decks inside the original corporate design contract instead of trying to approximate it from prompts.
If your organization cares about slide masters, locked branding, placeholder rules, layout fidelity, and CI validation, this is the tool.
The package is published to PyPI as pptx-cli and installs the pptx command.
Most AI slide generators fail where enterprise users care most:
- layouts drift from the official template
- placeholders get used inconsistently
- static branding moves or disappears
- theme styling gets recreated approximately instead of preserved exactly
- decks look plausible but are structurally wrong
pptx takes a different approach:
- Initialize from a real template
- Extract a manifest of layouts, placeholders, assets, and rules
- Generate only within those approved boundaries
- Validate output before it reaches humans, CI, or customers
The result is a CLI that behaves more like a compiler toolchain than a drawing tool.
- Initialize a manifest package from a real enterprise
.pptx - Inspect layouts, placeholders, themes, assets, and compatibility warnings
- Estimate text placeholder line capacity for agent guidance during inspection
- Build slides from approved layouts only
- Build full decks from JSON/YAML specs
- Preserve template-bound masters, themes, geometry, and protected elements
- Validate generated decks against manifest rules and template fingerprints
- Diff template versions to detect breaking changes
- Generate template-specific wrapper CLIs
- Expose an agent-first machine contract with:
- stable JSON response envelopes
- structured error codes
- documented exit codes
- a built-in
guidecommand --dry-runsupport for mutating commands
uv tool install pptx-cliuv tool install git+https://github.com/ThomasRohde/pptx-cli.gitpip install pptx-clipptx --version
pptx guide --format jsonIf you use an AI coding agent such as Claude Code, Codex, or Copilot, you can install the pptx-deck-builder skill to give your agent the ability to build PowerPoint decks using pptx:
npx skills add ThomasRohde/pptx-cli --skill pptx-deck-builderThis installs the skill directly from the repository — no need to clone it.
The examples below assume you have a local PowerPoint template file available,
shown here as Template.pptx. Proprietary templates are intentionally not
committed to the GitHub repository.
Initialize a template package from an existing PowerPoint file:
pptx init ./Template.pptx --out ./corp-templateInspect the extracted layouts:
pptx layouts list --manifest ./corp-template
pptx layouts show title-only --manifest ./corp-template
pptx placeholders list 1-title-and-content --manifest ./corp-templatepptx placeholders list --format json includes both explicit placeholder guidance and
an estimated_text_capacity block for text-capable placeholders so agents can stay
inside likely line limits when drafting slide content.
Create a single slide:
pptx slide create \
--manifest ./corp-template \
--layout title-only \
--set title="Enterprise AI Operating Model" \
--set subtitle="March 2026" \
--notes-file ./speaker-notes.md \
--out ./out/operating-model-slide.pptxBuild a full deck from a spec:
pptx deck build \
--manifest ./corp-template \
--spec ./deck.yaml \
--out ./out/operating-model.pptxValidate the result:
pptx validate \
--manifest ./corp-template \
--deck ./out/operating-model.pptx \
--strictPreview the write before touching the filesystem:
pptx deck build \
--manifest ./corp-template \
--spec ./deck.yaml \
--out ./out/operating-model.pptx \
--dry-runReplace an existing output file explicitly:
pptx deck build \
--manifest ./corp-template \
--spec ./deck.yaml \
--out ./out/operating-model.pptx \
--overwritemanifest: ./corp-template
metadata:
title: Enterprise AI Operating Model
author: Thomas Rohde
template_version: 1.2.0
slides:
- layout: title-only
content:
title: Enterprise AI Operating Model
subtitle: March 2026
notes: |
# Opening talk track
- Lead with why preserving the template matters
- Call out that validation stays available for CI
- layout: 1-breaker-with-pattern
content:
title: Why this change
subtitle: Preserve, don’t imitate
- layout: 1-title-and-content
content:
title: Core idea
content_1: |
Preserve the template.
Generate inside its rules.
subtitle: Layouts and placeholders become machine-readable contracts.pptx guide
pptx init
pptx doctor
pptx layouts list
pptx layouts show
pptx placeholders list
pptx theme show
pptx assets list
pptx slide create
pptx deck build
pptx validate
pptx manifest diff
pptx manifest schema
pptx completions generate
pptx wrapper generate
A template initialization produces a package like this:
corp-template/
manifest.yaml
manifest.schema.json
annotations.yaml
assets/
images/
media/
embedded/
previews/
layouts/
fingerprints/
parts.json
reports/
init-report.json
manifest.yaml— extracted source-of-truth contractmanifest.schema.json— schema for validation and toolingannotations.yaml— human-authored semantic annotations and placeholder overrides layered over extracted factsreports/init-report.json— warnings, unsupported features, and compatibility findingsfingerprints/parts.json— structural fingerprints used for validation and diffing
pptx supports these placeholder content types in v1:
- text
- image
- table
- chart
- markdown-text
Speaker notes are also supported in v1 as optional slide-level metadata via
slides[].notes in deck specs or pptx slide create --notes/--notes-file.
They are not placeholder content types and do not change layout placeholder
contracts.
markdown-text is parsed with markdown-it-py and currently maps CommonMark blocks into
PowerPoint paragraphs. Headings become plain paragraphs, bullet lists use native PowerPoint
bullet levels, ordered lists render as numbered paragraph text, and basic inline emphasis such
as bold/italic/code spans is preserved where PowerPoint run formatting can express it. Markdown
blocks also receive light presentation-aware spacing so headings, paragraphs, and lists do not
collapse into a dense wall of text.
The same markdown-to-text parsing pipeline is used for speaker notes, so headings, bullets, ordered lists, and basic inline emphasis remain available in presenter notes without introducing a separate formatting model.
pptx slide create --set picture=@diagram.png automatically normalizes the file into an
image payload. In deck specs, use the equivalent structured object explicitly:
slides:
- layout: 3-front-page-title-and-picture
content:
title: Workflow
picture:
kind: image
path: out/diagrams/workflow.png
image_fit: fitimage_fit defaults to fit, which preserves the whole image inside the placeholder.
Use cover to opt back into crop-to-fill behavior.
Tables and charts use the same kind pattern:
slides:
- layout: 1-title-and-content
content:
title: Status by workstream
content_1:
kind: table
columns: [Workstream, Status]
rows:
- [Platform, Active]
- [Sales, Planned]
- layout: 1-title-and-content
content:
title: Quarterly trend
content_1:
kind: chart
chart_type: column_clustered
categories: [Q1, Q2, Q3]
series:
- name: Revenue
values: [12, 15, 18]Guaranteed in scope:
- slide size and orientation
- master/layout relationships
- approved placeholder geometry
- protected static elements
- preserved theme references where supported
- deterministic content mapping into approved placeholders
Best-effort in v1:
- advanced chart workbook behavior
- highly custom chart or table styling internals
- content-sensitive text reflow edge cases
- animations and transitions
pptx is designed to be scriptable by both humans and coding agents.
In machine-readable mode, commands return a single JSON envelope on stdout:
{
"schema_version": "1.0",
"request_id": "req_20260307_120000_abcd",
"ok": true,
"command": "layouts.list",
"result": {},
"warnings": [],
"errors": [],
"metrics": {
"duration_ms": 42
}
}- stdout is reserved for structured machine output
- stderr is used for progress and diagnostics
LLM=trueenables minimal non-decorative output behavior--dry-runpreviews mutating commands without writing files
Use guide to retrieve the CLI contract in one call:
pptx guide --format jsonThat output includes:
- commands and subcommands
- input/output schema references
- examples
- error-code taxonomy
- exit-code mapping
- identifier conventions
pptx uses stable exit-code categories for automation:
| Exit code | Meaning |
|---|---|
0 |
Success |
10 |
Validation or schema error |
20 |
Permission or policy failure |
40 |
Conflict or stale-state failure |
50 |
I/O or package read/write failure |
90 |
Internal error |
Mutating commands support preview-first workflows and safe writes:
--dry-runfor non-destructive previews- structured change summaries for write operations
- explicit override flags for dangerous operations
- temporary-file staging and atomic replacement where possible
Because PowerPoint files are ZIP-based packages wearing office clothes, half the job is content generation and the other half is not breaking them.
You can generate a template-specific wrapper CLI for teams that want a narrower interface:
pptx wrapper generate \
--manifest ./corp-template \
--out ./wrappers/acme-pptxIn v1, wrapper generation emits a thin Python package scaffold that delegates to the shared pptx engine.
pptx validate checks both structure and fidelity constraints, including:
- master/layout usage
- placeholder mapping correctness
- required placeholder presence
- schema compliance of deck specs
- missing assets or broken relationships
- fingerprint mismatches for protected components
- geometry drift for locked objects and placeholders
This makes pptx suitable for:
- local authoring workflows
- CI pipelines
- agent-driven deck generation
- enterprise template governance
When templates change, pptx can compare manifest packages:
pptx manifest diff ./corp-template-v1 ./corp-template-v2Diffs highlight:
- added or removed layouts
- placeholder contract changes
- alias changes
- geometry changes
- theme/font changes
- asset changes
- additive vs. breaking changes
- Windows
- macOS
- Linux
Microsoft PowerPoint is not required to run the CLI.
- enterprise strategy decks
- consulting deliverables
- board and steering-committee presentations
- corporate communications templates
- internal automation pipelines generating
.pptxoutput from structured data - AI-assisted deck generation with strict branding control
If you have access to a proprietary integration template, place it locally as
an untracked Template.pptx in the repository root. That local fixture is used for:
- CLI integration tests
- README quick-start examples
- local manual smoke tests while the fixture catalog grows
CI does not require that file. It runs the public test suite with
PPTX_SKIP_TEMPLATE_TESTS=1.
If additional sanitized templates are introduced later, they should live under
tests/fixtures/templates/ with a short note describing their scenario coverage.
Clone the repository and sync the development environment:
git clone https://github.com/ThomasRohde/pptx-cli.git
cd pptx-cli
uv sync --group devRun the test suite:
uv run pytestRun linting and type checks:
uv run ruff check .
uv run ruff format --check .
uv run pyrightThe project uses semantic versioning with a single source of truth in src/pptx_cli/__init__.py.
Use the helper script to bump versions safely:
uv run python scripts/bump_version.py patch
uv run python scripts/bump_version.py minor
uv run python scripts/bump_version.py majorPushing a version change to main or master triggers the publish workflow
automatically. The helper only bumps the version, commits it, and pushes. The
publish workflow creates the matching release/tag on GitHub. Use --no-push to
keep the version bump local.
This updates the package version used for builds and PyPI publishing without needing to edit multiple files manually.
PRD.md— product definition and scopeCLI-MANIFEST.md— agent-first CLI design principles adopted by this projectSCAFFOLD.md— project scaffolding instructions
- richer preview generation
- deeper table/chart plugins
- broader enterprise policy packs
- multi-template registries
- post-v1 MCP integration
Contributions are welcome.
Please open an issue or discussion for:
- new placeholder/content type support
- template edge cases
- manifest schema changes
- CLI contract changes
- validation or fidelity bugs
For larger changes, include:
- the motivating template behavior
- expected vs. actual output
- sample manifest or sanitized
.pptxstructure where possible
MIT