# Local Ppt Builder

> 使用 @oai/artifact-tool 命令式 API 制作可直接使用、可编辑的本地 PPTX 的工程化流程：需求参数、环境约束、内容与备注规范、构图与字号规范、四步质检与交付。当用户要求创建/生成/修改本地 PPT、PPTX、幻灯片并交付可编辑文件，或要求演讲备注、占位符清单、布局与渲染验收时使用；与官方 presentations 技能配合，官方决定内容与版式，本技能保证工程执行与交付质量。

- Skill: `rain-flower/local-ppt-builder` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add rain-flower/local-ppt-builder`
- Raw SKILL.md: https://api.skillmd.com/api/skills/rain-flower/local-ppt-builder/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Docs & Writing
- Author: Rain-flower (https://skillmd.com/u/rain-flower)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/rain-flower/local-ppt-builder

---


# 本地 PPT 制作（Artifact API）

## 定位

与官方 presentations 技能配合使用。官方技能负责叙事、版式与视觉；本技能负责工程化生产、环境避坑与四步质检。每次制作先读官方 presentations SKILL.md、style_guidelines.md、API_QUICK_START.md、API_DOCS.md，再按本流程执行。

## 需求参数（开工前确认）

按以下参数开始，缺失时主动向用户确认或按兜底规则执行：

- 主题、受众、时长（决定页数与节奏，如 5 分钟约 8–10 页）
- 风格：商务 / 学术 / 活泼 / 路演等；用户未指定时用 Codex Grid 布局库
- 已有材料：有 / 无。**无材料时一律用可见占位符（如“（待替换）”“XXX”），绝不编造经历与数据**
- 成品规格：16:9（1280×720）可编辑 .pptx，页数与时长匹配，每页含演讲备注

## 环境与运行约束（长期有效，直接执行，不要重复踩坑）

1. **Node / Python 不在 PATH**：执行任何 node/python 命令前，先调用 `load_workspace_dependencies` 获取运行时绝对路径，否则报 `command not found`。
2. **不用 JSX**：Node 原生不支持 JSX，工作区无 esbuild/tsx/babel 转译器。统一用命令式 API（`Presentation.create`、`slide.shapes.add`、`shape.text.style`）配合绝对像素坐标排版。
3. **中文文件名陷阱**：保存 PPTX 用纯文件系统绝对路径（`fileURLToPath` 解码），不能把 URL 的 `pathname` 直接当路径，否则落盘成百分号编码文件名。
4. **安全策略**：文件编辑用 `apply_patch`，不用 `cat` 等命令写文件；不用 `rm -f`（环境拒绝），清理时用 `mv` 归档到临时目录。
5. **画布边界**：所有形状（含装饰圆、光斑、色条、横线）必须完全位于画布内；任何“出血”装饰都会被官方溢出检测判为整页失败。
6. **无视觉能力**：当前会话可能无法查看渲染图，不得依赖目视；必须用程序化验收替代（见质检流程）。
7. **文字适配估算会误报**：不要用“全文字宽 + 固定行距”的粗略估算直接下结论；以布局 JSON 中引擎实际计算的 `textLayout.lineCount` 为准，hard（越界/意外换行/文字互叠）与 soft（高度风险）分级处理。
8. **shell 小坑**：zsh 中输出分隔符用引号 `echo '---'`，避免 `=` 扩展报错。

## 生产流程（按顺序执行）

### 1. 定视觉路线（三选一，选定后不混用）

- 用户给了参考模板 → 按模板跟随流程，不引入 Codex Grid
- 用户给了明确风格 → 自定义视觉
- 无方向 → 使用 Codex Grid 布局库（读其 ARTIFACT、design_tokens.json、template-registry.json，按角色与密度挑选版式，保留版式层级与媒体框，替换示例内容）

### 2. 准备环境

设置 `SKILL_DIR`（官方 presentations 技能目录）、`TMP_DIR`（工作区内的临时构建目录）、`FINAL_PPTX`（成品绝对路径）。中间产物放 TMP_DIR，成品放用户工作区。

```bash
node "$SKILL_DIR/container_tools/setup_artifact_tool_workspace.mjs" --workspace "$TMP_DIR"
```

### 3. 内容策划

先明确一句话主张与叙事主线（如 问题→方案→证据→行动）。每页只传达一个核心观点；标题用结论式；正文 3–5 条短句；页数与时长相匹配。

### 4. 编写生成脚本

在 TMP_DIR 下写 ES module（`.mjs`）：

- 默认命令式 API + 绝对像素坐标；标题、卡片、徽章、装饰均用原生 shape 组合
- 输出 PPTX（`PresentationFile.exportPptx` + `pptx.save(FINAL_PPTX)`）的同时导出每页 PNG（`presentation.export({ slide, format: "png", scale: 1 })`）与 layout JSON（`slide.export({ format: "layout" })`）
- 演讲备注用 `slide.speakerNotes.textFrame.setText(...)` 写入

### 5. 内容与备注规范

- 无材料处用可见占位符，不编造
- 每页演讲备注：口语稿 + 转场语 + 关键页追问预案；建议时长放备注
- 外部资料一律加 `[Sources]` 块并说明来源
- 可见文案只写给受众，不出现制作提示、时间分配、计划脚手架（占位符除外）

### 6. 构图与字号规范

- 所有元素在画布内；标题保持单行（宽度估算 CJK≈1em、ASCII≈0.55em，留 10% 余量）
- 正文盒高：行数 × 字号 × 1.3 ≤ 盒高 − insets
- 字号下限：封面标题 ≥50pt、页标题 ≥35pt、小标题/卡片标题 ≥24pt、正文 ≥16pt
- 每页信息密度适中，避免挤满；先删文字，不靠缩小字号

## 四步质检（必做，全部通过才交付）

1. 渲染每页 PNG，并导出每页 layout JSON。
2. 跑官方 `slides_test.py`：`python3 "$SKILL_DIR/container_tools/slides_test.py" "$FINAL_PPTX"`，画布溢出必须清零。
3. 跑 `scripts/check_layout.mjs`：`node scripts/check_layout.mjs <layout-json目录> --size 1280x720`；越界/意外换行/高度风险/文本框互叠，hard 必须清零，soft 逐条人工确认。
4. OCR 抽查：macOS 用 `scripts/ocr_swift.swift`（Vision 框架）抽查每页关键文字是否渲染完整、位置正确；其他平台用可用 OCR 工具替代。

## 交付

- 给出成品绝对路径，用 `:codex-file-citation{path=... purpose="output"}` 引用
- 列出全部待用户替换的占位符与每页建议时长
- 附质检结果摘要（溢出检测 / 布局检查 / OCR 抽查）

## 资源

### scripts/

- `check_layout.mjs` — 布局 JSON 质检脚本：画布边界、意外换行、高度风险、文本框互叠。
- `ocr_swift.swift` — macOS Vision OCR 脚本，抽查渲染 PNG 的文字完整性；编译 `swiftc -O ocr_swift.swift -o ocr` 后逐张运行。

