#!/usr/bin/perl -w 

# this program is copyright 2004 by Vincent Fourmond
# you can modify and redistribute it under the terms of the Gnu public licence

use Getopt::Long qw(:config  bundling);

my $help = 0;
my $packages = "";
my $packages_add = "";
my $gv = 1;
my $doc_class = "article";
my $doc_option = "a4paper";
my $pre_beg_commands = "";
my $post_beg_commands = "\\pagestyle{empty}%\n";
my $keep_ps = 0;

# wether the extension of the target file is ps or eps.
my $eps_output = 0;

my $inputfile = 0;

my $force_special = 0;

my $keep = 0;

my $bbox = "gs";

my $dvips_options = "";
my $dvips_tmp_options = "";

my $pdf = 0;

my $help_text = <<"FIN_AIDE";
Usage: 
fig2ps [-h|--help]\tPrints this help
fig2ps [options] file.fig  Converts file.fig into ps using LaTeX for texts.
    --[no]gv runs or not gv at the end;
    --packages=pack1,pack2,... packages to be used
    --add=pack1,pack2,... supplementary packages to be used
    -k|--keep  wether to keep or not the temporary files
    --bbox=dvips|gs|a,b,c,d method for the bounding box
    --input=file use file as a TeX template (\\input file)
    --dvips=s optrions to go to dvips
    --[no]pdf wether fig2ps should produce ps or pdf output
    --eps wether the extension of the target file is eps or ps for postscript
    --keepps when producing pdf, tells to keep the intermediary ps file
    --[no]forcespecial forces every text object to be exported as special, that 
      is processed with LaTeX.

  See the man page for more details.
FIN_AIDE
    
 
###############################################################################
#############################  read config ####################################
###############################################################################


if ($0 =~ /pdf/ ){ $pdf = 1;}
if ($0 =~ /eps/ ){ $eps_output = 1;}


my $sysconfigfile = "/etc/fig2ps/fig2ps.rc";

my %conffilehash = ( 'PACKAGES' => \$packages, 'ADD' => \$packages_add,
		     'DOC_CLASS' => \$doc_class, 'DOC_OPTIONS' => \$doc_option,
		     'FORCE_SPECIAL' => \$force_special, 
		     'INPUT' => \$inputfile, 'GV' => \$gv);

if(-f $sysconfigfile) {
    readconfig($sysconfigfile,%conffilehash); 
}
else {
    print "Warning : the system-wide configuration file is missing\n";
}

my $persoconfigfile = $ENV{"HOME"}."/.fig2ps.rc";

if(-f $persoconfigfile) {
    readconfig($persoconfigfile,%conffilehash); 
}


GetOptions('help|h' => \$help,
	   'packages=s' => \$packages,
	   'add=s' => \$packages_add,
	   'gv!' => \$gv,
	   'keep|k' => \$keep,
	   'keepps' => \$keep_ps,
	   'bbox|b=s' => \$bbox,
	   'input|i=s' => \$inputfile,
	   'dvips=s' =>  \$dvips_tmp_options,
	   'pdf!' => \$pdf,
	   'eps' => \$eps_output,
	   'forcespecial!' => \$force_special
	   );

if ($help) { print $help_text;exit;}



my @Packages = (split (/,/,$packages));
my @Add =  (split (/,/,$packages_add));

my $header;

if($pdf)
{
    #for fonts !!
    push @Packages, "aeguill";
}

prepareTex();
 

my $file = $ARGV[0] or die "Usage: fig2ps file\n".
    "Run fig2ps --help to get more informations\n";

($pstmp = $file) =~ s/\.fig$/.fig2ps.tmp.ps/i;
($figtmp = $file) =~ s/\.fig$/.fig2ps.tmp.fig/i;
($pstmp2 = $file) =~ s/\.fig$/.fig2ps.tmp2.ps/i;
# we need to remove the spaces in the latex name, else it doesn' work at all
($textmp = $file) =~ s/\.fig$/.fig2ps.tmp.tex/i;
($logtmp = $file) =~ s/\.fig$/.fig2ps.tmp.log/i;
($auxtmp = $file) =~ s/\.fig$/.fig2ps.tmp.aux/i;
($dvitmp = $file) =~ s/\.fig$/.fig2ps.tmp.dvi/i;
if($eps_output) {
    ($psfile = $file) =~ s/\.fig$/.eps/i;
}
else {
    ($psfile = $file) =~ s/\.fig$/.ps/i;
}
($pdffile = $file) =~ s/\.fig$/.pdf/i;

