[RenPy] 纯文本查看 复制代码
[/backcolor]
[backcolor=white]init python:
import os
import subprocess
import hashlib
# 以下是相关文件地址,请读者根据自己的情况调整
# TinyTeX 根目录(相对 game 目录)
LATEX_ROOT = os.path.join(renpy.config.gamedir, "TinyTeX")
# 公式缓存目录
CACHE_DIR = os.path.join(renpy.config.gamedir, "cache", "latex_formulas")
# 公式渲染默认参数
LATEX_BIN = os.path.join(LATEX_ROOT, "bin", "windows", "latex.exe")
# 生成png的路径
# DVIPNG_BIN = os.path.join(LATEX_ROOT, "bin", "windows", "dvipng.exe")
# 生成svg的路径。
DVISVGM_BIN = os.path.join(LATEX_ROOT, "bin", "windows", "dvisvgm.exe")
# 我最终转向了svg,只是保留了png的代码。下面的被注释代码也是同理
# 分别是默认字号和作为对比的标准字号
# 我们通过一个比例来缩放图片,所以这里的字号并不直接对应字体大小
default_fontsize = 7
usual_fontsize = 10
# 根据公式的latex代码用hash生成固定长度的合法文件名
def latex_formula_path(code):
hash_key = hashlib.md5(f"{code}".encode("utf-8")).hexdigest()
# output_pic = os.path.join(CACHE_DIR, f"formula_{hash_key}.png")
output_pic = os.path.join(CACHE_DIR, f"formula_{hash_key}.svg")
print(code)
return hash_key, output_pic
# 根据源码生成图片文件
def latex_formula_pic(code):
hash_key, output_pic = latex_formula_path(code)
if os.path.exists(output_pic):
return output_pic
# LaTeX 源码模板(无需用户加 $ 符号)
# 正式版会注释掉这段代码,并移除掉约300M的TyniTex-1 on Windows in 2026,彼时on_testing被设置为False
# https://github.com/rstudio/tinytex-releases
# 如果缓存图片丢失,可能需要用户下载这个,然后解除下面的注释(将gallery_files.rpy中的on_testing设置为True)
# 在TinyTeX\bin\windows下使用cmd命令
# tlmgr install amsmath amssymb graphics
# 来安装基础包
if on_testing:
tex_template = r"""
\documentclass{{article}}
\usepackage{{amsmath,amssymb,color}}
\pagestyle{{empty}}
\everymath{{\displaystyle}}
\begin{{document}}
${code}$
\end{{document}}
""".format(code=code)
temp_tex = os.path.join(CACHE_DIR, f"temp_{hash_key}.tex")
temp_dvi = os.path.join(CACHE_DIR, f"temp_{hash_key}.dvi")
with open(temp_tex, "w", encoding="utf-8") as f:
f.write(tex_template)
try:
# 编译为 DVI
subprocess.run(
[LATEX_BIN, "-interaction=nonstopmode", "-output-directory", CACHE_DIR, temp_tex],
check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
)
# 透明PNG
# subprocess.run(
# [
# DVIPNG_BIN,
# "-D", "300",
# "-bg", "Transparent",
# "-T", "tight",
# "-o", output_pic, temp_dvi
# ], check=True, capture_output=True
# )
# 透明SVG
subprocess.run(
[
DVISVGM_BIN,
"-b", "min", # 最小边框
"-Z", "3.0", # 缩放
"-o", output_pic,
"--no-fonts=1",
temp_dvi
], check=True, capture_output=True
)
except subprocess.CalledProcessError:
return None
finally:
# 清理临时文件
for ext in [
".tex",
".dvi",
".aux",
".log"
]:
f = temp_tex.replace(".tex", ext)
if os.path.exists(f):
os.remove(f)
return output_pic
# custom_text_tag函数定义
def tex_tag(tag, argument, contents):
if len(contents)==0:
return ""
img_path = latex_formula_pic(contents[0][1])
# 渲染公式 [/backcolor]
[backcolor=white] if not img_path:
print("Not img_path")
return [(renpy.TEXT_TEXT, "渲染失败")]
# 计算图片缩放比例
# svg作为存储笔画而非像素点的图片文件,不仅体积通常更小,且更扛缩放
if argument:
scale = float(argument) / usual_fontsize
else:
scale = default_fontsize / usual_fontsize
# 缩放图片并竖直平移
# RenPy的文本标签返回的可视化组件,默认是左上角对齐文本,这导致图片更大时,文字与图片看着不协调
path = img_path.replace("\\", "/")
img = Transform(
path,
# 缩放尺寸
zoom=scale,
# 竖直平移
# 具体的计算,和文字的大小,以及窗口的尺寸,可能都有关。读者请根据自己的情况调整。
yoffset = (gui.text_size - im.Image(path).load().get_height()*scale)/2 + 5
)
return [(renpy.TEXT_DISPLAYABLE, img)]
# 注册文本标签
config.custom_text_tags["tex"] = tex_tag[/backcolor]
[backcolor=white]