#!/usr/bin/env perl 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 use Module::Load::Conditional qw(check_install);#pour verifier existence d une librairie 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" # - en cas d erreur de compilation Latex, le fichier .tex est fourni pret a la compilation, ainsi qu un fichier # de l historique de compilation. Ces 2 fichiers permettent de cerner le probleme.... et pourquoi pas aussi essayer # de finaliser la compilation manuellement plutot que de rester bloque (sans oublier tout de meme de signaler # le probleme aux developpeurs de ce script) # #-------------------------- # 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 tels que ^n ^3.14) # Le plus souvent, ce script rajoute des dollars autour des caracteres problematiques mais # cette action ne resoud pas tous les problemes. # La gestion de ces problemes se fait au cas par cas dans la subroutine traduction_pour_latex() # au niveau du bloc "A FAIRE EVOLUER" (par substitution de caracteres s///g) # MAIS il faut noter que c est la subroutine traduction_pour_latex_avec_gestion_dollars() qui # est appelee en premier de maniere a pouvoir inserer des formules mathematiques # dans les README avec des dollars simples $bla bla bla$ ou des dollars doubles $$bla bla bla$$ # ##################################################################################################### ###################################################################################################### # # 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 #-------------------------------------------------------------------------- # affichage de l aide si option -h ou -help #-------------------------------------------------------------------------- if(" @ARGV " =~ / -h /i or " @ARGV " =~ / -help /i) { afficher_ligne_tirets('print'); print "Script $NOM_PROG \n"; afficher_ligne_tirets('print'); print " Description :\n"; print " Creation du catalogue pdf de test sur la base des fichiers README\n"; print " trouves dans tous les repertoires commencant par Test_R et Test_L\n"; print " de l arborescence depuis le repertoire courant\n"; print "\n"; print " Usage : $NOM_PROG\n"; print "\n"; print " Argument obligatoire :\n"; print " aucun\n"; print "\n"; print " Options :\n"; print " pas d options...\n"; print "\n"; print " Remarque :\n"; print " le fichier pdf est genere avec Latex (necessite d avoir les commandes\n"; print " \"pdflatex\" et \"makeindex\")\n"; print "\n"; afficher_ligne_tirets('print'); print "\n"; exit; } ######################################################################################################### # 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 l option -interaction de la commande pdflatex @_ = qx(pdflatex -help | grep -- -interaction); ($#_ > -1) or die "\nErreur (prog:$NOM_PROG) : commande pdflatex => option -interaction 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 ######################################################################################################### # # RAPPEL : le repertoire Tests_en_attente_debug n est pas concerne (on le squizze avec une option "-not -path" dans la recherche find # #liste des repertoires de tests rapides (Test_R) my @REP_TESTS_R = map {chomp($_); $_} qx(find . -not -path "*Tests_en_attente_debug*" -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 . -not -path "*Tests_en_attente_debug*" -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 egalement 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); # # # # a ce stade, le fichier .tex est cree et pret a la compilation # # # #------------------------------------------------------------------------------------------ #compilation pdflatex (avec index) # on compile 2 fois : # 1- premier pdflatex (generation du .pdf et des fichiers index .idx, .ilg (makeindex lance automatiquement)) # 2- deuxieme pdflatex (table des matieres et index) # # a chaque fois, on utilise des options qui empechent pdflatex d attendre une reponse interactive en cas d erreur de compilation # option -halt-on-error => forcer a quitter a la moindre erreur # option -interaction=nonstopmode => desactiver les demandes interactives (par exemple si un fichier est introuvable, comme par exemple un package .sty inconnu) #------------------------------------------------------------------------------------------ #-declaration prealable d une subroutine qui sera execute en cas d erreur latex # => a la moindre erreur, on fournira a l utilisateur le moyen de cerner les bugs et de pourquoi pas finir la compilation par lui-meme sub traitement_erreur_latex { #fichier .tex (my $tex_catalogue = $NOM_PDF_CATALOGUE) =~ s/\.pdf$/.tex/; #fichier .log de la compilation (my $errlog_catalogue = $NOM_PDF_CATALOGUE) =~ s/\.pdf$/.error_log/; warn " Les fichiers suivants ont ete crees pour chercher manuellement la source de l erreur :\n"; warn " - $tex_catalogue (fichier .tex pret a la compilation)\n"; warn " - $errlog_catalogue (affichage renvoye par pdflatex)\n"; warn "\n"; warn " (vous pouvez essayer de compiler vous-meme le fichier .tex pour\n"; warn " finaliser la creation du catalogue)\n"; warn "\n"; #recopie du .tex mais en supprimant le retour d un cran dans le path du fichier figure des includegraphics (sinon l utilisateur ne pourra pas tester par lui-meme la compilation du fichier $tex_catalogue) open(FTEX1, "<$racine_fic_latex.tex"); open(FTEX2, ">../$tex_catalogue"); while() { s/\{\.\.\//\{/ if(/^\s*\\includegraphics/);#suppression retour d un cran dans le path du fichier figure print FTEX2; } close(FTEX1); close(FTEX2); system("mv -f toto.log ../$errlog_catalogue");#recopie du .log latex pour debuggage par l utilisateur #affichage des eventuelles erreurs presentes dans le fichier $errlog_catalogue chdir ".."; my @err_log = qx(grep -i error $errlog_catalogue | grep -v 'no output PDF');#on recupere les lignes qui contiennent le mot 'error' (sauf les lignes qui contiennent 'no output PDF' car on sait bien que le pdf n a pas ete cree!!!!) #si il existe au moins une ligne contenant le mot 'error', on produit un affichage if($#err_log > -1) { warn " Notamment, le fichier $errlog_catalogue contient les erreurs :\n"; afficher_ligne_tirets('warn'); warn " > $_" for @err_log; afficher_ligne_tirets('warn'); warn "\n"; } }#sub traitement_erreur_latex #--- #-1ere compilation pdflatex en utilisant des options qui empechent les demandes interactives : # option -halt-on-error => forcer a quitter a la moindre erreur # option -interaction=nonstopmode => desactiver les demandes interactives (par exemple en cas d absence d un package du preambule) #--- 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 system("pdflatex -halt-on-error -interaction=nonstopmode $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"; traitement_erreur_latex(); sortie_programme(); } #-verif presence des fichiers d index (fichiers .idx et .ilg) if(not -e "$racine_fic_latex.idx" or not -e "$racine_fic_latex.ilg") { warn "\nErreur (prog:$NOM_PROG) : le fichier index .idx ou .ilg n a pas ete cree apres compilation avec pdflatex\n"; traitement_erreur_latex(); sortie_programme(); } #--- #-2eme compilation pdflatex en utilisant des options qui empechent les demandes interactives : # option -halt-on-error => forcer a quitter a la moindre erreur # option -interaction=nonstopmode => desactiver les demandes interactives (par exemple en cas d absence d un package du preambule) #--- 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 -interaction=nonstopmode $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"; traitement_erreur_latex(); sortie_programme(); } # # # # si on atteint cet endroit du script, c est que tout s est bien passe # il ne reste plus qu a deplacer le .pdf hors du repertoire temporaire (et le repertoire temporaire s effacera tout seul) # # # #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)"; ; } #- - - - - - - - - - - - - - - - #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)"; ; } #- - - - - - - - - - - - - - - - #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 my $latex_brut = 0;#indicateur pour savoir si le mode "latex brut" est enclenche (suite a la presence de la balise \latex_brut) #rq : ce mode permet d ecrire du code latex directement dans les README 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; #recherche d une eventuelle balise de debut ou fin de mode latex brut if(/^\s*\\latex_brut\s*$/) { $latex_brut = 1; print $handle_fic_destination "\n";#on saute une ligne dans le .tex pour creer un nouveau paragraphe next; } elsif(/^\s*\\fin_latex_brut\s*$/) { $latex_brut = 0; next; } #----------------------------------------------- #cas d une ligne blanche (hors mode "latex brut") => incrementation du compteur et nouveau tour de boucle #----------------------------------------------- if($_ =~ /^\s*$/ and not $latex_brut) { $nb_lignes_blanches++; next; } #----------------------------------------------- # cas des lignes non blanches #----------------------------------------------- #on vide le nombre de lignes blanches actuel (on ecrit un "tilde" suivi de 2 backslash => creation d une ligne blanche sans bug latex) print $handle_fic_destination "\~\\\\\n" for(1 .. $nb_lignes_blanches); $nb_lignes_blanches = 0; #----------------------------------------------- #cas du mode "latex brut" => on recopie simplement ce qui a ete lu (charge a l utilisateur d ecrire un code latex correct) #----------------------------------------------- if($latex_brut) { print $handle_fic_destination "$_\n"; next; } #----------------------------------------------- #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 = traduction_pour_latex_avec_gestion_dollars($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 } #cas d un espace a inserer (i.e pas de figure, juste un crochet avec un facteur d echelle) if($nom_fig eq '') { print $handle_fic_destination "\\hspace*{${scale}cm}\n"; } #cas normal : le nom de figure n est pas une chaine vide => \includegraphics de la figure else { 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; } #----------------------------------------------- #cas normal : ligne classique #----------------------------------------------- else { #gestion des caracteres ou groupes de caracteres speciaux my $texte_a_ecrire = traduction_pour_latex_avec_gestion_dollars($_); #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 $_ = traduction_pour_latex_avec_gestion_dollars($_); #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 avec un traitement special pour les chaines entre dollars (mode mathematique de latex) # # en resume, il s agit d une surcouche de la subroutine traduction_pour_latex # # en entree : # - une chaine de caracteres # - le nom du fichier d ou la chaine provient # # en sortie : # - la chaine convertie (ou 0 si erreur) #-------------------------------------------------- sub traduction_pour_latex_avec_gestion_dollars { my $string = shift; my $fic_source = shift;#fichier d origine (uniquement pour pouvoir l afficher en cas d erreur) #on splitte suivant les "$" ou "$$" pour gerer l insertion de formules mathematiques my @liste_string = (); my @liste_dollars = (); @liste_string = split(/\$+/, $string);#recuperation des chaines entre dollars @liste_dollars = ($string =~ /(\$+)/g);#recuperation des dollars #premiere verification : le nombre de dollars doit etre egal au nombre de chaine moins 1 exemples : "hello $\delat=0.5$ world" => 3 chaines et 2 dollars # "kiss $$\delat=0.5$$ you" => 3 chaines et 2 dollars # "thanks $$\delat=0.5$$" => 3 chaines et 2 dollars et la 3eme chaine est vide) ($#liste_string == ($#liste_dollars+1)) or do { warn "\nErreur (prog:$NOM_PROG,sub:traduction_pour_latex_avec_gestion_dollars) : pas assez de balises mathematiques\"\$\" dans le fichier $fic_source a la ligne :\n$string\n\n"; return 0; }; #maintenant, on parcourt les listes et on traduit les chaines, sau celles entre dollars my $string_traduite = '';#la chaine finale renvoyee par cette subroutine (resultat de la concatenation des traductions) #la premiere chaine n est jamais entre dollars (rq : elle peut etre vide, comme par exemple dans le cas ou $string comme par un dollar) $string_traduite .= traduction_pour_latex($liste_string[0]); #pour les suivantes, on gere selon le cas ou on est entre les dollars et le cas hors dollars my $entre_les_dollars = 1;#indicateur pour savoir si on est entre des dollars (rq : pour la premiere chaine, on commence forcement entre des dollars) # si $entre_les_dollars == 1 => on est entre dollars # si $entre_les_dollars == -1 => on est hors dollars for(my $i=1; $i<=$#liste_string; $i++) { $string_traduite .= $liste_dollars[$i-1];#(rq : quelque soit le cas, il y a toujours le dollar precedent a concatener) #cas particulier : la derniere string n est jamais entre dollars => on la traduit et on quitte la boucle if($i == $#liste_string) { $string_traduite .= traduction_pour_latex($liste_string[$i]); last; } #cas normal : on gere selon que l on est entre dollars ou hors dollars #cas entre dollars => on verifie si les dollars sont coherents et on ne fait pas de traduction if($entre_les_dollars == 1) { ($liste_dollars[$i] eq $liste_dollars[$i-1]) or do { warn "\nErreur (prog:$NOM_PROG,sub:traduction_pour_latex_avec_gestion_dollars) : non coherence des balises mathematiques (la balise \"$liste_dollars[$i-1]\" n est pas coherente avec la balise \"$liste_dollars[$i]\"). Erreur trouvee dans le fichier $fic_source a la ligne :\n$string\n\n"; return 0; }; #pas de traduction car on est entre dollars $string_traduite .= $liste_string[$i]; } #cas hors dollars => on traduit else { $string_traduite .= traduction_pour_latex($liste_string[$i]); } #on switche de mode avant de commencer a traiter la chaine suivante $entre_les_dollars *= -1; }#for(my $i=1; $i<=$#liste_string; $i++) return $string_traduite; } #-------------------------------------------------- #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 traduction_pour_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) $string =~ s/\{/\\{/g;#accolade ouvrante $string =~ s/\}/\\}/g;#accolade fermante #ajouter ici d autres cas sous la forme : $string =~ s/bla bla/ha ha/g; #-------------------------------------------------------------------------------- #-------------------------------------------------------------------------------- return $string; }#sub traduction_pour_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 { my $funct_disp = shift; ($funct_disp eq 'print') or ($funct_disp eq 'warn') or die "\nErreur (sub:afficher_ligne_tirets) : l argument d entree doit etre \"print\" ou \"warn\" (argument recu : $funct_disp)...\n\n"; #utilisation de Term::ReadKey pour connaitre la largeur du terminal en nombre de caracteres # (seulement si la librairie existe. si non, la ligne de tirets aura une largeur de 78) my $nb_char_largeur_terminal = 78; if(check_install( module => 'Term::ReadKey')) { require Term::ReadKey; Term::ReadKey->import(qw(GetTerminalSize)); $nb_char_largeur_terminal = ( GetTerminalSize() )[0];#largeur du terminal en nombre de caracteres (via package Term::ReadKey) } 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 à 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 1 : le package makeidx doit etre place apres \usepackage{hyperref} pour beneficier des liens hyperef dans l index %remarque 2 : le package makeidx appelle la commande makeindex (donc executer makeindex dans un shell apres la premiere compilation pdflatex ne sert a rien) \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 absolu 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