pptx · diff
git:20260607.412f6db to git:20260616.904f11f
48 added, 463 removed. Audit A to A.
---
name: pptx
- description: "Presentation creation, editing, and analysis. When Claude needs to work with presentations (.pptx files) for: (1) Creating new presentations, (2) Modifying or editing content, (3) Working with layouts, (4) Adding comments or speaker notes, or any other presentation tasks"
- license: Proprietary. LICENSE.txt has complete terms
- # nativeEngine.triggers feed Code Buddy's keyword skill matcher (scoreSkill);
- # without them realistic requests score below the 0.3 auto-activation threshold.
+ description: "Create and edit PowerPoint presentations (.pptx): title slides, bullet layouts, tables, images, and speaker notes. Use whenever the user asks to build, modify, or populate a presentation/slide deck/PowerPoint."
+ license: MIT (Code Buddy original skill)
nativeEngine:
triggers:
- powerpoint
- pptx
- ppt
- presentation
- slide deck
- slides
---
- # PPTX creation, editing, and analysis
-
- ## Overview
-
- Create, edit, or analyze the contents of .pptx files when requested. A .pptx file is essentially a ZIP archive containing XML files and other resources. Different tools and workflows are available for different tasks.
-
- ## CRITICAL: Read All Documentation First
-
- **Before starting any presentation task**, read ALL relevant documentation files completely to understand the full workflow:
-
- 1. **For creating new presentations**: Read [`html2pptx.md`](html2pptx.md) and [`css.md`](css.md) in their entirety
- 2. **For editing existing presentations**: Read [`ooxml.md`](ooxml.md) in its entirety
- 3. **For template-based creation**: Read the relevant sections of this file plus [`css.md`](css.md)
-
- **NEVER set any range limits when reading these files.** Understanding the complete workflow, constraints, and best practices before starting is essential for producing high-quality presentations. Partial knowledge leads to errors, inconsistent styling, and visual defects that require rework.
-
- ## Reading and analyzing content
-
- ### Text extraction
-
- To read just the text content of a presentation, convert the document to markdown:
-
- ```bash
- # Convert document to markdown
- python3 -m markitdown path-to-file.pptx
- ```
-
- ### Raw XML access
-
- Use raw XML access for: comments, speaker notes, slide layouts, animations, design elements, and complex formatting. To access these features, unpack a presentation and read its raw XML contents.
-
- #### Unpacking a file
-
- `python3 ooxml/scripts/unpack.py <office_file> <output_dir>`
-
- #### Key file structures
-
- - `ppt/presentation.xml` - Main presentation metadata and slide references
- - `ppt/slides/slide{N}.xml` - Individual slide contents (slide1.xml, slide2.xml, etc.)
- - `ppt/notesSlides/notesSlide{N}.xml` - Speaker notes for each slide
- - `ppt/comments/modernComment_*.xml` - Comments for specific slides
- - `ppt/slideLayouts/` - Layout templates for slides
- - `ppt/slideMasters/` - Master slide templates
- - `ppt/theme/` - Theme and styling information
- - `ppt/media/` - Images and other media files
-
- #### Typography and color extraction
-
- **To emulate example designs**, analyze the presentation's typography and colors first using the methods below:
-
- 1. **Read theme file**: Check `ppt/theme/theme1.xml` for colors (`<a:clrScheme>`) and fonts (`<a:fontScheme>`)
- 2. **Sample slide content**: Examine `ppt/slides/slide1.xml` for actual font usage (`<a:rPr>`) and colors
- 3. **Search for patterns**: Use grep to find color (`<a:solidFill>`, `<a:srgbClr>`) and font references across all XML files
-
- ## Creating a new PowerPoint presentation **without a template**
-
- When creating a new PowerPoint presentation from scratch, use the **html2pptx** workflow to convert HTML slides to PowerPoint with accurate positioning.
-
- ### Workflow
-
- 1. **Read documentation**: Read [`html2pptx.md`](html2pptx.md) and [`css.md`](css.md) completely (see "CRITICAL: Read All Documentation First" section above)
-
- 2. **PREREQUISITE - Extract html2pptx library**:
- - Extract the library next to your script: `mkdir -p html2pptx && tar -xzf html2pptx.tgz -C html2pptx`
- - This creates a `html2pptx/` directory with the library files and CLI binaries
-
- 3. **Plan the presentation**: Follow html2pptx.md "Design Philosophy" section for:
- - Aesthetic direction and bold design choices
- - Color palette selection (see "Creating your color palette")
- - Typography strategy
- - Write DETAILED outline with slide layouts and presenter notes (1-3 sentences per slide)
-
- 4. **Set CSS variables**: Override CSS variables in a shared `.css` file for colors, typography, and spacing (see css.md "Design System Variables")
-
- 5. **Create HTML slides** (960px × 540px for 16:9): Follow html2pptx.md for:
- - Slide layout zones (title, content, footnote)
- - Critical text rules (proper HTML tags)
- - Supported elements and styling
-
- 6. Create and run a JavaScript file using the [`html2pptx`](./html2pptx) library to convert HTML slides to PowerPoint and save the presentation
-
- - Run with: `NODE_PATH="$(npm root -g)" node your-script.js 2>&1`
- - Use the `html2pptx` function to process each HTML file
- - Add charts and tables to placeholder areas using PptxGenJS API
- - Save the presentation using `pptx.writeFile()`
-
- - **⚠️ CRITICAL:** Your script MUST follow this example structure. Think aloud before writing the script to make sure that you correctly use the APIs. Do NOT call `pptx.addSlide`.
-
- ```javascript
- const pptxgen = require("pptxgenjs");
- const { html2pptx } = require("./html2pptx");
-
- // Create a new pptx presentation
- const pptx = new pptxgen();
- pptx.layout = "LAYOUT_16x9"; // Must match HTML body dimensions
-
- // Add an HTML-only slide
- await html2pptx("slide1.html", pptx);
-
- // Add a HTML slide with chart placeholders
- const { slide: slide2, placeholders } = await html2pptx("slide2.html", pptx);
- slide.addChart(pptx.charts.LINE, chartData, placeholders[0]);
-
- // Save the presentation
- await pptx.writeFile("output.pptx");
- ```
-
- 7. **Visual validation**: Convert to images and inspect for layout issues
- - Convert PPTX to PDF first: `soffice --headless --convert-to pdf output.pptx`
- - Then convert PDF to images: `pdftoppm -jpeg -r 150 output.pdf slide`
- - This creates files like `slide-1.jpg`, `slide-2.jpg`, etc.
- - Read each generated image file and carefully examine for:
- - **Text cutoff**: Text being cut off by header bars, shapes, or slide edges
- - **Text overlap**: Text overlapping with other text or shapes
- - **Positioning issues**: Content too close to slide boundaries or other elements
- - **Contrast issues**: Insufficient contrast between text and backgrounds
- - **Alignment problems**: Elements not properly aligned with each other
- - **Visual hierarchy**: Important content properly emphasized
- - **CRITICAL: All slides MUST pass these validation checks before delivering to the user.** Do not skip this step or deliver presentations with visual defects.
- - If issues found, fix them in the following order of priority:
- 1. **Increase margins** - Add more padding/spacing around problematic elements
- 2. **Adjust font size** - Reduce text size to fit within available space
- 3. **Rethink the layout entirely** - If the above fixes don't work, redesign the slide layout
- - Regenerate the presentation after making changes
- - Repeat until all slides are visually correct
-
- ## Editing an existing PowerPoint presentation
-
- To edit slides in an existing PowerPoint presentation, work with the raw Office Open XML (OOXML) format. This involves unpacking the .pptx file, editing the XML content, and repacking it.
-
- ### Workflow
-
- 1. **Read documentation**: Read [`ooxml.md`](ooxml.md) completely (see "CRITICAL: Read All Documentation First" section above)
- 2. Unpack the presentation: `python3 ooxml/scripts/unpack.py <office_file> <output_dir>`
- 3. Edit the XML files (primarily `ppt/slides/slide{N}.xml` and related files)
- 4. **CRITICAL**: Validate immediately after each edit: `python3 ooxml/scripts/validate.py <dir> --original <file>`
- 5. Pack the final presentation: `python3 ooxml/scripts/pack.py <input_directory> <office_file>`
-
- ## Creating a new PowerPoint presentation **using a template**
-
- To create a presentation that follows an existing template's design, duplicate and re-arrange template slides before replacing placeholder content.
-
- ### Workflow
-
- 1. **Extract template text AND create visual thumbnail grid**:
-
- - Extract text: `python3 -m markitdown template.pptx > template-content.md`
- - Read `template-content.md` completely to understand the template contents
- - Create thumbnail grids: `python3 scripts/thumbnail.py template.pptx`
- - See [Creating Thumbnail Grids](#creating-thumbnail-grids) section for more details
-
- 2. **Analyze template and save inventory to a file**:
-
- - **Visual Analysis**: Review thumbnail grid(s) to understand slide layouts, design patterns, and visual structure
- - Create and save a template inventory file at `template-inventory.md` containing:
-
- ```markdown
- # Template Inventory Analysis
-
- **Total Slides: [count]**
- **IMPORTANT: Slides are 0-indexed (first slide = 0, last slide = count-1)**
-
- ## [Category Name]
-
- - Slide 0: [Layout code if available] - Description/purpose
- - Slide 1: [Layout code] - Description/purpose
- - Slide 2: [Layout code] - Description/purpose
- [... EVERY slide must be listed individually with its index ...]
- ```
-
- - **Using the thumbnail grid**: Reference the visual thumbnails to identify:
- - Layout patterns (title slides, content layouts, section dividers)
- - Image placeholder locations and counts
- - Design consistency across slide groups
- - Visual hierarchy and structure
- - This inventory file is REQUIRED for selecting appropriate templates in the next step
-
- 3. **Create presentation outline based on template inventory**:
-
- - Review available templates from step 2.
- - Choose an intro or title template for the first slide. This should be one of the first templates.
- - Choose safe, text-based layouts for the other slides.
- - **CRITICAL: Match layout structure to actual content**:
- - Single-column layouts: Use for unified narrative or single topic
- - Two-column layouts: Use ONLY when there are exactly 2 distinct items/concepts
- - Three-column layouts: Use ONLY when there are exactly 3 distinct items/concepts
- - Image + text layouts: Use ONLY when there are actual images to insert
- - Quote layouts: Use ONLY for actual quotes from people (with attribution), never for emphasis
- - Never use layouts with more placeholders than available content
- - With 2 items, avoid forcing them into a 3-column layout
- - With 4+ items, consider breaking into multiple slides or using a list format
- - Count actual content pieces BEFORE selecting the layout
- - Verify each placeholder in the chosen layout will be filled with meaningful content
- - Select one option representing the **best** layout for each content section.
- - Save `outline.md` with content AND template mapping that leverages available designs
- - Example template mapping:
- ```
- # Template slides to use (0-based indexing)
- # WARNING: Verify indices are within range! Template with 73 slides has indices 0-72
- # Mapping: slide numbers from outline -> template slide indices
- template_mapping = [
- 0, # Use slide 0 (Title/Cover)
- 34, # Use slide 34 (B1: Title and body)
- 34, # Use slide 34 again (duplicate for second B1)
- 50, # Use slide 50 (E1: Quote)
- 54, # Use slide 54 (F2: Closing + Text)
- ]
- ```
-
- 4. **Duplicate, reorder, and delete slides using `rearrange.py`**:
-
- - Use the `scripts/rearrange.py` script to create a new presentation with slides in the desired order:
- ```bash
- python3 scripts/rearrange.py template.pptx working.pptx 0,34,34,50,52
- ```
- - The script handles duplicating repeated slides, deleting unused slides, and reordering automatically
- - Slide indices are 0-based (first slide is 0, second is 1, etc.)
- - The same slide index can appear multiple times to duplicate that slide
-
- 5. **Extract ALL text using the `inventory.py` script**:
-
- - **Run inventory extraction**:
- ```bash
- python3 scripts/inventory.py working.pptx text-inventory.json
- ```
- - **Read text-inventory.json** completely to understand all shapes and their properties
-
- - The inventory JSON structure:
-
- ```json
- {
- "slide-0": {
- "shape-0": {
- "placeholder_type": "TITLE", // or null for non-placeholders
- "left": 1.5, // position in inches
- "top": 2.0,
- "width": 7.5,
- "height": 1.2,
- "paragraphs": [
- {
- "text": "Paragraph text",
- // Optional properties (only included when non-default):
- "bullet": true, // explicit bullet detected
- "level": 0, // only included when bullet is true
- "alignment": "CENTER", // CENTER, RIGHT (not LEFT)
- "space_before": 10.0, // space before paragraph in points
- "space_after": 6.0, // space after paragraph in points
- "line_spacing": 22.4, // line spacing in points
- "font_name": "Arial", // from first run
- "font_size": 14.0, // in points
- "bold": true,
- "italic": false,
- "underline": false,
- "color": "FF0000" // RGB color
- }
- ]
- }
- }
- }
- ```
-
- - Key features:
- - **Slides**: Named as "slide-0", "slide-1", etc.
- - **Shapes**: Ordered by visual position (top-to-bottom, left-to-right) as "shape-0", "shape-1", etc.
- - **Placeholder types**: TITLE, CENTER_TITLE, SUBTITLE, BODY, OBJECT, or null
- - **Default font size**: `default_font_size` in points extracted from layout placeholders (when available)
- - **Slide numbers are filtered**: Shapes with SLIDE_NUMBER placeholder type are automatically excluded from inventory
- - **Bullets**: When `bullet: true`, `level` is always included (even if 0)
- - **Spacing**: `space_before`, `space_after`, and `line_spacing` in points (only included when set)
- - **Colors**: `color` for RGB (e.g., "FF0000"), `theme_color` for theme colors (e.g., "DARK_1")
- - **Properties**: Only non-default values are included in the output
-
- 6. **Generate replacement text and save the data to a JSON file**
- Based on the text inventory from the previous step:
-
- - **CRITICAL**: First verify which shapes exist in the inventory - only reference shapes that are actually present
- - **VALIDATION**: The replace.py script validates that all shapes in the replacement JSON exist in the inventory
- - Referencing a non-existent shape produces an error showing available shapes
- - Referencing a non-existent slide produces an error indicating the slide doesn't exist
- - All validation errors are shown at once before the script exits
- - **IMPORTANT**: The replace.py script uses inventory.py internally to identify ALL text shapes
- - **AUTOMATIC CLEARING**: ALL text shapes from the inventory are cleared unless "paragraphs" are provided for them
- - Add a "paragraphs" field to shapes that need content (not "replacement_paragraphs")
- - Shapes without "paragraphs" in the replacement JSON have their text cleared automatically
- - Paragraphs with bullets are automatically left aligned. Avoid setting the `alignment` property when `"bullet": true`
- - Generate appropriate replacement content for placeholder text
- - Use shape size to determine appropriate content length
- - **CRITICAL**: Include paragraph properties from the original inventory - don't just provide text
- - **IMPORTANT**: When bullet: true, do NOT include bullet symbols (•, -, \*) in text - they're added automatically
- - **ESSENTIAL FORMATTING RULES**:
- - Headers/titles should typically have `"bold": true`
- - List items should have `"bullet": true, "level": 0` (level is required when bullet is true)
- - Preserve any alignment properties (e.g., `"alignment": "CENTER"` for centered text)
- - Include font properties when different from default (e.g., `"font_size": 14.0`, `"font_name": "Lora"`)
- - Colors: Use `"color": "FF0000"` for RGB or `"theme_color": "DARK_1"` for theme colors
- - The replacement script expects **properly formatted paragraphs**, not just text strings
- - **Overlapping shapes**: Prefer shapes with larger default_font_size or more appropriate placeholder_type
- - Save the updated inventory with replacements to `replacement-text.json`
- - **WARNING**: Different template layouts have different shape counts - always check the actual inventory before creating replacements
-
- Example paragraphs field showing proper formatting:
-
- ```json
- "paragraphs": [
- {
- "text": "New presentation title text",
- "alignment": "CENTER",
- "bold": true
- },
- {
- "text": "Section Header",
- "bold": true
- },
- {
- "text": "First bullet point without bullet symbol",
- "bullet": true,
- "level": 0
- },
- {
- "text": "Red colored text",
- "color": "FF0000"
- },
- {
- "text": "Theme colored text",
- "theme_color": "DARK_1"
- },
- {
- "text": "Regular paragraph text without special formatting"
- }
- ]
- ```
-
- **Shapes not listed in the replacement JSON are automatically cleared**:
-
- ```json
- {
- "slide-0": {
- "shape-0": {
- "paragraphs": [...] // This shape gets new text
- }
- // shape-1 and shape-2 from inventory will be cleared automatically
- }
- }
- ```
-
- **Common formatting patterns for presentations**:
-
- - Title slides: Bold text, sometimes centered
- - Section headers within slides: Bold text
- - Bullet lists: Each item needs `"bullet": true, "level": 0`
- - Body text: Usually no special properties needed
- - Quotes: May have special alignment or font properties
-
- 7. **Apply replacements using the `replace.py` script**
-
- ```bash
- python3 scripts/replace.py working.pptx replacement-text.json output.pptx
- ```
-
- The script will:
-
- - First extract the inventory of ALL text shapes using functions from inventory.py
- - Validate that all shapes in the replacement JSON exist in the inventory
- - Clear text from ALL shapes identified in the inventory
- - Apply new text only to shapes with "paragraphs" defined in the replacement JSON
- - Preserve formatting by applying paragraph properties from the JSON
- - Handle bullets, alignment, font properties, and colors automatically
- - Save the updated presentation
-
- Example validation errors:
-
- ```
- ERROR: Invalid shapes in replacement JSON:
- - Shape 'shape-99' not found on 'slide-0'. Available shapes: shape-0, shape-1, shape-4
- - Slide 'slide-999' not found in inventory
- ```
-
- ```
- ERROR: Replacement text made overflow worse in these shapes:
- - slide-0/shape-2: overflow worsened by 1.25" (was 0.00", now 1.25")
- ```
-
- ## Creating Thumbnail Grids
-
- To create visual thumbnail grids of PowerPoint slides for quick analysis and reference:
-
- ```bash
- python3 scripts/thumbnail.py template.pptx [output_prefix]
- ```
-
- **Features**:
-
- - Creates: `thumbnails.jpg` (or `thumbnails-1.jpg`, `thumbnails-2.jpg`, etc. for large decks)
- - Default: 5 columns, max 30 slides per grid (5×6)
- - Custom prefix: `python3 scripts/thumbnail.py template.pptx my-grid`
- - Note: The output prefix should include the path if you want output in a specific directory (e.g., `workspace/my-grid`)
- - Adjust columns: `--cols 4` (range: 3-6, affects slides per grid)
- - Grid limits: 3 cols = 12 slides/grid, 4 cols = 20, 5 cols = 30, 6 cols = 42
- - Slides are zero-indexed (Slide 0, Slide 1, etc.)
+ # Create & edit PowerPoint with python-pptx
- **Use cases**:
+ Build real `.pptx` files with the open-source **python-pptx** library
+ (`python3 -c "import pptx"`). Work in visible steps; verify before reporting done.
- - Template analysis: Quickly understand slide layouts and design patterns
- - Content review: Visual overview of entire presentation
- - Navigation reference: Find specific slides by their visual appearance
- - Quality check: Verify all slides are properly formatted
+ ## Workflow
+ 1. **Outline the deck**: a title slide + one slide per section; note any tables,
+ images, or speaker notes.
+ 2. **Write a Python script** (heredoc via the `bash` tool) that builds the deck
+ with python-pptx and saves it.
+ 3. **Verify**: reopen with `Presentation(path)` and assert the slide count / title;
+ `print(path)`.
+ 4. **Report** the saved path + a one-line summary.
- **Examples**:
+ ## Quality conventions
+ - Start with a **title slide** (`slide_layouts[0]`), then content slides
+ (`slide_layouts[1]` for bullets, `slide_layouts[5]` "Title Only" for custom layouts/tables).
+ - Real **bullet lists** via the body placeholder's `text_frame` paragraphs (set `.level`
+ for sub-bullets) — not one big text blob.
+ - **Tables** via `slide.shapes.add_table(rows, cols, left, top, width, height)`; bold + fill
+ the header row.
+ - Use a consistent accent color and **web-safe fonts** (Arial, Calibri) so the deck renders
+ everywhere; keep ≤ ~6 bullets per slide.
+ - Add **speaker notes** with `slide.notes_slide.notes_text_frame.text = "…"` when useful.
+ ## Example
```bash
- # Basic usage
- python3 scripts/thumbnail.py presentation.pptx
-
- # Combine options: custom name, columns
- python3 scripts/thumbnail.py template.pptx analysis --cols 4
- ```
-
- ## Converting Slides to Images
-
- To visually analyze PowerPoint slides, convert them to images using a two-step process:
-
- 1. **Convert PPTX to PDF**:
-
- ```bash
- soffice --headless --convert-to pdf template.pptx
- ```
-
- 2. **Convert PDF pages to JPEG images**:
- ```bash
- pdftoppm -jpeg -r 150 template.pdf slide
- ```
- This creates files like `slide-1.jpg`, `slide-2.jpg`, etc.
-
- Options:
-
- - `-r 150`: Sets resolution to 150 DPI (adjust for quality/size balance)
- - `-jpeg`: Output JPEG format (use `-png` for PNG if preferred)
- - `-f N`: First page to convert (e.g., `-f 2` starts from page 2)
- - `-l N`: Last page to convert (e.g., `-l 5` stops at page 5)
- - `slide`: Prefix for output files
+ python3 - <<'PY'
+ from pptx import Presentation
+ from pptx.util import Inches, Pt
+ from pptx.dml.color import RGBColor
+ p = Presentation()
+ s = p.slides.add_slide(p.slide_layouts[0])
+ s.shapes.title.text = 'Q2 Robotics Budget'
+ s.placeholders[1].text = 'Funding 120k EUR — on track'
- Example for specific range:
+ s2 = p.slides.add_slide(p.slide_layouts[5]); s2.shapes.title.text = 'Line items'
+ tbl = s2.shapes.add_table(3, 3, Inches(0.6), Inches(1.6), Inches(8.5), Inches(2)).table
+ for j, h in enumerate(['Item', 'Cost', 'Status']):
+ cell = tbl.cell(0, j); cell.text = h
+ cell.text_frame.paragraphs[0].runs[0].font.bold = True
+ for i, row in enumerate([['Actuators', '8000', 'ordered'], ['Compute', '3500', 'done']], 1):
+ for j, v in enumerate(row):
+ tbl.cell(i, j).text = v
+ p.save('deck.pptx')
- ```bash
- pdftoppm -jpeg -r 150 -f 2 -l 5 template.pdf slide # Converts only pages 2-5
+ assert len(Presentation('deck.pptx').slides) == 2
+ print('deck.pptx')
+ PY
```
- ## Code Style Guidelines
-
- **IMPORTANT**: When generating code for PPTX operations:
-
- - Write concise code
- - Avoid verbose variable names and redundant operations
- - Avoid unnecessary print statements
-
- ## Dependencies
-
- Required dependencies (should already be installed):
-
- - **markitdown**: `pip3 install "markitdown[pptx]"` (for text extraction from presentations)
- - **pptxgenjs**: `npm install -g pptxgenjs` (for creating presentations via html2pptx)
- - **playwright**: `npm install -g playwright` (for HTML rendering in html2pptx)
- - **react-icons**: `npm install -g react-icons react react-dom` (for icons in SVG format)
- - **LibreOffice**: For PDF conversion (required for visual validation step)
- - macOS: `brew install --cask libreoffice`
- - Linux: `sudo apt-get install libreoffice`
- - **Poppler**: `sudo apt-get install poppler-utils` (for pdftoppm to convert PDF to images)
- - **defusedxml**: `pip3 install defusedxml` (for secure XML parsing)
+ ## Reading / editing existing files
+ - Read: iterate `Presentation(path).slides` and each `shape.text_frame`.
+ - Edit in place: load, modify shapes/placeholders/tables, `save()` back; keep the
+ existing theme, layout, and fonts.