Processus :

On commence par créer deux nouvelles variables $titre_etiket et $description_etik qui vont contenir la version parsée de nos titres et descriptions actuels. Pour cela on fait appel au sous-programme etiquetage() qui prend notre titre et notre description en paramètre. Dans ce sous programme, on effectue les mêmes opérations sur $titre puis $description : on fait appel à la fonction system() afin de lancer le programme TreeTagger installé sur notre machine.



On utilise de nouveau la fonction system() pour lancer un autre script perl, permettant d'insérer les résultats de l'étiquetage entre des balises sous forme d'un ficher XML :

 
				
			
#!/usr/bin/perl
<<DOC;
Format d\'entree : un texte étiqueté et lemmatisé par tree tagger
Format de Sortie : le même texte au format xml
DOC


# Usage
$ChaineUsage="Usage : treetagger2xml.pl <Fichier>\n";
if (@ARGV!=1) {
 die $ChaineUsage;
}

&ouvre;
&entete;
&traitement;
&fin;
&ferme;

##############################################################################################
# Récupération des arguments et ouverture des tampons
sub ouvre {
    $FichierEntree=$ARGV[0];
    open(Entree,$FichierEntree);
    $FichierSortie=$FichierEntree . ".xml";
    open(Sortie,">$FichierSortie");
}

# Entête de document XML
sub entete {
    print Sortie "<?xml version=\"1.0\" encoding=\"iso-8859-1\" standalone=\"no\"?>\n";
    print Sortie "<document>\n";
    print Sortie "<article>\n";
}

