#!/usr/bin/perl

%paststubs = ();

if (@ARGV != 1) {
    die "Usage: $0 [infile]";
    }

# Open input and output files
open(INFILE, "<$ARGV[0]");
$ARGV[0] =~ /(.*)\.ladot$/;
$basename = $1;
if ($basename eq "") {
    $basename = $ARGV[0];
    }
open(DOTOUT, ">/tmp/$basename.dot");
open(TEXOUT, ">$basename.tex");

while ($line = <INFILE>)
    {
    while ($line =~ /(\$.*?\$)(\((\d+)\))?/) {
        # print "LINE: $line";
        $sizehint = $3;
        # print "SIZEHINT: $sizehint\n";
        $tex = $1;
        $stub = make_stub($tex, $sizehint);
        $line =~ s/(\$.*?\$)(\((\d+)\))?/$stub/;
        print TEXOUT "\\psfrag{$stub}[cc][cc]{$tex}\n";
        }
    print DOTOUT $line;
    }

close(DOTOUT);
close(TEXOUT);

# Generate postscript of the graph, with stubs
system("dot -Tps /tmp/$basename.dot > $basename.ps");

# Graphviz 2.2 and later outputs postscript in which psfrag won't replace tags.
# This is psfrag's fault, but our problem.  Here's a fix.
system("sed -ibackup \"s/xshow/pop show/g\" $basename.ps");
# There is a way to get sed to modify in place with no backup file, but
# it seems the syntax of this option is slightly different in different
# versions of sed.  So we just remove the backup ourselves.
unlink("$basename.psbackup");

unlink("/tmp/$basename.dot");

sub make_stub($$)
    {
    # Make a placeholder (stub) for the TeX which will be substituted for the
    # real formatted TeX later.  Arguments are TeX code and an optional
    # "hint" about the desired width of the box.
    
    # This is tricky because the length of the stub
    # that we choose affects how Dot formats the PostScript.  We use the
    # heuristic that the length of the LaTeX code is correlated with the
    # amount of space needed to render the LaTeX code.

    if ($paststubs{$_[0]}) {
        return $paststubs{$_[0]};
        }

    my $length = int($_[1]);
    if ($length == 0) {
        # no sizehint given
        $length = length($_[0]) - 1;
        }
    # print "LENGTH of $_[0]: $length\n";
    # The first character of an unquoted string in Dot has to be one of these.
    $first_charset="_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    # Subsequent characters can be any of these.
    $subseq_charset="1234567890$first_charset";
    my $stub = "";
    for (my $i = 1; $i <= $length; $i++) {
        if ($i == 1) {
            $charset = $first_charset;
            }
        else {
            $charset = $subseq_charset;
            }
        $stub .= substr($charset, int(rand(length($charset))), 1);
        }
    #print "NEW STUB for $_[0]: $stub\n";
    $paststubs{$_[0]} = $stub;
    return $stub;
    }
