# Ppt YAML Deck Workflow

> Edit PraisonAIPPT YAML decks in examples, keep style consistent, regenerate matching PPTX, upload to Google Drive, Slack the View Link, and verify output. Use when users request slide/verse/section/highlight updates for deck YAML files.

- Skill: `mervinpraison/ppt-yaml-deck-workflow` (Agent Skill)
- Install (CLI): `npx skillmds@latest add mervinpraison/ppt-yaml-deck-workflow`
- Raw SKILL.md: https://api.skillmd.com/api/skills/mervinpraison/ppt-yaml-deck-workflow/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Docs & Writing
- Author: MervinPraison (https://skillmd.com/u/mervinpraison)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/mervinpraison/ppt-yaml-deck-workflow

---


# PPT YAML Deck Workflow

## Scope

Use this workflow for deck edits in `examples/*.yaml` where the output is a `.pptx` generated by `praisonaippt` (`python-pptx` via `praisonaippt/core.py`). This is **not** the Codex artifact-tool JS slide builder.

- **Source of truth**: `examples/<deck>.yaml`
- **Generated artefact**: `examples/<deck>.pptx` (same basename; regenerate after every YAML edit)
- **Full field reference**: copy from `examples/template.yaml`

## Standard checklist

Copy and track:

```text
Progress:
- [ ] 1) Identify target YAML deck and exact requested changes
- [ ] 2) Read current YAML structure before editing
- [ ] 3) Apply minimal YAML edits only
- [ ] 4) Regenerate matching PPTX with CLI
- [ ] 5) Confirm build success; paste slide outline + Google Drive View Link to user
- [ ] 6) Slack notify with the same Google Drive View Link (required)
- [ ] 7) Commit and push to **main**; merge the PR if you opened one
```

## YAML document structure

### Top level

| Key | Purpose |
|-----|---------|
| `presentation_title` | Opening title slide |
| `presentation_subtitle` | Optional subtitle on title slide |
| `slide_style` | Global look (background, colours, font, alignment) — or use `template: sermon-dark` |
| `template` | Built-in style theme name (`praisonaippt --list-templates`); replaces inline `slide_style` |
| `slide_size` | Optional: `widescreen` / `16:9` / `standard` / `4:3` / `16:10`, or `{ width, height }` in inches |
| `auto_upload_gdrive` | Default **`true`** on example decks; uploads PPTX after build when credentials exist (also honour `~/.praisonaippt` `defaults.auto_upload_gdrive`) |
| `sections` | List of section blocks (required) |

### Default style (use a theme template)

Prefer a built-in theme instead of copying `slide_style` into every deck:

```yaml
template: sermon-dark
auto_upload_gdrive: true
```

Other themes: `default`, `sermon-gold`, `light-minimal` — see `docs/templates.md` or `praisonaippt --list-templates`.

Inline override example:

```yaml
template: sermon-dark
slide_style:
  highlight_color: '#FFD700'
```

Legacy inline block (equivalent to `template: sermon-dark`):

```yaml
auto_upload_gdrive: true
slide_style:
  background_image: assets/background_alt.jpg
  text_color: white
  alignment: left
  reference_position: top
  font_name: Palatino
```

Omit `slide_size` unless the user needs `standard` / `4:3`; default build is widescreen (16:9).

### Section block

```yaml
sections:
  - section: Section title here    # use '' to skip the section divider slide
    section_subtitle: Optional     # second line on section slide
    verses:
      - reference: ...
        text: ...
```

### Verse block (common keys)

| Key | Effect |
|-----|--------|
| `reference` + `text` | Standard verse slide(s) |
| `highlights` | Strings, or objects: `text`, `color`, `bold`, `italic`, `underline`, `annotation` (1–9) |
| `leading_title` | Large headline above reference (sermon “message” slides); only on **first** slide when text is split |
| `split_max_length` | Max chars per slide before splitting (default 200); use 400–500 for long NKJV passages |
| `font_size`, `alignment` | Per-verse overrides (else from `slide_style`) |
| `reference_font_size` | Larger reference line (title-style slides) |
| `list_type: bullet` \| `numbered` | List slide; `text` lines separated by `\n` |
| `slide_type: image` + `image_path` | Image slide (`image_fit`: `contain` / `cover` / `fill`; optional `reference` + `text` as caption) |
| `text_below_reference` | Extra passage block below verse body (same slide) |

**Image slides** — add a verse entry:

```yaml
- slide_type: image
  image_path: assets/diagrams/my_chart.png
  image_fit: contain
  reference: Slide label
  text: Optional caption under the image
```

Paths resolve relative to the YAML file, then cwd, then repo root. Extract images from an existing PPTX with `praisonaippt convert-json deck.pptx` (saves under `assets/extracted_images/<stem>/` when slides are image-only).

**Generate new slide art** with the **gpt-image** skill (`.cursor/skills/gpt-image/`): `uv run .cursor/skills/gpt-image/scripts/generate.py --size 1536x864 --output assets/generated/...png`, then reference that path in YAML. Validate setup: `uv run .cursor/skills/gpt-image/scripts/validate_skill.py`.

Paths in `slide_style.background_image` are often relative to repo root (e.g. `assets/background_alt.jpg`).

## How YAML becomes slides

`load_verses_from_file` → `yaml.safe_load` → `validate_verses` (`praisonaippt/schema.py`) → `create_presentation` (`praisonaippt/core.py`):

1. **Title slide** — `presentation_title` / `presentation_subtitle`
2. **For each section** — if `section` is non-empty → **section slide**; if `section: ''` → no section slide
3. **For each verse**:
   - `slide_type: image` → image slide (resolved path, optional caption, `image_fit`)
   - `list_type: bullet` \| `numbered` → list slide
   - else → `split_long_text` on `text` → one **verse slide** per chunk via `add_verse_slide` (background, reference, body, highlights)

Optional CLI extras (only when user asks): `--convert-pdf`, `--upload-gdrive` (also triggered by `auto_upload_gdrive: true`).

## 1) Identify deck file

- Confirm the target YAML in `examples/` (newest examples include `100_fold_blessing.yaml`, `freedom_from_all_your_troubles.yaml`, `elshadai.yaml`).
- If user gives only topic/title, create a new YAML in `examples/` (copy `template.yaml`) with the requested name.

## 2) Read before edit

- Read the YAML section where changes are needed before modifying.
- For reorder requests, verify both source and destination blocks first.
- Match indentation and patterns used in neighbouring verses in that deck.

## 3) Apply minimal edits

- New decks and restyle requests: apply the **default `slide_style`** above so design matches the latest example decks.
- Keep existing `slide_style` on small content-only edits unless the user asked to restyle.
- Preserve verse text unless the user asked to rewrite it.
- For highlights, prefer keyword-only highlights unless user asks for colour/annotation objects (e.g. `color: green` for law, `#FFD700` for promise/grace, `#9900FF` for Hebrew names).
- When rebuilding from an existing `.pptx`, run `praisonaippt convert-json file.pptx` to recover highlights; if none are extracted, add them manually in YAML—`create_presentation` does not invent highlights.
- Confirm `presentation_title` matches what the user requested before regenerating.
- For section title slides, add a new `section` block only where needed.
- Do not edit `praisonaippt/core.py` for content changes—change YAML only.

## 4) Regenerate PPTX (required after YAML edit)

From repo root:

```bash
python3 -m praisonaippt.cli -i examples/<deck>.yaml -o examples/<deck>.pptx
```

Optional: export plain Markdown from the same YAML:

```bash
python3 -m praisonaippt.cli convert-markdown examples/<deck>.yaml
# → examples/<deck>.md (blockquotes, **highlights**, section headings)
# Google Doc upload uses examples/<deck>.html with yellow/green highlight colours like PPT
# Uploads as native Google Doc when auto_upload_gdrive: true or --upload-gdrive
```

Equivalent: `praisonaippt convert-markdown examples/<deck>.yaml --markdown-output notes.md --upload-gdrive`

Equivalent: `praisonaippt -i examples/<deck>.yaml -o examples/<deck>.pptx`

After a successful build, the CLI **automatically prints a numbered slide outline** (same as `list-slides` below). Use that output when reporting order to the user—do not run ad-hoc `python3 -c` snippets.

To list slides on an existing PPTX without rebuilding:

```bash
python3 -m praisonaippt.cli list-slides examples/<deck>.pptx
```

Equivalent: `praisonaippt list-slides examples/<deck>.pptx`

Skip the post-build outline with `--no-list-slides` on the generate command.

Example:

```bash
python3 -m praisonaippt.cli -i examples/100_fold_blessing.yaml -o examples/100_fold_blessing.pptx
```

## 5) Verify result and Google Drive URL

- Ensure CLI reports: `Presentation created successfully`, then the **slide outline** (`slides: N` and `01: …` lines).
- When confirming order in chat, paste or summarise that CLI outline (from build output or `list-slides`).
- **Default:** set `auto_upload_gdrive: true` in the deck YAML (and rely on `~/.praisonaippt` credentials). After every successful build, copy the CLI **`View Link:`** URL and **give it to the user** in your reply (full `https://docs.google.com/...` URL).
- If upload is skipped, say why (missing credentials, `auto_upload_gdrive: false`, or upload error) and still confirm the local `.pptx` path.
- If YAML parse or schema errors occur, fix quoting/block-scalar/indentation and rerun immediately.

## 6) Slack notify (required)

Do this **every time** a deck build finishes — do not wait for the user to ask. Follow `~/.cursor/skills/slack-notification/SKILL.md`.

The Slack body **must** include the Google Drive **View Link** (or **Edit Link** for a Google Doc). If upload was skipped, say why and include the local `.pptx` path.

```bash
source ~/.zshrc 2>/dev/null || true
# Fallback if vars missing: source ~/.config/automation/slack.env
~/.cursor/skills/slack-notification/scripts/send-slack.sh \
  --title "PraisonAIPPT: <deck title>" \
  --body "<2–5 lines: slides built, what changed>
View Link: <full https://docs.google.com/... URL>" \
  --emoji ":white_check_mark:"
```

Confirm in chat: "Slack notification sent". Do not log tokens.

## 7) Git update

- Stage only intended files (typically YAML; include `.pptx` if the repo tracks regenerated decks).
- Commit with a clear one-line message.
- **Always push to `main`** (`git push origin main`). Do not leave work only on a feature branch.
- If you created a pull request, **merge it** into `main` in the same turn (then push `main` if the merge was local).

## Common YAML pitfalls

- Plain scalars containing `:` may require quotes (e.g. `'Romans 2:13 (NKJV)'`).
- Keep list indentation consistent under `sections` and `verses`.
- Use block scalars (`>-` or `|-`) for multi-line verse text.
- Unknown top-level keys (e.g. `slide_styles` instead of `slide_style`) log warnings—use exact key names from `template.yaml`.

