2015-11-25 15:39:29 +01:00
#!/usr/bin/env perl
2015-06-26 02:03:28 +02:00
use strict ;
use warnings ;
use File::Basename ;
use English ;
2015-06-26 17:37:18 +02:00
use Encode ; # package encodage fichier texte
use Cwd ; # package pour connaitre le repertoire courant
2015-07-16 12:02:00 +02:00
use File::Spec::Functions qw( splitpath rel2abs ) ; #($volume, $rep, $fic) = splitpath($path); $absolute_path = rel2abs($relative_path)
2015-06-26 02:03:28 +02:00
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
2016-02-09 22:43:06 +01:00
use Module::Load::Conditional qw( check_install ) ; #pour verifier existence d une librairie
2015-06-26 02:03:28 +02:00
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
2015-06-26 17:37:18 +02:00
# fichier README de chaque repertoire de test)
2015-06-26 02:03:28 +02:00
#
2016-02-12 16:02:51 +01:00
#--------------------------
2015-06-29 17:41:12 +02:00
# Notes a tout le monde :
2016-02-12 16:02:51 +01:00
#--------------------------
2015-06-29 17:41:12 +02:00
# 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).
#
#
2016-02-12 16:02:51 +01:00
#--------------------------
2015-06-26 02:03:28 +02:00
# Notes aux utilisateurs :
2016-02-12 16:02:51 +01:00
#--------------------------
2015-07-15 13:42:40 +02:00
# - 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"
2016-02-12 16:02:51 +01:00
# - 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)
2015-06-26 02:03:28 +02:00
#
2016-02-12 16:02:51 +01:00
#--------------------------
2015-06-26 02:03:28 +02:00
# Notes aux developpeurs :
2016-02-12 16:02:51 +01:00
#--------------------------
2015-06-26 17:37:18 +02:00
# - 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
2015-06-26 02:03:28 +02:00
# (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
2016-02-09 22:43:06 +01:00
# (par exemple : <, >, _, etc... ou bien encore les exposants tels que ^n ^3.14)
2015-07-15 13:42:40 +02:00
# Le plus souvent, ce script rajoute des dollars autour des caracteres problematiques mais
2015-11-24 17:27:51 +01:00
# cette action ne resoud pas tous les problemes.
2016-02-09 22:43:06 +01:00
# La gestion de ces problemes se fait au cas par cas dans la subroutine traduction_pour_latex()
2015-06-26 17:37:18 +02:00
# au niveau du bloc "A FAIRE EVOLUER" (par substitution de caracteres s///g)
2015-11-24 17:27:51 +01:00
# 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$$
#
2015-06-26 02:03:28 +02:00
#####################################################################################################
2017-10-22 12:10:31 +02:00
# version 1.1: 22 octobre 2017: Gerard Rio: modification provisoire pour prendre en compte #
# l'existence de rubriques supplementaires aux deux obligatoires : 'But du test' #
# et 'Description du calcul', dans la version initiale seules ces deux rubriques sont #
# prises en compte. Introduction de la liste : @LISTE_RUBRIQUES_OBLIGATOIRES #
# pour mettre un message d'erreur et stopper le programme uniquement pour les rubriques #
# obligatoires. Ajout des rubriques possibles: #
# 'Grandeurs de comparaison', 'Informations sur les fichiers facultatifs', #
# 'Comparaison avec des solutions analytiques', 'Comparaison avec des codes de calcul' #
# modif fct pour tenir compte des ces ajouts. #
##############################################################################################
my $ version = "1.1" ;
2015-06-26 17:37:18 +02:00
######################################################################################################
#
# PARAMETRES
#
######################################################################################################
#--------------------------------------------------------------------------------
2015-06-26 02:03:28 +02:00
#nom du fichier catalogue de tests
2015-06-26 17:37:18 +02:00
#--------------------------------------------------------------------------------
2015-07-15 13:42:40 +02:00
my $ NOM_PDF_CATALOGUE = "catalogue_tests.pdf" ;
2015-06-26 02:03:28 +02:00
2015-06-26 17:37:18 +02:00
#--------------------------------------------------------------------------------
#encodage du fichier .tex temporaire (rq : notamment pour accepter les accents)
#--------------------------------------------------------------------------------
2015-06-26 02:03:28 +02:00
my $ ENCODAGE_TEX = 'iso-8859-15' ;
2015-06-26 17:37:18 +02:00
#--------------------------------------------------------------------------------
#concernant fichiers README :
#--------------------------------------------------------------------------------
#--liste des rubriques a recopier de chaque README (rq : insensible a la casse)
my @ LISTE_RUBRIQUES_README = ( 'But du test' ,
2017-10-22 12:10:31 +02:00
'Description du calcul' ,
'Grandeurs de comparaison' ,
'Informations sur les fichiers facultatifs' ,
'Comparaison avec des solutions analytiques' ,
'Comparaison avec des codes de calcul'
) ;
my @ LISTE_RUBRIQUES_OBLIGATOIRES = ( 'But du test' ,
'Description du calcul' ) ;
2015-06-26 17:37:18 +02:00
#--nom de la rubrique contenant des mots-cles (rq : insensible a la casse)
my $ NOM_RUBRIQUE_MOTS_CLES = 'Mots-cles' ;
2015-06-29 17:41:12 +02:00
#--nom de la rubrique contenant le ou les auteurs d un test (rq : insensible a la casse)
my $ NOM_RUBRIQUE_AUTEUR = 'Auteur' ;
2015-06-26 17:37:18 +02:00
2015-06-29 17:41:12 +02:00
#--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
2015-06-26 17:37:18 +02:00
2016-02-09 22:43:06 +01:00
#--------------------------------------------------------------------------
# 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 ;
}
2015-06-26 17:37:18 +02:00
2015-06-26 02:03:28 +02:00
#########################################################################################################
# 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" ;
2016-02-12 16:02:51 +01:00
#-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" ;
2015-06-26 02:03:28 +02:00
2015-06-26 17:37:18 +02:00
#verif validite de la commande makeindex
verif_commande ( 'makeindex' ) or die "\nErreur (prog:$NOM_PROG) : commande makeindex introuvable...\n\n" ;
2015-06-26 02:03:28 +02:00
#########################################################################################################
# liste des repertoires de test
#########################################################################################################
2016-09-07 17:02:58 +02:00
#
# RAPPEL : le repertoire Tests_en_attente_debug n est pas concerne (on le squizze avec une option "-not -path" dans la recherche find
#
2015-06-26 02:03:28 +02:00
#liste des repertoires de tests rapides (Test_R)
2016-09-07 17:02:58 +02:00
my @ REP_TESTS_R = map { chomp ( $ _ ) ; $ _ } qx( find . -not -path "*Tests_en_attente_debug*" -name "Test_R*" -type d ) ;
2015-06-26 17:37:18 +02:00
#print "$_\n" for @REP_TESTS_R; exit;
2015-06-26 02:03:28 +02:00
#liste des repertoires de tests rapides (Test_R)
2016-09-07 17:02:58 +02:00
my @ REP_TESTS_L = map { chomp ( $ _ ) ; $ _ } qx( find . -not -path "*Tests_en_attente_debug*" -name "Test_L*" -type d ) ;
2015-06-26 17:37:18 +02:00
#print "$_\n" for @REP_TESTS_L; exit;
2015-06-26 02:03:28 +02:00
#########################################################################################################
# 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 {
2015-06-26 17:37:18 +02:00
warn "\n" if ( not $ is_absence_README ) ; #on passe une ligne si c est le premier repertoire defaillant
2015-06-26 02:03:28 +02:00
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 ) {
2015-06-26 17:37:18 +02:00
warn "\n" ;
2015-06-29 17:41:12 +02:00
afficher_ligne_tirets ( 'warn' ) ;
2015-06-26 17:37:18 +02:00
warn "Erreur (prog:$NOM_PROG) : arret a cause de l absence de fichier(s) README\n" ;
2015-06-29 17:41:12 +02:00
afficher_ligne_tirets ( 'warn' ) ;
2015-06-26 02:03:28 +02:00
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)
#########################################################################################################
2015-07-15 13:42:40 +02:00
#on va creer un repertoire temporaire qui est sense s effacer automatiquement grace a l utilisation de File::Temp->newdir
2015-06-26 02:03:28 +02:00
# le probleme est que si un signal d interruption est envoye (ctrl-c par exemple), le repertoire ne sera pas efface.
2016-02-12 16:02:51 +01:00
# donc, on va egalement capturer certains signaux pour faire un appel a la subroutine sortie_programme()
2015-06-26 02:03:28 +02:00
$ 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()
2015-06-26 17:37:18 +02:00
my $ REP_TMP = File::Temp - > newdir ( "rep_tmp_" . $ NOM_PROG . '_XXXXX' ) ;
2015-06-26 02:03:28 +02:00
my $ racine_fic_latex = "toto" ;
#deplacement vers le repertoire temporaire
2015-06-26 17:37:18 +02:00
chdir $ REP_TMP ;
2015-06-26 02:03:28 +02:00
#------------------------------------------------------------------------------------------
#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 ---
2015-07-15 13:42:40 +02:00
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
2015-06-29 17:41:12 +02:00
print $ HANDLE_TEX "\\clearpage\n" ;
2015-06-26 02:03:28 +02:00
print $ HANDLE_TEX "\\section{Tests rapides}\n" ;
2015-06-26 17:37:18 +02:00
recopie_README ( "R" , $ HANDLE_TEX , \ @ REP_TESTS_R , @ LISTE_RUBRIQUES_README ) ;
2015-06-26 02:03:28 +02:00
#--- tests longs ---
2015-07-15 13:42:40 +02:00
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
2015-06-29 17:41:12 +02:00
print $ HANDLE_TEX "\\clearpage\n" ;
2015-06-26 02:03:28 +02:00
print $ HANDLE_TEX "\\section{Tests longs}\n" ;
2015-06-26 17:37:18 +02:00
recopie_README ( "L" , $ HANDLE_TEX , \ @ REP_TESTS_L , @ LISTE_RUBRIQUES_README ) ;
2015-06-26 02:03:28 +02:00
#------------------------------------------------------------------------------------------
2015-06-26 17:37:18 +02:00
#fin de l ecriture du fichier .tex
2015-06-26 02:03:28 +02:00
#------------------------------------------------------------------------------------------
2015-06-26 17:37:18 +02:00
#ajout de l index (ajout egalement dans le sommaire sans numerotation)
2015-06-29 17:41:12 +02:00
print $ HANDLE_TEX "\\clearpage\n" ;
2015-06-26 17:37:18 +02:00
print $ HANDLE_TEX "\\printindex\n" ; #ecriture de l index
#ajout de \end{document}
2015-06-26 02:03:28 +02:00
print $ HANDLE_TEX "\\end{document}\n" ;
close ( $ HANDLE_TEX ) ;
2015-06-26 17:37:18 +02:00
2016-02-12 16:02:51 +01:00
#
#
#
# a ce stade, le fichier .tex est cree et pret a la compilation
#
#
#
2015-06-26 02:03:28 +02:00
#------------------------------------------------------------------------------------------
2015-06-26 17:37:18 +02:00
#compilation pdflatex (avec index)
2016-02-12 16:02:51 +01:00
# 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)
2015-06-26 02:03:28 +02:00
#------------------------------------------------------------------------------------------
2016-02-12 16:02:51 +01:00
#-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 ( <FTEX1> ) {
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)
#---
2015-06-26 02:03:28 +02:00
print "\n" ;
2015-07-15 13:42:40 +02:00
afficher_ligne_tirets ( 'print' ) ;
2015-06-26 02:03:28 +02:00
print "compilation pdflatex (1ere fois)\n" ;
2015-07-15 13:42:40 +02:00
afficher_ligne_tirets ( 'print' ) ;
sleep 1 ; #petite pause pour laisser a l utilisateur le temps de voir l affichage precedent
2016-02-12 16:02:51 +01:00
system ( "pdflatex -halt-on-error -interaction=nonstopmode $racine_fic_latex.tex > toto.log" ) ;
2015-06-26 02:03:28 +02:00
#-verif presence .pdf
if ( not - e "$racine_fic_latex.pdf" ) {
2016-02-12 16:02:51 +01:00
warn "\nErreur (prog:$NOM_PROG) : erreur a l execution de pdflatex\n" ;
traitement_erreur_latex ( ) ;
2015-06-26 02:03:28 +02:00
sortie_programme ( ) ;
}
2016-02-12 16:02:51 +01:00
#-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 ( ) ;
2015-06-26 17:37:18 +02:00
sortie_programme ( ) ;
}
2015-07-15 13:42:40 +02:00
#---
2016-02-12 16:02:51 +01:00
#-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)
2015-07-15 13:42:40 +02:00
#---
afficher_ligne_tirets ( 'print' ) ;
2015-06-26 02:03:28 +02:00
print "compilation pdflatex (2eme fois)\n" ;
2015-07-15 13:42:40 +02:00
afficher_ligne_tirets ( 'print' ) ;
sleep 1 ; #petite pause pour laisser a l utilisateur le temps de voir l affichage precedent
2015-06-26 17:37:18 +02:00
system ( "rm -f $racine_fic_latex.pdf" ) ;
2016-02-12 16:02:51 +01:00
system ( "pdflatex -halt-on-error -interaction=nonstopmode $racine_fic_latex.tex > toto.log" ) ;
2015-06-26 17:37:18 +02:00
#-verif presence .pdf
if ( not - e "$racine_fic_latex.pdf" ) {
2016-02-12 16:02:51 +01:00
warn "\nErreur (prog:$NOM_PROG) : erreur a l execution de pdflatex\n" ;
traitement_erreur_latex ( ) ;
2015-06-26 17:37:18 +02:00
sortie_programme ( ) ;
}
2015-06-26 02:03:28 +02:00
2016-02-12 16:02:51 +01:00
#
#
#
# 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)
#
#
#
2015-06-26 02:03:28 +02:00
#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" ;
2015-06-29 17:41:12 +02:00
afficher_ligne_tirets ( 'print' ) ;
2015-06-26 02:03:28 +02:00
print "Le fichier $NOM_PDF_CATALOGUE a ete cree...\n" ;
2015-06-29 17:41:12 +02:00
afficher_ligne_tirets ( 'print' ) ;
2015-06-26 02:03:28 +02:00
print "\n" ;
#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2015-06-26 17:37:18 +02:00
#remarque : fin du programme => le repertoire temporaire $REP_TMP sera efface automatiquement
2015-06-26 02:03:28 +02:00
# car utilisation de File::Temp->newdir()
#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#--------------------------------------------------
#subroutine de sortie du programme
#--------------------------------------------------
sub sortie_programme {
2015-06-26 17:37:18 +02:00
#- - - - - - - - -
2015-06-26 02:03:28 +02:00
#effacement du repertoire temporaire (subroutine cleanup() du package File::Temp)
2015-06-26 17:37:18 +02:00
#- - - - - - - - -
# 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/ ) ;
2015-06-26 02:03:28 +02:00
cleanup ( ) ;
exit ;
2015-06-26 17:37:18 +02:00
} #sub sortie_programme
2015-06-26 02:03:28 +02:00
2015-06-26 17:37:18 +02:00
#--------------------------------------------------
#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
#- - - - - - - - -
2015-06-29 17:41:12 +02:00
#label actuel sous forme d un tableau d entier par conversion selon la table $TAB_CONVERT_lettre2pos
2015-06-26 17:37:18 +02:00
my @ tab_label = map { $ TAB_CONVERT_lettre2pos - > { $ _ } } split ( // , $ LABEL_ACTUEL ) ;
my $ nb_chars = $# tab_label + 1 ;
2015-06-29 17:41:12 +02:00
#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 !!!!)
2015-06-26 17:37:18 +02:00
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" ;
2015-06-29 17:41:12 +02:00
afficher_ligne_tirets ( 'warn' ) ;
2015-06-26 17:37:18 +02:00
warn "Erreur (prog:$NOM_PROG) : le nombre de tests de la batterie a atteint son maximum de 26 puissance $nb_chars !!!!!!\n\n" ;
2015-06-29 17:41:12 +02:00
afficher_ligne_tirets ( 'warn' ) ;
2015-06-26 17:37:18 +02:00
warn "\n" ;
sortie_programme ( ) ;
}
2015-06-26 02:03:28 +02:00
2015-06-26 17:37:18 +02:00
#incrementation du label
2015-06-29 17:41:12 +02:00
# 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
2015-06-26 17:37:18 +02:00
$ 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 ) {
2015-06-29 17:41:12 +02:00
#retour a la lettre A pour l indice courant
2015-06-26 17:37:18 +02:00
$ tab_label [ $ i ] = 1 ;
2015-06-29 17:41:12 +02:00
#incrementation de l indice suivant
$ tab_label [ $ i + 1 ] + + if ( $ i != ( $ nb_chars - 1 ) ) ; #sauf si c est le dernier indice
2015-06-26 17:37:18 +02:00
}
else {
last ;
}
}
2015-06-29 17:41:12 +02:00
#-conversion inverse selon la table $TAB_CONVERT_pos2lettre
2015-06-26 17:37:18 +02:00
$ 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
2015-06-26 02:03:28 +02:00
#--------------------------------------------------
2015-06-26 17:37:18 +02:00
#subroutine pour recopier les fichiers README d une
# liste de repertoires de tests vers un fichier ouvert
2015-06-26 02:03:28 +02:00
#--------------------------------------------------
2015-06-26 17:37:18 +02:00
#
# 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)
2015-06-29 17:41:12 +02:00
# - liste des noms de rubriques a recopier
2015-06-26 17:37:18 +02:00
#
# 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" ;
2015-06-29 17:41:12 +02:00
#derniere partie du nom du repertoire (en supprimant le prefixe Test_R_ ou Test_L_)
2015-06-26 17:37:18 +02:00
my $ nom_test = basename $ rep_test ;
2015-06-29 17:41:12 +02:00
$ nom_test =~ s/^Test_[RL]_// ;
2015-06-26 17:37:18 +02:00
$ 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" ;
2015-06-29 17:41:12 +02:00
#- - - - - - - - - - - - - - - -
#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> ;
}
2015-06-26 17:37:18 +02:00
#- - - - - - - - - - - - - - - -
#indexage et ecriture de la liste des mots-cles eventuels de ce test
#- - - - - - - - - - - - - - - -
2015-06-29 17:41:12 +02:00
my @ mots_cles = saisir_mots_rubrique_README ( $ fic_README , $ encodage_source , $ NOM_RUBRIQUE_MOTS_CLES ) ;
2015-06-26 17:37:18 +02:00
if ( $# mots_cles > - 1 ) {
#indexage
#--generation d un label
my $ label_section = genere_label_section ( ) ;
print $ HANDLE_TEX "\\label{$label_section}\n" ;
2015-06-29 17:41:12 +02:00
#--indexage de chaque mot-cle via commande \ind (voir preambule du document latex dans la subroutine preambule_fic_tex_tmp() )
2015-06-26 17:37:18 +02:00
foreach my $ mot_cle ( @ mots_cles ) {
print $ HANDLE_TEX "\\ind{$mot_cle}{$label_section}\n" ;
}
2015-06-29 17:41:12 +02:00
#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> ;
2015-06-26 17:37:18 +02:00
}
#- - - - - - - - - - - - - - - -
#ecriture du nom complet du repertoire sous forme d une arborescence simple
#- - - - - - - - - - - - - - - -
2015-06-29 17:41:12 +02:00
print $ HANDLE_TEX "\\noindent\n" ;
print $ HANDLE_TEX "\\begin{minipage}{\\linewidth}\n" ;
2015-06-26 17:37:18 +02:00
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 ;
}
2015-06-29 17:41:12 +02:00
print $ HANDLE_TEX "\\end{minipage}\n" ;
print $ HANDLE_TEX "\\\\\n\n" ;
2015-06-26 17:37:18 +02:00
#- - - - - - - - - - - - - - - -
#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 ) {
2017-10-22 12:10:31 +02:00
# on regarde si c'est un mot clef obligatoire
my $ obligatoire = 0 ;
foreach my $ toto ( @ LISTE_RUBRIQUES_OBLIGATOIRES )
{ if ( $ rubrique eq $ toto )
{ $ obligatoire = 1 ; last ; } ;
} ;
if ( $ obligatoire )
{ 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 ( ) ;
} ;
2015-06-26 17:37:18 +02:00
}
} #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 {
2015-06-26 02:03:28 +02:00
my $ fic_source = shift ;
my $ encodage_source = shift ;
my $ handle_fic_destination = shift ;
my @ mots_rubriques = @ _ ;
2015-06-26 17:37:18 +02:00
#construction du titre de la rubrique a partir des mots @mots_rubriques
# et d une expression reguliere pour rechercher la rubrique
2015-06-26 02:03:28 +02:00
my $ regexp = shift ( @ mots_rubriques ) ;
2015-06-26 17:37:18 +02:00
my $ nom_rubrique = $ regexp ;
2015-06-26 02:03:28 +02:00
foreach my $ mot ( @ mots_rubriques ) {
$ regexp . = '\s+' . "$mot" ;
2015-06-26 17:37:18 +02:00
$ nom_rubrique . = " $mot" ;
2015-06-26 02:03:28 +02:00
}
2015-06-26 17:37:18 +02:00
#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' ;
2015-06-26 02:03:28 +02:00
open ( my $ Hlocal , "<$encodage_source" , "$fic_source" ) ;
while ( <$Hlocal> ) {
2015-06-26 17:37:18 +02:00
next if ( not /^\s*$regexp\s*$/i ) ; #recherche du bloc correspondant a la rubrique
2015-06-29 17:41:12 +02:00
#normalement, la ligne suivante est une ligne de tirets
2015-06-26 17:37:18 +02:00
$ _ = <$Hlocal> ; chomp ;
2015-06-29 17:41:12 +02:00
#-si ce n est pas une ligne de tirets => echec
2015-06-26 17:37:18 +02:00
if ( not /^\s*-+\s*$/ ) {
$ is_probleme_rubrique = 1 ;
2015-06-29 17:41:12 +02:00
$ message = 'rubrique trouvee mais non conforme (absence de la ligne de tirets apres le nom de la rubrique)' ;
2015-06-26 17:37:18 +02:00
last ;
}
2015-06-26 02:03:28 +02:00
2015-06-26 17:37:18 +02:00
#- - - - - - - - - - - - - - - - - - - - - - - - - - -
#recopie de la rubrique vers le fichier de destination
#- - - - - - - - - - - - - - - - - - - - - - - - - - -
$ is_probleme_rubrique = 0 ;
$ message = 'rubrique trouvee et recopiee avec succes' ;
2015-06-26 02:03:28 +02:00
2015-06-26 17:37:18 +02:00
#creation d une sous-sous-section pour cette rubrique
print $ handle_fic_destination "\\subsubsection{$nom_rubrique}\n" ;
2015-07-16 12:02:00 +02:00
my $ nb_lignes_blanches = 0 ; #variables pour enregistrer les lignes blanches consecutives
2016-08-30 17:11:41 +02:00
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
2015-07-16 12:02:00 +02:00
SUBWHILE:while ( <$Hlocal> ) {
2015-06-29 17:41:12 +02:00
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)
2015-06-26 17:37:18 +02:00
chomp ;
2016-08-30 17:11:41 +02:00
#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 ;
}
2015-07-16 12:02:00 +02:00
#-----------------------------------------------
2016-08-30 17:11:41 +02:00
#cas d une ligne blanche (hors mode "latex brut") => incrementation du compteur et nouveau tour de boucle
2015-07-31 16:51:47 +02:00
#-----------------------------------------------
2016-08-30 17:11:41 +02:00
if ( $ _ =~ /^\s*$/ and not $ latex_brut ) {
2015-07-31 16:51:47 +02:00
$ nb_lignes_blanches + + ;
next ;
}
2016-08-30 17:11:41 +02:00
2015-07-31 16:51:47 +02:00
#-----------------------------------------------
# cas des lignes non blanches
#-----------------------------------------------
2015-11-24 17:27:51 +01:00
#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 ) ;
2015-07-31 16:51:47 +02:00
$ nb_lignes_blanches = 0 ;
2016-08-30 17:11:41 +02:00
#-----------------------------------------------
#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 ;
}
2015-07-31 16:51:47 +02:00
#-----------------------------------------------
2016-08-30 17:11:41 +02:00
#cas special : balise d ajout d une figure (saisie des fichiers figures et de la legende)
2015-07-16 12:02:00 +02:00
#-----------------------------------------------
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!!)
2015-11-24 17:27:51 +01:00
$ legende = traduction_pour_latex_avec_gestion_dollars ( $ legende ) ; #conversion de la legende
2015-07-16 12:02:00 +02:00
#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
2015-07-31 16:51:47 +02:00
# (on regarde si il y a un facteur d echelle a la fin du nom de fichier)
2015-07-16 12:02:00 +02:00
foreach my $ nom_fig ( @ nom_figures ) {
2015-07-31 16:51:47 +02:00
#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
}
2015-11-24 17:27:51 +01:00
#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" ;
}
2015-07-16 12:02:00 +02:00
}
print $ handle_fic_destination "\\caption{$legende}\n" ;
print $ handle_fic_destination "\\end{figure}\n" ;
#nouveau tour de la boucle SUBWHILE
next SUBWHILE ;
}
#-----------------------------------------------
2016-08-30 17:11:41 +02:00
#cas normal : ligne classique
2015-07-16 12:02:00 +02:00
#-----------------------------------------------
else {
2015-07-31 16:51:47 +02:00
#gestion des caracteres ou groupes de caracteres speciaux
2015-11-24 17:27:51 +01:00
my $ texte_a_ecrire = traduction_pour_latex_avec_gestion_dollars ( $ _ ) ;
2015-07-31 16:51:47 +02:00
2015-07-16 12:02:00 +02:00
#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
2015-06-26 17:37:18 +02:00
2015-06-26 02:03:28 +02:00
last ;
}
close ( $ Hlocal ) ;
2015-06-26 17:37:18 +02:00
return ( $ is_probleme_rubrique , $ message ) ;
} #sub recopie_rubrique_README
#--------------------------------------------------
2015-06-29 17:41:12 +02:00
#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
2015-06-26 17:37:18 +02:00
#--------------------------------------------------
#
# en entree :
# - chemin vers le fichier README
# - encodage du fichier README (de la forme ":encoding(nom_encodage)", par exemple : ":encoding(UTF-8)"
2015-06-29 17:41:12 +02:00
# - nom de la rubrique (insensible a la casse)
2015-06-26 17:37:18 +02:00
#
# en sortie :
2015-06-29 17:41:12 +02:00
# - liste de mots ou phrases (i.e les lignes non vides de la rubrique)
2015-06-26 17:37:18 +02:00
#
2015-06-29 17:41:12 +02:00
sub saisir_mots_rubrique_README {
2015-06-26 17:37:18 +02:00
my $ fic_source = shift ;
my $ encodage_source = shift ;
2015-06-29 17:41:12 +02:00
my $ nom_rubrique = shift ;
2015-06-26 17:37:18 +02:00
#construction d une expression reguliere pour rechercher la rubrique
2015-06-29 17:41:12 +02:00
$ nom_rubrique =~ s/^\s+// ;
$ nom_rubrique =~ s/\s+$// ;
my @ mots_rubrique = split ( /\s+/ , $ nom_rubrique ) ;
2015-06-26 17:37:18 +02:00
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...
2015-06-29 17:41:12 +02:00
#liste des lignes non vides de la rubrique $nom_rubrique de ce README
my @ liste_lignes_non_vides ;
2015-06-26 17:37:18 +02:00
open ( my $ Hlocal , "<$encodage_source" , "$fic_source" ) ;
while ( <$Hlocal> ) {
next if ( not /^\s*$regexp\s*$/i ) ; #recherche du bloc correspondant a la rubrique
2015-06-29 17:41:12 +02:00
#normalement, la ligne suivante est une ligne de tirets
2015-06-26 17:37:18 +02:00
$ _ = <$Hlocal> ; chomp ;
2015-06-29 17:41:12 +02:00
#-si ce n est pas une ligne de tirets => echec
2015-06-26 17:37:18 +02:00
if ( not /^\s*-+\s*$/ ) {
last ;
}
#- - - - - - - - - - - - - - - - - - - - - - - - - - -
2015-06-29 17:41:12 +02:00
#saisie des lignes non vides
2015-06-26 17:37:18 +02:00
#- - - - - - - - - - - - - - - - - - - - - - - - - - -
2015-06-26 02:03:28 +02:00
2015-06-26 17:37:18 +02:00
while ( <$Hlocal> ) {
2015-06-29 17:41:12 +02:00
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
2015-06-26 17:37:18 +02:00
chomp ;
s/^\s+// ; s/\s+$// ;
2015-06-26 02:03:28 +02:00
2015-06-26 17:37:18 +02:00
#gestion des caracteres ou groupes de caracteres speciaux
2015-11-24 17:27:51 +01:00
$ _ = traduction_pour_latex_avec_gestion_dollars ( $ _ ) ;
2015-06-26 02:03:28 +02:00
2015-06-29 17:41:12 +02:00
#ajout de la ligne a la liste
push ( @ liste_lignes_non_vides , $ _ ) ;
2015-06-26 17:37:18 +02:00
}
last ;
}
close ( $ Hlocal ) ;
2015-06-29 17:41:12 +02:00
return ( @ liste_lignes_non_vides ) ;
} #sub saisir_mots_rubrique_README
2015-06-26 17:37:18 +02:00
2015-11-24 17:27:51 +01:00
#--------------------------------------------------
#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 ;
}
2015-06-26 17:37:18 +02:00
#--------------------------------------------------
#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
#
2015-11-24 17:27:51 +01:00
sub traduction_pour_latex {
2015-06-26 17:37:18 +02:00
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; )
#--------------------------------------------------------------------------------
#--------------------------------------------------------------------------------
2015-07-31 16:51:47 +02:00
##############################################################################################
### 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 => \#)
2015-06-26 17:37:18 +02:00
$ string =~ s/_/\$\\_\$/g ; #tiret bas (solution : antislash devant + entre dollars)
2016-02-09 22:43:06 +01:00
$ string =~ s/\^($format_reel)/\$\^{$1}\$/g ; #cas d un exposant mathematique : symbole circonflexe suivi d un nombre (solution : entre dollars)
2015-06-26 17:37:18 +02:00
$ string =~ s/([<>])/\$$1\$/g ; #symboles inferieur et superieur (solution : entre dollars)
2016-08-30 17:11:41 +02:00
$ string =~ s/\{/\\{/g ; #accolade ouvrante
$ string =~ s/\}/\\}/g ; #accolade fermante
2015-06-26 17:37:18 +02:00
#ajouter ici d autres cas sous la forme : $string =~ s/bla bla/ha ha/g;
#--------------------------------------------------------------------------------
#--------------------------------------------------------------------------------
return $ string ;
2015-11-24 17:27:51 +01:00
} #sub traduction_pour_latex
2015-06-26 02:03:28 +02:00
2016-02-09 22:43:06 +01:00
#####################################################################################################
2015-06-29 17:41:12 +02:00
#subroutine permettant d ecrire une ligne de tirets de la largeur du terminal
2016-02-09 22:43:06 +01:00
#####################################################################################################
2015-06-26 17:37:18 +02:00
#
# en entree :
# - print ou warn (suivant que l on souhaite afficher avec print (donc vers STDOUT) ou warn (donc vers STDERR)
#
2015-06-29 17:41:12 +02:00
sub afficher_ligne_tirets {
2015-06-26 17:37:18 +02:00
my $ funct_disp = shift ;
2016-02-09 22:43:06 +01:00
( $ 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)
}
2015-06-26 17:37:18 +02:00
2015-06-29 17:41:12 +02:00
my $ ligne_tirets = '' ;
$ ligne_tirets . = '-' for ( 1 .. $ nb_char_largeur_terminal ) ;
2015-06-26 17:37:18 +02:00
2015-06-29 17:41:12 +02:00
print "$ligne_tirets\n" if ( $ funct_disp eq 'print' ) ;
warn "$ligne_tirets\n" if ( $ funct_disp eq 'warn' ) ;
} #sub afficher_ligne_tirets
2015-06-26 02:03:28 +02:00
2016-02-09 22:43:06 +01:00
2015-06-26 02:03:28 +02:00
#--------------------------------------------------
#subroutine d ecriture du preambule du fichier .tex temporaire
#--------------------------------------------------
2015-07-15 13:42:40 +02:00
#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}
2015-06-26 02:03:28 +02:00
sub preambule_fic_tex_tmp {
my $ handle = shift ;
print $ handle ' \ documentclass [ a4paper , 12 pt ] { 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 }
2015-06-26 17:37:18 +02:00
% \ usepackage { eurosym }
2015-06-26 02:03:28 +02:00
\ usepackage { calc }
% \ usepackage { t1enc }
\ usepackage { ifthen }
\ usepackage { lscape }
2015-07-16 12:02:00 +02:00
\ usepackage { float } % paquet pour placer les images correctement avec \ begin { figure } [ H ]
2015-06-26 02:03:28 +02:00
\ 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.1 cm
\ evensidemargin - 0.9 cm
\ topmargin - 1 cm
\ headsep 1 cm
\ textwidth 17 cm
\ textheight 24 cm
\ parindent 0.5 cm
\ raggedbottom
\ sloppy
\ setcounter { tocdepth } { 2 }
\ usepackage { hyperref }
\ hypersetup {
colorlinks = true , % colorise les liens
breaklinks = true , % permet le retour <EFBFBD> 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 }
2015-06-26 17:37:18 +02:00
2016-02-12 16:02:51 +01:00
% 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 )
2015-06-26 17:37:18 +02:00
\ 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 }
2015-07-15 13:42:40 +02:00
% commande suivante pour que l index figure dans la table des matieres
2015-06-26 17:37:18 +02:00
\ makeindex [ intoc ]
2015-06-26 02:03:28 +02:00
\ 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 :
2015-10-01 00:56:53 +02:00
# - chemin absolu de la commande (0 si commande introuvable)
2015-06-26 02:03:28 +02:00
#
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