2
0
Fork 0
Verif_Herezh/Perl/genere_catalogue_tests.pl

1003 lines
43 KiB
Perl
Executable file
Raw Blame History

#!/usr/bin/perl -s
use strict;
use warnings;
use File::Basename;
use English;
use Encode;# package encodage fichier texte
use Cwd; # package pour connaitre le repertoire courant
use File::Spec::Functions qw(splitpath rel2abs);#($volume, $rep, $fic) = splitpath($path); $absolute_path = rel2abs($relative_path)
use File::Temp qw/ cleanup /;#creation d un repertoire temporaire qui s efface automatiquement en sortie de programme => my ($handle, $nom_rep) = File::Temp->newdir(TEMPLATE => "toto_XXXX");
#fonction cleanup() => appel a cleanup() pour forcer la destruction des repertoires et fichier temporaires
my $NOM_PROG = basename $PROGRAM_NAME;#$NOM_PROG contient le nom de ce script (utile pour afficher le nom du script dans les warning (warn) ou les messages d erreur (die) )
#pattern d un reel pour les regex (pour eviter d utiliser $RE{num}{real} du package Regexp::Common qui n est pas toujours disponible)
my $format_reel = '[+-]?[\.]?\d+[\.]?\d*(?:[eE][+-]?\d*)?';
#####################################################################################################
# script pour generer automatiquement un document pdf qui resume les tests
# disponibles (recopie des rubriques "But du test" et "Description du calcul" du
# fichier README de chaque repertoire de test)
#
#
# Notes a tout le monde :
# une rubrique est un bloc contenu dans un fichier README sous la forme :
# une ligne de tirets
# nom de la rubrique
# une ligne de tirets
# ...
# ...
# une suite de lignes (vides ou non)
# ...
#
# IMPORTANT : ce script repere la fin d une rubrique par la presence d une autre ligne de tirets (ou la fin du fichier)
# ce qui veut dire que toute ligne de tirets (hormis les lignes qui encadrent le nom de la rubrique) met fin a la lecture
# de la rubrique.
# En vue des eventuels risques de fin de lecture prematuree, la variable $MOTIF_FIN_RUBRIQUE a ete definie au cas ou le
# besoin se fait sentir de definir clairement une balise de fin de rubrique (la valeur actuelle de cette variable etant
# pour l instant ecrite de maniere a reperer une ligne de tirets).
#
#
# Notes aux utilisateurs :
# - les repertoires de tests sont recherches dans toute l arborescence depuis l endroit ou
# ce script est lance (recherche de tous les repertoires commencant par Test_R ou Test_L)
# A noter que si un des repertoires ne contient pas de fichier README, le script s arrete sans
# creation du .pdf. De meme, si l un des fichiers README ne contient pas la rubrique "But du test"
# ou "Description du calcul". Cette securite a ete mise pour obliger a tenir a jour les README,
# evitant ainsi l oubli de certains tests dont le README n aurait pas ete cree ou mal cree.
# - A noter egalement que les repertoires vides vont provoquer l arret du programme. Il s agit des
# repertoires de tests qui ont ete supprimes de la base CVS mais dont la presence persiste. Comme
# ils sont vides, il n y a pas de README d ou l arret du programme. Pour supprimer,
# ces repertoires vides, il suffit de faire "cvs update -dP" ou bien utiliser l option -P a l import du
# projet "cvs co -P Verif_Herezh"
#
# Notes aux developpeurs :
# - le choix de ne pas generer de pdf a la moindre defaillance d un fichier README a pour
# but de forcer a rendre conforme les fichiers README. Une ecriture partielle du fichier
# pdf en omettant les README defaillants pourrait conduire a un oubli de certains tests.
# - l une des plus grandes difficultes est l encodage des fichiers pour gerer les accents.
# le choix d encodage est impose par la variable $ENCODAGE_TEX
# (en cas de gros probleme, la meilleure solution est de supprimer/remplacer les caracteres
# les plus problematiques des fichiers README)
# - c est difficile d anticiper ce que les gens vont ecrire dans les fichiers README.
# un certain nombre de caracteres ou de groupes de caracteres ne sont pas directement utilisables
# dans un fichier .tex
# (par exemple : <, >, _, etc... ou bien encore les exposants ^3.14159265)
# Le plus souvent, ce script rajoute des dollars autour des caracteres problematiques mais
# cette action ne resoud pas tous les problems.
# La gestion de ces caracteres se fait au cas par cas dans la subroutine translate_to_latex()
# au niveau du bloc "A FAIRE EVOLUER" (par substitution de caracteres s///g)
#####################################################################################################
######################################################################################################
#
# PARAMETRES
#
######################################################################################################
#--------------------------------------------------------------------------------
#nom du fichier catalogue de tests
#--------------------------------------------------------------------------------
my $NOM_PDF_CATALOGUE = "catalogue_tests.pdf";
#--------------------------------------------------------------------------------
#encodage du fichier .tex temporaire (rq : notamment pour accepter les accents)
#--------------------------------------------------------------------------------
my $ENCODAGE_TEX = 'iso-8859-15';
#--------------------------------------------------------------------------------
#concernant fichiers README :
#--------------------------------------------------------------------------------
#--liste des rubriques a recopier de chaque README (rq : insensible a la casse)
my @LISTE_RUBRIQUES_README = ('But du test',
'Description du calcul');
#--nom de la rubrique contenant des mots-cles (rq : insensible a la casse)
my $NOM_RUBRIQUE_MOTS_CLES = 'Mots-cles';
#--nom de la rubrique contenant le ou les auteurs d un test (rq : insensible a la casse)
my $NOM_RUBRIQUE_AUTEUR = 'Auteur';
#--motif pour reperer la fin d une rubrique (la recherche de fin de rubrique sera de la forme : ... =~ /^\s*$MOTIF_FIN_RUBRIQUE\s*$/ )
my $MOTIF_FIN_RUBRIQUE = '---+';#motif actuel : une suite d au moins 3 tirets
#########################################################################################################
# verifications prealables
#########################################################################################################
#verif validite de l encodage $ENCODAGE_TEX
@_ = grep {/^$ENCODAGE_TEX$/i} Encode->encodings(":all");
($#_ > -1) or die "\nErreur (prog:$NOM_PROG) : encodage $ENCODAGE_TEX non disponible (changer la variable \$ENCODAGE_TEX dans l en-tete de ce script)...\n\n";
$ENCODAGE_TEX = $_[0];
#verif validite de la commande pdflatex
verif_commande('pdflatex') or die "\nErreur (prog:$NOM_PROG) : commande pdflatex introuvable...\n\n";
#-verif validite de l option -halt-on-error de la commande pdflatex
@_ = qx(pdflatex -help | grep -- -halt-on-error);
($#_ > -1) or die "\nErreur (prog:$NOM_PROG) : commande pdflatex => option -halt-on-error non existante...\n\n";
#verif validite de la commande makeindex
verif_commande('makeindex') or die "\nErreur (prog:$NOM_PROG) : commande makeindex introuvable...\n\n";
#########################################################################################################
# liste des repertoires de test
#########################################################################################################
#liste des repertoires de tests rapides (Test_R)
my @REP_TESTS_R = map {chomp($_); $_} qx(find . -name "Test_R*" -type d);
#print "$_\n" for @REP_TESTS_R; exit;
#liste des repertoires de tests rapides (Test_R)
my @REP_TESTS_L = map {chomp($_); $_} qx(find . -name "Test_L*" -type d);
#print "$_\n" for @REP_TESTS_L; exit;
#########################################################################################################
# verification de la presence d un fichier README dans les tests rapides @REP_TESTS_R et les tests longs @REP_TESTS_L
#########################################################################################################
my $is_absence_README = 0;
foreach my $rep_test (@REP_TESTS_R,@REP_TESTS_L) {
(-e "$rep_test/README") or do {
warn "\n" if(not $is_absence_README);#on passe une ligne si c est le premier repertoire defaillant
warn "Erreur (prog:$NOM_PROG) : repertoire de test $rep_test ne contient pas de fichier README...\n";
$is_absence_README = 1;
};
}
#arret du programme si il y a absence d au moins 1 fichier README
if($is_absence_README) {
warn "\n";
afficher_ligne_tirets('warn');
warn "Erreur (prog:$NOM_PROG) : arret a cause de l absence de fichier(s) README\n";
afficher_ligne_tirets('warn');
die "\n";
}
#########################################################################################################
# generation du catalogue des tests au format .pdf
# rq : generation d un document latex puis d un document .pdf via pdflatex
# a la fin, seul le .pdf restera, tous les fichiers intermediaires seront effaces)
#########################################################################################################
#on va creer un repertoire temporaire qui est sense s effacer automatiquement grace a l utilisation de File::Temp->newdir
# le probleme est que si un signal d interruption est envoye (ctrl-c par exemple), le repertoire ne sera pas efface.
# donc, on va capturer certains signaux pour faire un appel a la subroutine sortie_programme()
$SIG{INT} = \&sortie_programme;#INT => capture signal : ctrl-c ou kill -2
$SIG{TERM} = \&sortie_programme;#TERM => capture signal : kill -15
#remarque : par essence, le signal kill -9 ne peut pas etre capture
#creation d un repertoire temporaire (... qui s effacera automatiquement en sortie de programme grace a l utilisation de la construction objet File::Temp->newdir()
my $REP_TMP = File::Temp->newdir("rep_tmp_".$NOM_PROG.'_XXXXX');
my $racine_fic_latex = "toto";
#deplacement vers le repertoire temporaire
chdir $REP_TMP;
#------------------------------------------------------------------------------------------
#creation du fichier .tex avec encodage $ENCODAGE_TEX (et debut du document : preambule)
#------------------------------------------------------------------------------------------
open(my $HANDLE_TEX, ">:encoding($ENCODAGE_TEX)", "$racine_fic_latex.tex");
preambule_fic_tex_tmp($HANDLE_TEX);
#------------------------------------------------------------------------------------------
#corps du texte (d abord les tests rapides, ensuite les tests longs)
#------------------------------------------------------------------------------------------
#--- tests rapides ---
afficher_ligne_tirets('print');
print " TESTS RAPIDES\n";
afficher_ligne_tirets('print');
sleep 1;#petite pause pour laisser a l utilisateur le temps de voir l affichage precedent
print $HANDLE_TEX "\\clearpage\n";
print $HANDLE_TEX "\\section{Tests rapides}\n";
recopie_README("R", $HANDLE_TEX, \@REP_TESTS_R, @LISTE_RUBRIQUES_README);
#--- tests longs ---
afficher_ligne_tirets('print');
print " TESTS LONGS\n";
afficher_ligne_tirets('print');
sleep 1;#petite pause pour laisser a l utilisateur le temps de voir l affichage precedent
print $HANDLE_TEX "\\clearpage\n";
print $HANDLE_TEX "\\section{Tests longs}\n";
recopie_README("L", $HANDLE_TEX, \@REP_TESTS_L, @LISTE_RUBRIQUES_README);
#------------------------------------------------------------------------------------------
#fin de l ecriture du fichier .tex
#------------------------------------------------------------------------------------------
#ajout de l index (ajout egalement dans le sommaire sans numerotation)
print $HANDLE_TEX "\\clearpage\n";
print $HANDLE_TEX "\\printindex\n";#ecriture de l index
#ajout de \end{document}
print $HANDLE_TEX "\\end{document}\n";
close($HANDLE_TEX);
#------------------------------------------------------------------------------------------
#compilation pdflatex (avec index)
# en trois temps :
# 1- premier pdflatex (generation du .pdf et du .idx)
# 2- makeindex (creation de l index)
# 3- deuxieme pdflatex (table des matieres et index)
#------------------------------------------------------------------------------------------
print "\n";
afficher_ligne_tirets('print');
print "compilation pdflatex (1ere fois)\n";
afficher_ligne_tirets('print');
sleep 1;#petite pause pour laisser a l utilisateur le temps de voir l affichage precedent
#---
#-1ere comilation (pdflatex avec option -halt-on-error pour forcer a quitter a la moindre erreur)
#---
system("pdflatex -halt-on-error $racine_fic_latex.tex > toto.log");
#-verif presence .pdf
if(not -e "$racine_fic_latex.pdf") {
warn "\nErreur (prog:$NOM_PROG) : erreur a l execution de pdflatex.\n";
warn " Les fichiers suivants ont ete cree a des fins de debug :\n";
warn " - $NOM_PDF_CATALOGUE.tex (fichier .tex donne en argument de pdflatex)\n";
warn " - $NOM_PDF_CATALOGUE.error_log (affichage renvoye par pdflatex)\n";
warn "\n";
system("mv -f $racine_fic_latex.tex ../$NOM_PDF_CATALOGUE.tex");
system("mv -f toto.log ../$NOM_PDF_CATALOGUE.error_log");
chdir "..";
sortie_programme();
}
#---
#-generation de l index
#---
afficher_ligne_tirets('print');
print "compilation index (makeindex)\n";
afficher_ligne_tirets('print');
sleep 1;#petite pause pour laisser a l utilisateur le temps de voir l affichage precedent
#-verif presence .idx
if(not -e "$racine_fic_latex.idx") {
warn "\nErreur (prog:$NOM_PROG) : le fichier index .idx n a pas ete cree\n";
warn " Les fichiers suivants ont ete cree a des fins de debug :\n";
warn " - $NOM_PDF_CATALOGUE.tex (fichier .tex donne en argument de pdflatex)\n";
warn " - $NOM_PDF_CATALOGUE.error_log (affichage renvoye par pdflatex)\n";
warn "\n";
system("mv -f $racine_fic_latex.tex ../$NOM_PDF_CATALOGUE.tex");
system("mv -f toto.log ../$NOM_PDF_CATALOGUE.error_log");
chdir "..";
sortie_programme();
}
system("makeindex $racine_fic_latex.idx > toto.log");
#---
#-2eme compilation (pdflatex avec option -halt-on-error pour forcer a quitter a la moindre erreur)
#---
afficher_ligne_tirets('print');
print "compilation pdflatex (2eme fois)\n";
afficher_ligne_tirets('print');
sleep 1;#petite pause pour laisser a l utilisateur le temps de voir l affichage precedent
system("rm -f $racine_fic_latex.pdf");
system("pdflatex -halt-on-error $racine_fic_latex.tex > toto.log");
#-verif presence .pdf
if(not -e "$racine_fic_latex.pdf") {
warn "\nErreur (prog:$NOM_PROG) : erreur a l execution de pdflatex.\n";
warn " Les fichiers suivants ont ete cree a des fins de debug :\n";
warn " - $NOM_PDF_CATALOGUE.tex (fichier .tex donne en argument de pdflatex)\n";
warn " - $NOM_PDF_CATALOGUE.error_log (affichage renvoye par pdflatex)\n";
warn "\n";
system("mv -f $racine_fic_latex.tex ../$NOM_PDF_CATALOGUE.tex");
system("mv -f toto.log ../$NOM_PDF_CATALOGUE.error_log");
chdir "..";
sortie_programme();
}
#deplacement du catalogue final vers le repertoire de depart sous le nom prevu par la variable $NOM_PDF_CATALOGUE
system("mv -f $racine_fic_latex.pdf ../$NOM_PDF_CATALOGUE");
#retour au repertoire de depart
chdir "..";
#affichage fin programme
print "\n";
afficher_ligne_tirets('print');
print "Le fichier $NOM_PDF_CATALOGUE a ete cree...\n";
afficher_ligne_tirets('print');
print "\n";
#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#remarque : fin du programme => le repertoire temporaire $REP_TMP sera efface automatiquement
# car utilisation de File::Temp->newdir()
#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#--------------------------------------------------
#subroutine de sortie du programme
#--------------------------------------------------
sub sortie_programme {
#- - - - - - - - -
#effacement du repertoire temporaire (subroutine cleanup() du package File::Temp)
#- - - - - - - - -
# rq : on remonte d un cran dans l arborescence si le repertoire courant est le repertoire temporaire
# (sinon le repertoire temporaire $REP_TMP ne pourra pas etre efface avec cleanup() )
chdir ".." if(cwd() =~ /$REP_TMP/);
cleanup();
exit;
}#sub sortie_programme
#--------------------------------------------------
#subroutine pour generer un label de section sur 9 caracteres de A a Z
# rq : la variable $LABEL_ACTUEL est hors subroutine pour la rendre globale
# elle est initialisee lors du premier appel a la subroutine
# rq : le label est constitue de 9 caracteres (a priori, il ne faut pas depasser ce nombre
# pour eviter une erreur latex dans les index)
# de toute facon, avec 9 caracteres, la batterie peut contenir jusqu a 26 puissance 9, soit plus de 5400 milliards de tests !!!!
#--------------------------------------------------
my $LABEL_ACTUEL;
sub genere_label_section {
#initialisation du label actuel si c est la premiere fois que cette subroutine est appelee
$LABEL_ACTUEL = 'AAAAAAAAA' if(not defined $LABEL_ACTUEL);
#le label a renvoyer est le label actuel
my $label_a_renvoyer = $LABEL_ACTUEL;
#table de conversion lettre en position alphabet (et l inverse)
my $TAB_CONVERT_lettre2pos = {
'A' => 1, 'B' => 2, 'C' => 3, 'D' => 4, 'E' => 5, 'F' => 6,
'G' => 7, 'H' => 8, 'I' => 9, 'J' => 10, 'K' => 11, 'L' => 12,
'M' => 13, 'N' => 14, 'O' => 15, 'P' => 16, 'Q' => 17, 'R' => 18,
'S' => 19, 'T' => 20, 'U' => 21, 'V' => 22, 'W' => 23, 'X' => 24,
'Y' => 25, 'Z' => 26};
my $TAB_CONVERT_pos2lettre = {
'1' => 'A', '2' => 'B', '3' => 'C', '4' => 'D', '5' => 'E', '6' => 'F',
'7' => 'G', '8' => 'H', '9' => 'I', '10' => 'J', '11' => 'K', '12' => 'L',
'13' => 'M', '14' => 'N', '15' => 'O', '16' => 'P', '17' => 'Q', '18' => 'R',
'19' => 'S', '20' => 'T', '21' => 'U', '22' => 'V', '23' => 'W', '24' => 'X',
'25' => 'Y', '26' => 'Z'};
#- - - - - - - - -
#actualisation du label pour le prochain appel
#- - - - - - - - -
#label actuel sous forme d un tableau d entier par conversion selon la table $TAB_CONVERT_lettre2pos
my @tab_label = map {$TAB_CONVERT_lettre2pos->{$_}} split(//, $LABEL_ACTUEL);
my $nb_chars = $#tab_label + 1;
#test sur le depassement du nombre max de tests, ce qui ne devrait jamais poser probleme (a moins que la batterie de verif ne contienne 26 puissance 9 tests !!!!)
my $is_max_test = 1;
for(my $i=0; $i<$nb_chars; $i++) {$is_max_test = 0 if($tab_label[$i] != 26);}
if($is_max_test) {
warn "\n";
afficher_ligne_tirets('warn');
warn "Erreur (prog:$NOM_PROG) : le nombre de tests de la batterie a atteint son maximum de 26 puissance $nb_chars !!!!!!\n\n";
afficher_ligne_tirets('warn');
warn "\n";
sortie_programme();
}
#incrementation du label
# par exemple : si le label actuel est ZZZAAAAAA, le tableau @tab_label en chiffres contient [26][26][26][1][1][1][1][1][1]
# on incremente la premiere case de 1 => [27][26][26][1][1][1][1][1][1]
# algo : pour tout nombre superieur a 27, on le remet a 1 et on incremente de 1 la case suivante
# donc, dans la boucle suivante, ca donne :
# i=0 => $tab_label[0] = 1; $tab_label[1] = 27
# i=1 => $tab_label[1] = 1; $tab_label[2] = 27
# i=2 => $tab_label[2] = 1; $tab_label[3] = 2 => fin de la boucle (last)
# tableau final => [1][1][1][2][1][1][1][1][1], ce qui correspond en lettres au nouveau label suivant : AAABAAAAA
$tab_label[0]++;
for(my $i=0; $i<$nb_chars; $i++) {
#incrementation de l indice suivant si l indice courant depasse 26
if($tab_label[$i] > 26) {
#retour a la lettre A pour l indice courant
$tab_label[$i] = 1;
#incrementation de l indice suivant
$tab_label[$i+1]++ if($i != ($nb_chars-1));#sauf si c est le dernier indice
}
else {
last;
}
}
#-conversion inverse selon la table $TAB_CONVERT_pos2lettre
$LABEL_ACTUEL = '';
foreach my $val (@tab_label) {$LABEL_ACTUEL .= $TAB_CONVERT_pos2lettre->{$val};}
#rappel : on return la valeur precedente de $LABEL_ACTUEL et non celle que l on vient d actualiser
return $label_a_renvoyer;
}#sub genere_label_section
#--------------------------------------------------
#subroutine pour recopier les fichiers README d une
# liste de repertoires de tests vers un fichier ouvert
#--------------------------------------------------
#
# en entree :
# - lettre indiquant test rapide ou long (donc la lettre "R" ou "L")
# - handle du fichier destination (donc deja ouvert par open() )
# - reference vers la liste des repertoires de test (antislash devant pour une reference : par exemple \@REP_TESTS_R)
# - liste des noms de rubriques a recopier
#
# pas de sortie
#
sub recopie_README {
my $lettre_rapide_ou_long = shift;#doit etre egal a R ou L
my $handle_destination = shift;
my $ref_liste_rep_tests = shift;
my @liste_rubriques = @_;
my $no_test = 0;
foreach my $rep_test (@$ref_liste_rep_tests) {
$_ = $rep_test; s/^\.+\///;#suppression de l eventuel ./ ou ../ devant le nom du repertoire
print "ajout test : $_\n";
#incrementation numero test
$no_test++;
#chemin du fichier README
my $fic_README = "../$rep_test/README";
#derniere partie du nom du repertoire (en supprimant le prefixe Test_R_ ou Test_L_)
my $nom_test = basename $rep_test;
$nom_test =~ s/^Test_[RL]_//;
$nom_test =~ s/_/\$\\_\$/g;#tiret bas entre dollars
#saisie de l encodage du README (par defaut : rien) (rq : on utilise la commande linux/Unix "file" pour avoir des infos sur l encodage)
my $encodage_source = '';
#cas UTF-nombre (exemples : UTF-8, UTF-16, etc...)
if(qx(file $fic_README) =~ /utf-(\d+)/i) {
$encodage_source = ":encoding(UTF-$1)";
}
#autres cas a definir
#elsif() {}
#- - - - - - - - - - - - - - - -
#ecriture d une nouvelle sous-section pour ce test
#- - - - - - - - - - - - - - - -
print $HANDLE_TEX "\\subsection{Test\$\\_\$$lettre_rapide_ou_long n\$^\\circ\$$no_test : $nom_test}\n";
#- - - - - - - - - - - - - - - -
#ecriture du ou des auteurs de ce test
#- - - - - - - - - - - - - - - -
my @auteurs = saisir_mots_rubrique_README($fic_README, $encodage_source, $NOM_RUBRIQUE_AUTEUR);
if($#auteurs > -1) {
print $HANDLE_TEX "\\noindent\n";
print $HANDLE_TEX "\\begin{minipage}{\\linewidth}\n";
print $HANDLE_TEX "\\noindent \\underline{Auteur} :\\\\\n";
foreach my $auteur (@auteurs) {print $HANDLE_TEX "\\hspace*{0.5cm} $auteur\\\\\n";}
print $HANDLE_TEX "\\end{minipage}\n";
print $HANDLE_TEX "\\\\\n\n";
}
else {
warn " Attention (prog:$NOM_PROG) : la rubrique \"Auteur\" n a pas ete trouvee (ou est vide) pour ce test...\n";
print "(entree pour continuer)"; <STDIN>;
}
#- - - - - - - - - - - - - - - -
#indexage et ecriture de la liste des mots-cles eventuels de ce test
#- - - - - - - - - - - - - - - -
my @mots_cles = saisir_mots_rubrique_README($fic_README, $encodage_source, $NOM_RUBRIQUE_MOTS_CLES);
if($#mots_cles > -1) {
#indexage
#--generation d un label
my $label_section = genere_label_section();
print $HANDLE_TEX "\\label{$label_section}\n";
#--indexage de chaque mot-cle via commande \ind (voir preambule du document latex dans la subroutine preambule_fic_tex_tmp() )
foreach my $mot_cle (@mots_cles) {
print $HANDLE_TEX "\\ind{$mot_cle}{$label_section}\n";
}
#recopie des mots-cles
print $HANDLE_TEX "\\noindent\n";
print $HANDLE_TEX "\\begin{minipage}{\\linewidth}\n";
print $HANDLE_TEX "\\noindent \\underline{Mots-cl\\\'es} :\\\\\n";
@_ = ();
push(@_, @mots_cles);
$_ = shift(@_);
s/\s+/~/g;#espaces insecables
print $HANDLE_TEX "\\hspace*{0.5cm} $_";
foreach my $mot_cle (@_) {
$mot_cle =~ s/\s+/~/g;#espaces insecables
print $HANDLE_TEX ", $mot_cle";
}
print $HANDLE_TEX "\\\\\n";
print $HANDLE_TEX "\\end{minipage}\n";
print $HANDLE_TEX "\\\\\n\n";
}
else {
warn " Attention (prog:$NOM_PROG) : la rubrique \"Mots-cles\" n a pas ete trouvee (ou est vide) pour ce test...\n";
print "(entree pour continuer)"; <STDIN>;
}
#- - - - - - - - - - - - - - - -
#ecriture du nom complet du repertoire sous forme d une arborescence simple
#- - - - - - - - - - - - - - - -
print $HANDLE_TEX "\\noindent\n";
print $HANDLE_TEX "\\begin{minipage}{\\linewidth}\n";
print $HANDLE_TEX "\\noindent \\underline{R\\\'epertoire} :\\\\\n";
my @rep_arbo = split(/\/+/, $rep_test);
shift(@rep_arbo) if($rep_arbo[0] =~ /^\.+$/);#suppression d un eventuel ./ ou ../ devant le nom du repertoire
#--variables pour faire une jolie indentation via \hspace
my $hspace_cm = 0.5;
my $hspace_cm_incr = 0.35;
foreach my $rep_arbo (@rep_arbo) {
$rep_arbo =~ s/_/\$\\_\$/g;#eventuels tirets bas entre dollars
print $HANDLE_TEX "\\hspace*{${hspace_cm}cm}\$\\triangleright\$ $rep_arbo\\\\\n";
$hspace_cm += $hspace_cm_incr;
}
print $HANDLE_TEX "\\end{minipage}\n";
print $HANDLE_TEX "\\\\\n\n";
#- - - - - - - - - - - - - - - -
#recopie des rubriques dans l ordre de la liste @liste_rubriques
#- - - - - - - - - - - - - - - -
#indicateurs de reussite de la recopie des rubriques du README
my ($is_probleme_rubrique, $message);
foreach my $rubrique (@liste_rubriques) {
$rubrique =~ s/^\s+//;
$rubrique =~ s/\s+$//;
my @mots_rubriques = split(/\s+/, $rubrique);
#ecriture de la rubrique
($is_probleme_rubrique, $message) = recopie_rubrique_README($fic_README, $encodage_source, $HANDLE_TEX, @mots_rubriques);
#-- erreur si la rubrique n a pas ete trouvee
if($is_probleme_rubrique) {
warn "Erreur (prog:$NOM_PROG) : lecture README => probleme dans la recopie de la rubrique \"$rubrique\" avec le message d erreur suivant :\n";
warn " **$message\n";
warn "\n";
sortie_programme();
}
}#foreach my $rubrique (@liste_rubriques)
}#foreach my $rep_test (@$ref_liste_rep_tests)
}#sub recopie_README
#--------------------------------------------------
#subroutine qui ecrit une rubrique du fichier README vers un fichier deja ouvert
#--------------------------------------------------
#
# en entree :
# - chemin vers le fichier README
# - encodage du fichier README (de la forme ":encoding(nom_encodage)", par exemple : ":encoding(UTF-8)"
# - handle du fichier destination (donc deja ouvert par open() )
# - liste de mots de la rubrique
#
# en sortie :
# - un indicateur de reussite avec les valeurs suivantes :
# 0 => la rubrique a ete trouvee et recopiee avec succes
# 1 => il y a eu une non-conformite
# - message
#
sub recopie_rubrique_README {
my $fic_source = shift;
my $encodage_source = shift;
my $handle_fic_destination = shift;
my @mots_rubriques = @_;
#construction du titre de la rubrique a partir des mots @mots_rubriques
# et d une expression reguliere pour rechercher la rubrique
my $regexp = shift(@mots_rubriques);
my $nom_rubrique = $regexp;
foreach my $mot (@mots_rubriques) {
$regexp .= '\s+'."$mot";
$nom_rubrique .= " $mot";
}
#a ce stade, le motif a trouver est de la forme : mot\s+mot\s+mot etc...
#indicateur de reussite et message associe
my $is_probleme_rubrique = 1;
my $message = 'rubrique introuvable';
open(my $Hlocal, "<$encodage_source", "$fic_source");
while(<$Hlocal>) {
next if(not /^\s*$regexp\s*$/i);#recherche du bloc correspondant a la rubrique
#normalement, la ligne suivante est une ligne de tirets
$_ = <$Hlocal>; chomp;
#-si ce n est pas une ligne de tirets => echec
if(not /^\s*-+\s*$/) {
$is_probleme_rubrique = 1;
$message = 'rubrique trouvee mais non conforme (absence de la ligne de tirets apres le nom de la rubrique)';
last;
}
#- - - - - - - - - - - - - - - - - - - - - - - - - - -
#recopie de la rubrique vers le fichier de destination
#- - - - - - - - - - - - - - - - - - - - - - - - - - -
$is_probleme_rubrique = 0;
$message = 'rubrique trouvee et recopiee avec succes';
#creation d une sous-sous-section pour cette rubrique
print $handle_fic_destination "\\subsubsection{$nom_rubrique}\n";
my $nb_lignes_blanches = 0;#variables pour enregistrer les lignes blanches consecutives
SUBWHILE:while(<$Hlocal>) {
last if(/^\s*$MOTIF_FIN_RUBRIQUE\s*$/);#critere d arret : motif de fin de rubrique (a moins que la fin du fichier n ait ete atteinte avant)
chomp;
#-----------------------------------------------
#cas d une ligne blanche => incrementation du compteur et nouveau tour de boucle
#-----------------------------------------------
if($_ =~ /^\s*$/) {
$nb_lignes_blanches++;
next;
}
#-----------------------------------------------
# cas des lignes non blanches
#-----------------------------------------------
#on vide le nombre de lignes blanches actuel
print $handle_fic_destination "\\vspace*{\\baselineskip}\n" for(1 .. $nb_lignes_blanches);
$nb_lignes_blanches = 0;
#-----------------------------------------------
#1) cas special : balise d ajout d une figure (saisie des fichiers figures et de la legende)
#-----------------------------------------------
if(/^\s*\\figures:\s*(\S+(?:\s+\S+)*)\s*\\legende:/) {
#noms des fichiers figures
my $fig = $1; $fig =~ s/^\s+//; $fig =~ s/\s+$//;
my @nom_figures = split(/\s+/, $fig);
#saisie de la legende (avec la possibilite qu elle soit ecrite sur plusieurs lignes)
my $legende = $_;
chomp($legende);
$legende =~ s/^\s*\\figures:\s*(\S+(?:\s+\S+)*)\s*\\legende:\s*//;#suppression de tout ce qu il y a avant la balise de debut de legende \legende: (dont cette balise elle-meme)
my $is_legende_ok = 0;#indicateur pour signaler que la balise de fin de legende a ete trouvee (sinon erreur)
#la boucle suivante gere le cas ou la legende est ecrite sur plusieurs lignes)
# => on va lire jusqu a atteindre la balise de fin de legende \fin_legende
while() {
#on quitte ce while si la balise de fin de legende a ete trouvee
if($legende =~ /\\fin_legende\s*$/) {
$is_legende_ok = 1;
last;
}
#lecture d une nouvelle ligne (ou fin de la boucle si on a atteint la fin du fichier)
last if(not my $tmp = <$Hlocal>);
$legende .= " $tmp";#rajout d un espace avant par securite (eviter que 2 mots ne soient colles)
chomp($legende);
}
#verif que la balise de fin de legende a bien ete trouvee (sinon preparation d un message d erreur et fin du while SUBWHILE)
$is_legende_ok or do {
$is_probleme_rubrique = 1;
$message = 'probleme d insertion de figure (balise de fin de legende non trouvee)';
last SUBWHILE;
};
#derniers traitements
$legende =~ s/\\fin_legende\s*$//;#suppression de la balise de fin de legende et d eventuels espaces en fin de legende
$legende =~ s/\s+/ /g;#reduction des espaces multiples a un seul espace (a priori inutile!!)
$legende = translate_to_latex($legende);#conversion de la legende
#repertoire ou se trouve l image (tout simplement le meme que le fichier README)
my $rep;
($_, $rep) = splitpath($fic_source);
#ecriture de l image (\includegraphics) et sa legende
print $handle_fic_destination "\\begin{figure}[H]\n";
print $handle_fic_destination "\\centering\n";
#-- autant de includegraphics que de fichiers image
# (on regarde si il y a un facteur d echelle a la fin du nom de fichier)
foreach my $nom_fig (@nom_figures) {
#echelle par defaut = 1
my $scale = 1.;
#si le nom du fichier contient un facteur d echelle, on le prend en compte
if($nom_fig =~ /\[\s*($format_reel)\s*\]$/) {
$scale = $1;
$nom_fig =~ s/\[\s*$format_reel\s*\]$//;#suppression de [facteur echelle] du nom du fichier
}
print $handle_fic_destination "\\includegraphics[scale=$scale]{$rep/$nom_fig}\n";
}
print $handle_fic_destination "\\caption{$legende}\n";
print $handle_fic_destination "\\end{figure}\n";
#nouveau tour de la boucle SUBWHILE
next SUBWHILE;
}
#-----------------------------------------------
#2) cas normal : ligne classique
#-----------------------------------------------
else {
#gestion des caracteres ou groupes de caracteres speciaux
my $texte_a_ecrire = translate_to_latex($_);
#ecriture du texte (suivi d un passage a la ligne pour respecter la forme du README)
print $handle_fic_destination "$texte_a_ecrire\\\\\n";
}
}#SUBWHILE
last;
}
close($Hlocal);
return ($is_probleme_rubrique, $message);
}#sub recopie_rubrique_README
#--------------------------------------------------
#subroutine permettant de saisir les mots ou phrases contenus dans une rubrique d un fichier README
# rq : cette subroutine renvoie simplement une liste des lignes non vides d une rubrique
#--------------------------------------------------
#
# en entree :
# - chemin vers le fichier README
# - encodage du fichier README (de la forme ":encoding(nom_encodage)", par exemple : ":encoding(UTF-8)"
# - nom de la rubrique (insensible a la casse)
#
# en sortie :
# - liste de mots ou phrases (i.e les lignes non vides de la rubrique)
#
sub saisir_mots_rubrique_README {
my $fic_source = shift;
my $encodage_source = shift;
my $nom_rubrique = shift;
#construction d une expression reguliere pour rechercher la rubrique
$nom_rubrique =~ s/^\s+//;
$nom_rubrique =~ s/\s+$//;
my @mots_rubrique = split(/\s+/, $nom_rubrique);
my $regexp = shift(@mots_rubrique);
foreach my $mot (@mots_rubrique) {
$regexp .= '\s+'."$mot";
}
#a ce stade, le motif a trouver est de la forme : mot\s+mot\s+mot etc...
#liste des lignes non vides de la rubrique $nom_rubrique de ce README
my @liste_lignes_non_vides;
open(my $Hlocal, "<$encodage_source", "$fic_source");
while(<$Hlocal>) {
next if(not /^\s*$regexp\s*$/i);#recherche du bloc correspondant a la rubrique
#normalement, la ligne suivante est une ligne de tirets
$_ = <$Hlocal>; chomp;
#-si ce n est pas une ligne de tirets => echec
if(not /^\s*-+\s*$/) {
last;
}
#- - - - - - - - - - - - - - - - - - - - - - - - - - -
#saisie des lignes non vides
#- - - - - - - - - - - - - - - - - - - - - - - - - - -
while(<$Hlocal>) {
last if(/^\s*$MOTIF_FIN_RUBRIQUE\s*$/);#critere d arret : motif de fin de rubrique (a moins que la fin du fichier n ait ete atteinte avant)
next if(/^\s*$/);#on saute les lignes vides
chomp;
s/^\s+//; s/\s+$//;
#gestion des caracteres ou groupes de caracteres speciaux
$_ = translate_to_latex($_);
#ajout de la ligne a la liste
push(@liste_lignes_non_vides, $_);
}
last;
}
close($Hlocal);
return(@liste_lignes_non_vides);
}#sub saisir_mots_rubrique_README
#--------------------------------------------------
#subroutine de conversion des caracteres ou groupe de caracteres speciaux en vue
# d une ecriture latex
#--------------------------------------------------
#
# en entree :
# - une chaine de caracteres
#
# en sortie :
# - la chaine convertie
#
sub translate_to_latex {
my $string = shift;
#--------------------------------------------------------------------------------
#--------------------------------------------------------------------------------
#A FAIRE EVOLUER : gestion au cas par cas des caracteres speciaux dans Latex
#
# (important : ne pas oublier de l option "g" a la fin de l operateur de substitution => $string =~ s/bla bla/ha ha/g; )
#--------------------------------------------------------------------------------
#--------------------------------------------------------------------------------
##############################################################################################
### IMPORTANT : la ligne ci-dessous traite le cas des antislash. Il faut absolument
### ne rien mettre avant ce traitement car les substitutions qui suivent
### rajoutent des antislash (et ceux-la, il ne faut pas les remplacer par \backslash)
##############################################################################################
$string =~ s/\\/\$\\backslash\$/g;#anti-slash (solution : caractere special \backslash entre dollars)
$string =~ s/\%/\\\%/g;#pourcent (solution : rajout d un antislash devant => \%)
$string =~ s/\#/\\\#/g;#diese (solution : rajout d un antislash devant => \#)
$string =~ s/_/\$\\_\$/g;#tiret bas (solution : antislash devant + entre dollars)
$string =~ s/\^($format_reel)/\$\^$1\$/g;#cas d un exposant mathematique : symbole circonflexe suivi d un nombre (solution : entre dollars)
$string =~ s/([<>])/\$$1\$/g;#symboles inferieur et superieur (solution : entre dollars)
#ajouter ici d autres cas sous la forme : $string =~ s/bla bla/ha ha/g;
#--------------------------------------------------------------------------------
#--------------------------------------------------------------------------------
return $string;
}#sub translate_to_latex
#--------------------------------------------------
#subroutine permettant d ecrire une ligne de tirets de la largeur du terminal
#--------------------------------------------------
#
# en entree :
# - print ou warn (suivant que l on souhaite afficher avec print (donc vers STDOUT) ou warn (donc vers STDERR)
#
sub afficher_ligne_tirets {
use Term::ReadKey;
my $nb_char_largeur_terminal = ( GetTerminalSize() )[0];#largeur du terminal en nombre de caracteres (via package Term::ReadKey)
my $funct_disp = shift;
my $ligne_tirets = '';
$ligne_tirets .= '-' for(1 .. $nb_char_largeur_terminal);
print "$ligne_tirets\n" if($funct_disp eq 'print');
warn "$ligne_tirets\n" if($funct_disp eq 'warn');
}#sub afficher_ligne_tirets
#--------------------------------------------------
#subroutine d ecriture du preambule du fichier .tex temporaire
#--------------------------------------------------
#a noter que dans ce preambule :
# - il y a des declarations particulieres pour generer proprement un index par mots-cles renvoyant
# aux sections (au lieu des numeros de page). Il s agit de \usepackage{imakeidx}, \newcommand{\ind}, \newcommand{\inds}
sub preambule_fic_tex_tmp {
my $handle = shift;
print $handle '\documentclass[a4paper,12pt]{scrartcl}
\usepackage[latin1]{inputenc}
\usepackage[francais]{babel}
\usepackage{epsfig,color}
\usepackage{graphicx}
\usepackage{hyperref}
\usepackage{fancybox}
\usepackage{wrapfig}
%\usepackage{pslatex}
\usepackage{amsmath}
\usepackage{subfigure}
%\usepackage{/Users/troufflard/LATEX/BIBLIOTHEQUE/macro_figure}
%\usepackage{eurosym}
\usepackage{calc}
%\usepackage{t1enc}
\usepackage{ifthen}
\usepackage{lscape}
\usepackage{float} % paquet pour placer les images correctement avec \begin{figure}[H]
\usepackage{tabularx}
\usepackage{multirow}
\usepackage{colortbl}
%\newcolumntype{M}[1]{>{\raggedright}m{#1}}
\usepackage{tikz}
\usetikzlibrary{trees}
\addto\captionsfrench{\def\figurename{Figure}}
\addto\captionsfrench{\def\tablename{Tableau}}
%\usepackage{hangcaption}
\oddsidemargin 0.1cm
\evensidemargin -0.9cm
\topmargin -1cm
\headsep 1cm
\textwidth 17cm
\textheight 24cm
\parindent 0.5cm
\raggedbottom
\sloppy
\setcounter{tocdepth}{2}
\usepackage{hyperref}
\hypersetup{
colorlinks=true, %colorise les liens
breaklinks=true, %permet le retour <20> la ligne dans les liens trop longs
urlcolor= blue, %couleur des hyperliens
linkcolor= blue, %couleur des liens internes
citecolor= green %couleur citation biblio
}
%creation d une longueur egale a \baselineskip pour l utiliser dans les tabular (car un bug incroyable fait que \baselineskip est egal a 0 dans les tabular!!!!)
\newlength{\savebaselineskip}
\setlength{\savebaselineskip}{\baselineskip}
\title{Catalogue des tests}
\date{\today}
%\pagestyle{arabic}
\pagenumbering{arabic}
%remarque : le package makeidx doit etre place apres \usepackage{hyperref} pour beneficier des liens hyperef dans l index
\usepackage{imakeidx}
%-- nouvelles commandes pour que ce soit des numeros de section (et non des pages) qui apparaissent dans l index
% selon astuce (2015-06-26) : http://www.latex-community.org/forum/viewtopic.php?f=51&t=14334
%:: \ind => 2 arguments : index entry, label de section
\newcommand{\ind}[2]{\index{#1|inds{\ref{#2}}}}
%:: \inds => ne sert qu a enlever les numeros de page dans la \ref de \ind
\newcommand{\inds}[2]{#1}
% exemple de sequence avec une section et 2 mots indexes concernant cette section :
% \section{Revelations : la face cachee du monde de la recherche}\label{section_1}\ind{scandale}{section_1}\ind{Capital_sur_M6}{section_1}
%commande suivante pour que l index figure dans la table des matieres
\makeindex[intoc]
\begin{document}
\maketitle
\tableofcontents
';
}#sub preambule_fic_tex_tmp
#####################################################################################################
#subroutine qui recherche l existence d une commande et renvoie le premier path trouve (renvoie 0 si commande introuvable)
#####################################################################################################
# en entree :
# - nom de la commande
#
# en sortie :
# - chemin aboslu de la commande (0 si commande introuvable)
#
sub verif_commande {
my $cmd = shift;#nom de la commande
#cas d un chemin absolu ou relatif (si la commande commence par . ou /. Par exemple : ./HZpp ../HZppfast ou /Users/dupont/bin/HZppfast)
if($cmd =~ /^\./ or $cmd =~ /^\//) {
#on passe la commande en chemin absolu
$cmd = rel2abs($cmd);
return $cmd;
}
#sinon on regarde dans la variable environnement $PATH
foreach my $path (split(/\s*:\s*/, $ENV{PATH})) {
if(-x "$path/$cmd") {
#on s assure que c est un chemin absolu
$cmd = rel2abs("$path/$cmd");
return $cmd;
}
}
#on regarde a nouveau si la commande est en chemin absolu ou relatif
# (cas d une commande qui ne commence pas par . ou / et qui n est pas dans les PATH. Par exemple : rep/HZpp)
if(-x $cmd) {
#on passe la commande en chemin absolu
$cmd = rel2abs($cmd);
return $cmd;
}
#cas ou la commande est introuvable
return 0;
}#sub verif_commande