#!/usr/bin/perl

## unpsfrag - turns LaTeX files using psfrag into pdflatex-compatible ones 
## -------------------------------------------------------------------
## (C)opyright 2002,2005 Félix Balado 

## 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.                             

## Author: Félix Balado
## Send bug reports to fiz ihl ucd ie (but expect no answers :)

## -------------------------------------------------------------------

## $Id: unpsfrag,v 1.5 2002/11/19 11:18:25 felix Exp felix $

@usagetxt= 
  (
   "Usage: unpsfrag [-h] [-v] input\n",
   "\n",
   "Conversion of a LaTeX file input.tex using psfrag into a new LaTeX\n",
   "file _input.tex without psfrag that can be compiled with pdflatex.\n",
   "\n",
   "unpsfrag automatically generates all necessary pdf files to allow\n",
   "the straightforward compilation of _input.tex with pdflatex.\n",
   "WARNING: existing pdf files having the same names will be\n",
   "overwritten. A script _clean is generated for deleting everything\n",
   "unpsfrag creates.\n",
   "\n",
   "Some assumptions for the script to work:\n",
   "- The \\usepackage{} declarations only carry one item, not a\n",
   "comma-separated list of them.\n",
   "- All information corresponding to each \\psfrag[][]{} declaration\n",
   "lies in a single line.\n",
   "\n",
   "\\usepackage{epsfig} _OR_ \\usepackage[dvips]{grapicx} are supported \n",
   "- If epsfig is used, the inclusion of an image must be in a single\n",
   "line, i.e. \\epsfxsize=8cm \\epsfbox{fig/multi_dither.eps}\n",
   "\n",
   "The use of several images inside a single \"figure\" environment is\n",
   "supported.\n",
   "New features (2005): references and citations inside psfrag are supported 
   as long as the original input.tex has been compiled before running 
   unpsfrag".
   "\n",
   "This script depends on having installed the following programs:\n",
   "- ps2eps 1.35,\n",
   "(http://www.telematik.informatik.uni-karlsruhe.de/~bless/ps2eps.html)\n",
   "- psselect 1.17\n",
   "- epstopdf 2.5\n",
   "- TeTeX distribution \n",
   "- gs 7.04 (APFL)\n",
   "For the final compilation use\n",
   "- pdflatex 3.14159-0.14h\n",
   "\n");

$version='$Revision: 1.5 $';
$need_help=0;

if ($#ARGV<0) 
  {
    $need_help=1;
  }
foreach $text (@ARGV)  
  {
    last if (!($text=~/^-/));
    if ($text=~/-h/)
      {
	$need_help=1;
      }
    elsif ($text=~/-v/)
      {
	print "Version $version\n";
	exit;
      }
    else 
      {
	print "Unrecognized option $text \n"; 
	$need_help=1;
      }
    shift(@ARGV);
  }
if ($need_help)
  {  
    print "@usagetxt";
    exit;
  }

$input_tex="$ARGV[0].tex"; # parametro ficheiro.tex

print "Processing $input_tex\n";

$output_tex="_$ARGV[0].tex";
$preamble="_preamble.tex";
$script="_process_figures";

# 1) Fazer um ficheiro geral sem psfrags e cos cabeçalhos adequados

open(INPUT_TEX,"$input_tex") || die;
open(OUTPUT_TEX,">$output_tex") || die;

while (<INPUT_TEX>) 
  {
    if (!/psfrag/)    # elimino psfrag 
      {
	s/\%.*$/\%/;    # "sem comentários"
	if (/\\usepackage\[dvips\]/ || /\\usepackage{epsf}/) 
	  {
	    print "Eliminando $_\n";
	    print OUTPUT_TEX "\\usepackage\[pdftex\]{graphicx}\n";
	    print OUTPUT_TEX "\\usepackage\[pdftex,bookmarksnumbered,colorlinks,hypertexnames=true,linkcolor=blue,plainpages,citecolor=red,urlcolor=blue\]{hyperref}\n";
	    print OUTPUT_TEX "\\pdfcompresslevel9\n";
	    print OUTPUT_TEX "\\pdfadjustspacing=1\n"; # espaciado como LaTeX 
	  } 
	elsif (/\\includegraphics/ || /\\epsfbox/) # ficar co argumento
	  {
	    /{([^}]*)}/;
	    $argumento=$1; 
	    $argumento=~s/\.eps//; 
	    $argumento=~s/\.ps//; 
	    $argumento=~s/\./-/; # pdflatex falha se hai pontos no nome
	    $argumento=~s/$/.pdf/; 
	    
	    print OUTPUT_TEX "\\includegraphics{$argumento}\n";
	    push(@pdf_files,$argumento);
	  }
	else
	  {
	    print OUTPUT_TEX;
	  }
      }
  }
