Présentation de TextWheel

Textwheel — littéralement, « la roue du texte » — est un projet visant à simplifier l’écriture de règles de transformation d’un texte d’un format vers un autre.

Quand on s’intéresse aux systèmes de publication sur Internet, on a la forte impression que chacun réinvente la roue de son côté, refaisant pour chaque composant du logiciel sa propre implémentation.

Textwheel s’attaque à l’un de ces composants : la transformation d’un texte « brut » en texte présentable à l’écran.

Par exemple, sous SPIP, on transforme :
{Hello} {{World}}
en :
<i>Hello</i> <strong>World</strong>

Sous Textile, on transforme :
_Hello_ *World*
en :
<em>Hello</em> <strong>World</strong>

En BBCode, on aura :
[i]Hello[/i] [b]World[/b]

L’ennui jusqu’ici c’est que chaque logiciel (gestion de contenu, gestion de forums) est livré avec ses propres raccourcis, dans sa propre implémentation. Il n’y a donc ni standard, ni possibilité d’échanger, ni possibilité de modifier ses raccourcis. Textwheel est une proposition visant à répondre à ces soucis d’interopérabilité.

Le principe : avec Textwheel, plutôt que de coder une fonction qui effectue ces règles de transformation, on les décrit dans un fichier de configuration (ex : spip.yaml), au format très simple (YAML). Textwheel se chargera d’appliquer ces règles.

Ainsi, Textwheel sépare la création des « raccourcis d’édition » de leur implémentation technique.

Avec Textwheel, les raccourcis de SPIP se programment donc ainsi :

strong:
  match: [ "{{", "}}" ]
  replace: [ "<strong>", "</strong>" ]
italics:
  match: [ "{", "}" ]
  replace: [ "<i>", "</i>" ]

Ceux de Textile :

strong:
  match: "/\*(\w*)\*/U"
  replace: "<strong>\1</strong>"
italics:
  match: "/_(\w*)_/U"
  replace: "<em>\1</em>"

et le BBCode :

strong:
  match: [ "[b]", "[/b]" ]
  replace: [ "<strong>", "</strong>" ]
italics:
  match: [ "[i]", "[/i]" ]
  replace: [ "<i>", "</i>" ]

On voit qu’il est dès lors très facile d’ajouter les raccourcis BBCode ou Textile dans SPIP, ou l’inverse, en manipulant des fichiers de configuration. Bien entendu les cas plus complexes (callbacks, expressions rationnelles) sont prévus.

Avantages de Textwheel

L’interopérabilité entre logiciels n’est pas le seul avantage.

-  Extensibilité. Il est plus aisé pour un utilisateur de manipuler un fichier de configuration au format établi, que de se plonger dans des modifications de code qui peuvent sauter à chaque mise à jour.

-  Traitements. Dès lors que les raccourcis sont codés de manière descriptive, et non pas fonctionnelle, il est possible de leur faire subir des traitements qui ne se limitent pas à les appliquer à un texte. On peut par exemple les appliquer à la chaîne sur l’ensemble des textes d’une base de données, et voir lesquels sont utilisés, combien de fois, à quels textes... et à quelle vitesse.

-  Rapidité. Ce qui permet de détecter des règles mal programmées, inutiles, trop lentes ou pas efficaces. En appliquant cette méthodologie aux raccourcis de SPIP, nous avons pu en quelques jours diviser par deux le temps de calcul des textes (sur certaines bases de texte d’usage réel).

-  Compilation. Une autre sortie possible pour un fichier de raccourcis, c’est une compilation sous forme de code dans un langage arbitraire (par exemple : PHP, python, ruby, javascript, C...). Cette approche devrait permettre à terme de retrouver les mêmes raccourcis sous différents logiciels, quel que soit leur langage de programmation, et aussi bien côté serveur (PHP, python) que client (javascript).

-  Tests unitaires. Jusqu’ici les raccourcis avaient tendance à « casser » dès lors qu’on mettait les mains dans le code, et il était bien difficile, lorsqu’on constatait un bug, de voir à quel niveau des traitements le résultat devenait non conforme. Maintenant que notre moteur peut comparer, pour chaque règle, le résultat obtenu avec sa valeur attendue, un jeu de tests peut non seulement nous dire si quelque chose a changé, mais nous dire aussi précisément quoi.

-  Évolutivité. Cette approche devrait permettre de redynamiser le travail sur les raccourcis (introduction de nouveaux raccourcis, suppression de raccourcis obsolètes, amélioration de raccourcis mal foutus...). Car on peut imaginer construire un outil qui permettra de signaler le cas échéant au webmestre qui met à jour son site qu’il aura, par exemple, deux articles à vérifier (et lesquels) suite à une amélioration du code. Outil qui sera basé sur de simples fichiers YAML.

