agentsclimarketplace

Html to pptx skill

Skill Alienxcript/html-export-skills/html-to-pptx skill

Convert a single-file HTML slide deck into a pixel-perfect PPTX by rendering it in headless Chrome, taking a full-page screenshot, slicing it into per-slide images with Pillow, and packing them into a PowerPoint file. Use when the user has an HTML presentation and wants a .pptx export.From its SKILL.md

Install
npx -y skills add Alienxcript/html-export-skills --skill html-to-pptx skill

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

5.1 KB, ~1.4k tokens by cl100k_base, as published. Nobody here has run it

HTML to PPTX Skill

Convert any single-file HTML slide deck into a .pptx file that looks exactly like the browser render — fonts, glows, gradients, animations frozen at their initial state.

How It Works

  1. Headless Chrome (via Puppeteer) renders the HTML at 1920×1080 and takes a single fullPage: true screenshot → one tall PNG
  2. Pillow slices that PNG into N equal strips (one per slide)
  3. python-pptx packs each strip as a full-bleed image on its own PPTX slide

This avoids all scroll/clip coordinate bugs — each slide is a guaranteed unique pixel crop.


Requirements Check

Before running, verify these are available:

  • node + puppeteer npm package (installed locally or globally)
  • python with pillow and python-pptx packages
  • Chrome or Edge executable on the system

Step-by-Step Instructions

1. Ask the user for inputs

You need:

  • HTML file path — the source presentation
  • Number of slides — how many slides the deck has
  • Output PPTX filename — where to save (default: same folder as HTML, same name with .pptx)
  • Slide aspect ratio — default 16:9 (1920×1080). Ask only if non-standard.
  • Chrome path — auto-detect from common locations, only ask if not found

Auto-detect Chrome from these paths (check in order):

  • C:/Program Files/Google/Chrome/Application/chrome.exe
  • C:/Program Files (x86)/Google/Chrome/Application/chrome.exe
  • C:/Program Files (x86)/Microsoft/Edge/Application/msedge.exe
  • /usr/bin/google-chrome
  • /usr/bin/chromium-browser

2. Install puppeteer if needed

# Check
node -e "require('puppeteer')" 2>&1

# Install locally in the HTML file's directory if missing
npm install puppeteer --save-dev

3. Write the screenshot script

Write _screenshot.mjs to the same folder as the HTML:

import puppeteer from 'puppeteer';
import path from 'path';
import { fileURLToPath } from 'url';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const HTML_PATH = path.join(__dirname, '<HTML_FILENAME>');
const W = 1920;
const H = 1080;

const browser = await puppeteer.launch({
  executablePath: '<CHROME_PATH>',
  headless: true,
  args: ['--no-sandbox', `--window-size=${W},${H}`],
});

const page = await browser.newPage();
await page.setViewport({ width: W, height: H, deviceScaleFactor: 1 });
await page.goto(`file:///${HTML_PATH.replace(/\\/g, '/')}`, {
  waitUntil: 'networkidle0',
  timeout: 30000,
});

// Wait for fonts and transitions to settle
await new Promise(r => setTimeout(r, 2500));

// Freeze animations, hide fixed UI chrome
await page.addStyleTag({ content: `
  * { animation: none !important; transition: none !important; }
  body::after { display: none !important; }
  #nav, #progress, nav, header[data-fixed] { display: none !important; }
` });

await page.screenshot({
  path: path.join(__dirname, '_fullpage.png'),
  fullPage: true,
});

console.log('Done.');
await browser.close();

4. Write the slice + pack script

Write _pack_pptx.py to the same folder:

from PIL import Image
from pptx import Presentation
from pptx.util import Inches
import os

FOLDER   = r'<FOLDER_PATH>'
FULLPAGE = os.path.join(FOLDER, '_fullpage.png')
OUT      = os.path.join(FOLDER, '<OUTPUT_FILENAME>')
SLIDES   = <SLIDE_COUNT>

img = Image.open(FULLPAGE)
W, H = img.size
slide_h = H // SLIDES

print(f"Full image: {W}x{H}, {SLIDES} slides, {slide_h}px each")

prs = Presentation()
prs.slide_width  = Inches(20)      # 1920px at 96dpi
prs.slide_height = Inches(11.25)   # 1080px at 96dpi
blank = prs.slide_layouts[6]

for i in range(SLIDES):
    top  = i * slide_h
    crop = img.crop((0, top, W, top + slide_h))
    tmp  = os.path.join(FOLDER, f'_slide_{i+1:02d}.png')
    crop.save(tmp)
    slide = prs.slides.add_slide(blank)
    slide.shapes.add_picture(tmp, left=0, top=0,
                             width=prs.slide_width,
                             height=prs.slide_height)
    print(f"  Slide {i+1:02d} rows {top}-{top+slide_h}")

prs.save(OUT)
print(f"Saved: {OUT}")

5. Run both scripts

node _screenshot.mjs
python _pack_pptx.py

6. Clean up temp files

After confirming the PPTX looks correct, delete:

  • _fullpage.png
  • _screenshot.mjs
  • _pack_pptx.py
  • _slide_01.png_slide_NN.png

Common Issues

ProblemCauseFix
All slides identicalUsing clip:{y:0} on scrolled viewportAlways use fullPage:true + slice — never scroll
PermissionError on savePPTX open in PowerPointClose the file first, or save to a new filename
Fonts wrong in PPTXCustom web fonts not installed locallyThis approach embeds pixel images so fonts are always correct
Slide count wrongH // SLIDES roundingCheck H % SLIDES == 0; if not, slides have min-height inconsistency in HTML
Chrome not foundWrong exe pathCheck Edge as fallback

What ships with it: 1 file

3.9 KB alongside SKILL.md

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.