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 hub.iflytek.com/ainote/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



拷贝出来放在浏览器就可以直接访问了,这个是a6纸张的渲染效果,可以根据图的大小动态的传入纸张规格



再来个大的

{"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(\n<[:150]%4\n-[:90.4,2.094]%115\n-[:18]%109\n-[:330]%110\n-[:30,,,,dlh]%111\n-[:90]%112\n-[:150,,,,dlh]%107\n-[:210]%108\n(\n-[:162]\\mcfabove{N}{H}%113\n-[:234]%114\n-[:306,,,,dbl={73}{73}]%->115\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(\n<:[:90]%9\n-[:30]%10\n(\n-[:330,,,1]NH_2%12\n)\n=[:90]O%11\n)\n-[:330]%8\n(\n=[:270]O%15\n)\n-[:30]\\mcfabove{N}{H}%13\n-[:330]%14\n(\n<:[:270]%16\n-[:330]%19\n(\n=[:270]O%21\n)\n-[:30,,,1]OH%20\n)\n-[:30]%17\n(\n=[:90]O%22\n)\n-[:330]\\mcfbelow{N}{H}%18\n-[:30]%23\n<:[:90]%24\n(\n=[:150]O%26\n)\n-[:30,,,1]NH%25\n-[:90,,1]%27\n-[:30]%28\n(\n=[:90]O%29\n)\n-[:330]\\mcfbelow{N}{H}%30\n-[:30]%31\n(\n-[:90]%33\n-[:30]%34\n-[:90]%35\n-[:30,,,1]NH_2%36\n)\n-[:330]%32\n(\n=[:270]O%37\n)\n-[:30]\\mcfabove{N}{H}%38\n-[:330]%39\n(\n<:[:270]%43\n-[:330]%44\n(\n-[:30,,,1]OH%46\n)\n=[:270]O%45\n)\n-[:30]%40\n(\n=[:90]O%42\n)\n-[:330]\\mcfbelow{N}{H}%41\n-[:30]%47\n(\n<:[:90]%49\n)\n-[:330]%48\n(\n=[:30]O%51\n)\n-[:270,,,2]HN%50\n-[:330,,2]%52\n(\n<[:30]%54\n-[:330]%55\n(\n-[:270,,,1]OH%57\n)\n=[:30]O%56\n)\n-[:270]%53\n(\n=[:330]O%58\n)\n-[:210,,,2]HN%59\n-[:270,,2]%60\n-[:210]%61\n(\n=[:270]O%62\n)\n-[:150]\\mcfabove{N}{H}%63\n-[:210]%64\n(\n<:[:270]%104\n-[:330,,,1]OH%105\n)\n-[:180,1.732]%91\n(\n-[:150,,,,dlhs]O%92\n)\n-[:270,,,1]NH%90\n-[:210,,1]%82\n(\n<[:270]%84\n(\n-[:330]%86\n-[:270]%87\n(\n-[:210,,,2]HO%89\n)\n=[:330]O%88\n)\n-[:210]%85\n)\n-[:150]%81\n(\n=[:90]O%83\n)\n-[:210]\\mcfbelow{N}{H}%71\n-[:150]%69\n(\n-[:90]%68\n(\n=[:30]O%70\n)\n-[:150]O%67\n-[:90]%65\n(\n<[:30]%66\n)\n-[:150]%->23\n)\n<[:210]%72\n-[:270]%73\n(\n=[:330]O%75\n)\n-[:210]%74\n-[:270,,,,drh]%80\n(\n-[:330,,,1]NH_2%106\n)\n-[:210]%79\n-[:150,,,,drh]%78\n-[:90]%77\n-[:30,,,,drh]%76\n(\n-[:330]%->74\n)\n}\n"}

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/index.html

用latex绘制有机化学分子式:http://static.latexstudio.net/wp-content/uploads/2016/09/chemfig.pdf