Surcharger une wheel en SPIP 3 (via un fichier .yaml)

Exemple pour modifier le traitement effectué par une wheel en la surchargeant dans un plugin (ou un squelette) :

Supposons qu’afin de ne pas passer pour un ayatollah de la mise en page, je souhaite modifier la wheel qui supprime les saut de lignes successifs (raccourcis _ donnant des <br>) dans les textes rédigés par les auteurs.
L’examen des fichiers yaml de textwheel/wheels/spip/ permet de trouver la règle en question dans spip.yaml :

paragraphes:
  # paragraphes
  # lignes vides consecutives, br imbriques dans des p
  # mais attention pas les br trop riches (ex: br style=clear:both)
  match: ["/ *\n(?: *\n)+(?:<br ?\/?>)*/S", '/(?:<br\b[^>]*>){2,}\s*/S', "/(<p\b[^>]*>)\n*(?:<br ?\/?>\n*)+/S"]
  replace: ['<p>', '<p>', '$1']
  priority: 0

C’est donc la règle paragraphes qu’il va falloir surcharger et plus précisément son 2e remplacement (match) :
'/(?:<br\b[^>]*>){2,}\s*/S' = "une suite de <br>" remplacé par une balise '<p>'

Il faut alors déterminer quelle est la wheel qui importe le fichier spip.yaml afin de pouvoir la surcharger. Le début du fichier textwheel/inc/textwheel.php opère (L25 et suivantes) la construction de la globale $GLOBALS[’spip_wheels’] qui stocke toutes les wheels :

$GLOBALS['spip_wheels']['raccourcis'] = array(
	'spip/spip.yaml',
	'spip/spip-paragrapher.yaml'
);

La wheel à surcharger est donc raccourcis.

A partir de là on va donc pouvoir faire la surcharge de la manière suivante :

  • dans le fichier mes_options.php du site ou prefixe_options.php d’un plugin on appelle un fichier multi_br.yaml supplémentaire en l’intégrant en fin de la wheel raccourcis :
$GLOBALS['spip_wheels']['raccourcis'][] =  'spip/multi_br.yaml';
  • ce fichier est stocké dans le dossier squelette du site ou d’un plugin sous le chemin wheels/spip/multi_br.yaml
  • dans ce fichier on redéclare la règle paragraphes :
paragraphes:
  # paragraphes
  # lignes vides consecutives, br imbriques dans des p
  # mais attention pas les br trop riches (ex: br style=clear:both)
  match: ["/ *\n(?: *\n)+(?:<br ?\/?>)*/S", '/(?:<br\b[^>]*>){2,}\s*/S', "/(<p\b[^>]*>)\n*(?:<br ?\/?>\n*)+/S"]
  replace: ['<p>', '$0', '$1']
  priority: 0

le 2e remplacement est effectué sans modification : $0 correspondant au résultat complet du match

Conclusion : par cette technique on peut surcharger des règles existante ou en ajouter sans toucher au contenu du plugin texwheel.

Surcharger une wheel en SPIP 4 (via un fichier .json)

Exemple pour modifier le traitement effectué par une wheel en la surchargeant dans un plugin (ou un squelette) :

Supposons qu’afin de ne pas passer pour un ayatollah de la mise en page, je souhaite modifier la wheel qui supprime les saut de lignes successifs (raccourcis _ donnant des <br>) dans les textes rédigés par les auteurs.
L’examen des fichiers json de textwheel/wheels/spip/ permet de trouver la règle en question dans spip.json :

  "paragraphes": {
    "match": [
      "\/ *\n(?: *\n)+(?:<br ?\\\/?>)*\/S",
      "\/(?:<br\\b[^>]*>){2,}\\s*\/S",
      "\/(<p\\b[^>]*>)\n*(?:<br ?\\\/?>\n*)+\/S"
    ],
    "replace": [
      "<p>",
      "<p>",
      "$1"
    ],
    "priority": 0
  },

C’est donc la règle paragraphes qu’il va falloir surcharger et plus précisément son 2e remplacement (match) :
'/(?:<br\b[^>]*>){2,}\s*/S' = "une suite de <br>" remplacé par une balise '<p>'

Il faut alors déterminer quelle est la wheel qui importe le fichier spip.json afin de pouvoir la surcharger. Le début du fichier textwheel/inc/textwheel.php opère (L25 et suivantes) la construction de la globale $GLOBALS[’spip_wheels’] qui stocke toutes les wheels :

$GLOBALS['spip_wheels']['raccourcis'] = array(
	'spip/spip',
	'spip/spip-paragrapher'
);

La wheel à surcharger est donc raccourcis.

