[spip-dev] Retour d'expérience sur le filtre post_autobr sur un texte comportant des modèles

Le filtre post_autobr permet d’ajouter en début de ligne des _ lorsqu’un texte comporte des retours simples à la ligne.

Mais, si un texte comporte un appel de modèle comportant des retours à la ligne, par exemple :

<modele123|param1=truc

param2=machin
param3=chose>

alors post_autobr ajoute des _ non désirés dans l’appel du modèle.

Les appels de modèles sur plusieurs lignes sont fort pratiques pour les modèles ayant un grand nombre de paramètres et permet d’avoir une meilleure lisibilité quand on rédige un texte.

La question qui se pose est la suivante :

  • soit la syntaxe d’appel d’un modèle sur plusieurs lignes est considérée comme correcte, dès lors le code de post_autobr devrait également échapper les modèles (pour le moment seul echappe_html est appelé, cette dernière fonction n’échappant pas les modèles) ;
  • soit la syntaxe d’appel à un modèle sur plusieurs lignes est considérée comme invalide. Auquel cas il faudrait faire évoluer la documentation de SPIP () cette dernière présentant des exemples avec une syntaxe sur plusieurs lignes.

Bien cordialement

Joseph

soit la syntaxe d'appel d'un modèle sur plusieurs lignes est considérée
comme correcte,

oui, elle est correcte

dès lors le code de post_autobr devrait également échapper
les modèles (pour le moment seul echappe_html est appelé, cette dernière
fonction n'échappant pas les modèles) ;

peux-tu envoyer des tests unitaires et un patch ?

Il faut que cette fonction soit parfaite et qu'on trouve enfin une
manière de l'activer par défaut sans tout casser dans les sites
existants. La situation actuelle est vraiment malpratique.

-- Fil

J'ai cherché mais pas trouvé. Existe-t-il déjà une fonction echapper_modeles ou équivalente ?
Cette dernière permettrait d'échapper les modèles sans les traiter (puisqu'ils seraient traités ensuite).
Avec une telle fonction, il suffirait d'ajouter $texte = echappe_html($texte, '', true); au filtre post_autobr.

J'essaie de préparer des tests unitaires.

Joseph

J'ai ajouté des tests unitaires pour post_autobr [48191].

En l'état, aucun des tests ne fonctionne car il manque un include_spip('inc/texte'); dans le code de post_autobr.

Joseph

Il apparait qu’il est possible de fournir une expression régulière à echappe_html.

J’ai testé, sous SPIP 2.1.10, ceci qui semble fonctionner :

// postautobr : transforme les sauts de ligne en _
// function post_autobr($texte, $delim="\n_ “) { include_spip(‘inc/texte’); $texte = str_replace(”\r\n", “\r”, $texte); $texte = str_replace("\r", “\n”, $texte); if (preg_match(",\n+$,", $texte, $fin)) $texte = substr($texte, 0, -strlen($fin = $fin[0])); else $fin = ‘’; $texte = echappe_html($texte, ‘’, true); // Echapper les modeles $preg_modeles = ‘(<([a-z_-]{3,})’ # <modele .’\s*([0-9])\s’ # id .’(|?)?’ # |arguments (y compris des tags <…>) .’\s/?’.’>)’; # fin du modele > $texte = echappe_html($texte, ‘’, true, $preg_modeles); $debut = ‘’; $suite = $texte; while ($t = strpos(’-’.$suite, “\n”, 1)) { $debut .= substr($suite, 0, $t-1); $suite = substr($suite, $t); $car = substr($suite, 0, 1); if (($car<>’-’) AND ($car<>’_’) AND ($car<>"\n") AND ($car<>"|") AND ($car<>"}") AND !preg_match(’,^\s*(\n|</?(quote|div)|$),S’,($suite)) AND !preg_match(’,</?(quote|div)> *$,iS’, $debut)) { $debut .= $delim; } else $debut .= “\n”; if (preg_match(",^\n+,", $suite, $regs)) { $debut.=$regs[0]; $suite = substr($suite, strlen($regs[0])); } } $texte = $debut.$suite; $texte = echappe_retour($texte); return $texte.$fin; } Il y a deux modifications : Cordialement Joseph

Au cas où cela puisse être utile ailleurs,
il est également possible d’envisager de faire une fonction echappe_modeles dans inc/texte.php avec

define(‘PREG_MODELES’, '(<([a-z-]{3,})’ # <modele
.’\s*([0-9])\s’ # id
.’(|?)?’ # |arguments (y compris des tags <…>)
.’\s
/?’.’>)’
); # fin du modele >

function echappe_modeles($letexte, $source=’’) {
$preg_modeles = ‘(<([a-z_-]{3,})’ # <modele
.’\s*([0-9])\s’ # id
.’(|?)?’ # |arguments (y compris des tags <…>)
.’\s
/?’.’>)’; # fin du modele >
return echappe_html($letexte,$source,true,_PREG_MODELES)
}

et de faire un appel à echappe_modeles dans post_autobr

Cordialement

joseph