#!/usr/bin/perl
#
# Usage:
#    ps2frag [-x<pts>] [-y<pts>] files...
#
# Ps2frag runs GhostScript on one or more postscript files.  For each
# file argument (eg: "example.ps"), a file with the extension ".frag" is
# written (eg: "example.frag").  The output file contains LaTeX
# source that gives the text, abs bottom-left coordinates, text bounding
# box, and rotation for each piece of text that is displayed by the
# postscript show operators (show, ashow, kshow etc).
#
# The -x and -y arguments can be used to offset the x and y locations
# of each text fragment.  Some programs that write postscript files like
# to offset all text by a small fixed amount.  For example, matlab puts
# text from a text() command 2.28 pts (4 * 0.57) above a plotted line with
# the same coordinates.  Therefore, to convert a matlab postscript file you
# should use
#
#      ps2frag -y -2.28 matlabplot.ps
#
# Similarly, idraw, with grid gravity turned on, puts text a small distance
# above the grid point.  For 12pt fonts the offset is 8.33 pts (it appears to
# be 0.7574 * (fontSize - 1) in general), so to convert an idraw postscript
# file you should use
#
#      ps2frag -y -8.33 idrawfile.ps
#
# (Note that these position corrections are only relevant if you want the
# LaTeX characters to line up exactly with other geometry such as lines etc).
#
# The output file (<file>.frag) is normally included with the
# \epsfbox{} LaTeX marco.  You should include the psfrag and epsfrag
# document styles to make everything work.
#
# Revision History:
#   26-Oct-93   Piet Tutelaers  ported to MSDOS and perlized
#   20-Sep-92   Craig Barratt	Released version 1.1.
#   17-Sep-92   Craig Barratt	Made PS2FRAG settable by user.
#    9-Jun-92   Craig Barratt	Changed egrep to grep for system V users.
#    1-Jun-92   Craig Barratt	Released version 1.0.
#   28-Feb-92   Craig Barratt	Initial version.
#
# Send comments and bugs to Craig Barratt (craig@isl.stanford.edu)
#

# Installation: PS2FRAG should point at wherever the ps2frag.ps
# file is installed (eg: set PS2FRAG = /usr/local/lib/ps/ps2frag.ps).
# The "set PS2FRAG" line below should be edited accordingly.
#
# [The user can override this default by setting the environment
#  variable PS2FRAG to point somewhere else; this was suggested
#  by Roque Donizete de Oliveira (oliveria@caen.engin.umich.edu).]
#

# Platform dependant code
$UNIX = 1; $verbose = 1;
$SEP = ':' if $UNIX;
$SEP = ';' if $MSDOS;

# Use default or user's PS2FRAG environment value
#$ENV{'PS2FRAG'} ='/stumpy.a/student/mconsult/latex/inputs/ps2frag.ps' unless $ENV{'PS2FRAG'};
$ENV{'PS2FRAG'} = './ps2frag.ps' unless $ENV{'PS2FRAG'};
die "Can't open $ENV{'PS2FRAG'}\n" unless -r $ENV{'PS2FRAG'};

# Verify if we have GhostScript
$GS = 'gs386.exe' if $MSDOS;
$GS = 'gs' if $UNIX; 
$gsfile = &where($ENV{'PATH'}, $GS);
die "$GS: not found in $ENV{'PATH'}\n" unless $gsfile ne '';
($ENV{'GS_LIB'}) = ($gsfile =~ m#^(.*)[/\\]#) if $MSDOS;

$dx = 0;
$dy = 0;

do 'getopts.pl';
&Getopts('x:y:') || &usage();
&usage() unless @ARGV;

$dx = $opt_x if $opt_x;
$dy = $opt_y if $opt_y;
die "$dx: invalid number\n" unless &valid_number($dx);
die "$dy: invalid number\n" unless &valid_number($dy);

foreach (@ARGV) {
   die "Can't open $_\n" unless -r $_;
   warn "$_:  missing '%!' magic code!\n" unless &postscript($_);
   $psfile = $_;
   s/[.].*$/.frag/; $fragfile = $_;
   s/[.].*$/.gs/; $gsout = $_;
   unlink($fragfile) if -r $fragfile;
   print "Running $GS ..." if $verbose;
   open(GS, "|$GS -dNODISPLAY $ENV{'PS2FRAG'} - > $gsout");
   print(GS "$dx $dy ($psfile) FragConvert\n");
   close(GS);
   print " done.\n" if $verbose;
   $error = `grep -s -i Error $gsout` if $gsout;
   if (! -r "$fragfile" || $error) {
      print "$GS failed on '$psfile' (see $gsout) running:\n";
      print "echo \"$dx $dy ($psfile) FragConvert\"",
            " | gs -dNODISPLAY $ENV{'PS2FRAG'} -\n" if $UNIX;
      print "echo $dx $dy ($psfile) FragConvert",
            " | $GS -dNODISPLAY $ENV{'PS2FRAG'} -\n" if $MSDOS;
      exit 1;
   }
   print "$fragfile created\n" if $verbose && $fragfile;
   unlink("$gsout");
}

exit 0;

sub usage{
    print "Usage: ps2frag [-x<pts>] [-x<pts>] files...\n";
    exit 1;
}

sub valid_number{
   local($_) = @_;
   /^-?\d*(\.\d*)?$/? 1: 0;
}

sub postscript{
   local($_) = @_;
   open(PS, $_);
   $magic = getc(PS) . getc(PS);
   close(PS);
   $magic eq '%!'? 1: 0;
}

#
# Look for a <file> with some possible <extensions> in <path>.
# Return absolute name of <file> when found otherwise empty string.
#
sub where {
   local($path, $file) = @_;
   foreach (split(/$SEP/, $path)) {
      if (-r "$_/$file") {
         return "$_/$file";
      }
   }
   return "";
}

