latex公式渲染有两种类型,一种是HTML形式展示公式,另一种是图片形式展示公式。如果是HTML形式展示公式,渲染是在前端完成的,一般会比较缓慢。知乎采取的方式是以图片形式展示公式。codecogs是一个latex公式渲染服务,它根据get请求返回一个svg图片。例如:

本文介绍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,否则客户端不知道你返回的是什么格式的图片
  • 跨域访问并不需要设置,因为加载的是静态资源。跨域访问只需要在header中设置: "Access-Control-Allow-Origin": "*"

使用latex命令时需要注意:

  • documentclass必须是minimal,这样能够保证生成的文件尽量小。
  • dvisvgm --no-fonts --no-styles,把dvi转为svg时取消导出字体和格式,而只是简单导出一张图片,否则客户端找不到这些字体和格式。
  • 使用latex --interaction=nonstopmode,能够保证即便报错也不会阻塞
  • 要引入amsmath,否则许多宏会找不到
  • 为了防止用户上传不合法公式造成超时的现象,需要使用subprocess模块,它是非阻塞的,父进程可以对子进程的运行时间进行监听。

TODO:

  • 添加缓存功能:对某个公式的请求可能很多,每次不需要调用latex重新生产,直接使用缓存结果。这个优化可能没有必要,因为当查询分布特别分散时,这个优化费力不讨好。
  • 添加统计功能:统计不同网站的请求次数,用来查看都有哪些人使用了本服务。其实调用别人服务是一件很危险的事情。调用别人的服务就是信任别人的服务,把别人的服务当做自己的一部分。当别人变得不可信任时,自己也就危险了。比如latex公式服务把返回的svg图片统一替换成某个不合法的图片。
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)

参考资料

https://cloud.tencent.com/developer/article/1015883

手动搭建latex公式渲染服务器的更多相关文章

  1. 手动搭建自己的nuget服务器及使用

    这篇文章的主要目的: 1.搭建自己的私有的nuget服务器 2.打包代码为nuget包 3.在其他项目中使用私有服务器上的nuget包 一. 搭建自己的nuget服务器 1. 创建一个空的ASP.NE ...

  2. 手动搭建apache james邮件服务器,实现邮件功能

    最近一直在搞邮件这块,本来我们邮件发送是用的腾讯免费的企业邮箱,邮件功能没有问题,但是由于邮件的限制,如下: 这些限制导致我们的部分客户是收不到邮件的,哪怕付费,这样的固定频率限制也是无法解决的,可以 ...

  3. 使用spire.doc导出支持编辑Latex公式的标准格式word

    背景 之前有的教辅标注需求,在导出题库的时候希望顺便导出可以查看word,方便线下预览成品效果,因为只是用来预览并且为了沿用前端的样式,当时方案就是直接生成html,写个word的文件头,这样就可以用 ...

  4. Org mode无法生成LaTeX公式预览图片

    最近需要在Cygwin平台下的Emacs Org mode中生成LaTeX数学公式的预览图片,从而得到图文并貌的笔记与任务管理文档.但当我执行org-toggle-latex-fragment命令后却 ...

  5. Latex 公式速查

    本文记录了一些常用的数学公式对应的 Latex 字符,用于快速查找需要的字符 所有的在 Latex 使用的字符公式,都需要放在\(和\),$ 和 $,\begin{math} 和\end{math}之 ...

  6. vue新手入门之使用vue框架搭建用户登录注册案例,手动搭建webpack+Vue项目(附源码,图文详解,亲测有效)

    前言 本篇随笔主要写了手动搭建一个webpack+Vue项目,掌握相关loader的安装与使用,包括css-loader.style-loader.vue-loader.url-loader.sass ...

  7. [翻译]用 Puppet 搭建易管理的服务器基础架构(3)

    我通过伯乐在线翻译了一个Puppet简明教程,一共分为四部分,这是第三部分. 本文由 伯乐在线 - Wing 翻译,黄利民 校稿.未经许可,禁止转载!英文出处:Manuel Kiessling.欢迎加 ...

  8. 搭建一个Flv视频播放服务器

    搭建一个Flv视频播放服务器 热度 15已有 11511 次阅读2009-11-2 22:27 |关键词:服务器 视频 flv 播放 文档 错漏 经过一天的努力,查了好多资料,终于搞定了Flv视频服务 ...

  9. 搭建Ubuntu12.04交叉编译服务器

    最近在公司学着搭建一台Linux服务器作为交叉编译的主机之用,服务器端选择了Ubuntu12.04 LTS桌面版,客户端采用Windows XP平台,使用SSH工具软件putty登录到Linux主机, ...

随机推荐

  1. Intent 常用场景 FileProvider 拍照 裁剪 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  2. 学 Win32 汇编[34] - 宏汇编(1)

    从接触 C 语言时, 我就不大喜欢宏; 但为了看懂别人的代码也不得不去了解. 宏可定义在源程序的任意位置, 但一般放在 .data 前面.有些简单的宏可以用 equ.textequ 或 = 来代替, ...

  3. Android传感器应用——重力传感器实现滚动的弹球

    一. 问题描述 Android中有多达11种传感器,不同的手机设备支持的传感器类型也不尽相同 1. 重力传感器 GV-sensor 2. 加速度传感器 G-sensor 3.  磁力传感器  M-se ...

  4. Pearson(皮尔逊)相关系数

    Pearson(皮尔逊)相关系数:也叫pearson积差相关系数.衡量两个连续变量之间的线性相关程度. 当两个变量都是正态连续变量,而且两者之间呈线性关系时,表现这两个变量之间相关程度用积差相关系数, ...

  5. async和await的返回值——NodeJS, get return value from async await

    在ES6和ES5中promise的执行也有不同点(上述提到,ES6中promise属microtask:在ES5中,暂未接触到有api直接操作microtask的,所以.then的异步是用setTim ...

  6. 【Python】由host得到IP

    代码: import socket host='www.163.com' ip=socket.gethostbyname(host) print('Ip of {} is {}'.format(hos ...

  7. log4j.xml写入数据库,只有SQL和参数,无其他信息

    <?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE log4j:configuration SY ...

  8. Linux网络编程:基于UDP的程序开发回顾篇

    基于无连接的UDP程序设计 同样,在开发基于UDP的应用程序时,其主要流程如下:   对于面向无连接的UDP应用程序在开发过程中服务端和客户端的操作流程基本差不多.对比面向连接的TCP程序,服务端少了 ...

  9. zeroclipboard实现多浏览器复制到粘贴板功能

    zeroclipboard实现多浏览器复制到粘贴板功能(单个复制按钮和多个复制按钮) 为了更好的用户体验,现在很多网站中文本框的内容只需要点击复制按钮这样就能把内容复制到粘贴板了:出于兼容性的考虑,基 ...

  10. 【转】一些linux基础命令

    学习Linux,其实很多基础命令很重要. 不论多么复杂的shell或者命令组合,都是一个一个的拼接组合命令拼接而成: 大号一个基本功,遇到需要的场景,信手拈来,随意组合拼接,是非常重要的. 恰好看到一 ...