Remplacement dynamiques des acronymes et abréviations

Rechercher

Remplacement dynamiques des acronymes et abréviations

  • Par Emacs
  • 3 commentaires
  • 10186 lectures
  • RSS -  Atom

A l'heure du « Web sémantique », on découvre beaucoup d'applications qui disposent d'une transformation automatique de leurs acronymes, abréviations et définitions présents dans le corps de leurs pages. Cette fonctionnalité apporte une valeur ajoutée non négligeable aux pages web et n'est finalement pas si compliqué que ça à mettre oeuvre. Ce tutoriel vous apporte une solution simple et efficace qu'il vous sera possible de mettre en œuvre très rapidement sur votre site. Pour réaliser cet exercice, nous nous appuierons sur une base de données MySQL et une classe PHP 5.

Présentation de l'application de remplacement d'acronymes

L'application que nous allons développée doit permettre de transformer un sigle (par exemple « PHP ») en un élément HTML spécifique dans lequel se trouvera sa définition. En HTML, il existe trois marqueurs différents : acronym, abbr et dfn.

Le premier permet d'appliquer une signification sur un acronyme (par exemple « ONU »). Le second sur une abréviation (par exemple « SNCF ») et le dernier d'apposer une définition sur un mot ou un ensemble de mots. La différence entre acronyme et abréviation est minime, c'est pourquoi on les confond souvent. En fait, ce qui sépare un acronyme d'une abréviation, c'est la manière dont est prononcé le sigle. Si le sigle peut se prononcer naturellement comme un mot ordinaire, alors on parlera plutôt d'acronyme. En revanche, si la prononciation du sigle nécessite d'épeler chaque lettre individuellement, alors on parlera d'abréviation.

Notre application distinguera ces 3 cas de figure. Tous les mots de notre glossaire devront également être enregistrés quelque part, c'est pourquoi nous opterons pour une base de données MySQL. Le choix de la base de données est complètement arbitraire. Nous aurions très bien pu utiliser un système d'information différent comme par exemple un fichier texte ou XML. La base de données a le principal avantage d'être plus pratique à manipuler.

Création de la table qui accueillera les mots

La gestion des mots ne nécessite pas d'un modèle de données très pointu. En effet, une seule table de 4 champs suffit pour stocker l'ensemble de nos mots. Analysons sa structure :

  • Un identifiant entier positif auto-incrémenté qui nous servira de clé primaire
  • Le sigle qui est une chaine de caractère. Nous lui ajouterons un index d'unicité.
  • Sa définition qui est aussi une chaine de caractères
  • Le tag HTML associé. Nous utiliserons un champ de type ENUM

Le modèle physique de notre table SQL est donc le suivant :

Script de génération de la table "glossaire"
CREATE TABLE `glossaire` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`sigle` VARCHAR( 50 ) NOT NULL ,
`definition` VARCHAR( 255 ) NOT NULL ,
`tag` ENUM('acronym','abbr','dfn') NOT NULL ,
UNIQUE (`sigle`)
) ENGINE = MYISAM ;

Ajoutons-y quelques données de test :

Introduction d'un jeu de données de test
INSERT INTO `glossaire` VALUES (1, 'HTML', 'HyperText Markeup Language', 'acronym');
INSERT INTO `glossaire` VALUES (2, 'PHP', 'Hypertext PreProcessor', 'acronym');
INSERT INTO `glossaire` VALUES (3, 'XML', 'eXtended Markeup Language', 'abbr');
INSERT INTO `glossaire` VALUES (4, 'CSS', 'Cascading Style Sheets', 'abbr');
INSERT INTO `glossaire` VALUES (5, 'Ajax', 'Utilisation de Javascript et d''une technologie serveur', 'dfn');
INSERT INTO `glossaire` VALUES (6, 'Serveur', 'Ordinateur qui rend des services à un autre', 'dfn');

Présentation de la classe PHP de glossaire

Cette classe PHP 5 permet de remplacer très facilement les mots du glossaire (issus de la base de données) avec leur équivalent HTML lorsqu'ils se trouvent dans le corps d'un texte. Bien sûr, cet outil gère le cas où la chaine à traiter contient du HTML et pourrait potentiellement contenir des mots du glossaire dans les attributs des tags HTML. Ce serait par exemple le cas si j'avais le mot "PHP" dans l'attribut "title" du tag <img> comme présenté ci-dessous :

<img src="logo_php.gif" alt="Le logo du langage PHP" />

