[spip-dev] Bug filtre couper ?

Bonjour,

Je constate une anomalie sur l’utilisation du filtre “couper” mais la doc étant assez évasive cela est peut être “normal”.

Testé sur SPIP 2.1.0 [15608] et SPIP 2.0.10 SVN [15770], dans une boucle ARTICLES classique :
#TITRE = Comparateur assurance habitation
→ 33 caractères
[(#TITRE|couper{30})] = Comparateur assurance habitati
→ Je ne devrais pas avoir “Comparateur assurance (…)” à la place ?

La doc précise que le filtre “essaie de ne pas couper les mots”, ce qui laisse supposer que de temps en temps ça ne marche pas ?

Je n’ai pas créé de ticket dans Trac ne sachant pas si c’était le comportement attendu…

Merci,
Thomas

#TITRE = Comparateur assurance habitation
-> 33 caractères
[(#TITRE|couper{30})] = Comparateur assurance habitati
-> Je ne devrais pas avoir "Comparateur assurance (...)" à la place ?

non, car là ça coupe "trop", on perd trop d'information

La doc précise que le filtre "essaie de ne pas couper les mots", ce qui
laisse supposer que de temps en temps ça ne marche pas ?

façon de parler ; on regarde de combien ça coupe, et si c'est trop
différent en % de ce qu'on vise, on fait autrement.

Je n'ai pas créé de ticket dans Trac ne sachant pas si c'était le
comportement attendu...

Ce qui serait nécessaire c'est un jeu de tests.

-- Fil

#TITRE = Comparateur assurance habitation
→ 33 caractères
[(#TITRE|couper{30})] = Comparateur assurance habitati
→ Je ne devrais pas avoir « Comparateur assurance (…) » à la place ?

non, car là ça coupe « trop », on perd trop d’information

Entre un mot tronqué ou signaler que l’on a tronqué l’information, je ne suis pas sur que ce soit plus pertinent…

La doc précise que le filtre « essaie de ne pas couper les mots », ce qui
laisse supposer que de temps en temps ça ne marche pas ?

façon de parler ; on regarde de combien ça coupe, et si c’est trop
différent en % de ce qu’on vise, on fait autrement.

Comment surcharger cette fonction pour retirer/modifier ce pourcentage ? En recréant la fonction couper() dans mes_fonctions.php, je fais planter le site… :confused:

J’ai eu le même soucis il y a quelques mois, signalé aussi sur cette liste d’ailleurs, et j’ai fini par développer mon propre filtre avec un autre nom parce que le comportement prévu ne me convenait pas.

Cool ! Tu le mets sur contrib ?

Je ne sais plus exactement ce qui est modifié par rapport à couper(), mais à priori pas grand chose, pas le temps d’expliquer maintenant, mais voici le code :

function mon_couper($texte, $taille=50, $suite = ’ (…)’)
{
if (!($length=strlen($texte)) OR $taille <= 0) return ‘’;
$offset = 400 + 2*$taille;
while ($offset<$length
AND strlen(preg_replace(",<[^>]+>,Uims","",substr($texte,0,$offset)))<$taille)
$offset = 2*$offset;
if ( $offset<$length
&& ($p_tag_ouvrant = strpos($texte,’<’,$offset))!==NULL){
$p_tag_fermant = strpos($texte,’>’,$offset);
if ($p_tag_fermant<$p_tag_ouvrant)
$offset = $p_tag_fermant+1; // prolonger la coupe jusqu’au tag fermant suivant eventuel
}
$texte = substr($texte, 0, $offset); /* eviter de travailler sur 10ko pour extraire 150 caracteres */

// on utilise les \r pour passer entre les gouttes
$texte = str_replace("\r\n", “\n”, $texte);
$texte = str_replace("\r", “\n”, $texte);

// sauts de ligne et paragraphes
$texte = preg_replace("/\n\n+/", “\r”, $texte);
$texte = preg_replace("/<(p|br)( [^>]*)?".">/", “\r”, $texte);

// supprimer les traits, lignes etc
$texte = preg_replace("/(^|\r|\n)(-[-#*]*|_ )/", “\r”, $texte);

// supprimer les tags
$texte = supprimer_tags($texte);
$texte = trim(str_replace("\n"," ", $texte));
$texte .= “\n”; // marquer la fin

// travailler en accents charset
$texte = unicode2charset(html2unicode($texte, /* secure */ true));
$texte = nettoyer_raccourcis_typo($texte);
$flag = 0;
// corriger la longueur de coupe
// en fonction de la presence de caracteres utf
if ($GLOBALS[‘meta’][‘charset’]==‘utf-8’){
$long = charset2unicode($texte);
$sv_len = spip_strlen($long);
$long = spip_substr($long, 0, max($taille,1));
if (spip_strlen($long) != $sv_len)
$flag = 1;
$nbcharutf = preg_match_all(’/(&#[0-9]{3,5};)/S’, $long, $matches);
$taille += $nbcharutf;
}

// couper au mot precedent
$long = spip_substr($texte, 0, max($taille-4,1));
$u = $GLOBALS[‘meta’][‘pcre_u’];
$court = preg_replace("/([^\s][\s]+)[^\s]*\n?$/".$u, “\1”, $long);
$points = $suite;

// ne pas faire de (…) si pas de coupe
if ($flag == 0) {
$points = ‘’;}
// trop court ?
if (spip_strlen($court) < max(0.75 * $taille,2)) {
$long = spip_substr($texte, 0, $taille);
$texte = preg_replace("/([^\s][\s]+)[^\s]*\n?$/".$u, “\1”, $long);
// encore trop court ? couper au caractere
if (spip_strlen($texte) < 0.75 * $taille)
$texte = $long;
} else
$texte = $court;

//if (strpos($texte, “\n”)) // la fin est encore la : c’est qu’on n’a pas de texte de suite
// $points = ‘’;

// remettre les paragraphes
$texte = preg_replace("/\r+/", “\n\n”, $texte);

// supprimer l’eventuelle entite finale mal coupee
$texte = preg_replace(’/&#?[a-z0-9]*$/S’, ‘’, $texte);

return quote_amp(trim($texte)).$points;

}

Merci Nico :wink:

Oué ! J'ai mis ça ici : http://www.spip-contrib.net/couper-autrement

Il y a sans doute plus intérêt à comprendre ce qui ne convient pas dans la fonction du core pour envisager de la corriger...

-Nicolas

Il y a sans doute plus intérêt à comprendre ce qui ne convient pas dans la fonction du core pour envisager de la corriger...

Comme je le disais à Thomas, la fonction du core fait des choix, qu'on
peut trouver discutables, mais qui ne relèvent pas du bug à corriger.

-- Fil

Mais qui pourrait relever à moindre frais d'une valeur configurable. Le pourcentage à partir duquel la fonction décide si elle doit couper par mot ou par caractère pourrait être en 4ème paramètre, ce qui permettrait de le surcharger pour tel ou tel besoin.

C'était mon idée quand je disait "corriger", en fait... :wink:

-Nicolas