# How Claude Skills Generate and Edit PowerPoint Presentations: A Complete Python Toolkit

> Discover how Claude Skills leverage a Python toolkit to generate and edit PowerPoint presentations programmatically. Modify content, preserve formatting, and automate tasks effortlessly.

- Repository: [Composio/awesome-claude-skills](https://github.com/composiohq/awesome-claude-skills)
- Tags: how-to-guide
- Published: 2026-07-28

---

**Claude Skills manipulates PowerPoint files through a specialized Python toolkit that extracts slide content into structured JSON, allows programmatic text modifications, and writes changes back while preserving formatting, fonts, and layout integrity.**

The `ComposioHQ/awesome-claude-skills` repository provides a self-contained solution for Python PowerPoint automation located under `document-skills/pptx`. This toolkit enables Claude Skills to programmatically generate new presentation content or edit existing decks without breaking visual consistency.

## The Two-Step Workflow

The toolkit operates through a strict inventory-and-replace pipeline that separates reading from writing. This design ensures that any automated edits respect the original slide structure while allowing LLMs to work with simple JSON data.

The workflow consists of two core scripts:

- **[`inventory.py`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/inventory.py)** – Scans a PowerPoint (`.pptx`) and builds a structured JSON inventory of every text-containing shape, preserving position, size, paragraph formatting, bullet information, and layout-related warnings.
- **[`replace.py`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/replace.py)** – Reads the JSON inventory (or a hand-crafted replacement file) and writes the new text back into the original presentation, applying the same formatting rules and re-validating for overflow or overlap issues.

## Step 1: Building the Inventory with [`inventory.py`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/inventory.py)

The [`document-skills/pptx/scripts/inventory.py`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/document-skills/pptx/scripts/inventory.py) script performs a deep traversal of each slide to create a machine-readable representation of the presentation.

### Shape Discovery and Validation

The `collect_shapes_with_absolute_positions` function recursively walks normal shapes and nested `GroupShape`s, calculating absolute EMU coordinates so that grouped objects are treated as if they were on the slide surface. The `is_valid_shape` function filters out placeholders such as slide numbers or empty frames, ensuring only meaningful text containers are processed.

### Paragraph and Format Extraction

For each valid shape, the script creates **`ParagraphData`** objects that capture:

- **Text content** and **bullet flags**
- **Alignment**, **spacing**, and **line spacing**
- **Font properties** including size, name, bold/italic/underline status, and color (or theme color)

### Overflow and Layout Detection

The inventory process includes several validation layers to catch presentation issues:

- **`_estimate_frame_overflow`** – Uses Pillow to measure wrapped text against the usable shape area, flagging any bottom overflow (`frame_overflow_bottom`).
- **`_calculate_slide_overflow`** – Checks whether a shape protrudes past the slide dimensions.
- **`_detect_bullet_issues`** – Warns when a paragraph contains manual bullet characters instead of native PowerPoint bullet formatting.
- **`detect_overlaps`** – After sorting shapes by visual position with `sort_shapes_by_position`, this function records any shape pairs that intersect (`overlapping_shapes`).

All metadata is stored in **`ShapeData`** objects, which convert to clean JSON via `ShapeData.to_dict`. The final inventory uses a hierarchical structure:

```json
{
  "slide-0": {
    "shape-0": {
      "left": 1.2,
      "top": 0.3,
      "width": 5.0,
      "height": 1.5,
      "paragraphs": [
        {
          "text": "Welcome",
          "font_name": "Calibri",
          "font_size": 24,
          "bold": true,
          "alignment": "CENTER"
        }
      ],
      "overflow": {
        "frame": {"overflow_bottom": 0.12}
      },
      "warnings": ["manual_bullet_symbol: use proper bullet formatting"]
    }
  }
}

```

Use `save_inventory` to serialize this structure to a JSON file for the replacement stage.

## Step 2: Applying Replacements with [`replace.py`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/replace.py)

The [`document-skills/pptx/scripts/replace.py`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/document-skills/pptx/scripts/replace.py) script consumes the original presentation path, a JSON replacement file, and an output path to write the edited deck.

### The Replacement Pipeline

1. **Load presentation** – Creates a single `Presentation` instance to ensure shape objects stay linked to the original file.
2. **Re-extract inventory** – Runs `extract_text_inventory` to guarantee that shape IDs match those referenced in the replacement JSON.
3. **Validate replacements** – The `validate_replacements` function verifies that every referenced slide and shape exists, and prints a list of shapes that were not addressed.
4. **Apply text** – For each shape, `text_frame.clear()` removes existing content. If the replacement JSON provides a `"paragraphs"` array, `apply_paragraph_properties` creates new paragraphs with replicated formatting (font, size, color, bullets, alignment, spacing).
5. **Post-replace validation** – After saving to a temporary file, the script re-runs inventory extraction to verify no new overflow or warnings were introduced. If problems are detected, the script aborts with a descriptive error.
6. **Write final file** – When all checks pass, `prs.save(output_file)` writes the edited presentation.

Because the replacement process uses the same `ParagraphData` and `ShapeData` logic as the inventory step, the resulting deck preserves visual layout while updating only explicitly changed text.

## Supporting Utilities

The toolkit includes additional scripts for specialized tasks:

- **[`rearrange.py`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/rearrange.py)** – Re-orders shapes on a slide based on visual position.
- **[`thumbnail.py`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/thumbnail.py)** – Renders low-resolution PNG previews of slides for UI thumbnails.
- **Issues-only mode** – Running [`inventory.py`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/inventory.py) with the `--issues-only` flag extracts only shapes exhibiting overflow, slide-boundary overflow, overlap, or formatting warnings, enabling focused edit passes.

## Code Examples

### Generate an Inventory from an Existing Deck

```python
from pathlib import Path
from document_skills.pptx.scripts.inventory import save_inventory, extract_text_inventory

pptx_path = Path("deck.pptx")
inventory_path = Path("deck_inventory.json")

# Extract all text shapes (including those with formatting issues)

save_inventory(
    inventory=extract_text_inventory(pptx_path, issues_only=False),
    output_path=inventory_path,
)
print(f"Inventory saved to {inventory_path}")

```

### Edit Titles and Bullet Lists Programmatically

```python
import json
from pathlib import Path
from document_skills.pptx.scripts.replace import apply_replacements

# Load the previously generated inventory

with open("deck_inventory.json") as f:
    inv = json.load(f)

# Change slide‑0, shape‑0 (title) and slide‑0, shape‑1 (bullet list)

inv["slide-0"]["shape-0"]["paragraphs"][0]["text"] = "New Presentation Title"
inv["slide-0"]["shape-1"]["paragraphs"] = [
    {"text": "First point", "bullet": True, "level": 0},
    {"text": "Second point", "bullet": True, "level": 0},
]

# Write back the modified JSON

with open("deck_replacements.json", "w") as f:
    json.dump(inv, f, indent=2)

# Apply the changes

apply_replacements(
    pptx_file="deck.pptx",
    json_file="deck_replacements.json",
    output_file="deck_updated.pptx",
)
print("Updated deck written to deck_updated.pptx")

```

### Fix Layout Issues with Issues-Only Mode

```bash
python document-skills/pptx/scripts/inventory.py deck.pptx deck_issues.json --issues-only

```

This creates [`deck_issues.json`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/deck_issues.json) containing only problematic shapes. Edit those entries and feed the file to [`replace.py`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/replace.py) to fix specific slides without modifying the rest of the deck.

## Summary

- **Claude Skills** use a two-step Python toolkit to generate and edit PowerPoint presentations without breaking layouts.
- **[`inventory.py`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/inventory.py)** extracts complete structural data including text, formatting, and layout warnings to JSON.
- **[`replace.py`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/replace.py)** validates and applies JSON modifications back to PPTX files while preserving fonts, colors, and bullet structures.
- **Overflow detection** and **overlap detection** ensure that automated edits do not introduce visual artifacts.
- The **issues-only mode** allows targeted fixes for problematic slides.

## Frequently Asked Questions

### How does the toolkit preserve PowerPoint formatting when replacing text?

The [`replace.py`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/replace.py) script uses the `apply_paragraph_properties` function to replicate the exact font properties, bullet structures, alignment, and spacing stored in the `ParagraphData` objects. By clearing the text frame rather than overwriting it, and then rebuilding paragraphs with the original formatting parameters, the toolkit ensures that visual styling remains intact.

### Can Claude Skills create entirely new PowerPoint presentations from scratch?

Yes. While the toolkit is optimized for editing existing files, Claude Skills can generate a valid JSON inventory structure programmatically and pass it to `apply_replacements` with a base template. The script validates that all referenced slides and shapes exist, so the workflow requires starting from a template PPTX with the desired layout shapes, then populating them via JSON replacement.

### What validation checks prevent corrupted output files?

The replacement pipeline includes post-processing validation that re-runs the inventory extraction after saving to a temporary file. This catches any `frame_overflow_bottom`, slide-boundary overflow, or `overlapping_shapes` issues introduced by the text changes. If new problems are detected, the script aborts before writing to the final output path, preventing the distribution of malformed presentations.

### How are nested shapes and grouped objects handled?

The `collect_shapes_with_absolute_positions` function in [`inventory.py`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/inventory.py) recursively processes `GroupShape` containers and calculates absolute EMU coordinates for all child elements. This flattens the hierarchy for JSON representation while preserving positional data, ensuring that grouped objects are treated correctly during both inventory extraction and text replacement phases.