[spip-dev] filtre couper : amélioration et correction de bug.

le filtre couper ne coupait pas tres bien les textes ; le code n'était
pas très lisible, et je souhaitais avoir un lien sur l'article plutot
que d'avoir un texte passif (...)

certains texte moins long que $long était tout de meme coupés.

j'ai donc créé ce filtre spécialement pour les articles. Pour les autres
type de composant, il faut garder le meme algo, mais changer l'url.

je n'ai pas trouvé d'autre moyen d'acceder à l'id_article que de passer
le contexte. est-ce possible autrement ?

j'ai créé une petite extension qui permet de couper :
- sur un nombre de caracteres,
- un nombre de ligne.

l'information est passée sur le meme argument, avec le caracteres :
comme separateur.

   couper{400}
   couper{400:12}

le script detecte automatiquement la syntaxte.

j'aurais pu ecrire une fonction max_nl(), ca aurait été plus modulaire.
mais, si l'article est coupé, avec un lien final, ca devient plus costaud
à realiser ; le max_nl devant intervenir apres couper_article.

si ce code pouvait etre intégré a SPIP, ca me ferait très plaisir.

// Marc Quinton ; amélioriation du filtre couper standard de SPIP.
//
// reprend le filtre couper de SPIP (ecrire/in_texte.php3)
// insere directement un lien si l'article n'est pas affiché en entier.
//
// usage :
//
// 1 - [(#TEXTE|textebrut|couper_article{400,$contexte}|nl2br)]
// 2 - [(#TEXTE|textebrut|couper_article{'400:12',$contexte}|nl2br)]
//
// 1 - coupe à 400 caracteres, et gerere l'url sur l'article, si nécessaire (texte coupé)
// 2 - veille à ce que le texte généré ne dépasse pas 12 lignes. Il faut mettre des ''
// sinon, erreur php.
//
// $contexte est recupéré dans le code de la boucle produit par le générateur SPIP
// l'objectif etant de retrouver l'id_article : $context['id_article']
//
// affichage produit (le [...] contient un lien sur l'article, pour voir le contenu)
// texte, texte, texte
// texte, texte, texte, texte
// texte, texte, texte [...]
//
// tabulation = 4
//
function couper_article($texte, $long, $context='') {

  $texte_coupe = false;

  if(preg_match('/(\d+):(\d+)/', $long, $matches)){
    $long = $matches[1];
    $max_lines = $matches[2];
    }

  // evite de faire travailler les expression régulieres sur un trop grand texte.
  // (petite optimisation) ; tient compte des racoursis, des sauts de lignes ...
  // d'ou la marge (*2)
  //
  if(strlen($texte) > $long * 2){
    $texte = substr($texte, 0, $long * 2);
    $texte_coupe = true;
  }

  $debug = sprintf("<br>longueur souhaitée = %s\n", $long);
  $debug .= sprintf("<br>max lines = %s\n", $max_lines);
  $debug .= sprintf("<br>longueur initiale = %s\n", strlen($texte));

  $texte = ereg_replace("\[([^\[]*)->([^]]*)\]","\\1", $texte);

  // supprimer les notes
  $texte = ereg_replace("\[\[([^]]|\][^]])*\]\]", "", $texte);

  // supprimer les codes typos
  $texte = ereg_replace("[{}]", "", $texte);

  // supprimer les sauts de lignes multiples
  $texte = preg_replace("/\n(\n\s*)+\n/m", "\n\n", $texte);

  // coupe si le texte depasse $max_lines.
  if(isset($max_lines)) {
    // cree un tableau avec chaque ligne.
    $lines = split("\n", $texte);

    // garde uniquement les $max_lines premieres lignes.
    if(count($lines) > $max_lines) {
      $texte = '';
      for($i = 0 ; $i < $max_lines ; $i++)
        $texte .= $lines[$i] . "\n";
      $texte_coupe = true;
    }
  }

  if(strlen($texte) > $long) {
    $texte_coupe = true;

    // coupe le texte a la longueur voulue.
    $texte = substr($texte, 0, $long);
  }
  if($texte_coupe) {
    // evite de couper en milieu de mot.
    $texte = ereg_replace("([^[:space:]][[:space:]]+)[^[:space:]]*$", "\\1", $texte);
  }

  $debug .= sprintf("<br>coupé = %s\n", $texte_coupe);
  $debug .= sprintf("<br>len text = %s\n", strlen($texte));

  if ($texte_coupe) {
    if($context != '') {
      $url_article = 'article.php3?id_article=';
      $url = sprintf('[<a href="%s%s" title="voir tout l\'article">...</a>]', $url_article,
        $context['id_article']);
      $texte .= "&nbsp;$url";
    } else
      $texte .= '&nbsp;(...)';
     }
  # $texte .= '<i>' . $debug . '</i>';

  return $texte;
}