Install
openclaw skills install awesome-deck-pdf-checkConvert PPTX, image, URL, or style keywords into a polished, pixel-perfect HTML slide deck with user-approved design and content, then export as high-quality...
openclaw skills install awesome-deck-pdf-checkBefore writing a single line of code or HTML, you MUST complete these two confirmation steps in order. Do not proceed until you receive explicit user approval for each.
Analyze the user's input (image / URL / keyword / .pptx), then show a design spec summary and ask:
Here's the design style I extracted from [source]:
- Background:
#000dark / Accent:#2997FFblue- Font: SF Pro Display, oversized heading, minimal whitespace
- Style: dark Keynote, glow effects
Does this match what you want? Any changes before I start?
If the user provided a website URL and fetching fails (Fake IP, login wall, etc.):
Wait for explicit approval → then move to Confirmation 2.
Ask the user if they have existing materials:
Do you have reference materials for the content? (existing PPT, doc, data, bullet points — anything works) If yes, send them over. If not, I'll draft an outline for you to review.
Once you receive a reply, prepare a numbered list: slide title + one-line summary per slide. Show it and ask:
Here's the planned structure — does this look right? Anything to add, remove, or change?
Wait for explicit approval → only then begin generating HTML.
If either confirmation is skipped, the workflow is broken. Start over from Confirmation 1.
export_pdf.js auto-detects Chrome in this order:
npm install puppeteer)/Applications/Google Chrome.app, Linux: /usr/bin/chromium)If npm install puppeteer fails (sandbox/network restriction):
# Option A: skip Chromium download, install separately
npm install puppeteer --ignore-scripts
npx puppeteer browsers install chrome
# Option B: use puppeteer-core (no bundled Chrome download)
npm install puppeteer-core
# script will auto-find system Chrome
# Option C: install system Chrome first, then run script
# macOS: brew install --cask google-chrome
# Linux: sudo apt install chromium-browser
npm install puppeteer-core
Do NOT fall back to wkhtmltopdf, pdfkit, weasyprint, or any other tool.
For full installation instructions across OpenClaw, Claude Code, Codex, and Linux/macOS setup, see references/install.md.
User input (image / website URL / style keyword / .pptx file)
↓ Step 1: Extract design spec → ⚠️ Confirm with user
↓ Step 2: Outline slide content → ⚠️ Confirm with user
↓ Step 3: Generate HTML → 💾 Save slides.html to disk
↓ Step 4: Run export_pdf.js → 💾 Output slides.pdf
Both slides.html and slides.pdf must exist as final outputs.
After analyzing the input, show the extracted design spec summary and ask for confirmation:
Here's what I extracted from [source]:
- Background:
#000000black · Accent:#2997FFapple blue- Font: SF Pro Display, oversized centered headline
- Style: dark Keynote, glow effects
Does this match the style you want? Any adjustments?
⚠️ If website fetch fails (e.g. Fake IP / login required):
Website analysis priority:
web_fetch page content → CSS/font extractionFirst ask if the user has existing materials:
Do you have any reference materials for the content? e.g. existing PPT, doc, report, or a list of key points? Send them over and I'll structure the slides — otherwise I'll draft an outline for you to review.
After receiving a reply, prepare a one-line summary per slide and confirm before generating HTML.
Supported inputs:
| Input | Approach |
|---|---|
| 📂 .pptx template | Parse with python-pptx: extract colors, fonts, backgrounds, placeholder layouts (most accurate) |
| 📎 Image / screenshot | Visual analysis: colors, font style, spacing, component patterns |
| 🌐 Website URL | Puppeteer screenshot + getComputedStyle font/color extraction |
| 💬 Style keyword | Use brand knowledge: Apple → SF Pro, Notion → Inter, Linear → Inter, Google → Google Sans |
Extracting from .pptx:
from pptx import Presentation
prs = Presentation("template.pptx")
slide = prs.slides[0]
for shape in slide.shapes:
if shape.has_text_frame:
for para in shape.text_frame.paragraphs:
for run in para.runs:
print(run.font.name, run.font.size, run.font.color.rgb, run.font.bold)
Fill extracted values into DESIGN.md (see references/DESIGN_TEMPLATE.md):
Font extraction by input type:
| Input | Method |
|---|---|
.pptx | run.font.name per text run |
| Website | getComputedStyle(el).fontFamily via Puppeteer |
| Image / screenshot | Visual analysis — describe closest match (e.g. "geometric sans, similar to Helvetica") |
| Style keyword | Brand knowledge mapping |
Fonts go into DESIGN.md as CSS variables. Append Chinese fallbacks at the end (never hardcode them as primary):
--font-heading: 'SF Pro Display', 'PingFang SC', 'Helvetica Neue', sans-serif;
--font-body: 'SF Pro Text', 'PingFang SC', 'Helvetica Neue', sans-serif;
⚠️ Save the HTML to a
.htmlfile first. Do not merge HTML generation and PDF export into one step. The HTML file is a required intermediate artifact — it must exist on disk before runningexport_pdf.js.
Generate a single .html file and write it to disk (e.g. slides.html):
<section class="...">, fixed width 1440px, height fits content@media print: page-break-after: always on every sectionFont consistency check after saving:
grep -n "font-family" slides.html
Only proceed to Step 3 once the .html file is saved and verified.
⚠️ Only use
export_pdf.js(Puppeteer screenshot-and-compose). Do NOT use any of these alternatives — they all produce broken output:
page.pdf()directly → A4 portrait, white space below every slidewkhtmltopdf→ outdated WebKit engine, broken flexbox/grid/modern CSS- Any other HTML-to-PDF CLI (Prince, WeasyPrint, pdfkit, etc.) → layout incorrect
The screenshot-and-compose approach is the only method that faithfully preserves the rendered layout.
Claude Code / Codex / OpenClaw / local agent (can run shell commands):
scripts/export_pdf.js, copy it to the project directory, run it:node export_pdf.js # reads slides.html → slides.pdf (auto-detects <section> elements)
node export_pdf.js my-deck.html # specify a different file
Claude.ai chat / any chat-only interface (cannot run shell commands):
slides.html. To export the PDF, copy scripts/export_pdf.js from the skill folder to the same directory and run node export_pdf.js."node export_pdf.js # reads slides.html → slides.pdf (auto-detects all <section> elements)
node export_pdf.js my-deck.html # specify a different HTML file
Auto-detection: The script automatically finds all <section> elements in DOM order — no need to manually set SELECTORS. Only configure SELECTORS manually if you need a custom slide order or to merge multiple elements into one slide:
// Optional manual override — leave as [] for auto-detect
const SELECTORS = [
'.cover',
'.section-2',
['.chart', '.stats'], // array = merge into one slide
];
See references/export_pdf_guide.md for details.
| Issue | Fix |
|---|---|
| PDF has white space / broken layout | Do not use page.pdf(), wkhtmltopdf, or any CLI PDF tool. Run export_pdf.js only — it uses Puppeteer screenshot-and-compose to preserve layout exactly |
| Chinese text renders as Song/Ming | Add 'PingFang SC' to font stack (available on macOS by default) |
| Inconsistent fonts across slides | Run grep -n "font-family" slides.html and normalize |
| Wrong page count in PDF | Check that SELECTORS covers all sections |
| Detached Frame error | Use the reusable overlayPage pattern — never use newPage()/close() in a loop |
| Website URL fails to fetch | Likely Fake IP proxy — use Puppeteer screenshot instead, or ask user for screenshots |