新插件:Org-mode LaTeX 即时预览

刚测试了一下,我发现我太久没写latex彻底记错了,BEGIN_EXPORT latex是org-mode自身支持的,不是第三方插件

那你不需要加 begin_scr 呀,直接 \begin{equation}

还是需要BEGIN_EXPORT的啊,不然怎么C-c '进入临时tex-mode buffer。


anyways,现在这个插件无法预览BEGIN_SRCBEGIN_EXPORT latex才是重点,希望可以改进一下

我刚刚傻了,不是 C-c C-c,begin_export 也不需要 org-edit-latex 那个 minor mode 可以处理

(当然用了确实无法预览,同意后面改进部分)

什么叫重启Emacs之后就不再更新了?我应该如何复现?

能给个样例吗?

* 测试
没问题:
\begin{equation}
    y = x 
\end{equation}
有问题:
#+BEGIN_EXPORT latex
  \begin{equation}
    y = x
  \end{equation}
#+END_EXPORT

原因出在start函数的

(let ((datum (org-element-context)))
    (if (memq (org-element-type datum) '(latex-environment latex-fragment))

前者(org-element-context)可得

(latex-environment (:begin 11 :end 54 :value "\\begin{equation}
    y = x 
\\end{equation}
" :post-blank 0 :post-affiliated 11 :parent nil))

而后者(org-element-context)可得

(export-block (:type "LATEX" :begin 59 :end 138 :value "  \\begin{equation}
    y = x
  \\end{equation}
" :post-blank 0 :post-affiliated 59 ...))

抱歉啦,我没有确定准确的复现方法。我先自己看看吧。如果确定是bug再报给你。

试一下https://github.com/yangsheng6810/org-latex-instant-preview/tree/block_export 能不能解决你的问题?能的话我就merge进master

3个问题:

  1. BEGIN_EXPORT block里面的颜色还有问题,无法识别dark mode,block外面的已经好了
  2. 现在是转换整个block里面的内容,有没有办法只识别block里面的数学latex部分?不然这种就会特别难看:
#+BEGIN_EXPORT latex
  打字打字打字打字abcdefgasdasdasd
  \begin{equation}
    y = x
  \end{equation}
#+END_EXPORT
  1. 如果切换buffer,生成的图片不会消失,还会挡视线。建议post-command-hook检查cursor还在不在latex部分甚至还在不在org-mode,不在就kill buffer

feature request: 调节图片大小,现在生成的实在太小了,看的眼睛疼

  1. ??不理解问什么会出现这个情况。你重新eval一下buffer或者开一个clean的Emacs看看。如果还有问题,把光标放在block内外分别eval一下(face-foreground 'default)给我看一下。
  2. 这个要实现会非常麻烦,要搞复杂的LaTeX正则表达式识别(可能还不正则)。我倾向于暂时不弄。另外:好奇你是处于什么理由要把正常的文字放到LaTeX block里去?
  3. 啥?这个功能又坏了?我看一下
  4. 图片大小我研究一下怎么搞

??不理解问什么会出现这个情况。你重新 eval 一下buffer或者开一个clean的Emacs看看。如果还有问题,把光标放在block内外分别 eval 一下 (face-foreground 'default) 给我看一下。

我看了一下你的源代码,当然有问题了啊:

    (if (or (memq (org-element-type datum) '(latex-environment latex-fragment))
            (and (memq (org-element-type datum) '(export-block)) <<< case B
                 (equal (org-element-property :type datum) "LATEX")))
	    (let ((ss (org-element-property :value datum))
              (end (org-element-property :end datum)))
          (when (memq (org-element-type datum) '(latex-fragment))  <<< never true in case B
            (setq ss (-wrap-color
                      (-remove-math-delimeter ss))))

修复方法:

               (end (org-element-property :end datum)))
-          (when (memq (org-element-type datum) '(latex-fragment))
+          (when (memq (org-element-type datum) '(latex-fragment export-block))
  • 这个要实现会非常麻烦,要搞复杂的LaTeX正则表达式识别(可能还不正则)。我倾向于暂时不弄。另外:好奇你是处于什么理由要把正常的文字放到LaTeX block里去?
  1. latex有比较好的补全以及snippet
  2. 一段话有好几个inline math formula,把整段放到latex block里写起来更快更方便
  • 啥?这个功能又坏了?我看一下

我看你现在的实现方式有点麻烦,按我上面说的来比较简单吧

第一个问题已经修复了。 第二个问题:之所以这么实现,是为了能解决窗口被缩放时preview的显示和update问题。

你这修复的。。。

+    (if (-in-latex-p datum) << if A is true
 	      (let ((ss (org-element-property :value datum))
               (end (org-element-property :end datum)))
-          (when (memq (org-element-type datum) '(latex-fragment))
+          (when (-in-latex-p datum) << then if A is true?

靠,脑子秀逗了……我洗个脸回来重新过一遍逻辑。

直接改成这个吧

     (if (-in-latex-p datum)
-	      (let ((ss (org-element-property :value datum))
+	    (let ((ss (-wrap-color
+                   (-remove-math-delimeter (org-element-property :value datum))))
               (end (org-element-property :end datum)))
-          (when (-in-latex-p datum)
-            (setq ss (-wrap-color
-                      (-remove-math-delimeter ss))))

是这样的,-remove-math-delimeter只应该在latex-fragment的时候用,因为只有这种情况用org-element-property :value datum)获得的TeX string有math delimiters。我修了一下,又加了一小段注释,麻烦测试一下。

关于preview不能正确关闭的问题,我这里能不太稳定的复现,需要点时间研究一下是什么情况。

关于图片大小的问题,现在在Emacs里我只能让渲染出来的SVG按位图放大,所以放大的会很糊。考虑到https://emacs.stackexchange.com/questions/55305/svg-image-display-blurry 的情况,可能这很难在Emacs里实现。我打算自己写一个tex2svg,直接用mathjax-node甚至MathJax 3.0。它们都提供了scale的选项。现在的tex2svg功能太局限了。

麻烦测试一下。

ok了

关于preview不能正确关闭的问题,我这里能不太稳定的复现,需要点时间研究一下是什么情况。

你正常浏览一个preview,然后马上C-x C-b进入buffer-menu或者ibuffer,就会发现preview还在

可以按照我刚才说的:建议post-command-hook检查cursor还在不在latex部分甚至还在不在org-mode,不在就kill buffer。如果我没记错的话lsp-ui就是类似这么做的

建议支持C-g keyboard-quit 关闭preview

现在在Emacs里我只能让渲染出来的SVG按位图放大,所以放大的会很糊。

还好吧,你暂时x2应该不会有什么明显的糊

相信我,非常非常的糊,真的。 :joy:

如果不信的话-render函数里这么改了试试看。如果你觉得能忍,我就先加个custom进去:

            (lambda (&rest _)
-             (let ((inhibit-message t))
+             (let ((inhibit-message t)
+                   (image-auto-resize 2.0))
                (with-current-buffer -posframe-buffer

我想尽量不侵入其他buffer的post-command-hook,现在的实现就是只locally改了post-command-hook。具体需要研究一下。

这个我考虑一下跟现有的逻辑怎么合并。

实现了不糊的scaling,在develop branch里。试一下?

赞,你可以把默认调成1.5,然后支持一下C-g 关闭就行了


还有我发现我打开emacs后就有三个buffer,不知道是不是配置问题

*org-latex-instant-preview-outpu...         0 Fundamental
*org-latex-instant-preview-posfr...         0 Fundamental      
*org-latex-instant-preview-outpu...         0 Fundamental

不知道能不能自定义预览的位置和大小?比如我想在buffer底部显示并且占整个buffer的宽度。