Programme TreeTagger

Les parties ajoutées au squelette du programme de départ sont détaillées ci-dessous sinon le programme perl est téléchargeable ici.


#/usr/bin/perl
my $rep="$ARGV[0]";
# on s'assure que le nom du répertoire ne se termine pas par un "/"
$rep=~ s/[\/]$//;
# on initialise une variable contenant le flux de sortie
my $DUMPFULL1="";
#----------------------------------------
my $output1="SORTIE.xml";
if (!open (FILEOUT,">$output1")) { die "Pb a l'ouverture du fichier $output1"};

# On crée une variable $output2 qui va contenir le nom du fichier SORTIE.txt.
# Ce fichier contiendra tous les mots contenus sur une ligne différente.
my $output2="SORTIE.txt";

# Si le fichier SORTIE.txt ne peut s'ouvrir ce message apparait.
if (!open (OUTPUT2,">$output2")) { die "Pb a l'ouverture du fichier $output2"};

# On crée une variable $output3 qui va contenir le nom du fichier mot.txt.
# Ce fichier contiendra l'analyse au fur et à mesure de TreeTagger.
my $output3="mot.txt";

# Si le fichier mot.txt ne peut s'ouvrir ce message apparait.
if (!open (OUTPUT3,">$output3")) { die "Pb a l'ouverture du fichier $output3"};

#----------------------------------------
&parcoursarborescencefichiers($rep);    #recurse!
#----------------------------------------
print FILEOUT "<?xml version=\"1.0\" encoding=\"iso-8859-1\" ?>\n";
print FILEOUT "<PARCOURS>\n";
print FILEOUT "<NOM>PICARD</NOM>\n";
print FILEOUT "<FILTRAGE>".$DUMPFULL1."</FILTRAGE>\n";
print FILEOUT "</PARCOURS>\n";

# On imprime dans le fichier SORTIE.txt le contenu de la variable $cont.
# Dans ce fichier, tous les mots seront chacun sur une ligne.
print OUTPUT2 $cont;

