From 2d70949d41503d7a57fea0613bcc522d188700b8 Mon Sep 17 00:00:00 2001 From: LaTeXSnipper Developer Date: Thu, 28 May 2026 14:35:43 +0800 Subject: [PATCH] docs: define native Office plugin direction --- docs/faq.md | 4 + docs/office_addin_design.md | 121 ++++++++++--------------- docs/office_plugin_design.md | 152 ++++++++++++++++++++++++++++++++ office_addin/README.md | 62 +++++++------ readme.md | 26 +++++- test/test_office_plugin_docs.py | 28 ++++++ 6 files changed, 291 insertions(+), 102 deletions(-) create mode 100644 docs/office_plugin_design.md create mode 100644 test/test_office_plugin_docs.py diff --git a/docs/faq.md b/docs/faq.md index 45e4c5d..21d96f5 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -38,6 +38,10 @@ The current shortcut UI only accepts `Ctrl+letter` and `Ctrl+Shift+letter`, so t - macOS: use the `.dmg` or `.app.zip` artifact. - Microsoft Store channel: use the Store package/update flow when installed from Store. +## What is the final Office plugin direction? + +The current `office_addin` project is an Office.js implementation kept for migration reference. The final Office integration is planned as a Windows-native `office_plugin` so LaTeXSnipper can provide persistent Ribbon loading, native shortcuts, double-click editing, OLE formula objects, Word OMML insertion, PowerPoint image insertion, and a local MathJax/native rendering pipeline without relying on Microsoft 365 enterprise deployment. + ## Does LaTeXSnipper require an internet connection? Core editing and local recognition workflows are designed to work locally after the required dependencies and models are installed. Some optional downloads, update checks, model downloads, and CDN fallbacks require network access. diff --git a/docs/office_addin_design.md b/docs/office_addin_design.md index 42f59e4..9e09ed6 100644 --- a/docs/office_addin_design.md +++ b/docs/office_addin_design.md @@ -1,19 +1,19 @@ -# Office Add-in 已实现设计 +# Office.js Add-in 迁移记录 -本文只描述当前已经交付的 Word 与 PowerPoint Office.js 行为,不记录未实现的愿景或兼容设想。 +本文记录 `office_addin` 已实现的 Office.js 行为和迁移价值。它不再作为 LaTeXSnipper Office 集成的最终设计文档;最终架构见 `docs/office_plugin_design.md`。 -## 目标与边界 +## 结论 -LaTeXSnipper Office 加载项连接本机 Office Bridge,负责公式输入、LaTeX 转换结果写入 Office、截图识别结果载入以及 Word 中由本加载项拥有的公式生命周期管理。 +Office.js 已经验证了 LaTeXSnipper 与 Word/PowerPoint 集成的核心流程,但它不适合作为最终产品形态: -对于本产品目标,当前实现位于可可靠使用的 Office.js 能力边界: +- 单机安装无法像原生插件一样可靠持久显示 Ribbon;稳定分发依赖企业部署、Office Store 或受信任目录策略。 +- Ribbon 图标、manifest、WebView Runtime、localhost HTTPS、证书和 sideload 缓存都属于宿主平台外部约束。 +- 无法实现每个公式都是可双击编辑的原生 OLE 对象。 +- 无法在 Word/PPT 对象模型底层提供类似 MathType/AxMath 的自绘公式对象、快捷键和对象生命周期控制。 -- Word 维护本加载项创建的带标记 OMML 公式,具备源代码、更新、删除与编号闭环。 -- PowerPoint 写入公式 PNG 图像;编号与公式合成为同一张图像。 -- 任意 Word 原生公式、缺失元数据的对象和 PowerPoint 图像不被伪装为可编辑 LaTeXSnipper 公式。 -- 不实现历史结构修复或猜测式兼容路径。 +因此,`office_addin` 保留为迁移参考;新增和最终能力进入 Windows 原生 `office_plugin`。 -## 运行结构 +## 已验证能力 ```text Word / PowerPoint Ribbon @@ -28,33 +28,18 @@ Word / PowerPoint Ribbon GET /health, /config ``` -Ribbon 命令通过共享运行时进入任务窗格调度层;`Editor`、`Insert`、`Screenshot OCR`、编号动作和 `Help` 都执行真实命令,而不是仅打开一个无动作的窗格。 +这些能力可以迁移到原生插件: -截图识别返回后,任务窗格输入值总会更新;若 `Dialog editor` 正在打开,父窗口通过 Office 对话框消息同时将同一 LaTeX 写入该编辑器。 +- Ribbon 命令模型:编辑器、插入、截图识别、加载、删除、编号、重编号。 +- Bridge 协议:LaTeX 转 OMML、截图 OCR、OCR 状态、安装路径发现。 +- MathLive 编辑器:公式输入、符号面板、结构模板、中英文 UI。 +- Word 公式元数据:公式 ID、LaTeX 源码、显示模式、编号模式和编号值。 +- 编号公式规则:每个编号公式独立布局,连续插入不得共享表格或对象容器。 +- PowerPoint 图片路径:裁剪公式图像、手动编号合成图像。 -## 语言 +## 当前 Word 行为 -`src/services/i18n.ts` 使用 `Office.context.displayLanguage` 选择 `en-US` 或 `zh-CN`: - -- 任务窗格和编辑对话框通过文本键渲染。 -- Ribbon 通过两份 manifest 内的 `zh-CN` override 由 Office 本身切换。 -- 帮助入口根据当前语言打开 `help.html` 或 `help.zh-cn.html`。 - -## Word 对象模型 - -### 公式身份 - -每个由加载项创建的 Word 公式使用内容控件标记 `latexsnipper-eq-{id}`。文档设置保存其 LaTeX、显示模式、编号模式和编号值。无标记或无元数据的公式不是受管理公式。 - -### 普通公式 - -普通公式使用 OMML 内容控件。插入、加载、更新与删除只针对该内容控件;当公式位于用户表格中时,删除操作不会删除用户表格。 - -### 编号公式 - -编号公式使用独立的无边框三列表格:中间单元格放公式,右侧单元格放编号,左右空间保证公式居中。每次插入均保留表格后的段落边界,连续插入不会生成共享表格。 - -### Word 命令 +每个由 Office.js 加载项创建的 Word 公式使用内容控件标记 `latexsnipper-eq-{id}`。文档设置保存其 LaTeX、显示模式、编号模式和编号值。无标记或无元数据的公式不是受管理公式。 | 命令 | 行为 | |---|---| @@ -67,7 +52,7 @@ Ribbon 命令通过共享运行时进入任务窗格调度层;`Editor`、`Inse 插入点若位于任意受管理公式或编号布局内部,适配器返回可读提示并拒绝写入。 -## PowerPoint 对象模型 +## 当前 PowerPoint 行为 `src/office/powerpointInsert.ts` 通过 `Office.context.document.setSelectedDataAsync` 和 `Office.CoercionType.Image` 写入 Bridge 生成的 PNG。 @@ -80,49 +65,37 @@ Ribbon 命令通过共享运行时进入任务窗格调度层;`Editor`、`Inse PowerPoint 工作流没有 `Load Selected`、`Update`、`Delete Selected`、自动编号或 `Renumber All`。稳定发布路径使用 `Office.CoercionType.Image` 写入图像,该方法不返回可由本插件标记并持续追踪的图片对象。删除后的图片无法可靠参与编号重算,因此不保留只会递增的伪自动编号状态。 -## Bridge 与数据 - -Bridge URL 与会话 token 由文档设置保存。Word 额外保存公式来源和自动编号状态;PowerPoint 插入结果不写入虚假的可编辑公式元数据。 - -本机安装包将构建后的 Office 站点、manifest 和 `localhost` TLS 配置安装到本机。启用 Office 功能后的桌面端发现这些资源后,以 `https://localhost:8765` 同时提供站点和 Bridge API: - -- Windows Inno 包为当前用户安装站点与证书,将实际所选安装目录写入产品注册表供 Bridge 发现,并将 Word/PPT manifest 写入 `WEF\Developer` 本机 sideload 注册。不写入需要 UNC 共享目录的 `TrustedCatalogs`。 -- macOS `.pkg` 安装站点与证书,并将 Word/PPT manifest 放入 Microsoft 文档指定的 `wef` 本机 sideload 目录。 -- GitHub Release workflow 额外产出 `OfficeDeploymentManifests-.zip`,供管理员通过 Microsoft 365 Integrated apps 统一部署;Windows 本机安装程序纳入 SignPath 签名路径。 - -本机 sideload 适用于单机安装和测试,不等同于 Microsoft 支持的组织级生产分发。组织内持续分配 Ribbon 插件由 Microsoft 365 Integrated apps 部署实现;Marketplace 上架仍不属于仓库可自动完成的发布步骤。 - -## Requirement Sets +## 不迁移的 Office.js 机制 -| 宿主 | Manifest 声明 | 支持目标 | -|---|---|---| -| Word | `WordApi 1.3`, `SharedRuntime 1.1` | Windows: Microsoft 365 Word Version 2205 (Build 15202.10000) 或 Word 2024;Mac: Word 16.61 | -| PowerPoint | `ImageCoercion 1.1`, `SharedRuntime 1.1` | Windows: Microsoft 365 PowerPoint Version 2102 (Build 13722.10000) 或 PowerPoint 2021/2024;Mac: PowerPoint 16.46 | +以下机制只服务于旧实现,不应进入 `office_plugin`: -本机 Bridge 和桌面截图是产品依赖,因此不把 Office Web 或移动版列为交付目标。 +- manifest sideload 作为持久安装方案。 +- 依赖任务窗格保持状态的命令调度。 +- 用文档设置弥补对象自身无法持久保存源数据的问题。 +- 通过 `localhost` 静态站点承载 Office UI。 +- 针对 Office.js 插入失败的 OOXML 字符串修补。 +- PowerPoint 中不可追踪图片对象的伪编辑流程。 ## 源码边界 -| 文件 | 责任 | +| 文件 | 迁移价值 | |---|---| -| `src/taskpane/App.ts` | 宿主工作流与命令调度 | -| `src/dialog/editorDialog.ts` | 可视化公式编辑 | +| `src/taskpane/App.ts` | 命令编排、状态提示、Bridge 调用顺序 | +| `src/dialog/editorDialog.ts` | 可视化公式编辑器交互 | | `src/taskpane/mathliveEditor.ts` | MathLive 封装 | -| `src/office/wordInsert.ts` | Word 受管理公式适配器 | -| `src/office/powerpointInsert.ts` | PowerPoint 图像适配器 | -| `src/services/i18n.ts` | 中英文字符串与错误显示 | -| `src/services/equationSession.ts` | 文档设置持久化 | -| `src/services/ribbonCommands.ts` | Ribbon 与共享运行时队列 | -| `../src/integration/office/addin_runtime.py` | 正式安装站点及 TLS 文件发现 | -| `../scripts/build_office_addin_installer.ps1` | Windows Office 加载项安装包构建 | -| `../scripts/build_office_addin_macos.sh` | macOS Office 加载项安装包构建 | - -## 官方依据 - -- [Word JavaScript API requirement sets](https://learn.microsoft.com/javascript/api/requirement-sets/word/word-api-requirement-sets) -- [Shared runtime requirement sets](https://learn.microsoft.com/javascript/api/requirement-sets/common/shared-runtime-requirement-sets) -- [Image coercion requirement sets](https://learn.microsoft.com/javascript/api/requirement-sets/common/image-coercion-requirement-sets) -- [Localize Office Add-ins](https://learn.microsoft.com/office/dev/add-ins/develop/localization) -- [Sideload Office Add-ins from a network share on Windows](https://learn.microsoft.com/office/dev/add-ins/testing/create-a-network-shared-folder-catalog-for-task-pane-and-content-add-ins) -- [Sideload Office Add-ins on Mac](https://learn.microsoft.com/office/dev/add-ins/testing/sideload-an-office-add-in-on-mac) -- [Deploy add-ins through Integrated apps](https://learn.microsoft.com/microsoft-365/admin/manage/test-and-deploy-microsoft-365-apps) +| `src/office/wordInsert.ts` | Word OMML、编号布局和元数据规则 | +| `src/office/powerpointInsert.ts` | PowerPoint 图像裁剪与编号合成 | +| `src/services/i18n.ts` | 中英文术语与错误提示 | +| `../src/integration/office/bridge_server.py` | Bridge API | + +## 清理条件 + +只有在 `office_plugin` 完成以下闭环后,才能删除 `office_addin`: + +- Word 原生 Ribbon 稳定加载。 +- Word OMML 插入、加载、更新、删除、编号和重编号达到现有能力。 +- Word OLE 公式对象可插入、双击编辑、保存源数据并重新渲染。 +- PowerPoint 图片插入能力不低于当前 Office.js 实现。 +- PowerPoint OLE 公式对象可插入、双击编辑、保存源数据并重新渲染。 +- 快捷键和安装器持久注册链路完成。 +- 回归测试覆盖对象生命周期、编号、文档保存/重开和卸载清理。 diff --git a/docs/office_plugin_design.md b/docs/office_plugin_design.md new file mode 100644 index 0000000..554789f --- /dev/null +++ b/docs/office_plugin_design.md @@ -0,0 +1,152 @@ +# Windows 原生 Office 插件目标架构 + +`office_plugin` 是 LaTeXSnipper Office 集成的最终主线。目标是做成类似 MathType/AxMath 的 Windows 原生插件:安装后 Word 和 PowerPoint 持久显示 Ribbon,每个 LaTeXSnipper 公式都是可识别、可保存源数据、可双击打开编辑器的对象。 + +`office_addin` 暂时保留为迁移参考,迁移完成后删除。 + +## 产品目标 + +- 绑定 Windows 桌面版 Office,不再追求 Office.js 的 Web/Mac 覆盖。 +- 原生 Ribbon 持久加载,不依赖 Microsoft 365 企业账号、Office 管理中心或 sideload manifest。 +- 支持全局和 Office 内快捷键。 +- Word 支持 OMML 公式和 LaTeXSnipper OLE 公式对象。 +- PowerPoint 支持当前 OMML 图片插入和 LaTeXSnipper OLE 公式对象。 +- 每个公式对象保存 LaTeX 源码、渲染参数、编号信息和 LaTeXSnipper 对象版本。 +- 双击公式对象打开 LaTeXSnipper 编辑器,修改后原地更新。 +- 本地 MathJax/MathLive/自绘渲染管线完全离线运行。 + +## 推荐技术路线 + +第一阶段优先使用 VSTO/C# 建立原生 Office 插件骨架;必要时用 COM/OLE 组件承载公式对象和自绘渲染。 + +| 层 | 建议 | +|---|---| +| Office 插件外壳 | VSTO Add-in for Word/PowerPoint | +| Ribbon | Ribbon XML,便于精确控制命令、图标和快捷键 | +| 公式对象 | LaTeXSnipper OLE/ActiveX 对象,支持嵌入、激活、双击编辑 | +| 编辑器 | WPF 或 WinUI 窗口;初期可复用本地 MathLive/WebView2,最终可替换为原生编辑器 | +| 渲染 | 本地 MathJax/MathLive 渲染服务 + 原生 GDI+/Direct2D/SVG/EMF 输出 | +| Bridge | 继续复用 LaTeXSnipper 桌面端本地服务,负责 OCR、转换和渲染 | +| 安装器 | Inno/MSI 写入 VSTO/COM/OLE 注册表,检测 Office 位数、VSTO Runtime、WebView2 Runtime | + +裸 COM Add-in 控制力更强,但生命周期、异常隔离、注册和 Ribbon 维护成本更高。第一版建议先用 VSTO 收敛 Word/PPT 工作流,再把公式对象和渲染管线下沉为独立 COM/OLE 组件。 + +## 对象模型 + +### 统一公式身份 + +每个公式都有稳定 ID: + +```text +latexsnipper:{document-id}:{equation-id} +``` + +对象内部保存: + +- LaTeX 源码 +- 显示模式 +- 渲染后宽高 +- 编号模式:无编号、自动编号、手动编号 +- 编号值 +- 渲染引擎:OMML、MathJax Native、图片兼容 +- LaTeXSnipper 对象格式版本 + +这些数据必须随 Word/PPT 文档保存,不能依赖外部临时缓存。 + +### Word + +Word 支持两条输出路径: + +| 路径 | 用途 | +|---|---| +| OMML 原生公式 | 文档可编辑性优先,适合普通 Word 数学排版 | +| LaTeXSnipper OLE 公式对象 | 自绘效果、TeX 兼容性、双击编辑和 MathType 式体验优先 | + +编号公式不再依赖 Office.js 的脆弱表格写入路径。最终可以由对象自身绘制编号区域,也可以由插件创建可控的 Word 布局容器,但公式身份必须绑定到单个 LaTeXSnipper 对象。 + +### PowerPoint + +PowerPoint 支持两条输出路径: + +| 路径 | 用途 | +|---|---| +| 图片插入 | 保留当前稳定行为,适合兼容导出和简单演示 | +| LaTeXSnipper OLE 公式对象 | 支持双击编辑、自绘渲染、源数据保存和精确缩放 | + +自动编号不应使用全局递增缓存。若需要自动编号,必须扫描当前幻灯片/演示文稿中仍存在的 LaTeXSnipper 对象,按对象数据计算最大编号或重排编号。 + +## 渲染管线 + +```text +LaTeX source + -> normalize + -> render request + -> OMML converter + -> MathJax native renderer + -> image/SVG/EMF renderer + -> Office adapter + -> Word OMML + -> Word OLE object + -> PowerPoint image + -> PowerPoint OLE object +``` + +本地 MathJax 原生渲染管线的目标: + +- 离线运行,不加载 CDN。 +- 输出紧贴公式边界的位图/SVG/EMF。 +- 支持对象 DPI、缩放、透明背景、深浅色策略。 +- 与 OLE 对象自绘共享同一套布局结果。 +- 渲染失败时返回明确错误,不生成不可编辑的半成品对象。 + +## 命令设计 + +| 命令 | Word | PowerPoint | +|---|---|---| +| `Open Editor` | 打开编辑器,可从当前选择加载公式 | 打开编辑器,可从当前选择加载公式 | +| `Insert OMML` | 插入 Word 原生 OMML | 插入当前兼容图片 | +| `Insert Native Object` | 插入 LaTeXSnipper OLE 公式对象 | 插入 LaTeXSnipper OLE 公式对象 | +| `Load Selected` | 加载选中 LaTeXSnipper 对象或受管 OMML | 加载选中 LaTeXSnipper 对象 | +| `Update Selected` | 原地更新对象 | 原地更新对象 | +| `Delete Selected` | 删除对象并清理元数据 | 删除对象并清理元数据 | +| `Auto Numbered` | 对受管公式启用自动编号 | 对受管对象启用自动编号 | +| `Renumber All` | 扫描文档对象重排 | 扫描演示文稿对象重排 | +| `Screenshot OCR` | 调用桌面端 OCR,写入编辑器 | 调用桌面端 OCR,写入编辑器 | + +快捷键应在 Ribbon XML/VSTO 层注册,并与 LaTeXSnipper 桌面端全局快捷键保持不冲突。 + +## 安装与持久化 + +Windows 安装器负责: + +- 安装 VSTO 插件。 +- 注册 Word 和 PowerPoint 加载项。 +- 注册 LaTeXSnipper OLE/COM 公式对象。 +- 安装或检测 VSTO Runtime、WebView2 Runtime。 +- 写入当前用户或机器级注册表项。 +- 安装图标、Ribbon 资源和本地渲染资源。 +- 卸载时清理插件注册、OLE 注册和临时缓存。 + +自定义安装位置不能影响插件加载。注册表中只保存稳定入口和资源根路径;插件启动时校验路径存在,不存在则显示可操作错误。 + +## 迁移阶段 + +1. 新建 `office_plugin` 项目骨架。 +2. Word VSTO Ribbon 持久显示,命令能打开编辑器。 +3. 复用 Bridge 完成 Word OMML 插入。 +4. 迁移 Word 受管公式元数据、加载、更新、删除。 +5. 迁移 Word 编号和重编号。 +6. 实现 PowerPoint 图片插入,达到 `office_addin` 当前能力。 +7. 引入 LaTeXSnipper OLE 公式对象。 +8. 接入本地 MathJax 原生渲染管线。 +9. 实现 Word/PPT 双击编辑和原地更新。 +10. 完成快捷键、安装器、卸载器和回归测试。 +11. 删除 `office_addin`。 + +## 不做的事 + +- 不继续投入 Office.js 持久安装方案。 +- 不依赖企业账号作为普通用户安装前提。 +- 不用图片对象伪装成可编辑公式。 +- 不保留无法识别来源的历史兼容逻辑。 +- 不让文档对象生命周期依赖任务窗格是否打开。 diff --git a/office_addin/README.md b/office_addin/README.md index 7bfc6e5..a7571b7 100644 --- a/office_addin/README.md +++ b/office_addin/README.md @@ -1,8 +1,20 @@ -# LaTeXSnipper Office 加载项 +# LaTeXSnipper Office.js 加载项 -该加载项通过本机 LaTeXSnipper Office Bridge 为 Word 和 PowerPoint 提供公式输入与截图识别。任务窗格、编辑器和 Ribbon 文本会按 Office 显示语言在中文与英文之间自动切换。 +`office_addin` 是当前已实现的 Office.js 加载项,也是迁移到 Windows 原生 Office 插件前的参考实现。它会暂时保留,用来复用 UI、Bridge 协议、OMML 转换、截图识别联动和 Word 编号公式处理经验;迁移完成后再安全删除。 -## 当前功能 +它不是 LaTeXSnipper Office 集成的最终方向。没有 Microsoft 365 企业部署、Office Store 或受信任共享目录时,Office.js 不能稳定提供类似 MathType、AxMath 的持久 Ribbon、原生对象、双击编辑和底层快捷键体验。 + +## 当前定位 + +| 项目 | 定位 | +|---|---| +| `office_addin` | Office.js 迁移参考和临时可用实现 | +| `office_plugin` | 计划中的 Windows 原生 Office 插件主线 | +| 桌面端 Bridge | 继续作为 OCR、LaTeX 转换、OMML/图片生成和本地渲染服务 | + +后续新增 Office 能力默认进入 `office_plugin`,不再把 Office.js 作为最终产品架构扩展。 + +## 已实现能力 ### Word @@ -33,14 +45,23 @@ PowerPoint 通过 `Office.CoercionType.Image` 插入 PNG 图像: PowerPoint 不提供已插入公式图像的 `Load`、`Update`、`Delete Selected`、`Auto Numbered` 或 `Renumber All`。正式可用的 `Office.CoercionType.Image` 写入路径不会返回可由插件持续跟踪的图片对象;删除图像后无法可靠识别哪些编号仍存在,因此 PPT 不生成伪自动编号。 -## Office.js 能力边界 +## Office.js 边界 -本实现已经覆盖当前目标中 Office.js 可可靠交付的边界: +本目录的实现只承认 Office.js 能可靠交付的范围: -- Word 只编辑和维护本加载项创建且仍具备元数据的公式,不猜测任意原生 Word 公式的 LaTeX 来源。 -- PowerPoint 只交付稳定的公式图像插入,不宣称提供原生可编辑公式对象。 +- Word 只编辑和维护本加载项创建且仍具备元数据的 OMML 公式。 +- PowerPoint 只交付稳定的公式图像插入。 +- 不猜测任意 Word 原生公式的 LaTeX 来源。 +- 不把 PowerPoint 图片伪装成可再次编辑的公式对象。 - 不保留损坏对象、历史结构或外来对象的兼容兜底逻辑。 +无法用 Office.js 可靠解决的需求已经转入原生插件设计: + +- 安装后长期稳定显示 Ribbon,无需企业账号或 Office 管理中心部署。 +- Word/PPT 中的每个公式都是可识别、可双击编辑、可持久保存源数据的原生对象。 +- 支持 OLE 公式对象、原生自绘渲染和快捷键。 +- 支持类似 MathType/AxMath 的 Windows 桌面插件体验。 + ## 支持要求 | 宿主 | 要求 | @@ -50,18 +71,6 @@ PowerPoint 不提供已插入公式图像的 `Load`、`Update`、`Delete Selecte 本地 Bridge 与桌面截图依赖使 Web 和移动版 Office 不属于当前支持范围。 -## 正式安装与分发 - -发布流水线生成本机运行时安装包以及持久部署 manifest 包: - -| 平台 | 产物 | 实际行为 | -|---|---|---| -| Windows | `OfficeAddinSetup-.exe` | 为当前用户安装站点与 `localhost` TLS 证书,并写入 Word/PPT 本机 sideload 注册;可选择安装目录 | -| macOS | `OfficeAddin-.pkg` | 安装站点与 `localhost` TLS 证书,并将 manifest 放入 Word/PPT 本机 sideload 目录 | -| Microsoft 365 部署 | `OfficeDeploymentManifests-.zip` | 包含 Word/PPT 生产 manifest,由管理员在 Microsoft 365 管理中心的 Integrated apps 中部署 | - -安装包提供单机 sideload 安装;安装后先重启已启用 Office 功能的 LaTeXSnipper 桌面端,再重启桌面版 Office。Windows 会将所选安装目录记录到当前用户注册表,并从该目录载入站点与 manifest,因此更改安装路径不会切断 Bridge 或 Ribbon 资源。Mac 可从 **开始 → 加载项** 打开已部署的加载项。本机 sideload 不是组织级生产分发机制。需要由 Office 持续分配给用户的 Ribbon 插件时,管理员应通过 Integrated apps 部署生产 manifest。 - ## 开发启动 首次使用前安装依赖并信任开发证书: @@ -100,9 +109,12 @@ npm run dev:powerpoint | `src/services/equationSession.ts` | Word 文档设置和编号状态 | | `../src/integration/office/addin_runtime.py` | 发现正式安装的站点与本机 TLS 配置 | -官方依据: -[Word requirement sets](https://learn.microsoft.com/javascript/api/requirement-sets/word/word-api-requirement-sets); -[Shared runtime requirement sets](https://learn.microsoft.com/javascript/api/requirement-sets/common/shared-runtime-requirement-sets); -[Image coercion requirement sets](https://learn.microsoft.com/javascript/api/requirement-sets/common/image-coercion-requirement-sets); -[Shared folder catalog sideloading on Windows](https://learn.microsoft.com/office/dev/add-ins/testing/create-a-network-shared-folder-catalog-for-task-pane-and-content-add-ins); -[Sideloading on Mac](https://learn.microsoft.com/office/dev/add-ins/testing/sideload-an-office-add-in-on-mac)。 +## 原生插件迁移原则 + +- 不把 Office.js 的 sideload、manifest、WebView 限制带入 `office_plugin`。 +- 保留 Bridge 的能力边界:OCR、转换、渲染、模型状态由桌面端负责。 +- Word 最终支持 OMML 公式和 LaTeXSnipper OLE 公式对象两种表示。 +- PowerPoint 最终支持当前 OMML 图片插入和 LaTeXSnipper OLE 公式对象两种表示。 +- 公式源数据、渲染参数、编号信息必须随对象持久保存,而不是依赖临时任务窗格状态。 + +详细目标架构见 `../docs/office_plugin_design.md`。 diff --git a/readme.md b/readme.md index 9974cba..ab19047 100644 --- a/readme.md +++ b/readme.md @@ -110,6 +110,24 @@ The main window includes PDF recognition and a separate bilingual reading tool: --- +## Office Integration Direction + +LaTeXSnipper is moving its Office integration from the current Office.js add-in toward a Windows-native plugin model. + +The current `office_addin` project is kept as a migration reference. It already proves the Bridge protocol, OMML insertion, PowerPoint image insertion, OCR handoff, and Word numbering behavior, but Office.js cannot reliably deliver the final product experience for single-user installs: persistent Ribbon loading, native formula objects, double-click editing, low-level shortcuts, and MathType/AxMath-style object lifecycle control. + +The planned `office_plugin` line targets Windows desktop Office: + +- Word: native OMML insertion and LaTeXSnipper OLE formula objects +- PowerPoint: current compatible image insertion and LaTeXSnipper OLE formula objects +- Local MathJax/MathLive/native rendering pipeline for self-rendered formula objects +- Per-formula persisted LaTeX source, render options, numbering data, and object identity +- Native Ribbon, shortcuts, double-click editing, update, delete, and renumber workflows + +See [Windows native Office plugin design](docs/office_plugin_design.md) and [Office.js migration record](docs/office_addin_design.md). + +--- + ## Computation Coverage The workbench currently covers common scenarios such as: @@ -269,11 +287,11 @@ is treated as a template runtime and must not be mutated by packaging scripts. GitHub Actions release builds run the platform package jobs in one workflow: -- Windows: Inno desktop installer and a separate Office add-in Inno installer; SignPath-signed artifacts are preferred, with unsigned fallbacks when signing is unavailable. +- Windows: Inno desktop installer; SignPath-signed artifacts are preferred, with unsigned fallbacks when signing is unavailable. - Linux: Debian/Ubuntu `.deb` package from `scripts/build_deb.sh`. -- macOS: `.app.zip` and `.dmg` artifacts from `scripts/build_macos.sh`, plus the Office add-in `.pkg` from `scripts/build_office_addin_macos.sh`. +- macOS: `.app.zip` and `.dmg` artifacts from `scripts/build_macos.sh`. -The Office packages install the localhost HTTPS site consumed by the LaTeXSnipper Office Bridge and set up per-user local sideload registration for desktop Office. Releases also contain production Word/PowerPoint manifests for managed deployment through Microsoft 365 Integrated apps. Each client still requires the desktop application with its Office feature enabled. +The old Office.js packages are retained only while `office_addin` is used as a migration reference. They install a localhost HTTPS site and local sideload manifests, but they are not the final Office plugin distribution path. The planned Windows-native `office_plugin` installer will own persistent Word/PowerPoint registration, Ribbon resources, OLE object registration, and shortcut integration. The release workflow expects these GitHub Actions variables: `SIGNPATH_ORGANIZATION_ID`, `SIGNPATH_PROJECT_SLUG`, @@ -312,6 +330,8 @@ LaTeXSnipper/ |-- tools/ | `-- deps/ # Local developer/build dependency environment |-- user_manual/ # Local manual source and generated PDF +|-- office_addin/ # Legacy Office.js add-in kept for migration +|-- docs/office_plugin_design.md # Windows-native Office plugin target design |-- Inno/ # GitHub Release installer scripts |-- packaging/ # Debian and MSIX packaging resources |-- scripts/ # Build, release, and regression utilities diff --git a/test/test_office_plugin_docs.py b/test/test_office_plugin_docs.py new file mode 100644 index 0000000..fa25385 --- /dev/null +++ b/test/test_office_plugin_docs.py @@ -0,0 +1,28 @@ +# coding: utf-8 + +from __future__ import annotations + +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] + + +def test_office_docs_point_to_native_plugin_as_final_direction() -> None: + root_readme = (ROOT / "readme.md").read_text(encoding="utf-8") + addin_readme = (ROOT / "office_addin" / "README.md").read_text(encoding="utf-8") + migration_doc = (ROOT / "docs" / "office_addin_design.md").read_text(encoding="utf-8") + plugin_doc = (ROOT / "docs" / "office_plugin_design.md").read_text(encoding="utf-8") + + assert "Office Integration Direction" in root_readme + assert "Windows-native plugin" in root_readme + assert "office_addin` project is kept as a migration reference" in root_readme + assert "不是 LaTeXSnipper Office 集成的最终方向" in addin_readme + assert "Office.js Add-in 迁移记录" in migration_doc + assert "不适合作为最终产品形态" in migration_doc + assert "Windows 原生 Office 插件目标架构" in plugin_doc + assert "LaTeXSnipper OLE 公式对象" in plugin_doc + assert "本地 MathJax 原生渲染管线" in plugin_doc + assert "双击编辑" in plugin_doc + assert "OfficeDeploymentManifests" not in addin_readme + assert "Microsoft 365 Integrated apps" not in addin_readme