diff --git a/.gitattributes b/.gitattributes
index 204b2c760ca9a7dd092768424452403db6d49c2b..5bcbc0f8d55d9538769ada6395f7b0ec883245e0 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -314,6 +314,7 @@ ecrire/inc/minipres.php -text
 ecrire/inc/modifier.php -text
 ecrire/inc/msiefix.php -text
 ecrire/inc/nfslock.php -text
+ecrire/inc/notes.php -text
 ecrire/inc/notifications.php -text
 ecrire/inc/petitionner.php -text
 ecrire/inc/php3.php -text
diff --git a/ecrire/inc/notes.php b/ecrire/inc/notes.php
new file mode 100644
index 0000000000000000000000000000000000000000..b7bf4b5cac9ff3b8e338de618188581848f8e2ba
--- /dev/null
+++ b/ecrire/inc/notes.php
@@ -0,0 +1,96 @@
+<?php
+
+/***************************************************************************\
+ *  SPIP, Systeme de publication pour l'internet                           *
+ *                                                                         *
+ *  Copyright (c) 2001-2008                                                *
+ *  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;
+
+//
+// Notes de bas de page
+//
+
+// argument chaine, on y recherche les notes et on les renvoie en tableau
+// argument tableau,c'est les notes qu'on met en page dans $GLOBALS[les_notes]
+
+function inc_notes_dist($arg)
+{
+	if (is_string($arg))
+		return traiter_raccourci_notes($arg);
+	else return traiter_les_notes($arg);
+}
+
+define('_RACCOURCI_NOTES', ', *\[\[(\s*(<([^>\'"]*)>)?.*?)\]\],msS');
+
+function traiter_raccourci_notes($letexte)
+{
+	global $compt_note,  $marqueur_notes, $les_notes, $notes_vues;
+	global $ouvre_ref, $ferme_ref;
+
+	if (!preg_match_all(_RACCOURCI_NOTES, $letexte, $m, PREG_SET_ORDER))
+		return array($letexte, array());
+
+	// quand il y a plusieurs series de notes sur une meme page
+	$mn =  !$marqueur_notes ? '' : ($marqueur_notes.'-');
+	$mes_notes = array();
+	foreach ($m as $r) {
+		list($note_source, $note_texte, $ref, $nom) = $r;
+
+		// note nommee ou pas ?
+		if ($nom AND strpos($note_texte, '</' . $nom .'>') === false) {
+			$note_texte = str_replace($ref,'',$note_texte);
+		} else 	$nom = ++$compt_note;
+
+		// eliminer '%' pour l'attribut id
+		$ancre = $mn . str_replace('%','_', rawurlencode($nom));
+
+		// ne mettre qu'une ancre par appel de note (XHTML)
+		$att = ($notes_vues[$ancre]++) ? '' : " id='nh$ancre'";
+
+		// creer le popup 'title' sur l'appel de note
+		if ($title = supprimer_tags(propre($note_texte))) {
+			$title = " title='" . couper($title,80) . "'";
+		}
+
+		// ajouter la note aux notes precedentes
+		if ($note_texte) {
+			$mes_notes[]= array($ancre, $nom, $note_texte);
+		}
+
+		// dans le texte, mettre l'appel de note a la place de la note
+		$pos = strpos($letexte, $note_source);
+		$letexte = substr($letexte, 0, $pos) .
+			code_echappement("$ouvre_ref<a href='#nb$ancre' class='spip_note' rel='footnote'$title$att>$nom</a>$ferme_ref") .
+			substr($letexte, $pos + strlen($note_source));
+	}
+	return array($letexte, $mes_notes);
+}
+
+
+// http://doc.spip.org/@traiter_les_notes
+function traiter_les_notes($notes) {
+	global $ouvre_note, $ferme_note;
+
+	$mes_notes = '<p>';
+	$title =  _T('info_notes');
+	foreach ($notes as $r) {
+		list($ancre, $nom, $texte) = $r;
+		$atts = " href='#nh$ancre' id='nb$ancre' class='spip_note' title='$title $ancre' rev='footnote'";
+		$mes_notes .= "\n\n"
+		. code_echappement("$ouvre_note<a$atts>$nom</a>$ferme_note")
+		. $texte;
+	}
+	$mes_notes= propre($mes_notes);
+	if ($GLOBALS['class_spip'])
+		$mes_notes = str_replace('<p class="spip">', '<p class="spip_note">', $mes_notes);
+
+	return ($GLOBALS['les_notes'] .= $mes_notes);
+}
+
+?>
diff --git a/ecrire/inc/texte.php b/ecrire/inc/texte.php
index 39639a39d7dc6562e462a750b84127512f8e054e..47f28f0d1f058b08d6268cde834fa55fc5a7a56c 100644
--- a/ecrire/inc/texte.php
+++ b/ecrire/inc/texte.php
@@ -865,6 +865,8 @@ function traiter_retours_chariots($letexte) {
 	return $letexte;
 }
 
+define('_RACCOURCI_CHAR', "{}_-");
+define('_RACCOURCI_BALISE', ",</?[a-z!][^<>]*[".preg_quote(_RACCOURCI_CHAR)."][^<>]*>,imsS");
 
 // Nettoie un texte, traite les raccourcis autre qu'URL, la typo, etc.
 // http://doc.spip.org/@traiter_raccourcis
@@ -874,7 +876,8 @@ function traiter_raccourcis($letexte) {
 	$letexte = pipeline('pre_propre', $letexte);
 
 	// Gerer les notes (ne passe pas dans le pipeline)
-	list($letexte, $mes_notes) = traite_raccourci_notes($letexte);
+	$notes = charger_fonction('notes', 'inc');
+	list($letexte, $mes_notes) = $notes($letexte);
 
 	//
 	// Tableaux
@@ -887,8 +890,8 @@ function traiter_raccourcis($letexte) {
 
 	if (preg_match_all(',[^|](\n[|].*[|]\n)[^|],UmsS', $letexte,
 	$regs, PREG_SET_ORDER))
-	foreach ($regs as $tab) {
-		$letexte = str_replace($tab[1], traiter_tableau($tab[1]), $letexte);
+	foreach ($regs as $t) {
+		$letexte = str_replace($t[1], traiter_tableau($t[1]), $letexte);
 	}
 
 	$letexte = "\n".trim($letexte);
@@ -898,15 +901,12 @@ function traiter_raccourcis($letexte) {
 		$letexte = traiter_listes($letexte);
 
 	// Proteger les caracteres actifs a l'interieur des tags html
-	$protege = "{}_-";
 	$illegal = "\x1\x2\x3\x4";
-	if (preg_match_all(",</?[a-z!][^<>]*[".preg_quote($protege)."][^<>]*>,imsS",
-	$letexte, $regs, PREG_SET_ORDER)) {
+	if (preg_match_all(_RACCOURCI_BALISE, $letexte, $regs, PREG_SET_ORDER)) {
+	// hack: on transforme les caracteres a proteger en les remplacant
+	// par des caracteres "illegaux". (cf corriger_caracteres())
 		foreach ($regs as $reg) {
-			$insert = $reg[0];
-			// hack: on transforme les caracteres a proteger en les remplacant
-			// par des caracteres "illegaux". (cf corriger_caracteres())
-			$insert = strtr($insert, $protege, $illegal);
+			$insert = strtr($reg[0], _RACCOURCI_CHAR, $illegal);
 			$letexte = str_replace($reg[0], $insert, $letexte);
 		}
 	}
@@ -920,7 +920,7 @@ function traiter_raccourcis($letexte) {
 	$letexte = preg_replace('@^\n<br />@S', '', $letexte);
 
 	// Retablir les caracteres proteges
-	$letexte = strtr($letexte, $illegal, $protege);
+	$letexte = strtr($letexte, $illegal, _RACCOURCI_CHAR);
 
 	// Fermer les paragraphes ; mais ne pas en creer si un seul
 	$letexte = paragrapher($letexte, $GLOBALS['toujours_paragrapher']);
@@ -928,97 +928,11 @@ function traiter_raccourcis($letexte) {
 	// Appeler les fonctions de post-traitement
 	$letexte = pipeline('post_propre', $letexte);
 
-	if ($mes_notes) traiter_les_notes($mes_notes);
+	if ($mes_notes) $notes($mes_notes);
 
 	return $letexte;
 }
 
-//
-// Notes de bas de page
-//
-
-// http://doc.spip.org/@traite_raccourci_notes
-function traite_raccourci_notes($letexte)
-{
-	global $compt_note,  $marqueur_notes, $les_notes, $notes_vues;
-	global $ouvre_ref, $ferme_ref, $ouvre_note, $ferme_note; #static ok
-
-	$mes_notes = '';
-	if (preg_match_all(', *\[\[(.*?)\]\],msS', $letexte, $matches, PREG_SET_ORDER))
-	foreach ($matches as $regs) {
-		$note_source = $regs[0];
-		$note_texte = $regs[1];
-		$num_note = false;
-
-		// note auto ou pas ?
-		if (preg_match(",^<([^>'\"]*)>,", ltrim($note_texte), $r)
-		AND strpos($note_texte, '</' . $r[1] .'>') === false) {
-			$num_note = $r[1];
-			$note_texte = substr_replace(ltrim($note_texte), '', 0, strlen($r[0]));
-		} else {
-			$compt_note++;
-			$num_note = $compt_note;
-		}
-
-		// preparer la note
-		if ($num_note) {
-			if ($marqueur_notes) // quand il y a plusieurs series
-					 // de notes sur une meme page
-				$mn = $marqueur_notes.'-';
-			// pas de '%' dans les attributs name
-			$ancre = $mn.str_replace('%','_',rawurlencode($num_note));
-
-			// ne mettre qu'une ancre par appel de note (XHTML)
-			if (!$notes_vues[$ancre]++)
-				$name_id = " name=\"nh$ancre\" id=\"nh$ancre\"";
-			else
-				$name_id = "";
-
-			$lien = "<a href=\"#nb$ancre\"$name_id class=\"spip_note\" rel=\"footnote\">";
-
-			// creer le popup 'title' sur l'appel de note
-			if ($title = supprimer_tags(propre($note_texte))) {
-				$title = $ouvre_note.$num_note.$ferme_note.$title;
-				$title = couper($title,80);
-				$lien = inserer_attribut($lien, 'title', $title);
-			}
-
-			$insert = "$ouvre_ref$lien$num_note</a>$ferme_ref";
-
-			// on l'echappe
-			$insert = code_echappement($insert);
-
-			$appel = "$ouvre_note<a href=\"#nh$ancre\" name=\"nb$ancre\" class=\"spip_note\" title=\"" . _T('info_notes') . " $ancre\" rev=\"footnote\">$num_note</a>$ferme_note";
-		} else {
-			$insert = '';
-			$appel = '';
-		}
-
-		// l'ajouter "tel quel" (echappe) dans les notes
-		if ($note_texte) {
-			if ($mes_notes)
-				$mes_notes .= "\n\n";
-			$mes_notes .= code_echappement($appel) . $note_texte;
-		}
-
-		// dans le texte, mettre l'appel de note a la place de la note
-		$pos = strpos($letexte, $note_source);
-		$letexte = substr($letexte, 0, $pos) . $insert
-			.  substr($letexte, $pos + strlen($note_source));
-	}
-	return array($letexte, $mes_notes);
-}
-
-
-// http://doc.spip.org/@traiter_les_notes
-function traiter_les_notes($mes_notes) {
-	$mes_notes = propre('<p>'.$mes_notes);
-
-	if ($GLOBALS['class_spip'])
-		$mes_notes = str_replace('<p class="spip">', '<p class="spip_note">', $mes_notes);
-
-	$GLOBALS['les_notes'] .= $mes_notes;
-}
 
 
 // Filtre a appliquer aux champs du type #TEXTE*