Aller au contenu | Aller au menu
Page personnelle de Denis Jasselette
Ce site regroupe quelques travaux personnels et autres informations d'utilité parfois douteuse.
Derniers articles
Équations TeX en HTML
Posté le sam 26 jun à 01:13.
Il sera question dans cet article d'un de mes scripts qui répond au doux nom de teqhtml, version courte de TeX Equations to HTML. Celui-ci, comme son nom l'indique fort subtilement, permet d'intégrer des équations mathématiques exprimées en TeX dans un code HTML.
Origine
À la base, je cherchais à pouvoir insérer des formules mathématiques dans mes pages HTML, voire Markdown, de façon simple et efficace. Beaucoup de gens se sont évidemment penchés sur cette question avant moi et plusieurs méthodes pour y parvenir existent. J'ai dû en éliminer certaines telles que MathML ou JsMath pour des raisons de portabilité. Le meilleur compromis que j'aie trouvé était celui exposé dans cet article de Kjell Magne Fauske.
Un avantage non négligeable de cette dernière solution est qu'elle était basée
sur un script en Python, ce qui me permettait de le bidouiller. Pour commencer,
j'ai modifié la méthode d'extraction des formules pour préférer les balises
$...$ et $$...$$ inspirées de
LaTeX et bien plus légères à écrire (dans l'esprit de Markdown).
Beaucoup de modifications plus tard, le script est devenu bien plus complet et n'a plus grand chose à voir avec celui de départ. Dès lors, j'ai pensé qu'il pourrait être utile à d'autres et c'est pourquoi il est maintenant disponible sous licence GNU GPL sur SourceForge.net.
Utilisation
Voici un exemple simple d'utilisation :
Dans un plan muni d'un repère orthonormé, l'équation du cercle de centre
et de rayon
est :
Ce résultat a été obtenu avec le code
Dans un plan muni d'un repère orthonormé, l'équation du cercle de centre
$C(a,b)$ et de rayon $r$ est :
$$(x - a)^2 + (y - b)^2 = r^2$$
Les $...$ délimitent une formule en ligne tandis que les
$$...$$ désignent un bloc. Les balises
<math>...</math> et
<dispmath>...</dispmath> (respectivement) en sont des alias
et peuvent être utilisées de la même façon.
Les deux syntaxes sont générées avec l'environnement LaTeX correspondant. Ce
qui implique que les mêmes différences de rendu sont observées. Par exemple,
une somme affichée en ligne :
sera plus
compacte que quand elle est affichée en bloc :

Il faut également remarquer que le script décale verticalement l'image pour que
sa ligne de base soit alignée avec celle du texte contigu. Par exemple, on
a
.
Ainsi, les formules s'intègrent au mieux dans le texte.
Petit détail pratique, pour afficher le caractère $
- à l'intérieur d'une formule, utilisez la méthode d'échappement habituelle de
TeX, à savoir
$ \$ $(rendu :
) ; - à l'extérieur d'une formule, utilisez la méthode d'échappement habituelle du
HTML, à savoir
$.
L'utilisation de ce script ne se limite pas aux fichiers HTML. En effet, on peut l'utiliser conjointement avec Markdown. Personnellement, je l'utilise également pour mes courriels, il me suffit de copier-coller le rendu vers la fenêtre d'édition de mon client de messagerie (Evolution).
Options importantes
--bg- Permet de changer la couleur de fond et notamment de la rendre transparente. La transparence progressive n'étant pas supportée par Internet Explorer, la valeur par défaut est blanc.
-i,--inline- N'utilise pas de fichiers externes pour stocker les images des formules. Celles-ci sont directement encodées dans le fichier de sortie. Malheureusement, ceci n'est pas supporté par Internet Explorer.
-s,--sans-serif- Permet d'utiliser une police sans serif pour les formules plutôt que celle par défaut. Vu que les pages Web utilisent le plus souvent de telles polices, ceci permet de rester consistent avec le style du texte. Cette option requiert que le paquet « sfmath » soit installé dans votre distribution LaTeX (sur Ubuntu, présent dans le paquet texlive-latex-extra).
Voir aussi
PHP : un moteur de templates
Posté le ven 12 fév à 23:07.
Cet article discute de l'utilisation de moteurs de templates en PHP. Beaucoup de moteurs libres sont disponibles sur le Web et beaucoup de gros projets embarquent leur propre version. J'explique brièvement ici le principe et quelques problèmes courants. Je propose ensuite une alternative qui me semble bien plus saine et plus simple à la fois.
Introduction
Fond et forme
Dans une page Web on peut distinguer le fond de la forme. Le fond désigne le contenu, dans notre cas, les données d'une page et la logique qui permet de traiter ces données. La forme est la représentation de ces données, c'est-à-dire toute la partie HTML. Ces deux aspects d'une page Web se gèrent complètement différemment et requièrent même des langages différents. Ainsi, pour que le code soit clair il est souvent utile de les séparer. En équipe, l'intérêt est encore plus flagrant puisqu'un graphiste pourra ainsi travailler indépendamment d'un programmeur et inversement.
Moteur de templates
Un moteur de templates aide les développeurs à séparer fond et forme. La démarche consiste à stocker les données récupérées grâce à la logique et ensuite de placer ces valeurs aux bons endroits dans un fichier HTML. Ce dernier fichier est appelé template (qui signifie gabarit).
Moteurs de templates en PHP
Il existe une multitude de moteurs de templates différents et pourtant la plupart sont fort similaires.
Typiquement, le moteur est disponible sous la forme d'une classe. Cette classe fournit un objet qui peut retenir des valeurs, voire des blocs de valeurs, et qui va traiter un fichier template en suivant une syntaxe spécifique pour indiquer les emplacements où placer les valeurs.
Syntaxes exotiques
La syntaxe utilisée peut varier fortement d'un moteur à l'autre. Elle contient en général au moins une façon d'afficher une valeur stockée. Elle peut aussi inclure des structures de contrôle pour effectuer boucles, conditions, inclusions d'autre templates ou exécution de fonctions définies par l'utilisateur.
Traitement de la syntaxe
La syntaxe est soit interprétée directement, soit compilée en PHP. Ces traitements sont souvent peu efficaces puisqu'ils sont codés en PHP. Il arrive même qu'ils donnent des résultats inattendus lorsqu'ils utilisent des REGEXP, par exemple. Le traitement des erreurs est fort variable également, il peut aller d'une erreur fatale à aucune erreur signalée mais un résultat incohérent pour une erreur de syntaxe.
En bref, le PHP étant déjà un langage interprété, une compilation complète et efficace est très difficile à obtenir.
Mise en cache intégrée
Enfin un point positif, la mise en cache est souvent gérée automatiquement par le moteur. C'est d'ailleurs une façon de pallier aux mauvaises performances de la compilation. Le fait qu'une fonction se charge d'afficher la page entière permet de récupérer facilement et de façon transparente le code final généré. Ceci requiert une configuration plus fine de la part du développeur pour obtenir le résultat voulu mais c'est l'inévitable contrainte de toute mise en cache.
Encapsulation des données
Voilà un gros mot issu de la POO, l'encapsulation. Il désigne ici le fait que les variables stockées dans l'objet sont les seules à être accessibles depuis un fichier template. Ainsi, pas de problème de conflits de noms et ça évite qu'un graphiste utilise une variable qui pourrait changer suivant l'implémentation de la logique.
PHP comme moteur
Finalement, quelle est la différence entre un moteur de templates et PHP ? S'il suffit de stocker des variables et de les afficher au milieu d'un code HTML, PHP a l'air tout à fait adapté.
Histoire
En fait, PHP a été initialement conçu avec les mêmes objectifs qu'un moteur de templates. On l'appelle un préprocesseur hypertexte (PHP est l'acronyme récursif de : « PHP: Hypertext Preprocessor ») mais c'est la même idée sous-jacente. Depuis, PHP s'est complexifié, il s'est vu intégrer des tas de fonctions et peut faire beaucoup plus. Cependant, les syntaxes de templates sont souvent directement traduisibles en quelques structures de contrôle de base de PHP.
Performance
Les performances ne peuvent qu'être meilleures puisqu'on rend inutile la compilation intermédiaire. De plus, on profite de toute la puissance de PHP avec ses erreurs et ses fonctions.
Syntaxes alternatives
Si vous trouvez trop long d'écrire <?php echo $var; ?>, pensez à <?=$var?>
qui est spécialement prévue pour ce cas de figure. La syntaxe des conditions et
des boucles délimitées par des accolades peut rendre le code indigeste au
milieu de HTML, mais peut-être préférerez-vous les équivalents :
<? if (!empty($next_article)): ?>
<a href="#a<?=formatURL(basename($next_article["filename"]))?>"
title="Article précédent">
<img src="skin/images/go-down.png" alt="Article précédent" />
</a>
<? else: ?>
<img src="skin/images/go-down-disabled.png"
alt="Pas d'article précédent" />
<? endif; ?>
Consultez la doc pour la liste complète.
Mise en cache
La mise en cache est plus délicate parce qu'il faudra refaire vos propres outils. Cependant, il y a moins d'étapes à mettre en cache qu'avec un moteur de templates. En effet, on ne doit plus se soucier de l'étape de compilation. De plus, la mise en cache des données finales est aisée puisqu'il suffit de récupérer le contenu finalement affiché. Tant que le fond est bien séparé de la forme, on peut inclure le template via une fonction et ainsi en profiter pour stocker le résultat de manière tout aussi transparente qu'avec un moteur.
Conclusion
Les moteurs de templates ne sont que des surcouches inutiles. Leur seul intérêt est de forcer l'architecture des fichiers. Beaucoup de gens ne s'en rendent pas compte mais PHP est fait, avant tout, pour ce genre de tâches. Les fonctions de gestion de bases de données, de manipulations d'images… ne sont que des plus. Une fois que l'architecture des fichiers est respectée, pourquoi ajouter une nouvelle syntaxe obscure et bancale ? Les graphistes n'auront pas plus de mal à apprendre les structures de base du PHP plutôt que celles d'une autre syntaxe.
Voir aussi
Character Encodings
Posté le jeu 22 oct à 09:25.
Ci-joint un article pdf que j'ai écrit dans le cadre de mon cours d'anglais.
Introduction au Markdown
Posté le sam 19 sep à 16:22.
Le HTML est le langage de balisage standard pour les pages Web. Il permet de formater du texte à l'aide de balises. Ces balises suivent une syntaxe proche de celle du XML puisqu'ils sont tous deux issus du SGML. Il est, comme le XML, avant tout destiné à être facilement lu par un programme et peut être fort verbeux.
Les langages de balisage légers permettent également le formatage de texte mais avec comme premiers objectifs de rester facilement lisibles sous la forme non traitée et de permettre une écriture plus rapide par un humain. Ce qui les rend particulièrement adaptés lorsqu'on est limité à une interface en texte brut, comme c'est le cas pour les formulaires sur le Web par exemple.
Un langage de balisage léger très populaire sur les forums est le BBCode avec sa syntaxe inspirée du HTML mais limitée aux balises les plus simples. Un autre exemple est le WikiCode utilisé notamment par la célèbre Wikipédia. Dans cet article, je vais vous présenter Markdown qui ressemble au WikiCode mais sans être aussi ciblé que ce dernier.
Origine
La communication par courrier électronique se pratiquait déjà avant l'Internet. Pendant longtemps, les messages étaient envoyés en texte brut pour des raisons de portabilité et de temps de téléchargement. De nos jours, bien que la plupart des clients permettent d'utiliser le HTML, l'utilisation du texte brut est toujours privilégiée pour certains usages, pour les mailing lists par exemple.
Des conventions syntaxiques sont apparues pour pallier l'absence de mise en
forme. La plus connue est sans doute celle qui consiste à précéder toutes les
lignes d'une citation par le caractère > suivi d'une espace.
La syntaxe de Markdown a été principalement inspirée de ces conventions.
Bref aperçu de la syntaxe
Reprenant l'exemple cité plus haut, les citations se marquent en précédant
chaque ligne de > , comme dans les emails. Les citations
peuvent s'imbriquer en répétant ces deux caractères en fonction de la
profondeur voulue.
Les paragraphes doivent simplement être précédés et suivis d'une ligne blanche. Les retours à la ligne simples sont ignorés pour vous permettre de limiter la largeur de vos lignes. Les retours à la ligne n'ont aucune valeur sémantique et sont donc déconseillés mais vous pouvez néanmoins les forcer en plaçant au moins deux espaces à la fin de la ligne.
L'emphase est marquée en entourant l'ensemble des mots concernés par * ou
_, l'emphase forte est obtenue en répétant ces mêmes symboles deux fois.
L'insertion de code dans une phrase se fait avec `.
Les listes à puces s'écrivent comme suit :
* Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
viverra nec, fringilla in, laoreet vitae, risus.
* Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
Suspendisse id sem consectetuer libero luctus adipiscing.
Les listes ordonnées s'écrivent de la même façon mais en utilisant un nombre
suivi d'un point plutôt que des * :
1. Premier élément
2. Deuxième élément
Le but n'est pas ici d'être exhaustif, comme l'indique le titre. Vous pouvez néanmoins constater que cette syntaxe est proche d'une écriture naturelle et qu'elle reste donc parfaitement lisible. Pour quelque chose de plus complet, je vous invite à consulter la documentation (originale ou traduite).
Mieux que HTML ?
Markdown n'est en aucun cas un remplacement pour le HTML. Il ne fait que fournir une syntaxe simplifiée pour utiliser les éléments de formatage les plus courants dans un texte.
Par contre, sa syntaxe simple ne vous limitera pas puisqu'il permet l'insertion de code HTML à peu près n'importe où. Ainsi, pour faire quelque chose de spécifique, comme un tableau ou la définition d'une abréviation, vous pourrez toujours vous rabattre sur la balise HTML correspondante.
Mise en cache Web
Posté le jeu 10 sep à 13:15.
La mise en cache de données consiste à stocker le résultat d'opérations coûteuses dans une zone de mémoire afin de pouvoir directement y accéder par la suite.
Le Web est particulièrement propice à cette pratique. En effet, communiquer à travers l'Internet constitue une opération très lourde et, en général, répétitive. Elle est répétitive au niveau du client d'une part qui doit télécharger les mêmes images d'une page à l'autre sur un site, par exemple. D'autre part, le serveur envoie souvent un même résultat à beaucoup de clients différents.
Cet article traite de la mise en cache à divers niveaux et aborde quelques pistes pour mettre ce principe en application. Vous n'y trouverez pas de code tout fait, comme souvent quand il s'agit d'optimisations, il n'y a pas de solution générale, vous devrez adapter les idées au cas par cas.
Cache serveur
Accès à une base de données
L'accès à une base de données en lecture constitue souvent la majeure partie de
la charge du serveur. Or, si certaines requêtes retournent effectivement un
résultat différent à chaque fois, la plupart change rarement. Pour soulager
votre serveur et éviter des requêtes inutiles pensez à mettre en cache certains
résultats. Suivant le type d'informations, vous pourrez les stocker dans un
fichier ou dans les variables de session. La fonction de PHP :
var_export() peut vous faciliter grandement la tâche.
Divers exemples courants
J'ai pris l'accès aux bases de données comme premier exemple car c'est souvent ce qui demande le plus de ressources au serveur mais les idées du précédent paragraphe peuvent être appliquées à tout ce qui plombe vos performances. Des exemples courants sont :
- L'utilisation de templates. La plupart des moteurs de templates que vous trouverez sur le Web mettent en cache leurs résultats et vous devriez éviter ceux qui ne le font pas. Le traitement de templates est très coûteux et doit être mis en cache pour être viable.
- La traduction à la volée. Je ne m'étendrai pas trop sur le sujet mais pour traduire un site Web, vous pouvez créer automatiquement un fichier par langue à partir d'un fichier où les morceaux de texte à traduire sont balisés plutôt que de les substituer à chaque affichage.
- La génération automatique d'images. Si vous utilisez GD, par exemple, pour générer une image dynamiquement, vous devriez essayer de déterminer une durée de vie pour chaque image (par exemple une minute, une heure ou une journée) pour ne pas effectuer ces calculs trop régulièrement.
Toute la difficulté est de savoir combien de temps la version en cache reste à jour. Pour le cas des templates ou de la traduction, vous pouvez utiliser la date de dernière modification du fichier de référence par rapport à celle de la version en cache. Vous pouvez également déterminer à l'avance un âge maximal au-delà duquel le cache est mis à jour, comme c'est le cas avec l'exemple des images. Cette dernière solution implique un décalage possible entre les modifications et l'affichage, à vous de savoir si vous pouvez vous le permettre et l'âge à utiliser pour que ce soit acceptable.
Mise en cache événementielle
Il n'est pas toujours évident de déterminer quand un élément en cache doit être rafraîchit au moment de l'affichage. Disons que vous avez un blog et que vous désirez mettre la page d'accueil en cache. Cette page d'accueil contient les derniers articles et pour chacun le nombre de commentaires postés. En exploitant les idées citées précédemment, vous pouvez penser à comparer la date de mise à jour de la version en cache avec la date du dernier article dans la base de données et avec la date du commentaire le plus récent en rapport avec les cinq derniers articles. Si votre blog est populaire, avec beaucoup de commentaires, vous ne gagnerez pas grand chose et vous ferez deux requêtes pour déterminer si le cache est à jour.
Une autre solution consiste à effacer le fichier contenant la version en cache lorsqu'un article ou un commentaire est ajouté. Il vous suffit alors de vérifier que le fichier existe pour savoir s'il faut rafraîchir le cache ou non. La mise à jour du cache est déclenchée par un événement.
Cache client
Contrôle du cache du navigateur avec HTTP
Votre navigateur met en cache certains fichiers, comme les images ou les fichiers statiques en général. Dès que la version en cache n'est plus à jour, le navigateur télécharge à nouveau le fichier. Pour le déterminer, le serveur HTTP et le navigateur communiquent en HTTP les informations nécessaires et plusieurs méthodes existent (elles peuvent également être utilisées conjointement).
La plus simple est l'en-tête Expires. Grâce à celui-ci, le serveur donne
directement une date à laquelle le fichier sera périmé et devra être rechargé.
Cette méthode est cependant assez limitée et contraignante. Je donne
ci-après une astuce pour contourner ses inconvénients dans
certains cas.
L'en-tête Last-Modified permet au serveur de donner la date de dernière
modification du fichier. L'idée est que le navigateur enregistre cette valeur
et, quand il veut utiliser le fichier, il envoie une requête avec un en-tête
If-Modified-Since qui renseigne la date enregistrée. Ainsi, si le serveur
constate que le fichier n'a pas été modifié depuis ce moment, il n'envoie pas
le fichier mais simplement une réponse de type 304 Not Modified, beaucoup
plus légère à télécharger. Le navigateur sait donc qu'il possède une version à
jour et il l'utilise. Cette méthode permet d'être sûr de toujours avoir le
fichier à jour mais oblige le navigateur à envoyer une requête et à attendre la
réponse.
HTTP 1.1 a introduit un nouvel en-tête : Cache-Control qui regroupe une
série de valeurs et permet de contrôler plusieurs aspects à la fois. La plus
importante de ces valeurs pour nous est max-age qui permet de spécifier le
nombre de secondes durant lequel le fichier peut être considéré comme à jour.
Un exemple de son utilisation :
Cache-Control: max-age=600
Dans cet exemple, le fichier ne sera pas rafraîchit avant 10 minutes
(600 secondes). Cet en-tête peut être combiné avec Last-Modified, ça
reviendra à vérifier que le fichier n'a pas été modifié mais pas plus d'une
fois toutes les 10 minutes. C'est fort similaire à Expires mais en plus
flexible.
Pour des informations exhaustives à propos de Cache-Control, consultez la
spécification de HTTP 1.1.
Le serveur peut également utiliser l'en-tête Etag avec la réponse
correspondante If-None-Match. Cependant, cette méthode est liée à des
informations sur le fichier et ne peut donc pas être étendue aux fichiers
dynamiques, je ne m'étendrai pas sur le sujet.
En général, les navigateurs permettent de contourner le comportement par défaut
et de forcer le rafraîchissement des fichiers avec leur fonction Actualiser.
Expires est la méthode la plus radicale. Il est fortement conseillé
d'utiliser une date d'expiration loin dans le futur pour tous les fichiers
images du design, les fichiers CSS et Javascript. Mais bien sûr, vous n'avez
pas envie de demander à vos visiteurs de faire un Ctrl + F5 à chaque fois que
vous modifiez ces fichiers. Voici une petite astuce pour contourner ce problème
et profiter pleinement de Expires. Disons que vous avez un fichier design.css
commun à toutes vos pages et vous ne le faites expirer que dans deux ans. Vous
modifiez votre fichier suite à un bug que vous avez découvert sous Internet
Explorer. Pour que tous vos visiteurs voient leur version rafraîchie, changez
simplement le nom du fichier en quelque chose comme : design.css?1 dans
votre balise <link> des pages HTML, ça n'affecte pas le contenu de votre
fichier mais le navigateur considère les deux fichiers comme différents. Ainsi,
seules vos pages auront besoin d'être rechargées régulièrement, ce qui est
souvent préférable de toutes façons.
Fichiers dynamiques
Les en-têtes Last-Modified et Etag pour les fichiers statiques sont
généralement très bien gérés par le serveur HTTP et des valeurs par défaut pour
l'expiration sont utilisées. Si vous voulez bidouiller celles-ci, consulter la
documentation de votre serveur (celle d'Apache). Pour les
fichiers de script comme PHP, le serveur ne peut rien deviner et ne donne donc
aucune indication utile au navigateur. Pour utiliser au mieux le cache du
navigateur vous devrez envoyer les bons en-têtes HTTP « à la main »,
en PHP utilisez la fonction header().
et de rayon
est :