# we need to remove the spaces in the latex name, else it doesn't work at all
# the same for dvi, log and  aux files...
$textmp =~ s/ /_/g;
$logtmp =~ s/ /_/g;
$auxtmp =~ s/ /_/g;
$dvitmp =~ s/ /_/g;
# we need it as well for pstmp, since it is included in the TeX file
$pstmp =~ s/ /_/g;


my $fig_file = $file;

if($force_special)
{
    $fig_file = $figtmp;
    make_special($file, $figtmp);
}

# added quoting of filenames (Bug#242463)
if(system "fig2dev -L pstex \"$fig_file\" > \"$pstmp\"")
{ 
    die "Problems with fig2dev pstex";
}

# added quoting of filenames (Bug#242463)
$commande = "fig2dev -L pstex_t -p \"$pstmp\" \"$fig_file\" |";

open PSTEX, $commande;
# added quoting of filenames (Bug#242463)
open TEX, "> $textmp";


my $tail = "\\end{document}\n";

print TEX $header;

while(<PSTEX>)
{
    print TEX;
}
print TEX $tail;
close PSTEX;
close TEX;

# added quoting of filenames (Bug#242463)
if(system "latex \"$textmp\"")
{
 die "Problems with LaTeX";
}

mkPS();

if($pdf)
{
    # added quoting of filenames (Bug#242463)
    system "epstopdf \"$psfile\" --outfile=\"$pdffile\"";
}


if(!$keep)
{
    print "Deleting temporary files...\n";
    unlink $figtmp,$pstmp,$pstmp2,$textmp,$dvitmp,$logtmp,$auxtmp;
    if($pdf) { unlink $psfile unless $keep_ps;};
}


if($gv )
{
    print "Starting gv\n";
    if($pdf) {
# added quoting of filenames (Bug#242463)
	system "gv \"$pdffile\"";
    }
    else {
# added quoting of filenames (Bug#242463)
	system "gv \"$psfile\"";
    }
}


###############################################################################
############################ make fig special #################################
###############################################################################

sub make_special {
    my $input = shift @_ or die "Not enough args";
    my $output = shift @_ or die "Not enough args";
    open IN, $input;
# added quoting of filenames (Bug#242463)
    open OUT, "> $output";
    while(<IN>)
    {
	if (/^4 /) # if this is a text
	{
	    my @data = split / +/;
	    if ($data[8] & 2) # already in special
	    {
		print OUT;
	    }
	    else {
		$data[8] ^= 2;
		print OUT  join ' ', @data;
	    }
	}
	else  	{
	    print OUT;
	}
    }

    close IN;
    close OUT;
}



###############################################################################
############################# prepare header ##################################
###############################################################################


