Emacs org-mode 的 inline latex 公式中显示中文

默认情况下,inline latex 公式不支持中文,使用不便。跟踪实现 org.el 中实现 inline latex 公式 preview 功能的源码,进行适当配置修改,inline 公式就能显示中文了。

inline formula preview 的调用 stack:

  1. org–latex-preview-region
  2. org-format-latex
    1. org–make-preview-overlay
  3. org-create-formula-image
    实现转 latex 为图片的核心功能。原理是把 latex region 的内容放在中间,同时穿靴戴帽组装成完整的 latex 文件,再通过(根据 org-preview-latex-default-process, org-preview-latex-process-alist 两个变量的定义来决定具体逻辑,默认是:) latex 转成 div,再通过 dvipng 转成 png,把 png 插入当前位置预览。
    穿靴戴帽,靴子很简单,帽子的来源:
(latex-header
         (or (plist-get processing-info :latex-header)
             (org-latex-make-preamble
              (org-export-get-environment (org-export-get-backend 'latex))
              org-format-latex-header
              'snippet)))

所以,要让 org-mode 中 inline latex 公式 preveiw 能显示中文,步骤:

  1. 操作变量 org-preview-latex-process-alist 值,增加自定义的内容 xelatex-chinese:
(add-to-list 'org-preview-latex-process-alist
        	     '(xelatex-chinese
        	       :programs ("xelatex" "convert")
        	       :description "XeLaTeX with Chinese support dvi > png"
        	       :message "you need to install the programs: xelatex and divpng."
        	       :image-input-type "pdf"
        	       :image-output-type "png"
        	       :image-size-adjust (1.7 . 1.6)
        	       :latex-header "\\documentclass[preview]{standalone}\n\\usepackage{xeCJK}\n\\setCJKmainfont{华文楷体}\n\\usepackage[usenames]{color}\n\\usepackage{amsmath}\n\\pagestyle{empty}" ;; pagestyle{empty} 是必须的
        	       :latex-compiler ("xelatex -interaction nonstopmode -output-directory %o %f")
        	       :image-converter ("convert -density 150 %f %O")))
  1. 操作变量 org-preview-latex-default-process,配置使用 xelatex-chinese 设定
        (setq org-preview-latex-default-process 'xelatex-chinese)

解决方案的扩展说明

  1. latex 不支持中文,如果要在公式中显示中文,必须使用 xelatex 引擎
  2. xelatex 引擎只能生成 pdf,不能(像 latex 一样)生产 dvi 文件
  3. 要选择合适的 documentclass,让 xelatex 生成的 pdf 只包含公式,而不是默认的(包含页眉、页脚、页边距等大量空白的完整)文档
  4. 要在公式中显示中文,必须 \usepackage{xeCJK} (用于中文支持)、 \usepackage{amsmath} 并且在公式中用 \text{} 来包裹汉字
  5. \documentclass{ctexart} 在这里不适用,会生成整页文档,而不是只包含公式部分的内容
  6. 在高分辨率设备上使用 convert,务必设置 density 参数为稍大数,否则图片很小,看不清楚
  7. 通过 convert 的 resize (而不是 density)来放大图片,没有效果
  8. 插入的 inline formula 图片可能过长,原因是 org-create-formula-image 函数中穿靴戴帽时进行了颜色设定,不明原因会导致图片过长,修改成:
(with-temp-file texfile
              (insert latex-header)
              (insert "\n\\begin{document}\n"
        	      string
        	      "\n\\end{document}\n"))
1 个赞

pdflatex 支持中文的。

xelatex 可以输出 xdv,扩展了 dvi, 不确定 dvipng 能处理 xdv 不。dvisvgm 明确支持 xdv: dvisvgm: Manual Page

不是一个 \usepackage{ctex} 就解决的问题吗?

好像还真不能解决。

你试试。

我用的 emacs 28.2,自带的 org.el 中定义变量 org-preview-latex-process-alist 的值是

((dvipng :programs
	 ("latex" "dvipng")
	 :description "dvi > png" :message "you need to install the programs: latex and dvipng." :image-input-type "dvi" :image-output-type "png" :image-size-adjust
	 (1.0 . 1.0)
	 :latex-compiler
	 ("latex -interaction nonstopmode -output-directory %o %f")
	 :image-converter
	 ("dvipng -D %D -T tight -bg Transparent -o %O %f"))
 (dvisvgm :programs
	  ("latex" "dvisvgm")
	  :description "dvi > svg" :message "you need to install the programs: latex and dvisvgm." :image-input-type "dvi" :image-output-type "svg" :image-size-adjust
	  (1.7 . 1.5)
	  :latex-compiler
	  ("latex -interaction nonstopmode -output-directory %o %f")
	  :image-converter
	  ("dvisvgm %f -n -b min -c %S -o %O"))
 (imagemagick :programs
	      ("latex" "convert")
	      :description "pdf > png" :message "you need to install the programs: latex and imagemagick." :image-input-type "pdf" :image-output-type "png" :image-size-adjust
	      (1.0 . 1.0)
	      :latex-compiler
	      ("pdflatex -interaction nonstopmode -output-directory %o %f")
	      :image-converter
	      ("convert -density %D -trim -antialias %f -quality 100 %O")))

其中 imagemagick 的方案使用了 pdflatex 作为 compiler。试了下,还是不支持显示 inline formula 里的中文。

我平时通过 ctex+xelatex 获取 tex 对中文的支持,对 pdflatex 不太了解,也许你是对的。

我不用试, 我一直这么用

这个具体加在哪里呢?

pdftex对中文的支持很别扭的.

@jkg 如果你同时使用Linux, ctex, 以及pdflatex, 记得设置fontset为windows, 且将对应宋黑仿楷字体文件复制到同目录下.

我经常用 #+latex_header: \usepackage{ctex}

#+latex_header: \usepackage{ctex} 我设置了,中文显示为空白

我的方法是在latex中添加如下符号 \text{中文}

ubuntu 22.04系统, emacs 28.1

配置了一下生成xdv转svg的方案,目前已经可以显示中文了:

配置:

(setq org-latex-packages-alist '(("" "mhchem" t)
				 ("" "ctex" t)))
(add-to-list 'org-preview-latex-process-alist
	     '(xelatex-ch
	       :programs ("xelatex" "dvisvgm")
	       :description "xdv > svg"
	       :message "You need to install xelatex & dvisvgm"
	       :image-input-type "xdv"
	       :image-output-type "svg"
	       :latex-compiler
	       ("xelatex -no-pdf -interaction nonstopmode -output-directory %o %f")
	       :image-converter
	       ("dvisvgm %f --no-fonts --exact-bbox --scale=%S --output=%O")))
(setq org-preview-latex-default-process 'xelatex-ch)
2 个赞