Vous vous en douterez, la difficulté réside dans le fait qu'il ne faut pas transformer ce mot s'il se trouve déjà dans des tags HTML. Par contre, il n'est pas interdit de transformer le mot s'il est présent entre deux tags HTML consécutifs. Par exemple :

<a href="http://www.php.net" title="Site officiel du langage PHP">Site officiel de PHP</a>

Heureusement que la classe que nous allons utilisée gère tout ça toute seule. Vous verrez que vous n'aurez presque plus rien à faire pour faire fonctionner votre glossaire.

Développement de notre application

L'algorithme global est très simple. Il se décompose en quatre temps présentés ci-après :

  1. Connexion sur la base de données
  2. Instanciation d'un objet de type Glossaire
  3. Récupération des mots du glossaire de la base de données et enregistrement dans l'objet Glossaire
  4. Transformation des mots dans la chaine HTML

Ce qui nous donne au final :

<?php
// Adresse du serveur de base de données
define('DB_SERVEUR', 'localhost');
// Login
define('DB_LOGIN','root');
// Mot de passe
define('DB_PASSWORD','root');
// Nom de la base de données
define('DB_NOM','NomDeLaBase');
// Driver correspondant à la BDD utilisée
define('DB_DSN','mysql:host='. DB_SERVEUR .';dbname='. DB_NOM);
// Import de la classe Glossaire
require(dirname(__FILE__).'/Glossaire.class.php');
// Déclaration des variables
$oPDO = null;
$oGlossaire = null;
$sTexte = 'Cette chaine contient du <a href="" title="Le langage HTML">langage HTML</a> et des feuilles de styles CSS. <strong>PHP</strong> et Ajax rendent cette page plus dynamique.';
try {
// Connexion sur la base de données
$oPDO = new PDO(DB_DSN, DB_LOGIN, DB_PASSWORD);
// Instanciation de l'objet Glossaire
$oGlossaire = new Glossaire();
// Récupération des mots du glossaire
foreach($oPDO->query('SELECT sigle, definition, tag FROM glossaire') as $aRow)
{
$oGlossaire->setWord($aRow['sigle'], $aRow['definition'], $aRow['tag']);
}
// Transformation de la chaine HTML
echo $oGlossaire->parseString($sTexte);
} catch(PDOException $e) {
exit('Une erreur interne s\'est produite !');
}
?>

Le code étant complètement commenté, je vous laisse le soin de comprendre son fonctionnement. Notez juste que pour ajouter un mot dans le glossaire, il suffit d'appeller la méthode setWord() de l'objet Glossaire, puis d'utiliser la méthode parseString() pour transformer les sigles en leur équivalent dans la chaine passée en paramètre. C'est aussi simple que cela :)

Optimisation de la procédure

La classe Glossaire s'appuie sur les expressions régulières pour transformer la chaine et remplacer les sigles. A long terme, ce code pourrait ralentir le chargement des pages si vous traitez à chaque appel les chaines et si vous récupérez un nombre trop important de la base de données.

Une solution serait de stocker en base de données les chaines préformatées. C'est-à-dire qu'il vaudrait mieux appliquer la transformation au moment de l'enregistrement de la chaine en base de données. Cela vous évitera de la traiter à chaque affichage. Néanmoins, cette méthode à un inconvénient non négligeable. Si vous ajoutez, modifier ou bien supprimer un mot du glossaire, il vous faudra retraiter chaque chaine précédemment traitée pour que les modifications du glossaire soient prises en compte.

Conclusion

Au terme de ce tutoriel, nous avons découvert une méthode simple et efficace pour mettre en place très rapidement un système de gestion dynamiques d'acronymes, abréviations et définitions. Il ne tient qu'à vous de l'implémenter dans votre application si nécessaire, et de l'étoffer. Par exemple, en développant les scripts de base pour ajouter, modifier et supprimer un mot de la base de données.

 



Les commentaires

1. Par Xireus le 22/03/2008 13:18

Sympa, utile, accessible !

2. Par NewSky le 20/02/2009 13:57

Salut,
Certes, l'application est très utile. Mais que se passe-t-il lorsqu'il y a du javascript dans le contenu à analyser ? Ex :
< p >mon contenu avec des acronymes< / p >
< script type="text/javascript" >
var = 'un_acronyme';
< / script >

Pour ma part, j'ai une regex qui fait tout ça en un coup :
|(?!<[^<>]*?)(?<![?.&])\bnilco\b(?!(?![^<>]*?>|msUi

mais j'ai le même problème...

3. Par nkgautier le 19/06/2009 17:14

c'est propre.