Un Wiki stand-alone en PHP
Présentation
J'avais besoin d'un composant Wiki pour que cette fonctionnalité puisse être inclue dans n'importe quelle application, et pourquoi pas sur ce site même ?
Mon objectif était simple :
- Un script court et auto-suffisant
- De la rapidité/performance
- Une bonne résilience aux données d'entrées invalides
- La syntaxe Wiki doit être un paramètre du code et pas hardcodée
- Doit être extensible par le biais de plug-ins (pour de nouveaux objets) ou de templates (pour leurs présentations)
Ce Wiki devait permettre de transformer une chaîne comme :
[[toc]]
==Titre principal
Voici une formule **très importante** pour la compréhension de la suite du chapitre :
<math>I_2=\frac{x-a}{2}f^{\prime\prime}(a)+\int_{a}^x\frac{x-t}{2}f^{(3)}(t)dt</math>
C'est un résultat capital à plus d'un titre :
# Il est élégant
# Il est aisé à dériver
# Il se retient facilement
==Deuxième partie
Texte **totalement** //non-important//
en une présentation HTML (par exemple) comme suit :
Le schéma
Pour obtenir ce résultat, j'aurai pu utiliser un des nombreux wikis disponibles, mais comme d'habitude, j'ai préféré le faire moi-même.
Pour ça, j'ai mixé un lexer et un parseur récursifs dans un même code et mis tout ça sous la forme d'une machine à états, décrite par des données et non pas du code.
Le raisonnement
Le premier constat c'est que les blocs à transformer ont des marqueurs de début et de fin, un mode de concrétisation, ou une template, et des options.
Par exemple pour transformer un bloc en gras le marqueur de début est '**', identique à celui de fin avec la possibilité d'être récursif (ce qui est mis en gras peut lui-même contenir d'autres mises en forme).
Un autre exemple est l'ajoût d'un titre. Cette fois le marqueur de début est '==', celui de fin est la fin de la ligne (\"\\n\") et l'option principale est de référencer le bloc produit dans la table des matières.
Le schéma est donc très simple et j'aboutit à un code de moins de 200 lignes, en comptant les options que je décris ci-dessous.
La syntaxe
| '==', '===' etc. | pour titres qui seront référencés dans la table des matières. |
| 'http://www.example.com' | une adresse web se transforme automatiquement en lien. |
| // | pour mettre en italique un bloc de texte |
| ** | pour mettre en gras un bloc de texte |
| [URL ALT] | pour ajouter un texte \"ALT\" qui pointe vers l'URL donnée |
| [{URL ALT}] | pour ajouter une image d'URL donnée qui a \"ALT\" comme texte alternatif |
| ---- | pour une ligne horizontale (eq. <hr/>) |
| \\n | un simple retour à la ligne (eq. <br/>) |
| \\n\\n | début d'un nouveau paragraphe (eq. <p>) |
| ` | deux backtick délimitent un bloc qui ne sera pas parsé par le module |
| \"> \" | pour mettre en exergue un bloc de texte multiligne (eq. <blockquote>) |
| \"- \" | un élément d'une liste à puces non-numérotées |
| \"# \" | un élément d'une liste à puces numérotées |
| [[refs]] | indique l'emplacement des notes de bas de page (créés par [URL]) |
| [[toc]] | crée la table des matières (contenant des pointeurs vers les titres décrits plus haut) |
| <math>...</math> | insère une formule au format TeX |
Les plug-ins
Comme plug-in de base, j'ai inclus celui des formules mathématique que je décris par ailleurs.
Les deux autres sont la possibilité d'avoir des notes en bas de pages (issu des blocs utilisant la notation [...]) et une table des matières automatique, créée à partir des titres.
Applications
Je n'ai pas écrit ce code uniquement pour m'amuser mais parce que l'édition de contenu des applications que je développe à titre professionnel m'imposait d'avoir une façon simple de créer des documents sans outils préalables.
Ainsi des sites commerciaux ou professionnels (donc privés) utilisent ce composant aujourd'hui même.
Reste à faire
La gestion des renvois des notes en bas de page n'est pas élégante du tout, c'est plus du hard-code qu'autre chose.
La gestion des tableaux est à faire, c'est crucial !
Au niveau du visuel, il faut : 1- générer le flux HTML et associer des classes CSS aux éléments comme les titres etc., 2- améliorer les templates existantes (qui sont basiques) et permettre de les modifier ou d'en ajouter de nouvelles, sur le schéma de [[toc]] et [[refs]].
Il faut gérer les antislashes pour indiquer que la ligne se poursuit à la suivante (c'est une pré-passe très courte à faire au début de la fonction principale).
Améliorer les notes en bas de page pour ajouter la possibilité d'ajouter des commentaires aux liens.