sub prepareTex {

    if($inputfile) # use a common style
    {
	my $file = `kpsewhich $inputfile`;
	print $file;
	open FILE,$file;
	my @lines = <FILE>;
	close FILE;
	if(grep /\\documentclass/,@lines > 0) {
	    # we have already document class
	    $header = "\\input{$inputfile}\n";
	}
	else {
	    $header = "\\documentclass[".$doc_option.
		"]{".$doc_class."}\n";
	    $header.= "\\input{$inputfile}\n";
	}

	# adds the add packages, (Teteph...)
	foreach(@Add) {
	    if(/\[(\S+)\](\S+)/)
	    {
		$header .=  "\\usepackage[$1]{$2}\n";
	    }
	    else {
		my @_add = split ':';
		my $pack = pop @_add;
		if(@add> 0)
		{
		    $header.= "\\usepackage[".join(',',@add)."]{$pack}\n";
		}
		else 
		{
		    $header.= "\\usepackage{$_}\n";
		}
		
	    }
	}
	
	# for the use of colors...
	$header.= "\\usepackage{color}\n";
	if($pdf) {
	    $header.= "\\usepackage{aeguill}\n";
	}
	    
    }
    else # builds "by hand" the package list
    {
	$header = "\\documentclass[".$doc_option.
	    "]{".$doc_class."}\n";
	
	foreach(@Packages,@Add) {
	    if(/\[(\S+)\](\S+)/)
	    {
		$header .=  "\\usepackage[$1]{$2}\n";
	    }
	    else {
		my @add = split ':';
		my $pack = pop @add;
		if(@add> 0)
		{
		    $header.= "\\usepackage[".join(',',@add)."]{$pack}\n";
		}
		else 
		{
		    $header.= "\\usepackage{$_}\n";
		}
		
	    }
	}
	
    }
    $header.=  $pre_beg_commands."\n\\begin{document}".$post_beg_commands;
}
###############################################################################
############################# make PS #########################################
###############################################################################

 
sub mkPS {
    $dvips_options .= $dvips_tmp_options;
    if($pdf)
    {
	$dvips_options = "-Ppdf ".$dvips_options;
    }
    print "$bbox\n";
    if($bbox eq "dvips") # we are using the -E option of dvips 
	#to make a tight BB
    {
# added quoting of filenames (Bug#242463)
	if(system "dvips $dvips_options -E \"$dvitmp\" -o \"$psfile\"")
	{die "Problems with dvips" ;}
	print "Using divps for the bounding box\n";
    }
    else {
	my ($LLX, $LLY, $URX, $URY);
	if(system "dvips $dvips_options  \"$dvitmp\" -o \"$pstmp2\"")
	{die "Problems with dvips" ;}
	if($bbox eq "gs") { # we let gs compute the Bounding box
	    # we specify the paper size to be b0 so that there is no problems
	    # with outbound items
	    $commande = "gs -dNOPAUSE -q -sDEVICE=bbox -sPAPERSIZE=b0 ".
		"\"$pstmp2\" < /dev/null 2>& 1|";
	    open BBOX, $commande;
	    my $found = 0;
	    while(<BBOX>)
	    {
		if(/^\%+BoundingBox/)
		{
		   s/\%\%BoundingBox\: //;
		   ($LLX, $LLY, $URX, $URY) = split / /;
		   $found = 1;
	       }
	    }
	    close BBOX;
	    die "Problems with gs" unless ($found == 1);
	    # Ajout d'un pixel autour de la figure, pour le confort de la
	    # visualisation avec 'gv' (Alex).
	    --$LLX; --$LLY; ++$URX; ++$URY;
	}
	else {
	    ($LLX, $LLY, $URX, $URY) = split /,/,$bbox ;
	}
	open IN, $pstmp2;
	open OUT, ">" . $psfile;
	while (<IN>) {
	    if (/^\%+BoundingBox/) {
		print OUT "%%BoundingBox: $LLX $LLY $URX $URY\n";
	    }
	    else {print OUT}
	}
	close OUT;
	close IN;
	print "Using $LLX $LLY $URX $URY for the bounding box\n";
    }
}



###############################################################################
############################ read config files ################################
###############################################################################


sub readconfig {
    my $file = shift @_;
    my %options = @_;

    open CONFIG, "$file";
    my $line = 0;
    while(<CONFIG>)
    {
	$line ++;
	while( /\\$/)
	{
	    chop;
	    chop;
	    $_.=<CONFIG>;
	}
	if ((!/^\#.*$/) && (!/^\s*$/) )
	{
	    (my $name, my $vals) = /(\S*)\s*=\s*(\S*)$/;
	    if((grep /$name/,keys(%options)) > 0)
	    {
		${$options{$name}} = $vals;
	    }
	    else {
		print "Warning : line ".$line." of file ".
		    $file." not understood\n";
	    }
	}
    }
    close CONFIG;
}






