#!/usr/bin/perl 
use Getopt::Long;

##### ##### ##### ##### ##### ##### ##### ##### 
#####
##### but : recoit en argument un nom ".jps", le traite et l'imprime 
##### sur la sortie standard ou sur le fichier ".ps" associe
#####
##### ##### ##### ##### ##### ##### ##### ##### 

$pi = 3.14159265358979;

############################################
###                                      ###
###           no de version              ###
###                                      ###
############################################

$version = "jps2ps version 0.019, 27 mai 2008";

############################################
###                                      ###
### localisation des differents fichiers ###
###                                      ###
############################################

## tentative pour reperer automatiquement la localisation du script

$montest = `ps a`;
$montest =~ s/([^\n]*jps2ps[^ ]*)//;
$montest = $1;
$montest =~ s/([^ ]*jps2ps[^ ]*)//;
$montest = $1;
## print (STDOUT "resultat :\n$montest \n");
$ok = 1;
$i = 0;
while ($ok and ($i < 10)) {
##    print (STDOUT "Passage...\n");
    $localisation = `ls -l $montest`;
##     print (STDOUT "$localisation\n");
    if ($localisation =~ /^l/) {
## 	print (STDOUT "c'est un lien\n");
	$montest = $localisation;
	$montest =~ s/.*-> //;
## 	print (STDOUT "$montest\n");
	$i++;
    } else {
	$ok = 0;
    }
}
### le repertoire d'installation de jps2ps
if (($i < 9) and ($montest =~ /jps2ps/)) {
    $montest =~ s/jps2ps\.pl//;
    $montest =~ s/\n//g;
##     print (STDOUT "finle : $montest\n");
    $JPS2PS_DIR = "$montest";
} else {
## on n'a pas reussi a trouver, on utilise la donnee "en dur"
    $JPS2PS_DIR = "/opt/syracuse/app/jps2ps/";
}

### le repertoire d'installation de BBgraf 
$BBGRAF_DIR = "/var/www/syracuse/bbgraf/";

##$JPS2PS_DIR = "/opt/syracuse/app/jps2ps/";

############################################
###                                      ###
### lecture de la ligne de commande      ###
###                                      ###
############################################

## but : analyse les arguments recus
## 5 arguments pris en compte : -a, -pst, -lpst, -i, et le nom du fichier

##print "@ARGV \n";     ## la liste des arguments
$nbarg = $#ARGV;  ## le nb d'arguments

$source = "-";
$sortieimposee = 0;
$sortielpst = 0;
$sortiepst = 0;

## on recupere le nom du  source
## ce doit etre la derniere chaine de la ligne de commande, et il ne doit
## pas commencer par un tiret.  s'il n'y a rien, on lit l'entree
## standard. rque : si on tape 'jps2ps -i ok.txt -i noh', le source lu
## sera 'noh.jps', ce qui n'est pas le but. Il faut alors taper 'jps2ps
## -i=ok.txt -i=noh'

for $i (0 .. $nbarg) {
    $argument = $ARGV[$i];
    if ($argument !~ /^-/) {
        $source = $argument;
        ## si le nom de fichier n'a pas de suffixe, on rajoute '.jps'
        if ($source !~ /\./) {
            $source = $source . "\.jps";
        };
    }
}

## print ("jps2ps : $source\n");

GetOptions (
   "i=s" => \@includefile,
##    "o" => \$fichiersortie,
##    "s" => \$fichiersource,
   "v" => \$demandeversion,
   "a" => \$sortieimposee,
   "pst" => \$sortiepst,
   "lpst" => \$sortielpst,
);

if ($demandeversion) {
    print (STDOUT "$version\n");
    exit (0);
}

##$source = "@ARGV[0]";

require $JPS2PS_DIR . "labels.pl";     ## les labels TeX
require $JPS2PS_DIR . "listpps.pl";    ## les fichiers .pps 
require $JPS2PS_DIR . "priorite.pl";   ## le tableau des ordres de priorite
require $JPS2PS_DIR . "dephash.pl";    ## le hachage des dependances
##require $JPS2PS_DIR . "exp2rpn.pl";    ## polonaise inverse -> cartesien
$exp2rpn = $JPS2PS_DIR . "exp2rpn.pl -v'a b c d e f g h i j k l m n o p q r s t u v w x y z xmin xmax ymin ymax tmin tmax pi' ";
$filtre = $JPS2PS_DIR . "filtre-file.pl";

