Skip to main content

markdown-pptx

markdown-pptx turns constrained Markdown into editable PowerPoint .pptx presentations built from real PowerPoint layouts and placeholders. It is a strict, predictable CLI designed for both people and coding agents.

PowerPoint generation uses the ps-python-pptx fork. The converter uses public library APIs only. See the API boundary for the capability mapping.

Prerequisite

markdown-pptx is designed to be used with uv. Install uv before continuing. The documented workflows and managed agent skill use uvx to run the tool without requiring a global installation.

Quick start with an agent

Install the managed agent skill:

uvx markdown-pptx skill install

Then use $markdown-pptx in Codex, Claude Code, or another agent harness that supports skills:

Use $markdown-pptx to create a seven-slide presentation about our product launch. Use a clear narrative, include speaker notes, and save both the Markdown source and editable PowerPoint deck.

The skill teaches the agent how to inspect the format and templates, write valid slide Markdown, render the deck, and handle the result.

Manage the agent skill

The standard location is ~/.agents/skills/markdown-pptx/SKILL.md. Normal invocations of an installed CLI, including help and version output, automatically synchronize an already-installed managed skill to the running CLI version. Missing and unmanaged skills are left alone. Skill-management commands skip this automatic check.

Synchronization is local only. It does not query a package index, refresh uv's cache, or update the CLI. The running CLI version is the authority. PEP 440 version comparison prevents downgrades and leaves equal versions unchanged. The skill continues to instruct agents to use uvx markdown-pptx.

Each generated SKILL.md stores lifecycle data in its YAML metadata mapping:

metadata:
  managed-by: markdown-pptx
  managed-version: "1.3.0"
  managed-content-sha256: "sha256:<64 lowercase hexadecimal characters>"

The version above is illustrative. The generated value exactly matches uvx markdown-pptx --version. The SHA-256 hash covers the entire UTF-8 file with LF line endings and only the hash value replaced by "". Verification preserves the original YAML formatting and normalizes CRLF and CR line endings. This detects modifications. It is not a signature or security boundary. No sidecar files are used.

An older managed skill updates only when its own stored hash verifies. Modified files and valid-version files with missing or malformed hashes are preserved. The legacy HTML managed marker remains recognized. Legacy skills without a version migrate as version 0. Managed skills with missing or invalid version metadata receive a fresh replacement as a recovery step, without hash verification. A conflicting managed-by value always prevents replacement.

Inspect the path, ownership, versions, integrity, and automatic synchronization eligibility without changing anything:

uvx markdown-pptx skill status
uvx markdown-pptx skill status --json

A normal explicit install creates a missing skill or updates a pristine older one. It refuses to overwrite modified or unverifiable managed content with valid version metadata. To restore the bundled skill and discard those edits:

uvx markdown-pptx skill install --force

Install-time --force still refuses unmanaged skills and never downgrades a newer version. Removal accepts current and legacy managed skills. Its existing --force option also permits removing unmanaged content and extra files in the selected skill directory:

uvx markdown-pptx skill remove

All three commands accept --skills-dir PATH. Custom locations require explicit updates because normal CLI invocations inspect only the standard location. Local source checkouts, local direct-source installs, and editable builds do not synchronize automatically. Unidentifiable installation origins are skipped conservatively. An installed wheel remains eligible. Explicit commands such as uvx --from . markdown-pptx skill install still work during development.

Automatic replacements are atomic and recheck the installed file before replacement. Maintenance failures do not change the primary command's exit status. Update notices and preservation warnings go to stderr, so documented JSON results on stdout stay valid. Changes affect future agent skill loading and may not change instructions already loaded into a running agent session.

What it creates

Markdown stays readable, while the generated presentation remains easy to edit in PowerPoint.

Rendered PowerPoint slide example

Use the CLI directly

Render a deck without installing the package globally:

uvx markdown-pptx deck.md deck.pptx

Inspect the supported format or the layouts in the default template:

uvx markdown-pptx --syntax
uvx markdown-pptx --examples list
uvx markdown-pptx --examples two-content
uvx markdown-pptx --list-layouts

