PPTX to Handout Site
Convert PowerPoint presentations into interactive React handout websites.
Usage
/pptx-to-handout <path-to-pptx-or-sourcematerials-folder>
Core Principles
- •Analyze first, ask second - Understand the content before asking questions
- •Show what you found - Summarize detected info, then ask for corrections/additions
- •Require local preview - User must see the site locally before deployment
- •Never auto-deploy - Deployment requires explicit user approval after preview
Workflow
Step 1: Determine Input Type
Check what the user provided:
- •PPTX file → Go to Step 2 (extraction)
- •Folder with
presentation.json→ Skip to Step 3 (already extracted) - •Nothing specified → Check if
sourcematerials/presentation.jsonexists in current directory
If no valid input found, ask the user to provide a PPTX file path or a folder containing extracted content.
Step 2: Extract PPTX Content
If input is a PPTX file:
pip install python-pptx # if not already installed python scripts/extract-pptx.py <input.pptx> sourcematerials/
After extraction, summarize what was extracted:
- •Number of slides
- •Number of images/videos found
- •Any extraction warnings
Limitations to mention: SmartArt exported as images, animations ignored, some formatting simplified.
Step 3: Analyze Presentation Content
Read sourcematerials/presentation.json and analyze the content. Extract:
- •
Detected metadata:
- •Presentation title (from first slide or metadata)
- •Speaker name (if found in slides)
- •Any dates, event names, or affiliations mentioned
- •
Content summary:
- •Total slide count and section breakdown
- •Key topics/themes identified
- •Notable people, organizations, tools mentioned
- •Quotes found (with attributions)
- •
Media inventory:
- •Count of images by type (photos, screenshots, diagrams, etc.)
- •Videos found and their sizes
Present this summary to the user before proceeding.
Step 4: Ask Clarifying Questions
Based on your analysis, use AskUserQuestion to gather missing or uncertain information:
Always ask about:
- •Project name - URL-friendly identifier for deployment (suggest one based on title)
- •Deployment target - Cloudflare Pages (25MB file limit) or Vercel
Ask only if not detected or uncertain:
- •Presentation title (if unclear from slides)
- •Speaker name and profile URL
- •Speaker bio (brief paragraph)
- •Event details (name, date, location) if this is for a conference
- •Any corrections to detected information
DO NOT ask about things you can confidently infer from the presentation.
Step 5: Generate entities.json
Create src/data/entities.json with extracted entities from your Step 3 analysis.
See references/entities-format.md for the full schema.
Entity types to extract:
- •people - Names mentioned with their roles and slideIndex
- •quotes - Attributed statements with:
- •
attribution- Who said it and source - •
topic- Category tag (ai_technology, learning, ai_ethics, etc.) - •
extractedFromImage- true if quote was in an image
- •
- •organizations - Companies, institutions with descriptions
- •tools - Software, AI tools with:
- •
description- What the tool does - •
url- Link to the tool (if available) - •
category- chatbot, research, development, productivity
- •
- •terms - Technical terms with definitions
- •dates - Significant dates with events and slideIndex
- •links - URLs with:
- •
title- Human-readable link title - •
description- What the link contains - •
linkType- tool, demo, article, documentation, research, personal, website
- •
CRITICAL - URL/Link Extraction (AI-Only, Semantic Approach):
Links are NOT extracted mechanically via regex. The AI must:
- •Read and understand each slide's content contextually
- •Identify meaningful URLs - not just strings that look like URLs
- •Reconstruct fragmented URLs - presentations often split URLs across lines
- •Provide semantic descriptions - explain what the link leads to
- •Classify by type - tool, demo, article, documentation, research, personal, website
- •Validate purpose - only include links relevant to the presentation topic
DO NOT rely on pattern matching. READ the slides, understand the context, and extract links that would be useful to the audience.
If uncertain about a URL, ask the user to confirm.
Step 5b: AI Image Categorization (Optional)
If the presentation has images, ask the user if they want to run AI-powered image analysis to generate descriptions and categories.
First, detect available backends:
python scripts/analyze-existing-images.py --list --json
This returns available backends and models:
- •lmstudio - Local LM Studio server (localhost:1234) with vision models
- •ollama - Local Ollama server (localhost:11434) with vision models (llava, etc.)
- •gemini - Cloud Gemini API (requires GEMINI_API_KEY)
Use AskUserQuestion to ask:
- •
Run image categorization?
- •Yes, with review UI - Launch web interface to review results before saving
- •Yes, batch process all - Process all images automatically
- •Skip for now - Can do later
- •
If yes, which backend? - Show only available backends from --list output
- •
Which model? - Show models available for the selected backend
Option A: Review UI (Recommended)
Launch the review server for interactive image analysis:
python scripts/image-review-server.py .
This opens a web UI at http://localhost:8765 where the user can:
- •Select which images to analyze
- •Choose backend and model from dropdowns
- •Review and edit AI-generated descriptions before saving
- •Approve results individually or in batch
Tell the user:
The image review UI is running at http://localhost:8765
In the UI you can:
- •Select a backend and model from the dropdowns
- •Check the images you want to analyze
- •Click "Analyze Selected" to process them
- •Review and edit the results
- •Click "Approve" on each result (or "Approve All")
- •Click "Save & Exit" when done
Press Ctrl+C in the terminal when finished.
Option B: Batch Processing
For automatic processing without review:
# With auto-detection (uses LM Studio > Ollama > Gemini priority) python scripts/analyze-existing-images.py . # Or with specific backend/model python scripts/analyze-existing-images.py . --backend lmstudio --model "qwen/qwen3-vl-4b" python scripts/analyze-existing-images.py . --backend ollama --model "llava:13b" python scripts/analyze-existing-images.py . --backend gemini
Recommended LM Studio models:
- •
qwen/qwen3-vl-4b- Fast, good quality for most images (recommended) - •
llava-v1.6-mistral- Alternative if Qwen unavailable
The script updates src/data/presentation.json with image descriptions, categories, and extracted quotes.
If user skips: Let them know they can run it later with:
python scripts/image-review-server.py . # Interactive review UI python scripts/analyze-existing-images.py . # Batch processing
Step 6: Generate sessionInfo.ts
Create src/data/sessionInfo.ts using information from Step 3 analysis and Step 4 user answers.
Key fields to populate for a good homepage:
- •
Required fields:
- •
title- Presentation title - •
subtitle- Brief tagline or event context - •
speaker.name,speaker.affiliation,speaker.email
- •
- •
Abstract (highly recommended):
- •Write a compelling 2-4 paragraph abstract based on the presentation content
- •Use
\n\nfor paragraph breaks - •This is displayed prominently on the homepage (NOT collapsed)
- •
Key Topics (recommended):
- •Extract 4-8 key topics from the presentation
- •Write as actionable bullet points
- •Displayed as a bullet list on the homepage
- •
Featured Links (optional but valuable):
- •Include 2-4 key tools or resources mentioned prominently in the presentation
- •Give each a descriptive name and brief description
- •These appear as clickable cards on the homepage
- •
Talk Page Link (optional):
- •If there's a booking page, event page, or talk recording, add to
talkPageUrl - •Set
talkPageLabelto something like "Book this workshop" or "Watch Recording"
- •If there's a booking page, event page, or talk recording, add to
See references/customization.md for the full format.
Fill in all fields you have data for. Leave optional fields empty ("" or []) if not applicable.
Step 7: Build and Local Preview
npm run build # Process media + compile + bundle npm run dev # Start dev server
Tell the user:
The site is running at http://localhost:5173
Please check:
- •Home page shows correct title, speaker info, and abstract
- •Slides page renders all slides with images/videos
- •Press
vto cycle between content/screenshot/outline views- •Press
dto open grid view of all slides- •Navigation works (arrows, keyboard)
- •Resources page shows extracted entities
- •Media Gallery displays images correctly
STOP and wait for user feedback. Do not proceed until user responds.
Step 8: Iterate Based on Feedback
If user reports issues or wants changes:
- •Make the requested fixes
- •Rebuild if necessary (
npm run build) - •Ask user to check again
- •Repeat until user confirms it looks good
Common fixes:
- •Adjusting sessionInfo.ts content
- •Adding/removing entities
- •Fixing image descriptions or categories
Step 9: Deploy (Only on Explicit Approval)
DO NOT deploy unless the user explicitly says to deploy (e.g., "deploy it", "looks good, deploy", "ship it").
When user approves deployment:
Vercel:
vercel --prod --yes
Cloudflare Pages:
npm run build # Ensure latest build npx wrangler pages deploy dist --project-name=<project-name>
After deployment, provide the live URL to the user.
Setting Up a New Project
If starting fresh (no existing handout project):
git clone https://github.com/techczech/PPT2HandoutSkill my-handout cd my-handout npm install
Then proceed with Step 1.
Requirements
- •Node.js 18+
- •Python 3.8+ with python-pptx (
pip install python-pptx) - •ffmpeg (optional, for video compression on Cloudflare)
References
- •Entities Format - JSON schema and image categories
- •Customization - Colors, fonts, sessionInfo, file structure
- •Troubleshooting - Common issues and fixes