eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' && eval 'exec perl -S $0 $argv:q'
  if 0;

use strict;				# to be sure, that all is safe ... :-)

# $Id: pst2pdf.pl 611 2011-12-14 08:41:35Z herbert $
# v. 0.13				simplify the use of PSTricks with pdf
# 2011-12-12	(c) Herbert Voss <hvoss@tug.org> 
#                   Pablo González Luengo and http://perlenespanol.com
# 
# 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 2 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, write to the
# Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA  02111-1307  USA
#
use File::Path;                         # creating/removing dirs
use File::Copy;                         # copying files
use File::Basename;			# scan argument
use IO::File;                           # simple IO operation
use Getopt::Long;			# read parameter
#----------------------- User part begin ------------------------
my $imageDir = "images";		# where to save the images
my $Iext = ".pdf";			# leave empty, if not a special one
my $tempDir = ".";			# temporary directory
my $verbose = 1;			# 0 or 1, logfile  
my $clear = 0;				# 0 or 1, clears all temporary files
my $DPI = 75;				# very low value for the png's
my $Iscale = 1;			 	# for \includegraphics
my $noImages = 0;			# 1->create no images
my $runBibTeX = 0;			# 1->runs bibtex
my $runBiber = 0;			# 1->runs biber and sets $runBibTeX=0
my $ppm = 0;				# 1->create .ppm files
my $norun = 0;				# 1->runs pdflatex
my $miktex = 0;				# 1->runs pdlatex for miktex
my $eps = 0;				# 1->create .eps files
#----------------------- User part end ---------------------------
#----------------------- program identification, options and help
my $program = "pst2pdf";
my $ident = '$Id: pst2pdf.pl 611 2011-12-14 08:41:35Z herbert $';
my $copyright = <<END_COPYRIGHT ;
Copyright 2011-01-18 (c) Herbert Voss <hvoss\@tug.org> 
END_COPYRIGHT
my $licensetxt= <<END_LICENSE ;
    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 2 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, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
	MA  02111-1307  USA
END_LICENSE
my $title = "$program $ident\n";
my $usage = <<"END_OF_USAGE";
${title}Usage: $program <texfile[,tex]>  [Options]
pst2pdf run a TeX source, and convert all PS-related part as 
	single images  (pdf and/or eps and/or png and/or ...) 
	and then runs pdflatex. See pst2pdf documentation for more info
Options:
  --help          - display this help and exit
  --version       - display version information and exit
  --license       - display license information and exit
  --imageDir      - the dir for the created images (default images) 
  --DPI=<int>     - the dots per inch for a cretaed ppm files (default 75)
  --ppm           - create .ppm files
  --eps	  	  - create .eps files	
  --Iscale=<real> - the value for [scale=] in \\includegraphics 
  --verbose       - long log
  --clear         - delete all temp files
  --norun         - create file-pdf.tex, but, no run pdflatex
  --runBibTeX     - run bibtex on the aux file, if exists
  --runBiber      - run biber on the bcf file, if exists
  --miktex	  - for miktex users -enable-write18	