A partir de là on va donc pouvoir faire la surcharge de la manière suivante :

  • dans le fichier mes_options.php du site ou prefixe_options.php d’un plugin on appelle un fichier multi_br.json supplémentaire en l’intégrant en fin de la wheel raccourcis :
    $GLOBALS['spip_wheels']['raccourcis'][] =  'spip/multi_br';
  • ce fichier est stocké dans le dossier squelette du site ou d’un plugin sous le chemin wheels/spip/multi_br.json
  • dans ce fichier on redéclare la règle paragraphes :
{
	"paragraphes": {
		"_comment": "surcharge pour autoriser les br successifs",
		"match": [
			"\/ *\n(?: *\n)+(?:<br ?\\\/?>)*\/S",
			"\/(?:<br\\b[^>]*>){2,}\\s*\/S",
			"\/(<p\\b[^>]*>)\n*(?:<br ?\\\/?>\n*)+\/S"
		],
		"replace": [
			"<p>",
			"$0",
			"$1"
		],
		"priority": 0
	}
}

le 2e remplacement est effectué sans modification : $0 correspondant au résultat complet du match
l’entrée _comment du json est facultative et utilisée pour permettre des commentaires de la surcharge.

Conclusion : par cette technique on peut surcharger des règles existante ou en ajouter sans toucher au contenu du plugin texwheel.

Télécharger


Le projet est développé sur le Git de SPIP https://git.spip.net/spip/textwheel : pour le télécharger utilisez la commande suivante :

git clone https://git.spip.net/spip/textwheel.git

ou récupérez son Zip sur https://plugins.spip.net/tw.html

Le plugin pour SPIP donne une page ?exec=tw dans l’espace privé qui permet de voir ce qui change entre textwheel et la fonction propre() classique de SPIP : les quelques textes où le rendu n’est pas exactement identique sont signalés, ainsi que le temps passé dans chaque rule, et le temps total des calculs.

Participer

Si cette rapide présentation vous a alléché, sachez que toutes les participations sont les bienvenues.

Le projet est, pour démarrer, codé en anglais et en PHP. Il offre d’ores et déjà des spécifications en version 0.1, une implémentation en PHP, et un plugin pour SPIP qui remplace le moteur historique de SPIP par cette nouvelle approche.

Nous n’en sommes qu’au début. Il y a beaucoup à faire sur ce projet, qu’il s’agisse d’améliorer les specs, de contribuer de la documentation, d’établir des cas tests, de coder des implémentations dans d’autres langages (ruby, javascript), etc.

Une communauté de développeurs se met en place sur la mailing-list textwheel@rezo.net ; URL : http://listes.rezo.net/mailman/listinfo/textwheel

A bientôt !

Discussion

