Sommaire Carte Index Recherche Nouvelles Archives Liens A propos
[Barre Superieure]
[Barre Inferieure]
[Photo de l'auteur]
par John Perr

L´auteur:

Utilisateur Linux depuis 1994; il est l'éditeur français de la revue LinuxFocus.


Sommaire:

  1. Introduction
  2. Définition
  3. Un exemple
  4. Version HTML
  5. Version macro
  6. Définition des macros
  7. Description
  8. Création des pages
  9. Récapitulatif
  10. Conclusion

Construire des fichiers avec des macros m4

[Illustration]

Résumé:

Cette introduction à l'utilisation du macro processeur m4 explique comment simplifier la mise à jour de fichiers textes ou HTML à l'aide de macros commandes m4.



 

Introduction

Il est fréquent d'avoir besoin d'un langage de macros commandes lorsqu'on utilise un éditeur. La plupart d'entre eux un en possède d'ailleur un intégré et même le compilateur C possède son propre pré-processeur CPP. Lorsque l'on doit éditer des fichiers de configuration au format texte, ou même éditer des pages HTML pour maintenir un petit site web, il peut s'avèrer pratique d'utiliser le macro processeur GNU/m4 qui est livré avec toutes les distributions de linux et qui est devenu un standard de facto dans le monde Unix.

Dans ce qui suit, nous allons voir comment utiliser le processeur de macro m4 pour construire des pages HTML et ainsi maintenir la cohérence d'un site web. Bien sûr, il existe quantité d'autres moyens d'obtenir le même résultat; c'est ce qui fait la beauté de ce système.

Cette technique est celle utilisée pour la génération du fameux fichier sendmail.cf. Voir à ce sujet l'article de Eric Jacoboni dans LinuxMagazine n°2 de janvier 99.

L'utilisation du langage macro m4 n'est pas limité à l'édition de fichier texte ou HTML, il pourra s'avèrer très utile pour les programmeurs qui souhaitent étendre les possibilités du préprocesseur du langage C ou pour ceux qui veulent disposer de possibilités équivalentes au C avec un autre langage.

 

Définition

On parle de processeur de macro pour définir un programme qui interprète des commandes (les macros) elles même définies par l'utilisateur. Par exemple avec une définition comme la suivante:

define(AUTEUR,`Aghata Christie<a.christie@scottland-yard.gov>')

il suffira de mettre le mot "AUTEUR" dans le texte pour qu'il soit remplacé par le texte "Aghata Christie<a.christie@scottland-yard.gov>" après utilisation du processeur de macros. Il existe bien sûr des fonctions plus évoluées comme nous le verrons dans ce qui suit.

 

Un exemple

Supposons que nous ayons à maintenir un site web qui comporte les même pages dans des langues différentes. De plus, chaque page possède une entête et un pied de page qui assure un aspect cohérent à l'ensemble du site. Pour faire simple et éviter d'avoir à utiliser un navigateur pour voir le résultat, notre exemple se limitera à du texte. Cela permettra aussi aux puristes qui utilisent lynx de naviguer sans problèmes. Voici le code html d'une page:

 

Version HTML

  
<!-- Début de l'entête -->
<HTML>
<HEAD>
<TITLE>Un site pour les utilisateurs de lynx</TITLE>
<META name="description" content="Site lynx et m4"> 
<META name="keywords" content="m4, lynx, GPL">
</HEAD>
<BODY BGCOLOR="#FFFFFF" LINK="#008000"
    VLINK="#808080" ALINK="#8080FF">
<TABLE>
  <TBODY>
  <TR><TD align=middle colspan="2">
      <H1>Lynx un navigateur en mode console</H1>
  <TR><TD align="left" valign="top" width="15%">
      <a href="./index-en.html">Anglais</A><BR>
      <a href="./index-fr.html">Français</A><BR>
      <a href="./index-es.html">Espagnol</A><BR>
      <a href="./index-it.html">Italien</A><BR>
      <a href="./index-de.html">Allemand</A><BR>
      <TD align=left>
<!-- Fin de l'entête -->

<!-- Corps de la page -->
   <P>Visitez le
   <A HREF="http://lynx.browser.org/">
   site officiel de lynx</A>
   pour plus d'informations sur Lynx,
   y compris les nouvelles mises à jour.</P>
       
   <P>Les liens vers les sources de la version
   courante et divers supports pour Lynx sont
   tenus à jour sur le site
   <A HREF="http://www.crl.com/~subir/lynx.html">
   liens Lynx</A>.</P>

   <P>Lynx est distribué dans le cadre de la lisence GNU
   (General Public License - GPL)
   sans restriction sur son utilisation ni sa distribution.
   Les mentions des droits de
   reproduction de Lynx, "COPYHEADER", et GNU GPL, "COPYING",
   sont inclus dans la racine de l'arborescence de la distribution.
   Lynx est supporté par la communauté des utilisateurs de Lynx,
   une communauté entièrement bénévole (et non-officielle).</P>
<!-- Fin du corps de la page -->

<!-- Début du pied de page -->
</TBODY>
</TABLE>
<HR size="0" noshadow>
<FONT SIZE=-2>
<EM>Date de mise à jour : 11/07/99
- &copy <A HREF="mailto:webmaster@lynx.browser.org">
lynx.browser.org</A> 1999
</EM></FONT>
</BODY>
</HTML>
<!-- Fin du pied de page -->

Voici l'apparence de cette page:

[Cliquez ici pour agrandir l'image] [Cliquez ici pour agrandir l'image]
avec lynx avec netscape

Pour la cohérence du site, toutes les pages auront les mêmes styles d'entêtes et de pieds de page, seul le corps de la page changera. Nous allons donc créer des macros m4 que nous insèrerons dans le texte HTML de nos pages et qui remplacerons tous les éléments répétitifs.
Avant de donner le détail des macros, regardons ce que donneras l'exemple ci-dessus une fois réécrit de cette manière:

 

Version macro

  
LYNX_TITRE(Lynx un navigateur en mode console)
LYNX_ENTETE(Un site pour les utilisateurs de lynx)

   <P>Visitez le
   <A HREF="http://lynx.browser.org/">
   site officiel de lynx</A>
   pour plus d'informations sur Lynx,
   y compris les nouvelles mises à jour.</P>
       
   <P>Les liens vers les sources de la version
   courante et divers supports pour Lynx sont
   tenus à jour sur le site
   <A HREF="http://www.crl.com/~subir/lynx.html">
   liens Lynx</A>.</P>

   <P>Lynx est distribué dans le cadre de la lisence GNU
   (General Public License - GPL)
   sans restriction sur son utilisation ni sa distribution.
   Les mentions des droits de reproduction de Lynx, "COPYHEADER",
   et GNU GPL, "COPYING", sont inclus dans la racine de
   l'arborescence de la distribution. Lynx est supporté par
   la communauté des utilisateurs de Lynx, une communauté
   entièrement bénévole (et non-officielle).</P>
LYNX_PIED

De cette manière, l'écriture des pages est beaucoup plus concises et le texte n'est pas noyé dans les balises HTML de début et de fin de page. De même pour créer les pages dans les autres langues, nous créeront des fichiers équivalents à celui-ci mais traduits. La version anglaise donnerait:

  
LYNX_TITRE(Lynx a fully-featured World Wide Web
            client for character-cell displays)
LYNX_ENTETE(Lynx homepage)

      <P>Links to the current sources and support materials
      for Lynx are maintained at
      <A HREF="http://www.crl.com/~subir/lynx.html">
      Lynx links</A></P>
      <P> and at the Lynx homepage
      <A HREF="http://lynx.browser.org/">
      Lynx Information.</A></P>
      <P>View these pages for information about Lynx,
      including new updates.</P>

      <P>Lynx is distributed under the
      GNU General Public License (GPL) without
   restrictions on usage or redistribution.
   The Lynx copyright statement, "COPYHEADER",
   and GNU GPL, "COPYING", are included in the top-level
   directory of the distribution.
   Lynx is supported by the Lynx user community,
   an entirely volunteer (and unofficial) organization.</P>
LYNX_PIED

On utilise pour chaque langue les mêmes macros LYNX_TITRE, LYNX_ENTETE et LYNX_PIED mais avec des arguments différents. Ces trois macros permettent de remplacer efficacement tout le code HTML de début et de fin de page. L'avantage non négligeable de ce système réside dans le fait que la définition des entêtes et pieds de page est unique pour tout le site. Ainsi, en cas de modification du style des pages du site, il n'y aura qu'un fichier à modifier: celui qui contient les définitions des macros au lieu de reprendre toutes les pages une par une.

 

Définition des macros

Ci-dessus, nous avons définis le besoin de 3 macros qui feront le gros du travail. Voici le fichier qui contient la définition de ces macros. Les explications suivent:

  
divert(-1)
# Fichier mac.css
# Version 1.0 des macros m4 pour Lynx
#
# Pour chaque langue est definit un fichier
# trans-LANG.m4 basé sur le modèle français.
# Si aucun fichier de traduction n'existe,
# le français est pris par défaut.
#
divert(0)
changequote({,})dnl # changer les apostrophes en accolades
ifdef({LANG},,{define({LANG},{fr})})dnl # Défaut= français
include({trans-}LANG{.m4})dnl	  # Appeler le fichier de traduction
undefine({format})dnl		  # Supprimer la définition de format
define({_ANNEE_},esyscmd(date +%Y))dnl 	  #Année en cours
define({LYNX_TITRE},{define(_TITLE_,$1)})dnl # Déclaration de la 1ère macro
dnl # Déclaration de la 2ième macro
define({LYNX_ENTETE},{<!-- Début de l'entête -->
<HTML>
<HEAD>
<TITLE>$1</TITLE>
<META name="description" content="Site lynx et m4"> 
<META name="keywords" content="m4, lynx, GPL">
</HEAD>
<BODY BGCOLOR="#FFFFFF" LINK="#008000" VLINK="#808080" ALINK="#8080FF">
<TABLE>
  <TBODY>
  <TR><TD align=middle colspan="2">
      <H1>_TITLE_</H1>
  <TR><TD align="left" valign="top" width="15%">
      <a href="./index-en.html">_ANGLAIS_</A><BR>
      <a href="./index-fr.html">_FRANCAIS_</A><BR>
      <a href="./index-es.html">_ESPAGNOL_</A><BR>
      <a href="./index-it.html">_ITALIEN_</A><BR>
      <a href="./index-de.html">_ALLEMAND_</A><BR>
      <TD align=left>
<!-- Fin de l'entête -->})dnl
dnl # Déclaration de la 3ième macro
define({LYNX_PIED},{<!-- Début du pied de page -->
</TBODY>
</TABLE>
<HR size="0" noshadow>
<FONT SIZE=-2>
<EM>_MAINTENEUR_.<BR>
_MAJ_
esyscmd(date +%d/%m/%y)
- &copy <A HREF="mailto:webmaster@lynx.browser.org">
lynx.browser.org</A>
_ANNEE_</EM></FONT>
</BODY>
</HTML>
<!-- Fin du pied de page -->})dnl
 

Description

Les lignes comprises entre "divert(-1)" et "divert(0)" sont des commentaires. "Divert" est une des macros prédéfinies du processeur m4 qui permet de retarder les résultats d'interprétations du fichier d'entrée. En utilisant -1, les lignes qui suivent ne sont pas retranscrites dans le fichier HTML définitif, ce qui est bien le résultat recherché.

La macro "changequote" permet de redéfinir les apostrophes qui permettent d'encadrer les arguments des macros par défaut. Ici elles sont remplacées par des accolades car dans la plupart des textes en français, les apostrophes apparaîssent régulièrement et faussent l'interprétation des macros. Les accolades sont moins utilisées pour du texte ou du HTML c'est pourquoi elles ont été choisies ici.

La macro "ifdef" permet de tester si la macro LANG est définie ce qui permet de la définir comme "fr" si elle n'existe pas. La macro LANG permet de préciser la langue utilisée. Nous verrons par la suite qu'elle sera définie lors de l'appel au macro-processeur m4 afin de choisir en quelle langue construire la page HTML.

La ligne "include" à le même sens qu'en C et permet d'inclure un fichier externe. Ici il s'agit du fichier de traduction qui contient des définitions propres à chaque langue. Voici son contenu en fonction de la langue:

  
divert(-1)
# Fichier trans-fr.m4
# Définitions pour le français
divert(0)
define({_ANGLAIS_},{Anglais})dnl
define({_FRANCAIS_},{Français})dnl
define({_ITALIEN_},{Espagnol})dnl
define({_ESPAGNOL_},{Italien})dnl
define({_ALLEMAND_},{Allemand})dnl
define({_WEBMASTER_},{John Perr})dnl
define({_MAINTENEUR_},{Page maintenue par _WEBMASTER_})dnl 
define({_MAJ_},{Date de mise à jour:})dnl
  
divert(-1)
# Fichier trans-en.m4
# Définitions pour l'anglais
divert(0)
define({_ANGLAIS_},{English})dnl
define({_FRANCAIS_},{French})dnl
define({_ITALIEN_},{Spanish})dnl
define({_ESPAGNOL_},{Italian})dnl
define({_ALLEMAND_},{German})dnl
define({_WEBMASTER_},{John Perr})dnl
define({_MAINTENEUR_},{Page maintained by _WEBMASTER_})dnl
define({_MAJ_},{Page updated on })dnl

Si vous parlez Espagnol, Italien ou Allemand, vous pourrez sans difficulté créer les fichiers pour ces langues à partir des deux exemples ci-dessus.

La ligne "undefine" supprime la définition par défaut de la macro prédéfinie de m4 qui s'appelle "format" car elle n'est pas utilisée ici. Si cette ligne est omise, chaque apparition du mot "format" dans le texte sera supprimé à moins de l'encadrer par des accolades ce qui est contraignant pour rédiger une simple page web.

Vient ensuite la définition de l'année courante à partir de la macro "easyscmd" qui appelle la commande système "date". On retrouve cette commande dans la définition du pied de page pour afficher la date de mise à jour de la page.

La ligne suivante définie la première de nos trois macros principales: LYNX_TITRE. C'est en fait une macro qui en définie une autre appelée _TITRE_. Cette façon de faire permet d'utiliser si nécessaire plusieurs fois le titre dans l'entête ou le pied de page à partir d'une déclaration. Notez l'utilisation du symbole $1 pour appeler le premier argument de la macro.

Les lignes restantes définissent les deux autres macros principales: LYNX_ENTETE et LYNX_PIED qui correspondent respectivement au contenu de l'entête et du pied de notre page HTML à quelques détails près. Les différences concernent les éléments variables de ces parties de la page, à savoir:

Le "dnl" qui apparait à la fin de chaque ligne est une macro prédéfinie de m4 qui permet de ne pas prendre en compte le reste de la ligne et évite aussi la création d'une ligne blanche dans le fichier de sortie lors de l'interprétation d'une ligne de macro.

 

Création des pages

L'ensemble du dispositif étant en place, la génération d'une page html à partir du fichier de base contenant le corps du texte se fait part la commande:

Où "XX" est le code de la langue à utiliser.Si aucune langue n'est spécifiée, le français est utilisé soit "XX=fr". Notez que l'option -D permet, tout comme avec gcc, de définir une macro depuis la ligne de commande.

 

Récapitulatif

Le tableau ci-dessous résume l'ensemble des fichiers utilisés et leur fonctions dans le cadre de cette application.

Les fichiers suivants servent à la générations des pages HTML:
index-XX.html Le corps de article, c'est à dire le texte écrit par l'auteur ou le traducteur. Il est different pour chaque article et chaque langue. (le code XX=en pour l'anglais, es pour l'espagnol, etc...)
mac.css Les définitions standards pour tous les groupes. Ce fichier est commun à toutes les pages et toutes les langues. Il peut être vu comme un modèle ou une feuille de style.
trans-XX.m4 Les définitions standards pour une langue (le code XX=en pour l'anglais, es pour l'espagnol, etc...). Ce fichier est commun à toutes les pages et une langue.
 

Conclusion

Bien qu'il soit puissant, le macro processeur m4 n'est qu'un processeur de macros commandes et ne saurait être comparé à un langage de programmation de script comme perl ou tcl. Une fois ses quelques particularités maîtrisées, il reste quand même un outils rapide et pratique tel que seul le monde Unix à su en créer. Pour en savoir plus, consulter la documentation fournie avec votre distribution. Il y figure en particulier un didacticiel à m4 d'une trentaine de pages qui couvre tous les aspects de son utilisation. Vous pouvez aussi consulter à titre d'exemple le site de l'Association Bordelaise des Utilisateurs Linux qui est maintenu avec un jeu de macros similaires à celles présentées ici.


Site Web maintenu par l´équipe d´édition LinuxFocus
© John Perr
LinuxFocus 1999

1999-08-23, generated by lfparser version 0.6