latex公式渲染有兩種類型,一種是HTML形式展現公式,另外一種是圖片形式展現公式。若是是HTML形式展現公式,渲染是在前端完成的,通常會比較緩慢。知乎採起的方式是以圖片形式展現公式。codecogs是一個latex公式渲染服務,它根據get請求返回一個svg圖片。例如:前端
https://www.zhihu.com/equation?tex=\frac{1}{3}
</a>本文介紹ubuntu下搭建相似codecogs的公式渲染服務。python
sudo apt-get install latex sudo apt-get install latex-cjk-chinese
#2、latex命令介紹 latex命令用於把tex文件轉換成pdf文件或者dvi文件。dvi是一種設備無關的可打印文件格式。 輸入dvi按兩次tab能夠找到dvisvgm,此命令將dvi文件轉爲svg。shell
#3、編寫服務程序 使用flask編寫服務,經過命令行的方式調用latex獲取svg。在返回時須要注意兩點:flask
"Access-Control-Allow-Origin": "*"
使用latex命令時須要注意:ubuntu
dvisvgm --no-fonts --no-styles
,把dvi轉爲svg時取消導出字體和格式,而只是簡單導出一張圖片,不然客戶端找不到這些字體和格式。latex --interaction=nonstopmode
,可以保證即使報錯也不會阻塞TODO:跨域
import os import signal import subprocess from flask import Flask, request, Response app = Flask(__name__) file_id = 0 latex_dir = os.path.join(os.path.expanduser("~"), "latex-server") if not os.path.exists(latex_dir): os.mkdir(latex_dir) def run_command(s, log_file): pro = subprocess.Popen(s, shell=True, preexec_fn=os.setsid) try: pro.wait(1) # 最多等待1秒鐘 except Exception as ex: print(ex) # pro.terminate() os.killpg(os.getpgid(pro.pid), signal.SIGTERM) # 殺死一個進程組 raise ex def gets(formula): global file_id file_id += 1 now = file_id tex_file, dvi_file, svg_file, log_file = [os.path.join(latex_dir, "{}.{}".format( now, file_type)) for file_type in "tex dvi svg log".split()] open(tex_file, mode='w').write(r""" \documentclass{minimal} \usepackage{amsmath} \begin{document} $$%s$$ \end{document} """ % formula) try: run_command("latex --interaction=nonstopmode --output-directory {} {}".format( latex_dir, tex_file), log_file) run_command( "dvisvgm --no-fonts --no-styles -c2,2 -o {} {}".format(svg_file, dvi_file), log_file) svg = open(svg_file).read() # 若是不存在,那就直接拋出異常吧 return svg except Exception as ex: raise ex finally: # 清理文件 for i in "tex dvi log aux svg".split(): filename = os.path.join(latex_dir, "{}.{}".format(now, i)) if os.path.exists(filename): os.remove(filename) @app.route("/render") def render(): formula = request.args['formula'] try: resp = gets(formula) return Response(response=resp, headers={ "Content-Type": "image/svg+xml" }) except Exception as ex: print(ex) return Response(status=500) if __name__ == '__main__': app.run(host='0.0.0.0', port=9988, debug=True)