SuperAPI AI 工具集

pptx-to-md

办公与效率

查看项目

更新于 10-16 02:12

技能介绍

用途

pptx-to-md 是一个把 .pptx 幻灯片转换为逐页 Markdown 的技能。它把一份演示文稿拆成每张幻灯片一个 Markdown 文件,既保留逐字文本,也保留嵌入截图、示意图和图表在其版面上下文中的含义。它不会改写文字,也不会脱离上下文描述图片。输出适合作为内容提升(content uplift)、Markdown 转 HTML 构建或其他下游转换的输入。

何时使用

当演示文稿把文字与嵌入的截图、示意图、图表或代码示例混排,且版面本身有意义(分栏、并排面板、标注框)时适用。纯文本提取会丢失版面或图片含义。

重要提示:如果演示文稿是 PDF、纯文本,或没有对内容有意义的图片,使用 uvx 'markitdown[all]' <path-to-file> -o output.md 更快,通常也足够,无需走本技能更复杂的流程。可以先尝试该方式并请用户审阅输出,告知若不够充分再继续更复杂的幻灯片提取流程。

流程

PPTX -> prepare.py -> 清单 + 渲染 JPG + 嵌入 PNG -> 每张幻灯片派发一个子智能体 -> 逐页 Markdown 文件 -> concatenate.py -> deck.md

编排者(调用会话中的你)做两件事:运行 prepare 和 concatenate 脚本,并为每张可见幻灯片派发一个子智能体。每个子智能体负责一张幻灯片的视觉与文本合成,并写出一个 Markdown 文件。子智能体相互独立,可干净地并行。

第 1 步 - 准备工作区

python <skill>/scripts/prepare.py <pptx-path> <workspace-dir>

该脚本解压 PPTX,通过 LibreOffice 和 pdftoppm 把每张可见幻灯片渲染为 JPG,然后为每张可见幻灯片写一个清单 JSON。渲染后,脚本会检查 JPG 数量是否与幻灯片数量一致,若不一致会向 stderr 发出警告——LibreOffice 已知会静默丢页,因此派发子智能体前务必先读该警告。

在命令沙箱之外运行此步骤。LibreOffice 无头模式需要写入其每用户配置并设置操作系统/任务策略,沙箱会阻止这些,因此在沙箱下 soffice 会静默失败:没有 PDF、输出为空、也没有 deck_index.json。在 Claude Code 中,请用 Bash 工具的 dangerouslyDisableSandbox: true 运行 prepare.py。需要识别的症状:rendered/ 保持为空且未写入 deck_index.json,同时 soffice 进程 CPU 接近零。

工作区结构如下:

workspace/ unpacked/ 原始 OOXML rendered/ PDF + 有序幻灯片 JPG manifests/slideNN.json 逐页清单 slide_images/slideNN.jpg 渲染的整页 JPG(稳定命名) embedded_images/slideNN/ 按页分组的嵌入 PNG slides/ 空 - 子智能体在此写 slideNN.md deck_index.json {visible, hidden, src_to_render}

第 2 步 - 扩展前先试点

挑选 2-4 张能覆盖演示文稿多样性的幻灯片:一张密集的、一张带截图的、一张带自定义示意图的、一张文字稀疏的。先用 references/sub_agent_prompt.md 中的提示模板为这些幻灯片派发子智能体,并把输出与 references/example_slide.md 中的范例对比。按需调整提示中针对该演示文稿的说明(需逐字保留的术语、需标记的术语、需强制执行的约定)。然后再扩展到其余幻灯片。

试点不是可选项。每份演示文稿在图片风格、版面密度和术语上的差异,意味着对某份文稿完美的提示在另一份上可能产出平淡或重复的输出。

第 3 步 - 并行派发子智能体

为每张可见幻灯片派发一个全新子智能体(具名 subagent 类型,而非 fork——该智能体只需要自己的清单,因此全新上下文比继承编排者历史更省)。每个智能体读取其清单、渲染的幻灯片 JPG 和嵌入 PNG,然后写出一个 slideNN.md。

获取派发列表,运行:

python <skill>/scripts/dispatch_list.py <workspace-dir>

这会为每张仍需子智能体的幻灯片输出一行制表符分隔的记录(slide_number、manifest_path、output_path),跳过 Markdown 已存在的幻灯片。这让部分失败后的重跑变得简单——不会不必要地重新提取任何幻灯片。

建议分批:每波 6 个子智能体。更大的波次可行,但会产生更多交错的完成通知,更嘈杂却不会更快。每个子智能体通常耗时 20-50 秒。

发送给每个智能体的确切提示在 references/sub_agent_prompt.md 中。发送前用 str.replace()(而非 str.format()——模板含字面大括号)替换占位符。提示中的规则——按长度调整的图片描述、外部链接去重、单行回复——并非风格问题;它们都是在早期运行中遇到真实失败模式后逐条加入的。理由见提示模板。

第 4 步 - 拼接

python <skill>/scripts/concatenate.py <workspace-dir> [--out deck.md] [--title "Deck title"]

这会把逐页 Markdown 按源幻灯片顺序拼接成单个 deck.md,并在头部注明被排除的隐藏幻灯片。若任何预期的幻灯片 Markdown 缺失,它会拒绝运行,这是正确的行为——部分演示文稿很少是想要的。

注意事项

LibreOffice 的 PDF 导出默认跳过隐藏幻灯片。这意味着渲染的 JPG 索引会与源幻灯片编号漂移。prepare.py 构建 src_to_render 映射,并把每个渲染 JPG 复制到以源幻灯片编号为键的稳定路径 slide_images/slideNN.jpg,因此清单引用稳定名称。若之后重新生成渲染,请重跑 prepare.py 以保持映射最新。

演讲者备注映射不总是 1:1。本技能从幻灯片的 _rels 文件读取 slide-to-notesSlide 关系,而非假设 slideN.xml 映射到 notesSlideN.xml。多数演示文稿恰好是 1:1,但并不保证。

源 XML 可能有拼写错误。流程会逐字保留它们。请在后续内容提升阶段修正,而非在提取阶段——这保持提取的确定性。

隐藏幻灯片默认被排除。多数演示文稿包含隐藏幻灯片是有原因的(进行中、已弃用内容、仅内部备注)。仅当希望它们出现在输出中时才传 --include-hidden——脚本随后会通过 LibreOffice 的 ExportHiddenSlides 过滤器正确渲染它们,使其在清单中获得真实 JPG。

密集截图受益于更高 DPI。默认是 150 DPI。对于截图中文字需在渲染 JPG 中可读的演示文稿,向 prepare.py 传 --dpi 200 或 --dpi 250。

依赖

  • LibreOffice (soffice) 在 PATH 中
  • Poppler (pdftoppm) 在 PATH 中
  • Python 3.10+

prepare 脚本会检查这两个二进制文件,若任一缺失会提前退出并给出清晰错误。