基于texlive定制chemfig化学式转换Python服务镜像的更多相关文章

  1. docker容器化python服务部署(supervisor-gunicorn-flask)

    docker容器化python服务部署(supervisor-gunicorn-flask) 本文系作者原创,转载请注明出处: https://www.cnblogs.com/further-furt ...

  2. SharePoint 2013 Word 转换PDF服务介绍及示例

    前言:在SharePoint使用过程中,经常会发现将文档进行格式转换的需求,之前,看到SharePoint 2013有将PPT转换PDF文档的服务,后来,才发现SharePoint 2010开始,就有 ...

  3. 翻译:打造基于Sublime Text 3的全能python开发环境

    原文地址:https://realpython.com/blog/python/setting-up-sublime-text-3-for-full-stack-python-development/ ...

  4. SharePoint Word 转换PDF服务介绍及示例

    前言:在SharePoint使用过程中,经常会发现将文档进行格式转换的需求,之前,看到SharePoint 2013有将PPT转换PDF文档的服务,后来,才发现SharePoint 2010开始,就有 ...

  5. twistd 启动Python服务

    twistd 启动Python服务 shell 脚本如下: #! /usr/bin/env sh MAIN_MODULE=pdf_task.py ROOT="/var/www/pdf/&qu ...

  6. 基于scrapy爬虫的天气数据采集(python)

    基于scrapy爬虫的天气数据采集(python) 一.实验介绍 1.1. 知识点 本节实验中将学习和实践以下知识点: Python基本语法 Scrapy框架 爬虫的概念 二.实验效果 三.项目实战 ...

  7. 基于Spring Cloud、JWT 的微服务权限系统设计

    基于Spring Cloud.JWT 的微服务权限系统设计 https://gitee.com/log4j/pig https://github.com/kioyong/spring-cloud-de ...

  8. 在C#/.NET应用程序开发中创建一个基于Topshelf的应用程序守护进程(服务)

    本文首发于:码友网--一个专注.NET/.NET Core开发的编程爱好者社区. 文章目录 C#/.NET基于Topshelf创建Windows服务的系列文章目录: C#/.NET基于Topshelf ...

  9. Cola Cloud 基于 Spring Boot, Spring Cloud 构建微服务架构企业级开发平台

    Cola Cloud 基于 Spring Boot, Spring Cloud 构建微服务架构企业级开发平台: https://gitee.com/leecho/cola-cloud

随机推荐

  1. Spring(一):Spring概述及相关概念

    Spring简介 Spring主要作用是用来解耦,降低代码之间的耦合度.根据功能的不同,可以将系统的代码分为主业务逻辑与系统服务逻辑. 主业务逻辑之间代码联系紧密,相互调用较多,复用性相对较低: 系统 ...

  2. LuckyStar hctf2018

    LuckyStar hctf2018 程序注册有TLS回调函数 char __stdcall TlsCallback_0(int a1, int a2, int a3) { char result; ...

  3. Windows + Jenkins + .NetFramework + SVN 持续部署

    Windows + Jenkins + .NetFramework + SVN 持续部署 环境准备 服务端环境 安装 Windows 服务器 1.阿里云购买临时服务器 阿里云:https://www. ...

  4. Python基础之:Python中的异常和错误

    目录 简介 Python中的内置异常类 语法错误 异常 异常处理 抛出异常 异常链 自定义异常 finally 简介 和其他的语言一样,Python中也有异常和错误.在 Python 中,所有异常都是 ...

  5. 在M1芯片的Mac系统上做.net core开发靠谱吗?

    作为一个7年老.NET程序员,最近几年苹果慢慢接替微软,成为我心中最酷的科技公司. 为什么我会选择Mac os作为我的开发环境? 很多做.net的同学都使用Windows系统作为自己的开发环境,我其实 ...

  6. [源码解析] 并行分布式框架 Celery 之 worker 启动 (2)

    [源码解析] 并行分布式框架 Celery 之 worker 启动 (2) 目录 [源码解析] 并行分布式框架 Celery 之 worker 启动 (2) 0x00 摘要 0x01 前文回顾 0x2 ...

  7. Windows安装完ADFS后卸载ADFS清除ADFS数据库

    ADFS卸载后不会卸载掉之前ADFS配置后留下来的数据库,所以如果有必要去删掉这个数据库的话需要找到对应的路径去将数据库删除掉. 具体路径为C:/windows/wid/data/adfsartifa ...

  8. 记一次metasploitable2内网渗透之2049端口NFS漏洞

    0x01.NFS简介 NFS是基于UDP/IP协议的应用,其实现主要是采用远程过程调用RPC机制,RPC提供了一组与机器.操作系统以及低层传送协议无关的存取远程文件的操作.RPC采用了XDR的支持.X ...

  9. 06_pytorch的autograd操作

    06_pytorch的autograd操作 目录 一.引言 二.Variable 2.1 Variable 的数据结构 2.2 反向传播 2.3 autograd 求导数和手动求导数 三.计算图 3. ...

  10. Jenkins 项目类型及配置项

    0. 简介 1. Freestyle project 1)General 2)源码管理 3)构建触发器 4)构建环境 5)构建 6)构建后操作 2. Maven 项目 1)所有配置项 2)Build ...