7.1 KiB
name, description, license
| name | description | license |
|---|---|---|
| ppt-editing-skill | 使用 XML 安全的工作流程编辑现有的 PowerPoint 文件或模板。适用于基于模板的演示文稿更新:分析布局、将内容映射到幻灯片、安全地复制/重新排序/删除幻灯片、并行编辑幻灯片 XML、清理孤立资源,并重新打包经过验证的 PPTX 输出。 | 专有许可。完整条款见 LICENSE.txt |
编辑演示文稿
基于模板的工作流程
使用现有演示文稿作为模板时:
-
复制并分析:
cp /path/to/user-provided.pptx template.pptx python -m markitdown template.pptx > template.md查看
template.md以了解占位文本和幻灯片结构。 -
规划幻灯片映射:为每个内容段落选择合适的模板幻灯片。
⚠️ 使用多样化的布局——单调的演示文稿是常见的失败模式。不要默认使用基本的标题加项目符号幻灯片。主动寻找:
- 多列布局(2 列、3 列)
- 图片与文字组合
- 满版图片加文字叠加
- 引用或标注幻灯片
- 章节分隔页
- 统计数据/数字标注
- 图标网格或图标加文字行
避免: 每张幻灯片重复使用相同的纯文本密集型布局。
将内容类型与布局风格相匹配(例如,关键点→项目符号幻灯片,团队信息→多列布局,客户评价→引用幻灯片)。
-
解包
-
构建演示文稿(亲自完成,不要使用子代理):
- 删除不需要的幻灯片(从
<p:sldIdLst>中移除) - 复制要重复使用的幻灯片(
add_slide.py) - 在
<p:sldIdLst>中重新排序幻灯片 - 在第 5 步之前完成所有结构变更
- 删除不需要的幻灯片(从
-
编辑内容:更新每个
slide{N}.xml中的文本。 如果可用,在此处使用子代理——幻灯片是独立的 XML 文件,因此子代理可以并行编辑。 -
清理
-
打包
输出结构
将用户提供的文件复制到当前工作目录的 template.pptx。这样可以保留原始文件,并为所有下游脚本提供可预测的名称。
cp /path/to/user-provided.pptx template.pptx
./
├── template.pptx # 用户提供的文件副本(绝不修改)
├── template.md # markitdown 提取结果
├── unpacked/ # 可编辑的 XML 树
└── edited.pptx # 最终重新打包的演示文稿
最低预期交付物:edited.pptx。
脚本
| 脚本 | 用途 |
|---|---|
unpack.py |
提取并美化打印 PPTX |
add_slide.py |
复制幻灯片或从布局创建 |
clean.py |
移除孤立文件 |
pack.py |
重新打包并验证 |
移除不在 <p:sldIdLst> 中的幻灯片、未引用的媒体文件以及孤立的关联关系。
始终先写入 /tmp/,然后再复制到最终路径。Python 的 zipfile 模块内部使用 seek,这在某些卷挂载(例如 Docker 绑定挂载)上会失败。先写入本地临时路径可以避免此问题。
验证、修复、压缩 XML,并重新编码智能引号。
幻灯片操作
幻灯片顺序在 ppt/presentation.xml → <p:sldIdLst> 中定义。
重新排序:重新排列 <p:sldId> 元素。
删除:移除 <p:sldId>,然后运行 clean.py。
添加:使用 add_slide.py。切勿手动复制幻灯片文件——该脚本会处理手动复制时遗漏的备注引用、Content_Types.xml 和关联关系 ID。
编辑内容
子代理: 如果可用,在此处使用它们(在完成第 4 步之后)。每张幻灯片是一个独立的 XML 文件,因此子代理可以并行编辑。在给子代理的提示中,请包含:
- 要编辑的幻灯片文件路径
- "对所有更改使用 Edit 工具"
- 下面的格式化规则和常见陷阱
对于每张幻灯片:
- 读取幻灯片的 XML
- 识别所有占位内容——文本、图片、图表、图标、说明文字
- 将每个占位符替换为最终内容
使用 Edit 工具,而不是 sed 或 Python 脚本。 Edit 工具要求精确指定要替换的内容及其位置,从而提供更高的可靠性。
格式化规则
- 将所有标题、副标题和内联标签加粗:在
<a:rPr>上使用b="1"。这包括:- 幻灯片标题
- 幻灯片内的段落标题
- 行首的内联标签(例如:"状态:"、"描述:")
- 绝不使用 Unicode 项目符号(•):使用正确的列表格式化,搭配
<a:buChar>或<a:buAutoNum> - 项目符号一致性:让项目符号继承自布局。仅在需要时指定
<a:buChar>或<a:buNone>。
常见陷阱
模板适配
当源内容比模板项目少时:
- 完全移除多余元素(图片、形状、文本框),而不仅仅是清空文本
- 清除文本内容后检查是否有残留的视觉元素
- 使用
markitdown进行内容质量检查,以发现数量不匹配的问题
当用不同长度的内容替换文本时:
- 替换为较短内容:通常安全
- 替换为较长内容:可能导致溢出或意外的换行
- 在文本更改后使用
markitdown进行验证 - 考虑截断或拆分内容以适应模板的设计限制
模板槽位 ≠ 源项目:如果模板有 4 个团队成员但源只有 3 个用户,请删除第 4 个成员的整个组合(图片加文本框),而不仅仅是清空文本。
多项内容
如果源包含多个项目(编号列表、多个段落),请为每个项目创建独立的 <a:p> 元素——绝不将它们合并为一个字符串。
❌ 错误做法——所有项目在一个段落中:
<a:p>
<a:r><a:rPr .../><a:t>步骤 1:做第一件事。步骤 2:做第二件事。</a:t></a:r>
</a:p>
✅ 正确做法——分段落并加粗标题:
<a:p>
<a:pPr algn="l"><a:lnSpc><a:spcPts val="3919"/></a:lnSpc></a:pPr>
<a:r><a:rPr lang="en-US" sz="2799" b="1" .../><a:t>步骤 1</a:t></a:r>
</a:p>
<a:p>
<a:pPr algn="l"><a:lnSpc><a:spcPts val="3919"/></a:lnSpc></a:pPr>
<a:r><a:rPr lang="en-US" sz="2799" .../><a:t>做第一件事。</a:t></a:r>
</a:p>
<a:p>
<a:pPr algn="l"><a:lnSpc><a:spcPts val="3919"/></a:lnSpc></a:pPr>
<a:r><a:rPr lang="en-US" sz="2799" b="1" .../><a:t>步骤 2</a:t></a:r>
</a:p>
<!-- 继续此模式 -->
从原段落复制 <a:pPr> 以保留行间距。在标题上使用 b="1"。
智能引号
由 unpack/pack 自动处理。但 Edit 工具会将智能引号转换为 ASCII 码。
添加包含引号的新文本时,请使用 XML 实体:
<a:t>the “Agreement”</a:t>
| 字符 | 名称 | Unicode | XML 实体 |
|---|---|---|---|
" |
左双引号 | U+201C | “ |
" |
右双引号 | U+201D | ” |
' |
左单引号 | U+2018 | ‘ |
' |
右单引号 | U+2019 | ’ |
其他
- 空白字符:在包含前导或尾随空格的
<a:t>上使用xml:space="preserve" - XML 解析:使用
defusedxml.minidom,而非xml.etree.ElementTree(后者会破坏命名空间)