close(FILEOUT);
close(FILEOUT2);
exit;
#----------------------------------------------
sub parcoursarborescencefichiers {
    my $path = shift(@_);
    opendir(DIR, $path) or die "can't open $path: $!\n";
    my @files = readdir(DIR);
    closedir(DIR);
    foreach my $file (@files) {
    next if $file =~ /^\.\.?$/;
    $file = $path."/".$file;
    if (-d $file) {
        &parcoursarborescencefichiers($file);    #recurse!
    }
    if (-f $file) {
# On appelle deux sous programmes indiqués par &.
        &ouvre;
        &entete;

        open (FILEIN,"$file");

# On va ouvrir le fichier outtagger.txt en réécriture (on pourra écrire dedans et
# à chaque nouveau rajout, ce rajout s'inscrira à la suite de l'ancien).
        open (FICHIER, ">>outtagger.txt");

# On imprime dans le fichier outtagger.txt les balises indiquées entre
# guillemets et entre, le contenu de la variable $file, cad le nom du fichier
# qui est ouvert.
        print FICHIER "<fichier>\n <name>".$file."</name>\n";

# On ferme le fichier outtagger.txt.
        close (FICHIER);

# Le programme est le même que celui du filtrage. Seulement ce qui a été inséré sera
# détaillé.
        while ($ligne = <FILEIN>){
        if ($ligne=~/<description>([^<]+)<\/description>/) {

            $filtr= "<FICHIER><NOM>".$file."</NOM><CONTENU>".$1."</CONTENU></FICHIER>";

# La variable $contenu contient le contenu de la variable $1 suivi d'un saut de ligne.
            $contenu =$1."\n";

# On va rechercher et remplacer certains caractères dans la variable $contenu afin
# de mettre un mot ou une ponctuation par ligne. Mais aussi afin remplacer le codage
# de certains accents. Ce mauvais codage ne posera pas de problème à TreeTagger
# mais il en posera un avec Cordial qui les analysera comme étant un mot à part.
# Dans une optique d'automatisation des tâches, ce programme perl va permettre 
# l'étiquetage avec TreeTagger et la sortie des résultats dans un fichier xml mais
# aussi la sortie d'un fichier un mot sur chaque ligne qui sera utilisé par
# Cordial tout de suite après.
# J'ai choisi segmenter les mots en fonction des délimiteurs que je garde (d'où $1).
            $contenu=~s/(['":!\?\.\-\(\)\[\]\{\}\-])/\n$1\n/g;
                    $contenu=~s/(&#38;#39;)/\n'\n/g;
            $contenu=~s/(&#38;#34;)/\n"\n/g;
            $contenu=~s/([,])/\n$1/g;
            $contenu=~s/(é|&#233;)/é/g;
            $contenu=~s/&#234;/ê/g;
            $contenu=~s/è/è/g;
            $contenu=~s/ô/ô/g;
            $contenu=~s/Ã[^.*]/à/g;
            $contenu=~s/[ ]/\n/g;

# On imprime le contenu de la variable $contenu soit un mot par ligne
# dans le fichier mot.txt (qui sera utilisé pour l'étiquetage avec TreeTagger.

                print OUTPUT3 $contenu;

# On ferme le fichier mot.txt.
                close (OUTPUT3);

# On crée une variable $texte qui contiendra le nom du fichier mot.txt.
# on lance TreeTagger avec ces options et paramètres dont la variable
# $texte qui contient le nom du fichier sur lequel on va appliquer
# TreeTagger, et le fichier de sortie en réécriture outtagger.txt.
# Le fichier mot.txt contient le contenu morcelé (un mot par ligne)
# textuel d'une balise description. À chaque nouvelle balise description
# ou nouveau fichier, le contenu du fichier mot.txt s'efface et se réécrit.
# C'est pourquoi à la fin il est vide.
# TreeTagger ne permettant pas l'analyse de plus de 200 mots et comme
# chaque balise description contient moins de 200 mots, ce système
# permet une analyser correcte et sans problème.
                my $texte="mot.txt";
                    $ENV{'PATH'} = "./bin;";
                    system("set $ENV{'PATH'}");
                    system("./bin/tree-tagger.exe -token -lemma -no-unknown ./lib/french.par $texte >>outtagger.txt");


# On appelle le sous-programme traitement.
            &traitement;
 
# On ouvre le fichier mot.txt en écriture et seulement en écriture.
# Toute nouvelle information imprimée dans ce fichier détruira les
# informations précédentes.
            open (OUTPUT3,">mot.txt");
          
          
                    $DUMPFULL1 = $DUMPFULL1 . $filtr ;


# On concatène la variable $contenu à la variable $cont.
# La variable $contenu comprend le contenu d'une description qui vient
# d'être modifié et la variable $con, les contenus des autres descriptions
# prises en compte et déjà modifié.
# Au final $cont contiendra l'ensemble des contenus modifiés des balises
# descriptions cad un mot par ligne.
             $cont=$cont.$contenu;
        
              }
          }
# On ouvre le fichier outtagger.txt en réécriture et on y imprime
# ce qu'il y a entre guillemets. Puis on ferme ce fichier.
     open (FICHIER, ">>outtagger.txt");
     print FICHIER "</fichier>\n";
     close (FICHIER);

     close (FILEIN);
     print $i++,"\n";
         }

# on appelle deux sous-programmes.
   &fin;
   &ferme;                  
   }
}
#----------------------------------------------
# Récupération des arguments et ouverture des tampons
# Le sous-programme suivant permet d'ouvrir deux fichiers et de
# renvoyer leur nom à des variables.
sub ouvre {
    my $FichierEntree="outtagger.txt";
    open(Entree,$FichierEntree);
    $FichierSortie=$FichierEntree . ".xml";
    open(Sortie,">$FichierSortie");
}

# Entête de document XML
# On imprime dans le fichier xml ces balises.
sub entete {
    print Sortie "<?xml version=\"1.0\" encoding=\"iso-8859-1\" standalone=\"no\"?>\n";
    print Sortie "<PARCOURS>\n";
    print Sortie "<NOM>PICARD</NOM>\n";
    print Sortie "<ETIQUETAGE>\n";   
}

# Traitement
sub traitement {
    while ($Ligne = <Entree>)
    {
    if ($Ligne!~/\ô\¯\:\\ô\¯\:\^C\^Q/) {
        # Remplacement des guillemets par <![CDATA["]]> (évite erreur d'interprétation XML)
        $Ligne=~s/\"/<![CDATA[\"]]>/g;
        $Ligne=~s/([^\t]*)\t([^\t]*)\t(.*)/<element>\n <data type=\"type\">$2<\/data>\n <data type=\"lemma\">$3<\/data>\n <data type=\"string\">$1<\/data>\n<\/element>/;
        print Sortie $Ligne;
    }
    }
}


# Fin de fichier
# On imprime dans le fichier xml ces balises.
sub fin {
print Sortie "</fichier>\n";
    print Sortie "</ETIQUETAGE>\n";
    print Sortie "</PARCOURS>\n";
}


# Fermeture des tampons
# On ferme les fichiers qu'on a ouvert lors du sous-programme.
# sub ouvre.
sub ferme {
    close(Entree);
    close(Sortie);
}