diff --git a/ecrire/inc_filtres.php3 b/ecrire/inc_filtres.php3
index 0021bdce71697cb41c32957f11829a4f13af0a12..a8bee30b9b32c71408643016b5fe982d037f32f8 100644
--- a/ecrire/inc_filtres.php3
+++ b/ecrire/inc_filtres.php3
@@ -357,52 +357,4 @@ function centrer($letexte) {
 	return aligner($letexte,'center');
 }
 
-// utilise avec ob_start() et ob_get_contents() pour
-// mettre en rouge les mots passes dans $var_s
-function surligner_mots($page, $mots) {
-	$accents =
-		/* A */ chr(192).chr(193).chr(194).chr(195).chr(196).chr(197).
-		/* a */ chr(224).chr(225).chr(226).chr(227).chr(228).chr(229).
-		/* O */ chr(210).chr(211).chr(212).chr(213).chr(214).chr(216).
-		/* o */ chr(242).chr(243).chr(244).chr(245).chr(246).chr(248).
-		/* E */ chr(200).chr(201).chr(202).chr(203).
-		/* e */ chr(232).chr(233).chr(234).chr(235).
-		/* Cc */ chr(199).chr(231).
-		/* I */ chr(204).chr(205).chr(206).chr(207).
-		/* i */ chr(236).chr(237).chr(238).chr(239).
-		/* U */ chr(217).chr(218).chr(219).chr(220).
-		/* u */ chr(249).chr(250).chr(251).chr(252).
-		/* yNn */ chr(255).chr(209).chr(241);
-
-	$accents_regexp = array(
-		"a" => "[a".chr(224).chr(225).chr(226).chr(227).chr(228).chr(229). chr(192).chr(193).chr(194).chr(195).chr(196).chr(197)."]",
-		"o" => "[o".chr(242).chr(243).chr(244).chr(245).chr(246).chr(248). chr(210).chr(211).chr(212).chr(213).chr(214).chr(216)."]",
-		"e" => "[e".chr(232).chr(233).chr(234).chr(235). chr(200).chr(201).chr(202).chr(203)."]",
-		"c" => "[c".chr(199).chr(231)."]",
-		"i" => "[i".chr(236).chr(237).chr(238).chr(239). chr(204).chr(205).chr(206).chr(207)."]",
-		"u" => "[u".chr(249).chr(250).chr(251).chr(252). chr(217).chr(218).chr(219).chr(220)."]",
-		"y" => "[y".chr(255)."]",
-		"n" => "[n".chr(209).chr(241)."]"
-	);
-
-	// Remplacer les caracteres potentiellement accentues dans la chaine
-	// de recherche par les choix correspondants en syntaxe regexp (!)
-	$mots = split("[[:space:]]+", $mots);
-	while (list(, $mot) = each ($mots)) {
-		if (strlen($mot) > 3) {
-			$mot = strtr($mot, $accents, "AAAAAAaaaaaaOOOOOOooooooEEEEeeeeCcIIIIiiiiUUUUuuuuyNn");
-			$mot = strtr(strtolower($mot), $accents_regexp);
-			$mots_surligne[] = $mot;
-		}
-	}
-
-	// Remplacer une occurence de mot maxi par espace inter-tag (donc au max par paragraphe)
-	if ($mots_surligne) {
-		$regexp = '(>[^<]*[^[:alnum:]<])(('.join('|', $mots_surligne).')[[:alnum:]]*)';
-		$page = eregi_replace($regexp, '\1<span class="spip_surligne">\2</span>', $page);
-	}
-
-	return $page;
-}
-
 ?>
