Titres, code : un premier programme effectif


Dernière intervention le 27/11/2003

Troisième projet :
Inclure les balises <h1>, <h2> et <h3> en début de titre.
Inclure les balises </h1>, </h2> et </h3> en fin de titre.

18. Incorporer la balise <h1>


Découverte des manipulations en mode interprêté


create aaa 100 allot ok
s" ###*Ceci est un titre" aaa swap cmove ok
aaa 10 type ###*Ceci e ok
s" <h1>" aaa swap cmove ok
aaa 10 type <h1>Ceci e ok
Du fait du choix initial : le début de ligne ###* (soit 4 signes) est facile à écraser avec <h1> sans avoir à gérer un décalage de la suite du texte.

Comment découvrir si le texte commence par <h1> ?


Gforth propose le mot "compare" qui est intéressant en ce sens qu'il permet d'isoler une portion de la chaine la plus longue

compare c-addr1 u1 c-addr2 u2 -- n

Compare two strings lexicographically. If they are equal, n is 0; if the first string is smaller, n is -1; if the first string is larger, n is 1.
Application à partir de la chaine aaa dans son état actuel :
aaa 4 s" <h1>" compare .s <1> 0 ok
Remarquer que l'interrogation de la pile donne 0 (les chaines sont égales).
aaa 4 s" <h2>" compare .s <1> -1 ok
Remarquer que l'interrogation de la pile donne 1 (les chaines sont différentes).
aaa 8 s" <h1>" compare .s <1> 1 ok
Nous avons pris une longueur de 8 caractères dans aaa. Il est normal que l'on retrouve 1 sur la pile : l'une des chaines est plus longue que l'autre.

Réalisation d'un test logique


Nous allons réaliser en test en utilisant IF THEN ELSE, puisque c'est la syntaxte de Gforth.
Remarquons qu'elle est plus lourde, moins subtile que la syntaxe de 4IM.

Syntaxe de Gforth :
: mot comparaison
if
ce qu'on fait si vrai
else
ce qu'on fait si faux
endif ;
Les instructions conditionnelles (telles que IF ELSE ENDIF ne "fonctionnent qu'à l'intérieur de mots compilés (pas en mode interprétés).

19. Un programme de synthèse


Application à un exemple : le script test.fs


#! /usr/local/bin/gforth

256 Constant max-line
Create chaine max-line allot
s" ###*Ceci est un titre" chaine swap cmove
: vrai? 0 = IF ." vrai " else ." faux " endif ;
chaine 4 s" ###*" compare
vrai? cr
chaine 4 s" ##**" compare
vrai? cr

bye

19. Un premier programme qui fait "tout"


Le script dont le listage est présenté ci-dessous permet de générer automatiquement les pages web qui correspondent aux règles définies au paragraphe 8.
Il est très perfectible (et d'ailleurs si un des mots s'appelle "pourri" c'est que l'auteur considère qu'il est allé au plus vite et sans trop de finesse).

Malgré tout, il fait ce pourquoi il a été saisi.
Certaines modifications ont été apportées dans le code, dans le sens de sa simplification, grâce à l'apport de Frédéric Dubois.

Listage du programme creepageconta3.fs


#! /usr/local/bin/gforth

256 Constant max-line
Create chaine max-line allot
variable n1 0 ( longueur de la chaine lue dans le fichier )
variable n2 0 ( longueur de la chaine ajoutée )
variable n3 0 ( longueur résultante )

( ouverture des fichiers cible et source )
s" entete.txt" r/o open-file throw Value fd-in
s" scripting6.html" w/o create-file throw Value fd-out

: br s" <br />" ;
: dans chaine swap cmove ;
: h1 s" <h1>" dans ;
: h2 s" <h2>" dans ;
: h3 s" <h3>" dans ;
: /h1 s" </h1>" ;
: /h2 s" </h2>" ;
: /h3 s" </h3>" ;

: ecris ( adr x -- ) fd-out write-file throw ;
: titre1 h1
chaine n1 @ ecris
/h1 ecris ;
: titre2 h2
chaine n1 @ ecris
/h2 ecris ;
: titre3 h3
chaine n1 @ ecris
/h3 ecris ;
: cod s" <code>" ecris ;
: /cod s" </code>" ecris ;
: pourri ( ce code est vraiment assez pourri )
chaine 4 s" ####" compare 0 =
if titre1 ( 1 )
else ( 1 )
chaine 4 s" ###*" compare 0 =
if titre2 ( 2 )
else ( 2 )
chaine 4 s" ##**" compare 0 =
if titre3 ( 3 )
else ( 3 )
chaine 4 s" ***D" compare 0 =
if cod ( 4 )
else ( 4 )
chaine 4 s" ***F" compare 0 =
if /cod ( 5 )
else ( 5 )
chaine n1 @ ecris
br ecris
endif ( 5 )
endif ( 4 )
endif ( 3 )
endif ( 2 )
endif ( 1 ) ;


( écriture et fermeture )

: ferm-dans ( ferme le fichier cible ) fd-out close-file throw ;
: ferm-source ( ferme le fichier source ) fd-in close-file throw ;


: ecris-entete ( transfert en-tete vers vers cible )
begin chaine max-line fd-in read-line throw
while chaine swap ecris
repeat ;

: ecris-body ( effectue le transfert source vers cible )
begin chaine max-line fd-in read-line throw
swap dup n1 ! swap
while pourri

repeat ;

: ecris-fin
s" <br><br><A HREF='#haut'> Haut de page</A><br /></p></body></html>" ecris ;

( écrit l'en-tête dans le fichier cible puis ferme le fichier d'en-tête )
ecris-entete
ferm-source

( ouvre le texte de l'article et le recopie modifié fans le fichier cible )

s" page6.txt" r/o open-file throw Value fd-in

ecris-body

ecris-fin

( fermeture des deux fichiers )
ferm-source
ferm-dans

bye
Je le commenterai davantage si une demande est exprimée en ce sens.

20. En guise de conclusion provisoire


Un pas en avant a été fait. Il va falloir maintenant se colleter avec Apache.

A suivre donc.




Haut de page