Prehtml, version 1.1
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!
(format .tar.gz, à décoder en lançant "tar -zxf
prehtml.tar.gz", un fichier nommé prehtml sera créé).
Mais avant d'utiliser ce programme, jetez un coup d'oeil rapide aux
questions
légales.
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 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 ? Parce que PHP, qui est conçu
pour s'exécuter sur le serveur lui-même, est infiniment plus
complexe que ce que je recherchais. De plus, PHP n'est pas conçu
pour générer toute une série de fichiers, alors que
prehtml sait le faire facilement avec <GENERATE> (c'était un
des buts du projet: gérer l'archivage de vieilles informations,
année par année). En bref: PHP n'est sans doute pas vraiment
utilisable pour traiter les fichiers avant de les télécharger
sur le serveur.
Est-ce que ça a marché? Essayez toujours de jeter un oeil
à montpellier.fubicy.org,
mais aussi à collectiftramway.free.fr,
un site que j'ai créé en quelques jours avec l'aide de ce
programme. Pour ma part, je suis plutôt content du résultat,
d'autant que moins d'une semaine après l'idée de départ,
le programme fonctionnait déjà et, pire, je l'utilisais déjà
avec parfaite satisfaction.
Aperçu général
Plusieurs cas se présentent:
-
Je crée une page toute simple: aucun problème, elle s'appellera
page.html (ou page.htm chez certains adeptes de Microsoft, pour cause de
limitation du MS-DOS à 8+3 caractères). J'utilise alors un
éditeur HTML quelconque et mon programme ne sert à rien.
-
Je crée une page qui doit être modifiée automatiquement
en fonction de certains paramètres: je crée une page nommée
page2.phtml (l'extension .phtm est également possible), qui est
une page normale mais contenant des commandes spéciales. Cette page
sera lue par prehtml et les commandes spéciales seront décodées:
à la fin du traitement, une page HTML sera créée par
mon programme (elle s'appellera page2.html, ou bien page2.htm pour les
microsots).
-
Je veux crée une série de pages HTML (par exemple une page
d'archives pour chaque année). J'écris alors une page nommée
page3.phtml, qui contient les commandes nécessaires pour décrire
comment les pages doivent être créées (en général,
ceci comprends l'inclusion d'autres pages). Le programme prehtml va exécuter
les commandes et créer toutes les pages demandées (mais toujours
basées sur page3.phtml), par contre il ne créera pas de page3.html.
Principe de prehtml
Le principe est fort simple: au début du programme, un "shell" démarre
en parallèle de prehtml. Les commandes trouvées dans les
fichiers .phtml (fichiers source) sont décodées avec l'aide
du shell et/ou sous la forme de commandes shell. Le même shell tournant
du début à la fin du traitement de la page, il est capable
de stocker des variables, ce qui est très utile.
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.phtml>".
Pour chaque fichier .phtml, 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.
-
(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>
-
<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.phtml ]>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>
-
variable $file : cette variable est définie automatiquement,
et est égale au nom du fichier principal que l'on traite (bref,
un fichier ".phtml"). 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/*.phtml) ou absolu (prehtml
~/site/*.phtml). Pour déterminer le nom des fichiers créés
à partir des .phtml, 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(?): Je trouve le système qui communique avec le shell
peu élégant, mais ça marche quand même très
bien. Voir le fichier shell.c si vous avez des suggestions à faire.
-
bug: il n'est actuellement pas possible de mettre <REINCLUDE>
après une commande <GENERATE>, mais ce sera sans doute corrigé
ultérieurement car cela serait intéressant.
-
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).
-
limitation: Le shell est potentiellement dangereux, comme tout langage
complet: ne traitez pas un fichier .phtml 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.
-
limitation: 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.
Trucs et astuces
Pour m'en sortir entre les extensions, j'utile ces conventions:
-
.phtml: 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 *.phtml (ce qui traite l'ensemble des fichiers)
-
utiliser l'utilitaire "make", avec un fichier nommé "Makefile" qui
contient les lignes suivantes:
faitprehtml.htm : *.phtml
prehtml $?
touch faitprehtml.htm
Le fichier "faitprehtml.htm", dans cet exemple, sert juste à sauvegarder
la date du dernier traitement par prehtml. Les fichiers *.phtml 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=*.phtml projet/*.phtml actualite/*.phtml
affiches/*.phtml
# action par défaut
all : faitprehtml.synchro
faitdepeches.synchro index.html quidonc.html
if grep
-r -n /home/julier *.htm *.html *.phtml; \
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.phtml" est inchangé
quidonc.html: liste/*/asso*.htm
prehtml
quidonc.phtml
# sert à oublier quand a tourner prehtml pour
la dernière fois
oublie :
rm -f
faitprehtml.synchro faitdepeches.synchro
# oblige à traiter pour les fichiers .phtml
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.phtml
# traitement normal pour toutes les pages: on lance
prehtml uniquement
# sur les fichiers .phtml 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 .phtml 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/*.phtml
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 "*.phtml"
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
-
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.
Moi
J'ai une page ici.
Adresse de cette page: http://mjulier.free.fr/prehtml/lisezmoi.html