#/usr/bin/perl
<<DOC; 
Nom: Egle Ramdani
FEVRIER 2006
Usage : perl inrep-outxml.pl répértoire-à-parcourir
Le programme prend en entrée le nom du répertoire contenant les fichiers à traiter
L'information trouvé dans la balise <description> est extrait, puis étiquetée avec Tree-Tagger.
La sortie est un fichier structuré contenant sur chaque ligne le nom du fichier et le résultat du filtrage:
<FICHIER>
<NOM>nom du fichier</NOM>
<CONTENU>
<ELEMENT>
<DATA type="forme">forme</DATA>
<DATA type="lemme">lemme</DATA>
<DATA type="cat">catégorie</DATA>
</ELEMENT>
</CONTENU>
</FICHIER>
Les sorties secondaires sont 
1. une arborescence qui contient les fichiers étiquetables par Tree-Tagger
2. un fichier qui contient la sortie brute de Tree-Tagger
DOC

# récupération du nom du répertoire ------------------------------------------------------------------
my $rep="$ARGV[0]";
# on s'assure que le nom du répertoire ne se termine pas par un "/"
$rep=~ s/[\/]$//;

#ouverture et entête du fichier xml ------------------------------------------------------------------
open (XMLOUT, ">treetaggerXML.xml");
open (OUTTAG, ">outtag.txt");
print XMLOUT "<?xml version=\"1.0\" encoding=\"iso-8859-1\" ?>\n";
print XMLOUT "<?xml-stylesheet type=\"text/xsl\" href=\"style_etiquetage_treetagger.xsl\"?>\n";
print XMLOUT "<PARCOURS>\n";
print XMLOUT "<ETIQUETEUR>Egle Ramdani</ETIQUETEUR>\n";

# lancement de la procédure qui parcours l'arborescence -----------------------------------------------
&parcoursarborescencefichiers($rep);

# fermeture du fichier XML ---------------------------------------------------------------------------
print XMLOUT "</PARCOURS>";
close(XMLOUT); 
exit;

#parcours de l'arborescence en recherche des fichiers ------------------------------------------------
sub parcoursarborescencefichiers {
    # récupération du chemin du dossier à parcourir
    my $path = shift(@_);
    # ouverture du dossier ou message d'erreur
    opendir(DIR, $path) or die "Impossible d'ouvrir $path: $!\n";
    # lecture du dossier et affectation des items trouvés à un tableau scalaire
    my @items = readdir(DIR);
    # fermeture du dossier
    closedir(DIR);
    # pour chaque item trouvé on fait le suivant:
    foreach my $item (@items) {
        next if $item =~ /^\.\.?$/;
        # on donne à l'item le chemin à partir du dossier initial
        $item = $path."/".$item;
        # si l'item en question est un dossier, on répète le traitement effectué
        if (-d $item) {
            # récursion 
            &parcoursarborescencefichiers($item);
        }
        # si l'item en question est un fichier on applique un traitement différent
        if (-f $item) {
            # incrémentation du numéro de fichier
            $nr++;
            # appelle de la procédure pour les problèmes du codage et de format
            $pourtagger = &traitementtypo($item, $nr);
            # définition du chemin du fichier de sortie temporaire de Tree-Tagger
            my $outtagtemp = "OUTtag/".$nr."outtag.txt";
            # lancement de Tree-Tagger
            system `./bin/tree-tagger.exe -token -lemma -no-unknown ./lib/french.par ./$pourtagger $outtagtemp`;
            # spécification du nom du fichier originel dans le fichier qui regroupe tous les résultats d'étiquetage
            print OUTTAG "$item\n";
            # initialisation d'une variable temporelle
            my $temp = "";
            # ouverture du fichier crée par Tree-Tagger
            open (TEMP, "$outtagtemp") or die "Impossible d'ouvrir le fichier $outtagtemp: $!\n";
            # lecture de ce fichier ligne par ligne
            while (my $ligne=<TEMP>){
                # on évite les lignes "non utiles" crées par Tree-Tagger
                if ($ligne!~/\ô\¯\:\\ô\¯\:\\/) {
                    # copie de la ligne courante dans le fichier de résultats
                    print OUTTAG "$ligne";
                    # remplacement des guillemets par <![CDATA["]]> (évite erreur d'interprétation XML)
                    $ligne=~s/\"/<![CDATA[\"]]>/g;
                    # définition des parties de la ligne qui nous intéressent (on évite les tabulations et le retour-chariot!)
                    $ligne=~/([^\t]*)\t([^\t]*)\t([A-Za-zéèêëàâôöäùûç,.!?]*)/;
                    # création d'un élément dans le fichier XML (inversion pour harmoniser le format avec celle du Cordial)
                    $temp.="<ELEMENT><DATA type=\"forme\">$1<\/DATA><DATA type=\"lemme\">$3<\/DATA><DATA type=\"cat\">$2<\/DATA><\/ELEMENT>";
                }
            }
        print XMLOUT "<FICHIER><NOM>$item</NOM><CONTENU>$temp</CONTENU></FICHIER>\n";
        close(TEMP);
        # suppression du fichier temporel
        unlink $outtagtemp;
        # comptage des fichiers traités
        print $i++,"\n";
    }
    }
}
# traitement des problèmes typographiques, du codage et du format de fichier ----------------------------------------------
sub traitementtypo {
    # récupération du chemin et le numéro du fichier
    my $chemin = shift;
    my $nom = shift;
    # définition du chemin pour le fichier de sortie
    my $intag="INtag/".$nom."intag.txt";
    # création du fichier de sortie
    open (INTAG, ">$intag");
    # ouverture du fichier indiqué par le chemin
    open (INPUT, "$chemin") or die "Impossible d'ouvrir le fichier $chemin: $!\n";
    while (my $ligne = <INPUT>){
        # traitement du contenu de la balise description
        if ($ligne=~/<description>([^<]+)<\/description>/) {
            $des = $1;
            if ($des ne "Toute l'actualité au moment de la connexion"){
                $des=~s/http\S+//g; #on enlève les liens html
                $des=~s/([^\.]$)/\1./g; #on s'assure que chaque ligne se termine par un point
                $des=~s/\.([A-Z])/. \1/g; #on s'assure qu'il y ait un espace entre les phrases
                $des=~s/([A-Za-zéèêëàâôöäùûç])\./\1 ./g; #on s'assure qu'il y ait une espace avant le point
                $des=~s/([A-Za-zéèêëàâôöäùûç]),/\1 ,/g; #on s'assure qu'il y ait une espace avant la virgule
                $des=~s/&\#38\;\#39\;/\'/g;
                $des=~s/&\#38\;\#34\;/"/g;
                $des=~s/&\#233\;/é/g;
                $des=~s/&\#234\;/ê/g;
                $des=~s/àª/ê/g;
                $des=~s/é/é/g;
                $des=~s/ô/ô/g;
                $des=~s/è/è/g;
                $des=~s/Ã/à/g;
                $des=~s/à§/ç/g;
                $des=~s/([A-Za-z]+\')([^h])/\1 \2/g; #division des chaînes contenant les apostrphes
                $des=~s/[^A-Za-zéèêëàâôöäùûç'.,!?]+/\1\n/g; #réorganisation du fichier: sortie=un mot par ligne
                # impression du résultat du "nettoyage"
                print INTAG "$des\n";
            }
        }
    }
    close(INTAG);
    # la procédure retourne le chemin vers le fichier crée
    return $intag;
}