##### ##### ##### ##### ##### ##### ##### ##### 
#####
##### les instructions traitees a part (valeurs par defaut)
#####
##### ##### ##### ##### ##### ##### ##### ##### 

sub init_vars {
   $xmin_str = "/xmin -6 def\n";
   $xmax_str = "/xmax 6 def\n";
   $ymin_str = "/ymin -6 def\n";
   $ymax_str = "/ymax 6 def\n";
   $border_str = "/border 7.5 def\n";
   $xmin = -6;
   $xmax = 6;
   $ymin = -6;
   $ymax = 6;
   $border = 7.5;
   $rotate = 0;
   $angle_repere = 90;
   $xunit = 0;
   $yunit = 0;
   $generic = 0;
   $autocrop = 0;
   ## $width = 0;
   ## $height = 0;
   
   $width_str = "/width 250 def\n";
   $height_str = "/height 250 def\n";
};

init_vars;
## $width_str = "";
## $height_str = "";

##### ##### ##### ##### ##### ##### ##### ##### 
#####
##### analyse du source .jps
#####
##### ##### ##### ##### ##### ##### ##### ##### 

## temoins pour les lectures de setxrange et setyrange
## = 1 si pas lu, et 0 si deja lu
$xtem = 1;
$ytem = 1;

$format = "";        ## initialisation du rapport width/height
$xyrapport = 1;      ## initialisation du rapport x/y

## lecture du source, et stockage ds le tableau @le_source
$i = 0;
## on lit d'abord les fichiers à inclure
if (defined @includefile) {
    foreach $file (@includefile) {
	open (FILE, $file) or die "ouverture du fichier $file impossible";
	while (<FILE>) {
	    $le_source [$i] = $_;
	    $i++;
	};
	close (FILE);
    }
}
## puis on lit le source
open (SRC, $source) or die "ouverture du fichier source $source impossible";
while (<SRC>) {
    $le_source [$i] = $_;
    $i = $i + 1;
};
close (SRC);

## ici, on traite la saisie des donnees pour le  calcul de la BB
## ainsi que le scan pour le traitement des dependances

