From agent4ppt
Generate an editable PPTX file from a markdown content file. Reads template path from frontmatter, maps <!-- ph:idx --> blocks to placeholders by idx, and converts markdown tables, chart YAML blocks, and images to native python-pptx objects.
How this skill is triggered — by the user, by Claude, or both
Slash command
/agent4ppt:generate-pptThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
**English:** Generate an editable PPTX file from a markdown file. Reads the PPTX template path from the markdown frontmatter (`template:` field — the sole authoritative reference to the source PPTX), maps each `<!-- ph:idx -->` block to the corresponding placeholder by `idx`, and converts markdown tables, chart YAML blocks, and images to native python-pptx objects. Content-placeholder mismatche...
English: Generate an editable PPTX file from a markdown file. Reads the PPTX template path from the markdown frontmatter (template: field — the sole authoritative reference to the source PPTX), maps each <!-- ph:idx --> block to the corresponding placeholder by idx, and converts markdown tables, chart YAML blocks, and images to native python-pptx objects. Content-placeholder mismatches are handled gracefully with per-warning output.
한국어: 마크다운 파일에서 편집 가능한 PPTX 파일을 생성합니다. 마크다운 frontmatter의 template: 필드(원본 PPTX에 대한 유일한 권위 있는 참조)에서 PPTX 템플릿 경로를 읽어 idx로 각 <!-- ph:idx --> 블록을 해당 플레이스홀더에 매핑하고, 마크다운 표·차트 YAML 블록·이미지를 python-pptx 네이티브 객체로 변환합니다. 콘텐츠-플레이스홀더 불일치는 경고 출력과 함께 가능한 만큼 채웁니다.
/generate-ppt <markdown_file> [--output <output.pptx>] [--lang ko|en] [--dry-run]
Executed via: python skills/generate-ppt/generate_ppt.py
| Parameter | 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 |
| Input | Type | Description |
|---|---|---|
markdown_file | File path | Markdown file with YAML frontmatter. Must contain a template: field pointing to the source PPTX. |
template (frontmatter) | PPTX path | The source PPTX template. Resolved relative to the markdown file's directory. |
A PPTX file at the resolved output path.
| Code | Meaning |
|---|---|
0 | Success — PPTX written |
1 | Error (file not found, missing template: field, dependency missing, etc.) |
Success marker (printed to stdout, machine-checkable):
[agent4ppt] PPTX generated → <path>
Verifiable artifacts:
----separated sections in the markdownArtifact validation commands:
python skills/generate-ppt/generate_ppt.py out.md --output out.pptx
echo "Exit: $?" # Must be 0
python -c "
from pptx import Presentation
import re
p = Presentation('out.pptx')
md = open('out.md').read()
body = md.split('---\n', 2)[-1]
slides_md = len(re.split(r'\n---\s*\n', body.strip()))
assert len(p.slides) == slides_md, f'Mismatch: pptx={len(p.slides)} md={slides_md}'
print('PASS: slide count matches')
"
The markdown file must begin with YAML frontmatter.
| Field | Required | Description |
|---|---|---|
template | ✅ | Relative or absolute path to the PPTX template. Relative paths are resolved from the markdown file's directory. |
fname | ❌ | Default output filename (e.g. output.pptx). Overridden by --output. |
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. |
Each slide section is separated by --- and may contain:
> 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*
The type:TYPE annotation declares what content is expected. The generator maps markdown syntax to python-pptx objects according to this contract:
| Placeholder type | Expected input syntax | python-pptx mapping |
|---|---|---|
title, center_title | # Heading text | Heading stripped of #, written as single run |
subtitle | Plain text or # Heading | Heading stripped of #, written as single run |
body | Bullets, numbered lists, bold, italic | Paragraph list with indent levels |
object | Any inline content or ||| multi-column | Fills first column; ||| splits into columns |
picture |  | Image inserted into placeholder frame |
table | GFM markdown table | First row → bold header; remaining rows → body |
chart | ```chart YAML block | Bar, column, line, or pie chart via python-pptx Chart API |
ftr, dt, sldnum | Plain text | Written as-is; typically auto-populated by PPTX |
Mismatches between the declared type: and the actual content syntax produce a warning to stderr but do not abort generation.
| 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 |  | 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 |
<!-- 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]
```
<!-- ph:1 type:object -->
Left column content
- Item A
- Item B
|||
Right column content
- Item C
- Item D
| Condition | Behaviour |
|---|---|
markdown_file not found | Exits 1, prints error + recovery hint to stderr |
template frontmatter field missing | Exits 1, prints error + example frontmatter to stderr |
| Template PPTX file not found | Exits 1, prints error + path check hint to stderr |
| Layout index out of range | Warning printed to stderr, uses layout 0 |
Placeholder idx not found in slide | Warning printed to stderr, placeholder skipped |
| Image file not found | Warning printed to stderr, placeholder left empty |
| Invalid chart YAML | Warning printed to stderr, placeholder left empty |
| Missing dependencies | Exits 1, prints bilingual install instructions to stderr |
This section documents every fatal and non-fatal exception scenario with exact error output and step-by-step recovery instructions.
The skill checks for required packages before any file I/O. If any package is missing it follows a multi-step fallback chain.
| Step | Action | Condition |
|---|---|---|
| 1 | Import check | Try import pptx, import yaml, import markdown_it. If all succeed → proceed normally. |
| 2 | Auto-install | If any package missing and AGENT4PPT_AUTO_INSTALL=1 (default), attempt pip install using two strategies (plain → --user). |
| 3 | Re-verify | After auto-install, re-check imports. If successful → proceed normally. |
| 4 | Guided error | If auto-install is disabled or fails, print bilingual install instructions to stderr and exit with code 1. |
For complete dependency fallback documentation, see the Dependencies section below.
Trigger: The template: frontmatter field points to a .pptx file that does not exist at the resolved path.
Error output (English):
[agent4ppt] Error: template file not found: ./MyTemplate.pptx
Hint: The 'template' field in your markdown frontmatter points to './MyTemplate.pptx'.
• Check that the file exists at this path.
• Relative paths are resolved from the markdown file's directory.
• To obtain a template, run: /parse-ppt-template <your_file.pptx>
• Or copy a .pptx file to the expected path and retry.
Error output (Korean — LANG=ko_KR.UTF-8 or --lang ko):
[agent4ppt] 오류: 템플릿 파일을 찾을 수 없습니다: ./MyTemplate.pptx
힌트: 마크다운 frontmatter의 'template' 필드가 './MyTemplate.pptx'를 가리킵니다.
• 해당 경로에 파일이 존재하는지 확인하세요.
• 상대 경로는 마크다운 파일의 디렉토리 기준으로 해석됩니다.
• 템플릿을 얻으려면: /parse-ppt-template <your_file.pptx> 를 실행하세요.
• 또는 .pptx 파일을 해당 경로에 복사한 후 다시 시도하세요.
Recovery steps:
template: field:
template: ./GIST NetAI PPT Theme.pptx # relative to the .md file
/home/user/slides/content.md and template: ./theme.pptx, the resolver looks for /home/user/slides/theme.pptx./parse-ppt-template to produce a markdown template whose frontmatter contains the correct template: path:
/parse-ppt-template "GIST NetAI PPT Theme.pptx"
cp /path/to/source.pptx ./my_template.pptx
template Frontmatter FieldTrigger: The markdown file has no YAML frontmatter, or the frontmatter is missing the template: key.
Error output (English):
[agent4ppt] Error: 'template' field missing in frontmatter
Hint: Your markdown file must begin with YAML frontmatter that includes a 'template' field.
Example:
---
template: ./my_template.pptx
fname: output.pptx
---
• Run /parse-ppt-template <your_file.pptx> to generate a template with correct frontmatter.
Error output (Korean):
[agent4ppt] 오류: frontmatter에 'template' 필드가 없습니다
힌트: 마크다운 파일은 반드시 'template' 필드를 포함한 YAML frontmatter로 시작해야 합니다.
예시:
---
template: ./my_template.pptx
fname: output.pptx
---
• /parse-ppt-template <your_file.pptx> 를 실행하면 올바른 frontmatter가 포함된 템플릿을 생성합니다.
Recovery steps:
template: field to the YAML frontmatter block at the top of your markdown file./parse-ppt-template — this skill automatically generates a markdown template with all required frontmatter fields pre-filled:
/parse-ppt-template "GIST NetAI PPT Theme.pptx"
# Produces a .md file with:
# ---
# template: GIST NetAI PPT Theme.pptx
# fname: output.pptx
# ...
# ---
--- lines at the very start of the file (no blank lines before the first ---).Trigger: The <markdown_file> argument passed to /generate-ppt does not exist.
Error output (English):
[agent4ppt] Error: markdown file not found: slides.md
Hint: Could not find the markdown content file at 'slides.md'.
• Check that the file path is correct.
• To generate a markdown template from a PPTX, run: /parse-ppt-template <your_file.pptx>
Error output (Korean):
[agent4ppt] 오류: 마크다운 파일을 찾을 수 없습니다: slides.md
힌트: 'slides.md'에서 마크다운 파일을 찾을 수 없습니다.
• 파일 경로가 올바른지 확인하세요.
• PPTX에서 마크다운 템플릿을 생성하려면: /parse-ppt-template <your_file.pptx> 를 실행하세요.
Recovery steps:
ls slides.md
/parse-ppt-template "GIST NetAI PPT Theme.pptx" --output slides.md
The following conditions produce warnings to stderr but do not abort generation. The PPTX is still written with the remaining content.
| Condition | stderr message | Recovery |
|---|---|---|
| Layout index out of range | Warning: layout index N out of range (max M), using layout 0 | Use a valid layout index (0-based). Run /parse-ppt-template to see available layouts. |
Placeholder idx not found | Warning: placeholder idx=N not found in slide layout M, skipping | Verify placeholder indices by running /parse-ppt-template. |
| Image file not found | Warning: image file not found: path/to/img.png, skipping | Check image path; relative paths resolve from the markdown file's directory. |
| Unsupported image format | Warning: unsupported image format '.xyz' ... | Use PNG, JPG, GIF, BMP, TIFF, or WebP. SVG is not supported by python-pptx. |
| Invalid chart YAML | Warning: invalid chart YAML in slide N: <error> | Check chart block syntax — see Chart Block Syntax. |
| Body placeholder not in layout | [agent4ppt] Info: no BODY placeholder in layout for slide N; created textbox fallback | Content is inserted via a textbox (or image) fallback. No action required unless precise positioning is needed. |
| Template layout/placeholder mismatch | ⚠ Template mismatch report (N warning(s)) | Run /revise-ppt to synchronise the markdown to the template. |
# Check dependencies only (no install, exits 0 if OK):
AGENT4PPT_AUTO_INSTALL=0 python skills/generate-ppt/generate_ppt.py slides.md --dry-run
# Validate markdown without writing output:
python skills/generate-ppt/generate_ppt.py slides.md --dry-run
# Check all dependencies are installed:
python -c "import pptx, yaml, markdown_it; print('All dependencies OK')"
# Inspect template structure (finds layout indices and placeholder idx values):
/parse-ppt-template "GIST NetAI PPT Theme.pptx"
# Run project installer to install all required dependencies:
bash scripts/install.sh
# 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
---
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]
## Dependencies
| Package | Min Version | Python Import | Purpose |
|---------|-------------|---------------|---------|
| `python-pptx` | `>= 0.6.21` | `pptx` | PPTX file creation and manipulation |
| `pyyaml` | `>= 6.0` | `yaml` | YAML frontmatter and chart block parsing |
| `markdown-it-py` | `>= 3.0` | `markdown_it` | Markdown content parsing |
### Dependency Check & Auto-Install Fallback
The skill **automatically checks all required dependencies on startup** before any file or argument processing begins. If packages are missing, it follows a **multi-step fallback chain** before exiting.
#### Fallback Chain (executed in `generate_ppt.py::_check_dependencies()`)
| Step | Action | Condition |
|------|--------|-----------|
| 1 | **Import check** | Try `import pptx`, `import yaml`, `import markdown_it`. If all succeed → proceed normally. |
| 2 | **Auto-install** | If any package is missing and `AGENT4PPT_AUTO_INSTALL=1` (default), attempt `pip install` using two strategies (plain → `--user`). |
| 3 | **Re-verify** | After auto-install, re-check imports. If successful → proceed normally. |
| 4 | **Guided error** | If auto-install is disabled or fails, print bilingual (Korean/English) install instructions to stderr and exit with code `1`. |
**Check logic (executed at module load time — before any CLI argument parsing):**
```python
# Step 1 — collect missing packages
missing: list[str] = []
for pkg, pip_name in [("pptx", "python-pptx"), ("yaml", "pyyaml"), ("markdown_it", "markdown-it-py")]:
try:
__import__(pkg)
except ImportError:
missing.append(pip_name)
# Step 2 — auto-install if AGENT4PPT_AUTO_INSTALL=1 (default)
if missing and os.environ.get("AGENT4PPT_AUTO_INSTALL", "1") == "1":
_try_auto_install(missing) # plain pip → --user pip
# Step 3 — re-verify after install
# ... re-import check, clear `missing` if successful ...
# Step 4 — guided error if still missing
if missing:
_print_fallback_instructions(missing, lang)
sys.exit(1)
Auto-install strategies (tried in order, each with 120 s timeout):
1. python -m pip install python-pptx pyyaml markdown-it-py # active venv / managed env
2. python -m pip install --user python-pptx pyyaml markdown-it-py # system Python without venv
Note:
sys.executableis used to ensure the same Python interpreter's pip is invoked. The 120-second timeout per strategy prevents hanging on slow or unavailable networks.
| Variable | Default | Description |
|---|---|---|
AGENT4PPT_AUTO_INSTALL | 1 | Set to 0 to disable automatic pip install on dependency failure. Useful in CI environments that should fail-fast. |
Auto-install attempt (Korean / English):
# Korean (LANG=ko_KR.UTF-8 or --lang ko)
[agent4ppt] 누락된 의존성 자동 설치 시도 중: python-pptx, markdown-it-py
# English (default)
[agent4ppt] Attempting auto-install of missing dependencies: python-pptx, markdown-it-py
Auto-install success:
[agent4ppt] Auto-installed via pip install: python-pptx, markdown-it-py
Guided error when auto-install fails or is disabled (English):
[agent4ppt] Missing dependencies: python-pptx, markdown-it-py
Install with:
pip install python-pptx markdown-it-py
Or run the project installer:
bash scripts/install.sh
To disable auto-install: AGENT4PPT_AUTO_INSTALL=0
Guided error — Korean output (LANG=ko_KR.UTF-8 or --lang ko):
[agent4ppt] 누락된 의존성: python-pptx, markdown-it-py
설치 방법:
pip install python-pptx markdown-it-py
또는 프로젝트 설치 스크립트 실행:
bash scripts/install.sh
자동 설치를 비활성화하려면: AGENT4PPT_AUTO_INSTALL=0
| Missing package | Impact on generation | Fallback behaviour |
|---|---|---|
python-pptx | Fatal — PPTX cannot be read or written | Exit 1; auto-install attempted first |
pyyaml | Fatal — frontmatter and chart YAML cannot be parsed | Exit 1; auto-install attempted first |
markdown-it-py | Fatal — markdown content cannot be parsed | Exit 1; auto-install attempted first |
All three packages are essential; the skill cannot perform any generation without them. The skill therefore exits with code 1 when any package is missing after auto-install (or after auto-install is skipped). No partial output file is written.
Rationale: Writing a partially-filled PPTX silently would be worse than failing loudly. The dependency check runs before any file I/O, so no output artifact is ever left in a corrupt state.
| Priority | Method | Command | When to use |
|---|---|---|---|
| 1 | Built-in auto-install (default) | Automatic on startup | Normal usage; set AGENT4PPT_AUTO_INSTALL=1 |
| 2 | Project installer (recommended) | bash scripts/install.sh | First-time setup; handles venv detection, --user fallback, and PEP 668 |
| 3 | Direct pip install | pip install "python-pptx>=0.6.21" "pyyaml>=6.0" "markdown-it-py>=3.0" | Inside an active virtual environment |
| 4 | User-level pip | pip install --user python-pptx pyyaml markdown-it-py | System Python without venv |
| 5 | uv (fast alternative) | uv pip install python-pptx pyyaml markdown-it-py | When uv is available |
| 6 | Check-only (dry run) | bash scripts/install.sh --check-only | CI pipelines that should fail rather than install |
| 7 | Disable auto-install | AGENT4PPT_AUTO_INSTALL=0 | Environments where pip install is forbidden |
When invoking this skill programmatically, the built-in auto-install handles most cases automatically. For environments where auto-install is disabled (AGENT4PPT_AUTO_INSTALL=0), use this wrapper pattern:
# Recommended agent wrapper pattern when auto-install is disabled:
python skills/generate-ppt/generate_ppt.py "$MD_FILE" --output "$OUT" 2>err.log
EXIT_CODE=$?
if [ $EXIT_CODE -ne 0 ] && grep -q "Missing dependencies" err.log; then
# Attempt recovery via project installer
bash scripts/install.sh
# Retry after installation
python skills/generate-ppt/generate_ppt.py "$MD_FILE" --output "$OUT"
fi
# CI fail-fast pattern (no install, just check):
AGENT4PPT_AUTO_INSTALL=0 python skills/generate-ppt/generate_ppt.py "$MD_FILE" --dry-run
# Quick verification (no install, exit 1 if missing):
bash scripts/install.sh --check-only
# Or inline Python check:
python -c "import pptx, yaml, markdown_it; print('All dependencies OK')"
# Disable auto-install and check only (machine-readable):
AGENT4PPT_AUTO_INSTALL=0 python skills/generate-ppt/generate_ppt.py slides.md --dry-run 2>&1 | grep -E "(OK|Missing)"
The lang field in frontmatter (highest precedence), --lang flag, or $LANG environment variable controls the language of warning/info messages.
Precedence: frontmatter.lang > --lang flag > LANG environment variable > default (en)
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub jinwangmok/agent4ppt --plugin agent4ppt