diff --git a/ecrire/inc_tidy.php b/ecrire/inc_tidy.php
index ebddda20d4cac56ec54a06b7b8a2118082c1bdbc..48cabd005f51bbbe0bd3d76d701bd22572cf9602 100644
--- a/ecrire/inc_tidy.php
+++ b/ecrire/inc_tidy.php
@@ -82,23 +82,39 @@ function xhtml ($buffer) {
 		else if ($charset == "utf-8") $enc_char = "utf8";
 		else return echappe_retour($buffer, $les_echap, "xhtml");
 
-		$nomfich = _DIR_CACHE."bidouille".rand();
-		$f = fopen($nomfich, 'wb');
-		fputs($f, $buffer);
-		fclose($f);
-		
-		exec("$tidy_command --tidy-mark false --char-encoding $enc_char --quote-nbsp false --show-body-only false --indent true --wrap false --output-xhtml true --add-xml-decl false -m $nomfich");
-		
-		$tidy = join(file($nomfich),"");
-		@unlink($nomfich);
-		
-		$tidy = echappe_retour($tidy, $les_echap, "xhtml");
-		$tidy = ereg_replace ("\<\?xml([^\>]*)\>", "", $tidy);
-		//$tidy = ereg_replace ("\/\*\<\!\[CDATA\[\*\/\n*", "", $tidy);
-		//$tidy = ereg_replace ("\/\*\]\]>\*\/", "", $tidy);
-		
-		return $tidy;
+		$cache = _DIR_CACHE.creer_repertoire(_DIR_CACHE,'tidy');
+		$nomfich = $cache.'tidy'.md5($buffer);
+		if (!file_exists($nomfich)) {
+			$tmp = "$nomfich.".@getmypid().".tmp";
+			ecrire_fichier($tmp, $buffer);
+
+			$c = "$tidy_command --tidy-mark false --char-encoding $enc_char --quote-nbsp false --show-body-only false --indent true --wrap false --output-xhtml true --add-xml-decl false -m $tmp"; #." 2>$nomfich.err";
+			spip_log ($c);
+
+			exec("$tidy_command --tidy-mark false --char-encoding $enc_char --quote-nbsp false --show-body-only false --indent true --wrap false --output-xhtml true --add-xml-decl false -m $tmp");
+			rename($tmp,$nomfich);
+		}
+
+		if (lire_fichier($nomfich, $tidy)
+		AND strlen(trim($tidy)) > 0) {
+			// purger le petit cache toutes les 5 minutes
+			spip_touch($nomfich); # rester vivant
+			if (spip_touch($cache.'purger_tidy', 300, true)) {
+				if ($h = @opendir($cache)) {
+					while (($f = readdir($h)) !== false) {
+						if (substr($f, 0, 4) == 'tidy'
+						AND time() - filemtime("$cache$f") > 300) {
+							@unlink("$cache$f");
+						}
+					}
+				}
+			}
 
+			$tidy = echappe_retour($tidy, $les_echap, "xhtml");
+			$tidy = ereg_replace ("\<\?xml([^\>]*)\>", "", $tidy);
+			return $tidy;
+		} else
+			return $buffer; # echec de tidy
 	}
 	else if (version_tidy() == "1") {
 		include_ecrire("inc_texte.php3");
diff --git a/ecrire/inc_version.php3 b/ecrire/inc_version.php3
index f57b221a658bd4e0d8bc754db52818519bd94098..b05f7551abca5068ed518d153923c42ecdc809bf 100644
--- a/ecrire/inc_version.php3
+++ b/ecrire/inc_version.php3
@@ -251,6 +251,11 @@ $convert_command = 'convert';
 // voir http://gallery.menalto.com/modules.php?op=modload&name=GalleryFAQ&file=index&myfaq=yes&id_cat=2#43
 $pnmscale_command = 'pnmscale';
 
+// tidy en ligne de commande (si on ne l'a pas en module php,
+// ou si le module php ne marche pas)
+// $tidy_command = '/bin/tidy' ou '/usr/local/bin/tidy', ou simplement 'tidy'
+$tidy_command = '';
+
 // faut-il passer les connexions MySQL en mode debug ?
 $mysql_debug = false;
 
diff --git a/inc-public.php3 b/inc-public.php3
index 40fbe44b65d4505b281c86b6d9996574a260b643..5fe107c522a2e6e779ae1bd07eb7b1b8a3702f44 100644
--- a/inc-public.php3
+++ b/inc-public.php3
@@ -45,7 +45,8 @@ if (defined("_INC_PUBLIC")) {
 	
 		// Une page "normale" va s'afficher ici
 		if (!($flag_ob AND ($var_mode == 'debug'
-		OR $var_recherche OR $affiche_boutons_admin))) {
+		OR $var_recherche OR $affiche_boutons_admin
+		OR $xhtml_page))) {
 			eval('?' . '>' . $page['texte']);
 			$page = '';
 		}
@@ -88,6 +89,12 @@ if (defined("_INC_PUBLIC")) {
 		$page = affiche_boutons_admin($page);
 	}
 
+	// Appliquer tidy au besoin
+	if (trim($page) AND $GLOBALS['xhtml_page']) {
+		include_ecrire('inc_tidy.php');
+		$page = xhtml($page);
+	}
+
 	// Affichage final s'il en reste
 	echo $page;