foreach $line (@le_source) {
    $ligne = $line;
    ## on elimine les commentaires
    if ($ligne =~ /%/) {
        $ligne =~ s/%.*$//;
    };
    if ($ligne =~ /\t/) {
        $ligne =~ s/\t/ /g;
    };
    ## traitement des mots cles particuliers (format image)
    if ($ligne =~ /^autocrop/) {
	$autocrop = 1;
    };
    if ($ligne =~ /^[^[%]*make_generic/) {
	$generic = 1;
    };
    if ($ligne =~ /setunit/) {
          ($xunit = $ligne) =~ s/^([0-9-.]*) ([0-9.]*) .*[\n]?$/$1/;
          ($yunit = $ligne) =~ s/^([0-9-.]*) ([0-9.]*) .*[\n]?$/$2/;
    };
    if ($ligne =~ /setxunit/) {
           $xunit = $ligne;
           $xunit =~ s/ setxunit.*[\n]?$//;
    };
    if ($ligne =~ /setyunit/) {
           $yunit = $ligne;
           $yunit =~ s/ setyunit.*[\n]?$//;
    };
    if ($ligne =~ /setxrange[^3]/ and $xtem =~ 1) {
           $xmin_str = "";
           $xmax_str = "";
	   $xtem = 0;
           ($xmin = $ligne) =~ s/^([0-9-.]*) ([0-9.]*) .*[\n]?$/$1/;
           ($xmax = $ligne) =~ s/^([0-9-.]*) ([0-9-.]*) .*[\n]?$/$2/;
           $setxrange_str = $ligne;
    };
    if ($ligne =~ /setyrange[^3]/ and $ytem =~ 1) {
           $ymin_str = "";
           $ymax_str = "";
	   $ytem = 0;
           ($ymin = $ligne) =~ s/^([0-9-.]*) ([0-9.]*) .*[\n]?$/$1/;
           ($ymax = $ligne) =~ s/^([0-9-.]*) ([0-9-.]*) .*[\n]?$/$2/;
           $setyrange_str = $ligne;
    };
##     if ($ligne =~ /^\/xmin/) {
## 	   $xmin_str = $ligne;
## 	   ($xmin = $xmin_str) =~ s/\/xmin[ {]*(.*)[ }]*def.*\n/$1/
##     };
##     if ($ligne =~ /^\/xmax/) {
## 	   $xmax_str = $ligne;
## 	   ($xmax = $xmax_str) =~ s/\/xmax[ {]*(.*)[ }]*def.*\n/$1/;
##     };
##     if ($ligne =~ /^\/ymin/) {
## 	   $ymin_str = $ligne;
## 	   ($ymin = $ymin_str) =~ s/\/ymin (.*) def.*\n/$1/;
##     };
##     if ($ligne =~ /^\/ymax/) {
## 	   $ymax_str = $ligne;
## 	   ($ymax = $ymax_str) =~ s/\/ymax (.*) def.*\n/$1/;
##     };
##     if ($ligne =~ /^\/border /) {
## 	   $border_str = $ligne;
## 	   ($border = $border_str) =~ s/\/border (.*) def.*\n/$1/;
##     };
    if ($ligne =~ /setborder/) {
	$border_str = $ligne;
        ($border = $border_str) =~ s/ setborder.*[\n]?$//;
    };
    if ($ligne =~ /setxyrapport/) {
        $xyrapport = $ligne;
        $xyrapport =~ s/ setxyrapport.*[\n]?$//;
    };
    if ($ligne =~ /setformat/) {
        $format = $ligne;
        $format =~ s/ setformat.*[\n]?$//;
    };
    if ($ligne =~ /setrotate/) {
        $rotate = $ligne;
        $rotate =~ s/ setrotate.*[\n]?$//;
    };
    if ($ligne =~ /setangle_repere/) {
        $angle_repere = $ligne;
        $angle_repere =~ s/ setangle_repere.*[\n]?$//;
    };
##     if ($ligne =~ /^\/width/) {
## 	      $width_str = $ligne;
## 	      $width = $ligne;
## 	      $width =~ s/^\/width[ ]*(.*) def.*[\n]?$/$1/;
##     };
    if ($ligne =~ /setwidth/) {
           $width_str = $ligne;
           $width = $ligne;
           $width =~ s/ setwidth.*[\n]?$//;
    };
##     if ($ligne =~ /^\/height/) {
## 	      $height_str = $ligne;
## 	      $height = $ligne;
## 	      $height =~ s/^\/height[ ]*(.*) def.*[\n]?$/$1/;
##     };
    if ($ligne =~ /setheight/) {
           $height_str = $ligne;
           ($height = $ligne) =~ s/ setheight.*[\n]?$//;
    };

    ### puis traitement standard
    ###
    ## on elimine les commentaires

    if ($ligne =~ /%/) {
           $ligne =~ s/%.*$//;
    }
    if ($ligne =~ /\(|\)|{|}|!|\[|\]|\//) {
           $ligne =~ s/\(|\)|!|{|}|\[|\]|\// /g;
    }
    if ($ligne =~ /  /) {
           $ligne =~ s/  / /g;
    }    
   $ligne =~ s/\r\n//;
   $ligne =~ s/\n//;
   @contenu = split (/ /, $ligne); 
   foreach $mot (@contenu) {
        if ($mot =~ /[a-zA-Z]/) {
## modif 01/07/00   while ($mot =~ /[0-9]/) {$mot =~ s/[0-9]//;};
#modif 02/01/04#            if ($mot =~ /[0-9]/) {$mot =~ s/[0-9]//g;};
##            ### impression pour deboguage
##            print "%%%%% $mot=="."\n";
            ##### on fixe les dependances
            foreach $dep (@{ $dependances {$mot} }) {
               $besoin {$dep} = 1;
##               ### impression pour deboguage
##               print "%% === $dep\n";
            }
        }
   }
};
    
$besoin {AAA} = 1;
$besoin {AAAnode} = 1;
$besoin {AAAscale} = 1;
$besoin {mulv} = 1;
$besoin {addv} = 1;
#close FICHIER;

## ##### impression pour deboguage
## print "%%%%% ======= on trouve =======\n";
## print '%' x 80 . "\n";
## 
## foreach $word (@cles) {
##    print "%% " . "$word   " . $besoin {$word} . "\n";
## }

##### ##### ##### ##### ##### ##### ##### ##### 
##### 
##### Si necessaire, on calcule les donnees manquantes
##### 
##### ##### ##### ##### ##### ##### ##### ##### 

## ##### impression pour deboguage
## print "%% xmin = $xmin \n";
## print "%% xmax = $xmax \n";
## print "%% ymin = $ymin \n";
## print "%% ymax = $ymax \n";
## print "%% scale = $scale \n";
## print "%% width = $width \n";
## print "%% height = $height \n";
## print "%% xyrapport = $xyrapport"."\n";
## print "%% format = $format"."\n";
## print "%% xunit = $xunit"."\n";
## print "%% yunit = $yunit"."\n";
##  print "%% angle_repere = $angle_repere"."\n";
##  print "%% angle_repere = " . sin ($angle_repere * $pi / 180) ."\n";

$dx = $xmax - $xmin;
$dy = $ymax - $ymin; #* sin ($angle_repere * $pi / 180);

## les xunit et yunit sont prioritaires
if ($xunit != 0) {
    $width = $dx * $xunit;
    $width_str = "/width $width def\n";
};
if ($yunit != 0) {
    $height = $dy * $yunit;
    $height_str = "/height $height def\n";
};

## Ici, on a recupere toutes les donnees de format presentes dans le source jps. 
## Les variables xmin, xmax, ymin, ymax, border et xyrapport sont initialisees.

##### calcul des donnees manquantes pour la Bounding Box si necessaire 
##### on veut qu'il y ait au moins une des 2 variables $width et $height
##### qui soit initialisee

if ((not $width) and (not $height)) {
    if ($dx > $dy) {
	$height = 250;
    }
    else {
	$width = 250;
    }
}

if ($width and $height) {
    ## rien a faire
} 
elsif ($format) {
    if ($width) {
        ## on a $width et $format
        $height = $width / $format;
        $height_str = "/height $height def\n";
    } else {
        ## on a $height et $format
        $width = $height * $format;
        $width_str = "/width $width def\n";
    }
}
else {
    if ($width) {
        $height = $dy * sin ($angle_repere * $pi / 180) * $width / ($xyrapport * $dx);
        $height_str = "/height $height def\n";
    }
    else {
        $width = $height * ($xyrapport * $dx) / ($dy * sin ($angle_repere * $pi / 180));
        $width_str = "/width $width def\n";
    }
}

## ##### on impose egalement width et height < 1000 pour eviter des problemes
## ##### lors de la convertion au format jpeg par les ImageMagick
## if ($width > 1000) {
##     $width = 1000;
## };
## if ($height > 1000) {
##     $height = 1000;
## };

## ##### impression pour deboguage
## 
## print "%% xmin = $xmin \n";
## print "%% xmax = $xmax \n";
## print "%% ymin = $ymin \n";
## print "%% ymax = $ymax \n";
## print "%% scale = $scale \n";
## print "%% width = $width \n";
## print "%% height = $height \n";
## print "%% border = $border \n";
## print "%% xyrapport = $xyrapport"."\n";
## print "%% format = $format"."\n";

### les dimensions de la Bounding Box
### (probleme ici si border, width ou height n'ont pas ete lus correctement)

$bbx = $width + 2 * $border;
$bby = $height + 2 * $border;
### puis on tronque
$bbx = int ($bbx);
$bby = int ($bby);

sub max {
    my ($x, $y) = @_;
    if ($x>$y) {
	return ($x);
    } else {
	return ($y);
    }
}

sub min {
    my ($x, $y) = @_;
    if ($x > $y) {
	return ($y);
    } else {
	return ($x);
    }
}

$alpha = $rotate * ($pi / 180);

## print ("bbx : $bbx\n");
## print ("bby : $bby\n");
## print ("rotate : $rotate,\n");
## print (sin ($alpha) . "\n");

$dlx = min (-$bby * sin ($alpha), 0);
$dlx = min ($dlx, $bbx * cos ($alpha));
$dlx = min ($dlx, $bbx * cos ($alpha) - $bby * sin ($alpha));
$dly = min ($bby * cos ($alpha), 0);
$dly = min ($dly, $bbx * sin ($alpha));
$dly = min ($dly, $bbx * sin ($alpha) + $bby * cos ($alpha));

$dlx = int ($dlx);
$dly = int ($dly);

## print ("dlx : $dlx\n");
## print ("dly : $dly\n");

$urx = max (-$bby * sin ($alpha), 0);
$urx = max ($urx, $bbx * cos ($alpha));
$urx = max ($urx, $bbx * cos ($alpha) - $bby * sin ($alpha));
$ury = max ($bby * cos ($alpha), 0);
$ury = max ($ury, $bbx * sin ($alpha));
$ury = max ($ury, $bbx * sin ($alpha) + $bby * cos ($alpha));

$urx = int ($urx);
$ury = int ($ury);

## print ("urx : $urx\n");
## print ("ury : $ury\n");

### la relative Bounding Box par rapport a l'origine du repere (utile pour PSTricks)
$botx = ($xmin * $width) / ($xmax - $xmin) - $border ;
$boty = ($ymin * $height) / ($ymax - $ymin) - $border ;
$topx = ($xmax * $width) / ($xmax - $xmin) + $border ;
$topy = ($ymax * $height) / ($ymax - $ymin) + $border ;
### puis on tronque
$botx = (int ($botx * 100)) / 100;
$boty = (int ($boty * 100)) / 100;
$topx = (int ($topx * 100)) / 100;
$topy = (int ($topy * 100)) / 100;
## print "%% botx = $botx \n";
## print "%% boty = $boty \n";
## print "%% topx = $topx \n";
## print "%% topy = $topy \n";
### unites pour PSTricks
$PSTxunit = (int (($width / $dx) * 100)) / 100 ;
$PSTyunit = (int (($height / $dy) * 100)) / 100 ;
### placement de la boite pour epsfbox dans PSTricks
$PSTOx = $xmin + ($dx/2);
$PSTOy = $ymin + ($dy/2);

##### ##### ##### ##### ##### ##### ##### ##### 
##### 
##### Impressions pour PSTricks
##### 
##### ##### ##### ##### ##### ##### ##### ##### 

if ($sortiepst or $sortielpst) {
    $dimptx = $bbx;
    $dimpty = $bby;
    ## on la calcule en mm
    $dimx = ($dimptx / 72.27) * 25.4;
    $dimy = ($dimpty / 72.27) * 25.4;
    ### puis on tronque
    $dimx = (int ($dimx * 100)) / 100;
    $dimy = (int ($dimy * 100)) / 100;
    print "%% xsize: $dimx mm, $dimptx pt\n";
    print "%% ysize: $dimy mm, $dimpty pt\n";
    print "\\psset{unit=1pt}\n";
    if ($sortiepst) {
    	print "\\pspicture($botx,$boty)($topx,$topy)\n";
    	print "\\psset{xunit=$PSTxunit,yunit=$PSTyunit}\n";
    	print "\\rput($PSTOx,$PSTOy){\\epsfbox{img}}\n";
    	print "\\endpspicture\n";
    }
    else {
    	print "\\begin{pspicture}($botx,$boty)($topx,$topy)\n";
    	print "\\psset{xunit=$PSTxunit,yunit=$PSTyunit}\n";
    	print "\\rput($PSTOx,$PSTOy){\\includegraphics{img}}\n";
    	print "\\end{pspicture}\n";
    }
}

##### ##### ##### ##### ##### ##### ##### ##### 
##### 
##### On selectionne la sortie
##### 
##### ##### ##### ##### ##### ##### ##### ##### 

if ((not $autocrop) and $sortieimposee) {
    $sortie = $source;
    $sortie =~ s/\.jps/\.ps/;
    open (SORTIE, ">$sortie") or die "ouverture du fichier $sortie impossible";
    select (SORTIE);
}
if ($autocrop) {
#   $tmp_sortie = $JPS2PS_DIR . "tmp/$$.ps";
#   $log = $JPS2PS_DIR . "tmp/$$.log";
   $tmp_sortie = "/tmp/$$.ps";
   $log = "/tmp/$$.log";
   open (SORTIE, ">$tmp_sortie") or die "ouverture du fichier $tmp_sortie impossible";
   select (SORTIE);
}

##### ##### ##### ##### ##### ##### ##### ##### 
##### 
##### On imprime les en-tetes et le minimum
##### 
##### ##### ##### ##### ##### ##### ##### ##### 

print "%!PS-Adobe-3.0 EPSF \n";

sub affiche_en_tete_BB {
   print "%%Title:  \n";
   print "%%Creator: $version \n";
   print "%%Pages:  1 \n";
   ## print "%%BoundingBox: 0 0 $bbx $bby \n";
   print "%%BoundingBox: $dlx $dly $urx $ury \n";
};

sub affiche_en_tete_suite {
   print "%%Pspicture: ($botx,$boty)($topx,$topy)\n";
   print "%%PSTunit: xunit=$PSTxunit,yunit=$PSTyunit\n";
   print "%%OriginePspicture: ($PSTOx,$PSTOy)\n";
   print "%%EndComments \n";
   print "%%Page: 1 1\n";
};

if (not $autocrop) {
    affiche_en_tete_BB;
}
# &affiche_en_tete;
&affiche_en_tete_suite;

##### ##### ##### ##### ##### ##### ##### ##### 
##### 
##### On ouvre 2 nouveaux dictionnaires
##### 
##### ##### ##### ##### ##### ##### ##### ##### 

print "/Pictdic 50 dict def Pictdic begin \n";
print "/jpsdic 500 dict def \n";
print "gsave \n";
print "jpsdic begin \n";
print "/pathdict 4 dict def \n";
print "/setrotate {pop} def\n";
print "/setformat {pop} def\n";
print "/setxyrapport {pop} def\n";
print "$rotate rotate\n";

##### ##### ##### ##### ##### ##### ##### ##### 
##### 
##### On imprime les cles particulieres
##### 
##### ##### ##### ##### ##### ##### ##### ##### 

print ("%%%%%%%%%%%%%%%%%%%% la BoundingBox %%%%%%%%%%%%%%%%%%%%%\n");

if ($besoin {setwidth}) {
    print (`cat ${setwidth}`);
    }
if ($besoin {setheight}) {
    print (`cat ${setheight}`);
    }
if ($besoin {setborder}) {
    print (`cat ${setborder}`);
    }
print $width_str;
print $height_str;
print $border_str;

print ("%%%%%%%%%%%%%%%% les bornes sur les axes %%%%%%%%%%%%%%%%\n");

print $xmin_str;
print $xmax_str;
print $ymin_str;
print $ymax_str;

if ($besoin {setxrange}) {
    print (`cat ${setxrange}`);
    print $setxrange_str;}
if ($besoin {setyrange}) {
    print (`cat ${setyrange}`);
    print $setyrange_str;}

print ("/angle_repere " . $angle_repere . " def\n");
## print `cat $mulv`;
## print `cat $addv`;
## print `cat $base_01`;
## print `cat $base_02`;
## print `cat $math`;
## print `cat $masque`;
#print ("masque\n");

## print ("newpath\n");
## print ("$border $border moveto\n");
## print ($bbx-2*$border . " 0 rlineto\n");
## print ("0 " . $bby-2*$border . " lineto\n");
## print (-$bbx+2*$border . " 0 rlineto\n");
## print ("closepath\n");
## print ("clip\n");

## ##### impression pour deboguage
## 
## print "%%%% le test : $dependances{xtick}[0] \n";
## 
## print "%" x 20 . " mots cles recherches " . "=" x 20 . "\n";
## 
## foreach $word (@cles) {
##     print "%%% $word\n";                                 ## le mot cle
##     print "%%%    ==> "."@{ $dependances {$word} }"." \n";   ## le tableau des dependances
##     print "%%%    ==> ";
##     foreach $dep (@{ $dependances {$word} }) {               ## les elts du tableau des deps
##     print "$dep ";}
##     print "\n";
## }
## 
## print "=" x 40 . "\n";

##### ##### ##### ##### ##### ##### ##### ##### 
#####
##### impression pour deboguage
#####
##### ##### ##### ##### ##### ##### ##### ##### 

### print "\n";
### 
### ## 
### ## 
## print "%%%%% ======= on trouve =======\n";
## print '%' x 80 . "\n";
## 
## foreach $word (sort (@cles)) {
##    print "%% " . "$word   " . $besoin {$word} . "\n";
## }

##### ##### ##### ##### ##### ##### ##### ##### 
#####
##### routine d'affichage du source jps
#####
##### ##### ##### ##### ##### ##### ##### ##### 

sub affiche_source_jps {
   ##### puis on imprime le source ## en omettant les cles particulieres
#   open (FICHIER, $source) or die "ouverture du fichier $source impossible";
   
   ## while (<FICHIER>) {
   ##     if (not ($_ =~ /^\/(xmin|xmax|ymin|ymax)/)) {print $_;};
   ## }
   
   $label_en_cours = 0;
   $label_tex = "";

   $expr_en_cours = 0;
   $expr_cart = "";

   print ("\n" . "%"x20 . " debut du code jps " . "%"x20 . "\n");
   
   foreach $ligne (@le_source) {
   #while ($ligne = <FICHIER>) {
       if (($ligne =~ /^<tex>/) or ($ligne =~ /^<latex>/)) {
   	   $label_en_cours = 1;
       };
       if ($ligne =~ /^#rpn#/) {
#           open (LOG, ">/var/www/syracuse/bbgraf/tmp/jps2ps.log") or die "ouverture du fichier log impossible"; 
#	   print (LOG "$ligne....\n");
   	   $ligne =~ s/\#rpn\#//;
   	   $ligne =~ s/\n//g;
   	   $ligne =~ s/[^a-zA-Z0-9\+\*\-\^\/\^\(\)\.,;]//g;
	   print (LOG "apres la manip : " . "$ligne" . "____\n");
#	   close (LOG);
#	   $ligne = &exp2rpn ($ligne) . "\n";
	   $ligne = `$exp2rpn ' $ligne'` . "\n";
       };
       if ($ligne =~ /^#inc#/) {
   	   $ligne =~ s/#inc#//;
	   print (`cat $ligne`);
	   $ligne = "";
       };
       if ($ligne =~ /^#tex#/) {
   	   $ligne =~ s/#tex#//;
#	   print (STDOUT $ligne);
   	   ($inclusion, $dim_label, @tablefont) = &traite_label ("<tex>\n" . "$ligne", @tablefont);
   	   print ($inclusion);
   	   print ($dim_label);
	   $ligne = "";
       };
       if ($ligne =~ /^#latex#/) {
   	   $ligne =~ s/#latex#//;
#	   print (STDOUT $ligne);
   	   ($inclusion, $dim_label, @tablefont) = &traite_label ("<latex>\n" . "$ligne", @tablefont);
   	   print ($inclusion);
   	   print ($dim_label);
	   $ligne = "";
       };
       if (not $label_en_cours){
   	   print ($ligne);
       } else {
   	   $label_tex = $label_tex . $ligne;
       };
       if (($ligne =~ /^<\/tex>/) or ($ligne =~ /^<\/latex>/)) {
   	   $label_en_cours = 0;
   	   ($inclusion, $dim_label, @tablefont) = &traite_label ($label_tex, @tablefont);
   	   print ($inclusion);
   	   print ($dim_label);
   	   $label_tex = "";
       };
   }
   print ("\n" . "%"x20 . " fin du code jps " . "%"x20 . "\n");
};

##### ##### ##### ##### ##### ##### ##### ##### 
#####
##### puis on imprime ce dont on a besoin
#####
##### ##### ##### ##### ##### ##### ##### ##### 

if ($generic) {
   foreach $word (sort (@cles)) {
       print ("%======= fichier $word =========\n");
       print (`cat ${$word}`);
   }
   print ("%"x20 . " debut du preliminaire pour generique " . "%"x20 . "\n");
   print ("/make_generic {} def\n");
   print ("setTimesRoman\n");

   print ("(fichier générique, $version) O show_dim ptojpoint pop /b exch def pop /a exch def pop pop\n");
   print ("(fichier générique, $version) xmin ymin xmax ymax milieu [xmax xmin sub .9 mul b a sub div dup] cctext\n");
#   print ("(fichier générique, $version) O [xmax xmin sub .9 mul b a sub div dup] cctext\n");
   print "\n";
   print ("%"x20 . " fin du preliminaire pour generique " . "%"x20 . "\n");
} else {
   foreach $word (sort (@cles)) {
      if ($besoin {$word}) {
          print ("%% ======== fichier $word ======== %%\n");
          print ("%% ======== ${$word} ======== %%\n");
          print (`cat ${$word}`);
      };
   }
   print "\n";
   print ("newpath\n");
   print ("   xmin ymin smoveto\n");
   print ("   xmax ymin slineto\n");
   print ("   xmax ymax slineto\n");
   print ("   xmin ymax slineto\n");
   print ("   closepath\n");
   print ("clip\n");
   ## encore un truc en dur : si "camview" est utilise, on calcule 
   ## la position par defaut de la camera
   if ($besoin {camview}) {
       print (`cat $camview_default`)} 
};

&affiche_source_jps;

sub affiche_conclusion {
   ##### et la conclusion
   print "\n";
   print "end\n";      ### fermeture du dictionnaire principal
   print "grestore\n";
   print "end\n";      ### fermeture du dictionnaire Pictdic
   print ("showpage\n");
   print ("%%Trailer\n");
   print ("%%EOF\n");
};

&affiche_conclusion;

if ($sortieimposee) {
    close (SORTIE);
}

if ($autocrop) {
   close (SORTIE);

   ## lecture du fichier de sortie, et stockage ds le tableau @la_sortie
   $i = 0;
   open (SRC, $tmp_sortie) or die "ouverture du fichier $source impossible (autocrop)";
   while (<SRC>) {
       $la_source [$i] = $_;
       $i = $i + 1;
   };
   close (SRC);
   
   `gs -sDEVICE=bbox -dNOPAUSE -dBATCH -q $tmp_sortie &> $log`;
   $bbox = `cat $log | grep "%%BoundingBox"`;
   
   
   ## on nettoie les fichiers temporaires
   print (`rm $tmp_sortie`);
   print (`rm $log`);

   if ($sortieimposee) {
       $sortie = $source;
       $sortie =~ s/\.jps/\.ps/;
       open (SORTIE, ">$sortie") or die "ouverture du fichier $sortie impossible";
       select (SORTIE);
   } else {
       select (STDOUT);
   };
   
   print "%!PS-Adobe-3.0 EPSF \n";
   print "%%Title:  \n";
   print "%%Creator: $version \n";
   print "%%Pages:  1 \n";
   ## print "%%BoundingBox: 0 0 $bbx $bby \n";
   #print "%%BoundingBox: $dlx $dly $urx $ury \n";
   #print "%%DocumentNeededResources: font Courier \n";
   #print "%%+ font Times-Roman \n";
   $ligne = $bbox;
   $ligne =~ s/%%BoundingBox: //;
   ($llx, $lly, $uux, $uuy) = split (/ /, $ligne);
#   print "$bbox";
   $llx = $llx - $border;
   $lly = $lly - $border;
   $uux = $uux + $border;
   $uuy = $uuy + $border;
   print "%%BoundingBox: $llx $lly $uux $uuy \n";

   foreach $ligne (@la_source) {
       print ($ligne);
   };
};

exit (0);