Examples:
* $program test.tex --clear --ppm --eps
* produce test-pdf.tex and .ppm,.eps,.tex and .pdf for all images in image dir
END_OF_USAGE
#
my $result=GetOptions (
  			"help",
  			"version",
  			"license",
			"DPI=i"      => \$DPI,      	# numeric
			"Iscale=f"   => \$Iscale,   	# real
			"imageDir=s" => \$imageDir, 	# string
			"tempDir=s"  => \$tempDir,  	# string
			"Iext=s"     => \$Iext,     	# string
			"clear"      => \$clear,    	# flag
			"noImages"   => \$noImages, 	# flag
			"runBibTeX"  => \$runBibTeX,   # flag
			"ppm"        => \$ppm,         # flag
			"norun"      => \$norun,       # flag
			"miktex"     => \$miktex,      # flag
			"eps"        => \$eps,		# flag
			"runBiber"   => \$runBiber, 	# flag
			"verbose"    => \$verbose,
) or die $usage;
# help functions
sub debug      { print STDERR "* @_\n" if $::opt_debug; }
sub warning    { print STDERR "==> Warning: @_\n"; }
sub error      { die "$title!!! Error: @_\n"; }
sub errorUsage { die "Error: @_ (try --help for more information)\n"; }
# options for command line
if ($::opt_help) {
  print $usage;
  exit (0);
}
if ($::opt_version) {
  print $title;
  print $copyright;
  exit (0);
}
if ($::opt_license) {
  print $licensetxt;
  exit (0);
}
# open file 
my $InputFilename = "";
if ($::opt_filter) {
  @ARGV == 0 or
  errorUsage "Input file cannot be used with filter option";
  debug "Filtering: will read standard input";
} else {
  @ARGV > 0 or errorUsage "Input filename missing";
  @ARGV < 2 or errorUsage "Unknown option or too many input files";
  $InputFilename = $ARGV[0];
  debug "Input filename:", $InputFilename;
}
my @SuffixList = (".tex","",".ltx");		# possible extensions
my ($name,$path,$ext) = fileparse($ARGV[0],@SuffixList);
if ($ext eq "") { $ext = ".tex"; }			# me need the extension as well
my $TeXfile = "$path$name$ext";
my $Logfile = "$tempDir/$name.plog";		# our own log file
open (LOGfile,">$Logfile") or die "cannot open $Logfile!";
LOG ("Parameters:"); 
LOG ("==> imageDir = $imageDir"); 
LOG ("==> Iext     = $Iext"); 
LOG ("==> DPI      = $DPI"); 
LOG ("==> Iscale   = $Iscale"); 
LOG ("==> tempDir  = $tempDir"); 
LOG ("==> verbose  = $verbose"); 
LOG ("==> clear    = $clear"); 
LOG ("==> noImages = $noImages"); 
LOG ("==> runBibTeX= $runBibTeX"); 
LOG ("==> runBiber = $runBiber"); 
LOG ("==> ppm      = $ppm"); 
LOG ("==> norun    = $norun"); 
LOG ("==> miktex   = $miktex");
LOG ("==> eps      = $eps");  

if ($runBibTeX && $runBiber) {
  LOG ("!!! you cannot run BibTeX and Biber at the same document ...");
  LOG ("!!! Assuming to run Biber");
  $runBibTeX = 0;
}
if ($ppm) {
  LOG ("Generate .ppm files ...");
  $ppm = 1;
}
if ($norun) {
  LOG ("no compile file-pdf.tex");
  $norun = 1;
}
if ($miktex) {
  LOG ("enable write 18 ...");
  $miktex = 1;
}
if ($eps) {
  LOG ("Generate .eps files ...");
  $eps = 1;
}

my $imgNo = 1;				# internal image counter
my $pstExaLoaded = 0;		# Document loads pst-exa

LOG ("Running on [$path][$name][$ext]"); 
open (FILE, "<$TeXfile") or die "cannot open source file $TeXfile!";	# the source
if (!$noImages ) {
  if (-d $imageDir) { LOG ("$imageDir exists") }
  else { mkdir("$imageDir", 0744) || die "cannot mkdir $imageDir: $!";
LOG ("Imagedir created"); }
LOG ("go to savePreamble ... "); 
savePreamble($name);
runBurst("$tempDir");
LOG ("done!\n go to runFile ..."); 
runFile($name);
LOG ("done!"); 
close FILE;					# close source file
}# !noImages

#------------ Create filename-pics.pdf, split and generate .ppm
sub runBurst{
if ($miktex){system("pdflatex -enable-write18 -interaction=nonstopmode $tempDir/$name");}
else{system("pdflatex -shell-escape -interaction=nonstopmode $tempDir/$name");}
system("pdftk $name-pics.pdf burst output $imageDir/$name-tmp-\%1d.pdf");
if ($ppm){system("pdftoppm -r  $DPI $name-pics.pdf $imageDir/$name-tmp"); 
# Renaming .ppm neded for windows
if ($^O eq 'MSWin32') {
my $dren = "$tempDir/$imageDir";
my $fichero = '';
my $ppmren = '';
my $renNo = 1;
if(opendir(DIR,$dren)){
  foreach (readdir DIR){
        $fichero = $_;
        if ($fichero =~ /([^\d]+)(\d+).ppm/){
	     my $renNo=int($2);
	     my $newname="$1$renNo.ppm";
          $ppmren = rename("$dren/$fichero","$dren/$newname");
        }
		}
	}
  else
	{
  print "dont open".$dren;
	}
closedir DIR;
}
# end renaming
}
}
#------------ end pdftk burst
LOG ("runpdfTeX ... "); 
runpdfTeX("$path$name",$name);
LOG ("all finished ... :-)"); 
close LOGfile;

if ( $clear ) {
unlink "$path$name.txt";
unlink "$path$name.log";
unlink "$path$name.plog";
unlink "$path$name.preamble";
unlink "$path$name.pdf";
 }
