手動搭建latex公式渲染伺服器
codecogs是一個latex公式渲染服務,它根據get請求返回一個svg圖片。例如:codecogs,這個服務的缺點是比較慢。
本文介紹ubuntu下搭建類似codecogs的公式渲染服務。
一、安裝latex
sudo apt-get install latex
sudo apt-get install latex-cjk-chinese
二、latex命令介紹
latex命令用於把tex檔案轉換成pdf檔案或者dvi檔案。dvi是一種裝置無關的可列印檔案格式。
輸入dvi按兩次tab可以找到dvisvgm,此命令將dvi檔案轉為svg。
三、編寫服務程式
使用flask編寫服務,通過命令列的方式呼叫latex獲取svg。在返回時需要注意兩點:
- 設定好content-type,否則客戶端不知道你返回的是什麼格式的圖片
- 跨域訪問並不需要設定,因為載入的是靜態資源
使用latex命令時需要注意:
- documentclass必須是minimal,這樣能夠保證生成的檔案儘量小。
dvisvgm --no-fonts --no-styles
,把dvi轉為svg時取消匯出字型和格式,而只是簡單匯出一張圖片,否則客戶端找不到這些字型和格式。
TODO:
- 新增快取功能:可能沒有必要
- 新增統計功能:統計不同網站的請求次數
import os 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 gets(formula): global file_id file_id += 1 tex_file, dvi_file, svg_file = [os.path.join(latex_dir, "{}.{}".format(file_id, file_type)) for file_type in "tex dvi svg".split()] open(tex_file.format(file_id), mode='w').write(r""" \documentclass{minimal} \begin{document} $%s$ \end{document} """ % formula) os.system("latex --output-directory {} {}".format(latex_dir, tex_file)) """ no-fonts no-styles不帶字型,c2,2表示橫豎都縮放兩倍 """ os.system("dvisvgm --no-fonts --no-styles -c2,2 -o {} {}".format(svg_file, dvi_file)) svg = open(svg_file).read() for i in "tex dvi log aux svg".split(): filename = os.path.join(latex_dir, "{}.{}".format(file_id, i)) if os.path.exists(filename): os.remove(filename) return svg @app.route("/render") def render(): formula = request.args['formula'] print(formula) resp = gets(formula) return Response(response=resp, headers={ "Access-Control-Allow-Origin": "*", "Content-Type": "image/svg+xml" }) if __name__ == '__main__': app.run(host='0.0.0.0', port=9988, debug=True)
四、LaTex 的 web 替代品及其存在問題
基於 HTML(svg)+CSS LaTex 渲染只實現了 Latex 非常少的一部分功能——公式渲染。
MathJax
MathJax 出現於 2011 年,發展至今已經有 6、7 個年頭了。其特點是對數學公式的渲染支援度很高。對開發者來講,其缺點是 js API 有點奇怪,渲染比較慢,好在支援伺服器端渲染。MathJax 首先有個配置檔案:
MathJax.Hub.Config({ extensions: ["tex2jax.js"], jax: ["input/TeX", "output/SVG"], tex2jax: { inlineMath: [ ['$', '$'], ["\\(", "\\)"], ], displayMath: [ ['$$', '$$'], ["\\[", "\\]"] ], processEscapes: true }, "SVG": { availableFonts: ["TeX"] } });
然後將呼叫渲染API,轉為美觀的LaTex效果,如下。由於渲染很慢,所以渲染過程是一個非同步執行的佇列。
MathJax.Hub.Queue(['Typeset', MathJax.Hub]);
KaTex
相對於 MathJax, KaTex 是後起之秀,是可汗學院的公式渲染方案。API 設計,對前端工程師更加友好。KaTex 的特點是渲染很快,KaTex 的 API 是一個同步呼叫。
katex.render("c = \\pm\\sqrt{a^2 + b^2}", element);
KaTex 由於發展比較晚,大約 2013 年,對 LaTex 語法的支援程度可能不如 MathJax,比如不支援中文。
KaTex 也支援伺服器端渲染。
var html = katex.renderToString("c = \\pm\\sqrt{a^2 + b^2}");
//=> <span class="katex">...</span>
MathQuill
跟 MathJax、KaTex 不同,MathQuill 是一個真正意義上的公式編輯器,一邊輸入一邊渲染,輸出可以是 Tex,但是對於複雜的公式,這種輸入方式還是有很大的侷限性,輸入過程還是需要記住一些 LaTex 命令。
使用 MathJax、KaTex方案的共同問題是用HTML、CSS來渲染公式,非常冗長,如果採用了伺服器端渲染,很容易超出資料庫欄位的長度限制,一個簡單的公式,就會產生很多 HTML 結構。
參考資料
https://cloud.tencent.com/developer/article/1015883