-
Notifications
You must be signed in to change notification settings - Fork 0
Math Preview
TeXLeaf 1.0.0 内置活动公式预览。它的产品方向受到 Ultra Math Preview 与 hscopes-booster 启发;当前版本使用随 VSIX 提供的 MathJax 4.1.3 和 New Computer Modern SVG 字体渲染活动公式。更完整的来源说明见 致谢与联合开发。
预览只读当前活动公式,不修改 TeX 文档、字符偏移、选择区或撤销历史。
扫描器识别:
$...$$$...$$\(...\)\[...\]mathdisplaymathequation-
align、alignat、aligned、alignedat -
gather、gathered -
multline、flalign、split -
cases、array -
matrix、pmatrix、bmatrix、Bmatrix、vmatrix、Vmatrix、smallmatrix - 上述常见环境的星号形式。
扫描会跳过注释、\verb、verbatim、Verbatim、lstlisting 和 minted 内容。嵌套 matrix/cases 等作为同一外层公式的一部分处理,避免显示重复卡片。
Math Preview 只在已保存的 .tex 文档、LaTeX/TeX language ID 和启用设置下运行;.bib、Untitled 或 Markdown 不显示。
texleaf.mathPreview.presentation 有三种值:
| 值 | 行为 |
|---|---|
cursor |
默认;光标进入公式时显示浮动卡片 |
hover |
使用 VS Code 原生 Hover 显示无光标公式 |
both |
同时注册 cursor 和 Hover |
默认 cursor 可以减少与 LaTeX Workshop 等扩展自带 Hover 的重复。若主题或某版 VS Code 与浮动 decoration 不兼容,可切到 hover 作为稳定降级路径。
cursor 模式会把编辑器光标位置规划到安全 TeX 边界,再向 MathJax 输入中插入一条窄的 \rule:
- 形状类似
|; - 深色主题使用鲜艳青色
#00e5ff; - 浅色主题使用洋红色
#e0005a; - 不把标记插入命令名、环境名、
\left/\right定界符、分数参数边界、注释、verb、UTF-16 surrogate pair 等危险位置; - 带光标渲染失败时自动回退到无光标公式,而不是只剩空框。
Hover 模式不显示光标标记。
行内公式的 autoBelow 模式优先使用“活动源码行下方”,autoAbove 则优先使用“活动源码行上方”:
- 光标在公式起始行:卡片左边缘与
$或\(opening delimiter 对齐; - 光标在同一多行公式的后续行:卡片移动到该活动行的所选方向,左边缘与该行第一个非空白字符对齐;
- 不与光标的横坐标对齐;
- 不强制跑到编辑器第 0 列;
- 首选侧空间不足时,两种自动模式会按下节规则尝试另一侧;
above/below则固定垂直方向。
卡片绝对定位,不参与 Monaco 的同行文字宽度计算,因此不会像旧版行内附件那样把后续输入推挤、折行或叠成一团。
行间公式保持 opening delimiter 的静态水平起点:
-
\[对齐它的反斜杠; -
$$对齐第一个$; -
\begin{align}、\begin{equation}等对齐\begin的反斜杠; - 纵向锚点落在结束行或可见尾部时,会根据 Tab 和缩进计算视觉列补偿,仍保持 opening 列;
- 最多只注入一个经过数值限制的
ch平移,不把文档文本或任意 CSS 拼入 decoration。
VS Code 稳定 API 不公开编辑器内容视口的可靠像素右边界。TeXLeaf 因此不做会偶尔跳到第 0 列的伪“右侧空间自动拟合”;超宽卡片保持正确 opening 对齐,右端可能被编辑器裁切。
默认 autoBelow 是“自动(优先下方)”:
- 下方能完整容纳预览时显示在下方;
- 下方不足时改到上方。
新增的 autoAbove 是“自动(优先上方)”:
- 上方能完整容纳预览时显示在上方;
- 上方不足时改到下方。
如果上下都不能完整容纳预览,两种自动模式都强制选择上方。对于超高、多行公式,它们共用同一套 overflow-tail 锚点:允许卡片顶部被视口裁切,同时尽量保留预览底部和公式源码最后三行,便于继续写公式尾部。
显式 above / below 严格服从用户选择,不自动改方向,也不会为显示预览而滚动文档。位置选择只依据公式边界、可见空间和设置,不根据原生 Suggest 候选数量猜测小组件方向。
旧设置值 auto 仍作为 autoBelow 的运行时兼容别名生效,避免已有用户配置突然改变方向;它不再出现在设置 UI 的可选值中,新配置应使用对称名称 autoBelow。
卡片的背景、边框、内边距和圆角直接画入安全 SVG:
| 主题 | 公式 | 光标 | 背景 | 边框 |
|---|---|---|---|---|
| 深色 | #ffffff |
#00e5ff |
#0b0f14,100% 不透明 |
白色,32% |
| 浅色 | #202020 |
#e0005a |
#fafafc,100% 不透明 |
黑色,28% |
不透明背景可避免壁纸、透明主题和源码字符穿透公式。MathJax 输出使用真正的 SVG path/use,加上高精度渲染提示;不是公式截图或字体 <text>。
最终抗锯齿仍由 VS Code 内嵌 Chromium、操作系统缩放、显示器和 window.zoomLevel 决定。TeXLeaf 不提供单独“硬件加速”开关;GPU/软件渲染由 VS Code 全局控制。关闭 VS Code 硬件加速可能改变抗锯齿,但不应作为 TeXLeaf 的默认排障步骤。
渲染架构:
- 扫描和当前公式选择在扩展侧进行;
- MathJax 首次需要时才懒加载到 Node Worker Thread;
- Worker 队列最多 32 个请求;
- 单次渲染超时 5 秒,超时后重启 Worker,避免扩展宿主永久卡住;
- 渲染和资产缓存各保留最多 64 项;
- 失败结果有短暂重试冷却,避免非法 TeX 每次按键反复重算;
- 文档版本、公式源码、主题、缩放和宏指纹参与缓存 key;
- 过时 generation 的结果不会覆盖新文档版本;
- 4,000 行或 1 MiB 以上大文档自动把防抖至少提高到 300 ms。
cursor / both 在连续输入时采用 last-known-good(stale-while-revalidate)策略:文档变化只重新调度,不先清空现有卡片;下一张有效 SVG 通过同一个稳定 decoration 原位换帧。临时不完整 TeX 或中间渲染失败有 750 ms 宽限,新输入或成功渲染会取消旧失败计时;Hover SVG 只在实际请求 Hover 时写入扩展私有缓存,不阻塞 cursor 帧更新。这样可避免每次按键造成“消失—重现”,同时仍拒绝过时 generation 覆盖新内容。
旧卡片不会无限保留:光标离开可识别公式、禁用预览、运行 TeXLeaf: 关闭当前 Math Preview,或停在无效状态超过 750 ms 后都会清理。hover 使用 VS Code 原生 Hover;编辑器在输入时可能主动关闭它,因此连续输入稳定性特指 cursor decoration,不承诺改变原生 Hover 的生命周期。
cursor 卡片宽度超过 40em 时会等比缩放;256em 高度只是异常 TeX 几何的绘制安全上限,不是把普通长公式强行压成 8em。
可通过 texleaf.mathPreview.debounceMs、scale 和 maxSourceLength 调整开销。完整默认值见 配置参考。
可以在设置中提供宏:
规则:
- 键名不含开头反斜杠,只允许字母和
@; - 最多 128 项;
- 单个 replacement 最多 2,048 字符;
- 序列化后总长度最多 16,384 个 UTF-16 字符;
- 参数个数可以从
#1...#9推断; - 文档前言中受支持的定义覆盖同名设置。
扫描器会从前言解析保守形式的:
\newcommand\renewcommand\providecommand\DeclareMathOperator
复杂 TeX 宏展开不等同于真正 LaTeX 引擎;动态包加载、任意代码和递归宏受限。
Worker 只启用明确允许的 MathJax TeX package,例如 base、ams、mathtools、newcommand、color 和受限 configmacros。安全边界包括:
- 用户设置的最大公式长度,默认 8,192;Worker 硬上限 32,768;
- MathJax
maxBuffer和宏展开上限; - 受限宏数量、名称、替换长度和总序列化长度;
- 禁用动态
require/autoload 和 HTML 类输入; - 输出必须是闭合 SVG;
- 拒绝
script、foreignObject、iframe/object/embed、事件属性和外部 URL; - decoration 使用 Base64
data:SVG,避免 Windows 长缓存路径导致空框;Hover 资产使用扩展私有缓存。
| 命令 | 作用 |
|---|---|
| TeXLeaf: 切换 Math Preview | 在当前资源所属范围切换总开关 |
| TeXLeaf: 刷新 Math Preview | 清除扫描、SVG、错误和资产缓存并重渲染 |
| TeXLeaf: 关闭当前 Math Preview | 暂时隐藏当前卡片;继续编辑或移动光标后可再出现 |
cursor 卡片显示时按 Escape 可关闭;Suggest、Rename 或 Inline Suggest 活动时不会抢占 Escape。
cursor 预览使用 Monaco decoration 的固定 ::before 兼容层,因为 VS Code 稳定扩展 API 不提供公开 view-zone 或任意编辑器浮层接口。这带来明确限制:
- 卡片不能给正文真正预留垂直空间;上下紧邻正文时可能暂时遮住相邻行;
- 无法可靠读取横向视口像素,所以超宽卡片允许右端裁切;
- 无法读取 Suggest 等原生弹出小组件的公开几何,预览不会跟随其开关或尺寸自动换边;
- decoration 没有可靠点击回调;
- 不能在保持 TextEditor 光标、选择、折叠、撤销和诊断语义的同时,把源码范围替换成可点击 MathJax 部件。
因此 TeXLeaf 专注于不改变源码语义的活动公式预览,不提供“光标离开后原地变公式、点击恢复源码”的整篇所见即所得替换,也不内置 PDF Webview 或 Custom Editor。需要 PDF 编译和 SyncTeX 时,请继续使用 LaTeX Workshop 或自己的构建工具。
- 默认使用
cursor,避免重复 Hover; - 若 LaTeX Workshop Hover 仍重叠,保持 TeXLeaf
cursor或关闭其中一方 Hover; - 如果同时启用其他公式预览扩展,应选择其中一个 cursor/hover 入口,避免重复卡片;
- 两个 cursor decoration 同时存在时,分别关闭其中一个扩展的预览总开关;
- 主题透明度不会传入 TeXLeaf 卡片背景,但主题或 VS Code 更新仍可能影响 decoration 定位。
| 症状 | 处理 |
|---|---|
| 只有圆角空框 | 运行刷新命令;确认当前是 1.0.0;查看 Output 中 MathJax/资产错误 |
| 深色公式模糊 | 检查 VS Code zoom/系统缩放;切换默认主题比较;不要用全局 CSS 给 SVG 加 stroke |
| 卡片遮住相邻行 | 增加公式附近空白行,改用 hover,或显式 above/below
|
| Suggest 挡住卡片 | Suggest 通常出现在光标下方,可改用 autoAbove 优先把预览放在上方;需要完全固定时使用 above。VS Code 不公开小组件几何,预览不会根据它自动换边 |
| 行间公式右端被裁切 | 这是保持 opening 对齐的已知边界;可降低 scale 或临时横向滚动 |
| 预览没对齐 | 检查 opening delimiter、Tab Size;提供最小复现和截图 |
| 自定义宏不生效 | 键不要带 \;检查长度/数量;运行刷新命令;简化定义 |
| 持续输入时 cursor 卡片每键消失 | 确认已升级到 1.0.0;cursor/both 会保留 last-known-good 并原位换帧,短暂失败宽限 750 ms |
| 停在非法公式后旧卡片仍短暂显示 | 这是 750 ms 宽限;继续完成公式,或等待清理。离开公式、禁用和 Dismiss 会立即清理 |
| 原生 Hover 输入时关闭 | VS Code 控制 Hover 生命周期;需要连续输入稳定显示时使用 cursor 或 both
|
| 大文档更新慢 | 大文档自动至少 300 ms;可进一步提高 debounce、降低 maxSourceLength |
更详细的日志与平台排查见 故障排查。
开始
片段
AI 写作
文献
预览
贡献与发布
{ "texleaf.mathPreview.macros": { "RR": "\\mathbb{R}", "inner": ["\\left\\langle #1,#2 \\right\\rangle", 2] } }