Skip to main content

Convert HTML slide decks to editable PowerPoint files using browser-based DOM measurement.

Project description

html-to-pptx

Convert HTML slide decks into editable PowerPoint files.

Unlike screenshot-based approaches that produce flat images, html-to-pptx measures every DOM element in a headless browser and maps it to a native PPTX shape — text boxes you can edit, images you can resize, backgrounds you can restyle. The output is a real presentation, not a picture of one.

Install

pip install html-to-pptx
python -m playwright install chromium

Quick start

CLI

html-to-pptx deck.html deck.pptx

Python

import asyncio
from html_to_pptx import convert

asyncio.run(convert("deck.html", "deck.pptx"))

Two-stage API

For more control, separate the measurement and rendering steps:

import asyncio
from html_to_pptx import extract_measurements, render_pptx

async def main():
    # Stage 1: measure DOM elements in a headless browser
    measurements = await extract_measurements("deck.html")

    # Stage 2: render measurements to python-pptx shapes
    prs = render_pptx(measurements)

    # Modify the presentation before saving
    prs.slides[0].shapes[0].text = "Custom title"
    prs.save("deck.pptx")

asyncio.run(main())

HTML format

Your HTML file should contain <section class="slide"> elements at a 1920×1080 canvas:

<!DOCTYPE html>
<html>
<head>
<style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body { background: #000; overflow: hidden; }
    .slide {
        width: 1920px;
        height: 1080px;
        display: none;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        font-family: sans-serif;
    }
    .slide.active { display: flex; }
</style>
</head>
<body>

<section class="slide active" style="background-color: #1e293b;">
    <h1 style="font-size: 64px; color: #f8fafc;">Hello World</h1>
</section>

<section class="slide" style="background-color: #ffffff;">
    <p style="font-size: 24px; color: #334155;">Second slide</p>
</section>

</body>
</html>

See examples/demo.html for a full five-slide deck.

What gets converted

HTML feature PPTX output
Text with fonts, colors, weight, style Editable text boxes with matching font properties
Mixed inline content (<p>text <strong>bold</strong> more</p>) Multi-run paragraphs with per-run styling
CSS linear-gradient backgrounds OOXML gradient fills with angle and stop positions
Gradient text (-webkit-background-clip: text) Gradient text fill (or solid fallback)
Inline <svg> elements Rasterized to PNG via Playwright screenshot
Background colors Solid fills (with alpha transparency)
Rounded corners (border-radius, including %) OOXML adjustment guides on rounded rectangles
Rounded images (border-radius on <img>) Rounded-rect geometry swap on picture shapes
Base64-embedded images (data:image/...) Native picture shapes
Borders (with alpha) Shape outlines with color, width, and opacity
Left-border accent bars Separate narrow rectangle shapes
text-transform (uppercase, etc.) Transformed text content
Hyperlinks Preserved on text runs
Ordered/unordered lists Bullet/number prefixes with marker colors
CSS ::before/::after pseudo-elements Synthetic shapes for decorative accents
RTL text direction Correct paragraph alignment
<br> tags in inline runs Multi-paragraph text frames
Element opacity OOXML alpha on fill colors

How it works

HTML file
    │
    ▼
┌─────────────────────────┐
│  Headless Chromium       │  ← Playwright loads the HTML at 1920×1080
│  (Playwright)            │
│                          │
│  For each .slide:        │
│  • Show slide in isolation│
│  • Clear CSS transforms  │
│  • Measure every visible │
│    element recursively:  │
│    position, size, color,│
│    font, text, images    │
└───────────┬─────────────┘
            │
            ▼
    Measurement tree (JSON)
            │
            ▼
┌─────────────────────────┐
│  python-pptx renderer    │
│                          │
│  For each element:       │
│  • Text leaf → text box  │
│  • Image → picture shape │
│  • Background → rectangle│
│  • Border → outline/shape│
│                          │
│  Coordinates:            │
│  CSS px → inches using   │
│  13.333/1920 ratio       │
└───────────┬─────────────┘
            │
            ▼
      Editable .pptx

Visual comparison tool

Verify conversion quality with side-by-side comparisons:

pip install html-to-pptx[compare]
html-to-pptx-compare deck.html -o results/

This screenshots the original HTML, converts to PPTX, renders the PPTX back to images via LibreOffice, and creates side-by-side comparison PNGs. Requires LibreOffice on PATH.

Output structure:

results/deck/
├── html_slide_0.png      # ground truth (HTML screenshot)
├── html_slide_1.png
├── pptx_slide_0.png      # converter output (PPTX rendered via LibreOffice)
├── pptx_slide_1.png
├── compare_slide_0.png   # side-by-side comparison
├── compare_slide_1.png
└── output.pptx           # the generated file

Limitations

  • External images are not fetched — use base64 data: URIs for embedded images
  • CSS background-image: url(...) on containers is not converted — only <img> tags with base64 src and inline <svg> elements become picture shapes
  • Radial gradients are not supported — only linear-gradient
  • Animations and transitions are not represented in PPTX
  • Font availability — the PPTX references font names from the HTML; if those fonts aren't installed on the machine opening the file, PowerPoint will substitute
  • Complex CSS layouts (grid, advanced flexbox) are measured as-rendered, but deeply nested layouts may lose some positioning precision

Development

git clone https://github.com/Design-Arena/html-to-pptx.git
cd html-to-pptx
pip install -e ".[dev]"
python -m playwright install chromium
pytest -v

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

html_to_pptx-0.2.1.tar.gz (26.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

html_to_pptx-0.2.1-py3-none-any.whl (22.9 kB view details)

Uploaded Python 3

File details

Details for the file html_to_pptx-0.2.1.tar.gz.

File metadata

  • Download URL: html_to_pptx-0.2.1.tar.gz
  • Upload date:
  • Size: 26.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for html_to_pptx-0.2.1.tar.gz
Algorithm Hash digest
SHA256 8093aeed7f4bf6e592e5ba1af2767fb5ada472a57428d5cbadab9059e1655cc9
MD5 27cd6760544579674500954e95ed8ae2
BLAKE2b-256 ff1c6cd0f7aaea33ce5500a798a89608435280f2828cdf0124e9099bcf218e1e

See more details on using hashes here.

Provenance

The following attestation bundles were made for html_to_pptx-0.2.1.tar.gz:

Publisher: publish.yml on Design-Arena/html-to-pptx

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file html_to_pptx-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: html_to_pptx-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 22.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for html_to_pptx-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 b2cb44b40f94b9235f3b18053a8bdc3d83292555832db6b0957ffe28ef188df0
MD5 f74a7c2c14dd716b713ab886c5ebbc8d
BLAKE2b-256 51e3763dcaf78b4c367baf0d36882df4b88ab4e120e1e3aba65d3828c40a8c9e

See more details on using hashes here.

Provenance

The following attestation bundles were made for html_to_pptx-0.2.1-py3-none-any.whl:

Publisher: publish.yml on Design-Arena/html-to-pptx

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page