#!/usr/bin/env python """ tex2png -- quick latex expression to png conversion tool Copyright 2008 Ask Hjorth Larsen This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . """ import sys import os from subprocess import Popen, PIPE from StringIO import StringIO from optparse import OptionParser usage = '%prog [options] files' version = '%prog 0.1' parser = OptionParser(usage=usage, version=version) parser.add_option('-r', '--resolution', type='int', metavar='num', default=256, help='output resolution [default: %default]') parser.add_option('-p', '--preamble', metavar='file', help='include specified file as preamble') parser.add_option('-v', '--view', action='store_true', help='view image file after generation') parser.add_option('-T', '--text', action='store_true', help='assume text mode input') parser.add_option('-N', '--no-clean', action='store_true', help='do not clean up aux/log/dvi files') opts, args = parser.parse_args() dvifilename = 'texput.dvi' logfilename = 'texput.log' auxfilename = 'texput.aux' viewcommand = 'qiv' def tex2png(formula, pngfilename): if not formula: return codebuffer = StringIO() def T(text): codebuffer.write(text) def Tn(text): T(text + '\n') Tn('\\documentclass{article}') for pkg in ['{type1cm}', '[psamsfonts]{amssymb}', '{amsmath}']: Tn('\\usepackage%s' % pkg) if opts.preamble is not None: Tn('\\input{%s}' % opts.preamble) Tn('\\begin{document}') Tn('\\thispagestyle{empty}') if not opts.text: Tn('\\begin{eqnarray*}') T(formula) if not opts.text: Tn('\\end{eqnarray*}') Tn('\\end{document}') code = codebuffer.getvalue() latex = Popen('latex', stdout=PIPE, stdin=PIPE) latex.stdin.write(code) latex.stdin.write('\\end') latex.stdin.close() exitcode = latex.wait() if exitcode != 0: print latex.stdout.read() return exitcode dvipng_args = ['dvipng', '-q', '-Ttight', '-M', '-pp1', '--noghostscript', '-D%d' % opts.resolution, '-o%s' % pngfilename, dvifilename] dvipng = Popen(dvipng_args, stdin=PIPE, stdout=PIPE) dvipng_exitcode = dvipng.wait() if dvipng_exitcode != 0: print 'Unexpected error (code %d) during dvipng' % dvipng_exitcode print dvipng.stdout.read() return exitcode def clean(): for tempfilename in [dvifilename, logfilename, auxfilename]: if os.path.isfile(tempfilename): os.remove(tempfilename) def main(): pngfilenames = [] def run(formula, pngfilename): exitcode = tex2png(formula, pngfilename) if exitcode == 0: pngfilenames.append(pngfilename) if len(args) == 0: formula = sys.stdin.read() pngfilename = 'out.png' run(formula, pngfilename) for filename in args: if not filename.endswith('.tex'): print 'Warning:', filename, 'is not a .tex file, skipping' continue formula = open(filename).read() pngfilename = filename[:-4] + '.png' run(formula, pngfilename) if not opts.no_clean: clean() if opts.view and pngfilenames: Popen([viewcommand] + pngfilenames) if __name__ == '__main__': main()