1. 程式人生 > >手動搭建latex公式渲染伺服器

手動搭建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