如何提高 org-mode 的 LaTeX 预览速度?

背景

数学PhD在读, 平时在WSL 2 + VcXsrv 使用doom emacs + org-mode (org-roam + org-noter) 记笔记和写推导过程, 需要用 LaTeX 写大量公式并实时地来回翻阅.

问题

类似于 org-latex-impatientemacs-webkit-katex-render 不太适合我, 因为它是光标在公式上时才预览, 但我需要一直看得到公式才不会打断思考.

导出成 HTML 或 PDF 后查看会稍微好一点, 但是就多了一个来回切换的步骤. 而且我需要在不同笔记中来回切换看不同的内容, 如果使用导出再查看的话就意味着我不能使用 org-roam 的链接, 也不能在笔记中快速搜索.

org-mode 的 LaTeX 预览机制貌似和 auctex 的预览机制不同, 只能单线程地进行预览, 我使用了 org-fragtog 来进行自动预览, 但是每次写完一个公式后自动预览时整个 emacs 都会卡一下. 这种短时间的卡顿还能接受, 但是随着笔记量(笔记数量和单个笔记的内容量)的增加, 每次打开一个笔记都需要很长时间. 即使有预览图片的 cache , 笔记量一增加, 索引这些图片并显示的时间也变得很长.

在有cache且保证没有冗余cache(即删掉了一些没用或错误的预览图片之后)的情况下, 我现在打开一个文档可能需要30秒到1分钟. 在没有cache的情况下, 单个文档重新渲染的时间可能需要5分钟以上. 这大大影响了我的使用效率.

想问一下大家有没有什么解决方案?

1赞

你具体怎么配置的?文档到底有多大呀?

我这边的设置在 Mac 上会直接创建相应的图片保存在文件夹里。只有第一次写的时候会卡一下,后面就很流畅了。除非把文件夹里的图片全删了后,重新打开时会卡蛮久的。

如果你开了 (setq org-startup-with-latex-preview t) 预览的话,可以考虑下关掉?然后通过 org-fragtog 移动光标只看自己需要的公式预览?

也可以试试 (setq org-startup-folded t),默认只显示一级标题,这样应该不会直接加载全部的图片吧?

我的设置:https://github.com/willbchang/ward-emacs/blob/master/config.org#org-fragtog

(use-package org-fragtog
  :hook
  (org-mode . org-fragtog-mode)
  :config
  (setq org-startup-with-latex-preview t)
  (setq org-format-latex-options (plist-put org-format-latex-options :scale 2.0))
  :custom
  (org-fragtog-preview-delay 1.0))

其它可能相关的因素:

(org-latex-pdf-process '("xelatex -interaction nonstopmode %f" "xelatex -interaction nonstopmode %f"))

我用的是

有 456 个图片,打开文档时没有卡顿的感觉。

Reddit上也有类似的问题,似乎无解:

https://www.reddit.com/r/emacs/comments/pr2tzz/is_it_possible_to_speed_up_the_latex_fragments/

但有org-mode的开发者在尝试异步的预览图片生成,不清楚进展如何。

我个人也有很多数学相关的笔记,除非清理缓存的图片,或者升级emacs,打开的速度还算可以接受。

我也有这个文件夹, 但是可能我的公式比较多, 我单个 org 文档的公式预览图片就将近1000了… 多个合起来就更多了… 所以即使有这个文件夹, 每次打开还是很慢.

我现在就是把 latex-preview 关掉的, 但是因为我公式多, 所以要预览特定某几个公式的时候比较难定位.

我也有看到这个链接, 没有找到对应的解决方案才来论坛上问问看 :tired_face:

  1. 有没有可能把单个文件进一步拆分?
  2. Swiper 输入 latex 实时查找?

附上配置

(use-package counsel
  :bind
  (("M-x" . counsel-M-x)
   ("s-f" . swiper)
   ("s-F" . counsel-rg))
  :config
  (use-package flx)
  (use-package amx)

  (ivy-mode 1)
  (add-to-list 'ivy-more-chars-alist '(counsel-rg . 1))
  (setq ivy-use-virtual-buffers t)
  (setq ivy-count-format "(%d/%d) ")
  (setq ivy-initial-inputs-alist nil)
  (setq ivy-re-builders-alist
        '((swiper     . ivy--regex-plus)
          (counsel-rg . ivy--regex-plus)
          (t          . ivy--regex-fuzzy))))

这个搜索倒是没想到 :open_mouth:

谢谢~如果没有更好的解决方案就只能先这样了。

感觉可以开 latex preview,只要 buffer 开了别关就行。看上去你的难处在于打开巨型笔记过慢,但是如果只有几条巨型笔记,那每天花几分钟开了就别关,个人感觉还能忍

我不用 org fragtop, 写完公式直接手动 org-latex-preview 一下,也会卡几秒但那是因为 latex 编译卡顿,并且这个几秒的卡顿不会随着 org 文档变大而变得更长

xenops支持org的异步preview

2赞

这个包很好用,这名字起的,以前搜都搜不到

太强了!非常好用的东西,需要多加推广。

我试用过这个包, 但是一直没有成功用起来, 我在 org-mode 里直接运行 xenops-mode 会报错, 提示 invalid function.

在 LaTeX-mode 里成功运行过一次, 结果把 emacs 给卡死了…

可能是我的使用姿势不太正确 :joy: :joy:

我在办公室有一台学校分配的台式机, 自己有一台笔记本, 两台电脑用 OneDrive 同步, 所以经常会出现一种情况是: 在一台电脑上写了很多内容之后, 第二天在另一台电脑上打开就需要更长的时间. :joy:

它默认会开32个latex线程,你得改一下xenops-math-latex-max-tasks-in-flight

我昨天晚上折腾了一下, 发现doom build之后就能用了, 也很流畅!

不过我想请教一下, 要怎么在打开 org-mode buffer 的时候自动启动 xenops-mode? 直接 add-hook 会报错: void variable: tex--prettify-symbols-alist.

试了一下,感觉很不错,唯一的问题是它不支持公式中的换行,比如:

$a+
b$

但对很长的公式,比如有各种aligned,matrix环境嵌套的公式,不换行代码就太混乱了。不知有没有什么解决办法

因为行内公式只能是一行的。

谢谢!我的例子举得不好,原本是想说display math的。不过我也找到原因了,貌似是分隔符必须对齐才行。

比如这个就不行:

\[a+
b\]

但这样写就可以了:

\[a+
b
\]

你应该是又举了个错误的例子

这样的应该也行

是的,它匹配公式的起始和结尾分隔符用的正则表达式分别是"^[ ]*\\\\\\[""^[ ]*\\\\\\]"

因此只要在一行的开头,前面有任意个空白字符都可以。

这个匹配逻辑跟org-mode自带的函数org-inside-LaTeX-fragment-p不一样,让我有点不习惯,不过问题不大。