Valider c4ae426e rédigé par marcimat@rezo.net's avatar marcimat@rezo.net
Parcourir les fichiers

Correction de plusieurs soucis sur la fonction nettoyer_raccourcis_typo() .

Cette fonction est utilisée par couper() ou pour calculer des attributs title 
ou encore pour indexer des documents par le plugin Indexer sur une base Sphinx.

C'est dans ce dernier cadre que quelques problèmes se sont montrées :

- la regexp qui supprimait les notes pouvait tuer PCRE si le texte était volumineux et avait des notes mal fermées.
On simplifie cette expression. Cela ne provoque aucun changement sur les bases de tests que j’ai pu voir, améliorant
même le retour de 3 articles qui renvoyaient vide avant à tord.

- contrairement à ce qu’affirmait le commentaire, les tableaux n’étaient pas supprimés dans la plupart des cas.
Effectivement la regexp cherchait uniquemnet des \r (sauts de paragraphe à cet endroit) et pas de \n (sauts de lignes à cet endroit).
La regexp n’étant pas multiligne d’une part et textwheel sachant bien gérer les tableaux même s’il n’y a pas de ligne vide avant/après,
on permet d’éliminer simplement les lignes de tableau en ajoutant \n à cet endroit.

Plus généralement cette fonction… ne nettoyait pas tous les raccourcis. Une partie était faite par couper() uniquement.
Il me semble que c'est un tord. On déplace donc de couper() dans la fonction nettoyer_raccourcis_typo() quelques nettoyages,
notamment la suppression des caractères de liste.

- les listes étaient retournées avec un saut de paragraphe entre chaque élément. Dans le cadre de ces fonctions ce n’est a priori pas utile,
et on retourne du coup un simple saut de ligne à la place (note: couper remplace les sauts de ligne par des espaces ensuite — pas les sauts de paragraphe).
Il y a donc un changement de comportement de ce point de vue.

- le texte de sortie est trimmé (couper() s’en occupe aussi d’ailleurs).

Conséquence notable pour Indexer : le contenu des tableau n’est plus retourné. Une option devrait être proposée à cette fonction
pour retourner les contenus des tableaux, mais sans les | .

On ajoute quelques fonctions de tests unitaires au passage.
La fonction couper() du core va être modifiée en conséquence.
parent fa8a905f
Chargement en cours
Chargement en cours
Chargement en cours
Chargement en cours
+5 −0
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -303,6 +303,11 @@ tests/data/typo/unordered_list.html -text
tests/data/typo/unordered_list.txt -text
tests/data/typo/whitespace.html -text
tests/data/typo/whitespace.txt -text
tests/simpletest/all_tests.php -text
tests/simpletest/data_test_typo.inc -text
tests/simpletest/lanceur_spip.php -text
tests/simpletest/nettoyer_raccourcis_typo.php -text
tests/simpletest/nettoyer_raccourcis_typo_old.php -text
tests/squelettes/modeles/textwheel_block.html -text
tests/squelettes/modeles/textwheel_inline.html -text
tests/tw_propre.php -text
+30 −5
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -340,12 +340,31 @@ function expanser_un_lien($reg, $quoi = 'echappe', $env = null) {
	}
}

// Meme analyse mais pour eliminer les liens
// et ne laisser que leur titre, a expliciter si ce n'est fait
// https://code.spip.net/@nettoyer_raccourcis_typo
/**
 * Nettoie un texte en enlevant les raccourcis typo, sans les traiter
 *
 * On ne laisse que les titres des liens, en les explicitant si ce n’est pas fait.
 *
 * @param string $texte
 * @param string $connect
 * @return string
 */
