converting a latex code to mathml or svg code in python
Asked Answered
B

5

5

Is there any python code that allow take a latex code (for equations) and parse it to mathml or svg code ? A simple function that take as argument a string (the latex code) and output a string (the svg or mathml code) would be perfect.

PS. I've found this http://svgkit.sourceforge.net/SVGLaTeX.html but it's a web based project and not sure how to use it.

EDIT: or in any language (not obligatory python), or at least an exe file that can be simply executed by a command line to do that (without installing additional stuff).

Babineaux answered 6/3, 2012 at 16:57 Comment(2)
When you say "without installing additional stuff"- do you already have LaTeX installed? (For example, could you run pdflatex on your command line?)Constantan
I don't have latex installed, I prefer a tool that can do it without needing a latex distribution installed (unless it's impossible).Babineaux
C
3

You can do this without installing anything:

import urllib
import urllib2

def latex2svg(latexcode):
    """
    Turn LaTeX string to an SVG formatted string using the online SVGKit
    found at: http://svgkit.sourceforge.net/tests/latex_tests.html
    """
    txdata = urllib.urlencode({"latex": latexcode})
    url = "http://svgkit.sourceforge.net/cgi-bin/latex2svg.py"
    req = urllib2.Request(url, txdata)
    return urllib2.urlopen(req).read()

print latex2svg("2+2=4")
print latex2svg("\\frac{1}{2\\pi}")

This script calls the SVGKit server you mention, which does the work of converting LaTeX to SVG. It returns the text of SVG (try it out).

Note that, as with any solution that relies on third-party web apps,

  1. This assumes you have a reliable internet connection

  2. Its performance depends on the speed of your connection and of the server

  3. This relies on the third-party site to stay consistent (if they take it down, or the format significantly changes, this will no longer work without adjustment)