# create a preamble file
# if we have a \input command inside the preamble, it doesn't hurt, we need
# it anyway for the postscript files and the pdf one.
sub savePreamble {				
  my $filename = pop;					# get the file name
  LOG ("----- Start Preamble -----"); 
  open (FILEp, ">$tempDir/$filename.preamble") 
    or die "cannot open preamble file $tempDir/$filename.preamble!";
  while (<FILE>) {					# read all until \begin{document}
    $pstExaLoaded = index($_,"usepackage{pst-exa}"); 
    my $i = index($_,"begin{document}");
    if ($i > 0) { 
      if ($i > 1) { print FILEp substr($_,0,--$i); }	# write all until \begin{document}
      close(FILEp);  					# close preamble
      LOG ("----- Close Preamble ------"); 
      return; 
    } else { 
      print FILEp "$_"; 				# write into preamble
      LOG ("$_"); 
    }
  }
  close(FILEp);
  if ( $verbose ) { LOG("<-----Preamble<----"); }
  return;
}

sub searchPS {						# search the PostScript parts
  my @PS = ();						# single PS sequence
  my @PStotal = ();					# all PS sequences as list of arrays
  my $depth = -1;					# counts nested macros
  my $type = -1;					# -1-> none; 1->PST; 2->PS; 
  my $EndDocument = 0;					# ignore all after \end{document}
  my $iVerb = 0;					# test for verbatim or lstlisting environment, must be ignored
  while (<FILE>) {					# scan the input file
    if (!$EndDocument) {
    chomp;							# delete EOL character
    my $line = $_; 					# save line
    if ( !$iVerb ) { 
      $iVerb = ((index($line,"begin{verbatim}") > 0) or (index($line,"begin{lstlisting}") > 0)); 
    } 								# do nothing until \end{verbatim}
    if ( !$iVerb ) {
      my $iPS = index($line,"begin{postscript}");
      my $iPST = index($line,"begin{pspicture*}");
      if ($iPST < 0) { $iPST = index($line,"begin{pspicture}"); }	# alternative 
      if ($iPST < 0) { $iPST = index($line,"pspicture"); }			# alternative \pspicture...
      if (($iPS > 0) && ( $type == 1 )){ print "postscript environment must be of outer level!\n"; exit 1; }
      if ( $type < 0 ) {			# no active environment
        if ($iPS > 0) { 			# we have \begin{postscript}
          $type = 2; 			
          $line = substr($line,$iPS-1);		# add rest of the line
  	  LOG("PS-Zeile: $line");
        } 				
        elsif ( $iPST > 0 ) { 				# we have \begin{pspicture} or \pspicture
          $type = 1; 
	  $depth++;  
          $line = substr($line,$iPST-1);	# add all unitl pspicture
	  LOG("PST-Zeile: $line");
        }
      }
# we have now \begin{pspicture} or \begin{postscript}
      if ($type > 0) {					# start Scan, we have an environment
        LOG ("searchPS: set \$type=$type"); 
        $iPST = index($line,"end{pspicture*}");
        if ($iPST < 0) { $iPST = index($line,"end{pspicture}"); }	# alternative
        if ($iPST < 0) { $iPST = index($line,"endpspicture"); }		# alternative \endpspicture...
        $iPS = index($line,"end{postscript}");	
        if ($iPST > 0) {				# test, we can have postscript and pspicture in one line
          if ( $type < 2) {				# found end of pspicture environment 
            LOG ("searchPS: $line"); 
	    $depth--; 
	    if ($depth < 0) { 
	      $type = -1; 
	      if (index($line,"endpspicture") > 0) 	# add line, depends to type
	           { push @PS,substr($line,0,$iPST+12); }	# \endpspicture
	      elsif (index($line,"pspicture*") > 0)
 	              { push @PS,substr($line,0,$iPST+15); }# \end{pspicture} 
	      else { push @PS,substr($line,0,$iPST+14); }	# \end{pspicture} 
              LOG ("searchPS: set \$type=$type"); 
              push @PStotal,[@PS];	# add PS sequence
              LOG ("---->PS---->\n@PS\n<----PS<----"); 
	      @PS = ();			# start new PS sequence
	    }				# no pspicture env left
	  } else { push @PS,$line; }	# pspicture inside postscript
        } elsif ($iPS > 0) { 		# must be type=1 -> stop Scan
          LOG ("searchPS: $line"); 
	  $type = -1;
    	  push @PS,substr($line,0,$iPS+15);	# add line
          LOG ("searchPS: set \$type=$type"); 
          push @PStotal,[@PS];			# add PS sequence
          LOG ("---->PS---->\n@PS\n<----PS<----"); 
	  @PS =();			# start new PS sequence
        } else { push @PS,$line; }	# add line
      }
      my $i = index($line,"end{document}");
      if ($i > 0) { $EndDocument++; LOG("EndDocument in searchPS"); }
    } 				# if ( $iVerb )
    if (( index($line,"end{verbatim}") > 0 ) or ( index($line,"end{lstlisting}") > 0 )) { $iVerb = 0; }
  }}
  if ( $verbose ) { 
    LOG("---->PStotal---->");
    for my $aref ( @PStotal ) { 
      my @a = @$aref;
      my $i = 0;
      foreach ( @a ) { LOG ($a[$i]); $i++; }
    }
    LOG ("<----PStotal<----"); 
  }
  close(FILE);
  return @PStotal;		# return all PS sequences
}