function nettoyer_raccourcis_typo($texte, $connect = '') {
	$texte = pipeline('nettoyer_raccourcis_typo', $texte);

	// 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);

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

	// travailler en accents charset
	$texte = unicode2charset(html2unicode($texte, true /* secure */ ));

	if (preg_match_all(_RACCOURCI_LIEN, $texte, $regs, PREG_SET_ORDER)) {
		include_spip('inc/texte');
		foreach ($regs as $reg) {
@@ -375,13 +394,19 @@ function nettoyer_raccourcis_typo($texte, $connect = '') {
	$texte = preg_replace(_RACCOURCI_ANCRE, "", $texte);

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

	// supprimer les codes typos
	$texte = str_replace(array('}', '{'), '', $texte);

	// supprimer les tableaux
	$texte = preg_replace(",(^|\r)\|.*\|\r,s", "\r", $texte);
	$texte = preg_replace(",(?:^|\r|\n)\|.*\|(?:\r|\n|$),s", "\r", $texte);

	// indiquer les sauts de paragraphes
	$texte = str_replace("\r", "\n\n", $texte);
	$texte = str_replace("\n\n+", "\n\n", $texte);

	$texte = trim($texte);

	return $texte;
}
+9 −0
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?php
require_once('lanceur_spip.php');

class AllTests_textwheel extends SpipTestSuite {
	function __construct() {
		parent::__construct('Tests Textwheel');
		$this->addDir(__FILE__);
	}
}
 No newline at end of file
+177 −0
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?php

trait Data_test_typo {

	protected function _printTest(array $data, $nettoyer, $couper) {
		$titre = isset($data['titre']) ? $data['titre'] : '';
		if (!$this->assertEqual($nettoyer, $data['nettoyer'])) {
			$this->reporter->paintFormattedMessage("Nettoyer_raccourcis_typo | $titre. Texte -> Attendu -> Reçu");
			$this->reporter->paintFormattedMessage($data['texte']);
			$this->reporter->paintFormattedMessage($data['nettoyer']);
			$this->reporter->paintFormattedMessage($nettoyer);
		}
		if (!$this->assertEqual($couper, $data['couper'])) {
			$this->reporter->paintFormattedMessage("Couper | $titre. Texte -> Attendu -> Reçu");
			$this->reporter->paintFormattedMessage($data['texte']);
			$this->reporter->paintFormattedMessage($data['couper']);
			$this->reporter->paintFormattedMessage($couper);
		}
	}

	function testNettoyerItalique(){
		$this->_testData([[
			'texte' => 'Un mot {italique}',
			'couper' => 'Un mot italique',
			'nettoyer' => 'Un mot italique',
		],[
			'texte' => '{Un texte italique}',
			'couper' => 'Un texte italique',
			'nettoyer' => 'Un texte italique',
		]]);
	}

	function testNettoyerGras(){
		$this->_testData([[
			'texte' => 'Un mot {{gras}}',
			'couper' => 'Un mot gras',
			'nettoyer' => 'Un mot gras',
		],[
			'texte' => '{{Un texte gras}}',
			'couper' => 'Un texte gras',
			'nettoyer' => 'Un texte gras',
		]]);
	}


	function testNettoyerIntertitre(){
		$this->_testData([[
			'texte' => '{{{Un intertitre}}}',
			'couper' => 'Un intertitre',
			'nettoyer' => 'Un intertitre',
		],[
			'texte' => "Ligne\n\n{{{Un intertitre}}}\n\nLigne",
			'couper' => "Ligne\n\nUn intertitre\n\nLigne",
			'nettoyer' => "Ligne\n\nUn intertitre\n\nLigne",
		]]);
	}

	function testNettoyerLiens(){
		$this->_testData([[
			'texte' => 'Un lien [interne->article1]',
			'couper' => 'Un lien interne',
			'nettoyer' => 'Un lien interne',
		],[
			'texte' => 'Un lien [externe->http://example.org]',
			'couper' => 'Un lien externe',
			'nettoyer' => 'Un lien externe',
		]]);
	}

	/**
	 * Les listes sont mises à plat
	 * 1 saut de ligne \n entre chaque, couper les réassemble en espace.
	 *
	 * @note
	 *    Avant SPIP 3.2, 1 saut de paragraphe \n\n entre chaque (couper le laissait).
	 */
	function testNettoyerListes(){
		$this->_testData([[
			'texte' =>
"Une liste
-* un
-* deux
-* trois
",
			'couper' => "Une liste un deux trois",
			'nettoyer' => "Une liste\nun\ndeux\ntrois",
		],[
			'texte' =>
"Une liste avec ligne

-* un
-* deux
-* trois

",
			'couper' => "Une liste avec ligne un deux trois",
			'nettoyer' => "Une liste avec ligne\nun\ndeux\ntrois",
		]]);
	}

	/**
	 * Les tableaux sont totalement supprimés.
	 * Enfin presque : remplacés par \n\n
	 * Le texte étant trimmé, \n en fins sont enlevés.
	 *
	 * @note
	 *     Avant SPIP 3.2, les tableaux n’étaient pas toujours correctement supprimés
	 */
	function testNettoyerTableaux(){
		$this->_testData([[
			// tableau sans sauts de ligne avant / après.
			'titre' => 'tableau sans sauts de ligne avant / après',
			'texte' =>
				"| {{colonneA}} | {{colonneB}} |
| ligneA1 | ligneB1 |
| ligneA2 | ligneB2 |",
			'couper' => "",
			'nettoyer' => "",
		],[
			'texte' =>
				"Un tableau sans ligne vide avant
| {{colonneA}} | {{colonneB}} |
| ligneA1 | ligneB1 |
| ligneA2 | ligneB2 |
",
			'couper' => "Un tableau sans ligne vide avant",
			'nettoyer' => "Un tableau sans ligne vide avant",
		],[
			'texte' =>
				"Un tableau avec ligne vide avant

| {{colonneA}} | {{colonneB}} |
| ligneA1 | ligneB1 |
| ligneA2 | ligneB2 |
",
			'couper' => "Un tableau avec ligne vide avant",
			'nettoyer' => "Un tableau avec ligne vide avant",
		],[
			'texte' =>
				"Un tableau avec ligne avant / après
| {{colonneA}} | {{colonneB}} |
| ligneA1 | ligneB1 |
| ligneA2 | ligneB2 |
Après
",
			'couper' => "Un tableau avec ligne avant / après\n\nAprès",
			'nettoyer' => "Un tableau avec ligne avant / après\n\nAprès",
		]]);
	}

	/**
	 * Les notes sont supprimées.
	 *
	 * @note
	 *     Avant 3.2 la regexp pouvait tuer pcre sur des textes longs
	 *     ayant des notes mal fermées.
	 */
	function testNettoyerNotes(){
		$this->_testData([[
			'texte' => 'Une note bien fermée [[note 1]]',
			'couper' => 'Une note bien fermée',
			'nettoyer' => 'Une note bien fermée',
		],[
			'texte' => 'Une note mal fermée [[note 1]',
			'couper' => 'Une note mal fermée [[note 1]',
			'nettoyer' => 'Une note mal fermée [[note 1]',
		],[
			'texte' => 'Un lien dans une note [[note [lien->article1]]]',
			'couper' => 'Un lien dans une note',
			'nettoyer' => 'Un lien dans une note',
		],[
			'texte' => 'Lien et note ratée [[note [lien->article1]] ]',
			'couper' => 'Lien et note ratée [[note lien] ]',
			'nettoyer' => 'Lien et note ratée [[note lien] ]',
		]]);
	}
}
 No newline at end of file
+12 −0
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?php
/**
 * Démarre SPIP afin d'obtenir ses fonctions depuis
 * les jeux de tests unitaires de type simpletest
 */
$remonte = '../';
while (!is_dir($remonte . 'ecrire')) {
	$remonte = "../$remonte";
}
require $remonte . 'tests/test.inc';

demarrer_simpletest();
Chargement en cours