close(OUTPUT_TEX); 
close(INPUT_TEX);

# 2) Criar preâmbulo robusto para usar nos ficheiros de imagem individuais
#    Basicamente, copia-se todo menos o estilo

open(PREAMBLE,">$preamble") || die;
open(INPUT_TEX,"$input_tex") || die;
while (<INPUT_TEX>) 
  {
    if (!/\\pagestyle/ && !/\\begin{document}/) 
      {
	print PREAMBLE;
      }
    last if /\\begin{document}/
  }
close(INPUT_TEX); 
close(PREAMBLE); 

# 3) Extrair os \includegraphics[]{} e similares para ficheiros 
# individuais .tex cos nomes ajeitados e criar o script final

open(SCRIPT,">$script") || die; # abrir o script final

$count=1;

open(INPUT_TEX,"$input_tex") || die;
while (<INPUT_TEX>) 
  {
    s/\%.*$//;
    $tmp="_tmp$count.tex";
    if (/\\begin{figure/) # deixo assi porque existe figure e figure*
      {
	print "Generating $tmp...\n";
	open(FILE_TEX,">$tmp") || die;
	
	## Incluir preamble robusto
	open(PREAMBLE,"$preamble");
	while ($pre=<PREAMBLE>)
	  {
	    print FILE_TEX $pre;
	  }
	close(PREAMBLE);
	print FILE_TEX "\\pagestyle{empty}\n"; 
		
	## Corpo, incluíndo todas as imagens dentro de figure
	## separadas em páginas distintas para poder processá-las
	## depois com psselect
	
	print FILE_TEX "\\begin{document}\n";                  
	print FILE_TEX "\\onecolumn\n"; 

	while (<INPUT_TEX>) 
	  {
	    if (/\\psfrag/) 
	      {
		print FILE_TEX;
	      }
	    elsif (!/\%/ && (/\\includegraphics/ || /\\epsfbox/))
	      {
		print FILE_TEX;
		chop;
		s/ //;
		print "Processing $_: ";
		
		/{([^}]*)}/;
		$argumento=$1;
		
		@filename=split(/\//,"$argumento");
		$nome=pop(@filename);
		
		# quitar possíveis terminaçons .eps ou .ps
		$nome=~s/\.eps//;
		$nome=~s/\.ps//;
		$nome=~s/\./-/;
		$argumento=~s/\.eps//;
		$argumento=~s/\.ps//;
		$argumento=~s/\./-/;
		
		print "$nome\n";
		push(@nomes_tmp,$nome);
		push(@argumentos_tmp,$argumento);
		
		print FILE_TEX "\\newpage\n"; 	      
		print FILE_TEX "\\onecolumn\n"; 	      
		
	      }
	    last if (/\\end{figure/);
	  }
	
	print FILE_TEX "\\end{document}\n"; 
	close(FILE_TEX);
	
	## script que processará posteriormente os ficheiros individuais
	## usando ps2eps (dvips -E falha qual escopeta de feira nos 
	## bounding box)
	
	print SCRIPT "cp -f $ARGV[0].aux _tmp$count.aux\n";
	print SCRIPT "latex _tmp$count\n";
	print SCRIPT "dvips -Ppdf -o _tmp$count.ps _tmp$count.dvi\n";
	
	for ($k=1;$k<=$#nomes_tmp+1;$k++)
	  {
	    $v=$nomes_tmp[$k-1];
	    $w=$argumentos_tmp[$k-1];
	    print SCRIPT "psselect -p$k _tmp$count.ps | ps2eps -l -f > _$v.eps\n";    
	    print SCRIPT "epstopdf _$v.eps --outfile=$w.pdf\n";
	  }	  
	
	$#nomes_tmp=-1;
	$#argumentos_tmp=-1;
	
	$count++;
      }
  }
close(INPUT_TEX);
print SCRIPT "cp $ARGV[0].bbl _$ARGV[0].bbl\n";
print SCRIPT "cp $ARGV[0].aux _$ARGV[0].aux\n";
close(SCRIPT);

chmod 0755, $script;

# cleansing script: apaga todos os ficheiros gerados
$clean="_clean";
open(CLEAN,">$clean");
print CLEAN "\\rm _*\n"; 
for($k=0;$k<=$#pdf_files;$k++)
  {
    $v=$pdf_files[$k];
    print CLEAN "rm -f $v\n"; 
  }
close(CLEAN);
chmod 0755, $clean;

# executa _process_figures
$command="`pwd`/$script";
$exec=`$command`;
