Skip to content

JinwangMok/agent4ppt

Repository files navigation

agent4ppt

English | 한국어 | 中文

A Claude Code plugin that parses PPTX templates into markdown templates, generates editable PPTX files from markdown, and supports interactive slide revision — all without image-based rendering. Markdown is the single source of truth.

License: MIT Python: 3.10+ Claude Code Plugin


Table of Contents


Features

  • Template Parsing — Reads a PPTX template and outputs a structured markdown file with placeholder annotations (<!-- ph:idx type:TYPE -->)
  • PPTX Generation — Converts markdown back to a PPTX that faithfully reproduces the template's visual layout
  • Interactive Revision — 3-step interview workflow to revise specific slides and regenerate PPTX
  • Rich Content Support — Tables, charts (bar/pie/line), images, multi-column layouts
  • Bilingual Output — Korean (ko) and English (en) guide comments via LANG env variable
  • 100% Editable — All content is inserted as native python-pptx objects (no image rendering)

Overview

agent4ppt is a Claude Code / OpenClaw plugin that solves a common problem for researchers, engineers, and presenters: maintaining a PPTX slide deck through iterations is tedious and error-prone when the content lives inside binary files.

The Problem

  • Editing a PPTX template manually is time-consuming and breaks consistency
  • AI-assisted slide generation often relies on screenshot/image pipelines that produce non-editable output
  • No reliable way to version-control slide content alongside code or documentation

The Solution: Markdown-First Pipeline

agent4ppt introduces a three-skill pipeline where a human-readable markdown file is the single source of truth for all slide content:

PPTX Template  →  /parse-ppt-template  →  Markdown Template
                                               ↓ (edit content)
                                          Markdown Content
                                               ↓
                          /generate-ppt  →  PPTX Output (editable)
                          /revise-ppt    →  Interactive revision loop

Key Design Principles

Principle Description
No image rendering All PPTX objects are created via python-pptx native API. Output is always fully editable in PowerPoint / LibreOffice Impress.
Markdown as truth Slide content, layout metadata, and revision history all live in a .md file. The PPTX template is referenced only, never modified.
Stable placeholder identity Placeholders are identified by idx (the python-pptx integer index), making round-trips and re-ordering slides safe.
Bilingual by design All user-facing strings (guide comments, prompts, error messages) support Korean and English via the LANG environment variable.
Graceful degradation Optional LibreOffice previews enhance the revision workflow but are never required; the core pipeline runs with Python alone. When a body placeholder is missing from the layout, content is inserted via a textbox fallback (or image fallback for image content).

Who Is This For?

  • Researchers who want to generate slide decks from structured markdown notes
  • Engineers who need to automate slide generation in CI/CD or scripted workflows
  • Claude Code / OpenClaw users who want a composable skill that integrates naturally with AI-assisted workflows
  • Anyone who prefers editing slides as text rather than clicking through PowerPoint

Installation

System Requirements

Before installing agent4ppt, ensure your environment meets these requirements:

Requirement Version Notes
Python ≥ 3.10 Required. Check: python3 --version
pip any Required. Check: pip --version
python-pptx ≥ 0.6.21 Auto-installed by scripts/install.sh
pyyaml ≥ 6.0 Auto-installed by scripts/install.sh
markdown-it-py ≥ 3.0 Auto-installed by scripts/install.sh
LibreOffice any (Optional) PNG slide previews in /revise-ppt

The three Python packages (python-pptx, pyyaml, markdown-it-py) are installed automatically by the bundled installer script. Only Python ≥ 3.10 and pip must be present beforehand.

No image-based rendering: agent4ppt uses python-pptx directly to write native PPTX objects (text frames, tables, charts). The output is always fully editable in PowerPoint or LibreOffice Impress.

Claude Code (Plugin Marketplace)

Install agent4ppt in two commands:

claude plugin marketplace add JinwangMok/agent4ppt
claude plugin install agent4ppt

The installer automatically runs scripts/install.sh which checks Python ≥ 3.10, installs the three required packages, and reports the optional LibreOffice dependency.

After installation, the three skills (/parse-ppt-template, /generate-ppt, /revise-ppt) are available directly in your Claude Code session.

OpenClaw (Agent Skills Standard)

agent4ppt follows the Agent Skills standard (SKILL.md format), making it compatible with OpenClaw and other Agent Skills-compatible runtimes.

Installation steps:

# Step 1: Clone the repository
git clone https://github.com/JinwangMok/agent4ppt.git
cd agent4ppt

# Step 2: Install Python dependencies
bash scripts/install.sh --no-register

# Step 3: Register with OpenClaw (point to the cloned directory)
# openclaw skill add ./agent4ppt
# — or — add the GitHub URL to your OpenClaw skill sources:
# openclaw skill add https://github.com/JinwangMok/agent4ppt

OpenClaw discovers skills automatically via the SKILL.md file in the repository root. Each skill entry defines:

SKILL.md field Value
trigger /parse-ppt-template, /generate-ppt, /revise-ppt
entry skills/<name>/<script>.py
requires_python >=3.10
dependencies python-pptx>=0.6.21, pyyaml>=6.0, markdown-it-py>=3.0

After registration, the three slash commands are available inside your OpenClaw session.

Codex CLI

agent4ppt is also compatible with Codex CLI. After cloning and installing dependencies:

git clone https://github.com/JinwangMok/agent4ppt.git
cd agent4ppt
bash scripts/install.sh

# Run skills directly via Python
python skills/parse-ppt-template/parse_template.py template.pptx --output slides.md
python skills/generate-ppt/generate_ppt.py slides.md --output output.pptx
python skills/revise-ppt/revise_ppt.py slides.md

Manual Installation

If you prefer manual setup without any agent runtime:

git clone https://github.com/JinwangMok/agent4ppt.git
cd agent4ppt
pip install python-pptx pyyaml markdown-it-py

Post-Installation Configuration

1. Verify the installation

After installing via any method above, confirm all required dependencies are available:

python3 -c "import pptx, yaml; from markdown_it import MarkdownIt; print('agent4ppt: all dependencies OK')"

You should see: agent4ppt: all dependencies OK

2. Configure output language

agent4ppt reads the LANG POSIX environment variable to choose Korean or English for guide comments and prompts. Set it once in your shell profile:

# Korean output (add to ~/.bashrc or ~/.zshrc)
export LANG=ko_KR.UTF-8

# English output (default — no explicit setting needed)
export LANG=en_US.UTF-8

You can also override the language per-invocation:

/parse-ppt-template template.pptx --lang ko   # Korean for this run only
/revise-ppt slides.md --lang en               # English for this run only

Language priority: --lang flag > frontmatter lang: field > $LANG environment variable > en (default)

3. Optional: enable PNG slide previews (LibreOffice)

The /revise-ppt skill can show PNG slide thumbnails during the interactive review workflow. This requires LibreOffice:

# Ubuntu / Debian
sudo apt install libreoffice

# macOS (Homebrew)
brew install --cask libreoffice

Without LibreOffice the skill degrades gracefully to a plain-text slide summary — the core parse/generate/revise functionality is unaffected.

4. Claude Code plugin settings (optional)

agent4ppt's behavior is fully controlled via command-line arguments and the LANG environment variable. No changes to ~/.claude/settings.json are required. To set a persistent language preference inside Claude Code:

// ~/.claude/settings.json
{
  "env": {
    "LANG": "ko_KR.UTF-8"
  }
}

Quick Start

1. Parse a PPTX template to markdown

/parse-ppt-template my_template.pptx
# → Generates my_template.md

2. Edit the markdown

Open my_template.md and fill in your content between the placeholder comments.

3. Generate PPTX from markdown

/generate-ppt my_template.md
# → Generates output.pptx (or the fname from frontmatter)

4. Interactively revise slides

/revise-ppt my_template.md

Pipeline Architecture

agent4ppt is built around a markdown-first pipeline. The markdown file is the single source of truth; the PPTX template is referenced once in the YAML frontmatter (template field) and never modified.

┌─────────────────────────────────────────────────────────────────┐
│                     agent4ppt Pipeline                          │
│                                                                 │
│  PPTX Template                                                  │
│  (read-only)                                                    │
│       │                                                         │
│       ▼  /parse-ppt-template                                    │
│  Markdown Template ──────────────────────────────────────────►  │
│  (YAML frontmatter + slide sections + <!-- ph:idx --> comments) │
│       │                                                         │
│       │  (user fills content)                                   │
│       ▼                                                         │
│  Markdown Content File                                          │
│       │                  ┌──────────────────────────────────┐   │
│       ├── /generate-ppt ─►  PPTX Output                     │   │
│       │                  │  (uses template from frontmatter) │   │
│       │                  └──────────────────────────────────┘   │
│       │                                                         │
│       └── /revise-ppt ──► (3-step interview)                    │
│                               │                                 │
│                               ├── update markdown in-place      │
│                               └── invoke /generate-ppt          │
└─────────────────────────────────────────────────────────────────┘

Data flow

Stage Input Output Key operation
parse *.pptx template *.md with <!-- ph:idx type:TYPE --> python-pptx reads slide layouts; idx-based placeholder mapping written to markdown
generate *.md content file *.pptx presentation Frontmatter template field resolves the source PPTX; each ph:idx block written to the matching placeholder
revise *.md content file updated *.md + *.pptx Interactive 3-step interview patches the markdown, then delegates to generate

Key design decisions

  • template in frontmatter is authoritative — The path stored in template: inside the markdown frontmatter is the only reference to the source PPTX. All three skills resolve the template from this field; there is no separate configuration file.
  • Placeholder identity = python-pptx idx — Placeholders are identified by their integer idx as returned by python-pptx, not by position or name. This makes re-ordering slides safe and ensures stable round-trips.
  • No image rendering — All content is inserted as native python-pptx objects (text frames, tables, charts). The PPTX output is fully editable in PowerPoint / LibreOffice Impress.
  • PNG preview is optional — LibreOffice headless provides visual previews in the revise-ppt workflow. The skill degrades gracefully to a plain-text slide summary when LibreOffice is absent.
  • Markdown is lossless — A parse → edit → generate round-trip produces a PPTX that faithfully reproduces the template layout. Re-parsing the generated PPTX would yield an equivalent markdown.
  • Preserved passthrough — Slide transitions, animations, speaker notes, and master slide properties are not modeled in markdown and are not destroyed; they survive the parse → generate roundtrip unchanged.

Placeholder ontology: template contract vs. spatial layout

Each placeholder annotation encodes two distinct concerns:

Concern Attribute Description
Template contract type:TYPE What a placeholder demands — the kind of content it accepts (title, body, picture, chart, etc.). This is the binding contract between markdown and the PPTX template.
Spatial layout pos:(x,y) size:WxH Where the placeholder lives on the slide. Informational metadata only; never used to reposition content.

generate-ppt only reads ph:idx and type:; the pos: and size: values from parse-ppt-template output are silently carried through and ignored during generation. They serve as documentation for the human editor.

Verifiable output artifacts

Each pipeline stage produces a verifiable artifact:

Stage Artifact Validation
parse *.md file YAML frontmatter template field present; <!-- ph:idx --> comments match template placeholder count
generate *.pptx file python-pptx can open the file; slide count matches markdown --- separator count
revise updated *.md + *.pptx Revision comments resolved or annotated; PPTX timestamp newer than original

Skills Reference

/parse-ppt-template

Parse a PPTX template file and generate a markdown template with placeholder annotations. Placeholders are identified by python-pptx idx-based indexing and annotated with <!-- ph:idx type:TYPE --> HTML comments.

Usage:

/parse-ppt-template <pptx_file> [--output <output.md>] [--lang ko|en] [--layouts-only]

Executed via: python skills/parse-ppt-template/parse_template.py

Arguments:

Argument Required Default Description
pptx_file Path to the PPTX template file
--output, -o <input>.md Output path for the generated markdown template
--lang, -l $LANG or en Language for guide comments in the output (ko | en)
--layouts-only false Generate one section per layout definition instead of per slide

Returns: A markdown file written to --output.

Exit code Meaning
0 Success — markdown written and all verification checks passed
1 Input/IO error (file not found, missing dependency, etc.)
2 Verification failure — markdown was written but failed structural invariant checks

Success markers (machine-checkable):