9 discussions

  • Bonjour,
    J’ai régulièrement des erreurs dans textwheell lorsque je suis en dev et que je fais une purge du cache ou un recalcul de page et que je repasse dans la partie privée ...
    A chaque fois le plantage est dû au fait que textwheel essaie d’appliquer une rule/règle nommée « --- », ce qui correspond à la récupération de l’entête d’un fichier yaml. Il y a donc probablement une erreur de décodage d’un des fichiers yaml de règles. L’erreur étant aléatoire, je n’ai pas réussi à déterminer dans quelles circonstances, ni à quel endroit du code se produisait le bug. Aussi afin de ne plus être enquiquiné, j’ai rajouté un test dans engine/textwhell.php dans la boucle foreach de la fonction text() :

    foreach ($rules as $name => $rule) 
    {
       if ($rule == "---") continue;
       $this->apply($rules[$name], $t);
    }

    Je ne sais pas si cela arrive à d’autres, peut-être est-ce dû à ma config et au jeux de plugins que j’utilise, mais peut-être qu’il serait bien d’implémenter un vérification que la ’rule’ passée soit correcte, ou même en amont lors de la récupération des rules dans les fichiers yaml ...

    Cordialement
    TG

    Répondre à ce message

  • JudaPriest

    Note pour les prochains.

    Doc pas à jour, le repo « officiel » à jour c’est https://git.spip.net/spip/textwheel

    Et en creusant (au hasard), il semble avoir un début de refonte pour le passage vers composer : https://github.com/spipremix/tw

    Répondre à ce message

  • 3

    Bonjour,

    Installer textwheel0.8.32 sur SPIP 3.0.24 -> un jeu d’enfant :-)
    Installer textwheel1.5.4 sur SPIP 3.2.1 -> un casse tête :-(

    impossible de l’activer et voici le message :

    Actions réalisées
    La désactivation du plugin « TextWheel pour SPIP » (version : 1.5.4) ne s’est pas correctement déroulée
    L’activation du plugin « TextWheel pour SPIP » (version : 1.5.4) s’est correctement déroulée

    Il ne se retrouve pas dans les plugins activés !

    Pourriez-vous m’aider s’il vous plaît, car là je patauge.

    • heu, textwheel est livré par défaut avec SPIP 3 et supérieur, pourquoi l’activer à part ?

    • Oups ! Ben évidemment, c’est une bonne raison.
      En tout cas merci pour votre réponse très rapide :-)

      En réalité, j’essayais d’activer textwheel afin de tenter de bricoler quelque chose pour pallier l’absence de mise à jour de Latexwheel, un plugin magnifique qui fait gagner un temps fou, mais qui n’est malheureusement plus disponible pour SPIP 3.2.

    • bah heu, je pense que LaTeXwheels est compatible 3.2, juste j’ai jamais eu le temps/le besoin de le tester (il aurait suffi peut être de commencer par demander sur le forum).

      Comme pour tous les plugins qui ne sont pas marqués compatible 3.2, cela peut juste signifier qu’il n’a pas été testé.

      La démarche est la suivante :
      -  dans le fichier paquet.xml, remplacer

      compatibilite="[3.0.0;3.1.*]"

      par

      compatibilite="[3.0.0;3.2.*]"


      -  cela permet d’activer le plugin
      -  tester le plugin
      -  si cela marche, prévenir l’auteur du plugin (en l’occurence moi) et/ou la communauté SPIP pour qu’elle mette à jour les infos dans la version distribuée du plugin.

      Sincèrement, vu comment fonctionne le plugin, je ne vois pas de raison qu’il ne fonctionne pas en 3.2

    Répondre à ce message

  • conil26

    Bjr,

    J’ai un warning que je ne parviens pas à supprimer en page d’accueil public après recalcul de la page.

    Merci de vos conseils.
    SPIP 3 avec Escal V 3.
    http://www.essaillon-sederon.net/

    Warning : array_merge() : Argument #1 is not an array in /home/www/2e575dd733252702d72dad94b64fec4a/web/plugins-dist/textwheel/inc/lien.php on line 538

    Répondre à ce message

  • 4

    Bonjour

    Je n’ai pas trouvé de téléchargement de TW compatible avec Spip 2.1 pour le plugin todo.

    Où dois-je chercher ?

    Bonne journée

    Jean-Michel

    Répondre à ce message

  • Bonjour,

    Sous SPIP 2.1.19 [19922], Sarka-SPIP 3.0.4 [40664] le plugin TextWheel 0.8.6 - stable annule les redirections d’articles.

    Pouvez-vous corriger SVP

    Bien cordialement

    FDG

    Répondre à ce message

  • 1
    benolaos

    Bonjour à tous,
    Je salive d’avance à la réalisation de ce projet qui permet, si je comprends bien, de pouvoir réellement « jouer » sur des mises en page personnalisées.
    Pour autant, je dois avouer ne pas avoir compris si à l’heure actuelle quelque chose a été fait ou non d’utilisable...

    • Textwheel est disponible en plugin pour SPIP 2.1, et intégré en standard dans SPIP3.

    Répondre à ce message

  • pour info : projet latewheels sur la spip-zone. Objectif : transformer des raccourcis SPIP en code latex.

    Répondre à ce message

  • tres bonne idee. il y a bcp de petit raccourcis qui serait bien utlise de pourvoir ’customize’ facilement.

    Répondre à ce message

Ajouter un commentaire

Avant de faire part d’un problème sur un plugin X, merci de lire ce qui suit :

  • Désactiver tous les plugins que vous ne voulez pas tester afin de vous assurer que le bug vient bien du plugin X. Cela vous évitera d’écrire sur le forum d’une contribution qui n’est finalement pas en cause.
  • Cherchez et notez les numéros de version de tout ce qui est en place au moment du test :
    • version de SPIP, en bas de la partie privée
    • version du plugin testé et des éventuels plugins nécessités
    • version de PHP (exec=info en partie privée)
    • version de MySQL / SQLite
  • Si votre problème concerne la partie publique de votre site, donnez une URL où le bug est visible, pour que les gens puissent voir par eux-mêmes.
  • En cas de page blanche, merci d’activer l’affichage des erreurs, et d’indiquer ensuite l’erreur qui apparaît.

Merci d’avance pour les personnes qui vous aideront !

Par ailleurs, n’oubliez pas que les contributeurs et contributrices ont une vie en dehors de SPIP.

Qui êtes-vous ?
[Se connecter]

Pour afficher votre trombine avec votre message, enregistrez-la d’abord sur gravatar.com (gratuit et indolore) et n’oubliez pas d’indiquer votre adresse e-mail ici.

Ajoutez votre commentaire ici

Ce champ accepte les raccourcis SPIP {{gras}} {italique} -*liste [texte->url] <quote> <code> et le code HTML <q> <del> <ins>. Pour créer des paragraphes, laissez simplement des lignes vides.

Ajouter un document

Suivre les commentaires : RSS 2.0 | Atom