diff --git a/ecrire/inc/math.php b/ecrire/inc/math.php
index 01470ef6bf3e641e04f2fd58298e9797c56ad552..b66522ce94787651a7a4ad1b29bda527a489af17 100644
--- a/ecrire/inc/math.php
+++ b/ecrire/inc/math.php
@@ -102,52 +102,43 @@ function produire_image_math($tex) {
  */
 function traiter_math($letexte, $source = '', $defaire_amp = false) {
 
-	$texte_a_voir = $letexte;
-	while (($debut = strpos($texte_a_voir, '<math>')) !== false) {
-		if (!$fin = strpos($texte_a_voir, '</math>')) {
-			$fin = strlen($texte_a_voir);
+	while (($debut = strpos($letexte, '<math>')) !== false) {
+		if (!$fin = strpos($letexte, '</math>', $debut)) {
+			$fin = strlen($letexte);
 		}
 
-		$texte_debut = substr($texte_a_voir, 0, $debut);
 		$texte_milieu = substr(
-			$texte_a_voir,
+			$letexte,
 			$debut + strlen('<math>'),
 			$fin - $debut - strlen('<math>')
 		);
-		$texte_fin = substr(
-			$texte_a_voir,
-			$fin + strlen('</math>'),
-			strlen($texte_a_voir)
-		);
-
-		// Les doubles $$x^2$$ en mode 'div'
-		while ((preg_match(',[$][$]([^$]+)[$][$],', $texte_milieu, $regs))) {
-			$expression = $regs[1];
-			if ($defaire_amp) {
-				$expression = str_replace('&amp;', '&', $expression);
-			}
-			$echap = "\n<p class=\"spip\" style=\"text-align: center;\">" . produire_image_math($expression) . "</p>\n";
-			$pos = strpos($texte_milieu, (string) $regs[0]);
-			$texte_milieu = substr($texte_milieu, 0, $pos)
-				. code_echappement($echap, $source)
-				. substr($texte_milieu, $pos + strlen($regs[0]));
-		}
 
-		// Les simples $x^2$ en mode 'span'
-		while ((preg_match(',[$]([^$]+)[$],', $texte_milieu, $regs))) {
-			$expression = $regs[1];
-			if ($defaire_amp) {
-				$expression = str_replace('&amp;', '&', $expression);
+		$traitements = [
+			// Les doubles $$x^2$$ en mode 'div'
+			['str' => '$$', 'preg' => ',[$][$]([^$]+)[$][$],', 'pre' => "\n<p class=\"spip\" style=\"text-align: center;\">", "post" => "</p>\n"],
+			// Les simples $x^2$ en mode 'span'
+			['str' => '$', 'preg' => ',[$]([^$]+)[$],'],
+		];
+		foreach ($traitements as $t) {
+			while (
+				str_contains($texte_milieu, $t['str'])
+				&& (preg_match($t['preg'], $texte_milieu, $regs))
+			) {
+				$expression = $regs[1];
+				if ($defaire_amp) {
+					$expression = str_replace('&amp;', '&', $expression);
+				}
+				$echap = produire_image_math($expression);
+				$echap = ($t['pre'] ?? '') . $echap . ($t['post'] ?? '');
+				$echap = code_echappement($echap, $source);
+
+				$pos = strpos($texte_milieu, (string) $regs[0]);
+				$texte_milieu = substr_replace($texte_milieu, $echap, $pos, strlen($regs[0]));
 			}
-			$echap = produire_image_math($expression);
-			$pos = strpos($texte_milieu, (string) $regs[0]);
-			$texte_milieu = substr($texte_milieu, 0, $pos)
-				. code_echappement($echap, $source)
-				. substr($texte_milieu, $pos + strlen($regs[0]));
 		}
 
-		$texte_a_voir = $texte_debut . $texte_milieu . $texte_fin;
+		$letexte = substr_replace($letexte, $texte_milieu, $debut, $fin - $debut);
 	}
 
-	return $texte_a_voir;
+	return $letexte;
 }