Convert PPTX/PPT presentations to clean, RAG-ready Markdown (text, tables, charts, SmartArt, formulas, images)
Project description
pptx2markdown
English | 한국어
pptx2markdown converts PowerPoint presentations into deterministic Markdown or
JSON for search, RAG, and document-processing pipelines. It parses native OOXML
structure and shape geometry directly: no OCR, vision model, API key, or cloud
service is used.
Why pptx2markdown?
- One static pipeline —
.pptxcontent is parsed from XML, relationships, and embedded package parts. - Deterministic reading order — recursive geometric XY-cut orders native shapes without semantic or model-based overrides.
- One output contract — Markdown and JSON are rendered from the same
versioned
PresentationDocument. - Rich native content — text, headings, lists, tables, charts, SmartArt, formulas, images, speaker notes, and embedded attachments are retained.
- Reviewable regressions — real PPTX fixtures are checked against byte-for-byte JSON and Markdown golden outputs on Linux, macOS, and Windows.
Supported content
| Content | Behavior |
|---|---|
| Text and headings | Preserves text and infers headings from native placeholder and style evidence |
| Lists | Preserves ordered and unordered list structure |
| Tables | Renders native PowerPoint tables as Markdown tables |
| Charts | Converts native charts through chart2md |
| SmartArt | Converts diagram content through smartart2md |
| Formulas | Converts OMML equations to LaTeX through omml2latex |
| Images | Copies embedded image parts to deterministic local asset paths |
| Speaker notes | Keeps notes separate from visible slide content |
| Attachments | Preserves recoverable PDF, audio, video, Office, ZIP, 3D, and OLE payloads as linked files |
The parser does not OCR text inside images, transcribe audio or video, reconstruct animations, interpret connector semantics, or reproduce slides pixel-for-pixel. PowerPoint review comments are intentionally excluded.
Requirements
- Python 3.12 or newer
.pptx: no Microsoft Office or LibreOffice required- legacy
.ppt: Microsoft PowerPoint on Windows or LibreOffice - EMF/WMF conversion: LibreOffice when conversion is needed
Installation
Let an AI agent install it
A local coding agent can inspect the environment, choose an isolated install, optionally configure LibreOffice, and verify the CLI. Give it one of these prompts and review every permission request.
Most agents:
Read https://raw.githubusercontent.com/PPTX2Markdown/PPTX2Markdown/main/.github/agent-install.md and install pptx2markdown for this machine. You may run the commands needed for installation after explaining them. Ask me before any administrator, sudo, password, system package-manager, shell-profile, PATH, or LibreOffice change.
Codex interactive planning:
/plan
Read https://raw.githubusercontent.com/PPTX2Markdown/PPTX2Markdown/main/.github/agent-install.md and install pptx2markdown for this machine. You may run the commands needed for installation after explaining them. Ask me before any administrator, sudo, password, system package-manager, shell-profile, PATH, or LibreOffice change.
See the complete agent installation procedure.
Manual installation
For an isolated CLI, use uv:
uv tool install pptx2markdown
Alternatively, use pipx or an active virtual environment:
pipx install pptx2markdown
# or, inside an active virtual environment
python -m pip install pptx2markdown
LibreOffice is optional:
# macOS
brew install --cask libreoffice
# Ubuntu / Debian
sudo apt-get install libreoffice libreoffice-impress
On Windows, .ppt conversion uses PowerPoint COM automation when available and
otherwise tries LibreOffice. SOFFICE_PATH may point to a specific LibreOffice
executable.
Quick start
# One file -> ./output/deck/deck.md
pptx2markdown deck.pptx
# Every .pptx/.ppt in the current directory
pptx2markdown
# Multiple files and a custom output root
pptx2markdown first.pptx second.pptx -o converted/
# Canonical JSON instead of Markdown
pptx2markdown deck.pptx --output-format json
Temporary Office lock files matching ~$*.pptx are silently skipped during
batch conversion.
From Python:
import pptx2markdown
exit_code = pptx2markdown.convert(
"deck.pptx",
output_dir="converted",
output_format="markdown",
)
if exit_code != 0:
raise RuntimeError("conversion failed")
Example Markdown:
[Page_1]
# Quarterly results
- Revenue increased 18%
- Operating margin reached 24%
| Region | Revenue |
| --- | ---: |
| APAC | $12.4M |
CLI options
| Flag | Default | Description |
|---|---|---|
-o, --output-dir |
./output |
Final Markdown/JSON and copied assets |
--work-dir |
./.pptx2markdown |
Extracted packages, analysis files, and caches |
--output-format |
markdown |
markdown or json |
--headings |
auto |
auto or placeholder-only strict heading detection |
--placeholder-inheritance |
style |
none, geometry, or style inheritance |
--inherited-shapes |
visible |
none, visible, or all layout/master shapes |
--ppt-converter |
auto |
auto, powerpoint, or libreoffice for .ppt |
--verbose |
off | Debug logging |
Run pptx2markdown --help for the authoritative CLI reference.
Output layout
output/
├── convert_manifest.json
└── <deck-name>/
├── <deck-name>.md # or <deck-name>.json
├── media/
└── attachments/
.pptx2markdown/
├── target_slides/
├── structure_analysis/
├── table_pipeline/
└── .cache/
convert_manifest.json records file and slide status, warnings, failures, and
block statistics. JSON output conforms to the packaged
PresentationDocument 1.0 schema. Source paths are reduced to a basename and
generated links use portable / separators.
Reading order and determinism
Reading order always uses recursive XY-cut over native shape bounding boxes. It splits geometric regions into columns and rows, then uses top-left order when no further cut is possible. Original XML order is only a deterministic tie-breaker or a fallback for objects without usable geometry.
For identical input and options, JSON and Markdown outputs are expected to be byte-for-byte stable across supported operating systems. The repository keeps 17 reviewable PPTX fixtures with both expected formats and emitted-asset hashes.
Security model
Normal .pptx conversion is local and makes no network or model calls. OOXML
extraction rejects path traversal, links, encrypted entries, relationship
escapes, and packages that exceed configured archive limits. Extracted
attachments are data from the input presentation; inspect them before opening.
Legacy .ppt and some vector-image conversions invoke the selected external
Office converter.
Documentation
Development
python -m pip install -e .
python -m unittest discover -v
python scripts/update_goldens.py --check
ruff check src tests scripts
ruff format --check src tests scripts
When parser behavior changes intentionally, review the generated Markdown and JSON diffs before accepting new golden snapshots.
License
The project is distributed under the Apache License 2.0.
Third-party golden fixture attribution is recorded in
THIRD_PARTY_NOTICES.md.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pptx2markdown-0.1.0.tar.gz.
File metadata
- Download URL: pptx2markdown-0.1.0.tar.gz
- Upload date:
- Size: 86.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a34eb16a43b6c431c91b6a07ef9387e7240d5d6e8c2b484ff1a8835fb643783b
|
|
| MD5 |
d8722315a083b48b5028151fbfb706ee
|
|
| BLAKE2b-256 |
451e7df2de0ba853aec1df0139e9d55102250c0e11d3373ae9b2d6c96c9b4819
|
Provenance
The following attestation bundles were made for pptx2markdown-0.1.0.tar.gz:
Publisher:
publish.yml on PPTX2Markdown/PPTX2Markdown
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pptx2markdown-0.1.0.tar.gz -
Subject digest:
a34eb16a43b6c431c91b6a07ef9387e7240d5d6e8c2b484ff1a8835fb643783b - Sigstore transparency entry: 2161583162
- Sigstore integration time:
-
Permalink:
PPTX2Markdown/PPTX2Markdown@44accbeed71a42b7774b4864886e42fa1c44533b -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/PPTX2Markdown
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@44accbeed71a42b7774b4864886e42fa1c44533b -
Trigger Event:
release
-
Statement type:
File details
Details for the file pptx2markdown-0.1.0-py3-none-any.whl.
File metadata
- Download URL: pptx2markdown-0.1.0-py3-none-any.whl
- Upload date:
- Size: 98.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ffb3e8125258efec3fddf7d65574370e685bcd63f2b964f10a0ca9a6d933f8b8
|
|
| MD5 |
2bc9331256ab128108aa719351c460d5
|
|
| BLAKE2b-256 |
c08b6ffb6482a838bc93ad822c68d3b72b558d46770627ab65cefe160508003a
|
Provenance
The following attestation bundles were made for pptx2markdown-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on PPTX2Markdown/PPTX2Markdown
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pptx2markdown-0.1.0-py3-none-any.whl -
Subject digest:
ffb3e8125258efec3fddf7d65574370e685bcd63f2b964f10a0ca9a6d933f8b8 - Sigstore transparency entry: 2161583355
- Sigstore integration time:
-
Permalink:
PPTX2Markdown/PPTX2Markdown@44accbeed71a42b7774b4864886e42fa1c44533b -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/PPTX2Markdown
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@44accbeed71a42b7774b4864886e42fa1c44533b -
Trigger Event:
release
-
Statement type: