Org-mode 用 Typst 生成的 LaTeX 公式预览 SVG 很小

最近在尝试给 Org-mode 加一个用 Typst 做公式预览的功能,但是过程中遇到了一个问题,即生成的 SVG 显示出来的样子特别小: 图片

(上下为作为对比的普通文本大小)

emacs -Q 下也是如此。目前不太清楚这个问题要怎么排查解决,所以来请教坛友。

P.S. 关于这个使用 Typst 做公式预览的功能,思路上就是以 .typ 文件作为中间文件,用 Typst 生成 SVG。流程是先把 :latex-compiler 设为一个从 tex 生成 typ 文件的脚本,把 org-latex-preview 生成的 tex 文件预处理一下、去掉 hardcode 的 LaTeX headers,再加上 Typst 的 headers;然后用 Typst 从这个 .typ 文件生成 SVG。当然这么做有很多缺点,不过作为一个原型来说暂且可行。

实现如下:

(add-to-list 'org-preview-latex-process-alist
             '(typst :programs ("typst")
                     :description "Use Typst to generate svg"
                     :message "you need to install the programs: python and typst."
                     :image-input-type "typ"
                     :image-output-type "svg"
                     :image-size-adjust (1.0 . 1.0)
                     :post-clean
                     (".typ")
                     :latex-compiler
                     ("python ~/src/latex2typst.py %f %O")
                     :latex-header ""
                     :image-converter
                     ("typst compile %f %O")
                     ))

其中的 latex2typst.py 的内容如下:

import sys
import re

def extract_rgb_values(text):
    pattern = r'\\definecolor\{(fg|bg)\}\{rgb\}\{(.+?)\}'
    matches = re.findall(pattern, text)
    color_dict = {}
    for match in matches:
        color_name = match[0]
        color_values = match[1].split(',')
        color_values = [float(value) * 100 for value in color_values]
        color_dict[color_name] = color_values
    return (color_dict['fg'], color_dict['bg'])

if len(sys.argv) > 2:
    input_filename = sys.argv[1]
    output_filename = sys.argv[2]
else:
    print("Please specify input and ouput filenames")
    sys.exit(1)

with open(input_filename) as f:
    contents = f.read()

fg, bg = extract_rgb_values(contents)

index = contents.find('\\color{fg}')
formula = contents[index+len('\\color{fg}')+1:-19]
if formula.startswith('$$'):
    formula = formula[1:-1]

def typst_header(fg, bg):
    fg_str = ','.join([str(value) + "%" for value in fg])
    bg_str = ','.join([str(value) + "%" for value in bg])
    return f"""#set text(fill: rgb({fg_str}))
#set page(width: auto, height: auto, margin: 4pt, fill: rgb({bg_str}))
"""

if index != -1:
    with open(output_filename, 'w') as f:
        f.write(typst_header(fg, bg))
        f.write(formula)
4 个赞

调整 image-size-adjust 会有效果吗,或者考虑直接生成 png?