Un glossaire automatique

Le but est d’obtenir un glossaire automatique de différents termes, gérant notamment la reconnaissance par expressions régulières.

Présentation

J’ai commencé à coder ce petit glossaire car je n’étais pas satisfait de ceux que j’avais pu trouver auparavant. Ce que je désirais :

  • une reconnaissance des mots par expression régulière (ainsi insensibilité à la casse, permet de sélectionner une même définition pour des termes différents)
  • la définition d’un mot s’affiche lorsque l’on passe la souris au dessus, ou en lien hypertexte si la définition est trop longue.
  • pouvoir gérer plusieurs ensembles de définitions, avec des définitions différentes pour le même mot.
    L’intérêt est de pouvoir utiliser un jeu de définitions ou un autre suivant le public auquel s’adresse l’article (langue, niveau technique, etc). Dans mon cas, le glossaire est utilisé sur un site de jeux de rôle, et nous avions donc besoin d’une définition pour les joueurs et une pour les maîtres, chacun ne devant lire que celle le concernant.

Il est intéressant de noter que le remplacement du terme n’a pas lieu si celui-ci se trouve dans un tag HTML, pour éviter par exemple de briser un lien hypertexte.

Pour un exemple d’article utilisant ce glossaire, consultez cet article.

Mise en place

  • Créez tout d’abord une rubrique glossaire, et une sous rubrique par jeu de définitions (par exemple utilisateurs débutants, utilisateurs avancés, etc).
  • Créez ensuite le groupe de mots clés Audience, et créez-y un mot-clé pour chaque sous rubrique créée auparavant.
  • Créer les mots clés glossaire et glossaire_un : le premier indique que vous souhaitez afficher les définitions de tous les termes disponibles, le second indique de ne le faire que sur la première occurence de chaque terme.
  • Rajouter enfin la fonction glossaire ci-dessous au contenu de votre fichier mes_fonction.php3.

Il vous suffit de reporter les numéros des mots clés dans la fonction glossaire, puis de remplacer dans votre squelette #TEXTE par [(#TEXTE|glossaire{#ID_ARTICLE})]

Utilisation

Pour ajouter un nouveau terme au glossaire, il suffit de publier un nouvel article dans la rubrique concernée ; le texte de cet article constitue la définition du terme.

Le sur-titre de l’article définit le terme à reconnaître. On y indiquera le code HTML des caractères spéciaux (è pour è, etc). Pour plus de détails sur l’utilisation d’expression régulières dans le surtitre, vous pouvez consulter cet article.

Le code

Voici la fonction à rajouter dans votre fichier mes_fonctions.php3, et à modifier.

la fonction glossaire :

/*
 *   +----------------------------------+
 *    Nom du Filtre : Glossaire                                                
 *   +----------------------------------+
 *   Publié le 30/11/2004
 *   Par Thomas Houssin <Thomas point Houssin at gmail.com>
 */
function glossaire($chaine,$idarticle=0) 
{
	if(strlen($chaine) == 0) Return "";
        if($idarticle == 0) Return "";

	#Indiquez ici les numeros des mots clés correspondant à chaque audience.
	$motcleA1 = 34;
	$motcleA2 = 44;

	#Indiquez ici les numeros des mots clés glossaire et glossaire_un
	#remplacement sur tout le texte ?
        $motglossaire = 39;
	$motglossaireun = 43;

	//numéro de la rubrique contenant les definitions de l'audience correspondante.
	$glossaireA1=36;
	$glossaireA2=35;
	
	//définitions par défaut
	$id_glossaire = $glossaireA2; 
	//longueur max pour utilisation de la balise <abbr>
	$long_max = 95;
	
	$printglossaire=0;

	$r = spip_query("SELECT * FROM spip_mots_articles WHERE id_article=$idarticle AND id_mot in ('$motcleA1','$motcleA2','$motglossaire','$motglossaireun')");
	while($o = spip_fetch_array($r))
	{

		switch($o['id_mot']) 
		{
			case $motcleA1: $id_glossaire = $glossaireA1; break;
			case $motcleA2: $id_glossaire = $glossaireA2; break;
			case $motglossaire: $rplct_unique = 0; $printglossaire=1; break;
			case $motglossaireun: $rplct_unique = 1; $printglossaire=1; break;
		}
	}
	#Quitte si pas de glossaire demandé

	if($printglossaire)
        { 
		#Récupération des mots et des définitions
		$r = spip_query("SELECT id_article,surtitre,descriptif,texte FROM spip_articles WHERE statut='publie' AND id_rubrique='$id_glossaire'");
		if( count($r))
		{
			#définition des remplacements
			$indice=0;
			$patterns[]="";
			$replacements[]="";

			$trans = get_html_translation_table(HTML_ENTITIES);
			$trans["<"] = "<";
			$trans[">"] = ">";
			$trans["&"] = "&";
			$trans["\""] = "\"";
			$trans["'"] = "'";

			$chaine = strtr($chaine, $trans);
	
			while($o = spip_fetch_array($r))
			{
				$texte_temp = $o['texte'];
				$patterns[$indice] = "#(?!<.*?)(".$o['surtitre'].")(?![^<>]*?>)#xsi" ;
				$long_desc = strlen($texte_temp);

				if( strlen($o['surtitre']) > 0 and $long_desc > 0)
				{
					if( $long_desc < $long_max)
					{
						$replacements[$indice] = "<abbr title=\"".$texte_temp."\">\\0</abbr>" ;
					}
					else
					{
						$replacements[$indice] = "<a href=\"article.php3?id_article=$o[0]\">\\0</a>" ;
					}
				$indice ++;
				}
			}

			#tri nécessaire
			ksort($patterns);
			ksort($replacements);
		
			if($rplct_unique)
			{
				$chaine=preg_replace($patterns, $replacements, $chaine,1);
			}
			else
			{
				$chaine=preg_replace($patterns, $replacements, $chaine);
			}
		}
	}
	return $chaine;
}
  • Pour gérer deux ensembles de définition, reportez les identifiants des mots-clés et des rubriques contenant les définitions dans le code de cette fonction.
  • Pour ne gérer qu’un ensemble de définition, le plus simple est d’indiquer dans le code ci-dessus que le deuxième jeu de définition n’existe pas ; pour cela, modifier
    #Indiquez ici les numeros des mots clés correspondant à chaque audience.
    	$motcleA1 = 34;
    	$motcleA2 = 44;

    en

    #Indiquez ici les numeros des mots clés correspondant à chaque audience.
    	$motcleA1 = 34;
    	$motcleA2 = 0;
  • Pour au contraire en gérer plus de deux, rajouter des entrées du type $motcléA3=xx dans les définitions, et des lignes du genre case $motcleA3: $id_glossaire = $glossaireA3; break; au niveau de l’instruction switch.
    On aura par exemple, pour 3 ensembles d’entrées :
    [...]
    #Indiquez ici les numeros des mots clés correspondant à chaque audience.
    	$motcleA1 = 34;
    	$motcleA2 = 44;
            $motcleA3 = 47;
    
    	#Indiquez ici les numeros des mots clés glossaire et glossaire_un
    	#remplacement sur tout le texte ?
            $motglossaire = 39;
    	$motglossaireun = 43;
    
    	//numéro de la rubrique contenant les definitions de l'audience correspondante.
    	$glossaireA1=36;
    	$glossaireA2=35;
            $glossaireA3=37;
    
    [...]
    
    while($o = spip_fetch_array($r))
    	{
    
    		switch($o['id_mot']) 
    		{
    			case $motcleA1: $id_glossaire = $glossaireA1; break;
    			case $motcleA2: $id_glossaire = $glossaireA2; break;
    			case $motcleA3: $id_glossaire = $glossaireA3; break;
    			case $motglossaire: $rplct_unique = 0; $printglossaire=1; break;
    			case $motglossaireun: $rplct_unique = 1; $printglossaire=1; break;
    		}
    	}

N’hésitez pas à proposer des améliorations ou à signaler des erreurs...

L’expression régulière qui sert à remplacer dans tout le texte sauf dans les balises HTML provient de http://fr.php.net/preg_replace. Elle semble correcte et meilleure que celle que j’utilisais au début.

updated on 28 May 2007

Discussion

8 discussions

  • Bonjour,

    Un glossaire interne a été pris en charge par le Couteau Suisse.
    Pour plus d’infos, c’est ici : Un glossaire interne pour vos sites.

    Entre autres :
    -  Les définitions sont stockées par mots-clés : groupe « Glossaire »
    -  De nombreuses balises HTML sont préservées
    -  Le survol de la souris affiche directement la définition du mot.
    -  Le cadre de définition est configurable par css
    -  Pas de nouvelle fenêtre ouverte (popup)
    -  La recherche est insensible à la casse.
    -  Pas de filtre à ajouter dans le squelette

    Reply to this message

  • Ayant migré mon site vers SPIP 1.9, j’ai également migré ce plugin. En attendant d’avoir le temps de relire le code et de modifier cet article, vous pouviez trouver une version préliminaire ici et une version simplifiée du glossaire

    Reply to this message

  • Bonjour,

    J’utilise ce glossaire automatique qui marche très bien pour les articles.

    Le site que je suis en train de préparer pour mon travail utilise beaucoup les rubriques et assez peu les articles en fait. Le glossaire automatique n’a donc que très peu d’utilité s’il ne prend pas en compte les textes des rubriques.

    J’ai cherché comment modifier cette fonction pour qu’elle fonctionne aussi sur les rubriques mais sans succès :-( . Quelqu’un pourrais m’éclairer ? sachant que j’ai aucune notion du php....

    pour info, j’utilise encore spip 1.8

    Merci

    misterfred

    Reply to this message

  • Bonjour,

    J’utilise ce glossaire automatique qui marche très bien pour les articles.

    Le site que je suis en train de préparer pour mon travail utilise beaucoup les rubriques et assez peu les articles en fait. Le glossaire automatique n’a donc que très peu d’utilité s’il ne prend pas en compte les textes des rubriques.

    J’ai cherché comment modifier cette fonction pour qu’elle fonctionne aussi sur les rubriques mais sans succès :-( . Quelqu’un pourrais m’éclairer ? sachant que j’ai aucune notion du php....

    Merci

    misterfred

    Reply to this message

  • Salut à tous,

    merci beaucoup pour cette contribution, qui est une très bonne idée...
    Mon seul problème, qui est de taille, est que je ne parvient pas à la faire fonctionner.

    Je suis en SPIP 1.8.

    Voici ce que j’ai fait :
    -  j’ai créé un groupe de mot clé Audience
    -  j’ai créé 4 mots clé dans ce groupe qui sont : sigle et technique (mes 2 groupes de definition) + glossaire et glossaire_un (peut être faut-il les créer dans un groupe différent, mais je ne pense pas)
    -  j’ai créé une rubrique glossaire contenant 2 sous-rubriques nommées sigle et technique
    -  j’ai reporter les ID des mots clefs et des rubriques concernées dans le filtre glossaire dans mes_fonctions.php3
    -  j’ai créé les articles correspondants aux mots que je voulais voire figurer dans le glossaire, en remplissant les 3 champs sur-titre, titre et texte
    -  j’ai lié les articles dans lesquels je voulais voire fonctionner le glossaire au mots clefs glossaire et soit à sigle soit à technique

    Je n’ai aucune erreur technique, mais rien ne se passe...
    Je ne comprends pas...

    Quelqu’un peut-il m’éclairer, j’ai peut être oublier un truc.

    Merci d’avance.

    Reply to this message

  • 3

    Salut,

    j’ai essayé d’installer ce glossaire qui me serait d’une très grande utilité.. Mais malheureusement je n’arrive pas à le faire fonctionner.. J’ai recommencé X fois et rien n’y fait.

    Il y a une toute petite erreur dans le code ici

    while($o = spip_fetch_array($r))
    			{
    
    				$texte_temp = $o['texte'];
    				$patterns[$indice] = "#(?!<.*?)(".$o['surtitre'].")(?![^<>]*?>)#xsi" ;

    Il faut mettre un espace (ou intervertir...) entre le ? et le > ----> ?>)#xsi" ;
    de la dernière ligne sinon le code php se termine prématurément.

    Je me demande si j’ai été claire. Bon sinon et bien mon problème est que ça ne marche pas du tout. Rien ne se passe, les mots clés sont créés, la rubrique et les sous-rubriques aussi etc... mais pas moyen de le faire fonctionner.
    Par contre je n’ai aucun message d’erreur indiqué..
    Quelqu’un peut-il m’aider?

    • Il faut mettre un espace (ou intervertir...) entre le ? et le > ----> ?>)#xsi" ; de la dernière ligne sinon le code php se termine prématurément.

      Hum nan ; je ne sais pas pourquoi le code termine prématurément, mais si tu fais ca, l’expression régulière ne va plus fonctionner correctement, et en effet, aucun mot ne sera reconnu... Normalement, le code publié devrait fonctionner, mais ca fait un certain temps que je n’ai pas testé, je vais essayer de regarder ca avec les dernières versions...

    • J’ai télécharger la derniére version de SPIP-v1-8-2-d.
      je ne trouve pas le fichier mes_fonction.php3

      ou se trouve t’il ?

      Merci pour toutes les infos de votre site :)

    • mes_fonctions.php3 se trouve à la racine du site ; s’il n’existe pas, il suffit de l’y créer.

    Reply to this message

  • 1

    Tout d’abord merci pour cette contrib que je trouve géniale.

    Mais je reconnais qu’il m’a fallu un peu de temps pour comprendre son fonctionnement (le temps de comprendre le code !). Car, à mon humble avis, il manque une explication fondamentale : les articles pour lesquels on souhaite que le glossaire fonctionne doivent être associés à au moins deux mots clés.

    1. L’article en question doit d’abord être associé au mot-clé glossaire ou glossaire_un : on définit ainsi si la définiton doit apparaître à chaque occurence du mot dans l’article (mot-clé glossaire) ou uniquement sur la première occurence (mot-clé glossaire_un).
    2. L’article doit aussi être associé au mot-clé lié au jeu de définitions. Ainsi on spécifie si les définitions qui apparaîtront correspondent au niveau utilisateurs débutants, utilisateurs avancés, etc pour reprendre l’exemple donné dans la contrib.

    Et avec ça, ça marche super bien, même s’il faut se méfier de certains mots : si l’on veut définir l’acronyme SI (Système d’Information) il faudra le rédiger S.I. dans les articles et définir le surtitre en S\.I\. sinon on risque d’avoir des surprises...

    • Autre détail : la balise HTML utilisée n’est pas reconnue par IE (en tout cas pas sur mon IE6). Il est alors préférable de remplacer la balise <abbr> par <acronym> qui, elle, est reconnue. Néanmoins, même si IE reconnait <acronym>, il ne la souligne pas pour autant comme le fait Firefox. J’ai donc rajouté dans mon fichier typographie.css le texte suivant :

      acronym {
              border-bottom: 1px dotted #a3a3a3;
      }

    Reply to this message

  • Je me permet de rajouter cela, posté dans la partie admin par ’le Jamais Content’ :

    gérant un site en utf-8, j’ai un peu modifié la fin du filtre qu’on place dans mes_options, parce que sans cela, ça me semait une misère pas croyable :

    // on va à la fin du filtre là où il y a...
    else
    {
            $chaine=preg_replace($patterns, $replacements, $chaine);
    }
    
    // puis on rajoute...
    // (on prend les même et on recommence)
    #définition des remplacements
    $indice=0;
    $patterns[]="";
    $replacements[]="";
    
    // on refait le tableau
    $trans = get_html_translation_table(HTML_ENTITIES);
    $trans["<"] = "<";
    $trans[">"] = ">";
    $trans["&"] = "&";
    $trans["\""] = "\"";
    $trans["'"] = "'";
    
    // array_flip !
    // on remet le toutim dans l'état où on l'avait pris
    // et miracle, ça redevient lisible - fin de la sueur froide-
    $trans = array_flip($trans);
    $chaine = strtr($chaine, $trans);
    
            }
    }
    return $chaine;

    Reply to this message

Comment on this article

Who are you?
  • [Log in]

To show your avatar with your message, register it first on gravatar.com (free et painless) and don’t forget to indicate your Email addresse here.

Enter your comment here

This form accepts SPIP shortcuts {{bold}} {italic} -*list [text->url] <quote> <code> and HTML code <q> <del> <ins>. To create paragraphs, just leave empty lines.

Add a document

Follow the comments: RSS 2.0 | Atom