Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 11 additions & 12 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ jobs:
uses: actions/upload-artifact@v7
with:
name: unsigned-latexsnipper-installer
path: dist/installer/LaTeXSnipperSetup-*.exe
path: dist/installer/LaTeXSnipper_*_amd64.exe
if-no-files-found: error
retention-days: 30

Expand Down Expand Up @@ -197,7 +197,7 @@ jobs:

build-office-plugin-installer:
name: Validate Office Plugin Installer
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v6
Expand Down Expand Up @@ -226,7 +226,7 @@ jobs:
echo "Release version $version does not match VERSION $product_version." >&2
exit 1
fi
installer="office_plugin/release/OfficePluginSetup-${version}.exe"
installer="office_plugin/release/LaTeXSnipper_${version}_office_amd64.exe"
checksum="${installer}.sha256"
test -f "$installer"
test -f "$checksum"
Expand Down Expand Up @@ -358,7 +358,6 @@ jobs:
name: latexsnipper-macos
path: |
dist/*.dmg
dist/*.app.zip
dist/SHA256SUMS-macos.txt
if-no-files-found: error
retention-days: 30
Expand Down Expand Up @@ -398,7 +397,7 @@ jobs:
publish-release-assets:
name: Publish Release Assets
if: ${{ always() && (startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_dispatch' && inputs.publish_assets)) && needs.build-windows-installer.result == 'success' && needs.build-office-plugin-installer.result == 'success' && needs.build-linux-deb.result == 'success' && needs.build-macos-app.result == 'success' && needs.build-user-manual.result == 'success' }}
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
needs:
- build-windows-installer
- build-linux-deb
Expand All @@ -425,30 +424,30 @@ jobs:
mkdir -p publish-assets

if [[ -d release-assets/signed-latexsnipper-installer ]]; then
signed_count="$(find release-assets/signed-latexsnipper-installer -type f -name 'LaTeXSnipperSetup-*.exe' | wc -l | tr -d ' ')"
signed_count="$(find release-assets/signed-latexsnipper-installer -type f -name 'LaTeXSnipper_*_amd64.exe' | wc -l | tr -d ' ')"
else
signed_count="0"
fi

if [[ "${signed_count}" != "0" ]]; then
echo "Using signed Windows installer."
find release-assets/signed-latexsnipper-installer -type f -name 'LaTeXSnipperSetup-*.exe' -exec cp -v {} publish-assets/ \;
find release-assets/signed-latexsnipper-installer -type f -name 'LaTeXSnipper_*_amd64.exe' -exec cp -v {} publish-assets/ \;
elif [[ -d release-assets/unsigned-latexsnipper-installer ]]; then
unsigned_count="$(find release-assets/unsigned-latexsnipper-installer -type f -name 'LaTeXSnipperSetup-*.exe' | wc -l | tr -d ' ')"
unsigned_count="$(find release-assets/unsigned-latexsnipper-installer -type f -name 'LaTeXSnipper_*_amd64.exe' | wc -l | tr -d ' ')"
if [[ "${unsigned_count}" != "0" ]]; then
echo "Signed Windows installer is missing; using unsigned Windows installer."
find release-assets/unsigned-latexsnipper-installer -type f -name 'LaTeXSnipperSetup-*.exe' -exec cp -v {} publish-assets/ \;
find release-assets/unsigned-latexsnipper-installer -type f -name 'LaTeXSnipper_*_amd64.exe' -exec cp -v {} publish-assets/ \;
else
echo "Unsigned Windows installer artifact exists but contains no LaTeXSnipperSetup-*.exe; skipping Windows release asset."
echo "Unsigned Windows installer artifact exists but contains no LaTeXSnipper_*_amd64.exe; skipping Windows release asset."
fi
else
echo "No signed or unsigned Windows installer artifact found; skipping Windows release asset."
fi

find release-assets/office-plugin-installer -type f -name 'OfficePluginSetup-*.exe' -exec cp -v {} publish-assets/ \;
find release-assets/office-plugin-installer -type f -name 'LaTeXSnipper_*_office_amd64.exe' -exec cp -v {} publish-assets/ \;
find release-assets/user-manual -type f -name 'LaTeXSnipper_User_Manual.pdf' -exec cp -v {} publish-assets/ \;
find release-assets/latexsnipper-linux-deb -type f -name '*.deb' -exec cp -v {} publish-assets/ \;
find release-assets/latexsnipper-macos -type f \( -name '*.dmg' -o -name '*.app.zip' \) -exec cp -v {} publish-assets/ \;
find release-assets/latexsnipper-macos -type f -name '*.dmg' -exec cp -v {} publish-assets/ \;

asset_count="$(find publish-assets -maxdepth 1 -type f | wc -l | tr -d ' ')"
if [[ "${asset_count}" == "0" ]]; then
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ packaging/debian/usr

# Large binary files
*.exe
!office_plugin/release/OfficePluginSetup-*.exe
!office_plugin/release/LaTeXSnipper_*_office_amd64.exe
office_plugin/release/InstallerAssets/
*.dll
*.zip
Expand Down
2 changes: 1 addition & 1 deletion .signpath/artifact-configurations/windows-installer.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<artifact-configuration xmlns="http://signpath.io/artifact-configuration/v1">
<zip-file>
<pe-file path="LaTeXSnipperSetup-*.exe">
<pe-file path="LaTeXSnipper_*_amd64.exe">
<authenticode-sign />
</pe-file>
</zip-file>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<artifact-configuration xmlns="http://signpath.io/artifact-configuration/v1">
<zip-file>
<pe-file path="OfficePluginSetup-*.exe">
<pe-file path="LaTeXSnipper_*_office_amd64.exe">
<authenticode-sign />
</pe-file>
</zip-file>
Expand Down
2 changes: 1 addition & 1 deletion Inno/latexsnipper.iss
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ ChangesAssociations=no
DisableProgramGroupPage=yes
LicenseFile={#MyLicenseFile}
OutputDir={#MyOutputDir}
OutputBaseFilename=LaTeXSnipperSetup-{#MyAppVersion}
OutputBaseFilename=LaTeXSnipper_{#MyAppVersion}_amd64
SetupIconFile={#MyRepoRoot}\src\assets\icon.ico
SolidCompression=yes
WizardStyle=modern
Expand Down
8 changes: 4 additions & 4 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@

| 平台 | 下载文件 | 使用识别前注意 |
| ------------------------ | --------------------------------- | -------------------------------------------------------- |
| **Windows** | `LaTeXSnipperSetup-<version>.exe` | 已包含 Python 运行时,无需另装系统 Python |
| **Linux(Debian/Ubuntu)** | 对应架构的 `.deb` | 需要 Python `>=3.10,<3.14` 及 venv/pip;Wayland 可能限制截图和全局快捷键 |
| **macOS** | 对应架构的 `.dmg` 或 `.app.zip` | 需要 Python `>=3.10,<3.14` 及 venv/pip;截图需授予屏幕录制权限 |
| **Windows** | `LaTeXSnipper_<version>_amd64.exe` | 已包含 Python 运行时,无需另装系统 Python |
| **Linux(Debian/Ubuntu)** | `LaTeXSnipper_<version>_<architecture>.deb` | 需要 Python `>=3.10,<3.14` 及 venv/pip;Wayland 可能限制截图和全局快捷键 |
| **macOS** | `LaTeXSnipper_<version>_<architecture>.dmg` | 需要 Python `>=3.10,<3.14` 及 venv/pip;截图需授予屏幕录制权限 |

> [!NOTE]
> Linux/macOS 使用系统 Python 创建受管理的依赖环境,Windows 使用内置 Python 3.11 模板。`.deb` 声明了 `python3` 和 `python3-venv` 依赖;macOS 若没有可用 Python,请先安装受支持的版本。
Expand Down Expand Up @@ -83,7 +83,7 @@
* 支持公式编辑、更新,以及 Word 自动编号和引用。
* 本地渲染公式,通过桌面端 Automation API 调用截图识别。

从 [Releases](https://github.com/SakuraMathcraft/LaTeXSnipper/releases/latest) 单独下载 `OfficePluginSetup-<version>.exe`。支持 Windows 上的 32 位和 64 位 Office 2019/2021/2024、LTSC 2021/2024 及 Microsoft 365 Apps。
从 [Releases](https://github.com/SakuraMathcraft/LaTeXSnipper/releases/latest) 单独下载 `LaTeXSnipper_<version>_office_amd64.exe`。支持 Windows 上的 32 位和 64 位 Office 2019/2021/2024、LTSC 2021/2024 及 Microsoft 365 Apps。

[安装要求与完整功能](office_plugin/README.md) · [公式工作流](docs/office_plugin_formula_workflows.md)

Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.1.0
3.1.0
2 changes: 1 addition & 1 deletion docs/automation_api.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Automation API v1

LaTeXSnipper v3.0.0 exposes its resident MathCraft runtime and the external OCR model already configured in the desktop application through a versioned job API. Clients cannot provide or read upstream URLs, model names, credentials, paths, or prompts.
LaTeXSnipper exposes its resident MathCraft runtime and the external OCR model already configured in the desktop application through a versioned job API. Clients cannot provide or read upstream URLs, model names, credentials, paths, or prompts.

## Enable and discover

Expand Down
6 changes: 3 additions & 3 deletions docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ The main differences are platform integration details:
| Window close / background behavior | Closing the main window hides it to the system tray; use the tray menu to exit. | Closing the main window hides it to the system tray when a tray is available; without a tray, the app asks before exiting. | Closing the main window minimizes it while the app keeps running; Dock/menu Quit exits the app. |
| Permission model | No explicit screenshot permission is required for the normal capture path. | Wayland compositors can restrict global shortcuts or screenshot capture. | Screen Recording permission is required for screenshots. The native Carbon hotkey path normally does not require Accessibility permission. |
| Dependency runtime | GitHub builds start from the bundled dependency root `<install-dir>\_internal\deps`; users may switch to another root. | Defaults to `~/.latexsnipper/deps`; users may switch to another root. | Defaults to `~/Library/Application Support/LaTeXSnipper/deps`; users may switch to another root. |
| Packaging | Inno installer from GitHub Releases. | Debian/Ubuntu `.deb`. | `.dmg` and `.app.zip`. |
| Packaging | Inno installer from GitHub Releases. | Debian/Ubuntu `.deb`. | `.dmg`. |

The shortcut UI uses the platform's primary modifier: `Ctrl` on Windows/Linux and `Command` on macOS. macOS system and editing shortcuts such as `Command+Q`, `Command+H`, `Command+M`, `Command+W`, `Command+A`, `Command+C`, `Command+V`, `Command+X`, `Command+Z`, `Command+Space`, `Command+Tab`, and screenshot shortcuts are intentionally rejected; use an `Option+Command` combination when a plain Command shortcut is reserved.

## Which installer should I use?

- Windows: use `LaTeXSnipperSetup-<version>.exe` from GitHub Releases. The release workflow prefers the signed installer; if signing is unavailable, the same filename may be published as an unsigned fallback.
- Windows: use `LaTeXSnipper_<version>_amd64.exe` from GitHub Releases. The release workflow prefers the signed installer; if signing is unavailable, the same filename may be published as an unsigned fallback.
- Linux: use the `.deb` package on Debian/Ubuntu-compatible systems.
- macOS: use the `.dmg` or `.app.zip` artifact.
- macOS: use the `.dmg` artifact for your architecture.

## Why does macOS still say Screen Recording is unavailable after I enabled it?

Expand Down
37 changes: 23 additions & 14 deletions docs/office_plugin_formula_workflows.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,23 @@

- 新建和格式化从当前设置产生样式快照;普通编辑、重编号及转换保留公式已有快照。
- 局部字体与颜色命令优先于默认样式。默认样式在 MathJax 解析后、布局前应用。
- Word OLE、PPT OLE / PNG 使用同一 SVG 轮廓;OMML 复用带样式 MathML,再映射 Word 属性,最终排版由 Word 管理。
- MathLive 目前仍是编辑参考。三类字体的完整设置面板、最终效果预览与预设功能按重构方案后续阶段实施。
- 编辑器以源码最外层 `\textcolor{#RRGGBB}{…}` 表示当前公式的全局颜色;工具栏修改该命令,源码区修改该命令则同步工具栏。提交和预览的 `Typography.Color` 从源码读取,MathLive 继承同一颜色,局部 `\textcolor` 可覆盖外层。右键局部上色立即写入源码。
- Word OLE、PPT OLE / PNG 使用同一 SVG 轮廓;Word OMML 与 PowerPoint 文本内原生公式复用带样式 MathML,由各自宿主管理排版。
- MathLive 提供可视化编辑;符号、数字、汉字三类字体和独立的默认字形共同构成样式快照。设置页的 JSON 导入/导出只管理当前宿主的全局公式默认属性;编辑器内调整只作用于当前公式。

## 用户偏好与升级保留

用户偏好与安装文件分开保存。Word 和 PowerPoint 共用注册表项,但使用不同的值名;两者的公式默认属性也在同一 JSON 文件内分别保存。

| 数据 | 存储位置 | 具体内容 |
| --- | --- | --- |
| Word 插入和编号偏好 | `HKCU\Software\LaTeXSnipper\OfficePlugin` | `WordInsertionBackend`、`NumberPlacement`、`NumberEnclosure`、`NumberIncludeChapter`、`NumberIncludeSection`、`HideChapterBoundary`、`HideSectionBoundary`、`NumberSeparator` |
| PowerPoint 插入偏好 | 同一注册表项 | `PowerPointInsertionBackend` |
| Word / PowerPoint 公式默认属性 | `%APPDATA%\LaTeXSnipper\OfficePlugin\settings.json` | 两个宿主各自的符号字体、数字字体、汉字字体、默认字形、字号、颜色和新建时跟随文字字号;JSON 导入/导出只读写对应宿主的这组属性 |
| 公式编辑器常用内容 | `%LOCALAPPDATA%\LaTeXSnipper\OfficePlugin\WordEditorWebView2` 和 `PowerPointEditorWebView2` | 各宿主 WebView2 的 `localStorage`:内置磁贴收藏、自定义公式收藏、符号库当前标签与折叠状态;两宿主不互相覆盖 |
| 文档内托管公式 | Word 文档变量与公式对象;PowerPoint OLE / PNG shape tags | 公式源码、身份及各公式自己的样式快照;随 Office 文档保存。PowerPoint 文本内原生公式由 Office 保存,不使用插件 shape tags |

安装包在升级、重装前运行 `ForceClean.ps1`,清理旧安装目录、VSTO / ClickOnce 注册与缓存、OLE 注册,以及 `%LOCALAPPDATA%\LaTeXSnipper\OfficePlugin\WordAddIn` / `PowerPointAddIn` 渲染缓存和 PowerPoint 临时图片。脚本不删除上述用户偏好注册表项、`settings.json`、两个编辑器 WebView2 目录或 Office 文档。卸载时也调用同一清理脚本并保留这些用户数据。`TypographySettingsStore` 只在读取到损坏或不支持版本的 `settings.json` 时删除该文件并重建默认值,不执行配置迁移;此时注册表中的插入与编号偏好和编辑器常用内容仍保留。

## 统一元数据模型

Expand Down Expand Up @@ -331,14 +346,17 @@ REF LaTeXSnipperEq_{equationId} \h

## PowerPoint 插入、加载、删除、转换、格式化

PowerPoint 没有 Word 编号和引用链路,公式对象是 shape:
PowerPoint 没有 Word 编号和引用链路。插入时按当前位置选择两条路径:

- 文本框内为折叠的文字光标:复用 MathJax 的带样式 MathML 转换,粘贴为 PowerPoint 原生公式,保留同一文本框内的前后文字与自动换行。公式字号使用本次编辑选择;启用“新建时跟随文字字号”时,初值来自文本光标。后续在 PowerPoint 内编辑该原生公式。
- 文字区域外:按设置将 OLE 或 PNG 作为独立幻灯片对象居中插入;选中已有插件公式不妨碍新建。选中一段文字时要求先收起选区到光标。

- 新建保存源码与样式快照,按设置插入 PNG 或 OLE;普通更新使用已有快照。
- OLE / PNG 新建保存源码与样式快照;普通更新使用已有快照。
- 加载从 shape 元数据恢复完整信息;删除同时清理对应 PNG 临时文件。
- OLE / PNG 转换保留源码、样式和原位置 / 用户缩放。
- 所选 / 全文格式化共用样式流程;全文遍历演示文稿各页的托管公式,恢复新的自然尺寸。

PowerPoint 编辑器固定白底黑字,Word 编辑器按系统深色模式适配。编辑参考与最终预览的进一步分工见字体重构方案。
PowerPoint 文本内原生公式不参与插件的加载、OLE / PNG 转换和批量格式化,因为这些操作面向带插件元数据的幻灯片对象。Word 和 PowerPoint 编辑器固定使用浅色界面;编辑区继承源码中的全局颜色。最终预览按当前属性渲染,小字号在屏幕上适当放大以便检查;插入仍使用选定的实际字号。

## 链路复杂度核对

Expand Down Expand Up @@ -387,12 +405,3 @@ Word 插入、更新、删除、编号、解析、转换和格式化都在必要
- OLE 对象本身或 PNG shape。

这些都是 Office 文档内的原生持久化载体,不依赖本机临时内存。PowerPoint PNG 的临时图片路径只用于本机清理文件,不影响公式元数据加载。

## 当前明确边界

- 不从编号数字反向删除公式。
- 不把默认字体/颜色作为编辑器打开时的临时样式。
- 不在加载所选时改写侧边栏用户草稿以外的持久源码。
- 不在格式化全文时批量重写所有公式源码。
- 不把解析与全文重编号耦合;解析后的全局序号校正仍由用户显式执行“重编号”。
- 不扫描非主正文 story,也不跨已有公式、字段、受保护对象或表格单元格边界配对定界符。
Loading