PPT Master 如何保留现有 PPTX 设计并用新内容填充(Edit Native PPTX)
手里有一份设计已经定稿的 .pptx(公司模板、去年的旧稿、品牌方给的壳子),你不想让它被重新设计,只想换掉内容、调整页面顺序,或者补上演讲者备注和音频——这就是 PPT Master 的 Edit Native PPTX 路由要解决的问题。它把源文件导入一个"保源"(source-preserving)的 round-trip 工作区:没动的页面按字节原样恢复,改过的页面只重建被改的对象,备注、旁白、转场都作为叠加层处理,不触碰可见内容。最终导出的是一个新的 .pptx,源文件的设计完整保留。
前提是已经按 Getting Started 装好 PPT Master:Python 3.10+、一个能读写工作目录并执行 shell 命令的 agent 宿主(Claude Code、Codex、VS Code Copilot 等),并从安装目录安装依赖:
python3 -m pip install -r requirements.txt
完整流程定义在 edit-native-pptx 工作流 中,本文按它的执行顺序展开。
先确认该走哪条路
PPT Master 里"用一份现有 PPT"分四条路,选错会把不想要的页面重做掉。FAQ 给出的判据是两个问题:内容要不要保留?设计(版式 + 视觉)要不要保留?
| 意图 | 路由 | 固定不变的部分 |
|---|---|---|
| 保留内容 + 重做版式 | Generate PPTX + beautify profile | 页数、页序、逐页文案、图表数据 |
| 替换内容 + 保留设计 | Edit Native PPTX | 原生源设计;未改页面按字节保持,选定页面可编辑、重排、重复或省略 |
| 只保留内容,重做设计与分页 | Generate PPTX | 源事实;故事结构和页数可变 |
| 内容和设计都保留 | 不需要生成 | 直接用原文件 |
典型触发形态(工作流 §1):一个被称为"模板"的裸 PPTX + 新材料;"只保留这几页、按这个顺序"的选择性复用;"重做第 5 页和第 7 页"的页面级改写;合并两页内容;或一份成品 deck 只加备注/旁白/自动翻页/转场。只有当"保留设计"和"重新设计"真的模糊时,才需要向对方确认一个问题。
反过来,这份路由有硬边界:全程不运行 pptx_template_import.py、project_manager.py init 或 finalize_svg.py,也不创建 svg_output/——round-trip 工作区本身就是项目,svg_to_pptx.py --roundtrip 是唯一能恢复源幻灯片的导出器。如果你的目的是把设计提炼成可复用模板,那是 Create Template 的事,走完后交给 Generate。
输入准备
- 源 PPTX(必需):它是原生设计的唯一权威。
- 新材料(内容要变时必需):文本、Markdown、文档或 URL。文档/网页类材料先用
source_to_md.py转成 Markdown;只给一个没有事实支撑的主题不够,要么要材料,要么经用户同意后从给定 URL 收集。 - 可选交付意图:受众、页数、必须保留/必须删除的页、是否要备注、旁白、转场、自动翻页。
一条硬性事实规则:页面或备注里每一条实质性陈述都必须来自用户材料;模板里的占位措辞绝不能变成输出内容。没有内容映射(哪页用哪份材料)的页面应被丢弃,而不是硬填。
导入 round-trip 工作区
python3 skills/ppt-master/scripts/pptx_to_svg.py "<source.pptx>" -o "projects/<slug>_<YYYYMMDD>" --inheritance-mode both --roundtrip
其中 <source.pptx> 是你的源文件,<slug>_<YYYYMMDD> 是项目目录名(自定义短名 + 日期)。--roundtrip 要求搭配 --inheritance-mode both。导入后每个源页面对应一张紧凑可编辑 SVG 加一份不可变的原生备份,工作区布局如下(以 工作流 §3 的路径表为准):
| 路径 | 内容 | 使用规则 |
|---|---|---|
authoring-svg-flat/slide_NN.svg |
每个源页面对应一张紧凑 SVG,按顺序 | 只打开你确定要编辑或需要判断是否复用的页面 |
authoring-svg-flat/authoring_summary.json |
页面名册 + 每页画布、文本、图像、矢量、占位符、source-ref、代理对象计数 | 先读它,据此做计划,再开任何 SVG |
images/、icons/imported/、audio/、video/、sounds/ |
源媒体与导入矢量 | 保留原文件名;改动其中任一部分的字节会让所有引用它的输出页重建,格式不匹配会导致导出失败 |
notes/slide_NN.md |
源演讲者备注 | 按输出页增、改、删 |
native-payloads/、analysis/ |
不可变原生备份与工具契约 | 不要读、不要改、不要引用 |
sources/source.pptx |
精确的源包 | 需要批量读页文本时用 ppt_to_md.py "<workspace>/sources/source.pptx" -o "<workspace>/validation/source_readback.md" 而不是逐张打开 SVG |
validation/、exports/ |
诊断与导出产物 | 工具写入 |
一个必须记住的对象:源代理(source proxy)。SmartArt、复杂效果、媒体框这类不支持的 native 对象会以 <image data-pptx-source-proxy="native-restore"> 形式存在,它是原对象的原子替身。留在那里即可恢复原样;Slide 本地代理可以整块删除,继承自 Master/Layout 的代理要保留;编辑代理本体或它的预览素材会导致导出失败。
规划输出页面:page_plan.json
默认行为是"恒等往返":不写 page_plan.json 时,导出结果就是源 deck 本身(页序、内容原样)。只有当输出页册与源不同——删页、重排、复用某页、复制页——才在工作区根目录写 page_plan.json:
{
"schema": "ppt-master.roundtrip-page-plan.v1",
"pages": [
{"source_slide": 1},
{"source_slide": 4, "svg": "chapter_market.svg"},
{"source_slide": 7},
{"source_slide": 7, "svg": "kpi_second_half.svg"}
]
}
字段只有这三个,不多不少:
pages是完整的、非空的输出顺序;source_slide是从 1 开始计的源页索引,决定该页用哪个原生幻灯片做骨架;svg是authoring-svg-flat/里的创作文件名;省略表示直接用该页的slide_NN.svg。想复用同一源页两次,就把它的 SVG 复制一份起新名字,再在计划里列出副本——每个输出页必须对应不同文件,所有额外文件都必须出现在计划中。
导出器会拒绝的计划(fail-closed):同 deck 跳页而目标页缺失或重复、未知/重复/跨页归属的 svg 文件名、越界的 source_slide。省略某个源页时,只由它拥有的音频、视频或不可解码载荷会被一并丢弃,导出时会打印提示;带计划导出还会丢掉 presentation 级 sections 和 custom shows,并重新编号 slide id。
规划时文档给的方法是:把源页面名册当作页面库而不是大纲——源页的版式本身已经编码了一种论述结构(hero 陈述、先总后分、对比、递进、指标行、密集说明),把目标信息和结构逻辑相同的页面对齐,装不下就删内容或删页,而不是硬塞。源页可以移动、省略、复用,目标故事决定顺序。
合并两页时,一个输出页有且只有一个骨架:选版式能承载合并结果的页做骨架,其他页的对象只能通过 adopt 命令搬入(源引用是页内局部的,直接粘贴裸 SVG 会失效):
python3 skills/ppt-master/scripts/svg_authoring_view.py "projects/<slug>_<YYYYMMDD>/authoring-svg-flat" --adopt-object slide_05.svg:<element-id> --into chapter_market.svg
被 adopt 的对象会固化它的有效继承属性与祖先变换、失去原生身份,整页标记为 rebuilt;源代理不能离开自己的页,所以依赖代理的合并必须以该页为骨架。对象落在目标页末尾,再正常编辑位置。
新增页面同样需要骨架:复制最接近的源页并起新名字,在 page_plan.json 里用该页的 source_slide 列出它,删掉 Slide 本地内容后在空白画布上创作(继承来的代理保留),页面标记为 rebuilt。
规划完成后有一个阻塞性确认(§4.3):在动任何 SVG、写备注、生成音频或导出之前,先把完整方案摆出来并等明确确认——输出名册(每页:输出页 → 源页 → referenced / edited / new copy,以及每个被改或被删页的一句话理由)、内容映射(哪份材料去哪、什么内容因为没有合适版式而被丢弃)、每个增强模块的开/关及其效果与时长。聊天里确认即可,确认之后才写 page_plan.json。
编辑页面:只改计划内、保持身份
编辑前文档要求先加载 shared-standards-core.md(第一次编辑时),创作新视觉元素时才看 svg-effects.md,改 native 图表/表格数据时才看 native-data-interface.md。
两条硬规则:
- 只编辑计划内页面。被引用(referenced)的页永远不打开写;导出收据会用
passthrough/cloned_passthrough或patched来证明这一点,被引用页绝不能出现在rebuilt里。 - 就地编辑、保持身份。在现有树内改文本、颜色、位置、内容,对所有你无意改动的对象保留其
data-pptx-*属性——存活的属性按原生恢复,被重写的对象才从你的 SVG 转换。不要把svg_output/惯例或别的 deck 的页面粘贴到 round-trip 页面上。
各类编辑的具体规则(§5 表):
- 替换文本:按槽位的几何与字号判断视觉容量,而不是按旧占位文本的长度;溢出时依次尝试改短 → 拆到另一个选中的页面 → 换更大的源版式;缩字号是最后手段,且绝不全 deck 统一缩。
- 封面/章节页:只替换标题、副标题、作者、章节标签。
- 密集内容页:压缩到该页有的槽位数,溢出内容挪到另一个选中页。
- native 表格/图表:导入对象带
data-pptx-native-authority="json",在行内 JSON 里改单元格文本或类目/系列数值,结构和格式保持源自源文件,导出时必须加--native-charts-and-tables——否则装船的是过期的预览图。 - 图片:让现有
<image>指向images/下的新文件,保留原来的框。 - 新元素:按 shared standards 写规范紧凑 SVG;图标用
icon_sync.py "<workspace>" <lib/name>;需要 AI 图时用image_gen.py --manifest。 - 跨页对象:只能走
--adopt-object;代理不能移动。
编辑完成后有两个必跑命令:刷新汇总,然后跑容量检查门(capacity gate):
python3 skills/ppt-master/scripts/svg_authoring_view.py "projects/<slug>_<YYYYMMDD>/authoring-svg-flat" --refresh-summary
python3 skills/ppt-master/scripts/svg_quality_checker.py "projects/<slug>_<YYYYMMDD>" --roundtrip
--roundtrip 模式会把编辑过的文本与其所在框和画布做估算:error 会阻断导出,直到文本被改短、拆分或挪到更大版式;warning 要么修复,要么带着明确理由接受。导出器本身仍是最后一道门,遇到无法恢复或无法转换的页面会 fail-closed 停下。
可选叠加层:备注、旁白、转场
如果确认的计划里只保留源备注、不加任何模块,这一节整体跳过。
备注以输出页 SVG 的文件名(stem)为键:notes/<stem>.md 对规范页会替换源备注(删除该文件即移除备注);对复制页只作用于该输出页,没有文件时副本继承源备注。备注是口语正文——svg_to_pptx.py 内嵌、notes_to_audio.py 逐字朗读,标题、列表符、[tag]、时长行都会被读出来。每个内容页写 2–5 句自然的话,封面/章节/结尾页一两句,语言整 deck 统一,且备注不得引入页面或材料里没有的陈述。
旁白音频:在备注完成后,对同一工作区路径执行 generate-audio 的 Step 1–4(默认 edge 后端,notes_to_audio.py 从 page_plan.json 解析名册,副本继承,名册不完整会直接拒绝)。源 deck 自带的 audio/ 媒体不动。音频要求每一输出页都有完整备注,缺页时先回 §6 补齐,不能带着部分备注进 TTS。
转场与对象动画:默认保留源 deck 的设置,只在用户要求时替换。全 deck 换转场用 svg_to_pptx.py -t <effect> [--transition-duration <s>];逐页行写在 animations.json;对象动画按 animations.md 创作,行以输出 stem 为键,复制页在没有自己的行时继承源页行。
这里有一个明确的失败现象要提前知道:重建了某个源动画所指向的对象,动画就失去目标,导出会停并报 Edited slide removed source animation target(s)。解法:给该页写自己的行——"<stem>": {"animation": {"effect": "none"}} 直接丢弃源 build,或为页面重新创作动画——然后重新导出。
导出与验证
导出只有一条命令,在工作区根目录运行:
python3 skills/ppt-master/scripts/svg_to_pptx.py "projects/<slug>_<YYYYMMDD>" --roundtrip
按已确认的模块叠加参数:
-t <effect> [--transition-duration <s>]:全 deck 替换转场;--recorded-narration audio --use-narration-timings:旁白 + 自动翻页(round-trip 导出默认读取工作区的animations.json);--animation-config animations.json:逐页运动;-a <preset>(默认none):对象动画策略;--no-notes:剥离备注;--native-charts-and-tables:编辑过图表/表格数据时必须加。
导出写入 exports/ 并打印确切输出路径——若带旁白或 native 图表,文件名会加 _narrated 或 _native_charts_tables 后缀,后续步骤一律使用打印出来的路径。同时打印一张收据(receipt):
Round-trip export summary: output_pages=N passthrough=P cloned_passthrough=C patched=M rebuilt=R
四个桶的含义:passthrough = 恒等页,原始 XML 原样(被引用、无计划、无叠加);cloned_passthrough = 计划中被引用页落在克隆部件上;patched = 形状 XML 未动,但顺序、备注、转场、动画或旁白时长变了;rebuilt = 可见创作内容或所引用的素材发生了变化——恰好是 §4.3 中标记 edited 的页,加上引用了已变更素材的页。只加交付层(notes/motion 等)不改可见内容的任务,收据必须显示 rebuilt=0,这是判断"设计是否真的保住了"的直接指标。
验证用两个脚本(工作流 §7 原样给出,脚本位于 skills/ppt-master/scripts/):
pptx_delivery_check.py "<printed_output.pptx>" > ".../validation/<output_stem>.delivery.json"
ppt_to_md.py "<printed_output.pptx>" -o ".../validation/readback.md"
- 交付检查:无结构性错误;advisory 级别的问题需人工过一遍。
- 回读核对:幻灯片数量等于计划长度(或源页数)、关键标题与被替换的文本确实出现、备注数量吻合、收据分桶与确认过的名册一致。
FAQ 里对应问题("I already have a finished .pptx — can I reuse its design and just fill in new content?")还提到:如果源页面库缺了故事需要的新结构(而不只是换内容),那就不属于这条路由——回到普通 Generate,或先跑 Create Template 再从生成的工作区 Generate。
边界与不支持项
工作流 §8 明确列出当前支持面:
- 支持:未改页面按字节引用(选择/重排/重复/省略);选定页上编辑文本、颜色、图片、native 表格单元格、native 图表数据(图表/表格编辑只有配合
--native-charts-and-tables才生效);按规范紧凑 SVG 创作新元素;SmartArt、复杂效果、嵌入媒体以原子代理形式保留;备注、旁白、自动翻页、转场、对象动画作为以输出页为键的叠加层。 - 不支持:删除复制页继承来的源备注(需要给副本写自己的
notes/<stem>.md);编辑源代理;改变幻灯片尺寸;给现有 deck 添加 Master/Layout 结构——这些需求走 Create Template → Generate 的生命周期。
导出失败时不要绕过导出器手改 XML:native-payloads/ 与 analysis/ 是工具契约区,导出器对无法恢复的页面是 fail-closed 设计,报 Edited slide removed source animation target(s) 这类错误时应按上文修正页面计划后重跑,而不是放宽检查。
核对清单
完成一次 Edit Native PPTX 交付,工作区里应能看到(对应 §7 的收尾清单):
- 工作区位于
projects/<slug>_<YYYYMMDD>/,计划已确认,名册有变化时page_plan.json已写入; - 只编辑了计划内页面,
authoring_summary.json已刷新,svg_quality_checker.py --roundtrip无 error; - 备注/音频/动画按确认的方案完成,
--roundtrip收据分桶与确认名册一致(纯交付任务rebuilt=0); validation/下有交付 JSON 与回读 Markdown,最终 deck 在打印出来的exports/路径上。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0631
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
video-shotcraftAI宣传片skill,使用 Remotion 制作电影级产品视频:提供106 张镜头配方卡和可复用的视频魔板。适用于 Claude Code 与 Codex以及所有其他智能体Markdown00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python09
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00