Constantan answered 6/3, 2012 at 20:51 Comment(2)
Great temporary solution, of course it would be much better if we don't need an internet connection to do the conversion, but it's ok for now. Thanks.Babineaux
Great. Every solution, though, will involve either using an internet connection or installing LaTeX. After all, something needs to interpret the LaTeX code (it's not like you could encapsulate all of LaTeX into a few Python functions).Constantan
L
3

My solution is to use latex to generate a DVI file and then use dvisvgm to convert the dvi to svg:

  1. latex file.tex # produces file.dvi
  2. dvisvgm --no-fonts file.dvi file.svg # --no-fonts: use SVG paths only

In my experience, the final svg is rendered exactly as wanted (with InkScape, or QSvgRenderer).

The LaTeX template I use is this:

\documentclass[paper=a5,fontsize=12pt]{scrbook}
\usepackage[pdftex,active,tightpage]{preview}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{amsfonts}
\usepackage{tikz}
\begin{document}
\begin{preview}
\begin{tikzpicture}[inner sep=0pt, outer sep=0pt]
\node at (0, 0) {texCode}; % <--Put your tex-code here
\end{tikzpicture}
\end{preview}
\end{document}
Lallage answered 3/6, 2013 at 9:12 Comment(0)
R
3

I know of two solutions and both served me at some point and worked well for me. I provide them in the order of my personal preference.

Option 1 - latextools library

This is my preferred solution as it allows to combine SVG generated LaTeX with other SVG objects without messing them up.

import latextools
import drawSvg as draw  # pip3 install drawSvg

# Render latex
latex_eq = latextools.render_snippet(
    r'$\sqrt{X^\dag}$',
    commands=[latextools.cmd.all_math])
svg_eq = latex_eq.as_svg()

# Use the rendered latex in a vector drawing
d = draw.Drawing(100, 100, origin='center', displayInline=False)
d.append(draw.Circle(0, 0, 49, fill='yellow', stroke='black', stroke_width=2))
d.draw(svg_eq, x=0, y=0, center=True, scale=2.5)

d.saveSvg('vector.svg')
d.savePng('vector.png')

Creates output image from latextools

Option 2 - latex2svg library

Intended to be more of command line tool, not present on PyPi (you have to download the file) but totally works programmatically with minor modifications.

from latex2svg import latex2svg
out = latex2svg(r'\( e^{i \pi} + 1 = 0 \)')
print(out['depth'])  # baseline position in em
print(out['svg'])  # rendered SVG

Outputs output from latex2svg

Reject answered 17/6, 2020 at 4:15 Comment(0)
D
2

About SVGLaTeX:

I would say you can use it as a python script on your computer (non-webbased) [edit: not as it is], but it does not fulfill your requirement 'without installing additional stuff' since I think you'd need a latex distribution.

About MathML vs. SVG:

Converting Latex to mathml (I could find only webbased solutions) is different to converting LateX to SVG, in the sense that mathml is more like a description of the math source like LateX source, and SVG is a format to store the typeset equations, like PDF.

Producing SVG from LateX is a much more involved process than converting LaTeX to MathML, the former (to my knowledge) always ultimately using Knuts TeX program. So if you do not install any LateX [edit: or use it remotely] you'd have to convert to MathML. [Hopefully someone else knows a tool for it. I am not familiar with JavaScript. Can it be run from console?].

Edit:

Python script to make SVG from LateX (along the line of SVGLatex/eqtexsvg):

from subprocess import call
import sys, re

if not len(sys.argv) == 2:
    print "usage: tex2svg input_file.tex"
    exit(1)

tex_name = sys.argv[1]
svg_name = tex_name[:-4] + ".svg"
ps_name = tex_name[:-4] + ".ps"
dvi_name = tex_name[:-4] + ".dvi"

if call(["latex", tex_name]): exit(1)
if call(["dvips", "-q", "-f", "-e", "0", "-E", "-D", "10000", "-x", "1000", "-o", ps_name, dvi_name]): exit(1)
if call(["pstoedit", "-f", "plot-svg", "-dt", "-ssp", ps_name,  svg_name]): exit(1)
Denaturalize answered 6/3, 2012 at 18:11 Comment(5)
How to use it as a python script on my computer if I have a latex distribution installed ? (even if I prefer to not have latex installed).Babineaux
SVGLaTeX contains a python script, but unfortunately it seems not to exactly accept a latex file and save a svg file. So I stripped it down and appended some lines of python to my answer. Basically it calls latex, dvips and pstoedit. Could just use a shell script. You can save it and call it with one argument, your latex file. It will give you an svg-file with the same name as your latex file just .svg instead of .tex.Denaturalize
I get this error when I try to execute your code: C:\Users\TheUser\Desktop>tex2svg.py input.tex Traceback (most recent call last): File "C:\Users\TheUser\Desktop\tex2svg.py", line 13, in <module> if call(["latex", tex_name]): exit(1) File "C:\Python26\lib\subprocess.py", line 444, in call return Popen(*popenargs, **kwargs).wait() File "C:\Python26\lib\subprocess.py", line 595, in init errread, errwrite) File "C:\Python26\lib\subprocess.py", line 821, in _execute_child startupinfo) WindowsError: [Error 2] The specified file is not foundBabineaux
From your error I would say it either complaines that the file "input.tex" cannot be found or that the program "latex" cannot be found. I ran the script in linux, then it worked (with input.tex in my current directory and latex installed).Denaturalize
You could try replacing "latex" in the script by "C:\ ... \latex.exe" (replace the ... to where you have latex)Denaturalize
S
2

There is a VERY simple solution that only uses matplotlib.

import matplotlib.pyplot as plt
import matplotlib as mpl
mpl.rcParams.update({'text.usetex':True})

def latex2fig(latex, output_file, fontsize = 30):
    fig = plt.figure();
    fig.text(0,0,r'${}$'.format(latex), fontsize = fontsize);
    fig.savefig(output_file, bbox_inches = 'tight');

For example, we can run

latex2fig('e=mc^2','einstein.svg');

which will output the .svg image

e=mc^2 generated with latex2fig

To render LaTeX with matplotlib, follow the instructions in:

https://omz-software.com/pythonista/matplotlib/users/usetex.html

I got an error in Ubuntu, that was resolved by running:

 $ sudo apt-get install dvipng texlive-latex-extra texlive-fonts-recommended cm-super

Source: Python: Unable to Render Tex in Matplotlib

Seethe answered 22/2, 2023 at 13:5 Comment(1)
Underrated solution. I'd add transparent='true' to fig.savefig().Gyniatrics

© 2022 - 2024 — McMap. All rights reserved.