diff --git a/ecrire/inc_version.php b/ecrire/inc_version.php index 2e47f4e457b306c948430a60502b207521cf6271..5ebcdfc787f79e824f33f1f86b3149ab16f9a77d 100644 --- a/ecrire/inc_version.php +++ b/ecrire/inc_version.php @@ -433,7 +433,7 @@ define('_SPIP_EXTRA_VERSION', '-dev'); define('_DEV_VERSION_SPIP_COMPAT',"3.2.99"); // version des signatures de fonctions PHP // (= date de leur derniere modif cassant la compatibilite et/ou necessitant un recalcul des squelettes) -$spip_version_code = 20200930; +$spip_version_code = 20201020; // version de la base SQL (= numero SVN de sa derniere modif) $spip_version_base = 24379; diff --git a/ecrire/public/phraser_html.php b/ecrire/public/phraser_html.php index e7f7afb7cfd2868f7f5c96433f572bd913e6a2ad..483669ea89f4abaa18d4822492740bf0afcc30c8 100644 --- a/ecrire/public/phraser_html.php +++ b/ecrire/public/phraser_html.php @@ -502,6 +502,9 @@ function phraser_champs_interieurs($texte, $ligne, $sep, $result) { } $champ->apres = phraser_champs_exterieurs($debut, $n, $sep, $result); + // reinjecter la boucle si c'en est une + phraser_boucle_placeholder($champ); + $result[$i] = $champ; $i++; $texte = substr($texte, $p + strlen($match[0])); @@ -869,11 +872,57 @@ function public_trouver_premiere_boucle($texte, $id_parent, $descr, $pos_debut_t return $premiere_boucle; } +/** + * @param object|string $champ + * @param null|string $boucle_placeholder + * @param null|object $boucle + */ +function phraser_boucle_placeholder(&$champ, $boucle_placeholder=null, $boucle = null) { + static $boucles_connues = array(); + // si c'est un appel pour memoriser une boucle, memorisons la + if (is_string($champ) and !empty($boucle_placeholder) and !empty($boucle)) { + $boucles_connues[$boucle_placeholder][$champ] = &$boucle; + } + else { + if (!empty($champ->nom_champ) and !empty($boucles_connues[$champ->nom_champ])) { + $placeholder = $champ->nom_champ; + $id = reset($champ->param[0][1]); + $id = $id->texte; + if (!empty($boucles_connues[$placeholder][$id])) { + $champ = $boucles_connues[$placeholder][$id]; + } + } + } +} + + +/** + * Generer une balise placeholder qui prend la place de la boucle pour continuer le parsing des balises + * @param string $id_boucle + * @param $boucle + * @param string $boucle_placeholder + * @param int $nb_lignes + * @return string + */ +function public_generer_boucle_placeholder($id_boucle, &$boucle, $boucle_placeholder, $nb_lignes) { + $placeholder = "[(#{$boucle_placeholder}{" . $id_boucle . '})' . str_pad("", $nb_lignes, "\n") . "]"; + //memoriser la boucle a reinjecter + $id_boucle = "$id_boucle"; + phraser_boucle_placeholder($id_boucle, $boucle_placeholder, $boucle); + return $placeholder; +} -function public_phraser_html_dist($texte, $id_parent, &$boucles, $descr, $ligne_debut_texte = 1) { +function public_phraser_html_dist($texte, $id_parent, &$boucles, $descr, $ligne_debut_texte = 1, $boucle_placeholder = null) { $all_res = array(); + // definir un placholder pour les boucles dont on est sur d'avoir aucune occurence dans le squelette + if (is_null($boucle_placeholder)) { + do { + $boucle_placeholder = "BOUCLE_PLACEHOLDER_" . strtoupper(md5(uniqid())); + } while (strpos($texte, $boucle_placeholder) !== false); + } + $ligne_debut_initial = $ligne_debut_texte; $pos_debut_texte = 0; while ($boucle = public_trouver_premiere_boucle($texte, $id_parent, $descr, $pos_debut_texte)) { $err_b = ''; // indiquera s'il y a eu une erreur @@ -1046,18 +1095,18 @@ function public_phraser_html_dist($texte, $id_parent, &$boucles, $descr, $ligne_ } $descr['id_mere_contexte'] = $id_boucle; - $result->milieu = public_phraser_html_dist($result->milieu, $id_boucle, $boucles, $descr, $ligne_milieu); + $result->milieu = public_phraser_html_dist($result->milieu, $id_boucle, $boucles, $descr, $ligne_milieu, $boucle_placeholder); // reserver la place dans la pile des boucles pour compiler ensuite dans le bon ordre // ie les boucles qui apparaissent dans les partie conditionnelles doivent etre compilees apres cette boucle // si il y a deja une boucle de ce nom, cela declenchera une erreur ensuite if (empty($boucles[$id_boucle])){ $boucles[$id_boucle] = null; } - $result->preaff = public_phraser_html_dist($result->preaff, $id_parent, $boucles, $descr, $ligne_preaff); - $result->avant = public_phraser_html_dist($result->avant, $id_parent, $boucles, $descr, $ligne_avant); - $result->apres = public_phraser_html_dist($result->apres, $id_parent, $boucles, $descr, $ligne_apres); - $result->altern = public_phraser_html_dist($result->altern, $id_parent, $boucles, $descr, $ligne_altern); - $result->postaff = public_phraser_html_dist($result->postaff, $id_parent, $boucles, $descr, $ligne_postaff); + $result->preaff = public_phraser_html_dist($result->preaff, $id_parent, $boucles, $descr, $ligne_preaff, $boucle_placeholder); + $result->avant = public_phraser_html_dist($result->avant, $id_parent, $boucles, $descr, $ligne_avant, $boucle_placeholder); + $result->apres = public_phraser_html_dist($result->apres, $id_parent, $boucles, $descr, $ligne_apres, $boucle_placeholder); + $result->altern = public_phraser_html_dist($result->altern, $id_parent, $boucles, $descr, $ligne_altern, $boucle_placeholder); + $result->postaff = public_phraser_html_dist($result->postaff, $id_parent, $boucles, $descr, $ligne_postaff, $boucle_placeholder); // Prevenir le generateur de code que le squelette est faux if ($err_b) { @@ -1078,14 +1127,21 @@ function public_phraser_html_dist($texte, $id_parent, &$boucles, $descr, $ligne_ $boucles[$id_boucle] = $result; } + // remplacer la boucle par un placeholder qui compte le meme nombre de lignes + $placeholder = public_generer_boucle_placeholder($id_boucle, $boucles[$id_boucle], $boucle_placeholder, $ligne_suite - $ligne_debut_texte); + $longueur_boucle = $pos_courante - $boucle['debut_boucle']; + $texte = substr_replace($texte, $placeholder, $boucle['debut_boucle'], $longueur_boucle); + $pos_courante = $pos_courante - $longueur_boucle + strlen($placeholder); + // phraser la partie avant le debut de la boucle - $all_res = phraser_champs_etendus(substr($texte, $pos_debut_texte, $boucle['debut_boucle'] - $pos_debut_texte), $ligne_debut_texte, $all_res); - $all_res[] = &$boucles[$id_boucle]; + #$all_res = phraser_champs_etendus(substr($texte, $pos_debut_texte, $boucle['debut_boucle'] - $pos_debut_texte), $ligne_debut_texte, $all_res); + #$all_res[] = &$boucles[$id_boucle]; $ligne_debut_texte = $ligne_suite; $pos_debut_texte = $pos_courante; } - $all_res = phraser_champs_etendus(substr($texte, $pos_debut_texte), $ligne_debut_texte, $all_res); + $all_res = phraser_champs_etendus($texte, $ligne_debut_initial, $all_res); + return $all_res; -} +} \ No newline at end of file