Prehtml, version 1.8
Télécharger l'ensemble du
projet (sources, exécutable pour linux, et mini-documentation).
Ce lien fonctionne sur mon site, mais pas forcément si cette
page est recopiée ailleurs! Si ça ne marche pas, essayez http://mjulier.free.fr/prehtml/prehtml-current.tar.gz
(format .tar.gz, à décoder en lançant "tar -zxf
prehtml.tar.gz", un répertoire nommé prehtml sera
créé, contenant le code source et l'exécutable qui
s'appelle simplement "prehtml").
Mais avant d'utiliser ce programme, jetez un coup d'oeil rapide aux questions légales.
Recompilation
Aller dans le répertoire contenant les fichiers source, et taper
"make". L'exécutable est créé avec les
informations de débogage: pour les supprimer tapez "strip
prehtml".
Il faut avoir "make", j'ai utilisé GNU make, mais je pense que
ça marche avec n'importe quel make Unix.
Il faut aussi avoir un compilateur C. Par défaut, j'ai mis
"gcc", pour en utiliser un autre il faut modifier la ligne "CC=gcc" du
fichier Makefile.
Si vous compilez ce programme sur un système non-Unix, je ne
sais pas ce que ça peut donner, ni même si ça peut
marcher. Testé sur Linux/i386.
Origine du projet
Des difficultés pour maintenir une liste de
dépêches d'information sur un site consacré au
vélo comme moyen de transport dans la région de
Montpellier.
Initialement, chaque fois que je rajoutais une information, il
fallait que je modifie une page "actualites.html", en écrivant
le texte de la nouvelle information. Puis je rajoutais une cible <A
NAME="pistes_etroites"> sur l'article, puis je recopiais le titre en
haut de la page d'actualités avec un lien vers cette info <A
HREF="#pistes_etroites"> pour retrouver facilement les
dernières infos, et enfin je rajoutais cette info sur la page
d'accueil "index.html" pour signaler la nouveauté <A
HREF="actualites.html#pistes_etroites">. C'était beaucoup de
travail à chaque fois, sans compter le travail d'archivage des
informations un peu périmées.
Ensuite, j'ai été remplacé par un jeune
génie des maths et de l'informatique, qui a automatisé
tout le processus avec des scripts Perl et shell dans tous les sens, et
quelques utilitaires Unix. Brillant, il faut le dire, mais
incompréhensible: j'aime bien le Perl, mais à chaque fois
que je m'y remets 3 mois après la dernière fois, j'ai
oublié toute la syntaxe. Et le système rendait impossible
ou presque l'utilisation d'éditeurs HTML un peu
évolués comme Netscape/Mozilla et équivalents.
J'ai donc décidé de faire mon propre système,
en me basant sur le langage qui me paraissait le plus simple et le plus
connu: le Bourne-Shell, c'est-à-dire le langage de la console
d'Unix. Pourquoi ne pas utiliser plutôt PHP? Bon,
déjà, ce n'est pas l'usage classique de PHP, que la
plupart des gens font tourner sur le serveur; cela dit, rien
n'empêcherait de préparer d'abord les pages avec PHP sur
sa propre machine, avant de les mettre sur le serveur. Le principal
avantage de mon programme par rapport à PHP est celui-ci: je
peux éditer mes pages dans un éditeur Wysiwyg (j'utilise
Mozilla Composer), et quand je tape "<echo $lien>", mon
programme arrive à faire ce qu'il faut même si c'est
devenu "<echo $lien>" (codage HTML), ou bien
"%3Cecho%$20lien%3E" (codage utilisé dans les liens
eux-mêmes). Alors qu'avec PHP, il faut inclure les commandes dans
des balises <?php ...>, chose en pratique impossible à
faire facilement. Regardez mes exemples, en bas de cette page, pour
comprendre ce qu'on peut faire facilement avec mon système.
Si vous connaissez le shell, prehtml vous paraîtra
évident. Sinon, vous avez le choix: soit apprendre le shell,
soit vous passer de prehtml et trouver une autre solution à vos
problèmes. Pour l'instant, je suis à ma connaissance le
seul et unique utilisateur de ce programme.
Prehtml est écrit en C standard. Le C++ serait plus
adapté mais j'aurais passé plus de temps à m'y
remettre qu'à tout faire en C (le langage utilisé dans
les microcontrôleurs...). On m'a fait remarqué qu'il
aurait été plus simple d'utiliser des analyseurs
syntaxiques tout faits: c'est juste, mais je ne connais pas du tout ces
choses-là. Et que Perl sait faire tout cela ou presque: c'est
exact, mais comme je l'ai signalé, ma mémoire n'arrive
pas à retenir la syntaxe du Perl: à force de vouloir
englobler toutes les syntaxes existantes dans le monde de la
programmation, je trouve que ça perd un peu sa logique. Et je
trouve le Perl très difficile à déboguer
(peut-être par manque d'habitude).
Syntaxe
Les fonctions sont écrites sous une forme qui ressemble à
des balises HTML. Par exemple <SHELL titre="Le vélo">.
Bien
sûr, ce sont des balises inconnues du HTML! Mais la
différence est que si l'on utilise un éditeur HTML, cette
balise risque fort de devenir ceci ">SHELL titre="Le
vélo">" (c'est ce que fournit Netscape
Composer). Mais ce n'est pas grave, prehtml est prévu pour
décoder ce charabia et exécuter la commande tout aussi
bien. Cela dit, si la commande est tapée à la main, donc
réellement sous la forme <SHELL titre="Le vélo">,
ça marche également.
Les commandes prehtml fonctionnent en minuscules ou en majuscules.
Mais attention car le shell, lui, fait la différence! "ls" donne
la liste des fichiers, mais pas "LS", et si vous définissez
"$titre", alors "$Titre" n'est pas défini.
On lance le programme en tapant "prehtml
<liste_de_fichiers.prehtml>". Pour chaque fichier .prehtml, un
fichier .html est créé (sauf cas spécial
mentionné plus bas). Si le fichier source s'appelle .phtm, le
fichier créé s'appelle .htm. Si on donne plusieurs
fichiers, le programme fonctionne comme si on le lançait
successivement avec chaque fichier. Si le fichier qui doit être
créé existe déjà et est exactement
identique à celui qui devrait être créé, il
n'est pas modifié (sa date n'est pas affectée, ce qui est
utile pour des programmes automatiques comme Makefile ou sitecopy,
utilisables pour créer ou pour télécharger le
site).
Trêve de baratin, voici la liste des commandes, leur syntaxe,
et des exemples:
- <SHELL commande_shell>: Permet d'exécuter
une commande shell discrètement, c'est-à-dire
sans sortie dans le fichier .html créé. Exemples:
- <SHELL titre="Des pistes cyclables sur le trottoir">:
permet de définir une variable pour la suite
- <SHELL numero_info=`expr $numero_info + 1`>: permet
d'incrémenter une variable.
- <SHELL ls infos/*.html | tee liste.txt>: crée un
fichier utilisable par la suite. Cet exemple sert surtout à
signaler une limitation: il est impossible de mettre le
caractère ">" dans une commande prehtml, car il signale la
fin d'une commande. Il n'y a pas de code d'échappement,
peut-être serait-ce utile? Mais pour une simple redirection vers
un fichier, le programme "tee" fonctionne très bien.
- <ECHO texte>: permet d'écrire ce qu'on veut
dans le fichier créé, comme la commande "echo" du shell:
- Info n°<ECHO $numero_info>: <ECHO
$titre>. Notez que le fait de créer un lien
n'empêche pas la fonction de marcher, mais il faut faire
attention à ce que le lien englobe bien toute la commande, du
"<" au ">".
- <shell ref="sans_bagnoles">: ceci définit une
variable
Cliquez ici pour lire l'info :
l'adresse indiquée pour ce lien est <echo #$ref>, ce qui
sera remplacé par #sans_bagnoles
La journée du 22 septembre a
été une réussite...: juste au début de
cette ligne se trouve une cible (champ <A NAME>), dont le nom est
<ECHO #$ref>: le nom deviendra "#sans_bagnoles" après
passage par prehtml.
- Notez que l'on peut parfois inclure
des balises HTML dans des commandes prehtml, mais avec
précautions: les caractères < et > sont
codés spécialement, et ce codage est décodé
à la sortie. Exemple:
<shell titre="C'est très joli">: la variable
$titre
va prendre la valeur "C'est _lt_B_gt_très_lt_/B_gt_ joli"
<echo $titre>: le shell va fournir la valeur de la variable
$titre, mais prehtml va décoder cela et fournir la chaîne
suivante: "C'est <B>très</B> joli", ce qui
s'affichera bien "C'est très joli" dans le navigateur.
Il est évident qu'un tel système n'est pas toujours
pertinent. L'exemple cité est sans doute le seul qui a un
intérêt pratique.
Si la commande contient vraiment "_lt_", le premier "_" deviendra
"_und_". À la fin, le texte "_und_lt_" redeviendra donc "_lt_",
l'honneur est sauf.
- <SHELLECHO commande_shell>:
comme <SHELL>, sauf que le résultat est écrit dans
le fichier créé. Si la commande donne plusieurs lignes,
des sauts de lignes sont insérés entre chaque ligne (NB:
globalement le HTML n'est pas sensible aux sauts de ligne), mais ni au
début, ni à la fin. Il serait peut-être plus
rusé d'insérer des <P> entre chaque ligne, mais
j'attends vos suggestions pour savoir ce qui est le mieux
- Dernière mise à jour le <SHELLECHO date
"+%A %e %B %Y à %Hh%M">. Notez que:
- je peux mettre toute la commande en gras pour faire
ressortir
le résultat, ou bien plus que la commande, mais pas une fraction
de la commande (sous peine d'erreurs imprévisibles)
- le "à" inclus dans la commande (éventuellement
sous la forme à qui est décodée avant
d'être envoyée au shell) est recodé au format HTML
(à)avant d'être écrit dans le fichier de
sortie. C'est également le comportement de <ECHO>
- Et pour finir philosophons sur ceci: <SHELLECHO fortune>.
- <ECHONOESC>: comme <ECHO>, sauf que la
sortie
n'est pas recodée en HTML: ce n'est sans doute pas très
utile, mais sait-on jamais. "NOESC" signifie ici "no escape", pas
d'échappement des caractères spéciaux pour le HTML.
- <shell nom="El Señor Julier">
<meta name="Author" content="<ECHONOESC $nom>">
- <SHELLECHONOESC>: comme <SHELLECHO>, sauf
que
la sortie n'est pas recodée en HTML. Utile si vous faîtes
marcher une commande qui produit réellement du HTML. Un exemple
relativement simple:
- Voici la liste des fichiers HTML:
<SHELLECHONOESC ls *.html | awk $'{print $0"\074P\076"}'>:
remarquez l'échappement $'....' (compris par le shell) qui
petmet de transformer \074 en < et \076 en >. La commande
envoyée à awk est donc '{print $0"<P>"}', ce qui
lui dit d'écrire chaque ligne de l'entrée avec <P>
à la fin. L'ensemble permet de sortir la liste des fichiers avec
un passage de ligne au format HTML entre chaque.
- <INCLUDE fichiers>: inclut un ou des fichiers dans
le fichier principal.
Remarque 1: quand je dis inclure, je veux dire que les
fichiers
inclus seront traités comme s'ils étaient dans le fichier
source. Les fonctions prehtml des fichiers inclus sont
exécutées.
Remarque 2: on peut inclure plusieurs fichiers avec une seule
commande, c'est la syntaxe de la commande "cat"
Remarque 3: cette commande (comme presque toutes les commandes
de prehtml) est récursive: les sous-fichiers peuvent en inclure
à leur tour... Ils peuvent même s'inclure eux-mêmes,
mais ça ne doit pas boucler indéfiniment!
Remarque 4: si on inclut un fichier créé avec un
éditeur HTML, celui-ci contiendra certainement des balises
telles que
<HTML><HEAD></HEAD><BODY>....</BODY></HTML>.
L'insertion des fichiers commence après le champ <BODY>
(s'il existe) et se termine avant </BODY> (s'il existe), ce qui
permet de l'inclure dans un autre fichier HTML sans se poser de
questions.<INCLUDE bandeau_haut.htm>: pratique pour
définir un entête, que l'on peut changer en même
temps dans toutes les pages du site.
- Info n°<echo $numero_info>:
<INCLUDE depeche_${numero_info}.html>: dois-je vraiment
détailler l'utilité de ceci?
- <INCLUDE
definitionscommunes/*.htm>: on peut faire ça si l'on veut.
- <NOTINCLUDE fichiers>: comme <INCLUDE>, sauf
que les fichiers inclus et traités ne sont pas retransmis dans
la sortie. Pourtant, toutes les opérations sont faites
(même les sous-inclusions de fichiers, etc...). Principale
utilité: connaître des variables qui vont être
définies dans un fichier inclus. Exemple:
- <shell fichier=depeche_${annee}_${numero_info}.htm>
<NOTINCLUDE $fichier>
(Le fichier "depeche_2001_1.htm" contient la commande suivante:
<shell titre="Tous à vélo!">)
N°<echo "$numero_info : $titre">
(produit: "N°1 : Tous à vélo!")
- <REINCLUDE fichiers>: comme <INCLUDE>, sauf
que le fichier en cours de création est repris à son
commencement, et que l'entête du premier fichier inclus n'est pas
supprimé. Si <REINCLUDE> est rencontré dans une
commande <GENERATE>, ça fonctionne également, mais
attention: il faut alors qu'un <REINCLUDE> soit trouvé
pour toutes les fois qu'un fichier a été
créé avec <GENERATE>, sinon certains fichiers
créés n'auront plus d'entête ! Par contre, si
<REINCLUDE> est rencontré après une commande
</GENERATE>, cela provoque une erreur.
Par ailleurs, si <REINCLUDE> est rencontré dans un fichier
"non inclu" (avec <NOTINCLUDE>) il est traité comme un
<INCLUDE> normal. L'intérêt est que l'on peut
vouloir exécuter les commandes inclues dans une page, qui vole
elle-même la mise en page d'une autre, mais sans reprendre la
dite
mise en page ni perdre le début du fichier en cours de
création.
- (je suis dans un fichier qui contient le texte, mais dont le
titre, les mots clés, et les couleurs ne sont pas
définies);
<shell titre="Contactez-nous!">
<REINCLUDE canvas.htm>
Pour nous contacter: tél:.... e-mail:.....
Dans cet exemple, le fichier "canvas.htm" est une page HTML vide, mais
avec des couleurs définies, ainsi que les mots clés
valables pour tout le site, et comme titre la commande "<echo
$titre>". La queue de ce fichier (à partir de </BODY>
n'est pas transmise, ce qui permet d'enchaîner directement sur le
corps du fichier principal. J'ai donc "volé" la
présentation de la page "canvas.htm", tout en y mettant le titre
désiré. Idéal pour fixer la présentation de
toutes les pages!
- (exemple avec GENERATE)
<shell fichiers="un.html deux.html trois.html">
<for fich in $fichiers>
<GENERATE $fich>
<shell titre="Le titre de cette page est $fich">
<REINCLUDE canvas.htm>...et voilà, vous lisez
présentement le fichier <echo $fich>!
</GENERATE>
- exemple à plusieurs niveaux
(utilisé pour le site http://collectiftramway.free.fr,
mais là j'ai nettement simplifié):
fichiers principaux: une_page.prehtml
(édités avec Netscape Composer) |
<shell titre="Une page"><reinclude
presentation.htm> |
fichier de présentation: presentation.htm
(ce fichier aussi est édité avec Netscape Composer) |
<shell titre_complet="Collectif Tramway - $titre";
feuilledestyle=colltram.css><reinclude style.htm>
Sommaire:
bla
bla
bla |
<CHUT> |
</CHUT> |
fichier pour appeler les CSS (cascading style
sheets), ce que Netscape Composer version 4.76 ne gère pas: style.htm
(édité avec un éditeur de texte normal) |
<html><head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<meta name="GENERATOR"
content="Mozilla/4.76[fr]/Linux + prehtml/unix_console">
<meta name="AUTHOR" content="Collectif
Tramway">
<meta name="DESCRIPTION" content="bla bla
bla"
<meta name="KEYWORDS" content="bla, blo,
blu">
<META HTTP-EQUIV="Content-Style-Type"
CONTENT="text/css">
<LINK REL="STYLESHEET" HREF="<echo
$feuilledestyle>">
<title><echo
$titrecomplet></title></head>
<body>
|
feuille de style: colltram.css
(avec un éditeur de texte normal) |
/* définition des
entêtes */
H1 { display: block;font-size: 1.7em; margin: .67em auto;
font-weight: bolder; }
H2 { display: block; font-size: 1.4em; margin: .83em
auto; font-weight: bolder; }
/* etc...*/ |
- <IF condition>... [<ELSE>...] <FI>:
permet de faire des conditions. La syntaxe de l'instruction "if" du
shell, mais sans le point-virgule ";" à la fin. Note: il n'y a
pas de "then". La commande <ELSE> est facultative. Bien
sûr, les <IF> peuvent être imbriqués entre
eux, ce qui est souvent utile. La condition peut être une
commande normale, l'instruction "test", ou bien une expression entre
crochets [ ] (ne pas oublier les espaces obligatoires), ce qui revient
au même que "test", je crois.
- <IF [ $file = index.prehtml ]>ACCUEIL<ELSE>Accueil<FI>:
pratique pour faire des bandeaux qui s'adaptent à chaque page.
- <FOR variable IN liste>...... <DONE>: comme
en shell: la variable designée par valoir successivement chaque
mot de la liste. Ce qui est entre <FOR> et <DONE> va
être lu autant de fois qu'il y a de mots dans la liste. C'est une
instruction indispensables pour faire des pages un peu dynamiques, car
elle permet de faire des boucles. On peut imbriquer les <FOR>,
mais le <DONE> doit être dans le même fichier que le
<FOR> (le contraire sera d'ailleurs très bizarre).
- <FOR fichier IN depeches/depeche*.htm>
<notinclude $fichier>
- <echo $titre>
<DONE>: ceci permet de générer une liste de titres
toute simple
- <FOR fichier IN $liste_de_fichiers>
<include $fichier><DONE>: ceci permet
de lister joliment le contenu de plusieurs fichiers.
- <WHILE condition>....<DONE>: exécute
la partie entre <WHILE> et <DONE> tant que la condition est
vraie (et donc aucune fois si la condition est fausse dès le
départ. Je suppose qu'il y a des cas où c'est plus utile
que <FOR>. On peut également imbriquer les <WHILE>
entre eux (ou bien avec les <FOR>).
- <shell nb=1>
<WHILE [ -f depeche_${nb}.htm ]> (fait la boucle tant qu'il
existe un fichier du nom demandé)
<include depeche_${nb}.htm>
<shell nb=`expr $nb + 1`>
<DONE>
- <GENERATE nom_de_fichier>.....</GENERATE>:
commande spéciale qui demande à prehtml de ne pas
créer le fichier normalement prévu, mais celui qui est
indiqué dans la commande. La seule utilisation
intéressante est à l'intérieur d'une boucle
<FOR> ou <WHILE>, auquel cas les instructions
<GENERATE> et </GENERATE> sont rencontrées plusieurs
fois avec un nom différent à chaque fois.
Un fichier est créé pour chaque nom (le même nom ne
peut venir qu'une seule fois). Le début et la fin du fichier
sont communs à tous les fichiers créés, et
correspondent respectivement à la partie avant <GENERATE>
et à la partie après </GENERATE>. Par contre, la
partie variable correspond à la partie qui se trouve entre ces
deux commandes.
Remarque 1: après un </GENERATE> et avant un
<GENERATE> suivant, il ne doit y avoir que des caractères
"blancs" (espaces, tabulations, sauts de ligne "\n"), car autrement le
programme ne saurait pas où envoyer ces caractères.
Attention, les caractères blancs, ça ne comprends pas les
<BR> ou les <P> et </P> que peut inclure un
éditeur HTML si on tape sur ENTRÉE.
Remarque 2: contrairement aux autres instructions, il n'est
pas possible d'imbriquer les <GENERATE>.
Exemple:
- <for annee in 19?? 20??>
<GENERATE archives_${annee}.html>Archives de l'année
<echo $annee>
<for depeche in ${annee}/depeche*.htm>
<include $depeche>
<done>
</GENERATE>
<done>
- <CHUT>... </CHUT>: supprime
momentanément la sortie dans un fichier. On peut remarquer que
<NOTINCLUDE> est à peu près équivalent
à <CHUT><INCLUDE></CHUT>. On peut imbriquer
les <CHUT>.
Cette balise peut servir à mettre des commentaires, mais sa
véritable utilité est due aux éditeurs HTML. Si
l'on veut qu'une boucle génère un tableau ou une liste,
par exemple, il faut d'abord générer le début du
tableau (ou de la liste), puis chaque ligne, puis la fin. Or un
éditeur HTML type "Wysiwyg" ne permet pas de faire un
début de tableau sans mettre aussi la fin. La façon la
plus simple de contourner le problème est de mettre <CHUT>
à l'endroit qui est inutile. Attention car si on ne fait pas
attention, on peut générer du HTML incorrect (NB: il
existe des programmes pour vérifier la qualité du HTML:
par exemple "weblint", programme gratuit, au moins sur Linux). Exemple
d'utilisation pour un tableau:
- On génère d'abord le début du tableau (on
s'arrête juste à la fin de la dernière cellule de
la 1ère ligne)
Titre d'une colonne |
Titre de l'autre colonne<CHUT> |
- Pour chaque élément, on reprend à la fin
d'une ligne, et on génère la ligne suivante, puis on
s'arrête juste à la fin
<FOR variable IN liste>
|
</CHUT> |
dans une ligne: une cellule |
et une autre cellule<CHUT> |
<DONE>
- Puis on termine la dernière ligne et le
tableau lui-même
- Bref, on a créé un tableau sans même
savoir
quel est le nom des balises HTML pour cela! Il est cependant utile de
connaître un peu le HTML. Par exemple pour les couleurs: on peut
définir la couleur du tableau (juste au début), la
couleur de chaque ligne, et la couleur de chaque cellule. Par exemple,
dans l'exemple indiqué, le début est indiqué avec
le "fond du tableau" jaune, donc tout le tableau apparaîtra en
jaune, sauf la première ligne, dont le "fond de ligne" est en
bleu clair: la première ligne apparaîtra en bleu clair,
car la couleur de ligne est prioritaire sur la couleur de fond.
- <ERROR message> et <WARNING message>:
provoque une erreur ou un avertissement volontaire, avec le même
format que la commande <ECHO> (l'erreur stoppe prehtml, tandis
que l'avertissement n'empêche pas le programme de continuer son
fonctionnement):
<CHUT>ceci vérifie que la nouvelle fraîche n'est pas
périmée:
<shell info_peremption=20011104> (date de péremption au
format "AAAAMMJJ")
<if [ `date +%Y%m%d` -gt "$info_peremption" ]>
alors on provoque une erreur
<ERROR "Retirez
l'information, elle est périmée:
\$info_peremption=$info_peremption">
<fi>
Là, mon vieux, tu vas être obligé de mettre ton
site à jour pour recompiler cette page!!!
(avec WARNING, ce serait moins exigeant...)
</CHUT>
- <TAG message>: crée une balise HTML, avec
le
même format que la commande <ECHO>
<TAG div class=\"$style_courant\">
- variable $file : cette variable est définie
automatiquement, et est égale au nom du fichier principal que
l'on traite (bref, un fichier ".prehtml"). La variable $file ne prend
donc pas le nom des fichiers inclus.
- variable $thisfile : cette variable prend le nom du
fichier dans lequel elle est définie. Ceci n'a probablement
aucun intérêt.
- variable $dest : cette variable prend le nom du fichier
qui est en train d'être créé (donc un fichier
.html). Notez que si on utilise les balises <GENERATE>, la
variable $dest reste égale à la valeur qu'elle avait
avant la balise <GENERATE>. L'application la plus évidente
est la création de bandeaux qui s'adaptent selon la page:
- <include bandeau.htm>
avec un fichier "bandeau.htm" contenant ceci:
<if [ $dest = index.html ]>Accueil<else>Accueil<fi> |
<if [ $dest = page.html ]>Page<else>Page<fi> |
- Comportement concernant les changements de répertoire:
- le répertoire courant est celui à partir duquel
on a lancé prehtml. Il est utilisé pour lire et
écrire les fichiers, et pour l'exécution des commandes
shell
- on peut donner un chemin relatif (prehtml depeches/*.prehtml)
ou
absolu (prehtml ~/site/*.prehtml). Pour déterminer le nom des
fichiers créés à partir des .prehtml, le programme
retire juste le "p": les fichiers HTML sont donc créés
dans le même répertoire que les fichiers sources,
même si ce n'est pas le répertoire courant.
- attention cependant: un commande telle que <INCLUDE
bandeau.htm> ira chercher le fichier dans le répertoire
courant, pas nécessairement dans le répertoire où
se trouve le fichier source. De même, une commande telle que
<FOR fichier IN depeche*.htm> utilisera tous les fichiers
"depeche*.html" se trouvant dans le répertoire courant.
Bugs et limitations
- bug: Une commande prehtml (partie entre "<" et ">")
ne peut pas dépasser une certaine taille, actuellement 160
caractères (environ), définie par #define LONGUEUR_LIGNE
dans le fichier prehtml.h. Cette limite est la taille de ce qu'on a
tapé: on peut taper <for fichier in
depeches/20*/depeche*.html>, qui est une commande courte, même
si les fichiers sont très nombreux, et que leurs noms pris
ensemble dépassent de loin cette limite. Par contre, chaque
fichier doit avoir un nom plus court que cette limite (y compris chemin
d'accès).
- bug: Ce système n'est prévu que pour
le jeu de caractères iso-8859-1 (iso-latin-1, européen de
l'ouest), ça risque de faire n'importe quoi si on met des
caractères orientaux ou d'Europe centrale. Je pense que la bonne
solution serait de traiter les "é" et autres comme c'est
fait pour les balises HTML inclues dans les commandes (donc ne pas les
décoder, pour s'affranchir des questions liées au jeu de
caractères). Rien n'est prévu pour les jeu de
caractères sur 2 octets, et là ce serait sans doute plus
délicat.
- limitation: Le shell est potentiellement dangereux, comme
tout langage complet: ne traitez pas un fichier .prehtml d'origine
inconnue, si jamais il contenait <SHELL rm -R \>, vous pourriez
effacer tout le disque.
- limitation: Le shell se bloque facilement, par exemple
avec <echo "salut>, à cause du guillemet non
refermé. S'il manque un guillemet ou autre, la commande ne
démarre pas, et le programme s'arrête après 3
secondes. Si la commande dure plus de 30 secondes, le programme le
signale et indique à quel endroit c'est arrivé, mais
continue le traitement sans erreur.
- limitation: On ne peut pas mettre ">" dans une
commande
prehtml puisque c'est le signal de fin de commande. Pour contourner, il
y a "tee" pour les redirections, ou bien les codes d'échappement
du shell en $'\074....\076'
- limitation: Si on veut réellement écrire
une
commande prehtml dans le fichier HTML, il est difficile de faire en
sorte qu'elle ne soit pas décodée par prehtml. Mieux vaut
écrire la page directement en HTML (comme celle-ci par exemple),
ou bien inclure directement une page HTML (par exemple avec
<SHELLECHONOESC cat un_fichier.html>). Si vous voulez
réellement taper une commande, vous pouvez toujours inclure
quelque chose qui va empêcher prehtml de repérer la
commande: par exemple <<ECHO>WHILE> donne <WHILE>,
puisque <ECHO> tout seul ne donne aucune sortie.
- limitation: C'est pour les amateurs de shell, mais
à tout prendre, il est plus utile d'apprendre le shell que
d'apprendre un langage que l'on ne retrouvera jamais.
- limitation: Serait-il utile d'avoir une version de
<SHELLECHO> qui inclue des <P> à la fin de chaque
ligne? Ça n'a rien de difficile.
- limitation: Les caractères accentués non
terminés par ";" ne sont pas décodés (exemple:
é au lieu de é), je crois que ceci est une entorse
à la norme HTML, mais les éditeurs HTML incluent toujours
le point-virgule.
Trucs et astuces
Pour m'en sortir entre les extensions, j'utile ces conventions:
- .prehtml: fichiers qui doivent être traités par
prehtml
- .html: fichiers écrits directement sous la forme
définitive, et fichiers générés par prehtml
- .htm: fichiers inclus par prehtml
Pour lancer prehtml, il y a au moins deux bonnes méthodes:
- si tous les fichiers sont dans le même répertoire,
et qu'ils ne sont pas trop gros (question de vitesse), on peut lancer:
prehtml *.prehtml (ce qui traite l'ensemble des fichiers)
- utiliser
l'utilitaire "make", avec un fichier nommé "Makefile" qui
contient les lignes suivantes:
faitprehtml.htm : *.prehtml
prehtml $?
touch faitprehtml.htm
Le fichier "faitprehtml.htm", dans cet exemple, sert juste à
sauvegarder la date du dernier traitement par prehtml. Les fichiers
*.prehtml plus récents sont alors traités avec prehtml.
Voici un exemple de Makefile que j'utilise:
# Je définie ici la liste des fichiers
à traiter par prehtml
sources=*.prehtml projet/*.prehtml
actualite/*.prehtml affiches/*.prehtml
# action par défaut
all :
faitprehtml.synchro faitdepeches.synchro index.html quidonc.html
if
grep -r -n /home/julier *.htm *.html *.prehtml; \
then echo Lien incorrect!; exit 2; fi
# cette page contient la liste des
associations adhérentes au collectif:
# elle doit être refaite dès que
la liste des associations a bougé,
# même si le fichier "quidonc.prehtml"
est
inchangé
quidonc.html: liste/*/asso*.htm
prehtml quidonc.prehtml
# sert à oublier quand a tourner
prehtml pour la dernière fois
oublie :
rm
-f faitprehtml.synchro faitdepeches.synchro
# oblige à traiter pour les fichiers
.prehtml
force : oublie all
# La page d'accueil doit être refaite
à chaque fichier modifié,
# car j'ai mis a la date de dernière
modification dessus.
index.html: $(sources) */* */*/*
prehtml index.prehtml
# traitement normal pour toutes les pages:
on lance prehtml uniquement
# sur les fichiers .prehtml qui ont
été modifiés depuis la dernière fois
faitprehtml.synchro: $(sources)
prehtml $?
touch faitprehtml.synchro
# traitement à part pour les pages
d'actualités, qui sont créées à partir
# d'un fichier .prehtml qui crée
d'autres
fichiers avec <GENERATE>: je retraite
# toute la liste dès qu'il y a une
nouvelle info (fichiers info*.htm)
faitdepeches.synchro: actualite/info*.htm
prehtml actualite/*.prehtml
touch faitdepeches.synchro
# Ceci ne sert pas à grand-chose
clean : oublie
rm
-f *.tmp *~ core a.out
Pour transférer les fichier sur le serveur j'utilise "sitecopy"
(un programme gratuit). Pour ne transférer que les bons
fichiers,
le fichier de configuration ~/.sitecopyrc contient les lignes
suivantes:
exclude "*.htm"
exclude "*.prehtml"
exclude "*.tmp"
exclude "Makefile"
Questions légales
Tout le monde a le droit d'utiliser ce programme, de le recompiler (en
enlevant les informations de débogage par exemple...), de
l'adapter à d'autres systèmes d'exploitation, de le
modifier pour son usage ou pour l'usage d'autrui.
Les limitations sont les suivantes:
- Il doit être indiqué quel est l'auteur original
(Michel Julier), et si des modifications ont été
apportées par d'autres personnes.
- Il est possible de le vendre (bonne chance!), mais il n'est pas
possible d'interdire aux utilisateurs de le redistribuer (gratuitement
ou non).
- Ce programme doit être fourni avec ses sources
complètes, même s'il a été modifié
par quelqu'un d'autre que moi.
Historique
- 13/04/2007: version 1.8: modification d'une commande shell
utilisée en interne (read) pour éviter des blocages
- 14/08/2006: version 1.7: ajout des extensions .prehtml et .prehtm
comme noms valides. Ceci car .phtm et .phtml sont parfois
refusés par certains éditeurs HTML en tant que
correspondant à des programmes en PHP. Les extensions .phtml et
.phtm restent utilisables
- 20/08/2005: version 1.6: amélioration du comportement des
fonctions dont la réponse est longue, de façon à
éviter les passages à la ligne intempestifs tous les 160
caractères.
- 03/10/2004: version 1.5: modification de la communication entre
le process principal et le process du shell Unix qui est lancé
en parallèle. Au lieu des fichiers FIFO nommés (pas
très élégant, et non portable sur une machine
non-Unix), ce sont maintenant les fonctions pipe() et dup2() qui sont
utilisées.
- 20/04/2003: version 1.4: traitement spécifique du codage
des caractères dans les liens. Alors que Netscape Composer
version 4 laissait gentiment des codes comme <a href="<echo
$lien>">cliquez ici</a>, Netscape Composer versions 6 et 7
ou Mozilla 1.3 (que j'utilise maintenant) détectent des
caractères interdits dans un lien et transforment en <a
href="%3Cecho%20$lien%3E">cliquez ici</a>. Cette nouvelle
version détecte ce codage, le décode avant de traiter la
commande prehtml, puis recode le résultat de la même
manière (au lieu du codage HTML genre "é")
- 03/08/2002: correction d'un bug qui rendait inutilisable la
fonction <SHELLECHONOESC>
- 18/05/2002: ajout de <TAG>
- 26/01/2002: version 1.3: modification des spécifs de
<REINCLUDE>, pour permettre de mettre <REINCLUDE> dans un
fichier inclus (exemple à plusieurs niveaux dans cette doc):
j'en avais besoin et en fait c'était devenu réalisable
depuis la version 1.2
- 28/11/2001: version 1.2: Correction d'un gros bug dans
<REINCLUDE>: on pouvait retrouver un fichier avec plein
d'entêtes mises à la suite (ce qui ne semble poser de
problème dans aucun navigateur!).
- 17/10/2001: version 1.1: Correction de <REINCLUDE>, qui
marche maintenant même dans <GENERATE>, et ajout des
commandes <ERROR> et <WARNING>.
- 23/10/2001: version 1.0.beta-2. Ajout de <REINCLUDE>.
- 15/10/2001: version 1.0.beta-1. Grand nettoyage: gestion
complète du shell bloqué ou tardant trop, et de l'arre
par l'utilisateur; effacement des fichiers temporaires en cas
d'arrêt brutal.
- 13/10/2001: version 1.0. C'est la première modification
depuis un mois: détection des blocages du shell (guillemet non
fermé, possibilité limitée d'inclure du HTML dans
les commandes). Je décide de mettre enfin un numéro de
version.
- 27/09/2001: le programme fonctionne vraiment bien, je l'utilise
pour la création d'un autre site: http://collectiftramway.free.fr
(association militant pour améliorer les projets de tramway
à Montpellier).
- 14/09/2001: le programme fonctionne, je commence à
l'utiliser pour un site réel: http://montpellier.fubicy.org
(association de cyclistes urbains à Montpellier)
- 31/08/2001: idée originale d'un préprocesseur
basé sur le shell, et utilisable depuis un éditeur HTML
Wysiwyg. Une brève recherche sur internet, et je ne trouve rien
dans ce genre. En fait, je voudrais un genre de PHP, mais simple, et
qui vise le traitement avant de télécharger les pages sur
un serveur (et non le traitement à la demande).
Moi
J'ai une page ici.
Adresse de cette page: http://mjulier.free.fr/prehtml/lisezmoi.html