Skip to content

feat: 使用本地 SVG 引擎实现 PPTX 预览与编辑 - #161

Merged
wangkailang merged 6 commits into
mainfrom
codex/pptx-local-preview-editor
Jul 31, 2026
Merged

feat: 使用本地 SVG 引擎实现 PPTX 预览与编辑#161
wangkailang merged 6 commits into
mainfrom
codex/pptx-local-preview-editor

Conversation

@wangkailang

@wangkailang wangkailang commented Jul 24, 2026

Copy link
Copy Markdown
Owner

改动概览

  • 使用 pptx-svg WASM 在本地解析 PPTX,并将全部幻灯片渲染为可缓存的 SVG
  • 解析幻灯片 OOXML 图片关系,将 PNG、JPEG、GIF、WebP 媒体按文件头识别后内联到 SVG,替换灰色占位
  • 为固定尺寸 SVG 补充 viewBox 和等比缩放属性,保证右侧窄区域也能完整展示幻灯片
  • 为幻灯片内容生成稳定对象 ID,支持检查对象并精确修改文本 run
  • PPTX 对象搜索使用 locale 无关的大小写归一化,确保不同系统语言下结果一致
  • PPTX 编辑结果通过临时文件原子写回源文件,不再反复生成 *-edited.pptx 副本
  • 移除 editPptxText 的 outputPath 参数,确保 Agent 始终修改当前选中的 PPTX
  • 编辑成功后重新打开原路径;重复打开同一路径时递增预览修订号,强制重新读取内容
  • 内容提取返回 parse-error 时保留 contentPreviewError,避免视觉预览成功时丢失诊断信息
  • 新增 pptx-editor 任务技能,接入内置技能注册和 Agent 编辑流程
  • 更新文件预览面板,支持逐页幻灯片预览、缩放以及视觉/内容视图切换
  • 支持在预览中用鼠标或键盘选择形状与文本片段,并显示选中高亮
  • 选中元素后在附近显示轻量 Chat 输入框,自动处理上下方空间、左右边缘和预览缩放
  • 就地输入使用当前 Chat 会话发送,不覆盖底部输入框中的已有草稿
  • 将本地选中对象、源文件路径和修订标识注入 pptx-editor,避免手工查找对象 ID
  • 完整移除 LibreOffice、soffice、Quick Look 和 Office 转 PDF 的原生及 TypeScript 实现
  • 旧版 .ppt 不再调用外部转换器,改为提示用户另存为 .pptx

实现说明

PPTX 预览与编辑链路现在为:

PPTX → 本地 WASM 解析 → OOXML 图片关系解析 → 安全内联 SVG → 响应式等比展示 → 元素选择 → 就地 Chat → 当前对话 → 稳定对象 ID → 文本回写 → 原子替换源文件 → 同路径刷新预览

预览缓存以文件路径、mtime、大小、内容哈希和渲染器版本生成指纹。选中元素时会携带 sourceRevision;写入前再次校验源文件修订,避免外部修改 PPTX 后使用过期对象 ID。全部解析、选择和回写均在本机执行。

编辑时先在源文件目录生成临时 PPTX,导出完成后再原子替换源文件;导出或临时写入失败时不会提前破坏原文件。工具不再接受另存路径,结果中的 outputPath 固定返回源路径,用于触发右侧预览刷新。

工具结果监听直接使用事件携带的 toolName,兼容历史结果重放。仅成功的 editPptxText 结果会刷新预览;失败结果不会误触发预览切换。同一路径再次打开时通过 fileRevision 让预览组件重新挂载,确保删除文本等修改立即可见。

PPTX 对象、文本 run 和备注搜索统一使用 toLowerCase(),不依赖进程默认 locale。视觉 SVG 渲染成功但内容提取返回 unsupported/parse-error 时,会继续展示幻灯片,同时把失败 message 放入 contentPreviewError 供诊断和 UI 使用。

就地输入支持 Enter 发送、Shift+Enter 换行、Esc 或关闭按钮取消。当前会话执行中会拒绝重复提交,并保留尚未发送的就地输入内容。

验证

  • pnpm lint(通过;仓库既有测试字符串仍有 1 条 warning)
  • pnpm typecheck
  • pnpm test(378 个测试文件、3499 项测试通过)
  • pnpm build
  • Turkish locale 下 indigo 仍可匹配 INDIGO
  • PPTX 视觉预览成功、内容解析 fulfilled parse-error 时保留诊断信息
  • PPTX 精确文本修改后原子覆盖源文件,且技能 schema 不再暴露 outputPath
  • 过期 sourceRevision 在写入前被拒绝
  • 编辑结果自动打开、失败结果忽略、历史结果重放和同路径强制刷新回归测试
  • OOXML 图片内联、文件头 MIME 识别、固定尺寸 SVG 响应式展示回归测试
  • 真实 PPTX 第 7 页图片完成 JPEG 内联,渲染结果不再包含灰色占位
  • 真实 PPTX 完成渲染、对象检查、文本修改和重新读取回环验证

当前边界

预览中可选择形状、图片、图表和文本片段作为 Agent 上下文;当前编辑工具只对外开放精确文本 run 修改,形状、图片和图表的属性写入尚未开放。当前图片预览支持 PNG、JPEG、GIF、WebP;其他嵌入媒体格式仍保留占位。

改动细节:
- 引入 pptx-svg WASM,在本地将 PPTX 渲染为逐页 SVG 并按文件指纹缓存
- 新增演示文稿对象检查与稳定对象 ID,支持精确修改文本 run 后导出新 PPTX
- 新增 pptx-editor 任务技能并接入内置技能注册
- 更新文件预览面板,支持幻灯片全页预览、缩放及视觉/内容视图切换
- 移除 LibreOffice、soffice、Quick Look 和 Office 转 PDF 的原生及 TypeScript 链路
- 旧版 .ppt 改为提示另存为 .pptx,不再调用外部转换器
- 补充 PPTX 缓存、对象检查、编辑导出、预览界面和旧链路移除测试
Copilot AI review requested due to automatic review settings July 24, 2026 09:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR replaces the previous LibreOffice/Quick Look Office preview pipeline with a fully local PPTX pipeline based on pptx-svg WASM, enabling cached per-slide SVG rendering plus stable object IDs for precise text-run edits and PPTX re-export, and updates the renderer preview UI + skills registry accordingly.

Changes:

  • Introduces a local PPTX presentation model (preparePptxPreview, inspection, and text-run editing) and adds a new pptx-editor task skill.
  • Refactors Office preview IPC + shared types to support "presentation" (PPTX SVG) and "content" previews, removing the native LibreOffice conversion entrypoint.
  • Updates file preview UI/tests and i18n strings to align with the new preview behavior and removes LibreOffice-related messaging.

Reviewed changes

Copilot reviewed 23 out of 24 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/shared/office-preview.ts Updates shared preview/result types for presentation SVG previews and removes PDF/image preview fields.
src/renderer/i18n/zh-CN/index.ts Removes LibreOffice/PDF unavailability string.
src/renderer/i18n/ja/index.ts Removes LibreOffice/PDF unavailability string.
src/renderer/i18n/en/index.ts Removes LibreOffice/PDF unavailability string.
src/renderer/i18n/i18n-types.ts Regenerates types to remove the deleted i18n key.
src/renderer/components/file-preview/FilePreviewPanel.tsx Implements PPTX visual preview via per-slide SVGs and removes PDF/image Office fallback UI.
src/renderer/components/file-preview/tests/FilePreviewPanel.office.test.tsx Updates tests to validate content-only Office previews and PPTX SVG slide rendering.
src/main/skills/pptx-editor.ts Adds a new mutating task skill for inspecting/editing PPTX text via stable object IDs.
src/main/skills/index.ts Registers the new pptx-editor skill.
src/main/skills/tests/pptx-processor.test.ts Adds a spec test for the new pptx-editor skill shape/category/tools.
src/main/presentation/pptx.ts Introduces the local PPTX renderer adapter, preview caching, object inspection, and text editing/export.
src/main/presentation/tests/pptx.test.ts Adds unit tests for PPTX preview caching, inspection IDs, and edit/export behavior.
src/main/office-preview/paths.ts Deletes LibreOffice path resolution helper (no longer needed).
src/main/office-preview/content.ts Removes legacy PPT conversion and updates unsupported messaging + cache version bump.
src/main/office-preview/tests/paths.test.ts Removes tests for deleted LibreOffice path resolution.
src/main/office-preview/tests/content.test.ts Updates legacy PPT handling test to assert “unsupported” without external converter.
src/main/native/index.ts Removes TypeScript bridge types/exports for the native Office conversion entrypoint.
src/main/native/tests/exports.test.ts Updates tests to accept native bindings without the removed Office converter.
src/main/ipc/file-handlers.ts Switches PPTX visual preview to local WASM SVG pipeline and non-PPTX to content-only; merges PPTX visual+content.
package.json Adds pptx-svg@0.6.4 dependency.
pnpm-lock.yaml Locks pptx-svg@0.6.4 with Node engine requirements.
native/filework-native/src/office_preview.rs Deletes Rust napi LibreOffice/Quick Look conversion implementation.
native/filework-native/src/lib.rs Removes the office_preview module export.
docs/plans/2026-06-29-office-preview-pipeline.md Removes the old LibreOffice-based preview pipeline plan doc.
Files not reviewed (1)
  • pnpm-lock.yaml: Generated file