# Traitement
sub traitement {
    while ($Ligne = <Entree>) {
	if ($Ligne!~/\ô\¯\:\\ô\¯\:\\/) {
	# 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
sub fin {
    print Sortie "</article>\n";
    print Sortie "</document>\n";
}

# Fermeture des tampons
sub ferme {
    close(Entree);
    close(Sortie);
}



On va enfin pouvoir utiliser la variable $titredescriptionglobal créée plus tôt et qui résulte de la concaténation de $titre et $description. On utilise la fonction system() pour lancer le programme Talismane. On y fait une dernière fois appel pour convertir notre texte annoté en document XML correctement formé. On utilisera le script suivant :

 
	

my $first=0;
my $firstSentence=0;
open(INPUT,"<:encoding(utf-8)",$ARGV[0]);
open(OUTPUT,">:encoding(utf-8)","$ARGV[0].xml");
print OUTPUT "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
print OUTPUT "<basetalismane>\n";
my $first=0;
while (my $ligne=<INPUT>) {
	next if ($ligne=~/^$/);
	if ($ligne=~/^([^\t]*)	([^\t]*)	([^\t]*)	([^\t]*)	([^\t]*)	([^\t]*)	([^\t]*)	([^\t]*)	([^\t]*)	([^\t]*)$/) {
		my $a1=$1;
		my $a2=$2;
		my $a3=$3;
		my $a4=$4;
		my $a5=$5;
		my $a6=$6;
		my $a7=$7;
		my $a8=$8;
		my $a9=$9;
		my $a10=$10;
		chomp($a1);chomp($a2);chomp($a3);chomp($a4);chomp($a5);chomp($a6);chomp($a7);chomp($a8);chomp($a9);chomp($a10);
		$a1=~s/&/&amp;/g;
		$a2=~s/&/&amp;/g;
		$a3=~s/&/&amp;/g;
		$a4=~s/&/&amp;/g;
		$a5=~s/&/&amp;/g;
		$a6=~s/&/&amp;/g;
		$a7=~s/&/&amp;/g;
		$a8=~s/&/&amp;/g;
		$a9=~s/&/&amp;/g;
		$a10=~s/&/&amp;/g;
		if ($a1 == 1) {
			if ($first > 0) {print OUTPUT "</p>\n";}
			print OUTPUT "<p>\n";
		}
		$first++;
		print OUTPUT "<item><a>$a1</a><a>$a2</a><a>$a3</a><a>$a4</a><a>$a5</a><a>$a6</a><a>$a7</a><a>$a8</a><a>$a9</a><a>$a10</a></item>\n";
	}
}
close(INPUT);
print OUTPUT "</p>\n</basetalismane>\n";
close(OUTPUT);



C'est ici que s'achève notre script, on va pouvoir passer à l'extraction de patrons morpho-syntaxiques. Voici la version complète ci-dessous pour les curieux :

 
	

#/usr/bin/perl
<<DOC; 
2020
 usage : perl parcours-arborescence-fichiers repertoire-a-parcourir rubrique
 Le programme prend en entrée le nom du répertoire-racine contenant les fichiers
 à traiter et le nom de la rubrique à traiter parmi ces fichiers
DOC
#-----------------------------------------------------------
my $rep="$ARGV[0]";
my $rubrique ="$ARGV[1]";
# on s'assure que le nom du répertoire ne se termine pas par un "/".
$rep=~ s/[\/]$//;
open(OUT,">:encoding(utf8)","sortie-slurp_$rubrique.txt");
open(OUTXML,">:encoding(utf8)","sortiexml-slurp_$rubrique.xml");
open(OUTTALISMANE,">:encoding(utf8)","sortietalismane-slurp_$rubrique.txt");
print OUTXML "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n";
print OUTXML "<corpus2019>\n";
my %dico_des_titres=();
#----------------------------------------
&parcoursarborescencefichiers($rep);	#recurse!
system("perl talismane2xml.pl sortietalismane-slurp_$rubrique.txt");
#----------------------------------------
print OUTXML "</corpus2019>\n";
close OUT;
close OUTXML;
close OUTTALISMANE;
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) {
			if ($file =~/$rubrique.+xml$/) {
				print $i++," Traitement de : ",$file,"\n";
				open(FIC,"<:encoding(utf8)",$file);
				$/=undef;     #ou $\=""
				my $textelu=<FIC>;
				close FIC;
                # 1. initialisation du texte global
                my $titredescriptionglobal="";
				while ($textelu=~/<item>.*?<title>(.+?)<\/title>.+?<description>(.+?)<\/description>/sg) {
					my $titre=$1;
					my $description=$2;
					if (!(exists $dico_des_titres{$titre})) { 
					$dico_des_titres{$titre}=$description ;
					# Appel du sous-programme de nettoyage 
					($titre,$description)=&nettoyage($titre,$description);
                    $titredescriptionglobal=$titredescriptionglobal.$titre."\n";;
                    $titredescriptionglobal=$titredescriptionglobal.$description."§\n";
					my ($titre_etiket,$description_etiket)=&etiquetage($titre,$description);
					# Ecriture des résultats en sorties
					print OUT $titre,"\n";
					print OUT $description,"\n";
					print OUTXML "<item><titre>$titre_etiket</titre><description>$description_etiket</description></item>\n";
					}
				}
                # 2. lancement de talismane sur $titredescriptionglobal
                # actuellement les données à annoter sont dans une variable
                # il faut donc les mettre dans un fichier
                open(TALIS,">:encoding(utf8)","bao1_test.txt");
                print TALIS $titredescriptionglobal;
                close TALIS;
                # lancer talismane :
                system("java -Xmx1G -Dconfig.file=TALISMANE/talismane-fr-5.2.0.conf -jar ./TALISMANE/talismane-core-5.3.0.jar --analyse --sessionId=fr --encoding=UTF8 --inFile=bao1_test.txt --outFile=bao1_test.tal");
                
                # intégrer le resultat de l'annotation précédente dans le fichier global talismane
                open(TEMP, "<:encoding(utf8)", "bao1_test.tal");
                $temp=<TEMP>;
                close TEMP;
                print OUTTALISMANE $temp;
                               
			}
		}
    }
}
#----------------------------------------------
sub nettoyage {
    my $titre = $_[0];
    my $description = $_[1];
	$titre=~s/^<!\[CDATA\[//;
	$titre=~s/\]\]>$//;
	$description=~s/^<!\[CDATA\[//;
	$description=~s/\]\]>$//;
    $description=~s/&lt;.+?&gt;//g;
    $description=~s/&#38;#39;/'/g;
    $description=~s/&#38;#34;/"/g;
    $titre=~s/&lt;.+?&gt;//g;
    $titre=~s/&#38;#39;/'/g;
    $titre=~s/&#38;#34;/"/g;
    $titre=~s/$/\./g;
    return $titre,$description;
}
#----------------------------------------------
sub etiquetage {
    my $titre = $_[0];
    my $description = $_[1];
	#-----------------etiquetage titre-----------------------------
	open (ETI, ">:encoding(utf8)", "temporaire.txt");
    print ETI $titre;
    close ETI;
    system ("perl -f tokenise-utf8.pl temporaire.txt | ./treetagger/bin/tree-tagger ./treetagger/french-spoken.par -token -lemma -no-unknown > test.txt.pos");
    system ("perl treetagger2xml.pl test.txt.pos utf8"); #résultats dans test.txt.pos.xml
    open (TEMP, "<:encoding(utf8)", "test.txt.pos.xml");
    $/=undef;
    my $titre_etik_xml=<TEMP>;
    close TEMP;
    $titre_etik_xml=~s/^<\?xml[^>]+>//;
	#-----------------etiquetage description-----------------------------
    open (ETI, ">:encoding(utf8)", "temporaire.txt");
    print ETI $description;
    close ETI;
    system ("perl -f tokenise-utf8.pl temporaire.txt | ./treetagger/bin/tree-tagger ./treetagger/french-spoken.par -token -lemma -no-unknown > test.txt.pos");
    system ("perl treetagger2xml.pl test.txt.pos"); #résultats dans test.txt.pos.xml
    open (TEMP, "<:encoding(utf8)", "test.txt.pos.xml");
    $/=undef;
    my $description_etik_xml=<TEMP>;
    close TEMP;
    $description_etik_xml=~s/^<\?xml[^>]+>//;
    return $titre_etik_xml,$description_etik_xml;
}
#-----------------------------------------------------------------------



Voici également les fichier XML obtenus en sortie :