mcpField
P
pptx-to-md

pptx-to-md

github.com/sammcj文档处理16758 次安装2 天前更新
代码仓库

关于 pptx-to-md

pptx-to-md 可将 PowerPoint 演示文稿逐页提取为 Markdown,并保留布局和图片语境,适合后续编辑或转换内容。

主要功能

  1. 01逐页输出 Markdown
  2. 02保留布局语境
  3. 03结合图片含义进行提取
  4. 04先试处理再批量提取
  5. 05按源页顺序合并

适用场景

  1. 01提取含图表和截图的演示文稿
  2. 02为内容编辑准备幻灯片文本
  3. 03将幻灯片 Markdown 用于 HTML 构建

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/sammcj/agentic-coding --skill pptx-to-md

安装后在 Claude Code 中输入/pptx-to-md确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
example_slide.md
sub_agent_prompt.md
scripts/
concatenate.py
dispatch_list.py
prepare.py

详细介绍

将 PPTX 提取为逐页 Markdown

此技能可将 .pptx 文件转换为每张幻灯片对应的一个 Markdown 文件,同时保留版式上下文和图像含义。它不会改写文本,也不会脱离上下文描述图像。输出适合作为内容提升流程、Markdown 转 HTML 构建流程或其他下游转换的输入。

适用场景

演示文稿在重要的版式中混合了文本、嵌入的屏幕截图、图表、数据图或代码示例,例如分栏、并排面板和标注框。纯文本提取会丢失版式或图像含义。

重要提示:如果演示文稿是 PDF、仅含文本,或者不包含对内容有意义的图像,那么使用 uvx 'markitdown[all]' <path-to-file> -o output.md 会更快,而且通常就足够了,无需使用下文所述的这套更复杂的技能流程。你可以先尝试这种方式,并请用户检查输出;同时告知用户,如果效果不够理想,你会继续使用更复杂的幻灯片提取流程。

流程

PPTX -> prepare.py -> manifests + rendered JPGs + embedded PNGs
     -> dispatch one sub-agent per slide
     -> per-slide markdown files
     -> concatenate.py -> deck.md

编排器(即调用会话中的你)需要完成两件事:运行准备脚本和合并脚本,并为每张可见幻灯片派发一个子 Agent。每个子 Agent 负责通过视觉和文本信息组合内容,为一张幻灯片编写一个 Markdown 文件。子 Agent 彼此独立,可以顺畅地并行运行。

步骤 1 - 准备工作区

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

此步骤会解压 PPTX,通过 LibreOffice 和 pdftoppm 将每张可见幻灯片渲染为 JPG,然后为每张可见幻灯片写入一个清单 JSON 文件。渲染完成后,脚本会检查 JPG 数量是否与幻灯片数量一致;如果数量不一致,则向 stderr 发出警告。已知 LibreOffice 有时会在没有提示的情况下漏掉幻灯片,因此派发子 Agent 前务必查看该警告。

在任何命令沙箱之外运行此步骤。 LibreOffice 无头模式需要写入每用户配置文件并设置沙箱会阻止的 OS/任务策略,因此在沙箱中运行时,soffice 会静默失败:没有 PDF、输出为空,也不会生成 deck_index.json。在 Claude Code 中,具体做法是使用 Bash 工具的 dangerouslyDisableSandbox: true 运行 prepare.py。可识别的现象:rendered/ 目录始终为空,且没有写入 deck_index.json,同时 soffice 进程的 CPU 占用接近零。

工作区结构如下:

workspace/
  unpacked/                    raw OOXML
  rendered/                    PDF + ordered slide JPGs
  manifests/slideNN.json       per-slide manifest
  slide_images/slideNN.jpg     rendered whole-slide JPG (stable name)
  embedded_images/slideNN/     embedded PNGs grouped per slide
  slides/                      empty - sub-agents write slideNN.md here
  deck_index.json              {visible, hidden, src_to_render}

步骤 2 - 先试运行,再扩展

选取 2-4 张能够体现演示文稿多样性的幻灯片:一张内容密集的、一张带屏幕截图的、一张带自定义图表的,以及一张文本稀少的。先按照 references/sub_agent_prompt.md 中的提示词模板派发子 Agent 处理这些幻灯片,并将输出与 references/example_slide.md 中的示例进行比较。如有需要,调整提示词中的演示文稿专属说明,例如需逐字保留的术语、需标记的术语以及需遵守的约定。完成后,再将任务分派给演示文稿中的其余幻灯片。

试运行并非可选步骤。不同演示文稿的图像风格、版式密度和术语各不相同,因此适用于一份演示文稿的提示词,可能会在另一份演示文稿中生成平淡或重复的输出。

第 3 步 - 并行调度子 Agent

对于每张可见幻灯片,调度一个全新的子 Agent(使用指定的 Agent 类型,不要分叉现有 Agent——该 Agent 只需读取其清单,因此使用全新上下文比继承编排 Agent 的历史记录更省资源)。每个 Agent 都会读取清单、渲染后的幻灯片 JPG 和嵌入的 PNG,然后写入一个 slideNN.md。

要获取调度列表,请运行:

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

这会为每张仍需子 Agent 处理的幻灯片输出一行以制表符分隔的数据(slide_number、manifest_path、output_path),并跳过 Markdown 文件已存在的幻灯片。这样,即使上次运行只完成了一部分,重新运行也很简单——无需重新提取任何幻灯片。

建议的批次大小:每波 6 个子 Agent。更大的批次也可以,但会产生更多交错的完成通知,显得更嘈杂,却不会更快。每个子 Agent 通常需要 20-50 秒。

要发送给每个 Agent 的确切提示词位于 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,以更新映射。

演讲者备注的映射不一定总是一一对应。 此工具会从幻灯片的 _rels 文件中读取幻灯片到备注幻灯片的关联,而不是假定 slideN.xml 对应 notesSlideN.xml。多数幻灯片集碰巧是一一对应,但并不能保证。

源 XML 可能包含拼写错误。 流程会原样保留这些错误。请在后续的内容提升阶段进行修正,不要在提取过程中修正——这样可以确保提取过程具有确定性。

默认排除隐藏幻灯片。 大多数幻灯片集出于某些原因包含隐藏幻灯片(进行中的内容、已弃用内容、仅供内部使用的备注)。只有在需要将它们纳入输出时才传入 --include-hidden——脚本随后会通过 LibreOffice 的 ExportHiddenSlides 过滤器正确渲染它们,因此清单中会包含对应的 JPG。

高密度截图适合使用更高 DPI。 默认值为 150 DPI。如果幻灯片截图中的文字需要在渲染后的 JPG 中清晰可读,请向 prepare.py 传入 --dpi 200 或 --dpi 250。

依赖项

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

prepare 脚本会检查这两个二进制文件;如果任一个缺失,就会立即退出并显示清晰的错误信息。

评论

支持 Markdown