original in en John Perr
en to nl Tom Uijldert
Linux gebruiker sinds 1994; hij is één van de franse redacteuren van LinuxFocus.
Een macrotaal is vaak nodig bij het gebruik van een tekst editor. De meeste
hebben reeds zo'n mogelijkheid. Zelfs programmeurs hebben hierover de
beschikking middels de C preprocessor cpp
. Bij een toepassing
als het onderhoud van configuratiebestanden of het onderhouden van een
kleine website, kan de GNU/m4 macro processor een handig hulpmiddel zijn om
het werk te verlichten. De GNU/m4 macro processor is een standaard onderdeel
van Linux en is ook een standaard bij Unix gebruikers.
Hieronder laten we zien hoe de GNU/m4 macro processor gebruikt kan worden in het onderhoud van de HTML pagina's van een kleine website. Het pakket zorgt voor coherentie over de hele site. Uiteraard zijn er tientallen manieren om hetzelfde te bereiken met andere hulpmiddelen; dat is het mooie van Unix.
Deze techniek wordt gebruikt voor het construeren van het overbekende bestand
sendmail.cfg
. Er is een m4 macro-pakket te verkrijgen bij de
universiteit van Berkeley en ontworpen door
Eric Allman.
De GNU/m4 macro processor mogelijkheden houden niet op bij het veranderen van tekst en HTML. Het kan heel handig zijn voor programmeurs die de mogelijkheden van CPP uit willen breiden of voor diegene die de mogelijkheden van CPP ook in andere talen willen toepassen.
Een macro processor is een programma dat commando's (macro's) interpreteert die zijn gedefinieerd door de gebruiker. Macro's worden meestal vermengd met tekst om te worden verwerkt. De volgende definitie bijvoorbeeld:
define(AUTHOR,`Agatha Christie<[email protected]>')
geeft de mogelijkheid om het woord AUTHOR op welke plaats dan ook in een tekst te zetten. Het zal worden vervangen door "Agatha Christie<[email protected]>" na bewerking door m4. Er zijn natuurlijk ook bruikbaarder functies, die we nu gaan bekijken.
Laten we aannemen dat we een website moeten onderhouden met daarop dezelfde pagina's maar in verschillende talen. Verder heeft iedere pagina dezelfde kop en voet, om de site een coherent aanzien te geven. Om de zaak eenvoudig te houden en te voorkomen dat we een browser nodig hebben om het resultaat te bekijken, zullen we alleen met tekst werken. Hierdoor zijn gebruikers van Lynx ook in staat om de site te bekijken. Hier is de HTML-code voor 1 pagina:
<!-- Start of header --> <HTML> <HEAD> <TITLE>Lynx homepage</TITLE> <META name="description" content="Site lynx et m4"> </HEAD> <BODY BGCOLOR="#FFFFFF" LINK="#008000" VLINK="#808080" ALINK="#8080FF"> <TABLE> <TBODY> <TR><TD align=middle colspan="2"> <H1>Lynx a fully-featured World Wide Web client for character-cell displays</H1> <TR><TD align="left" valign="top" width="15%"> <a href="./index-en.html">English</A><BR> <a href="./index-fr.html">French</A><BR> <a href="./index-es.html">Italian</A><BR> <a href="./index-it.html">Spanish</A><BR> <a href="./index-de.html">German</A><BR> <TD align=left> <!-- End of header --> <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> <!-- Start of footer --> </TBODY> </TABLE> <HR size="0" noshadow> <FONT SIZE=-2> <EM>Page maintained by John Perr.<BR> Page updated on 25/07/99 - © <A HREF="mailto:[email protected]">lynx.browser.org</A>1999 </EM></FONT> </BODY> </HTML> <!-- End of footer -->Hier is het resultaat:
met lynx | met netscape |
Alle pagina's hebben een kop en voet in dezelfde stijl. Alleen de taal en de
inhoud zullen verschillen. We gaan nu m4 macro's ontwerpen die in de HTML
tekst worden verwerkt, om daar alle herhaalde data uit te halen.
Alvorens op de details van die macro's in te gaan, gaan we eerst kijken naar
bovenstaand voorbeeld maar dan met macro's:
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
Hiermee is het schrijven van HTML pagina's eenvoudiger en de leesbaarheid wordt niet gehinderd door HTML-tags. Om pagina's in andere talen te maken, moeten er vertalingen worden gemaakt. De franse pagina wordt dan als volgt:
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 distribue 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 supporte par la communaute des utilisateurs de Lynx, une communaute enti�rement benevole (et non-officielle).</P> LYNX_PIED
Bij iedere taal worden dezelfde macro's LYNX_TITRE, LYNX_ENTETE en LYNX_PIED gebuikt maar met andere argumenten. Deze drie macro's zijn een efficiënt alternatief voor de HTML codes voor de kop- en voet regels. Dit is het belangrijkste voordeel van het systeem: de definitie van de kop- en voet regels zijn consistent over de hele site. Als de opmaak van kop of voet moet worden veranderd, kan worden volstaan met een wijziging van de macro-definities in plaats van het met de hand wijzigen van iedere pagina.
divert(-1) # File mac.css # Version 1.0 M4 macros for Lynx # # A file trans-LANG.m4 is defined for each # language, based on the french one. # If no translation file exist, # french is the default. # divert(0) changequote({,})dnl # change quotes to curly braces ifdef({LANG},,{define({LANG},{fr})})dnl # Default= french include({trans-}LANG{.m4})dnl # call translation file undefine({format})dnl # Suppress the format definition define({_ANNEE_},esyscmd(date +%Y))dnl #Current year define({LYNX_TITRE},{define(_TITLE_,$1)})dnl # First macro dnl # Second macro define({LYNX_ENTETE},{<!-- Header start --> <HTML> <HEAD> <TITLE>$1</TITLE> <META name="description" content="Site lynx and 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> <!-- end of header -->})dnl dnl # Third macro define({LYNX_PIED},{<!-- Start of footer --> </TBODY> </TABLE> <HR size="0" noshadow> <FONT SIZE=-2> <EM>_MAINTENEUR_.<BR> _MAJ_ esyscmd(date +%d/%m/%y) - © <A HREF="mailto:[email protected]"> lynx.browser.org</A> _ANNEE_</EM></FONT> </BODY> </HTML> <!-- End of footer -->})dnl
De regels tussen divert(-1)
en divert(0)
is
commentaar. divert
is één van de ingebouwde
macro's van de m4 processor. Het is bedoeld om de uitvoer om te
leiden. De waarde -1 vertelt de processor de daaropvolgende tekst niet
in het HTML bestand te zetten, wat precies is wat we willen.
De macro changequote
herdefinieert het aanhalingsteken wat
normaal in gebruik is voor het groeperen van macro argumenten. Hij wordt
vervangen door accolades omdat in teksten, en dan vooral in franse teksten,
aanhalingstekens veel worden gebruikt. Dit zou een foute interpretatie van
macro's kunnen veroorzaken. Accolades worden niet zo vaak gebruikt voor tekst
of HTML, vandaar deze herdefinitie.
De macro ifdef
wordt gebruikt om te testen of de LANG macro is
gedefinieerd. Zo niet, dan wordt het standaard "fr". LANG wordt gebruikt om
de taal in te stellen. We zullen in het voorbeeld hieronder laten zien hoe
de taal te definiëren van een HTML-pagina met gebruikmaking van m4.
De regel met include
heeft dezelfde betekenis als in C en wordt
gebruikt om een ander bestand in te lezen. Het wordt hier gebruikt om
taal-afhankelijke macro's, gebruikt in de kop- en voet regels, in te laden.
Hier de inhoud, afhankelijk van de taal:
divert(-1) # File trans-fr.m4 # Definitions for french divert(0) define({_ANGLAIS_},{Anglais})dnl define({_FRANCAIS_},{Francais})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) # File trans-en.m4 # Definitions for english 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
Als je het Spaans, Italiaans of Duits machtig bent, dan zou je analoge bestanden aan kunnen maken voor deze talen.
De regel met undefine
doet de standaard definitie van de
ingebouwde format
macro teniet omdat deze hier niet wordt
gebruikt. Bij het weglaten van deze regel zou, iedere keer dat het woord
format in de tekst voorkomt, het woord vervallen, behalve als het
tussen aanhalingstekens staat (accolades in dit geval). Dit is niet aan te
raden bij het veranderen van eenvoudige web-pagina's.
Daarna wordt het huidige jaar gedefinieerd. Deze wordt verkregen middels de
macro easycmd
, die het Unix commando date
aanroept.
Het commando wordt ook gebruikt in de voet regels om de datum te kunnen
laten zien waarop de pagina het laatst is veranderd.
De volgende regels definiëren de eerste van onze drie macro's:
LYNX_TITRE. Deze definieert een ander macro, _TITRE_ genaamd. Deze tweede
definitie is nodig om de titel meerdere malen in de kop- en voet regels te
kunnen verwerken vanuit één definitie. Let op het gebruik van
$1
om te refereren aan het eerste argument van de macro.
De rest van de regels definiëren de andere twee macro's: LYNX_ENTETE en LYNX_PIED die de inhoud van de kop- en voetregels van onze HTML-pagina bevatten, met uitzondering van de variabele inhoud van die regels. Dat zijn:
dnl
aan het eind van de regel is een ingebouwde macro van m4
die het volgende aangeeft: verwijder alles tot aan het einde van de regel.
dnl
voorkomt het genereren van een lege regel bij het uitvoeren
van een macro.
Nu het systeem gereed is, wordt het genereren van de web-pagina met het volgende commando opgestart:
XX
is daarbij de code die wordt gebruikt voor iedere taal. Merk
op dat de optie -D
wordt gebruikt die, net als bij
gcc
, een macro definieert vanaf de commando-regel.
De volgende bestanden worden gebruikt voor het genereren van HTML pagina's:
index-XX.html | De inhoud van de pagina. Dat is tekst, geschreven door de auteur of de vertaler. Dit verschilt per pagina en per taal (de code is XX=en voor Engels, es voor Spaans, etc...). |
mac.css | Standaard definities. Dit bestand zit in alle pagina's en talen. Het is een soort stijl-pagina. |
trans-XX.m4 | Standaard definities voor een taal. Dit bestand wordt gebruikt door alle pagina's van één bepaalde taal (de code XX=en voor Engels, es voor Spaans, etc...). |
Met dank aan Paul Kienzle voor het nakijken van dit artikel.