#!/usr/bin/env python
# -*- encoding: iso-8859-15 -*-

# tedot.py - a wrapper for dot to create graphs that may contain TeX-Math as Labels
# (c) Jens Georg, 2005
# 
# this is a destillation of ladot and unpsfrag
#
# ladot: http://brighten.bigw.org/projects/ladot/
# unpsfrag: http://www.gts.tsc.uvigo.es/~fiz/unpsfrag

import sys
import os
import re
import string
import tempfile
import random
import commands
import shutil

psfrags = []
stubs = {}

# returns an uniqe string for every occurence of LaTeX Math code
def make_stub(match):
	if not stubs.has_key(match.group(0)):
		stub_charset = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
		try:
			length = int(match.group(3))
		except:
			length = len(match.group(1)) - 1

		stub = string.join ([random.choice(stub_charset)  for k in range(0, length)], "")

		stubs[match.group(0)] = stub
		psfrags.append("\\psfrag{%s}[cc][cc]{%s}" % (stub, match.group(1)))
	return stubs[match.group(0)]

def dot_to_ps(dotname):
	# let dot create the postscript and read the resulting file
	# as we need to process it anyway
	tmpps = string.join(commands.getoutput("dot -Tps " + dotname), "")
	tmpdot.close()

	# replace all [...] xshow with plain show to make psfrags happy
	# fixme: This is not necessary for graphviz <= 2.0
	tmpps = re.sub("\n\[.*\]\nxshow", "\nshow", tmpps)
	psfile = open(os.path.join (tmpdir, basename + ".tmp.ps"), "w+b")
	psfile.write (tmpps)
	psfile.close()

def create_tmp_tex(psfrags):
	texfile = open(os.path.join (tmpdir, basename + ".tex"), "w+b")
	texfile.write ("""
% This LaTeX file has been automagically created by tedot
\documentclass{article}
\usepackage[dvips]{graphicx}
\usepackage{psfrag}
\pagestyle{empty}
\\begin{document}
\\onecolumn
	""")
	for frag in psfrags:
		texfile.write(frag + "\n")
	texfile.write("\\includegraphics{%s.tmp.ps}\n" % basename)
	texfile.write("\\end{document}\n%EOF")
	texfile.close()

if __name__ == "__main__":
	if len(sys.argv) != 2:
		print 'Usage: %s <dotfile>' % sys.argv[0]
		sys.exit(0)

	# initialisation stuff
	tmpdir = tempfile.mkdtemp()
	basename = re.sub("(.*)\.[^.]+$", "\\1", os.path.basename (sys.argv[1]))

	# read original .dot
	dot = open(sys.argv[1])
	lines = dot.readlines()
	dot.close()

	# ok, create temporary .dot
	tmpdot = tempfile.NamedTemporaryFile()
	texre = re.compile ("(\$.*?\$)(\((\d+)\))?")
	for line in lines:
		tmpdot.write(texre.sub(make_stub, line))
	tmpdot.flush()

	# create temporary ps file
	dot_to_ps (tmpdot.name)

	# create simple latex-file
	create_tmp_tex (psfrags)

	# compile latex file
	oldpath = os.getcwd()
	os.chdir(tmpdir)
	os.system ("latex -interaction=batchmode %s" % basename + ".tex")

	# run dvips
	os.system ("dvips %s" % basename + ".dvi")

	# extract graphic as eps
	os.system ("ps2eps -l -f %s" % basename + ".ps")
	os.chdir(oldpath)

	# copy generated eps to current directory
	shutil.move (os.path.join (tmpdir, basename + ".eps"), oldpath)

	# cleanup the tmpdir mess ;)
	shutil.rmtree (tmpdir)