[agent4ppt] Markdown template written → <path>
[agent4ppt] Verification passed ✓  (N section(s), template_path confirmed, idx annotations present)

Output format:

The generated markdown file contains:

  • YAML frontmattertemplate, fname, title, subTitle, date, author, lang fields
  • Slide sections separated by ---
  • Layout indicator > layout: N at the top of each slide section
  • Layout name comment <!-- layout_name: NAME --> (informational)
  • Placeholder annotations <!-- ph:idx type:TYPE pos:(x,y) size:WxH --> with spatial metadata
  • Guide comments <!-- Enter the ... --> (in the selected language) explaining each placeholder
  • Content placeholders with example content ready to fill

Placeholder type values:

Type python-pptx placeholder kind
title Title
center_title Center Title
subtitle Subtitle
body Body
object Object (generic)
picture Picture
table Table
chart Chart / diagram
media Media clip
ftr Footer
dt Date
sldnum Slide number

Examples:

# Basic — output written to same directory as template
/parse-ppt-template "GIST NetAI PPT Theme.pptx"

# Specify output path and Korean guide comments
/parse-ppt-template "GIST NetAI PPT Theme.pptx" --output slides_template.md --lang ko

# One section per layout (for templates with no slide content)
/parse-ppt-template my_template.pptx --layouts-only --output layouts.md

Example output:

---
template: ./GIST NetAI PPT Theme.pptx
fname: output.pptx
title: ""
subTitle: ""
date: ""
author: ""
lang: en
---

> layout: 0
<!-- layout_name: Title Slide -->

<!-- ph:0 type:center_title pos:(0.9167",1.75") size:7.6548"×0.7547" -->
<!-- Enter the centered slide title -->
# Slide Title

<!-- ph:1 type:subtitle pos:(0.9167",2.6495") size:5.588"×0.8832" -->
<!-- Enter the subtitle -->
Subtitle text here

---

> layout: 1

<!-- ph:0 type:title pos:(0.4583",0.25") size:8.5"×1.2" -->
<!-- Enter the slide title -->
# Section Header

<!-- ph:1 type:body pos:(0.4583",1.5") size:8.5"×4.5" -->
<!-- Enter the main body content. Supports bullets, bold, italic. -->
- Bullet one
- Bullet two

Error handling:

Condition Behaviour
pptx_file not found Exits 1, prints error to stderr
File has no .pptx extension Warning printed, continues
Missing dependency (python-pptx, pyyaml) Exits 1, prints install instructions
PPTX file is corrupt or unreadable Exits 1, prints error to stderr
Structural verification fails after writing Exits 2, prints failure details to stderr

/generate-ppt

Generate an editable PPTX file from a markdown file. Reads the PPTX template path from the markdown frontmatter, maps each <!-- ph:idx --> block to the corresponding placeholder, and converts markdown tables, chart YAML blocks, and images to native python-pptx objects.

Usage:

/generate-ppt <markdown_file> [--output <output.pptx>] [--lang ko|en] [--dry-run]

Executed via: python skills/generate-ppt/generate_ppt.py

Arguments:

Argument Required Default Description
markdown_file Path to the markdown content file
--output, -o frontmatter.fname or <input>.pptx Output PPTX file path
--lang, -l $LANG or en Language for warning/info messages (ko | en)
--dry-run false Validate inputs and build slides in memory without writing the PPTX file

Returns: A PPTX file at the output path. Exit code 0 on success, 1 on error.

Success marker (machine-checkable):

[agent4ppt] PPTX generated → <path>

Frontmatter fields:

Field Required Description
template Relative or absolute path to the PPTX template
fname Default output filename (e.g. output.pptx)
title Presentation title (metadata)
subTitle Presentation subtitle (metadata)
date Presentation date string
author Author name
lang Language override (en or ko). Takes precedence over $LANG and --lang.

Slide section structure:

> layout: N               ← layout index (0-based), required

<!-- ph:0 type:title -->  ← placeholder annotation (idx=0, type=title)
# My Slide Title          ← content for this placeholder

<!-- ph:1 type:body -->
- Bullet one
- Bullet two
- **Bold text** and *italic*

Supported content types:

Type Syntax Notes
Plain text Any text Written as-is
Headings # Title, ## Sub Leading # stripped for title/subtitle placeholders
Bullet list - item or * item Up to 9 indent levels
Numbered list 1. item Treated as bullets
Bold **text** run.font.bold = True
Italic *text* run.font.italic = True
Link [text](url) Underlined text; hyperlink relationship not inserted
Image ![alt](path/to/image.png) For picture or object placeholders
Table GFM markdown table First row becomes bold header
Chart ```chart YAML block Bar, column, line, pie charts
Multi-column ||| separator Splits content; first column fills the placeholder

Chart block syntax:

<!-- ph:2 type:chart -->
```chart
type: bar          # bar | column | line | pie
title: My Chart
categories: [Q1, Q2, Q3, Q4]
series:
  - name: Revenue
    values: [100, 150, 120, 200]
  - name: Expenses
    values: [80, 90, 100, 110]
```

Examples:

# Generate PPTX — output filename comes from frontmatter fname field
/generate-ppt slides.md

# Override output path
/generate-ppt slides.md --output final_presentation.pptx

# Korean messages
/generate-ppt slides.md --lang ko

# Dry-run: validate markdown structure without writing a PPTX file
/generate-ppt slides.md --dry-run

Full markdown example:

---
template: ./GIST NetAI PPT Theme.pptx
fname: my_presentation.pptx
title: "Research Overview"
subTitle: "GIST NetAI Lab"
date: "2026-03-22"
author: "Jinwang Mok"
lang: en
---

> layout: 0

<!-- ph:0 type:title -->
# Research Overview

<!-- ph:1 type:subtitle -->
GIST NetAI Lab · 2026

---

> layout: 2

<!-- ph:0 type:title -->
# Benchmark Results

<!-- ph:1 type:table -->
| Model | Accuracy | Latency (ms) |
|-------|----------|--------------|
| Ours  | 94.2%    | 12           |
| Base  | 88.7%    | 15           |

---

> layout: 3

<!-- ph:0 type:title -->
# Training Loss

<!-- ph:1 type:chart -->
```chart
type: line
title: Training Loss
categories: [Epoch 1, Epoch 2, Epoch 3, Epoch 4, Epoch 5]
series:
  - name: Train
    values: [1.8, 1.2, 0.9, 0.7, 0.6]
  - name: Val
    values: [2.0, 1.5, 1.1, 0.9, 0.8]

**Error handling:**

| Condition | Behaviour |
|-----------|-----------|
| `markdown_file` not found | Exits 1, prints error to stderr |
| `template` frontmatter field missing | Exits 1, prints error to stderr |
| Template PPTX file not found | Exits 1, prints error to stderr |
| Layout index out of range | Warning printed, uses layout 0 |
| Placeholder `idx` not found in slide | Warning printed, placeholder skipped |
| Image file not found | Warning printed, placeholder left empty |
| Invalid chart YAML | Warning printed, placeholder left empty |
| Body placeholder not in layout | Warning printed, content inserted via textbox/image fallback |
| Missing dependencies | Exits 1, prints install instructions |

---

### /revise-ppt

Interactively revise an existing presentation through a **3-step interview workflow**: select target slides, describe changes per slide, apply edits to the markdown source and regenerate the PPTX. Optionally renders PNG slide previews via LibreOffice headless; falls back to markdown text when LibreOffice is unavailable.

**Usage:**

/revise-ppt <markdown_file> [--pptx <pptx_file>] [--output <output.pptx>] [--lang ko|en]


Executed via: `python skills/revise-ppt/revise_ppt.py`

**Arguments:**

| Argument | Required | Default | Description |
|----------|----------|---------|-------------|
| `markdown_file` | ✅ | — | Path to the markdown source file to revise (the single source of truth) |
| `--pptx` | ❌ | derived from `frontmatter.fname` | Path to the existing PPTX file used for PNG preview generation |
| `--output`, `-o` | ❌ | `frontmatter.fname` or `<markdown>.pptx` | Output path for the regenerated PPTX |
| `--lang`, `-l` | ❌ | `$LANG` or `en` | Language for interview prompts (`ko` \| `en`) |

**Returns:** The `markdown_file` is **updated in place**. A new PPTX is generated by delegating to `generate-ppt`. Exit code `0` on success, `1` on error.

**Success markers:**

[agent4ppt] PPTX generated → ← emitted by the generate-ppt subprocess Revision complete! Updated file: ← emitted by revise-ppt


**Workflow — 3 steps:**

**Step 1 — Select target slides**

=== Slide Revision Workflow === Your presentation has 8 slide(s).

STEP 1: Which slides would you like to revise? Enter slide numbers separated by commas (e.g. 1,3,5), a range (e.g. 2-4), or 'all':

2,4-6


**Selection syntax:**

| Input | Meaning |
|-------|---------|
| `1,3,5` | Slides 1, 3, and 5 |
| `2-4` | Slides 2, 3, and 4 |
| `2~4` | Same as `2-4` |
| `all` | All slides |
| `*` | All slides |
| `모두` | All slides (Korean alias) |

**Step 2 — Describe changes per slide**

STEP 2: Let's go through each selected slide.

--- Slide 2 (layout: 1) --- Slide 2 preview: /path/to/my_presentation_previews/slide_2.png

Describe your changes. Examples:

  • Change title to 'New Title'
  • Replace bullet 2 with 'Updated content'
  • Change layout to layout 3
  • Replace chart with new data
  • Add image path/to/image.png Your instructions for slide 2:

Change title to 'Updated Results'


**Supported instruction patterns (applied automatically):**

| Pattern | Example | Effect |
|---------|---------|--------|
| Change title | `Change title to 'New Title'` | Replaces title placeholder heading |
| Change layout | `Change layout to 3` | Updates `> layout: N` in the section |
| Free-form | Any other text | Appended as `<!-- REVISION: ... -->` comment for manual review |

**Step 3 — Apply and regenerate**

STEP 3: Applying changes and regenerating PPTX... Applying changes to slide 2... Applying changes to slide 4... Regenerating PPTX... [agent4ppt] PPTX generated → ./my_presentation.pptx

Revision complete! Updated file: ./my_presentation.pptx Markdown updated: ./slides.md PPTX regenerated: ./my_presentation.pptx


**Revision state tracking:**

A JSON state file `<markdown_stem>_revision_state.json` is created after Step 1 and updated after Step 3:

```json
{
  "markdown_path": "/absolute/path/to/slides.md",
  "pptx_path": "/absolute/path/to/output.pptx",
  "iteration_count": 1
}
  • iteration_count increments after each successful revision cycle
  • State persists across multiple invocations for resumable multi-round editing
  • File path is deterministic: <markdown_stem>_revision_state.json in the same directory as the markdown file

PNG preview:

When LibreOffice is installed, slide previews are generated to a deterministic directory (<pptx_stem>_previews/) next to the PPTX file — verifiable without prior knowledge of temporary directory names:

libreoffice --headless --convert-to png --outdir <pptx_stem>_previews/ presentation.pptx

If LibreOffice is not found, a plain-text .txt file is written to the same deterministic path with a text summary of the slide's placeholder content. The revise-ppt skill works fully without LibreOffice — only the visual preview is affected.

Install LibreOffice:

# Ubuntu / Debian
sudo apt install libreoffice

# macOS (Homebrew)
brew install --cask libreoffice

Examples:

# Standard interactive revision (auto-detects PPTX from frontmatter fname)
/revise-ppt slides.md

# Provide PPTX path explicitly for PNG preview generation
/revise-ppt slides.md --pptx final_presentation.pptx

# Specify explicit output PPTX path
/revise-ppt slides.md --output revised_v2.pptx

# Korean prompts
/revise-ppt slides.md --lang ko

Error handling:

Condition Behaviour
markdown_file not found Exits 1, prints error to stderr
No slides selected Exits 0, prints advisory message
LibreOffice not found Warning printed, falls back to text preview
generate-ppt subprocess fails Stderr from subprocess printed, exits 1
KeyboardInterrupt (Ctrl-C) Exits 0 with [agent4ppt] Cancelled.
Missing dependencies Exits 1, prints install instructions

Markdown Format

The markdown file is the canonical document — not a serialization or export format. All content edits are made in markdown; the PPTX is always regenerated from it. The template: field in YAML frontmatter is the sole authoritative reference to the source PPTX; no secondary path or configuration file exists.

YAML Frontmatter

Every markdown file must begin with YAML frontmatter delimited by ---:

Field Required Description
template Path to the source PPTX template. Relative paths are resolved from the markdown file's directory. This is the sole authoritative reference to the source PPTX — no secondary path exists.
fname Default output PPTX filename (e.g. output.pptx). Overridden by --output.
title Presentation title (written to PPTX metadata)
subTitle Presentation subtitle
date Date string
author Author name
lang Language override (en or ko). Takes precedence over $LANG and --lang.

Slide Sections

After the frontmatter, slides are separated by ---. Each slide section begins with a layout reference (> layout: N, 0-based), followed by one or more placeholder blocks:

> layout: 1
<!-- layout_name: Content Slide -->

<!-- ph:0 type:title pos:(0.46",0.25") size:8.5"×1.2" -->
# Slide Title

<!-- ph:1 type:body pos:(0.46",1.5") size:8.5"×4.5" -->
- First bullet point
- Second bullet point
  - Nested bullet
- **Bold text** and *italic*

Placeholder annotation fields:

Field Meaning
ph:N python-pptx placeholder index (idx), 0-based integer
type:TYPE Template contract — the kind of content the placeholder accepts
pos:(x,y) Spatial layout — horizontal and vertical position (informational)
size:WxH Spatial layout — width and height (informational)

Template Contract vs. Spatial Layout

Each placeholder annotation encodes two distinct concerns in a single line:

Concern Attribute Role
Template contract type:TYPE What content the placeholder accepts. This is the binding semantic contract; it determines which markdown syntax is valid (title/body/picture/chart/table/…).
Spatial layout pos: and size: Where the placeholder lives on the slide. Informational metadata preserved passthrough; generate-ppt does not use these values for positioning.

Complete Example

Below is a complete example showing all supported content types:

---
template: ./my_template.pptx
fname: output.pptx
title: "My Presentation"
subTitle: "2026 Annual Report"
date: "2026-03-22"
author: "Jinwang Mok"
lang: en
---

> layout: 0

<!-- ph:0 type:title -->
# My Presentation

<!-- ph:1 type:body -->
Welcome to the annual report.

---

> layout: 2

<!-- ph:0 type:title -->
# Sales Data

<!-- ph:1 type:table -->
| Quarter | Revenue | Growth |
|---------|---------|--------|
| Q1      | $1.2M   | +12%   |
| Q2      | $1.5M   | +25%   |
| Q3      | $1.3M   | +8%    |
| Q4      | $1.8M   | +38%   |

<!-- ph:2 type:chart -->
```chart
type: bar
title: Quarterly Revenue
categories: [Q1, Q2, Q3, Q4]
series:
  - name: Revenue (M$)
    values: [1.2, 1.5, 1.3, 1.8]

layout: 3

Team Photo

Team photo


layout: 4

Left column content

  • Item A
  • Item B

|||

Right column content

  • Item C
  • Item D

### Placeholder Types

| `type` | Description |
|--------|-------------|
| `title` | Slide title text box |
| `body` | Main content area (bullets, text) |
| `picture` | Image placeholder |
| `chart` | Chart placeholder |
| `table` | Table placeholder |
| `object` | Generic object / multi-content area |

---

## Language Support

Set the output language for guide comments and prompts:

```bash
# Via environment variable
export LANG=ko   # Korean
export LANG=en   # English (default)

# Via command-line flag
/parse-ppt-template template.pptx --lang ko
/revise-ppt slides.md --lang en

Language priority: --lang flag > $LANG environment variable > en (default)


Dependencies

Python Packages

pip install python-pptx pyyaml markdown-it-py
# or use the bundled installer:
bash scripts/install.sh

Optional: LibreOffice (for PNG preview)

LibreOffice is required only for the PNG slide preview feature in /revise-ppt. Without it, the skill gracefully falls back to markdown text display.

Platform Install Command
Ubuntu/Debian sudo apt install libreoffice
macOS (Homebrew) brew install --cask libreoffice
Windows Download from libreoffice.org

Complete End-to-End Example

# 1. Parse the PPTX template into a markdown template
/parse-ppt-template "GIST NetAI PPT Theme.pptx" --output my_talk.md

# 2. Edit my_talk.md — fill in slide content, add tables/charts/images
#    (use your editor or ask Claude to fill in the content)

# 3. Generate the PPTX from the markdown
/generate-ppt my_talk.md

# 4. Review the result and interactively revise if needed
/revise-ppt my_talk.md

Output Artifact Verification

Each skill emits a machine-readable success marker and exits with code 0. You can verify the pipeline non-interactively:

# Verify parse-ppt-template output
python skills/parse-ppt-template/parse_template.py template.pptx --output out.md
echo "Exit: $?"          # 0=success+verified, 2=written but verification failed
grep -q "^template:" out.md && echo "PASS: frontmatter present"
grep -qP "ph:\d+ type:\w+" out.md && echo "PASS: placeholders found"

# Verify generate-ppt output
python skills/generate-ppt/generate_ppt.py out.md --output out.pptx
echo "Exit: $?"          # Must be 0
python -c "from pptx import Presentation; p=Presentation('out.pptx'); print('PASS: slides =', len(p.slides))"

# Verify roundtrip fidelity
python -c "
from pptx import Presentation
p = Presentation('out.pptx')
slides_pptx = len(p.slides)
import re
md = open('out.md').read()
body = md.split('---\n', 2)[-1]
slides_md = len(re.split(r'\n---\s*\n', body.strip()))
assert slides_pptx == slides_md, f'Mismatch: pptx={slides_pptx} md={slides_md}'
print('PASS: slide count matches')
"

# Verify revision state (after running /revise-ppt)
python -c "
import json
state = json.load(open('out_revision_state.json'))
assert 'markdown_path' in state
assert 'iteration_count' in state
print('PASS: revision state valid, iteration_count =', state['iteration_count'])
"

Environment Variables

Variable Description
LANG POSIX locale string used to auto-detect output language (e.g. ko_KR.UTF-8 → Korean). Standard system variable; no need to set explicitly on Korean-locale systems.

Contributing

Contributions are welcome! agent4ppt is an open-source project and your improvements, bug reports, and ideas help make it better for everyone.

How to Contribute

  1. Fork the repository on GitHub
  2. Clone your fork locally:
    git clone https://github.com/<your-username>/agent4ppt.git
    cd agent4ppt
  3. Create a branch for your change:
    git checkout -b feature/my-improvement
  4. Install dependencies and run the test suite to confirm everything passes:
    bash scripts/install.sh
    pytest
  5. Make your changes — add tests for any new functionality
  6. Verify tests still pass:
    pytest --tb=short
  7. Commit with a clear, descriptive message
  8. Push your branch and open a Pull Request against main

Contribution Guidelines

Area Guideline
Code style Follow PEP 8. Use type hints for public functions.
Tests All new features must include pytest tests under tests/. Maintain ≥ 80 % coverage for changed modules.
No image rendering All PPTX content must be inserted via python-pptx native objects. Image-based rendering PRs will not be merged.
Bilingual docs Any user-facing string additions must include both English (en) and Korean (ko) variants in the i18n dictionaries.
Markdown as source of truth Changes to the markdown schema must be backward-compatible, or include a migration note.
Dependencies New runtime dependencies require a strong justification. Dev-only dependencies are fine.

Reporting Issues

Please open a GitHub Issue and include:

  • OS and Python version (python3 --version)
  • agent4ppt version (see plugin.json)
  • The exact command you ran
  • Full error output (stdout + stderr)
  • Minimal reproducible example (the PPTX template or markdown file if possible)

Development Setup

# Clone and enter the repository
git clone https://github.com/JinwangMok/agent4ppt.git
cd agent4ppt

# Install runtime dependencies
bash scripts/install.sh

# Install dev extras (pytest, coverage)
pip install pytest pytest-cov

# Run all tests
pytest

# Run with coverage report
pytest --cov=agent4ppt --cov=skills --cov-report=term-missing

Code of Conduct

This project follows a simple rule: be respectful and constructive. Harassment or discriminatory language in any form will not be tolerated.


License

MIT License — Copyright (c) 2026 Jinwang Mok

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

See the full license text in LICENSE.


agent4ppt 中文文档

English | 한국어 | 中文

agent4ppt 是一个 Claude Code 插件,可将 PPTX 模板解析为 Markdown 模板,从 Markdown 生成可编辑的 PPTX 文件,并支持交互式幻灯片修订——无需基于图像的渲染。Markdown 是唯一的数据来源(Single Source of Truth)。


目录


功能

  • 模板解析 — 读取 PPTX 模板,输出带有占位符注释(<!-- ph:idx type:TYPE -->)的结构化 Markdown 文件
  • PPTX 生成 — 将 Markdown 转换回 PPTX,忠实还原模板的视觉布局
  • 交互式修订 — 3步问答工作流,用于修订特定幻灯片并重新生成 PPTX
  • 丰富内容支持 — 表格、图表(条形图/饼图/折线图)、图片、多列布局
  • 双语输出 — 通过 LANG 环境变量支持韩语(ko)和英语(en)指南注释
  • 100% 可编辑 — 所有内容均以原生 python-pptx 对象插入(无图像渲染)

安装

Claude Code(插件市场)

使用两行命令安装 agent4ppt:

claude plugin marketplace add JinwangMok/agent4ppt
claude plugin install agent4ppt

安装程序自动运行 scripts/install.sh,检查 Python ≥ 3.10,安装三个必需包,并提示可选的 LibreOffice 依赖。

安装后,三个技能(/parse-ppt-template/generate-ppt/revise-ppt)可在 Claude Code 会话中直接使用。

OpenClaw(Agent Skills 标准)

agent4ppt 遵循 Agent Skills 标准SKILL.md 格式),兼容 OpenClaw 及其他 Agent Skills 兼容运行时。

# 克隆仓库
git clone https://github.com/JinwangMok/agent4ppt.git
cd agent4ppt

# 安装依赖
bash scripts/install.sh

OpenClaw 通过仓库根目录的 SKILL.md 自动发现技能。要注册到 OpenClaw,指向克隆的目录或将仓库 URL 添加到 OpenClaw 技能源。

Codex CLI

agent4ppt 也兼容 Codex CLI。克隆并安装依赖后:

git clone https://github.com/JinwangMok/agent4ppt.git
cd agent4ppt
bash scripts/install.sh

# 通过 Python 直接运行技能
python skills/parse-ppt-template/parse_template.py template.pptx --output slides.md
python skills/generate-ppt/generate_ppt.py slides.md --output output.pptx
python skills/revise-ppt/revise_ppt.py slides.md

手动安装

如果不使用任何代理运行时:

git clone https://github.com/JinwangMok/agent4ppt.git
cd agent4ppt
pip install python-pptx pyyaml markdown-it-py

系统要求

依赖项 版本 用途
Python ≥ 3.10 运行环境
python-pptx ≥ 0.6.21 PPTX 读写
pyyaml ≥ 6.0 Frontmatter 解析
markdown-it-py ≥ 3.0 Markdown 解析
LibreOffice 任意版本 PNG 幻灯片预览 (可选)

快速开始

1. 将 PPTX 模板解析为 Markdown

/parse-ppt-template my_template.pptx
# → 生成 my_template.md

2. 编辑 Markdown 文件

打开 my_template.md,在占位符注释之间填写内容。

3. 从 Markdown 生成 PPTX

/generate-ppt my_template.md
# → 生成 output.pptx(或 frontmatter 中的 fname 值)

4. 交互式修订幻灯片

/revise-ppt my_template.md

流水线架构

agent4ppt 基于 Markdown 优先的流水线。Markdown 文件是单一数据来源;PPTX 模板仅在 YAML frontmatter 的 template 字段中被引用一次,且从不被修改。

┌─────────────────────────────────────────────────────────────────┐
│                     agent4ppt 流水线                             │
│                                                                 │
│  PPTX 模板                                                       │
│  (只读)                                                         │
│       │                                                         │
│       ▼  /parse-ppt-template                                    │
│  Markdown 模板 ─────────────────────────────────────────────►    │
│  (YAML frontmatter + 幻灯片节 + <!-- ph:idx --> 注释)            │
│       │                                                         │
│       │  (用户填写内容)                                          │
│       ▼                                                         │
│  Markdown 内容文件                                               │
│       │                  ┌──────────────────────────────────┐   │
│       ├── /generate-ppt ─►  PPTX 输出                         │   │
│       │                  │  (使用 frontmatter 中的模板)       │   │
│       │                  └──────────────────────────────────┘   │
│       │                                                         │
│       └── /revise-ppt ──► (3步问答)                             │
│                               │                                 │
│                               ├── 就地修改 Markdown              │
│                               └── 调用 /generate-ppt            │
└─────────────────────────────────────────────────────────────────┘

数据流

阶段 输入 输出 核心操作
解析 *.pptx 模板 <!-- ph:idx type:TYPE -->*.md python-pptx 读取幻灯片布局;基于 idx 的占位符映射写入 Markdown
生成 *.md 内容文件 *.pptx 演示文稿 Frontmatter template 字段解析源 PPTX;每个 ph:idx 块写入匹配的占位符
修订 *.md 内容文件 更新后的 *.md + *.pptx 3步问答修补 Markdown,然后委托生成

关键设计决策

  • frontmatter 中的 template 是权威来源template: 字段中存储的路径是源 PPTX 的唯一引用。三个技能都从此字段解析模板;没有单独的配置文件。
  • 占位符标识 = python-pptx idx — 占位符通过 python-pptx 返回的整数 idx 标识,而非位置或名称。这使幻灯片重排安全,并确保稳定的往返转换。
  • 无图像渲染 — 所有内容均以原生 python-pptx 对象插入(文本框、表格、图表)。PPTX 输出在 PowerPoint / LibreOffice Impress 中完全可编辑。
  • PNG 预览为可选 — LibreOffice headless 在 revise-ppt 工作流中提供视觉预览。当 LibreOffice 不可用时,技能会优雅地降级为纯文本幻灯片摘要。
  • Markdown 无损解析 → 编辑 → 生成 往返转换生成的 PPTX 忠实再现模板布局。

可验证的输出工件

每个流水线阶段均产生可验证的工件:

阶段 工件 验证方法
解析 *.md 文件 YAML frontmatter 含 template: 字段;<!-- ph:idx --> 注释数与模板占位符数匹配
生成 *.pptx 文件 python-pptx 可打开文件;幻灯片数与 Markdown --- 分隔符数匹配
修订 更新的 *.md + *.pptx 修订注释已解决或已标注;PPTX 时间戳比原始更新

技能参考

/parse-ppt-template

解析 PPTX 模板文件,生成带有占位符注释的 Markdown 模板。占位符由 python-pptx idx 索引标识,并以 <!-- ph:idx type:TYPE --> HTML 注释标注。

用法:

/parse-ppt-template <pptx文件> [--output <输出.md>] [--lang ko|en] [--layouts-only]

执行方式:python skills/parse-ppt-template/parse_template.py

参数:

参数 必填 默认值 说明
pptx文件 PPTX 模板文件路径
--output-o <输入文件名>.md 生成的 Markdown 模板输出路径
--lang-l $LANGen 输出指南注释语言(ko | en
--layouts-only false 按布局定义而非按幻灯片生成各节

返回值:

将 Markdown 文件写入 --output。成功时退出码为 0,失败时为 1

成功标记(机器可检测):

[agent4ppt] Markdown template written → <路径>

占位符类型值:

类型 python-pptx 占位符类型
title 标题(Title)
center_title 居中标题(Center Title)
subtitle 副标题(Subtitle)
body 正文(Body)
object 通用对象(Object)
picture 图片(Picture)
table 表格(Table)
chart 图表(Chart)
media 媒体剪辑(Media clip)
ftr 页脚(Footer)
dt 日期(Date)
sldnum 幻灯片编号(Slide number)

示例:

# 基本用法
/parse-ppt-template "GIST NetAI PPT Theme.pptx"

# 指定输出路径和韩语指南注释
/parse-ppt-template "GIST NetAI PPT Theme.pptx" --output slides_template.md --lang ko

# 按布局生成各节(适用于无内容的模板)
/parse-ppt-template my_template.pptx --layouts-only --output layouts.md

输出示例:

---
template: ./GIST NetAI PPT Theme.pptx
fname: output.pptx
title: ""
subTitle: ""
date: ""
author: ""
lang: en
---

> layout: 0

<!-- ph:0 type:title -->
# 幻灯片标题

<!-- ph:1 type:body -->
在此输入内容

---

> layout: 1

<!-- ph:0 type:center_title -->
# 节标题

<!-- ph:1 type:subtitle -->
节副标题文字

错误处理:

条件 行为
找不到 pptx文件 退出码 1,输出错误信息
文件无 .pptx 扩展名 输出警告,继续执行
缺少依赖项(python-pptxpyyaml 退出码 1,输出安装说明

/generate-ppt

从 Markdown 文件生成可编辑的 PPTX 文件。从 Markdown frontmatter 中读取 PPTX 模板路径,将每个 <!-- ph:idx --> 块映射到相应的占位符,并将 Markdown 表格、图表 YAML 块和图片转换为原生 python-pptx 对象。

用法:

/generate-ppt <markdown文件> [--output <输出.pptx>] [--lang ko|en]

执行方式:python skills/generate-ppt/generate_ppt.py

参数:

参数 必填 默认值 说明
markdown文件 Markdown 内容文件路径
--output-o frontmatter.fname<输入>.pptx 输出 PPTX 文件路径
--lang-l $LANGen 警告/信息消息语言(ko | en

返回值:

在指定输出路径生成 PPTX 文件。成功时退出码为 0,失败时为 1

成功标记(机器可检测):

[agent4ppt] PPTX generated → <路径>

Frontmatter 字段:

字段 必填 说明
template PPTX 模板的相对或绝对路径。相对路径基于 Markdown 文件的目录解析。
fname 默认输出文件名(例如 output.pptx),可通过 --output 覆盖
title 演示文稿标题(元数据)
subTitle 演示文稿副标题(元数据)
date 演示文稿日期字符串
author 作者姓名
lang 语言覆盖(enko),优先级高于 $LANG--lang

幻灯片节结构:

> layout: N               ← 布局索引(从 0 开始),必填

<!-- ph:0 type:title -->  ← 占位符注释(idx=0, type=title)
# 我的幻灯片标题          ← 此占位符的内容

<!-- ph:1 type:body -->
- 项目一
- 项目二
- **加粗文本***斜体*

支持的内容类型:

类型 语法 备注
纯文本 任意文本 原样写入
标题 # 标题## 副标题 title/subtitle 占位符中去掉前导 #
项目符号列表 - 项目* 项目 最多 9 级缩进
编号列表 1. 项目 作为项目符号处理
加粗 **文本** run.font.bold = True
斜体 *文本* run.font.italic = True
链接 [文本](url) 下划线文本;不插入超链接关系
图片 ![替代文本](路径/image.png) 用于 pictureobject 占位符
表格 GFM Markdown 表格 第一行为粗体标题
图表 ```chart YAML 块 条形图、柱形图、折线图、饼图
多列 ||| 分隔符 拆分内容;第一列填充占位符

图表块语法:

<!-- ph:2 type:chart -->
```chart
type: bar          # bar | column | line | pie
title: 我的图表
categories: [Q1, Q2, Q3, Q4]
series:
  - name: 收入
    values: [100, 150, 120, 200]
  - name: 支出
    values: [80, 90, 100, 110]
```

示例:

# 生成 PPTX——输出文件名来自 frontmatter fname 字段
/generate-ppt slides.md

# 覆盖输出路径
/generate-ppt slides.md --output final_presentation.pptx

# 使用中文/英语消息
/generate-ppt slides.md --lang en

完整 Markdown 示例:

---
template: ./GIST NetAI PPT Theme.pptx
fname: my_presentation.pptx
title: "研究概述"
subTitle: "GIST NetAI 实验室"
date: "2026-03-22"
author: "Jinwang Mok"
lang: en
---

> layout: 0

<!-- ph:0 type:title -->
# 研究概述

<!-- ph:1 type:subtitle -->
GIST NetAI 实验室 · 2026

---

> layout: 2

<!-- ph:0 type:title -->
# 基准测试结果

<!-- ph:1 type:table -->
| 模型 | 准确率 | 延迟 (ms) |
|------|--------|-----------|
| 我们 | 94.2%  | 12        |
| 基线 | 88.7%  | 15        |

---

> layout: 3

<!-- ph:0 type:title -->
# 训练损失

<!-- ph:1 type:chart -->
```chart
type: line
title: 训练损失
categories: [Epoch 1, Epoch 2, Epoch 3, Epoch 4, Epoch 5]
series:
  - name: 训练集
    values: [1.8, 1.2, 0.9, 0.7, 0.6]
  - name: 验证集
    values: [2.0, 1.5, 1.1, 0.9, 0.8]

**错误处理:**

| 条件 | 行为 |
|------|------|
| 找不到 `markdown文件` | 退出码 1,输出错误信息 |
| frontmatter 中缺少 `template` 字段 | 退出码 1,输出错误信息 |
| 找不到模板 PPTX 文件 | 退出码 1,输出错误信息 |
| 布局索引超出范围 | 输出警告,使用布局 0 |
| 幻灯片中找不到占位符 `idx` | 输出警告,跳过该占位符 |
| 找不到图片文件 | 输出警告,占位符留空 |
| 无效的图表 YAML | 输出警告,占位符留空 |
| 缺少依赖项 | 退出码 1,输出安装说明 |

---

### /revise-ppt

通过 **3步问答工作流**交互式修订现有演示文稿:选择目标幻灯片 → 逐幻灯片描述修改 → 应用编辑到 Markdown 源文件并重新生成 PPTX。可通过 LibreOffice headless 渲染 PNG 幻灯片预览;若 LibreOffice 不可用,则回退到 Markdown 文本显示。

**用法:**

/revise-ppt <markdown文件> [--pptx <pptx文件>] [--output <输出.pptx>] [--lang ko|en]


执行方式:`python skills/revise-ppt/revise_ppt.py`

**参数:**

| 参数 | 必填 | 默认值 | 说明 |
|------|------|--------|------|
| `markdown文件` | ✅ | — | 要修订的 Markdown 源文件路径(唯一数据来源) |
| `--pptx` | ❌ | 从 `frontmatter.fname` 自动派生 | 用于 PNG 预览生成的现有 PPTX 文件路径 |
| `--output`,`-o` | ❌ | `frontmatter.fname` 或 `<markdown>.pptx` | 重新生成的 PPTX 输出路径 |
| `--lang`,`-l` | ❌ | `$LANG` 或 `en` | 问答提示语言(`ko` \| `en`) |

**返回值:**

`markdown文件`**就地更新**。新 PPTX 通过委托 `generate-ppt` 生成。成功时退出码为 `0`,失败时为 `1`。

**成功标记:**

[agent4ppt] PPTX generated → <路径> Revision complete! Updated file: <路径>


**工作流——3 步:**

**第1步 — 选择目标幻灯片**

=== 幻灯片修订工作流 === 您的演示文稿共有 8 张幻灯片。

第1步:您要修订哪些幻灯片? 请输入幻灯片编号,以逗号分隔(例如 1,3,5),范围表示(例如 2-4),或输入 'all':

2,4-6


**幻灯片选择语法:**

| 输入 | 含义 |
|------|------|
| `1,3,5` | 第 1、3、5 张幻灯片 |
| `2-4` | 第 2、3、4 张幻灯片 |
| `2~4` | 同 `2-4` |
| `all` | 所有幻灯片 |
| `*` | 所有幻灯片 |

**第2步 — 逐幻灯片描述修改**

第2步:逐一处理选中的幻灯片。

--- 幻灯片 2(布局:1)--- [预览 PNG: /tmp/agent4ppt_preview_xyz/slides2.png]

请描述您的修改。示例:

  • 将标题改为"新标题"
  • 将第 2 个项目符号替换为"更新的内容"
  • 将布局改为布局 3
  • 用新数据替换图表
  • 添加图片 路径/to/image.png 幻灯片 2 的修改说明:

将标题改为"更新的结果"


**支持的修改模式(自动应用):**

| 模式 | 示例 | 效果 |
|------|------|------|
| 更改标题 | `将标题改为"新标题"` | 替换标题占位符标题 |
| 更改布局 | `将布局改为 3` | 更新节中的 `> layout: N` |
| 自由格式 | 其他任意文本 | 以 `<!-- REVISION: ... -->` 注释附加,等待人工审查 |

**第3步 — 应用并重新生成**

第3步:正在应用更改并重新生成 PPTX... 正在对幻灯片 2 应用更改... 正在对幻灯片 4 应用更改... 正在重新生成 PPTX... [agent4ppt] PPTX generated → ./my_presentation.pptx 修订完成!更新的文件:./my_presentation.pptx


**PNG 预览:**

LibreOffice 已安装时,使用以下命令生成幻灯片预览:

```bash
libreoffice --headless --convert-to png --outdir /tmp/agent4ppt_preview_<id> presentation.pptx

若未找到 LibreOffice,则显示幻灯片占位符内容的纯文本摘要。revise-ppt 技能无需 LibreOffice 即可完整运行——仅视觉预览功能受影响。

安装 LibreOffice:

# Ubuntu / Debian
sudo apt install libreoffice

# macOS (Homebrew)
brew install --cask libreoffice

示例:

# 标准交互式修订(从 frontmatter fname 自动检测 PPTX)
/revise-ppt slides.md

# 明确提供 PPTX 路径
/revise-ppt slides.md --pptx final_presentation.pptx

# 指定输出路径
/revise-ppt slides.md --output revised_v2.pptx

# 使用英语提示
/revise-ppt slides.md --lang en

错误处理:

条件 行为
找不到 markdown文件 退出码 1,输出错误信息
未选择任何幻灯片 退出码 0,输出提示信息
找不到 LibreOffice 输出警告,回退到文本预览
generate-ppt 子进程失败 输出子进程 stderr,退出码 1
KeyboardInterrupt(Ctrl-C) 输出 [agent4ppt] Cancelled.,退出码 0
缺少依赖项 退出码 1,输出安装说明

Markdown 格式

以下是展示所有支持内容类型的完整示例:

---
template: ./my_template.pptx
fname: output.pptx
title: "我的演示文稿"
subTitle: "2026 年度报告"
date: "2026-03-22"
author: "Jinwang Mok"
lang: en
---

> layout: 0

<!-- ph:0 type:title -->
# 我的演示文稿

<!-- ph:1 type:body -->
欢迎来到年度报告。

---

> layout: 2

<!-- ph:0 type:title -->
# 销售数据

<!-- ph:1 type:table -->
| 季度 | 营收  | 增长率 |
|------|-------|--------|
| Q1   | $1.2M | +12%   |
| Q2   | $1.5M | +25%   |
| Q3   | $1.3M | +8%    |
| Q4   | $1.8M | +38%   |

<!-- ph:2 type:chart -->
```chart
type: bar
title: 季度营收
categories: [Q1, Q2, Q3, Q4]
series:
  - name: 营收(百万美元)
    values: [1.2, 1.5, 1.3, 1.8]

layout: 3

团队照片

团队照片


layout: 4

左列内容

  • 项目 A
  • 项目 B

|||

右列内容

  • 项目 C
  • 项目 D

### 占位符类型

| `type` | 说明 |
|--------|------|
| `title` | 幻灯片标题文本框 |
| `body` | 主要内容区域(项目符号、文本) |
| `picture` | 图片占位符 |
| `chart` | 图表占位符 |
| `table` | 表格占位符 |
| `object` | 通用对象/多内容区域 |

---

## 语言支持

设置指南注释和提示的输出语言:

```bash
# 通过环境变量设置
export LANG=ko   # 韩语
export LANG=en   # 英语(默认)

# 通过命令行标志设置
/parse-ppt-template template.pptx --lang ko
/revise-ppt slides.md --lang en

语言优先级:--lang 标志 > $LANG 环境变量 > en(默认值)


依赖项

Python 包

pip install python-pptx pyyaml markdown-it-py
# 或使用内置安装脚本:
bash scripts/install.sh

可选:LibreOffice(用于 PNG 预览)

LibreOffice 仅用于 /revise-ppt 中的 PNG 幻灯片预览功能。未安装时,技能会优雅地回退到 Markdown 文本显示。

平台 安装命令
Ubuntu/Debian sudo apt install libreoffice
macOS (Homebrew) brew install --cask libreoffice
Windows libreoffice.org 下载

完整端对端示例

# 1. 将 PPTX 模板解析为 Markdown 模板
/parse-ppt-template "GIST NetAI PPT Theme.pptx" --output my_talk.md

# 2. 编辑 my_talk.md — 填写幻灯片内容,添加表格/图表/图片
#    (使用编辑器或请 Claude 帮助填写内容)

# 3. 从 Markdown 生成 PPTX
/generate-ppt my_talk.md

# 4. 查看结果,如有需要可进行交互式修订
/revise-ppt my_talk.md

输出工件验证

每个技能均输出机器可读的成功标记并以退出码 0 退出。您可以非交互式地验证流水线:

# 验证 parse-ppt-template 输出
python skills/parse-ppt-template/parse_template.py template.pptx --output out.md
echo "退出码: $?"          # 必须为 0
grep -q "^template:" out.md && echo "PASS: frontmatter 存在"
grep -q "ph:[0-9]" out.md   && echo "PASS: 占位符已找到"

# 验证 generate-ppt 输出
python skills/generate-ppt/generate_ppt.py out.md --output out.pptx
echo "退出码: $?"          # 必须为 0
python -c "from pptx import Presentation; p=Presentation('out.pptx'); print('PASS: 幻灯片数 =', len(p.slides))"

环境变量

变量 说明
LANG 用于自动检测输出语言的 POSIX 区域设置字符串(例如 ko_KR.UTF-8 → 韩语)。这是标准系统变量,在韩语区域设置的系统上无需手动设置。

许可证

MIT © 2026 Jinwang Mok


agent4ppt 한국어 문서

English | 한국어 | 中文

PPTX 템플릿을 마크다운 템플릿으로 파싱하고, 마크다운에서 편집 가능한 PPTX 파일을 생성하며, 대화형 슬라이드 수정을 지원하는 Claude Code 플러그인 — 이미지 기반 렌더링 없이 사용 가능합니다. 마크다운이 단일 진실 원천(single source of truth)입니다.

License: MIT Python: 3.10+ Claude Code Plugin


목차


기능

  • 템플릿 파싱 — PPTX 템플릿을 읽어 플레이스홀더 주석(<!-- ph:idx type:TYPE -->)이 포함된 구조화된 마크다운 파일을 출력
  • PPTX 생성 — 마크다운을 다시 PPTX로 변환하여 템플릿의 시각적 레이아웃을 충실하게 재현
  • 대화형 수정 — 특정 슬라이드를 수정하고 PPTX를 재생성하는 3단계 인터뷰 워크플로우
  • 다양한 콘텐츠 지원 — 표, 차트(막대/파이/선형), 이미지, 다중 컬럼 레이아웃
  • 이중 언어 출력LANG 환경 변수를 통한 한국어(ko) 및 영어(en) 가이드 주석
  • 100% 편집 가능 — 모든 콘텐츠는 네이티브 python-pptx 객체로 삽입(이미지 렌더링 없음)

프로젝트 개요

agent4ppt는 연구자, 엔지니어, 발표자가 흔히 겪는 문제를 해결하는 Claude Code / OpenClaw 플러그인입니다: 콘텐츠가 바이너리 파일 내부에 있을 때 PPTX 슬라이드 덱을 반복적으로 수정하는 작업은 번거롭고 오류가 발생하기 쉽습니다.

문제

  • PPTX 템플릿을 수동으로 편집하는 것은 시간이 많이 걸리고 일관성을 깨뜨림
  • AI 지원 슬라이드 생성이 스크린샷/이미지 파이프라인에 의존하여 편집 불가능한 출력을 생성
  • 코드나 문서와 함께 슬라이드 콘텐츠를 버전 관리할 신뢰할 수 있는 방법이 없음

해결책: 마크다운 우선 파이프라인

agent4ppt는 3개 스킬 파이프라인을 제공합니다. 사람이 읽을 수 있는 마크다운 파일이 모든 슬라이드 콘텐츠의 단일 진실 원천(Single Source of Truth)입니다:

PPTX 템플릿  →  /parse-ppt-template  →  마크다운 템플릿
                                              ↓ (콘텐츠 편집)
                                         마크다운 콘텐츠
                                              ↓
                         /generate-ppt  →  PPTX 출력 (편집 가능)
                         /revise-ppt    →  대화형 수정 루프

핵심 설계 원칙

원칙 설명
이미지 렌더링 없음 모든 PPTX 객체는 python-pptx 네이티브 API를 통해 생성됩니다. 출력은 항상 PowerPoint / LibreOffice Impress에서 완전히 편집 가능합니다.
마크다운이 진실 슬라이드 콘텐츠, 레이아웃 메타데이터, 수정 기록이 모두 .md 파일에 저장됩니다. PPTX 템플릿은 참조만 될 뿐 수정되지 않습니다.
안정적인 플레이스홀더 식별 플레이스홀더는 idx(python-pptx 정수 인덱스)로 식별되어 라운드트립과 슬라이드 순서 변경이 안전합니다.
설계상 이중 언어 모든 사용자 향 문자열(가이드 주석, 프롬프트, 오류 메시지)은 LANG 환경 변수를 통해 한국어와 영어를 지원합니다.
자연스러운 폴백 선택적 LibreOffice 미리보기가 수정 워크플로우를 향상시키지만 필수는 아닙니다. 핵심 파이프라인은 Python만으로 실행됩니다.

대상 사용자

  • 구조화된 마크다운 노트에서 슬라이드 덱을 생성하려는 연구자
  • CI/CD 또는 스크립트 워크플로우에서 슬라이드 생성을 자동화하려는 엔지니어
  • AI 지원 워크플로우와 자연스럽게 통합되는 구성 가능한 스킬을 원하는 Claude Code / OpenClaw 사용자
  • PowerPoint를 클릭하는 것보다 텍스트로 슬라이드를 편집하기를 선호하는 모든 분

설치

시스템 요구 사항

agent4ppt를 설치하기 전에 다음 요구 사항을 확인하세요:

요구 사항 버전 비고
Python ≥ 3.10 필수. 확인: python3 --version
pip 모든 버전 필수. 확인: pip --version
python-pptx ≥ 0.6.21 scripts/install.sh가 자동 설치
pyyaml ≥ 6.0 scripts/install.sh가 자동 설치
markdown-it-py ≥ 3.0 scripts/install.sh가 자동 설치
LibreOffice 모든 버전 (선택 사항) /revise-ppt에서 PNG 슬라이드 미리보기

세 가지 Python 패키지(python-pptx, pyyaml, markdown-it-py)는 번들 설치 스크립트가 자동으로 설치합니다. Python ≥ 3.10pip만 미리 준비되어 있으면 됩니다.

이미지 기반 렌더링 없음: agent4ppt는 python-pptx를 직접 사용하여 네이티브 PPTX 객체(텍스트 프레임, 표, 차트)를 작성합니다. 출력 파일은 PowerPoint 또는 LibreOffice Impress에서 항상 완전히 편집 가능합니다.

Claude Code (플러그인 마켓플레이스)

두 줄 명령으로 agent4ppt를 설치하세요:

claude plugin marketplace add JinwangMok/agent4ppt
claude plugin install agent4ppt

설치 프로그램은 자동으로 scripts/install.sh를 실행하여 Python ≥ 3.10을 확인하고, 세 가지 필수 패키지를 설치하며, 선택적 LibreOffice 의존성을 안내합니다.

설치 후 세 가지 스킬(/parse-ppt-template, /generate-ppt, /revise-ppt)을 Claude Code 세션에서 바로 사용할 수 있습니다.

OpenClaw (Agent Skills 표준)

agent4ppt는 Agent Skills 표준(SKILL.md 형식)을 준수하여 OpenClaw 및 기타 Agent Skills 호환 런타임에서 사용할 수 있습니다.

설치 단계:

# 1단계: 저장소 클론
git clone https://github.com/JinwangMok/agent4ppt.git
cd agent4ppt

# 2단계: Python 의존성 설치
bash scripts/install.sh --no-register

# 3단계: OpenClaw에 등록 (클론된 디렉토리 지정)
# openclaw skill add ./agent4ppt
# — 또는 — 저장소 URL을 OpenClaw 스킬 소스에 추가:
# openclaw skill add https://github.com/JinwangMok/agent4ppt

OpenClaw는 저장소 루트의 SKILL.md를 통해 스킬을 자동 감지합니다. 각 스킬 항목은 다음을 정의합니다:

SKILL.md 필드
trigger /parse-ppt-template, /generate-ppt, /revise-ppt
entry skills/<이름>/<스크립트>.py
requires_python >=3.10
dependencies python-pptx>=0.6.21, pyyaml>=6.0, markdown-it-py>=3.0

등록 후 세 가지 슬래시 명령을 OpenClaw 세션 내에서 사용할 수 있습니다.

Codex CLI

agent4ppt는 Codex CLI와도 호환됩니다. 클론 및 의존성 설치 후:

git clone https://github.com/JinwangMok/agent4ppt.git
cd agent4ppt
bash scripts/install.sh

# Python으로 스킬 직접 실행
python skills/parse-ppt-template/parse_template.py template.pptx --output slides.md
python skills/generate-ppt/generate_ppt.py slides.md --output output.pptx
python skills/revise-ppt/revise_ppt.py slides.md

수동 설치

에이전트 런타임 없이 수동 설정을 선호하는 경우:

git clone https://github.com/JinwangMok/agent4ppt.git
cd agent4ppt
pip install python-pptx pyyaml markdown-it-py

설치 후 설정

1. 설치 확인

위의 어느 방법으로든 설치한 후, 모든 필수 의존성이 사용 가능한지 확인하세요:

python3 -c "import pptx, yaml; from markdown_it import MarkdownIt; print('agent4ppt: all dependencies OK')"

출력 결과: agent4ppt: all dependencies OK

2. 출력 언어 설정

agent4ppt는 LANG POSIX 환경 변수를 읽어 가이드 주석 및 프롬프트의 언어(한국어/영어)를 결정합니다. 쉘 프로파일에 한 번 설정하세요:

# 한국어 출력 (~/.bashrc 또는 ~/.zshrc에 추가)
export LANG=ko_KR.UTF-8

# 영어 출력 (기본값 — 별도 설정 불필요)
export LANG=en_US.UTF-8

개별 실행 시 언어를 재정의할 수도 있습니다:

/parse-ppt-template template.pptx --lang ko   # 이번 실행만 한국어
/revise-ppt slides.md --lang en               # 이번 실행만 영어

언어 우선순위: --lang 플래그 > 마크다운 frontmatter lang: 필드 > $LANG 환경 변수 > en (기본값)

3. 선택 사항: PNG 슬라이드 미리보기 활성화 (LibreOffice)

/revise-ppt 스킬은 대화형 검토 워크플로우 중 PNG 슬라이드 썸네일을 표시할 수 있습니다. 이 기능은 LibreOffice가 필요합니다:

# Ubuntu / Debian
sudo apt install libreoffice

# macOS (Homebrew)
brew install --cask libreoffice

LibreOffice가 없으면 스킬은 일반 텍스트 슬라이드 요약으로 자연스럽게 폴백됩니다 — 핵심 파싱/생성/수정 기능에는 영향이 없습니다.

4. Claude Code 플러그인 설정 (선택 사항)

agent4ppt의 동작은 명령줄 인수와 LANG 환경 변수로 완전히 제어됩니다. ~/.claude/settings.json 변경은 필요하지 않습니다. Claude Code 내에서 영구적인 언어 기본값을 설정하려면:

// ~/.claude/settings.json
{
  "env": {
    "LANG": "ko_KR.UTF-8"
  }
}

빠른 시작

1. PPTX 템플릿을 마크다운으로 파싱

/parse-ppt-template my_template.pptx
# → my_template.md 생성

2. 마크다운 편집

my_template.md를 열어 플레이스홀더 주석 사이에 콘텐츠를 입력하세요.

3. 마크다운에서 PPTX 생성

/generate-ppt my_template.md
# → output.pptx 생성 (또는 frontmatter의 fname 값)

4. 슬라이드 대화형 수정

/revise-ppt my_template.md

파이프라인 아키텍처

agent4ppt는 마크다운 우선 파이프라인을 기반으로 합니다. 마크다운 파일이 단일 진실 원천(single source of truth)이며, PPTX 템플릿은 YAML frontmatter의 template 필드에서 한 번만 참조되고 수정되지 않습니다.

┌─────────────────────────────────────────────────────────────────┐
│                     agent4ppt 파이프라인                         │
│                                                                 │
│  PPTX 템플릿                                                     │
│  (읽기 전용)                                                     │
│       │                                                         │
│       ▼  /parse-ppt-template                                    │
│  마크다운 템플릿 ─────────────────────────────────────────────►   │
│  (YAML frontmatter + 슬라이드 섹션 + <!-- ph:idx --> 주석)       │
│       │                                                         │
│       │  (사용자가 콘텐츠 입력)                                   │
│       ▼                                                         │
│  마크다운 콘텐츠 파일                                             │
│       │                  ┌──────────────────────────────────┐   │
│       ├── /generate-ppt ─►  PPTX 출력                        │   │
│       │                  │  (frontmatter의 템플릿 사용)       │   │
│       │                  └──────────────────────────────────┘   │
│       │                                                         │
│       └── /revise-ppt ──► (3단계 인터뷰)                         │
│                               │                                 │
│                               ├── 마크다운 인플레이스 수정        │
│                               └── /generate-ppt 실행            │
└─────────────────────────────────────────────────────────────────┘

데이터 흐름

단계 입력 출력 핵심 작업
파싱 *.pptx 템플릿 <!-- ph:idx type:TYPE -->이 포함된 *.md python-pptx가 슬라이드 레이아웃을 읽고 idx 기반 플레이스홀더 매핑을 마크다운에 작성
생성 *.md 콘텐츠 파일 *.pptx 프레젠테이션 Frontmatter template 필드가 소스 PPTX를 찾아내고 각 ph:idx 블록이 매칭 플레이스홀더에 작성됨
수정 *.md 콘텐츠 파일 업데이트된 *.md + *.pptx 3단계 인터뷰로 마크다운을 패치한 후 generate에 위임

주요 설계 결정

  • frontmatter의 template이 권위적 — 마크다운 frontmatter의 template: 필드에 저장된 경로가 소스 PPTX에 대한 유일한 참조입니다. 세 가지 스킬 모두 이 필드에서 템플릿을 찾으며, 별도의 설정 파일이 없습니다.
  • 플레이스홀더 식별 = python-pptx idx — 플레이스홀더는 위치나 이름이 아닌 python-pptx가 반환하는 정수 idx로 식별됩니다. 이로 인해 슬라이드 순서 변경이 안전하고 안정적인 라운드트립이 보장됩니다.
  • 이미지 렌더링 없음 — 모든 콘텐츠는 네이티브 python-pptx 객체(텍스트 프레임, 표, 차트)로 삽입됩니다. PPTX 출력은 PowerPoint / LibreOffice Impress에서 완전히 편집 가능합니다.
  • PNG 미리보기는 선택 사항 — LibreOffice 헤드리스가 revise-ppt 워크플로우에서 시각적 미리보기를 제공합니다. LibreOffice가 없을 때 스킬은 일반 텍스트 슬라이드 요약으로 자연스럽게 폴백됩니다.
  • 마크다운은 무손실파싱 → 편집 → 생성 라운드트립은 템플릿 레이아웃을 충실하게 재현하는 PPTX를 생성합니다.
  • 패스스루 보존 — 슬라이드 전환, 애니메이션, 발표자 노트, 마스터 슬라이드 속성은 마크다운에서 모델링되지 않으며 파괴되지도 않습니다. 파싱 → 생성 라운드트립을 통해 변경 없이 유지됩니다.

플레이스홀더 온톨로지: 템플릿 계약 대 공간적 레이아웃

각 플레이스홀더 주석은 두 가지 별개의 관심사를 인코딩합니다:

관심사 속성 설명
템플릿 계약 type:TYPE 플레이스홀더가 요구하는 것 — 허용하는 콘텐츠의 종류(title, body, picture, chart 등). 마크다운과 PPTX 템플릿 사이의 구속력 있는 계약입니다.
공간적 레이아웃 pos:(x,y) size:WxH 플레이스홀더가 슬라이드에서 위치하는 곳. 정보 제공용 메타데이터로만 사용되며 콘텐츠 재배치에는 절대 사용되지 않습니다.

generate-pptph:idxtype:만 읽습니다. parse-ppt-template 출력의 pos:size: 값은 생성 시 조용히 전달되어 무시됩니다. 이 값들은 사람 편집자를 위한 문서 역할을 합니다.

검증 가능한 출력 아티팩트

각 파이프라인 단계에서 검증 가능한 아티팩트가 생성됩니다:

단계 아티팩트 검증 방법
파싱 *.md 파일 YAML frontmatter template 필드 존재 여부; <!-- ph:idx --> 주석이 템플릿 플레이스홀더 수와 일치
생성 *.pptx 파일 python-pptx로 파일 열기 가능; 슬라이드 수가 마크다운 --- 구분자 수와 일치
수정 업데이트된 *.md + *.pptx 수정 주석이 해결되거나 주석 처리됨; PPTX 타임스탬프가 원본보다 새로움

스킬 참조

/parse-ppt-template

PPTX 템플릿 파일을 파싱하여 플레이스홀더 주석이 포함된 마크다운 템플릿을 생성합니다. 플레이스홀더는 python-pptx idx 기반 인덱싱으로 식별되며 <!-- ph:idx type:TYPE --> HTML 주석으로 표시됩니다.

사용법:

/parse-ppt-template <pptx_파일> [--output <출력.md>] [--lang ko|en] [--layouts-only]

실행 경로: python skills/parse-ppt-template/parse_template.py

인수:

인수 필수 기본값 설명
pptx_파일 PPTX 템플릿 파일 경로
--output, -o <입력파일명>.md 생성된 마크다운 템플릿의 출력 경로
--lang, -l $LANG 또는 en 출력의 가이드 주석 언어(ko | en)
--layouts-only false 슬라이드별 대신 레이아웃 정의별로 하나의 섹션 생성

반환값: --output에 마크다운 파일이 작성됩니다.

종료 코드 의미
0 성공 — 마크다운이 작성되었고 모든 검증 확인이 통과됨
1 입력/IO 오류 (파일 없음, 의존성 누락 등)
2 검증 실패 — 마크다운은 작성되었으나 구조적 불변 확인에 실패

성공 마커 (기계로 확인 가능):

[agent4ppt] Markdown template written → <경로>
[agent4ppt] Verification passed ✓  (N section(s), template_path confirmed, idx annotations present)

출력 형식:

생성된 마크다운 파일에는 다음이 포함됩니다:

  • YAML frontmattertemplate, fname, title, subTitle, date, author, lang 필드
  • 슬라이드 섹션---으로 구분
  • 레이아웃 표시자 — 각 슬라이드 섹션 시작 부분의 > layout: N
  • 레이아웃 이름 주석<!-- layout_name: NAME --> (정보 제공용)
  • 플레이스홀더 주석 — 공간 메타데이터가 포함된 <!-- ph:idx type:TYPE pos:(x,y) size:WxH -->
  • 가이드 주석 — 각 플레이스홀더를 설명하는 <!-- Enter the ... --> (선택한 언어로)
  • 콘텐츠 플레이스홀더 — 바로 채울 수 있는 예시 콘텐츠 포함

플레이스홀더 type 값:

타입 설명
title 슬라이드 제목
center_title 가운데 제목
subtitle 부제목
body 본문(목록, 텍스트)
object 일반 개체
picture 이미지
table
chart 차트/다이어그램
media 미디어 클립
ftr 바닥글
dt 날짜
sldnum 슬라이드 번호

예시:

# 기본 설정 — 출력은 템플릿과 같은 디렉토리에 작성됨
/parse-ppt-template "GIST NetAI PPT Theme.pptx"

# 출력 경로와 한국어 가이드 주석 지정
/parse-ppt-template "GIST NetAI PPT Theme.pptx" --output slides_template.md --lang ko

# 레이아웃별 하나의 섹션 (슬라이드 콘텐츠가 없는 템플릿용)
/parse-ppt-template my_template.pptx --layouts-only --output layouts.md

예시 출력:

