use strict; use iterd; # parcours une arborescence use tagger; # encapsulation tree-tagger er Cie use XML::XPath; use XML::LibXML; use File::Basename; # # Usage : perl fils2text.pl /tmp/nuages/2006 /tmp/resdata /home/yan/treetager/cmd/tree-tagger-french # # my $rep="$ARGV[0]"; # Nom du répertoir à parcourir #$rep="//rech2/PLURITAL/PROJET-ENCADRE-2005-2006/NUAGES/DVD/fils-presse-archivage/2006/Feb/1";####ILPGA $rep=~ s/[\/]$//; # # 1. directory des résultats # my $resultdir = "$ARGV[1]" ; #$resultdir="resdata";######ILPGA # # 2. La commande pour étiqueter # my $tagcmd="$ARGV[2]"; #$tagcmd="C:/TreeTagger/bin/tree-tagger.exe";#####ILPGA if ( ! (-f $tagcmd && -x $tagcmd ) ) { print "Fichier $tagcmd introuvable ou non executable \n "; exit; } # system ( sprintf ("mkdir -p %s" , $resultdir ) ); # # fichier qui va cumuler le texte à étiqueter # my $filetotag = "$resultdir/filetotag"; #open (HANDLETAG,">$filetotag") or die("$!");#####ILPGA open (HANDLETAG,">:utf8",$filetotag) or die("$!"); my $refhand = \*HANDLETAG ; # # Le fichier piur l'info mutuelle # my $imfile = "$resultdir/im.win"; #open (IM,">$imfile") or die("$!");#####ILPGA open (IM,">:utf8",$imfile) or die("$!"); # # # NBR (globale ) sert de compteur pour indexer les fichiers à l'intérieur d'une archive. # my $NBR = 0 ; # # On crée un itérateur ( voir classe iterd ci joint ) pour parcourir l'arborescence. # il appellera la fonction extract ( ci dessous ) sur chaque fichier # en lui passant l'info dont elle a besoin. # print "Parcours et extraction de $rep \n"; my $walker = new iterd(); $walker->setFunction ( \&extract ) ; #my $data = {'filetotag' => $refhand , 'fromfile' => $mapfromfile }; my $data = {'filetotag' => $refhand }; $walker->setData ($data) ; $walker->traverse($rep) ; close ($refhand) ; # print " Le cumul est fait . On coupe et On étiquette \n" ; # my $segments ; # # $^O contient le nom de l'OS ça ne s'invente pas .. # if ( $^O eq "linux" ) { $segments = [ $filetotag ]; } else { $segments = splitag ( $filetotag , 25 ); } # # On créé un tagger , une seule instance pour tous les fichiers à tagger. # my $tagger = new tagger(); $tagger->setCommand ( $tagcmd ); # # mark est le séparateur entre les différents sections "Description" # Il contient le nom du fichier d'où la section provient # my $mark = '^__{FROMFILE[0-9]+'. $rep . '/([^}]+)}__$'; foreach my $ftotag (@$segments) { my $resultag = "$ftotag"."_t"; # print "tree-tagger sur $ftotag dans $resultag \n"; # $tagger->setTextAsFile ($ftotag); $tagger->setOutFile ($resultag); $tagger->process(); # # On lit le résultat de l'étiquetage et on crée un fichier xml correspondant au fils # en cours de traitement # la structure ainsi crée est parallèle à celle que l'on a en entrée. # # open(FIC,"<$resultag") ; my $l ; my $dom = undef ; my $root = undef ; my $fullp = undef ; my $dirnm = undef ; while ( defined( $l = ) ) { chomp $l; my @tab = (); @tab = split (/\t/ , $l); if ( $tab[0] =~ m|$mark| ) { #__{FROMFILE1/tmp/nuages/2006/Jan/18/23-30-00/0,2-3208,1-0,0.xml}__ VER:pper # toFile du précédent document et compression # alloc du nouveau if ( defined ( $dom ) ) { $dom->toFile($fullp, 2); system ( sprintf ("gzip -f %s" , $fullp) ); } else { $dom = XML::LibXML::Document->createDocument( "1.0", "UTF-8" ); $root = $dom->createElement( "etik" ); $dom->setDocumentElement( $root ); } $fullp = "$resultdir". "/". $1 ; $dirnm = dirname($fullp) ; system ( sprintf ("mkdir -p %s" , $dirnm) ) ; print IM "\n"; } else { my $word = $dom->createElement("w"); if ( $tab[2] =~ m// ) { $word->setAttribute("lemma","unknown"); } else { $word->setAttribute("lemma",$tab[2]); if ( ($tab[1] ne "PUN") && ($tab[1] ne "SENT") && ($tab[1] ne "NUM")) { print IM sprintf("%s_%s\n",$tab[2],$tab[1]); } } $word->setAttribute("type",$tab[1]); $word->appendTextNode( $tab[0] ); $root->appendChild($word); } } # # dernier mkdir, dernier toFile et compression # system ( sprintf ("mkdir -p %s" , $dirnm) ) ; $dom->toFile($fullp, 2); system ( sprintf ("gzip -f %s" , $fullp) ); # On peut jeter le fichier resultat. close ( FIC ) ; unlink $ftotag; unlink $resultag; } close ( IM ) ; # print "Le corpus a été étiqueté dans $resultdir \n"; print "L'info mutuelle est dans $imfile \n"; unlink $filetotag; # exit ; # #FIN ######################################################################################### # # Fonction extract: # # Elle est appelée sur chaque fichier xml de l'arborescence. # Elle recoit 2 arguments : # $file : le fichier à traiter ( extraire le texte de la balise "description" ) # data->filetotag : le fichier dans lequel écrire le texte extrair # sub extract { my ($file,$data) = @_; my $filetotag = $data->{filetotag}; # # 1.On crée un filtreur pour $file #$mot =~ m/__\{FROMFILE[0-9]+\}__/ # seuls les noms de la forme 0,2-3208,1-0,0.xml # if ( $file !~ /\d+,\d+-\d+,\d+-\d+,\d+\.xml$/ || -z $file ) { return ; } print "Processing : $file \n"; my $xp; my @tabres ; eval { $xp = XML::XPath->new(filename => $file ); @tabres = $xp->findnodes('//item/description/text()'); }; if ($@) { warn "XPath exception pour $file : $@ \n"; return ; } # # le tableau tabres contient le texte des # balises "description". Après un nettoyage sommaire # On écrit tout ça dans $filetotag # $NBR++ ; my $key = "__{"."FROMFILE"."${NBR}".$file."}__" ; print $filetotag "$key\n" ; foreach my $node (@tabres) { my $v = $node->toString() ; if ( $v !~ /http:\/\/www\.lemonde\.fr/ ) { print $filetotag "$v\n"; } } return ; } ######################################################################################### # # Fonction splitag: # # Elle est appelée sur Windows pour segmenter le résultat de l'extraction. # Elle retourne ( une référence vers ) la liste des pathes des segments. # # Elle recoit 2 arguments : # $tagfile : le fichier à traiter # $NSIZE : le nombre de balises à cumuler dans un segment. # sub splitag { my ($tagfile,$NSIZE) = @_; # my $dirtagfile = dirname($tagfile); # # la reference à retourner my $refseg = () ; # # 1. On ouvre le fichier à découper # open(TAGFILE,"<$tagfile") or die("$!"); # # Le fichier $tagfile contient toutes les balises "description". Il est # structuré de façon à pouvoir retrouver à quels fils appartient un texte. # my $extcur = 1 ; my $current= 0 ; my $line ; my $curfile = $dirtagfile . "/" . $extcur ; open(CURFILE,">$curfile") or die("$!"); while ( defined( $line = ) ) { chomp $line; if ( $line =~ /^__{FROMFILE([0-9]+)/ ) { $current++ ; if ( $current > $NSIZE ) { $current = 0 ; push ( @{$refseg} , $curfile ) ; close ( CURFILE ) ; $extcur++; $curfile = $dirtagfile . "/" . $extcur ; open(CURFILE,">$curfile") or die("$!"); } } print CURFILE "$line\n" ; } close ( CURFILE ) ; close ( TAGFILE ) ; push ( @{$refseg} , $curfile ) ; return $refseg ; }