关于 powerpoint
PowerPoint Skill 使用 python-pptx 根据 YAML 定义生成和管理幻灯片,适合需要脚本化创建、提取、更新和校验演示文稿的用户。
主要功能
- 01通过 YAML 定义内容与样式
- 02生成和更新幻灯片
- 03提取现有 PPTX 内容
- 04几何与视觉校验
- 05导出为图片或 SVG
适用场景
- 01根据结构化内容生成演示文稿
- 02更新演示文稿中的指定幻灯片
- 03检查版式与视觉问题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ microsoft/ hve-core --skill powerpoint安装后在 Claude Code 中输入/powerpoint确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
content-extra-py-template.mdcontent-yaml-template.mdpyproject.tomlreferences/script-reference.mdscripts/build_deck.pyembed_audio.pyembed-audio.shexport_slides.pyexport_svg.pyexport-svg.shextract_content.pygenerate_themes.pygenerate-themes.shInvoke-EmbedAudio.ps1Invoke-ExportSvg.ps1Invoke-GenerateThemes.ps1invoke-pptx-pipeline.shInvoke-PptxPipeline.ps1pdf_safety.pypptx_charts.pypptx_colors.pypptx_fills.pypptx_fonts.pypptx_shapes.pypptx_tables.pypptx_text.pypptx_utils.pyrender_pdf_images.pyvalidate_deck.pyvalidate_geometry.py详细介绍
PowerPoint 技能
使用 python-pptx,并通过 YAML 驱动的内容和样式定义来生成、更新和管理 PowerPoint 幻灯片。
概述
此技能提供 Python 脚本,用于读取 YAML 配置文件并生成 PowerPoint 幻灯片。每张幻灯片都由 content.yaml 文件定义,其中描述了布局、文本和形状。style.yaml 文件定义尺寸、模板配置、布局映射、元数据和默认值。
SKILL.md 涵盖技术参考内容:先决条件、命令、脚本架构、API 限制和故障排除。有关约定和设计规则(元素定位、视觉质量、颜色和对比度、情境化样式),请遵循 pptx.instructions.md。
先决条件
PowerShell
Invoke-PptxPipeline.ps1 脚本通过 uv sync 自动创建虚拟环境并安装依赖项。需要 uv、Python 3.11+ 和 PowerShell 7+。
安装 uv
如果尚未安装 uv,请使用能够通过已发布的哈希值验证下载内容的包管理器:
# Windows
winget install --id astral-sh.uv -e
# macOS / Linux (Homebrew)
brew install uv
如需改用发行版归档文件安装,请从 uv 发布页面下载,并在解压前使用其 .sha256 文件进行校验。
系统依赖项(导出和验证)
“导出”和“验证”操作需要 LibreOffice 将 PPTX 转换为 PDF;此外,还可选用 poppler 中的 pdftoppm 将 PDF 渲染为 JPG。如果没有 pdftoppm,PyMuPDF 会负责图像渲染。
“验证”操作中基于视觉的检查需要使用 GitHub Copilot CLI 访问模型。
# macOS
brew install --cask libreoffice
brew install poppler # optional, provides pdftoppm
# Linux
sudo apt-get install libreoffice poppler-utils
# Windows (winget preferred, choco fallback)
winget install TheDocumentFoundation.LibreOffice
# choco install libreoffice-still # alternative
# poppler: no winget package; use choco install poppler (optional, provides pdftoppm)
Copilot CLI(视觉验证)
validate_slides.py 脚本使用 GitHub Copilot SDK 将幻灯片图像发送给支持视觉能力的模型。必须安装并完成身份验证的 Copilot CLI:
# Install Copilot CLI
npm install -g @github/copilot-cli
# Authenticate (uses the same GitHub account as VS Code Copilot)
copilot auth login
# Verify
copilot --version
必需文件
style.yaml— 尺寸、默认值、模板配置和元数据content.yaml— 每张幻灯片的内容定义(文本、形状、图像、布局)- (可选)
content-extra.py— 用于复杂幻灯片绘制的自定义 Python 代码
内容目录结构
所有幻灯片内容都存放在工作目录下的 content/ 文件夹中:
content/
├── global/
│ ├── style.yaml # Dimensions, defaults, template config, and theme metadata
│ └── voice-guide.md # Voice and tone guidelines
├── slide-001/
│ ├── content.yaml # Slide 1 content and layout
│ └── images/ # Slide-specific images
│ ├── background.png
│ └── background.yaml # Image metadata sidecar
├── slide-002/
│ ├── content.yaml # Slide 2 content and layout
│ ├── content-extra.py # Custom Python for complex drawings
│ └── images/
│ └── screenshot.png
├── slide-003/
│ ├── content.yaml
│ └── images/
│ ├── diagram.png
│ └── diagram.yaml
└── ...
全局样式定义(style.yaml)
全局 style.yaml 定义尺寸、模板配置、布局映射、元数据和默认值。颜色和字体按元素在各张幻灯片的 content.yaml 中指定,而不是集中定义在样式文件中。
完整模板、字段参考和使用说明,请参阅 style.yaml 模板。
每张幻灯片的内容定义(content.yaml)
每张幻灯片的 content.yaml 定义布局、文本、形状和位置。所有位置和尺寸值的单位均为英寸。颜色值使用 #RRGGBB 十六进制格式或 @theme_name 引用。
文本约定:渲染时,textbox.text 和 shape.text 中类似 Markdown 列表的行会被解析为 PowerPoint 列表。无序标记(-、+、*)会转换为项目符号段落,有序标记(1.、1))会转换为自动编号段落,行首缩进会映射为段落级别。
完整模板、支持的元素类型、支持的形状类型和使用说明,请参阅 content.yaml 模板。
无障碍功能:每张幻灯片的 title 会作为屏幕阅读器播报和导航所用的幻灯片标题;图像上的 alt 或 decorative 用于设置其替代文本;style.yaml 中的 metadata.language 用于设置文档和文本的语言。
复杂绘图(content-extra.py)
如果幻灯片需要的复杂绘图无法通过 content.yaml 元素定义来实现,请在幻灯片文件夹中创建 content-extra.py 文件。render() 函数的签名固定。构建脚本会在放置完标准 content.yaml 元素后调用该函数。
完整模板、函数参数和使用指南,请参阅 content-extra.py 模板。
安全验证
默认情况下,content-extra.py 的执行处于禁用状态。当幻灯片文件夹中包含该文件,且未传入 --allow-scripts 时,构建会失败,并显示指明文件名的错误。检查脚本后,传入 --allow-scripts 以授权执行。
授权执行后,构建脚本会在运行文件前执行基于 AST 的静态分析,并拒绝以下模式。此分析是一种 lint,用于及早发现明显错误。它不是安全边界:通过别名导入被阻止的模块无法被检测到,而且允许使用 pathlib 和 open。授权才是控制手段。
允许导入:
pptx及所有pptx.*子模块- 安全的标准库模块(例如
math、copy、json、re、pathlib、collections、itertools、functools、typing、enum、dataclasses、decimal、fractions、string、textwrap)
禁止导入:
subprocess、os、shutil、socket、ctypes、signal、multiprocessing、threading、http、urllib、ftplib、smtplib、imaplib、poplib、xmlrpc、webbrowser、code、codeop、compileall、py_compile、zipimport、pkgutil、runpy、ensurepip、venv、sqlite3、tempfile、shelve、dbm、pickle、marshal、importlib、sys、telnetlib- 允许列表中未列出的任何第三方包
禁止的内置函数:
- 危险函数:
eval、exec、__import__、compile、breakpoint - 间接绕过函数:
getattr、setattr、delattr、globals、locals、vars - 对
builtins、os、sys、subprocess和importlib使用属性形式的调用(例如builtins.eval(...))
--allow-scripts 标志:
传入 --allow-scripts 以授权执行 content-extra.py 文件。如果存在脚本但未传入该标志,构建会失败,而不会跳过脚本,因此演示文稿不会悄无声息地丢失自定义绘图。该标志用于授权执行,不会跳过 lint。
此项属于行为变更。以前只要存在 content-extra.py 就能构建的演示文稿,现在需要传入 --allow-scripts;依赖被禁止导入的脚本也不再能绕过限制。
python scripts/build_deck.py \
--content-dir content/ \
--style content/global/style.yaml \
--output slide-deck/presentation.pptx \
--allow-scripts
验证失败时,构建会抛出 ContentExtraError,并在错误消息中指出违规内容和文件路径。
脚本参考
完整的命令列表见 references/script-reference.md:构建演示文稿、从模板构建、更新指定幻灯片、从现有 PPTX 中提取内容、验证、将幻灯片导出为图像或 SVG、试运行验证、生成主题变体,以及嵌入音频。
脚本架构
构建和提取脚本使用 scripts/ 目录中的共享模块:
| 模块 | 用途 |
|---|---|
pptx_utils.py | 共享工具:退出代码、日志配置、幻灯片筛选器解析、单位转换(emu_to_inches())、YAML 加载 |
pptx_colors.py | 颜色解析(#hex、@theme、带亮度的字典)、主题颜色映射(16 个条目) |
pptx_fonts.py | 字体解析、字体系列规范化、字重后缀处理、对齐方式映射 |
pptx_shapes.py | 形状常量映射(29 个条目及圆形别名)、自选图形名称映射、旋转工具 |
pptx_fills.py | 纯色、渐变和图案填充的应用与提取;带虚线样式的线条/边框样式设置 |
pptx_text.py | 文本框属性(边距、自动调整大小、垂直锚点)、段落属性(间距、级别)、文本运行属性(下划线、超链接)、将类 Markdown 列表解析为项目符号/自动编号段落 |
pptx_tables.py | 表格元素的创建与提取,支持单元格合并、带状样式和单元格级样式设置 |
pptx_charts.py | 12 种图表类型(柱形图、条形图、折线图、饼图、散点图、气泡图等)的图表元素创建与提取 |
validate_deck.py | 仅针对 PPTX 的验证,包括演讲者备注和幻灯片数量 |
validate_geometry.py | 结构验证,包括元素边距、相邻间距、边界溢出和标题间距 |
validate_slides.py | 通过 Copilot SDK 进行基于视觉的幻灯片问题检测和质量验证,包含内置检查,并按幻灯片输出纯文本结果 |
render_pdf_images.py | 使用 PyMuPDF 将 PDF 渲染为 JPG,可选择按幻灯片编号命名 |
generate_themes.py | 使用颜色映射 YAML 文件,根据基础内容目录生成主题变体 |
embed_audio.py | 将 WAV 音频嵌入 PPTX 幻灯片,支持逐张幻灯片匹配文件,并将音频图标放置在画面外 |
export_svg.py | 通过 LibreOffice 转换为 PDF 并使用 PyMuPDF 渲染 SVG,实现 PPTX 到 SVG 的导出 |
python-pptx 的限制
- python-pptx 不支持 SVG 图像。请始终使用
cairosvg或Pillow转换为 PNG。 - python-pptx 无法以编程方式创建新的幻灯片母版或版式。请使用空白版式,或通过
--template参数从模板 PPTX 开始。 - 打开并保存现有文件时会保留切换效果和动画,但无法通过 API 创建或修改这些效果。
- 提取内容时,由于幻灯片母版和版式的继承关系,许多文本元素没有内联样式。重建前,请在内容 YAML 中添加明确的字体属性。
- 导出和验证操作需要 LibreOffice 执行 PPTX 到 PDF 的转换。PowerShell 编排器会在启动前检查 LibreOffice 是否可用,如果缺失,则提供针对相应平台的安装说明。
- 在继承背景的幻灯片上访问
background.fill会将背景替换为NoFill。访问填充属性前,请检查slide.follow_master_background。 - 渐变填充使用 python-pptx 的
GradientFillAPI 和GradientStop对象。每个渐变色标都指定一个位置(0–100)和一种颜色。 - 主题颜色通过
MSO_THEME_COLOR枚举解析。亮度调整通过颜色格式的brightness属性应用。 - 基于模板构建时,按名称或索引加载版式。如果找不到匹配项,版式名称解析会回退到索引 6(空白)。
安全注意事项
此技能通过 PyMuPDF 处理 PDF 文件;该库封装了 MuPDF C 库。MuPDF 会解析不受信任的二进制结构(交叉引用表、流对象、字体定义),而以往的 CVE 表明,C 语言解析器中的内存安全漏洞可能导致崩溃、内存泄露,或在极少数情况下导致代码执行。
已采取的缓解措施
- 在调用
fitz.open()前,scripts/pdf_safety.py会验证每个 PDF(文件是否存在、是否为常规文件、大小是否 <= 100 MB、是否包含%PDF-魔数、页数是否 <= 1000)。 - 所有
fitz操作都封装在safe_open_pdf()中,该函数会将 MuPDF 异常转换为带类型的PdfSafetyError子类(PdfTooLargeError、PdfInvalidFormatError、PdfTooManyPagesError、PdfParseError、PdfRenderError)。 pyproject.toml中将pymupdf固定在特定版本范围(>=1.27.1,<2.0),以跟进安全修复,同时避免静默采用会导致 API 变更的主版本。
深度防御说明:5 字节的
%PDF-魔数检查是结构有效性的必要条件,但并非充分条件。以%PDF-开头的精心构造的小文件仍会进入 MuPDF 解析器,而其中可能存在内存安全漏洞。调用方必须及时更新 PyMuPDF,以应对最新安全公告(通过 microsoft/hve-core#1020 /pip-audit跟踪),并继续将此类输入视为不受信任内容。PdfSafetyError层级(PdfTooLargeError、PdfInvalidFormatError、PdfTooManyPagesError、PdfParseError、PdfRenderError)与版本固定和 CVE 监控共同构成一层防御;任何单一防御层都不足以独立应对风险。
已接受的风险
这些缓解措施可以降低但无法消除 C 扩展的攻击面。使用者应将来自此技能 PPTX 到 PDF 转换流程之外的 PDF 输入视为不受信任内容,并在处理恶意输入前应用额外的沙箱措施(子进程、容器)。
更新策略
每季度以及每次收到 pip-audit 警报时,重新检查 MuPDF 和 PyMuPDF 的 NVD 和 OSV 安全公告。
交叉引用
- microsoft/hve-core#1018 — 原始加固请求
- microsoft/hve-core#1020 — 用于持续监控 CVE 的 pip-audit CI(独立工作)
故障排除
| 问题 | 原因 | 解决方案 |
|---|---|---|
| SVG 运行时错误 | python-pptx 无法嵌入 SVG | 添加前通过 cairosvg 转换为 PNG |
| 元素之间的文本重叠 | 垂直间距不足 | 遵循 pptx.instructions.md 中的元素定位规范 |
| 宽度超出幻灯片范围 | 元素超出幻灯片边界 | 遵循 pptx.instructions.md 中的元素定位规范 |
| 明亮的强调色作为填充时难以辨认 | 明亮背景上的白色文字 | 将用于框填充的强调色饱和度降低至约 60% |
| 背景填充被替换为 NoFill | 在继承的背景上访问了 background.fill | 访问前检查 slide.follow_master_background |
| 缺少演讲者备注 | content.yaml 中未指定备注 | 为每张内容幻灯片添加 speaker_notes 字段 |
| 验证期间找不到 LibreOffice | Validate 会先将幻灯片导出为图像 | 安装 LibreOffice:brew install --cask libreoffice(macOS) |
找不到 uv | 未安装 uv 包管理器 | 安装 uv:winget install --id astral-sh.uv -e(Windows)或 brew install uv(macOS/Linux);参见上文“安装 uv” |
| uv 找不到 Python | PATH 中没有 Python 3.11 或更高版本 | 通过 uv python install 3.11 或 pyenv install 3.11 安装 |
uv sync 失败 | .venv 缺失或损坏 | 删除技能根目录下的 .venv/,然后重新运行 uv sync |
| 脚本中出现导入错误 | 依赖项未安装或虚拟环境已过期 | 在技能根目录运行 uv sync 以重新创建环境 |
环境恢复
当脚本因模块缺失、导入错误或虚拟环境损坏而失败时,请通过以下方式恢复:
cd "<powerpoint-skill-root>"
rm -rf .venv
uv sync
运行命令前,请根据已加载的技能位置确定 <powerpoint-skill-root>。
这会使用 pyproject.toml 作为唯一事实来源,从头重建虚拟环境。除非传入 -SkipVenvSetup,否则 Invoke-PptxPipeline.ps1 编排器会在每次调用时自动运行 uv sync。
如果 uv 本身不可用,请先安装它(参见上文“安装 uv”),然后重试。如果 Python 3.11 或更高版本不可用,请运行 uv python install 3.11,让 uv 获取并管理该解释器。