|
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
本贴使用cunsom_text_tag注册标签tex,实现在文本中插入公式,公式来自于latex语句。
可以查看附件图片来查看效果。
下文介绍代码。关于该代码的应用(即,为什么我要做这个功能),在代码之后。
版本:RenPy 8.5.2
代码:方便起见,建议单开一个latex.rpy。思路:通过python的subprocess包,调用其他程序,生成latex图片放入文件夹,再被游戏调用。
被调用的程序,以及更多详细内容,在下文注释里有,请参考。
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])
# 渲染公式 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
关于该代码的目的——如果我们需要在文本中灵活的插入数学公式,甚至公式数目很多时,开发者希望能够通过简单的文本标签命令,写入latex语句来返回公式图片。
比起一个一个公式图片制作,使用该方法可以更灵活的写代码以及改代码。
除了latex,也有markdown、typist等等其他的能够自由输入公式的语言。本教程提供了一个利用subprocess的处理方法,读者有兴趣可以用其他的程序。例如其实我朋友试过用mathjax来生成,而不是TyniTex来生成我的latex语句。思路是类似的。
另外,如上所述,写代码的过程中,可能会出现写错的公式等等,在调试过程中可能会出现额外的,废弃的图片。
读者可以根据上述代码写一个脚本,在开发阶段的末期,使用脚本删掉所有废弃的图片,以及生成一些前面改动过相信可以成功处理,但又懒得回前面去运行一边的图片。
|
-
文本标签可以使用在对话框里,也可以出现在可视组件里
|