diff --git a/ecrire/inc_surligne.php3 b/ecrire/inc_surligne.php3
new file mode 100644
index 0000000000000000000000000000000000000000..31213169c95beb1292065e953ebacdb403cacfca
--- /dev/null
+++ b/ecrire/inc_surligne.php3
@@ -0,0 +1,116 @@
+<?php
+
+//
+// Ce fichier ne sera execute qu'une fois
+if (defined("_ECRIRE_INC_SURLIGNE")) return;
+define("_ECRIRE_INC_SURLIGNE", "1");
+
+// utilise avec ob_start() et ob_get_contents() pour
+// mettre en rouge les mots passes dans $var_recherche
+function surligner_mots($page, $mots) {
+	$accents =
+		/* A */ chr(192).chr(193).chr(194).chr(195).chr(196).chr(197).
+		/* a */ chr(224).chr(225).chr(226).chr(227).chr(228).chr(229).
+		/* O */ chr(210).chr(211).chr(212).chr(213).chr(214).chr(216).
+		/* o */ chr(242).chr(243).chr(244).chr(245).chr(246).chr(248).
+		/* E */ chr(200).chr(201).chr(202).chr(203).
+		/* e */ chr(232).chr(233).chr(234).chr(235).
+		/* Cc */ chr(199).chr(231).
+		/* I */ chr(204).chr(205).chr(206).chr(207).
+		/* i */ chr(236).chr(237).chr(238).chr(239).
+		/* U */ chr(217).chr(218).chr(219).chr(220).
+		/* u */ chr(249).chr(250).chr(251).chr(252).
+		/* yNn */ chr(255).chr(209).chr(241);
+
+	$accents_regexp = array(
+		"a" => "[a".chr(224).chr(225).chr(226).chr(227).chr(228).chr(229). chr(192).chr(193).chr(194).chr(195).chr(196).chr(197)."]",
+		"o" => "[o".chr(242).chr(243).chr(244).chr(245).chr(246).chr(248). chr(210).chr(211).chr(212).chr(213).chr(214).chr(216)."]",
+		"e" => "[e".chr(232).chr(233).chr(234).chr(235). chr(200).chr(201).chr(202).chr(203)."]",
+		"c" => "[c".chr(199).chr(231)."]",
+		"i" => "[i".chr(236).chr(237).chr(238).chr(239). chr(204).chr(205).chr(206).chr(207)."]",
+		"u" => "[u".chr(249).chr(250).chr(251).chr(252). chr(217).chr(218).chr(219).chr(220)."]",
+		"y" => "[y".chr(255)."]",
+		"n" => "[n".chr(209).chr(241)."]"
+	);
+
+	// Remplacer les caracteres potentiellement accentues dans la chaine
+	// de recherche par les choix correspondants en syntaxe regexp (!)
+	$mots = split("[[:space:]]+", $mots);
+	while (list(, $mot) = each ($mots)) {
+		if (strlen($mot) > 3) {
+			$mot = strtr($mot, $accents, "AAAAAAaaaaaaOOOOOOooooooEEEEeeeeCcIIIIiiiiUUUUuuuuyNn");
+			$mot = strtr(strtolower($mot), $accents_regexp);
+			$mots_surligne[] = $mot;
+		}
+	}
+
+	// Remplacer une occurence de mot maxi par espace inter-tag (max 1 par paragraphe, sauf italiques etc.)
+	// se limiter a 4 remplacements pour ne pas bouffer le CPU
+	if ($mots_surligne) {
+		$regexp = '/(>([^<]*[^[:alnum:]])?)(('.join('|', $mots_surligne).')[[:alnum:]]*?)/Uis';
+		$page = preg_replace($regexp, '\1<span class="spip_surligne">\3</span>', $page, 4);
+	}
+
+	return $page;
+}
+
+
+// debut et fin, appeles depuis les squelettes
+function debut_surligne($mots,$mode_surligne) {
+
+	switch ($mode_surligne) {
+		case 'auto' :	// on arrive du debut de la page, on ne touche pas au buffer
+			ob_end_flush();
+			ob_start("");
+			$mode_surligne = 'actif';
+			break;
+
+		case 'actif' :	// il y a un buffer a traiter
+			$la_page = mots_surligne(ob_get_contents(), $mots);
+			ob_end_clean();
+			echo $la_page;
+			ob_start("");
+			$mode_surligne = 'actif';
+			break;
+
+		case 'inactif' :	// il n'y a pas de buffer
+			ob_start("");
+			$mode_surligne = 'actif';
+			break;
+
+		case false :	// conditions pas reunies (flag_preserver, etc.)
+			break;
+	}
+
+	return $mode_surligne;
+}
+
+function fin_surligne($mots,$mode_surligne) {
+
+	switch ($mode_surligne) {
+		case 'auto' :	// on arrive du debut de la page, on s'occupe du buffer
+			$la_page = surligner_mots(ob_get_contents(), $mots);
+			ob_end_clean();
+			echo $la_page;
+			ob_start("");
+			$mode_surligne = 'inactif';
+			break;
+
+		case 'actif' :	// il y a un buffer a traiter
+			$la_page = surligner_mots(ob_get_contents(), $mots);
+			ob_end_clean();
+			echo $la_page;
+			$mode_surligne = 'inactif';
+			break;
+
+		case 'inactif' :	// il n'y a pas de buffer
+			break;
+
+		case false :	// conditions pas reunies (flag_preserver, etc.)
+			break;
+	}
+
+	return $mode_surligne;
+}
+
+?>
\ No newline at end of file