Sunday, April 20, 2008

pnglatex, a quick little script to make images from latex snippets

I wanted an easy way to make images from latex code so I whipped up this little python script to do that. The -n parameter sets the basename of the png files and the -d sets the latex snippet to be interpreted in display mode. There is a separate image created for each snippet.

eg
python pnglatex.py -n mathimage -d '\frac{2}{3}' '\frac{3}{4}'

Some code snagged from the movable type plug in. Relies on having latex, dvipng, and python.

#Permission is hereby granted, free of charge, to any person obtaining a copy
#of this software and associated documentation files (the "Software"), to
#deal in the Software without restriction, including without limitation the
#rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
#sell copies of the Software, and to permit persons to whom the Software is
#furnished to do so, subject to the following conditions:
#
#The above copyright notice and this permission notice shall be included in
#all copies or substantial portions of the Software.
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
#FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
#IN THE SOFTWARE.
#

import sys
import optparse, tempfile, os, re

tex_preamble = r'''
\documentclass{article}
\usepackage{amsmath}
\usepackage{amsthm}
\usepackage{amssymb}
\usepackage{bm}
\newcommand{\mx}[1]{\mathbf{\bm{#1}}} % Matrix command
\newcommand{\vc}[1]{\mathbf{\bm{#1}}} % Vector command
\newcommand{\T}{\text{T}} % Transpose
\pagestyle{empty}
\begin{document}
'''

tex_postamble = '\end{document}'

def main():
parser = optparse.OptionParser()
parser.add_option("-d", action="store_true", dest="displaymode", default=True)
parser.add_option("-n", action="store", type="string", dest="basename", default="latexImage")
(optlist, args) = parser.parse_args()
displayMode = optlist.displaymode
basename = optlist.basename
# create a LaTeX document and insert equations
fd, texfn = tempfile.mkstemp(suffix='.tex', prefix='eq')
f = os.fdopen(fd, 'w+')
f.write(tex_preamble)
for eq in args:
text = re.sub(r'\n{2,}', '\n', eq)
if displayMode:
f.write("\\[\n%s \n\\] \n \\newpage \n" % text)
else:
f.write("$%s$ \n \\newpage \n" % text)
f.write(tex_postamble)
f.close()

# compile LaTeX document. A DVI file is created
tex_base = os.path.basename(texfn.replace('.tex', ''))
tex_path = os.path.dirname(texfn)
cd = os.getcwd()
os.chdir(tex_path)
sts = os.system('latex %s >/dev/null 2>/dev/null' % texfn)
if sts != 0:
return
os.chdir(cd)

# Run dvipng on the generated DVI file. Use tight bounding box.
# Magnification is set to 1200
if len(args) > 1:
basename = basename + '%d'

cmd = "dvipng -T tight -x 1200 -z 9 -bg Transparent " \
+ "-o %s.png %s 2>/dev/null 1>/dev/null" % (basename, tex_path + '/' + tex_base)
sts = os.system(cmd)

os.remove(os.path.join(tex_path, tex_base+'.log'))
os.remove(os.path.join(tex_path, tex_base+'.aux'))
os.remove(os.path.join(tex_path, tex_base+'.dvi'))

if __name__ == "__main__":
main()

No comments: