diff --git a/.gitattributes b/.gitattributes
index 5891a208ee3624ed242df94685894e64f5842ec5..95db991cb5bb8bb84dcf4bf395d1bfa5df9b56b3 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -387,6 +387,8 @@ ecrire/maj/vieille_base/charger.php -text
 ecrire/maj/vieille_base/create.php -text
 ecrire/prive.php -text
 ecrire/public/aiguiller.php -text
+ecrire/public/decompile.php -text
+ecrire/public/format_html.php -text
 ecrire/public/index.php -text
 ecrire/public/jointures.php -text
 ecrire/public/quete.php -text
diff --git a/ecrire/public/compiler.php b/ecrire/public/compiler.php
index ed25d753db6cf16c9548bde937487cc2706d5b89..9b4b6d12f26a4ea38f1df6453d668f627276edbc 100644
--- a/ecrire/public/compiler.php
+++ b/ecrire/public/compiler.php
@@ -762,46 +762,6 @@ function compile_retour($code, $avant, $apres, $altern, $tab, $n)
 }
 
 
-// affichage du code produit
-
-// http://doc.spip.org/@code_boucle
-function code_boucle(&$boucles, $id, $nom)
-{
-	$boucle = &$boucles[$id];
-
-	// Indiquer la boucle en commentaire
-	$pretty = '';
-
-	if ($boucle->type_requete != 'boucle')
-	  {
-	    // Resynthetiser les criteres
-	    foreach ($boucle->param as $param) {
-	      $s = "";
-	      $sep = "";
-	      foreach ($param as $t) {
-		if (is_array($t)) { // toujours vrai normalement
-		  $s .= $sep;
-		  $c = $t[0];
-		  if ($c->apres)
-		    $s .= ($c->apres . $c->texte . $c->apres);
-		  else {
-		// faudrait decompiler aussi les balises...
-		    foreach ($t as $c)
-		      $s .=  ($c->type == 'texte') ? $c->texte : '#...';
-		  }
-		  $sep = ", ";
-		}
-	      }
-	      $pretty .= ' {' . $s . '}';
-	    }
-	  }
-
-	$pretty = "BOUCLE$id(".strtoupper($boucle->type_requete) . ")" .
-		strtr($pretty,"\r\n", "  ");
-
-	return $pretty;
-}
-
 function compile_inclure_doublons($lexemes)
 {
 	foreach($lexemes as $v)
@@ -953,7 +913,12 @@ function compiler_squelette($squelette, $boucles, $nom, $descr, $sourcefile, $co
 	// idem pour la racine
 	$descr['id_mere'] = '';
 	$corps = calculer_liste($squelette, $descr, $boucles);
+	$debug = (isset($GLOBALS['var_mode']) AND $GLOBALS['var_mode']=='debug');
 
+	if ($debug) {
+		include_spip('public/decompile');
+		include_spip('public/format_' . _EXTENSION_SQUELETTES);
+	}
 	// Calcul du corps de toutes les fonctions PHP,
 	// en particulier les requetes SQL et TOTAL_BOUCLE
 	// de'terminables seulement maintenant
@@ -981,24 +946,34 @@ function compiler_squelette($squelette, $boucles, $nom, $descr, $sourcefile, $co
 			$req .
 			"\n}\n\n";
 
-		if (isset($GLOBALS['var_mode']) AND $GLOBALS['var_mode'] == 'debug')
+		if ($debug)
 			boucle_debug_compile ($id, $nom, $boucles[$id]->return);
 	}
 
 	$code = "";
 	foreach($boucles as $id => $boucle) {
-		$code .= "\n//\n// <BOUCLE " .
-#		  code_boucle($boucles, $id, $nom). # pas au point
+		$code .= "\n\n/* BOUCLE " .
 		  $boucle->type_requete .
-		  ">\n//\n" .
+		  " " .
+		  (!$debug ? '' : 
+			decompile_criteres($boucle->param, $boucle->criteres)) .
+		  " */\n\n" .
 		  $boucle->return;
 	}
 
 	$secondes = spip_timer('calcul_skel');
 	spip_log("COMPIL ($secondes) [$sourcefile] $nom.php");
 
+	$head = '';
+	if (is_array($tableau_des_erreurs))  {
+		foreach ($tableau_des_erreurs as $err) {
+			$head .= "\n// "
+			. str_replace("\n", ' ', join(" ", $err));
+		}
+	}
+
 	if (!CODE_COMMENTE)
-		$head = '';
+		$head .= '';
 	else $head = "
 /*
  * Squelette : $sourcefile
diff --git a/ecrire/public/decompile.php b/ecrire/public/decompile.php
new file mode 120000
index 0000000000000000000000000000000000000000..8d8238f2a49134c2c41b7f981fbcb4c6d04996f6
--- /dev/null
+++ b/ecrire/public/decompile.php
@@ -0,0 +1 @@
+../../Ajouts/Essai/public/decompile.php
\ No newline at end of file
diff --git a/ecrire/public/format_html.php b/ecrire/public/format_html.php
new file mode 100644
index 0000000000000000000000000000000000000000..a7196827bf29ba844ec15c49d3ae850a8e053ef6
--- /dev/null
+++ b/ecrire/public/format_html.php
@@ -0,0 +1,77 @@
+<?php
+
+/***************************************************************************\
+ *  SPIP, Systeme de publication pour l'internet                           *
+ *                                                                         *
+ *  Copyright (c) 2001-2009                                                *
+ *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
+ *                                                                         *
+ *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
+ *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
+\***************************************************************************/
+
+if (!defined("_ECRIRE_INC_VERSION")) return;
+
+function format_boucle_html($avant, $nom, $type, $crit, $corps, $apres, $altern, $prof)
+{
+	$avant = $avant ? "<B$nom>avant" : "";
+	$apres = $apres ? "$apres</B$nom>" : "";
+	$altern = $altern ? "$altern<//B$nom>" : "";
+	if (!$corps) $corps = " />"; else $corps = ">$corps</BOUCLE$nom>";
+	return "$avant<BOUCLE$nom($type)$crit$corps$apres$altern";
+}
+
+function format_include_html($file, $fond, $args, $prof)
+{
+ 	$t = $file ? ("(" . $file . ")") : "" ;
+	if ($fond) array_unshift($args, "fond=" . $fond);
+	if ($args) $args = "{" . join(", ",$args) . "}";
+	return "<INCLURE" . $t . $args  . ">";
+}
+
+function format_polyglotte_html($args, $prof)
+{
+	return "<multi>" . join(" ", $args) . "</multi>";
+}
+
+function format_idiome_html($nom, $module, $args, $s, $prof)
+{
+	return "<:"  . ($module ? "$module:" : "") . $nom . $args . ":>";
+}
+
+function format_champ_html($nom, $boucle, $etoile, $avant, $apres, $args, $filtres, $next, $prof)
+{
+	$nom = "#"
+	. ($boucle ? ($boucle . ":") : "")
+	. $nom
+	. $etoile
+	. $args
+	. $filtres;
+
+	// Determiner si c'est un champ etendu, 
+	// notamment pour éviter que le lexeme suivant s'agrege au champ
+	// si pas d'etoile terminale, pas d'arg et suivi d'une ambiguite
+
+	$s = ($avant OR $apres OR $filtres
+	      OR ($prof < 0) 
+	      OR (strpos($args, '(#') !==false)
+	      OR (!$args
+		    AND !$etoile
+		    AND	$next
+		    AND ($next->type == 'texte')
+		  AND preg_match(',^[\w\d|{*],', $next->texte)));
+
+	return $s ? "[$avant($nom)$apres]" : $nom;
+}
+
+function format_liste_html($fonc, $args, $prof)
+{
+  return ($fonc ? "|$fonc" : $fonc)
+	. (!$args ? "" : ("{" . join(",", $args) . "}"));
+}
+
+function format_critere_html($args, $prof)
+{
+  return (!$args ? "" : ("{" . join(",", $args) . "}"));
+}
+