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.0.tar.gz (25.6 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.0-py3-none-any.whl (22.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: html_to_pptx-0.2.0.tar.gz
  • Upload date:
  • Size: 25.6 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.0.tar.gz
Algorithm Hash digest
SHA256 2ae6544a1d31b9333804d9483ded873bfe7a63ec054d871d223c0cec6782c3d9
MD5 5938c5f38bb2a587c55b53777321a7b3
BLAKE2b-256 7986a7160b61230d9cf932a2cda96b37cafbb33e79039b89390fcf0fbd63f77c

See more details on using hashes here.

Provenance

The following attestation bundles were made for html_to_pptx-0.2.0.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.0-py3-none-any.whl.

File metadata

  • Download URL: html_to_pptx-0.2.0-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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 64379a7e1fb901aff6bd014699fcffd3a168eeaab5c400c3af7eeb4cd906d8d0
MD5 aab8cad39c82cf77d181e2a02751c98b
BLAKE2b-256 f31a4651be4d3a83d71b9c63e771cee293af6a357c6c221191ad8ad1b4a4e40c

See more details on using hashes here.

Provenance

The following attestation bundles were made for html_to_pptx-0.2.0-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