Comments suppressed due to low confidence (2)

src/main/skills/pptx-editor.ts:49

  • Search matching currently lowercases text with toLocaleLowerCase(), which can produce locale-dependent results. Prefer toLowerCase() for deterministic matching across environments.
            ? item.objects.filter((object) =>
                object.textRuns.some((run) =>
                  run.text.toLocaleLowerCase().includes(normalizedSearch),
                ),

src/main/skills/pptx-editor.ts:59

  • Notes matching uses toLocaleLowerCase(), which can be locale-dependent. Use toLowerCase() for consistent matching behavior.
            item.objects.length > 0 ||
            item.notes.some((note) =>
              note.toLocaleLowerCase().includes(normalizedSearch),
            ),

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/main/skills/pptx-editor.ts Outdated
Comment on lines +136 to +140
if (extracted) {
result.contentPreviewPath = extracted.contentPreviewPath;
}

return `${visualMessage}. ${installHint} ${contentMessage}`;
if (contentResult.status === "rejected") {
result.contentPreviewError = getErrorMessage(contentResult.reason);

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已在 168a114 修复:内容解析 fulfilled 但返回 unsupported(含 parse-error)时,将 preview.message 保留到 contentPreviewError。新增 fs:prepareOfficePreview IPC 回归用例覆盖视觉成功、内容解析失败的组合。

改动细节:
- 将幻灯片 SVG 安全清洗后以内联方式渲染,保留本地对象元数据
- 支持鼠标或键盘选择形状与文本片段,并显示选中高亮
- 将选中对象、源文件路径与修订标识注入 pptx-editor 输入
- 增加 sourceRevision 校验,阻止过期对象 ID 写入已变化的 PPTX
- 补充 SVG 安全、选择交互、聊天注入和过期修订回归测试
改动细节:
- 选中幻灯片元素后在元素附近显示轻量输入框
- 根据元素位置自动选择上下方并处理左右边缘,缩放时保持输入框可读尺寸
- 支持 Enter 发送、Shift+Enter 换行、Esc 或关闭按钮取消
- 就地请求直接提交到当前 Chat 会话,不再覆盖底部输入框草稿
- 会话执行中拒绝重复提交并保留就地输入内容
- 补充浮层定位、选择上下文和当前会话提交回归测试及多语言文案
- 编辑工具成功导出后自动打开新 PPTX,并通过预览修订号刷新同路径内容
- 解析 OOXML 图片关系并按文件头识别媒体类型,替换本地 SVG 灰色占位
- 为固定尺寸 SVG 补充 viewBox 与等比缩放,保证幻灯片完整展示
- 补充结果重放、失败结果、同路径刷新、图片内联和响应式预览回归测试
- 移除 editPptxText 的 outputPath 参数,禁止 Agent 反复生成重命名副本
- 导出结果通过临时文件原子替换源 PPTX,失败前不破坏原文件
- 保留 sourceRevision 校验,并返回原路径触发右侧预览刷新
- 更新技能说明与原地编辑回归测试
- 将对象、文本和备注搜索统一改为 locale 无关的 toLowerCase 匹配
- PPTX 内容解析返回 unsupported 时保留 message 到 contentPreviewError
- 补充 Turkish locale 搜索与 fulfilled parse-error IPC 回归测试
@wangkailang
wangkailang merged commit caadff5 into main Jul 31, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants