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 = '';
382 // Traiter chaque ligne
383 $reg_line1 = ',^(\|(' . _RACCOURCI_TH_SPAN
. '))+$,sS';
384 $reg_line_all = ',^(' . _RACCOURCI_TH_SPAN
. ')$,sS';
387 foreach ($regs[1] as $ligne) {
390 // Gestion de la premiere ligne :
391 if (!$thead_ok and $l == 1) {
392 // - <caption> et summary dans la premiere ligne (seulement si on n'a pas dépassé le premier thead) :
393 // || caption | summary || (|summary est optionnel)
394 if (preg_match(',^\|\|([^|]*)(\|(.*))?$,sS', rtrim($ligne, '|'), $cap)) {
395 $cap = array_pad($cap, 4, null);
397 if ($caption = trim($cap[1])) {
398 $debut_table .= "<caption>" . $caption . "</caption>\n";
400 $summary = ' summary="' . entites_html(trim($cap[3])) . '"';
402 // - <thead> sous la forme |{{titre}}|{{titre}}|
403 // Attention thead oblige a avoir tbody
405 if (preg_match($reg_line1, $ligne, $thead)) {
406 preg_match_all('/\|([^|]*)/S', $ligne, $cols);
410 for ($c = count($cols) - 1; $c >= 0; $c--) {
412 if ($cols[$c] == '<') {
416 $attr = " colspan='$colspan'";
419 // inutile de garder le strong qui n'a servi que de marqueur
420 $cols[$c] = str_replace(array('{', '}'), '', $cols[$c]);
421 $ligne = "<th id='id{$tabid}_c$c'$attr>$cols[$c]</th>$ligne";
422 $hc[$c] = "id{$tabid}_c$c"; // pour mettre dans les headers des td
426 $debut_table .= "<thead><tr class='row_first'>" .
427 $ligne . "</tr></thead>\n";
434 // Sinon ligne normale
436 // Gerer les listes a puce dans les cellules
437 // on declenche simplement sur \n- car il y a les
438 // -* -# -? -! (qui produisent des - !)
439 if (strpos($ligne, "\n-") !== false) {
440 $ligne = traiter_listes($ligne);
443 // tout mettre dans un tableau 2d
444 preg_match_all('/\|([^|]*)/S', $ligne, $cols);
446 // Pas de paragraphes dans les cellules
447 foreach ($cols[1] as &$col) {
448 if (strlen($col = trim($col))) {
449 $col = preg_replace("/\n{2,}/S", "<br /> <br />", $col);
451 $col = str_replace("\n", _AUTOBR
. "\n", $col);
456 // assembler le tableau
457 $lignes[] = $cols[1];
461 // maintenant qu'on a toutes les cellules
462 // on prepare une liste de rowspan par defaut, a partir
463 // du nombre de colonnes dans la premiere ligne.
464 // Reperer egalement les colonnes numeriques pour les cadrer a droite
465 $rowspans = $numeric = array();
467 $n = $k ?
count($lignes[0]) : 0;
469 // distinguer les colonnes numeriques a point ou a virgule,
470 // pour les alignements eventuels sur "," ou "."
471 $numeric_class = array(
476 for ($i = 0; $i < $n; $i++
) {
478 for ($j = 0; $j < $k; $j++
) {
479 $rowspans[$j][$i] = 1;
480 if ($align and preg_match('/^[{+-]*(?:\s|\d)*([.,]?)\d*[}]*$/', trim($lignes[$j][$i]), $r)) {
488 $numeric[$i] = $align ?
(" class='numeric " . $numeric_class[$align] . "'") : '';
490 for ($j = 0; $j < $k; $j++
) {
491 if (preg_match($reg_line_all, $lignes[$j][0])) {
492 $hl[$j] = "id{$tabid}_l$j"; // pour mettre dans les headers des td
497 if (!isset($hl[0])) {
499 } // toute la colonne ou rien
501 // et on parcourt le tableau a l'envers pour ramasser les
502 // colspan et rowspan en passant
505 for ($l = count($lignes) - 1; $l >= 0; $l--) {
510 for ($c = count($cols) - 1; $c >= 0; $c--) {
511 $attr = $numeric[$c];
512 $cell = trim($cols[$c]);
516 } elseif ($cell == '^') {
517 $rowspans[$l - 1][$c] +
= $rowspans[$l][$c];
521 $attr .= " colspan='$colspan'";
524 if (($x = $rowspans[$l][$c]) > 1) {
525 $attr .= " rowspan='$x'";
527 $b = ($c == 0 and isset($hl[$l])) ?
'th' : 'td';
528 $h = (isset($hc[$c]) ?
$hc[$c] : '') . ' ' . (($b == 'td' and isset($hl[$l])) ?
$hl[$l] : '');
530 $attr .= " headers='$h'";
532 // inutile de garder le strong qui n'a servi que de marqueur
534 $attr .= " id='" . $hl[$l] . "'";
535 $cols[$c] = str_replace(array('{', '}'), '', $cols[$c]);
537 $ligne = "\n<$b" . $attr . '>' . $cols[$c] . "</$b>" . $ligne;
542 $class = alterner($l +
1, 'odd', 'even');
543 $html = "<tr class='row_$class $class'>$ligne</tr>\n$html";
546 return "\n\n<table" . $GLOBALS['class_spip_plus'] . $summary . ">\n"
556 * Traitement des listes
558 * On utilise la wheel correspondante
563 function traiter_listes($t) {
564 static $wheel = null;
566 if (!isset($wheel)) {
567 $wheel = new TextWheel(
568 SPIPTextWheelRuleset
::loader($GLOBALS['spip_wheels']['listes'])
573 $t = $wheel->text($t);
574 } catch (Exception
$e) {
575 erreur_squelette($e->getMessage());
582 // Ces deux constantes permettent de proteger certains caracteres
583 // en les remplacanat par des caracteres "illegaux". (cf corriger_caracteres)
585 define('_RACCOURCI_PROTEGER', "{}_-");
586 define('_RACCOURCI_PROTECTEUR', "\x1\x2\x3\x4");
588 define('_RACCOURCI_BALISE', ",</?[a-z!][^<>]*[" . preg_quote(_RACCOURCI_PROTEGER
) . "][^<>]*>,imsS");
591 * mais d'abord, une callback de reconfiguration des raccourcis
592 * a partir de globales (est-ce old-style ? on conserve quand meme
593 * par souci de compat ascendante)
598 function personnaliser_raccourcis(&$ruleset) {
600 if (isset($GLOBALS['debut_intertitre']) and $rule = $ruleset->getRule('intertitres')) {
601 $rule->replace
[0] = preg_replace(',<[^>]*>,Uims', $GLOBALS['debut_intertitre'], $rule->replace
[0]);
602 $rule->replace
[1] = preg_replace(',<[^>]*>,Uims', $GLOBALS['fin_intertitre'], $rule->replace
[1]);
603 $ruleset->addRules(array('intertitres' => $rule));
605 if (isset($GLOBALS['debut_gras']) and $rule = $ruleset->getRule('gras')) {
606 $rule->replace
[0] = preg_replace(',<[^>]*>,Uims', $GLOBALS['debut_gras'], $rule->replace
[0]);
607 $rule->replace
[1] = preg_replace(',<[^>]*>,Uims', $GLOBALS['fin_gras'], $rule->replace
[1]);
608 $ruleset->addRules(array('gras' => $rule));
610 if (isset($GLOBALS['debut_italique']) and $rule = $ruleset->getRule('italiques')) {
611 $rule->replace
[0] = preg_replace(',<[^>]*>,Uims', $GLOBALS['debut_italique'], $rule->replace
[0]);
612 $rule->replace
[1] = preg_replace(',<[^>]*>,Uims', $GLOBALS['fin_italique'], $rule->replace
[1]);
613 $ruleset->addRules(array('italiques' => $rule));
615 if (isset($GLOBALS['ligne_horizontale']) and $rule = $ruleset->getRule('ligne-horizontale')) {
616 $rule->replace
= preg_replace(',<[^>]*>,Uims', $GLOBALS['ligne_horizontale'], $rule->replace
);
617 $ruleset->addRules(array('ligne-horizontale' => $rule));
619 if (isset($GLOBALS['toujours_paragrapher']) and !$GLOBALS['toujours_paragrapher']
620 and $rule = $ruleset->getRule('toujours-paragrapher')
622 $rule->disabled
= true;
623 $ruleset->addRules(array('toujours-paragrapher' => $rule));
627 // retourner une signature de l'etat de la fonction, pour la mise en cache
630 isset($GLOBALS['debut_intertitre']) ?
$GLOBALS['debut_intertitre'] : "",
631 isset($GLOBALS['debut_gras']) ?
$GLOBALS['debut_gras'] : "",
632 isset($GLOBALS['debut_italique']) ?
$GLOBALS['debut_italique'] : "",
633 isset($GLOBALS['ligne_horizontale']) ?
$GLOBALS['ligne_horizontale'] : "",
634 isset($GLOBALS['toujours_paragrapher']) ?
$GLOBALS['toujours_paragrapher'] : 1,
640 * Nettoie un texte, traite les raccourcis autre qu'URL, la typo, etc.
642 * @pipeline_appel pre_propre
643 * @pipeline_appel post_propre
646 * @param bool $show_autobr
649 function traiter_raccourcis($t, $show_autobr = false) {
650 static $wheel = array(), $notes;
651 static $img_br_auto, $img_br_manuel, $img_br_no;
652 global $spip_lang, $spip_lang_rtl;
654 // hack1: respecter le tag ignore br
656 and strncmp($t, _AUTOBR_IGNORER
, strlen(_AUTOBR_IGNORER
)) == 0
658 $ignorer_autobr = true;
659 $t = substr($t, strlen(_AUTOBR_IGNORER
));
661 $ignorer_autobr = false;
664 // Appeler les fonctions de pre_traitement
665 $t = pipeline('pre_propre', $t);
668 $key = personnaliser_raccourcis($key);
669 if (!isset($wheel[$key])) {
670 $ruleset = SPIPTextWheelRuleset
::loader(
671 $GLOBALS['spip_wheels']['raccourcis'], 'personnaliser_raccourcis'
673 $wheel[$key] = new TextWheel($ruleset);
675 if (_request('var_mode') == 'wheel'
676 and autoriser('debug')
678 $f = $wheel->compile();
679 echo "<pre>\n" . spip_htmlspecialchars($f) . "</pre>\n";
682 $notes = charger_fonction('notes', 'inc');
685 // Gerer les notes (ne passe pas dans le pipeline)
686 list($t, $mes_notes) = $notes($t);
689 $t = $wheel[$key]->text($t);
690 } catch (Exception
$e) {
691 erreur_squelette($e->getMessage());
694 // Appeler les fonctions de post-traitement
695 $t = pipeline('post_propre', $t);
698 $notes($mes_notes, 'traiter', $ignorer_autobr);
701 if (_AUTOBR
and !function_exists('aide_lang_dir')) {
702 include_spip('inc/lang');
705 // hack2: wrap des autobr dans l'espace prive, pour affichage css
706 // car en css on ne sait pas styler l'element BR
707 if ($ignorer_autobr and _AUTOBR
) {
708 if (is_null($img_br_no)) {
709 $img_br_no = ($show_autobr ?
http_img_pack("br-no" . aide_lang_dir($spip_lang, $spip_lang_rtl) . "-10.png",
710 _T("tw:retour_ligne_ignore"), "class='br-no'", _T("tw:retour_ligne_ignore")) : "");
712 $t = str_replace(_AUTOBR
, $img_br_no, $t);
714 if ($show_autobr and _AUTOBR
) {
715 if (is_null($img_br_manuel)) {
716 $img_br_manuel = http_img_pack("br-manuel" . aide_lang_dir($spip_lang, $spip_lang_rtl) . "-10.png",
717 _T("tw:retour_ligne_manuel"), "class='br-manuel'", _T("tw:retour_ligne_manuel"));
719 if (is_null($img_br_auto)) {
720 $img_br_auto = http_img_pack("br-auto" . aide_lang_dir($spip_lang, $spip_lang_rtl) . "-10.png",
721 _T("tw:retour_ligne_auto"), "class='br-auto'", _T("tw:retour_ligne_auto"));
723 if (false !== strpos(strtolower($t), '<br')) {
724 $t = preg_replace("/<br\b.*>/UiS", "$img_br_manuel\\0", $t);
725 $t = str_replace($img_br_manuel . _AUTOBR
, $img_br_auto . _AUTOBR
, $t);
734 * Transforme les raccourcis SPIP, liens et modèles d'un texte en code HTML
736 * Filtre à appliquer aux champs du type `#TEXTE*`
739 * @uses echappe_html()
740 * @uses expanser_liens()
741 * @uses traiter_raccourcis()
742 * @uses echappe_retour_modeles()
746 * Texte avec des raccourcis SPIP
747 * @param string|null $connect
748 * Nom du connecteur à la bdd
750 * Environnement (pour les calculs de modèles)
754 function propre($t, $connect = null, $env = array()) {
755 // les appels directs a cette fonction depuis le php de l'espace
756 // prive etant historiquement ecrits sans argment $connect
757 // on utilise la presence de celui-ci pour distinguer les cas
758 // ou il faut passer interdire_script explicitement
759 // les appels dans les squelettes (de l'espace prive) fournissant un $connect
760 // ne seront pas perturbes
761 $interdire_script = false;
762 if (is_null($connect) and test_espace_prive()) {
764 $interdire_script = true;
771 $t = pipeline('pre_echappe_html_propre', $t);
773 // Dans l'espace prive on se mefie de tout contenu dangereux
774 // avant echappement des balises <html>
775 // https://core.spip.net/issues/3371
776 // et aussi dans l'espace public si la globale filtrer_javascript = -1
777 // https://core.spip.net/issues/4166
778 if ($interdire_script
779 or $GLOBALS['filtrer_javascript'] == -1
780 or (isset($env['espace_prive']) and $env['espace_prive'] and $GLOBALS['filtrer_javascript']<=0)
781 or (isset($env['wysiwyg']) and $env['wysiwyg'] and $GLOBALS['filtrer_javascript']<=0)) {
782 $t = echapper_html_suspect($t, false);
784 $t = echappe_html($t);
785 $t = expanser_liens($t, $connect, $env);
787 $t = traiter_raccourcis($t, (isset($env['wysiwyg']) and $env['wysiwyg']) ?
true : false);
788 $t = echappe_retour_modeles($t, $interdire_script);
790 $t = pipeline('post_echappe_html_propre', $t);