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

我挺好奇楼主是啥专业的哈哈。动手能力不错。

已实现,在develop branch。

预览无法显示:

图片

问题描述: 总是提示 Buffer “org-latex-instant-previewNotes/org-mode.org” has a running process; kill it? (y or n)

并报错

Error reading SVG image ‘(image :type svg :data

StartFraction 1 Over x squared EndFraction equals equals :scale 1 :max-width 1072 :max-height 897)’

环境信息

tex2svg --version 1.0.1

    emacs  version    27.1
    build      Oct 15, 2020
    features   NOTIFY KQUEUE ACL GNUTLS LIBXML2 ZLIB TOOLKIT_SCROLL_BARS MODULES THREADS JSON PDUMPER GMP
    traits     (server-running envvar-file)

latex可以正常渲染,svg也可以正常预览。请问进一步该如何排查问题?

第一个问题看一眼develop branch有没有修好。第二个问题我没理解什么意思,能给一个minimal的复现方式吗?

  1. 切换到develop后, Buffer has a running process 问题解决
  2. 第二个问题的表现预览为空,实例: latex-preview

报错实例就是上面所说的Error reading SVG image。但是emac是能正常预览svg的

看你这个像Mac,我没有Mac,所以不清楚具体情况,可能要你自己调试。具体方式如下:

首先(require 'names-dev),这个是开发namespace要用的包。如果你看了代码,你可能注意到我用了names.el这个包。这个包的作用是可以省略长长的包的名字。然后去看-fill-posframe-buffer这个函数,里面的ss是svg的内容。你可以修改这个函数,把hack之前的ss写进一个.svg为扩展名的文件里,然后用emacs打开,看有没有什么问题。然后把加过scaless也写进一个.svg为扩展名的文件里,看看能不能正常打开。比如把函数改成:

(defun -fill-posframe-buffer ()
  "Write SVG in posframe buffer."
  (let ((ss (with-current-buffer -output-buffer
              (buffer-string))))
    (write-region ss nil "tmp_1.svg")
    (unless (get-buffer -posframe-buffer)
      (get-buffer-create -posframe-buffer))
    ;; when compile error, ss is exactly the error message, so we do nothing.
    ;; Otherwise when compile succeed, do some hacks
    (when (s-contains-p "svg" ss)
      (setq ss
            (concat
             ;; 100% seems wierd
             "<svg height=\"110%\">"
             ;; ad-hoc for scaling
             (format "<g transform=\"scale(%s)\">" scale)
             ss
             "</g></svg>")))
    (write-region ss nil "tmp_2.svg")
    (-insert-into-posframe-buffer ss)
    (setq -last-preview ss)))

函数修改完之后,光标放在函数体中间,运行names-eval-defun,函数就更新了。然后去org文件里去编辑公式,之后把上面的’tmp_1.svg"和"tmp_2.svg"拷贝出来(避免被新的preview给覆盖),看看emacs能不能正常打开。

感谢细致的回复!按照您的提示进行排查,发现原始svg显示正常,放大之后的无法显示。目前我简单粗暴地把放大功能给注释掉了……

两个svg标签嵌套在我的环境中显示有问题,目前能成功放大的方法是指定原始svg的height和 width。对svg不太熟悉,有时间再学习学习。

这个估计是librsvg的问题。有librsvg的坑,也有emacs的SVG实现的坑。在emacs 27上,SVG的无损放大功能有些问题,所以我通过改SVG来实现的scale。在emacs28最新的master上,放大的bug已经修复了,这个修复并不完美,也有没有close的相关bug。

我在develop branch做了修改,如果scale是1.0的话就不做scaling了。你看看能不能解决你的问题,避免你自己搞hack。

没有问题,感谢帮助!

考虑到melpa维护者和一些其他大佬的建议,我不再使用names这个包,并且取了个更短的名字org-latex-impatient。请使用这个包的各位将配置文件里的org-latex-instant-preview-*替换成org-latex-impatient-*。如有不便,请多多包涵。

升级后显示成不知是什么东西,看不清!全是这样,如图:

这个应该是*Message* buffer,看起来像是你字体大小过小了,试试text-scale-increase来放大字体看看。另外,希望能提供你的Emacs的具体信息 (Emacs版本,是否使用了doom/spacemacs等发行版,org-latex-impatient的配置和具体安装方法),还有试试裸Emacs能不能正常运行。

裸Emacs的运行方法:emacs -Q启动Emacs,然后eval下面的内容

     (require 'package)
     (setq package-enable-at-startup nil)
     (add-to-list 'package-archives
                  '("melpa" . "https://melpa.org/packages/"))

     (package-initialize)

之后M-x package-install-file,找到你 local 的org-latex-impatient.el,安装相应依赖。然后(require 'org-latex-impatient)来 load 这个包。设置相应的tex2svg的binary的位置

(setq org-latex-impatient-tex2svg-bin
          ;; location of tex2svg executable
          "~/node_modules/mathjax-node-cli/bin/tex2svg")

最后打开一个 org 文件,M-x org-latex-impatient-mode来启动这个 mode。

1 个赞

windows上无法使用,劳请作者兼容一下windows

不好意思,手头没有Windows的机器,可能需要你自己研究搞定。 在Github的issue里有人分享他在Windows上的解决方案,可以参考一下

@yangsheng6810

在 Window 10测试了一下 (inline 的 $ax^{2}bx+c=0$) 生成的 tex-string 会是

\newcommand{\ensuremath}[1]{#1} \renewcommand{\usepackage}[1]{} \color{#F8F8F2}{ax^{2}bx+c=0}

已用 tex2svg 测试过 生成的将是空 svg

想知道 tex-string 的正确生成应该是 什么样?

@yangsheng6810 使用 Issue 中方法 可以 在 Window 可以使用了 ,

      (let ((tex-string (org-latex-impatient--get-tex-string))
            (latex-header
                  (concat (s-join "" org-latex-impatient-user-latex-definitions) 	;;++
                          ""						                                ;;++														
                          (org-latex-impatient--get-headers)))) 					;;++
        ;;      (concat (s-join "\n" org-latex-impatient-user-latex-definitions)
        ;;              "\n"
        ;;              (org-latex-impatient--get-headers))))
        (unless (org-latex-impatient-inhibit tex-string)
          (setq org-latex-impatient--current-window (selected-window))
          (setq org-latex-impatient--is-inline nil)
          ;; the tex string from latex-fragment includes math delimeters like
          ;; $, $$, \(\), \[\], and we need to remove them.
          (when (org-latex-impatient--need-remove-delimeters)
            (setq tex-string (org-latex-impatient--remove-math-delimeter tex-string)))

          (setq org-latex-impatient--position (org-latex-impatient--get-tex-position)
                ;; set forground color for LaTeX equations.
                tex-string (concat latex-header
                                   (org-latex-impatient--add-color tex-string)))
          (if (and org-latex-impatient--last-tex-string
                   (equal tex-string
                          org-latex-impatient--last-tex-string))
              ;; TeX string is the same, we only need to update posframe
              ;; position.
              (when (and org-latex-impatient--last-position
                         (equal org-latex-impatient--position org-latex-impatient--last-position)
                         ;; do not force showing posframe when a render
                         ;; process is running.
                         (not org-latex-impatient--process)
                         (not org-latex-impatient--force-hidden))
                (org-latex-impatient--show))
            ;; reset `-force-hidden'
            (setq org-latex-impatient--force-hidden nil)
            ;; A new rendering is needed.
            (org-latex-impatient--interrupt-rendering)

            (setq tex-string (s-replace-all '(("^" . "^^^^")) tex-string))		       ;; ++

你的修改是主要加了;;++的那几行吗?

在 Window 上要先用 (image-type-available-p 'svg) 测试 image mode 是否支持 svg

可以看一下 Windows 下 emacs 怎样显示 svg?

得说一句 有这个文件librsvg-2-2.dll不代表支持 svg ,还是要看 (image-type-available-p 'svg) 返回结果

我是重新安装了 Emacs 才支持的

文件修改只有 ;;++ 这些,但我没有对每个语句进行验证,因为是依 Issue 中的来

最后测试结果是可以显示

不过,我只测试了 inline 预览。

恩,多谢。我打算写个针对Windows的FAQ,写好了请您斧正。