3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
6 * Copyright (c) 2001-2020 *
7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
9 * Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
10 * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
11 \***************************************************************************/
14 * Gestion des textes et raccourcis SPIP
16 * Surcharge de ecrire/inc/texte
18 * @package SPIP\Textwheel\Texte
21 if (!defined('_ECRIRE_INC_VERSION')) {
25 include_spip('inc/texte_mini');
26 include_spip('inc/lien');
28 include_spip('inc/textwheel');
31 defined('_AUTOBR') ||
define('_AUTOBR', "<br class='autobr' />");
32 define('_AUTOBR_IGNORER', _AUTOBR ?
"<!-- ig br -->" : "");
34 // Avec cette surcharge, cette globale n'est plus définie, et du coup ça plante dans les plugins qui font un foreach dessus comme ZPIP
35 $GLOBALS['spip_raccourcis_typo'] = array();
36 if (!isset($GLOBALS['toujours_paragrapher'])) {
37 $GLOBALS['toujours_paragrapher'] = true;
40 // class_spip : savoir si on veut class="spip" sur p i strong & li
41 // class_spip_plus : class="spip" sur les ul ol h3 hr quote table...
42 // la difference c'est que des css specifiques existent pour les seconds
44 if (!isset($GLOBALS['class_spip'])) {
45 $GLOBALS['class_spip'] = '';
47 if (!isset($GLOBALS['class_spip_plus'])) {
48 $GLOBALS['class_spip_plus'] = ' class="spip"';
53 * Échapper et affichier joliement les `<script` ...
58 function echappe_js($t) {
62 $wheel = new TextWheel(
63 SPIPTextWheelRuleset
::loader($GLOBALS['spip_wheels']['echappe_js'])
68 $t = $wheel->text($t);
69 } catch (Exception
$e) {
70 erreur_squelette($e->getMessage());
71 // sanitizer le contenu methode brute, puisqu'on a pas fait mieux
80 * Paragrapher seulement
82 * Fermer les paragraphes ; Essaie de préserver des paragraphes indiqués
83 * à la main dans le texte (par ex: on ne modifie pas un `<p align='center'>`)
87 * @param null $toujours_paragrapher
88 * true pour forcer les `<p>` même pour un seul paragraphe
92 function paragrapher($t, $toujours_paragrapher = null) {
93 static $wheel = array();
94 if (is_null($toujours_paragrapher)) {
95 $toujours_paragrapher = $GLOBALS['toujours_paragrapher'];
98 if (!isset($wheel[$toujours_paragrapher])) {
99 $ruleset = SPIPTextWheelRuleset
::loader($GLOBALS['spip_wheels']['paragrapher']);
100 if (!$toujours_paragrapher
101 and $rule = $ruleset->getRule('toujours-paragrapher')
103 $rule->disabled
= true;
104 $ruleset->addRules(array('toujours-paragrapher' => $rule));
106 $wheel[$toujours_paragrapher] = new TextWheel($ruleset);
110 $t = $wheel[$toujours_paragrapher]->text($t);
111 } catch (Exception
$e) {
112 erreur_squelette($e->getMessage());
119 * Empêcher l'exécution de code PHP et JS
121 * Sécurité : empêcher l'exécution de code PHP, en le transformant en joli code
122 * dans l'espace privé. Cette fonction est aussi appelée par propre et typo.
124 * De la même manière, la fonction empêche l'exécution de JS mais selon le mode
125 * de protection passe en argument
127 * Il ne faut pas désactiver globalement la fonction dans l'espace privé car elle protège
128 * aussi les balises des squelettes qui ne passent pas forcement par propre ou typo après
129 * si elles sont appelées en direct
133 * @param int $mode_filtre
135 * -1 : protection dans l'espace privé et public
136 * 0 : protection dans l'espace public
137 * 1 : aucune protection
138 * utilise la valeur de la globale filtrer_javascript si non fourni
142 function interdire_scripts($arg, $mode_filtre=null) {
143 // on memorise le resultat sur les arguments non triviaux
144 static $dejavu = array();
145 static $wheel = array();
147 if (is_null($mode_filtre) or !in_array($mode_filtre, array(-1, 0, 1))) {
148 $mode_filtre = $GLOBALS['filtrer_javascript'];
151 // Attention, si ce n'est pas une chaine, laisser intact
152 if (!$arg or !is_string($arg) or !strstr($arg, '<')) {
155 if (isset($dejavu[$mode_filtre][$arg])) {
156 return $dejavu[$mode_filtre][$arg];
159 if (!isset($wheel[$mode_filtre])) {
160 $ruleset = SPIPTextWheelRuleset
::loader(
161 $GLOBALS['spip_wheels']['interdire_scripts']
163 // Pour le js, trois modes : parano (-1), prive (0), ok (1)
164 // desactiver la regle echappe-js si besoin
165 if ($mode_filtre == 1
166 or ($mode_filtre == 0 and !test_espace_prive())
168 $ruleset->addRules(array('securite-js' => array('disabled' => true)));
170 $wheel[$mode_filtre] = new TextWheel($ruleset);
174 $t = $wheel[$mode_filtre]->text($arg);
175 } catch (Exception
$e) {
176 erreur_squelette($e->getMessage());
177 // sanitizer le contenu methode brute, puisqu'on a pas fait mieux
178 $t = textebrut($arg);
181 // Reinserer les echappements des modeles
182 if (defined('_PROTEGE_JS_MODELES')) {
183 $t = echappe_retour($t, "javascript" . _PROTEGE_JS_MODELES
);
185 if (defined('_PROTEGE_PHP_MODELES')) {
186 $t = echappe_retour($t, "php" . _PROTEGE_PHP_MODELES
);
189 return $dejavu[$mode_filtre][$arg] = $t;
194 * Applique la typographie générale
196 * Effectue un traitement pour que les textes affichés suivent les règles
197 * de typographie. Fait une protection préalable des balises HTML et SPIP.
198 * Transforme les balises `<multi>`
201 * @uses traiter_modeles()
202 * @uses corriger_typo()
203 * @uses echapper_faux_tags()
206 * @param string $letexte
208 * @param bool $echapper
210 * @param string|null $connect
211 * Nom du connecteur à la bdd
213 * Environnement (pour les calculs de modèles)
217 function typo($letexte, $echapper = true, $connect = null, $env = array()) {
223 // les appels directs a cette fonction depuis le php de l'espace
224 // prive etant historiquement ecrit sans argment $connect
225 // on utilise la presence de celui-ci pour distinguer les cas
226 // ou il faut passer interdire_script explicitement
227 // les appels dans les squelettes (de l'espace prive) fournissant un $connect
228 // ne seront pas perturbes
229 $interdire_script = false;
230 if (is_null($connect)) {
232 $interdire_script = true;
233 $env['espace_prive'] = test_espace_prive();
236 $echapper = ($echapper ?
'TYPO' : false);
237 // Echapper les codes <html> etc
239 $letexte = echappe_html($letexte, $echapper);
243 // Installer les modeles, notamment images et documents ;
245 // NOTE : propre() ne passe pas par ici mais directement par corriger_typo
248 $letexte = traiter_modeles($mem = $letexte, false, $echapper ?
$echapper : '', $connect, null, $env);
249 if (!$echapper and $letexte != $mem) {
254 $letexte = corriger_typo($letexte);
255 $letexte = echapper_faux_tags($letexte);
257 // reintegrer les echappements
258 if ($echapper !== false) {
259 $letexte = echappe_retour($letexte, $echapper);
262 // Dans les appels directs hors squelette, securiser ici aussi
263 if ($interdire_script) {
264 $letexte = interdire_scripts($letexte);
267 // Dans l'espace prive on se mefie de tout contenu dangereux
268 // https://core.spip.net/issues/3371
269 // et aussi dans l'espace public si la globale filtrer_javascript = -1
270 // https://core.spip.net/issues/4166
271 if ($GLOBALS['filtrer_javascript'] == -1
272 or (isset($env['espace_prive']) and $env['espace_prive'] and $GLOBALS['filtrer_javascript']<=0)) {
273 $letexte = echapper_html_suspect($letexte);
279 // Correcteur typographique
281 define('_TYPO_PROTEGER', "!':;?~%-");
282 define('_TYPO_PROTECTEUR', "\x1\x2\x3\x4\x5\x6\x7\x8");
284 define('_TYPO_BALISE', ",</?[a-z!][^<>]*[" . preg_quote(_TYPO_PROTEGER
) . "][^<>]*>,imsS");
287 * Corrige la typographie
289 * Applique les corrections typographiques adaptées à la langue indiquée.
291 * @pipeline_appel pre_typo
292 * @pipeline_appel post_typo
293 * @uses corriger_caracteres()
294 * @uses corriger_caracteres()
296 * @param string $t Texte
297 * @param string $lang Langue
298 * @return string Texte
300 function corriger_typo($t, $lang = '') {
301 static $typographie = array();
307 $t = pipeline('pre_typo', $t);
309 // Caracteres de controle "illegaux"
310 $t = corriger_caracteres($t);
312 // Proteger les caracteres typographiques a l'interieur des tags html
313 if (preg_match_all(_TYPO_BALISE
, $t, $regs, PREG_SET_ORDER
)) {
314 foreach ($regs as $reg) {
316 // hack: on transforme les caracteres a proteger en les remplacant
317 // par des caracteres "illegaux". (cf corriger_caracteres())
318 $insert = strtr($insert, _TYPO_PROTEGER
, _TYPO_PROTECTEUR
);
319 $t = str_replace($reg[0], $insert, $t);
323 // trouver les blocs idiomes et les traiter à part
324 $t = extraire_idiome($ei = $t, $lang, true);
327 // trouver les blocs multi et les traiter à part
328 $t = extraire_multi($em = $t, $lang, true);
331 // Charger & appliquer les fonctions de typographie
332 $idxl = "$lang:" . (isset($GLOBALS['lang_objet']) ?
$GLOBALS['lang_objet'] : $GLOBALS['spip_lang']);
333 if (!isset($typographie[$idxl])) {
334 $typographie[$idxl] = charger_fonction(lang_typo($lang), 'typographie');
336 $t = $typographie[$idxl]($t);
338 // Les citations en une autre langue, s'il y a lieu
340 $t = echappe_retour($t, 'idiome');
343 $t = echappe_retour($t, 'multi');
346 // Retablir les caracteres proteges
347 $t = strtr($t, _TYPO_PROTECTEUR
, _TYPO_PROTEGER
);
350 $t = pipeline('post_typo', $t);
352 # un message pour abs_url - on est passe en mode texte
353 $GLOBALS['mode_abs_url'] = 'texte';
363 define('_RACCOURCI_TH_SPAN', '\s*(:?{{[^{}]+}}\s*)?|<');
366 * Traitement des raccourcis de tableaux
368 * @param string $bloc
371 function traiter_tableau($bloc) {
372 // id "unique" pour les id du tableau
373 $tabid = substr(md5($bloc), 0, 4);
375 // Decouper le tableau en lignes
376 preg_match_all(',([|].*)[|]\n,UmsS', $bloc, $regs, PREG_PATTERN_ORDER
);
378 $debut_table = $summary = '';
381 // Traiter chaque ligne
382 $reg_line1 = ',^(\|(' . _RACCOURCI_TH_SPAN
. '))+$,sS';
383 $reg_line_all = ',^(' . _RACCOURCI_TH_SPAN
. ')$,sS';
386 foreach ($regs[1] as $ligne) {
389 // Gestion de la premiere ligne :
390 if (!$thead_ok and $l == 1) {
391 // - <caption> et summary dans la premiere ligne (seulement si on n'a pas dépassé le premier thead) :
392 // || caption | summary || (|summary est optionnel)
393 if (preg_match(',^\|\|([^|]*)(\|(.*))?$,sS', rtrim($ligne, '|'), $cap)) {
394 $cap = array_pad($cap, 4, null);
396 if ($caption = trim($cap[1])) {
397 $debut_table .= "<caption>" . $caption . "</caption>\n";
399 $summary = ' summary="' . entites_html(trim($cap[3])) . '"';
401 // - <thead> sous la forme |{{titre}}|{{titre}}|
402 // Attention thead oblige a avoir tbody
404 if (preg_match($reg_line1, $ligne, $thead)) {
405 preg_match_all('/\|([^|]*)/S', $ligne, $cols);
409 for ($c = count($cols) - 1; $c >= 0; $c--) {
411 if ($cols[$c] == '<') {
415 $attr = " colspan='$colspan'";
418 // inutile de garder le strong qui n'a servi que de marqueur
419 $cols[$c] = str_replace(array('{', '}'), '', $cols[$c]);
420 $ligne = "<th id='id{$tabid}_c$c'$attr>$cols[$c]</th>$ligne";
421 $hc[$c] = "id{$tabid}_c$c"; // pour mettre dans les headers des td
425 $debut_table .= "<thead><tr class='row_first'>" .
426 $ligne . "</tr></thead>\n";
433 // Sinon ligne normale
435 // Gerer les listes a puce dans les cellules
436 // on declenche simplement sur \n- car il y a les
437 // -* -# -? -! (qui produisent des - !)
438 if (strpos($ligne, "\n-") !== false) {
439 $ligne = traiter_listes($ligne);
442 // tout mettre dans un tableau 2d
443 preg_match_all('/\|([^|]*)/S', $ligne, $cols);
445 // Pas de paragraphes dans les cellules
446 foreach ($cols[1] as &$col) {
447 if (strlen($col = trim($col))) {
448 $col = preg_replace("/\n{2,}/S", "<br /> <br />", $col);
450 $col = str_replace("\n", _AUTOBR
. "\n", $col);
455 // assembler le tableau
456 $lignes[] = $cols[1];
460 // maintenant qu'on a toutes les cellules
461 // on prepare une liste de rowspan par defaut, a partir
462 // du nombre de colonnes dans la premiere ligne.
463 // Reperer egalement les colonnes numeriques pour les cadrer a droite
464 $rowspans = $numeric = array();
466 $n = $k ?
count($lignes[0]) : 0;
468 // distinguer les colonnes numeriques a point ou a virgule,
469 // pour les alignements eventuels sur "," ou "."
470 $numeric_class = array(
475 for ($i = 0; $i < $n; $i++
) {
477 for ($j = 0; $j < $k; $j++
) {
478 $rowspans[$j][$i] = 1;
479 if ($align and preg_match('/^[{+-]*(?:\s|\d)*([.,]?)\d*[}]*$/', trim($lignes[$j][$i]), $r)) {
487 $numeric[$i] = $align ?
(" class='numeric " . $numeric_class[$align] . "'") : '';
489 for ($j = 0; $j < $k; $j++
) {
490 if (preg_match($reg_line_all, $lignes[$j][0])) {
491 $hl[$j] = "id{$tabid}_l$j"; // pour mettre dans les headers des td
496 if (!isset($hl[0])) {
498 } // toute la colonne ou rien
500 // et on parcourt le tableau a l'envers pour ramasser les
501 // colspan et rowspan en passant
504 for ($l = count($lignes) - 1; $l >= 0; $l--) {
509 for ($c = count($cols) - 1; $c >= 0; $c--) {
510 $attr = $numeric[$c];
511 $cell = trim($cols[$c]);
515 } elseif ($cell == '^') {
516 $rowspans[$l - 1][$c] +
= $rowspans[$l][$c];
520 $attr .= " colspan='$colspan'";
523 if (($x = $rowspans[$l][$c]) > 1) {
524 $attr .= " rowspan='$x'";
526 $b = ($c == 0 and isset($hl[$l])) ?
'th' : 'td';
527 $h = (isset($hc[$c]) ?
$hc[$c] : '') . ' ' . (($b == 'td' and isset($hl[$l])) ?
$hl[$l] : '');
529 $attr .= " headers='$h'";
531 // inutile de garder le strong qui n'a servi que de marqueur
533 $attr .= " id='" . $hl[$l] . "'";
534 $cols[$c] = str_replace(array('{', '}'), '', $cols[$c]);
536 $ligne = "\n<$b" . $attr . '>' . $cols[$c] . "</$b>" . $ligne;
541 $class = alterner($l +
1, 'odd', 'even');
542 $html = "<tr class='row_$class $class'>$ligne</tr>\n$html";
545 return "\n\n<table" . $GLOBALS['class_spip_plus'] . $summary . ">\n"
555 * Traitement des listes
557 * On utilise la wheel correspondante
562 function traiter_listes($t) {
563 static $wheel = null;
565 if (!isset($wheel)) {
566 $wheel = new TextWheel(
567 SPIPTextWheelRuleset
::loader($GLOBALS['spip_wheels']['listes'])
572 $t = $wheel->text($t);
573 } catch (Exception
$e) {
574 erreur_squelette($e->getMessage());
581 // Ces deux constantes permettent de proteger certains caracteres
582 // en les remplacanat par des caracteres "illegaux". (cf corriger_caracteres)
584 define('_RACCOURCI_PROTEGER', "{}_-");
585 define('_RACCOURCI_PROTECTEUR', "\x1\x2\x3\x4");
587 define('_RACCOURCI_BALISE', ",</?[a-z!][^<>]*[" . preg_quote(_RACCOURCI_PROTEGER
) . "][^<>]*>,imsS");
590 * mais d'abord, une callback de reconfiguration des raccourcis
591 * a partir de globales (est-ce old-style ? on conserve quand meme
592 * par souci de compat ascendante)
597 function personnaliser_raccourcis(&$ruleset) {
599 if (isset($GLOBALS['debut_intertitre']) and $rule = $ruleset->getRule('intertitres')) {
600 $rule->replace
[0] = preg_replace(',<[^>]*>,Uims', $GLOBALS['debut_intertitre'], $rule->replace
[0]);
601 $rule->replace
[1] = preg_replace(',<[^>]*>,Uims', $GLOBALS['fin_intertitre'], $rule->replace
[1]);
602 $ruleset->addRules(array('intertitres' => $rule));
604 if (isset($GLOBALS['debut_gras']) and $rule = $ruleset->getRule('gras')) {
605 $rule->replace
[0] = preg_replace(',<[^>]*>,Uims', $GLOBALS['debut_gras'], $rule->replace
[0]);
606 $rule->replace
[1] = preg_replace(',<[^>]*>,Uims', $GLOBALS['fin_gras'], $rule->replace
[1]);
607 $ruleset->addRules(array('gras' => $rule));
609 if (isset($GLOBALS['debut_italique']) and $rule = $ruleset->getRule('italiques')) {
610 $rule->replace
[0] = preg_replace(',<[^>]*>,Uims', $GLOBALS['debut_italique'], $rule->replace
[0]);
611 $rule->replace
[1] = preg_replace(',<[^>]*>,Uims', $GLOBALS['fin_italique'], $rule->replace
[1]);
612 $ruleset->addRules(array('italiques' => $rule));
614 if (isset($GLOBALS['ligne_horizontale']) and $rule = $ruleset->getRule('ligne-horizontale')) {
615 $rule->replace
= preg_replace(',<[^>]*>,Uims', $GLOBALS['ligne_horizontale'], $rule->replace
);
616 $ruleset->addRules(array('ligne-horizontale' => $rule));
618 if (isset($GLOBALS['toujours_paragrapher']) and !$GLOBALS['toujours_paragrapher']
619 and $rule = $ruleset->getRule('toujours-paragrapher')
621 $rule->disabled
= true;
622 $ruleset->addRules(array('toujours-paragrapher' => $rule));
626 // retourner une signature de l'etat de la fonction, pour la mise en cache
629 isset($GLOBALS['debut_intertitre']) ?
$GLOBALS['debut_intertitre'] : "",
630 isset($GLOBALS['debut_gras']) ?
$GLOBALS['debut_gras'] : "",
631 isset($GLOBALS['debut_italique']) ?
$GLOBALS['debut_italique'] : "",
632 isset($GLOBALS['ligne_horizontale']) ?
$GLOBALS['ligne_horizontale'] : "",
633 isset($GLOBALS['toujours_paragrapher']) ?
$GLOBALS['toujours_paragrapher'] : 1,
639 * Nettoie un texte, traite les raccourcis autre qu'URL, la typo, etc.
641 * @pipeline_appel pre_propre
642 * @pipeline_appel post_propre
645 * @param bool $show_autobr
648 function traiter_raccourcis($t, $show_autobr = false) {
649 static $wheel = array(), $notes;
650 static $img_br_auto, $img_br_manuel, $img_br_no;
651 global $spip_lang, $spip_lang_rtl;
653 // hack1: respecter le tag ignore br
655 and strncmp($t, _AUTOBR_IGNORER
, strlen(_AUTOBR_IGNORER
)) == 0
657 $ignorer_autobr = true;
658 $t = substr($t, strlen(_AUTOBR_IGNORER
));
660 $ignorer_autobr = false;
663 // Appeler les fonctions de pre_traitement
664 $t = pipeline('pre_propre', $t);
667 $key = personnaliser_raccourcis($key);
668 if (!isset($wheel[$key])) {
669 $ruleset = SPIPTextWheelRuleset
::loader(
670 $GLOBALS['spip_wheels']['raccourcis'], 'personnaliser_raccourcis'
672 $wheel[$key] = new TextWheel($ruleset);
674 if (_request('var_mode') == 'wheel'
675 and autoriser('debug')
677 $f = $wheel->compile();
678 echo "<pre>\n" . spip_htmlspecialchars($f) . "</pre>\n";
681 $notes = charger_fonction('notes', 'inc');
684 // Gerer les notes (ne passe pas dans le pipeline)
685 list($t, $mes_notes) = $notes($t);
688 $t = $wheel[$key]->text($t);
689 } catch (Exception
$e) {
690 erreur_squelette($e->getMessage());
693 // Appeler les fonctions de post-traitement
694 $t = pipeline('post_propre', $t);
697 $notes($mes_notes, 'traiter', $ignorer_autobr);
700 if (_AUTOBR
and !function_exists('aide_lang_dir')) {
701 include_spip('inc/lang');
704 // hack2: wrap des autobr dans l'espace prive, pour affichage css
705 // car en css on ne sait pas styler l'element BR
706 if ($ignorer_autobr and _AUTOBR
) {
707 if (is_null($img_br_no)) {
708 $img_br_no = ($show_autobr ?
http_img_pack("br-no" . aide_lang_dir($spip_lang, $spip_lang_rtl) . "-10.png",
709 _T("tw:retour_ligne_ignore"), "class='br-no'", _T("tw:retour_ligne_ignore")) : "");
711 $t = str_replace(_AUTOBR
, $img_br_no, $t);
713 if ($show_autobr and _AUTOBR
) {
714 if (is_null($img_br_manuel)) {
715 $img_br_manuel = http_img_pack("br-manuel" . aide_lang_dir($spip_lang, $spip_lang_rtl) . "-10.png",
716 _T("tw:retour_ligne_manuel"), "class='br-manuel'", _T("tw:retour_ligne_manuel"));
718 if (is_null($img_br_auto)) {
719 $img_br_auto = http_img_pack("br-auto" . aide_lang_dir($spip_lang, $spip_lang_rtl) . "-10.png",
720 _T("tw:retour_ligne_auto"), "class='br-auto'", _T("tw:retour_ligne_auto"));
722 if (false !== strpos(strtolower($t), '<br')) {
723 $t = preg_replace("/<br\b.*>/UiS", "$img_br_manuel\\0", $t);
724 $t = str_replace($img_br_manuel . _AUTOBR
, $img_br_auto . _AUTOBR
, $t);
733 * Transforme les raccourcis SPIP, liens et modèles d'un texte en code HTML
735 * Filtre à appliquer aux champs du type `#TEXTE*`
738 * @uses echappe_html()
739 * @uses expanser_liens()
740 * @uses traiter_raccourcis()
741 * @uses echappe_retour_modeles()
745 * Texte avec des raccourcis SPIP
746 * @param string|null $connect
747 * Nom du connecteur à la bdd
749 * Environnement (pour les calculs de modèles)
753 function propre($t, $connect = null, $env = array()) {
754 // les appels directs a cette fonction depuis le php de l'espace
755 // prive etant historiquement ecrits sans argment $connect
756 // on utilise la presence de celui-ci pour distinguer les cas
757 // ou il faut passer interdire_script explicitement
758 // les appels dans les squelettes (de l'espace prive) fournissant un $connect
759 // ne seront pas perturbes
760 $interdire_script = false;
761 if (is_null($connect) and test_espace_prive()) {
763 $interdire_script = true;
770 $t = pipeline('pre_echappe_html_propre', $t);
772 // Dans l'espace prive on se mefie de tout contenu dangereux
773 // avant echappement des balises <html>
774 // https://core.spip.net/issues/3371
775 // et aussi dans l'espace public si la globale filtrer_javascript = -1
776 // https://core.spip.net/issues/4166
777 if ($interdire_script
778 or $GLOBALS['filtrer_javascript'] == -1
779 or (isset($env['espace_prive']) and $env['espace_prive'] and $GLOBALS['filtrer_javascript']<=0)
780 or (isset($env['wysiwyg']) and $env['wysiwyg'] and $GLOBALS['filtrer_javascript']<=0)) {
781 $t = echapper_html_suspect($t, false);
783 $t = echappe_html($t);
784 $t = expanser_liens($t, $connect, $env);
786 $t = traiter_raccourcis($t, (isset($env['wysiwyg']) and $env['wysiwyg']) ?
true : false);
787 $t = echappe_retour_modeles($t, $interdire_script);
789 $t = pipeline('post_echappe_html_propre', $t);