【分享】在 org-mode 和 latex-mode 中美化公式预览

如何对齐 org-latex-preview 预览图的水平基准线?

按照当前思路用最简单的方式优化了基线校准, 最终效果如下:

与原本的效果对比:

旧:

新: Screenshot 2022-10-18 at 06.56.28

由于实现方式很简单, 只是单纯检查内容是否有上下标. 然后根据这些来单个调整图片位置.

所以目前还有许多不完善的地方, 希望能够慢慢修正.

代码如下:

(defun my/org-latex--get-tex-string ()
  "Return the content of the LaTeX fragment at point."
  (let ((datum (org-element-context)))
    (org-element-property :value datum)))

(defun my/latex-fragment-superscript-p ()
  "Return `t' if '^' in current LaTeX fragment."
  (memq 94 (string-to-list (my/org-latex--get-tex-string))))

(defun my/latex-fragment-subscript-p ()
  "Return `t' if '_' in current LaTeX fragment."
  (memq 95 (string-to-list (my/org-latex--get-tex-string))))

(defun my/latex-fragment-script-p ()
  "Return `t' if both '_' &  '^' in current LaTeX fragment."
  (and (memq 94 (string-to-list (my/org-latex--get-tex-string)))
       (memq 95 (string-to-list (my/org-latex--get-tex-string)))))

(defun org--make-preview-overlay (beg end image &optional imagetype)
  "Build an overlay between BEG and END using IMAGE file.
Argument IMAGETYPE is the extension of the displayed image,
as a string.  It defaults to \"png\"."
  (setq my/position 'center)
  (cond ((my/latex-fragment-script-p)
         (setq my/position 'center))
        ((my/latex-fragment-superscript-p)
         (setq my/position 100))
        ((my/latex-fragment-subscript-p)
         (setq my/position 70)))
  (let ((ov (make-overlay beg end))
	(imagetype (or (intern imagetype) 'png)))
    (overlay-put ov 'org-overlay-type 'org-latex-overlay)
    (overlay-put ov 'evaporate t)
    (overlay-put ov
		 'modification-hooks
		 (list (lambda (o _flag _beg _end &optional _l)
			 (delete-overlay o))))
    (overlay-put ov
		 'display
		 (list 'image :type imagetype :file image :ascent my/position))))

当然除此之外, 精准的基线校准方案依然是有的, 比如

(texfrag 我很难读懂它的代码, 没有明白它的实现方式.)

同时 dvisvgm 文档中所描述的解决方案: dvisvgm: Generating scalable vector graphics from DVI and EPS files, p363. 与 preview-latex 并调整 preview.el 的变量而可能实现的一种较为完美的解决方案. 但本人目前还没有找到具体实现方式.