# Creating subfiles.tex and .eps for images
sub runTeX{
  my $filename = pop;
  my $name = "$filename";
  copy("$filename.tex", "$imageDir/$filename-$imgNo.tex") or die "Cannot copy Source file!";
  if ($eps){
			system("pdftops -level3 -eps $imageDir/$filename-$imgNo.pdf $imageDir/$filename-$imgNo.eps");
		   }
$imgNo=$imgNo+1;
}

sub runFile {
  my $filename = pop;
  my @PSarray = searchPS();
  if ( $verbose ) { 
    LOG("---->PSarray---->");
    for my $aref ( @PSarray ) { 
      my @a = @$aref;
      my $i = 0;
      foreach ( @a ) { print LOG $a[$i]."\n"; $i++; }
    }
    LOG("<----PSarray<----"); 
    my $no = @PSarray;
    LOG("PS: ".$no." PS sequence(s)"); 
  }
  for my $aref ( @PSarray ) {
    my @PS = @$aref;
    open (FILEp,"<$tempDir/$filename.preamble") or die "cannot open $tempDir/$filename.preamble!";
    open (FILEsub,">$tempDir/$filename-tmp.tex") or die "cannot open $tempDir/$filename-tmp.tex!";
    while (<FILEp>) {print FILEsub $_; }
    print FILEsub "\\pagestyle{empty}\n";
    print FILEsub "\\begin{document}\n";
    if ( $verbose ) { LOG("\@PS: $_"); }
    foreach ( @PS ) { print FILEsub "$_\n"; }
    print FILEsub "\\end{document}\n";
    close (FILEsub);
    close (FILEp);
    runTeX("$tempDir/$filename-tmp");
  }
}
# Replace files
sub runpdfTeX() {
  my ($name,$pdfname) = @_;
  open (PDF, ">$tempDir/$pdfname-pdf.tex") or die "cannot open $tempDir/$pdfname-pdf.tex!";
  open (FILE, "<$name.tex") or die "cannot open $name!";
  my $ignore = 0;
  my $IMGno = 1;
  my $depth = -1;
  my $type = -1;
  my $EndDocument = 0;					# ignore all after \end{document}
  my $iVerb = 0;
  while (<FILE>) {					# scan the input file
    if ( !$iVerb ) { 
      $iVerb = ((index($_,"begin{verbatim}") > 0) or (index($_,"begin{lstlisting}") > 0)); 
    } # do nothing until \end{verbatim}|| \end{lstlisting}
    if ( !$iVerb ) {
      my $i = index($_,"end{document}");
      if ($i > 0) { print PDF $_; $EndDocument++; LOG("EndDocument in runpdfTeX"); }
      if ( !$EndDocument ) {
        my $iPS = index($_,"begin{postscript}");
        if ( $iPS > 0 ) { 
          $type = 2; 
          $ignore = 1; 
          if ($iPS > 1) { print PDF substr($_,0,--$iPS); }	# add preceeding text
	print PDF "\\includegraphics[scale=$Iscale]{$pdfname-tmp-$IMGno}"; # use pdfname
          $IMGno=$IMGno+1;
        }		# postscript env
        if ( $type < 2 ) {
          my $iPST = index($_,"begin{pspicture*}");
          if ($iPST < 0) { $iPST = index($_,"begin{pspicture}"); }	# alternative ...
          if ($iPST < 0) { $iPST = index($_,"\\pspicture"); }		# alternative \endpspicture...
          if ( $iPST >= 0 ) {	 				# start Scan
            $ignore = 1;
            $type = 1; 
            $depth++; 							# pspicture env
	    LOG("Increase depth: $depth");
	    if ( $depth == 0 ) {
              if ($iPST > 1) { print PDF substr($_,0,--$iPST); }	# add preceeding text
              print PDF "\\includegraphics[scale=$Iscale]{$pdfname-tmp-$IMGno}"; 	# use \graphicspath
              $IMGno=$IMGno+1;
	      LOG("Increase Image counter: $IMGno");
            }
          }
        }
        if ( !$ignore ) { print PDF "$_"; }		# default line
        if ( $type == 2 ) {						# postscript env
          my $iPS = index($_,"end{postscript}");
          if ($iPS > 0) {
            print PDF substr($_,$iPS+15);		# rest of line
            $ignore = 0; 
            $type=-1;
          }										# end Scan
        } elsif ( $type == 1 ) {				# pspicture env
          my $iPST = index($_,"end{pspicture*}");
          if ($iPST < 0) { $iPST = index($_,"end{pspicture}"); }	# alternative ...
          if ($iPST < 0) { $iPST = index($_,"endpspicture"); }		# alternative \endpspicture...
          if ($iPST > 0) {		 				# end Scan
	    if (index($_,"endpspicture") > 0) 		# add rest of line, depends to type
	       { print PDF substr($_,$iPST+12); }	# \endpspicture
	    elsif (index($_,"pspicture*") > 0)
	            { print PDF substr($_,$iPST+15); }	# \end{pspicture*} 
	    else    { print PDF substr($_,$iPST+14); }	# \end{pspicture}
            $depth--; 
	    LOG("Decrease depth: $depth");
            if ($depth < 0) { $ignore = 0; }
          }
        }
      } # if ( !$EndDocument ) 
    } else { print PDF $_; } # if ( $iVerb )
    if (( index($_,"end{verbatim}") > 0 ) or ( index($_,"end{lstlisting}") > 0 )) { $iVerb = 0; }
  } # while (<FILE>)
  close (FILE);
  close (PDF);
# Coment pst-package
	open (IPDF, "<$tempDir/$pdfname-pdf.tex"); 
	undef $/;   # read all file
	my ($uno,$dos) = split(/\\begin\{document\}/,<IPDF>,2);
	close IPDF;
	
	my @coment = split /\n/, $uno; # split in two
	my @preamb;

	foreach my $line (@coment) { 
	chomp($line); 
	$line =~ s/\\usepackage(?:\[.+?\])?\{pst.+?}//g; 			# delete
	$line =~ s/\\usepackage(?:\[.+?\])?\{psfr.+?}//g; 			# delete
	$line =~ s/(\\usepackage(?:\[.+?\])?)\{auto-pst.+?}//g; 	# delete
	$line =~ s/(\\usepackage(?:\[.+?\])?)\{vaucanson-.+?}//g; 	# delete
	$line =~ s/(\\usepackage(?:\[.+?\])?)\{psgo}//g; 	# delete
	$line =~ s/(\\usepackage(?:\[.+?\])?)\{graph/\%$1\{graph/g; # comment
	next if $line =~ m/^\s*$/;
	push(@preamb,$line);    # adding changes
}
my $clean = join("\n", @preamb, "\\usepackage{grfext}\n\\\PrependGraphicsExtensions*{$Iext}\n\\usepackage{graphicx}\n\\graphicspath{{$imageDir/}}\n\\begin{document}\n". $dos);

open (OPDF,">$tempDir/$pdfname-pdf.tex"); # write changes
print OPDF $clean; 
close OPDF; 
# close coment pst-package

my $runAgain = 0;
if ($norun){print "Done\n";}
else {system("pdflatex -interaction=nonstopmode $pdfname-pdf");}
if (-e "$tempDir/$pdfname-pdf.idx") { system("makeindex $tempDir/$pdfname-pdf.idx"); $runAgain++; }
if ($runBibTeX && -e "$tempDir/$pdfname-pdf.aux") { system("bibtex $tempDir/$pdfname-pdf");  $runAgain++; }
if ($runBiber && -e "$tempDir/$pdfname-pdf.bcf") { system("biber $tempDir/$pdfname-pdf");  $runAgain++; }
if ($runAgain) { system("pdflatex $tempDir/$pdfname-pdf"); }
if ( $clear ) {
	unlink "$name.txt";
	unlink "$tempDir/$name.aux";
	unlink "$tempDir/$pdfname-pdf.log";
	unlink "$tempDir/$pdfname-pdf.aux";
	unlink "$tempDir/$pdfname-pdf-autopp.txt";
	unlink "$tempDir/$pdfname-pics.pdf";
	unlink "$tempDir/doc_data.txt";
	unlink "$tempDir/$pdfname-tmp.tex";
	}
}

sub LOG() { 
  if ( $verbose ) { print LOGfile "@_\n"; } 
}
__END__