To install the command as a persistent tool instead:

uv tool install markdown-pptx

The examples below continue to use uvx markdown-pptx so they work without a global installation.

How the format works

The document model has four core rules:

  1. Optional document front matter may appear only at the beginning of the file.
  2. Each ATX # H1 or Setext H1 starts exactly one slide.
  3. Optional slide front matter may appear only immediately after its H1 heading.
  4. Everything until the next H1 belongs to that slide.

A minimal two-slide deck looks like this:

# Quarterly review
---
layout: Title Slide
---

Acme Corporation

# Highlights
---
layout: Title and Content
---

- Revenue grew 18%
- Customer retention reached 94%
- Two new products launched

Render it with:

uvx markdown-pptx deck.md deck.pptx

If no --template is provided, the packaged default template is used.

Use a PowerPoint template

Inspect a template before writing the deck, then use only the layouts it provides:

uvx markdown-pptx --list-masters --template theme.pptx
uvx markdown-pptx --list-layouts --template theme.pptx --master 2
uvx markdown-pptx deck.md deck.pptx --template theme.pptx --master 2

All embedded slide masters are retained in the output. This keeps every layout group available in PowerPoint after the deck is generated.

The effective master is selected in this order:

  1. The slide-level master value
  2. The CLI --master option
  3. The first embedded master

Master selectors may be 1-based indices or exact unique master or theme names. Indices are the most reliable choice because template names can be blank or duplicated. Layout names are resolved only within the effective master.

The renderer uses real placeholders for slide titles and bodies. Missing placeholders, duplicate layout names, and ambiguous placeholder mappings are errors. It does not invent free-positioned text boxes to compensate for an incompatible template.

Customize a deck

Document front matter sets deck-wide defaults:

Key Purpose
aspect_ratio Select 16:9 or 4:3
fonts Set body and heading fonts
color_scheme Start from a preset or define PowerPoint theme colors
background Set a solid color, gradient, image, or no background
title_color Set the default title color
body_color Set the default body and subtitle color

Slide front matter controls an individual slide:

Key Purpose
master Override the default slide master
layout Select a layout from the effective master
background Override the document background
title_color Override the document title color
body_color Override the document body color
hide_background_graphics Hide inherited master graphics
notes Add speaker notes to the PowerPoint notes pane
table Set native PowerPoint table-style flags

Run uvx markdown-pptx --syntax for the complete schema, accepted values, and examples.

Theme colors

Use color_scheme to recolor theme-aware template content throughout the presentation:

---
color_scheme:
  preset: Office
  dark_1: "#10263F"
  light_1: "#F9F9F9"
  accent_1: "#1D6FA8"
  accent_2: "#5AA9E6"
title_color: "var(--dark-1)"
body_color: "var(--dark-2)"
---

Colors accept hex, RGB, HSL, and PowerPoint theme references such as var(--accent-1). Set preset: null and provide all 12 theme slots for a fully custom palette. Theme-aware template objects follow the resulting palette, while hard-coded RGB colors and images do not.

When a template should provide the colors, use --ignore-document-colors, --ignore-slide-colors, or both. These options do not change images, layouts, or content.

Tables

Write standard Markdown pipe tables and put PowerPoint styling options in slide front matter:

# Quarterly summary
---
layout: Title and Content
table:
  header_row: true
  total_row: true
  first_column: true
  banded_rows: true
---

| Region | Revenue |
| --- | ---: |
| North | $50,000 |
| Total | $50,000 |

Table flags control native PowerPoint styling. They do not calculate totals or change the Markdown table structure. A slide may use table metadata only when it contains at least one table. The flags apply to both tables on a Two Content slide.

Images and paths

Local image paths are resolved relative to the Markdown file. Remote HTTP and HTTPS images are enabled by default. Use --no-remote-images for offline builds or untrusted Markdown. Download assets ahead of time and use local paths when reproducible builds matter.

When reading Markdown from stdin, provide an output path and a base directory for relative assets:

uvx markdown-pptx --input - --output deck.pptx --base-dir ./assets

Layouts and supported content

The built-in template provides these common layouts. Supplied templates may use different names and placeholders.

Layout Body behavior
Title Slide Body text is placed in the subtitle placeholder
Section Header Body text is placed in the subtitle or body placeholder
Title and Content Accepts text flow, one image, or one table
Two Content One thematic break separates left and right content. Each side accepts text flow, one image, or one table
Title Only Does not accept body content
Blank Requires an empty title and empty body

Supported Markdown includes:

  • Paragraphs
  • Bullet and ordered lists, nested up to three levels, with continuation paragraphs and empty items
  • Task lists with static checked and unchecked boxes
  • ATX or Setext H1 slide headings and H2 through H6 headings within a slide
  • Emphasis, strong text, strikethrough, superscript, subscript, inline code, and links
  • Hard line breaks from two trailing spaces or a trailing backslash
  • Fenced code blocks with editable syntax coloring for recognized languages
  • Plain indented code blocks
  • Blockquotes with nested text, headings, lists, and code
  • Pipe tables
  • Local and remote standalone images, including linked images

Soft line breaks become spaces so ordinary source wrapping does not force a line break on the slide. Use a hard line break when the visual line must end. A Setext heading uses === for H1 or --- for H2 on the next line. Setext has no H3 through H6 form. Slide front matter must still immediately follow the slide heading.

Inline formatting stays editable in PowerPoint, including formatting nested inside links. Task boxes are static symbols. Fenced code uses the first language label for syntax coloring when Pygments recognizes it. Unknown labels produce plain editable code. Image alt text and optional titles are stored in the picture metadata. A link around a standalone image makes the picture clickable.

HTML comments and tags are ignored. Text between tags stays visible as plain text. Script and style content is omitted.

The intentionally unsupported set includes:

  • Thematic breaks outside the single Two Content separator
  • Footnotes
  • Images mixed into text paragraphs
  • Arbitrary positioning
  • Layered backgrounds
  • Animations

Link and image definitions apply across the whole deck, including slide titles. Full references ([Guide][docs]), collapsed references ([docs][]), and shortcut references ([docs]) work. Definitions can appear before the first slide, after document front matter, or in a later slide body. They do not produce visible content. Labels follow CommonMark normalization, and the first definition wins.

[docs]: https://example.com "Read the documentation"

# [Documentation][docs]

Read the [guide][docs].

# Next steps

Revisit [docs] before starting.

Definitions inside fenced or indented code, HTML comments, and YAML metadata are not collected. Unresolved references remain literal Markdown text. Ordinary visible content before the first slide remains invalid.

Optional link titles become PowerPoint ScreenTips on text links, including nested formatting and slide titles. For a linked standalone image, the image title supplies picture metadata and the outer link title supplies the ScreenTip:

[![Quarterly chart](chart.png "Revenue chart")](https://example.com "Open the full report")

Use --examples references for a complete document.

Content inside lists

Continuation paragraphs, code blocks, and body headings retain the containing list item's text indentation. Lists inside quotes retain their relative nesting and still count toward the three-level limit. HTML comments inside lists are ignored. Images inside list items produce an explicit error. Use a standalone image content area instead.

Ordered lists preserve their starting number, including zero. PowerPoint native numbering is used for values from 1 through 32767. Outside that range, numbers are editable text prefixes and do not automatically renumber after edits in PowerPoint. Subsequent numbers follow the first marker, as in CommonMark. Template paragraph spacing is preserved.

Theme syntax colors

Fenced code keeps its existing Pygments colors by default. Set code_highlighting in document front matter or override it on a slide:

code_highlighting: theme-dark
background: "#FFFFFF"
Value Behavior
default Existing Pygments palette. No background analysis
theme-dark Dark code colors for a light background
theme-light Light code colors for a dark background

A slide inherits the document setting. Explicit default restores the original palette on that slide. These modes apply to code blocks, including plain blocks with no recognized language. Inline code keeps its ordinary text formatting. Theme modes override body_color within code blocks.

Code role Theme slot
Ordinary names, punctuation, operators Dark 1 for theme-dark, Light 1 for theme-light
Comments Same base color, italic
Keywords and HTML tags Accent 1, bold
Strings, numbers, constants Accent 2
Functions, types, classes, built-ins, HTML attributes Accent 3

The three accent roles stay fixed across languages and slides. Dark 1 and Light 1 provide the theme's primary text colors without consuming an accent. Each color receives the smallest native brightness adjustment needed to reach a 4.5:1 contrast ratio, using the WCAG relative luminance formula. Colors that already meet the target remain unchanged. Comments meet the same target as other tokens.

The output uses editable PowerPoint theme references. Changing the theme in PowerPoint changes these colors too, but does not rerun contrast analysis. Regenerate the deck after a theme change to recalculate the adjustments.

Analysis runs once per content placeholder that contains code. Two Content areas are analyzed separately. Solid backgrounds use their resolved color. Image backgrounds use the visible source region behind the placeholder, including cover cropping, with at most 256 pixels on the longest side. A luminance histogram discards 1% at each tail and uses the remaining range. Decoded images are cached for the render. Supported gradients use a 16 by 16 grid across the placeholder.

Image and gradient results are estimates. They do not guarantee contrast at every glyph. Template graphics layered over backgrounds, complex placeholder fills, and unsupported background effects are not fully rendered. When background inspection fails, the opposite theme text color is used as an explicit assumption and a warning is reported. A high-contrast background may make the target impossible. The renderer retains the requested light or dark variant, uses its maximum contrast, and reports the failure. It does not add a panel or switch variants.

Plain CLI output sends warnings to stderr. JSON render output includes a code_highlighting array with slide and placeholder identifiers, analysis method, sample count, estimated minimum contrast, warnings, and target_met. That value is null when the background had to be assumed. The default palette produces no analysis entries.

The color-ignore flags remove the existing document or slide color overrides. They retain code_highlighting, which then uses the remaining template colors and backgrounds.

Use markdown-pptx --examples theme-code for a complete authoring example.

Run uv run python scripts/benchmark_code_colors.py to compare the image range analysis with an average-only baseline. Both use the same crop and sample size. On the development machine, the 1080p and 4K cases took about 6 milliseconds per area, about 1.2 to 1.5 times the baseline. Image decoding is measured separately and cached during rendering. These are local measurements, not performance guarantees.

Two content areas

Select Two Content explicitly and put exactly one top-level thematic break between the left and right content:

# Compare options
---
layout: Two Content
---

## First option

- Small scope
- Quick feedback

***

## Second option

- Broader scope
- More preparation

Each side follows the same content rules as Title and Content. Text beside an image or table is supported. Mixing text and an image or table within one side is rejected. Either side can be empty, but the separator is still required.

Prefer *** surrounded by blank lines. CommonMark --- and ___ thematic breaks also work. A --- directly below paragraph text is a Setext H2 underline. YAML front matter remains valid only immediately after the slide heading. Breaks inside code fences remain literal code. Nested breaks and more than one break are rejected.

The selected template layout must contain exactly two body/content placeholders with non-overlapping horizontal bounds. Content follows their position from left to right, regardless of placeholder index. No divider line or extra text boxes are created. Layouts with three or more content areas are unsupported.

Discover authoring examples

The CLI includes complete Markdown documents covering every supported metadata key and Markdown feature:

uvx markdown-pptx --examples
uvx markdown-pptx --examples list
uvx markdown-pptx --examples two-content
uvx markdown-pptx --examples tables --json

--examples prints the full annotated catalog. --examples list lists topic names and descriptions. --examples NAME prints only the selected document's raw Markdown, suitable for saving as a .md file. --json returns structured entries with descriptions, asset requirements, and Markdown source. The list form omits the source to keep discovery compact. Each example is a separate document. Image examples require the assets described in their requirements.

Use --help to discover commands, --syntax to inspect the format contract, and --examples to learn authoring. Use --list-layouts --template theme.pptx --json to check a template's actual layout compatibility. These commands work without installing a skill.

Automation and image export

Structured results and overwrite safety

Use --json for agent and automation workflows:

uvx markdown-pptx deck.md deck.pptx --json

Successful JSON includes the output path, slide count, and template master details. Failures include a stable error code and relevant input, line, slide, or partial-output context.

The CLI refuses to overwrite an existing presentation or colliding generated image. Add --force only when replacing generated output is intended:

uvx markdown-pptx deck.md deck.pptx --force --json

Export slide images on Windows

On Windows, the CLI can use an installed desktop copy of Microsoft PowerPoint to export PNG or JPEG previews after generating the editable presentation:

uvx markdown-pptx deck.md deck.pptx --export-images png --slides 1,3-5 --image-width 1600 --json

Image export requires Windows, an interactive desktop session, and an installed, licensed, initialized PowerPoint application. The default output directory is <pptx-name>-images. PNG is recommended for text and diagrams.

The editable .pptx is retained if image export fails. With --json, the partial output path is reported in error.details.pptx_output.

Reference

Useful discovery and metadata commands:

uvx markdown-pptx --help
uvx markdown-pptx --syntax
uvx markdown-pptx --list-color-schemes
uvx markdown-pptx --list-masters --template theme.pptx
uvx markdown-pptx --list-layouts --template theme.pptx --master 2
uvx markdown-pptx --about
uvx markdown-pptx --version

Exit codes:

Code Meaning
0 Success
2 Usage or input error
3 Markdown or front-matter parse error
4 Template or layout error
5 Image or other asset error
6 Unsupported Markdown content
7 PowerPoint rendering error
8 Unexpected internal error

Examples

Regenerate the showcase from the repository checkout:

uvx --refresh --from . markdown-pptx sample/showcase.md sample/showcase.pptx --template sample/showcase-template.pptx --force

Development

Install the development environment and run the checks:

uv sync --locked --all-groups
uv run pytest
uv run ruff check .
uv run ruff format --check .

The real PowerPoint export smoke test is optional and requires desktop PowerPoint:

$env:MARKDOWN_PPTX_TEST_POWERPOINT="1"
uv run pytest tests/test_powerpoint_integration.py

Build and validate distributable packages:

uv build
uv run twine check dist/*

CI runs tests/wheel_smoke.py with an isolated installed wheel. It checks version discovery, generated skill metadata, automatic synchronization, and inspection output. Run uv run python tests/wheel_smoke.py --expect-local to check development-build exclusion and explicit installation. Both the smoke checks and pytest use temporary skill directories.

Release files for markdown-pptx 1.6.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for markdown-pptx 1.6.0
File Size Uploaded
markdown_pptx-1.6.0.tar.gz 424.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for markdown-pptx 1.6.0
File Interpreter ABI Platform
markdown_pptx-1.6.0-py3-none-any.whl Python 3 none any Details

Total release size: 538.2 kB

Release files / markdown_pptx-1.6.0.tar.gz

Download URL markdown_pptx-1.6.0.tar.gz
Size 424.0 kB
Tags Source
SHA-256 checksum
How to use checksums
b9e68019f6e6abd92a1cfb5c6dfada1340581830231922e0b897015ba3a74997
BLAKE2b-256 checksum
How to use checksums
88f7885312af293564884d3bd7a8279c3f05a2f1139862b1c6d5a1f6fd0ae1f5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 26, 2026.

Transparency log

Release files / markdown_pptx-1.6.0-py3-none-any.whl

Download URL markdown_pptx-1.6.0-py3-none-any.whl
Size 114.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
439741de98dc8209d6e81793d10b907ad989eccbf0cf5b2bfc5014b25a8826aa
BLAKE2b-256 checksum
How to use checksums
cc7656c214f67fa2ac610e0b1b6cb082a37c47b8c18e6b7c3de544fd6802ba53
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 26, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.6.0 This release

2 release files

1.5.0

2 release files

1.4.0

2 release files

1.3.0

2 release files

1.2.1

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.2

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page