---
template: ./GIST NetAI PPT Theme.pptx
fname: output.pptx
title: ""
subTitle: ""
date: ""
author: ""
lang: ko
---

> layout: 0
<!-- layout_name: Title Slide -->

<!-- ph:0 type:center_title pos:(0.9167",1.75") size:7.6548"×0.7547" -->
<!-- 가운데 슬라이드 제목을 입력하세요 -->
# 슬라이드 제목

<!-- ph:1 type:subtitle pos:(0.9167",2.6495") size:5.588"×0.8832" -->
<!-- 부제목을 입력하세요 -->
부제목 텍스트

---

> layout: 1

<!-- ph:0 type:title pos:(0.4583",0.25") size:8.5"×1.2" -->
<!-- 슬라이드 제목을 입력하세요 -->
# 섹션 헤더

<!-- ph:1 type:body pos:(0.4583",1.5") size:8.5"×4.5" -->
<!-- 주요 본문 콘텐츠를 입력하세요. 목록, 굵게, 기울임 지원. -->
- 항목 하나
- 항목 둘

오류 처리:

조건 동작
pptx_파일을 찾을 수 없음 종료 코드 1, stderr에 오류 출력
파일에 .pptx 확장자 없음 경고 출력 후 계속 진행
의존성 누락 (python-pptx, pyyaml) 종료 코드 1, 설치 안내 출력
PPTX 파일 손상 또는 읽을 수 없음 종료 코드 1, stderr에 오류 출력
작성 후 구조 검증 실패 종료 코드 2, stderr에 실패 세부 사항 출력

/generate-ppt

마크다운 파일에서 편집 가능한 PPTX 파일을 생성합니다. 마크다운 frontmatter에서 PPTX 템플릿 경로를 읽고, 각 <!-- ph:idx --> 블록을 해당 플레이스홀더에 매핑하며, 마크다운 표, 차트 YAML 블록, 이미지를 네이티브 python-pptx 객체로 변환합니다.

사용법:

/generate-ppt <마크다운_파일> [--output <출력.pptx>] [--lang ko|en] [--dry-run]

실행 경로: python skills/generate-ppt/generate_ppt.py

인수:

인수 필수 기본값 설명
마크다운_파일 마크다운 콘텐츠 파일 경로
--output, -o frontmatter.fname 또는 <입력>.pptx 출력 PPTX 파일 경로
--lang, -l $LANG 또는 en 경고/정보 메시지 언어(ko | en)
--dry-run false PPTX 파일을 작성하지 않고 입력을 검증하고 슬라이드를 메모리에서 빌드

반환값: 출력 경로에 PPTX 파일. 성공 시 종료 코드 0, 오류 시 1.

성공 마커 (기계로 확인 가능):

[agent4ppt] PPTX generated → <경로>

Frontmatter 필드:

필드 필수 설명
template PPTX 템플릿의 상대 또는 절대 경로
fname 기본 출력 파일명 (예: output.pptx)
title 프레젠테이션 제목 (메타데이터)
subTitle 프레젠테이션 부제목 (메타데이터)
date 프레젠테이션 날짜 문자열
author 저자 이름
lang 언어 재정의(en 또는 ko). $LANG--lang보다 우선합니다.

슬라이드 섹션 구조:

> layout: N               ← 레이아웃 인덱스 (0부터 시작), 필수

<!-- ph:0 type:title -->  ← 플레이스홀더 주석 (idx=0, type=title)
# 슬라이드 제목           ← 이 플레이스홀더의 콘텐츠

<!-- ph:1 type:body -->
- 항목 1
- 항목 2
- **굵은 텍스트***기울임 텍스트*

지원하는 콘텐츠 유형:

유형 구문 비고
일반 텍스트 임의의 텍스트 그대로 작성됨
제목 # 제목, ## 소제목 제목/부제목 플레이스홀더에서 앞의 # 제거됨
글머리 기호 목록 - 항목 또는 * 항목 최대 9단계 들여쓰기
번호 매기기 목록 1. 항목 글머리 기호로 처리됨
굵게 **텍스트** run.font.bold = True
기울임 *텍스트* run.font.italic = True
링크 [텍스트](url) 밑줄 텍스트; 하이퍼링크 관계는 삽입되지 않음
이미지 ![대체텍스트](경로/image.png) picture 또는 object 플레이스홀더용
GFM 마크다운 표 첫 번째 행은 굵은 헤더가 됨
차트 ```chart YAML 블록 막대, 컬럼, 선형, 파이 차트
다중 컬럼 ||| 구분자 콘텐츠 분할; 첫 번째 컬럼이 플레이스홀더를 채움

차트 블록 구문:

<!-- ph:2 type:chart -->
```chart
type: bar          # bar | column | line | pie
title: 나의 차트
categories: [Q1, Q2, Q3, Q4]
series:
  - name: 매출
    values: [100, 150, 120, 200]
  - name: 비용
    values: [80, 90, 100, 110]
```

예시:

# PPTX 생성 — 출력 파일명은 frontmatter fname 필드에서 가져옴
/generate-ppt slides.md

# 출력 경로 직접 지정
/generate-ppt slides.md --output final_presentation.pptx

# 한국어 메시지
/generate-ppt slides.md --lang ko

# 드라이런 — 파일 작성 없이 검증만 수행
/generate-ppt slides.md --dry-run

전체 마크다운 예시:

---
template: ./GIST NetAI PPT Theme.pptx
fname: my_presentation.pptx
title: "연구 개요"
subTitle: "GIST NetAI 연구실"
date: "2026-03-22"
author: "진왕 목"
lang: ko
---

> layout: 0

<!-- ph:0 type:title -->
# 연구 개요

<!-- ph:1 type:subtitle -->
GIST NetAI 연구실 · 2026

---

> layout: 2

<!-- ph:0 type:title -->
# 벤치마크 결과

<!-- ph:1 type:table -->
| 모델 | 정확도 | 지연시간 (ms) |
|------|--------|--------------|
| 우리 | 94.2%  | 12           |
| 기반 | 88.7%  | 15           |

---

> layout: 3

<!-- ph:0 type:title -->
# 학습 손실

<!-- ph:1 type:chart -->
```chart
type: line
title: 학습 손실
categories: [에포크 1, 에포크 2, 에포크 3, 에포크 4, 에포크 5]
series:
  - name: 학습
    values: [1.8, 1.2, 0.9, 0.7, 0.6]
  - name: 검증
    values: [2.0, 1.5, 1.1, 0.9, 0.8]

**오류 처리:**

| 조건 | 동작 |
|------|------|
| `마크다운_파일`을 찾을 수 없음 | 종료 코드 1, stderr에 오류 출력 |
| `template` frontmatter 필드 누락 | 종료 코드 1, stderr에 오류 출력 |
| 템플릿 PPTX 파일을 찾을 수 없음 | 종료 코드 1, stderr에 오류 출력 |
| 레이아웃 인덱스 범위 초과 | 경고 출력, 레이아웃 0 사용 |
| 슬라이드에서 플레이스홀더 `idx`를 찾을 수 없음 | 경고 출력, 플레이스홀더 건너뜀 |
| 이미지 파일을 찾을 수 없음 | 경고 출력, 플레이스홀더 비워둠 |
| 잘못된 차트 YAML | 경고 출력, 플레이스홀더 비워둠 |
| 의존성 누락 | 종료 코드 1, 설치 안내 출력 |

---

### /revise-ppt

**3단계 인터뷰 워크플로우**를 통해 기존 프레젠테이션을 대화형으로 수정합니다. 대상 슬라이드 선택 → 슬라이드별 변경 사항 설명 → 마크다운 소스에 편집 사항 적용 후 PPTX 재생성. LibreOffice 헤드리스를 통해 PNG 슬라이드 미리보기를 선택적으로 렌더링하며, LibreOffice가 없을 때는 마크다운 텍스트로 폴백됩니다.

**사용법:**

/revise-ppt <마크다운_파일> [--pptx <pptx_파일>] [--output <출력.pptx>] [--lang ko|en]


실행 경로: `python skills/revise-ppt/revise_ppt.py`

**인수:**

| 인수 | 필수 | 기본값 | 설명 |
|------|------|--------|------|
| `마크다운_파일` | ✅ | — | 수정할 마크다운 소스 파일 경로 (단일 진실 원천) |
| `--pptx` | ❌ | `frontmatter.fname`에서 파생 | PNG 미리보기 생성에 사용되는 기존 PPTX 경로 |
| `--output`, `-o` | ❌ | `frontmatter.fname` 또는 `<마크다운>.pptx` | 재생성된 PPTX의 출력 경로 |
| `--lang`, `-l` | ❌ | `$LANG` 또는 `en` | 인터뷰 프롬프트 언어(`ko` \| `en`) |

**반환값:** `마크다운_파일`이 **인플레이스로 업데이트**됩니다. 새 PPTX는 `generate-ppt`에 위임하여 생성됩니다. 성공 시 종료 코드 `0`, 오류 시 `1`.

**성공 마커:**

[agent4ppt] PPTX generated → <경로> ← generate-ppt 서브프로세스에서 출력 Revision complete! Updated file: <경로> ← revise-ppt에서 출력


**워크플로우 — 3단계:**

**1단계 — 대상 슬라이드 선택**

=== 슬라이드 수정 워크플로우 === 프레젠테이션에 슬라이드가 8개 있습니다.

1단계: 어떤 슬라이드를 수정하시겠습니까? 슬라이드 번호를 쉼표로 구분하여 입력하거나 (예: 1,3,5), 범위로 입력하거나 (예: 2-4), 'all'을 입력하세요:

2,4-6


**슬라이드 선택 구문:**

| 입력 | 의미 |
|------|------|
| `1,3,5` | 슬라이드 1, 3, 5 |
| `2-4` | 슬라이드 2, 3, 4 |
| `2~4` | `2-4`와 동일 |
| `all` | 모든 슬라이드 |
| `*` | 모든 슬라이드 |
| `모두` | 모든 슬라이드 (한국어 별칭) |

**2단계 — 슬라이드별 변경 사항 설명**

2단계: 선택한 각 슬라이드를 살펴보겠습니다.

--- 슬라이드 2 (레이아웃: 1) --- 슬라이드 2 미리보기: /경로/to/my_presentation_previews/slide_2.png

변경 사항을 설명하세요. 예시:

  • Change title to 'New Title'
  • Replace bullet 2 with 'Updated content'
  • Change layout to layout 3 슬라이드 2에 대한 지시 사항:

Change title to 'Updated Results'


**자동으로 적용되는 지시 패턴:**

| 패턴 | 예시 | 효과 |
|------|------|------|
| 제목 변경 | `Change title to 'New Title'` | 제목 플레이스홀더 제목을 교체 |
| 레이아웃 변경 | `Change layout to 3` | 섹션의 `> layout: N`을 업데이트 |
| 자유 형식 | 기타 텍스트 | 수동 검토를 위해 `<!-- REVISION: ... -->` 주석으로 추가됨 |

**3단계 — 적용 및 재생성**

3단계: 변경 사항을 적용하고 PPTX를 재생성합니다... 슬라이드 2에 변경 사항 적용 중... 슬라이드 4에 변경 사항 적용 중... PPTX 재생성 중... [agent4ppt] PPTX generated → ./my_presentation.pptx

Revision complete! Updated file: ./my_presentation.pptx Markdown updated: ./slides.md PPTX regenerated: ./my_presentation.pptx


**수정 상태 추적:**

1단계 이후에 JSON 상태 파일 `<마크다운_줄기>_revision_state.json`이 생성됩니다:

```json
{
  "markdown_path": "/절대/경로/to/slides.md",
  "pptx_path": "/절대/경로/to/output.pptx",
  "iteration_count": 1
}

iteration_count는 각 성공적인 수정 사이클 후에 증가하여 재개 가능한 다중 라운드 편집을 지원합니다.

PNG 미리보기:

LibreOffice가 설치된 경우, 슬라이드 미리보기는 <pptx_줄기>_previews/ 디렉토리에 확정적으로 생성됩니다. LibreOffice가 없는 경우 텍스트 요약 파일로 자동 폴백됩니다.

예시:

# 표준 대화형 수정
/revise-ppt slides.md

# PNG 미리보기 생성을 위해 PPTX 경로 명시 지정
/revise-ppt slides.md --pptx final_presentation.pptx

# 명시적 출력 PPTX 경로 지정
/revise-ppt slides.md --output revised_v2.pptx

# 한국어 프롬프트
/revise-ppt slides.md --lang ko

오류 처리:

조건 동작
마크다운_파일을 찾을 수 없음 종료 코드 1, stderr에 오류 출력
슬라이드 미선택 종료 코드 0, 안내 메시지 출력
LibreOffice를 찾을 수 없음 경고 출력, 텍스트 미리보기로 폴백
generate-ppt 서브프로세스 실패 서브프로세스 stderr 출력, 종료 코드 1
KeyboardInterrupt (Ctrl-C) [agent4ppt] Cancelled. 출력 후 종료 코드 0
의존성 누락 종료 코드 1, 설치 안내 출력

마크다운 형식

마크다운 파일은 직렬화 형식이 아닌 정식(canonical) 문서 그 자체입니다. 모든 콘텐츠 편집은 마크다운에서 이루어지며, PPTX는 항상 마크다운으로부터 재생성됩니다.

YAML Frontmatter

모든 마크다운 파일은 ---으로 구분된 YAML frontmatter로 시작해야 합니다:

필드 필수 설명
template 소스 PPTX 템플릿 경로. 상대 경로는 마크다운 파일 기준. 소스 PPTX에 대한 유일한 권위 있는 참조
fname 기본 출력 PPTX 파일명 (예: output.pptx)
title 프레젠테이션 제목 (PPTX 메타데이터)
subTitle 프레젠테이션 부제목
date 날짜 문자열
author 저자 이름
lang 언어 재정의(en 또는 ko). $LANG--lang보다 우선

슬라이드 섹션

frontmatter 이후, 슬라이드는 ---으로 구분됩니다. 각 슬라이드 섹션은 레이아웃 참조(> layout: N)로 시작하고, 플레이스홀더 블록이 이어집니다:

> layout: 1
<!-- layout_name: Content Slide -->

<!-- ph:0 type:title pos:(0.46",0.25") size:8.5"×1.2" -->
# 슬라이드 제목

<!-- ph:1 type:body pos:(0.46",1.5") size:8.5"×4.5" -->
- 첫 번째 글머리 기호
- 두 번째 글머리 기호
  - 중첩 글머리 기호
- **굵은 텍스트***기울임 텍스트*

템플릿 계약 vs. 공간적 레이아웃

각 플레이스홀더 주석은 하나의 줄에 두 가지 별개의 관심사를 인코딩합니다:

관심사 속성 역할
템플릿 계약 type:TYPE 플레이스홀더가 허용하는 콘텐츠. 이것이 구속력 있는 의미론적 계약이며, 유효한 마크다운 구문을 결정합니다 (title/body/picture/chart/table/…).
공간적 레이아웃 pos:size: 슬라이드에서 플레이스홀더가 위치하는 곳. 패스스루로 보존되는 정보 제공용 메타데이터이며, generate-ppt는 이 값들을 위치 결정에 사용하지 않습니다.

완전한 예시

지원하는 모든 콘텐츠 유형을 보여주는 완전한 예시:

---
template: ./my_template.pptx
fname: output.pptx
title: "나의 프레젠테이션"
subTitle: "2026 연간 보고서"
date: "2026-03-22"
author: "진왕 목"
lang: ko
---

> layout: 0

<!-- ph:0 type:title -->
# 나의 프레젠테이션

<!-- ph:1 type:body -->
연간 보고서에 오신 것을 환영합니다.

---

> layout: 2

<!-- ph:0 type:title -->
# 판매 데이터

<!-- ph:1 type:table -->
| 분기 | 매출  | 성장률 |
|------|-------|--------|
| Q1   | $1.2M | +12%   |
| Q2   | $1.5M | +25%   |
| Q3   | $1.3M | +8%    |
| Q4   | $1.8M | +38%   |

<!-- ph:2 type:chart -->
```chart
type: bar
title: 분기별 매출
categories: [Q1, Q2, Q3, Q4]
series:
  - name: 매출 (백만 달러)
    values: [1.2, 1.5, 1.3, 1.8]

layout: 3

팀 사진

팀 사진


layout: 4

왼쪽 컬럼 내용

  • 항목 A
  • 항목 B

|||

오른쪽 컬럼 내용

  • 항목 C
  • 항목 D

### 플레이스홀더 유형

| `type` | 설명 |
|--------|------|
| `title` | 슬라이드 제목 텍스트 상자 |
| `body` | 주요 콘텐츠 영역(목록, 텍스트) |
| `picture` | 이미지 플레이스홀더 |
| `chart` | 차트 플레이스홀더 |
| `table` | 표 플레이스홀더 |
| `object` | 일반 개체/다중 콘텐츠 영역 |

---

## 언어 지원

가이드 주석 및 프롬프트의 출력 언어 설정:

```bash
# 환경 변수로 설정
export LANG=ko   # 한국어
export LANG=en   # 영어 (기본값)

# 명령줄 플래그로 설정
/parse-ppt-template template.pptx --lang ko
/revise-ppt slides.md --lang en

언어 우선순위: --lang 플래그 > $LANG 환경 변수 > en (기본값)


의존성

Python 패키지

pip install python-pptx pyyaml markdown-it-py
# 또는 번들 설치 스크립트 사용:
bash scripts/install.sh

선택 사항: LibreOffice (PNG 미리보기용)

LibreOffice는 /revise-ppt의 PNG 슬라이드 미리보기 기능에만 필요합니다. 설치되지 않은 경우 마크다운 텍스트 표시로 자연스럽게 폴백됩니다.

플랫폼 설치 명령
Ubuntu/Debian sudo apt install libreoffice
macOS (Homebrew) brew install --cask libreoffice
Windows libreoffice.org에서 다운로드

전체 엔드투엔드 예시

# 1. PPTX 템플릿을 마크다운 템플릿으로 파싱
/parse-ppt-template "GIST NetAI PPT Theme.pptx" --output my_talk.md

# 2. my_talk.md 편집 — 슬라이드 콘텐츠 입력, 표/차트/이미지 추가
#    (편집기를 사용하거나 Claude에게 콘텐츠 입력을 요청)

# 3. 마크다운에서 PPTX 생성
/generate-ppt my_talk.md

# 4. 결과를 검토하고 필요하면 대화형으로 수정
/revise-ppt my_talk.md

출력 아티팩트 검증

각 스킬은 기계가 읽을 수 있는 성공 마커를 출력하고 종료 코드 0으로 종료합니다. 파이프라인을 비대화형으로 검증할 수 있습니다:

# parse-ppt-template 출력 검증
python skills/parse-ppt-template/parse_template.py template.pptx --output out.md
echo "종료 코드: $?"          # 0=성공+검증됨, 2=작성되었으나 검증 실패
grep -q "^template:" out.md && echo "PASS: frontmatter 존재"
grep -qP "ph:\d+ type:\w+" out.md && echo "PASS: 플레이스홀더 발견"

# generate-ppt 출력 검증
python skills/generate-ppt/generate_ppt.py out.md --output out.pptx
echo "종료 코드: $?"          # 반드시 0이어야 함
python -c "from pptx import Presentation; p=Presentation('out.pptx'); print('PASS: 슬라이드 수 =', len(p.slides))"

# 라운드트립 충실도 검증
python -c "
from pptx import Presentation
p = Presentation('out.pptx')
slides_pptx = len(p.slides)
import re
md = open('out.md').read()
body = md.split('---\n', 2)[-1]
slides_md = len(re.split(r'\n---\s*\n', body.strip()))
assert slides_pptx == slides_md, f'불일치: pptx={slides_pptx} md={slides_md}'
print('PASS: 슬라이드 수 일치')
"

# 수정 상태 검증 (/revise-ppt 실행 후)
python -c "
import json
state = json.load(open('out_revision_state.json'))
assert 'markdown_path' in state
assert 'iteration_count' in state
print('PASS: 수정 상태 유효, iteration_count =', state['iteration_count'])
"

환경 변수

변수 설명
LANG 출력 언어 자동 감지에 사용되는 POSIX 로케일 문자열 (예: ko_KR.UTF-8 → 한국어). 표준 시스템 변수로, 한국어 로케일 시스템에서는 별도로 설정할 필요가 없습니다.

기여하기

기여를 환영합니다! agent4ppt는 오픈소스 프로젝트이며 개선 사항, 버그 리포트, 아이디어 모두 환영합니다.

기여 방법

  1. GitHub에서 저장소를 Fork합니다
  2. 로컬에 Clone합니다:
    git clone https://github.com/<your-username>/agent4ppt.git
    cd agent4ppt
  3. 변경사항을 위한 브랜치를 생성합니다:
    git checkout -b feature/my-improvement
  4. 의존성을 설치하고 테스트 스위트가 통과하는지 확인합니다:
    bash scripts/install.sh
    pytest
  5. 변경을 수행합니다 — 새로운 기능에는 반드시 테스트를 포함시키세요
  6. 테스트가 통과하는지 확인합니다:
    pytest --tb=short
  7. 명확하고 설명적인 메시지로 커밋합니다
  8. 브랜치를 Push하고 main을 대상으로 Pull Request를 엽니다

기여 가이드라인

영역 가이드라인
코드 스타일 PEP 8 준수. 공개 함수에는 타입 힌트를 사용하세요.
테스트 모든 새로운 기능은 tests/ 하위에 pytest 테스트를 포함해야 합니다. 변경된 모듈의 커버리지는 80% 이상을 유지하세요.
이미지 렌더링 금지 모든 PPTX 콘텐츠는 python-pptx 네이티브 객체를 통해 삽입해야 합니다. 이미지 기반 렌더링 PR은 병합되지 않습니다.
이중 언어 문서 사용자에게 보이는 문자열을 추가할 때는 i18n 딕셔너리에 영어(en)와 한국어(ko) 모두 포함해야 합니다.
마크다운 우선 마크다운 스키마 변경은 하위 호환성을 유지하거나 마이그레이션 노트를 포함해야 합니다.
의존성 새로운 런타임 의존성은 강력한 이유가 필요합니다. 개발 전용 의존성은 괜찮습니다.

이슈 보고

GitHub 이슈를 열고 다음을 포함해 주세요:

  • OS 및 Python 버전 (python3 --version)
  • agent4ppt 버전 (plugin.json 참조)
  • 실행한 정확한 명령
  • 전체 오류 출력 (stdout + stderr)
  • 최소 재현 가능한 예시 (가능하면 PPTX 템플릿 또는 마크다운 파일)

개발 환경 설정

# 저장소 클론 및 진입
git clone https://github.com/JinwangMok/agent4ppt.git
cd agent4ppt

# 런타임 의존성 설치
bash scripts/install.sh

# 개발용 패키지 설치 (pytest, coverage)
pip install pytest pytest-cov

# 모든 테스트 실행
pytest

# 커버리지 리포트 포함 실행
pytest --cov=agent4ppt --cov=skills --cov-report=term-missing

행동 강령

이 프로젝트는 간단한 규칙을 따릅니다: 서로 존중하고 건설적으로 행동하세요. 어떤 형태의 괴롭힘이나 차별적 언행도 허용되지 않습니다.


라이선스

MIT 라이선스 — Copyright (c) 2026 Jinwang Mok

본 소프트웨어 및 관련 문서 파일(이하 "소프트웨어")의 사본을 취득하는 모든 사람에게 소프트웨어를 제한 없이 사용, 복사, 수정, 병합, 출판, 배포, 서브라이선스 및/또는 판매할 수 있는 권한이 무료로 부여됩니다. 소프트웨어를 제공받은 사람이 동일한 조건 하에 소프트웨어를 사용할 수 있도록 허가하는 것을 포함합니다.

위의 저작권 고지와 본 허가 고지는 소프트웨어의 모든 사본 또는 중요한 부분에 포함되어야 합니다.

소프트웨어는 상품성, 특정 목적에 대한 적합성 및 비침해에 대한 보증을 포함하되 이에 국한되지 않는 어떠한 종류의 명시적 또는 묵시적 보증 없이 "있는 그대로" 제공됩니다.

전체 라이선스 텍스트는 LICENSE를 참조하세요.

About

Claude Code plugin: PPTX template ↔ markdown pipeline (parse, generate, revise)

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors