基于texlive定制chemfig化学式转换Python服务镜像

chemfig

据别人介绍,在绘制平面分子式,乃至化学反应式、机理图时,大家使用的基本都是ChemDraw。当然ChemDraw是一款强大的软件,无论是平面的还是立体的分子结构式都能毫不费力地绘制出来。当然这份强大是要钱的,对于平面的分子式或反应式,不要钱而且还可行的方案大致也就LaTeX语言中的Chemfig宏包。
Chemfig是法国学者开发的宏包,εTeX,pdfLaTeX等TeX编译器都能正常使用,并且相对来说开发是比较活跃的。

texlive

TeX Live 是 TUG (TeX User Group) 发布并维护的的 TeX 系统,可以称得上是TeX的官方系统。对于任何阶段的TeX用户,都可以使用TeX Live, 以保持在跨操作系统、跨用户的TeX文件一致性。

texlive Docker镜像及服务化改造

texlive的安装B站有很多教程,目标是需要提供绘制chemfig化学方程式转换的服务,而texlive软件本身并不提供相关的api服务,需要对其进行服务化改造,因为考虑容器化部署,需要将texlive封装成docker镜像

话不多说,我们选择的基础镜像是 texlive:2020 ,使用Python对外提供服务,关于texlive相关的介绍可以参考博客:chemfig化学式转换为pdf

拉取镜像并运行

docker pull texlive:2020

docker run --name texlive -d texlive:2020

docker ps -a | grep  live
dda1561ae866  texlive:2020   "tail -f /dev/null" 8 seconds ago  Up 2  texlive

docker exec -it dda1561ae866 bash

安装python,制作texlive-python镜像

texlive是基于Alpine Linux,目前主流
cat /etc/issue
Welcome to Alpine Linux 3.12

修改apk镜像源
vi etc/apk/repositories

替换文件内容为阿里源:
http://mirrors.aliyun.com/alpine/v3.8/main/
http://mirrors.aliyun.com/alpine/v3.8/community/

更新软件库
apk update
fetch http://mirrors.aliyun.com/alpine/v3.8/main/x86_64/APKINDEX.tar.gz
fetch http://mirrors.aliyun.com/alpine/v3.8/community/x86_64/APKINDEX.tar.gz
v3.8.5-67-gf94de196ca [http://mirrors.aliyun.com/alpine/v3.8/main/]
v3.8.5-66-gccbd6a8ae7 [http://mirrors.aliyun.com/alpine/v3.8/community/]
OK: 9578 distinct packages available

安装python3
apk add --no-cache python3 python3-dev py-pip

验证安装
python3 -V
Python 3.6.9
bash-4.4# pip3 -V
pip 18.1 from /usr/lib/python3.6/site-packages/pip (python 3.6)

保存镜像

docker commit dda1561ae866 textlive-python

至此,我们的拥有python环境texlive镜像就已经制作好了

服务化改造

python脚本

from flask import Flask, abort, request, jsonify
import os
import subprocess
import uuid
import base64

app = Flask(__name__)

@app.route('/texlive/translate/', methods=['POST'])
def translate():
    if not request.json or 'chemfig' not in request.json:
        abort(400)
    chem_fig = request.json['chemfig']
    # 由于不好测算化学方程式图形的大小,这里支持配置纸张大小,我们这里默认a5paper
    if 'paper' in request.json:
        paper = request.json['paper']
    else:
        paper = 'a5paper'
    tempFile = open("template.tex")
    lines = tempFile.readlines()
    lines[2] = lines[2].replace("a5paper", paper)
    lines[15] = chem_fig + "\n"
    uuidStr = str(uuid.uuid1())
    new_file_name = uuidStr + '.tex'
    newFile = open(new_file_name, "a+")
    for line in lines:
        newFile.write(line)
    newFile.flush()
    newFile.close()
    try:
        # 这里使用subprocess比较稳定,os.system经常会出现莫名问题,至少这个pdflatex命令用os.system会报错
        subprocess.run(["pdflatex", "-interaction=nonstopmode", new_file_name])
        pdf_string = open(uuidStr + '.pdf', "rb").read()
        encoded = base64.b64encode(pdf_string)
        pdf_link = "data:application/pdf;base64,{}".format(encoded)
        pdf_link = pdf_link.replace("b'", "").replace("'", "")
    except:
        remove_file(uuidStr)
    else:
        remove_file(uuidStr)

    return jsonify({"image": pdf_link})

def remove_file(uuid_str):
    os.system('rm ' + uuid_str + '.tex')
    os.system('rm ' + uuid_str + '.log')
    os.system('rm ' + uuid_str + '.pdf')
    os.system('rm ' + uuid_str + '.aux')

if __name__ == '__main__':
    app.run(host="0.0.0.0", port=8080, debug=False)

Latex模板

template.tex

\documentclass{minimal}
\usepackage{xcolor, mol2chemfig}
\usepackage[a5paper, margin=10px, total={6in, 8in}]{geometry}

\usepackage[helvet]{sfmath}
\setcrambond{2.5pt}{0.4pt}{1.0pt}
\setbondoffset{1pt}
\setdoublesep{2pt}
\setatomsep{%(atomsep)spt}
\renewcommand{\printatom}[1]{\fontsize{8pt}{10pt}\selectfont{\ensuremath{\mathsf{#1}}}}

\setlength{\parindent}{0pt}
\setlength{\fboxsep}{0pt}
\begin{document}

\chemfig{H_3C-[:30]N**6(-(=O)-(**5(-N(-CH_3)--N-))--N(-CH_3)-(=O)-)}

\end{document}

mol2chemfig.sty

requirements.txt

Flask

startup.sh

python3 ./main.py

DockerFile

FROM texlive-python:2020
COPY main.py /home
COPY mol2chemfig.sty /home
COPY template.tex /home
COPY requirements.txt /home
COPY startup.sh /home
WORKDIR /home
EXPOSE 8080
RUN pip3 install -r requirements.txt && ls
CMD ["bash", "startup.sh"]

服务镜像制作

构建 texlive-python-api

dockerfile构建
docker build -t texlive-python-api .
打tag
docker tag texlive-python-api xxx.xxx.com/xxx/texlive-python-api:2020
推送远程镜像仓库
docker push xxx.xxx.com/xxx/texlive-python-api:2020

跑一个试试

docker run -p 8080:8080 -d --name texlive-python-api texlive-python-api

请求body

{"paper":"a6paper",
"chemfig":"\\chemfig{CH_3-[:108,,1]N-[:54](-[:180,0.85,,,draw=none]\\mcfcringle{1.03})%\n-[:126]N-[:198]-[:270](-[:342]\\phantom{N})-[:210](=[:270]O)-[:150]N(%\n-[:210,,,2]H_3C)-[:90](=[:150]O)-[:30]N(-[:330])-[:90,,,1]CH_3}\n\n\\bigskip\n\n\\chemfig{CH_3-[:108,,1]N-[:54](-[:180,0.85,,,draw=none]\\mcfcringle{1.03})%\n-[:126]N-[:198]-[:270](-[:342]\\phantom{N})-[:210](=[:270]O)-[:150]N(%\n-[:210,,,2]H_3C)-[:90](=[:150]O)-[:30]N(-[:330])-[:90,,,1]CH_3}"}

postman

基于texlive定制chemfig化学式转换Python服务镜像
拷贝出来放在浏览器就可以直接访问了,这个是a6纸张的渲染效果,可以根据图的大小动态的传入纸张规格
基于texlive定制chemfig化学式转换Python服务镜像
再来个大的
{"paper":"a3paper",
"chemfig":"\\chemfig{CH_3-[:108,,1]N-[:54](-[:180,0.85,,,draw=none]\\mcfcringle{1.03})%\n-[:126]N-[:198]-[:270](-[:342]\\phantom{N})-[:210](=[:270]O)-[:150]N(%\n-[:210,,,2]H_3C)-[:90](=[:150]O)-[:30]N(-[:330])-[:90,,,1]CH_3}\n\n\\bigskip\n\n\\chemfig{\nO%5\n=[:270]%3\n(\n-[:210]%2\n(\n115\n)\n-[:270,,,,dlh]%->109\n)\n-[:270,,,2]HN%1\n-[:330,,2]%93\n(\n-[:270]%95\n-[:210]%96\n-[:270]%97\n-[:330]%98\n-[:30]%99\n-[:330]%100\n-[:270]%101\n-[:210]%102\n-[:270]%103\n)\n=[:30]O%94\n)\n-[:330]\\mcfbelow{N}{H}%6\n-[:30]%7\n(\n23\n)\n74\n)\n}\n"}

基于texlive定制chemfig化学式转换Python服务镜像

PS:LaTeX是一种基于ΤΕΧ的排版系统,不光是化学方程式,其他latex语法都可以通过本镜像渲染,template.tex是模板文件,对latex排版有要求的可以自行定制

参考链接

chemfig化学式转换为pdf:https://www.cnblogs.com/xiaoqi/p/chemfig.html
mol2chemfig:http://chimpsky.uwaterloo.ca/mol2chemfig/index
Chemfig中文手册:https://chemfig.man.huzheyang.cn
用latex绘制有机化学分子式:http://static.latexstudio.net/wp-content/uploads/2016/09/chemfig.pdf

Original: https://www.cnblogs.com/surging-dandelion/p/14758184.html
Author: 蒲公英的狂想
Title: 基于texlive定制chemfig化学式转换Python服务镜像

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/579596/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • ReentrantLock的原理解析

    重入锁(ReentrantLock)是一种可重入无阻塞的同步机制。性能同synchronized接近(老版本jdk中性能很差)。 下面重点看下常用的lock()和unlock()方…

    Java 2023年6月6日
    072
  • Shiro中Subject对象的创建与绑定流程分析

    我们在平常使用Shrio进行身份认证时,经常通过获取Subject 对象中保存的Session、Principal等信息,来获取认证用户的信息,也就是说Shiro会把认证后的用户信…

    Java 2023年6月9日
    077
  • 59.你要的全拿走

    dsfsd posted @2022-09-28 08:33 随遇而安== 阅读(5 ) 评论() 编辑 Original: https://www.cnblogs.com/55z…

    Java 2023年6月7日
    076
  • 数据结构与算法之递归

    用循环实现阶乘 阶乘的规则就是输入数字n计算乘积.例如n为3计算结果为123。此算法的时间复杂度为O(n) public static long f1(long n) { long…

    Java 2023年6月8日
    078
  • 15分钟学会JWT使用

    什么是JWT? JSON Web Token ,通过数字签名的方式,以JSON对象为载体,在不同的服务终端之间安全的传输信息。 jwt 可以生成 一个加密的token,做为用户登录…

    Java 2023年6月9日
    066
  • OpenStack 安装 Keystone

    OpenStack 安装 Keystone 本篇主要记录一下 如何安装 openstack的 第一个组件 keystone 认证授权组件 openstack 版本 我选的是quee…

    Java 2023年6月9日
    093
  • Day16自定义异常

    package com.exception.demo02;//自定义的异常类public class MyException extends Exception{ //传递数字&g…

    Java 2023年6月5日
    076
  • 解决vue使用el-dialog中组件只有第一次执行avue-crud初始话查询方法的问题

    解决方式: 在el-dialog标签中加入v-if=’dialogVisible’,dialogVisible是控制打开el-dialog弹窗的标志 dia…

    Java 2023年6月16日
    070
  • 解读ASP.NET 5 & MVC6系列(8):Session与Caching

    在之前的版本中,Session存在于System.Web中,新版ASP.NET 5中由于不在依赖于System.Web.dll库了,所以相应的,Session也就成了ASP.NET…

    Java 2023年5月30日
    064
  • Android开发Android Gradle plugin requires Java 11 to run. You are currently using Java 1.8.错误的解决方法

    Android开发Android Gradle plugin requires Java 11 to run. You are currently using Java 1.8.错…

    Java 2023年5月29日
    0100
  • 数据校验

    数据校验 element前端自定义校验规则 :rules=”dataRule” 绑定数据校验规则方法 * firstLetter: [ { validato…

    Java 2023年6月9日
    085
  • Spring Boot启动流程源码解析

    定义: BeanFactoryPostProcessor:是一个接口,它允许自定义修改应用程序上下文的beanDefiinition BeanDefinitionRegistryP…

    Java 2023年6月14日
    051
  • 二进制妙用之位标记

    二进制妙用之位标记 1. 使用背景 已知一个字符串 String s = “abcdefg”,需要判断字符串中是否存在重复的字符。 2. 常规实现 根据Hashset特性判断重复。…

    Java 2023年6月13日
    072
  • spring测试

    今天在用spring做集成测试的时候,代码如下 @Test @DatabaseSetup({"userData.xml", "emptyUserMai…

    Java 2023年6月7日
    062
  • RabitMQ 简介

    The secret of being miserable is to have leisure to bother about whether you are happy or …

    Java 2023年6月9日
    054
  • Spring框架的XML扩展特性

    Spring框架从2.0版本开始,提供了基于Schema风格的XML扩展机制,允许开发者扩展spring配置文件。现在我们来看下怎么实现这个功能,可以参考spring帮助文档中的《…

    Java 2023年5月30日
    062
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球