source: spip-zone/_core_/plugins/textwheel/inc/texte.php @ 98725

Last change on this file since 98725 was 98725, checked in by xdjuj@…, 3 years ago

En HTML5 l'attribut summary est obsolète sur les tables.

File size: 21.8 KB
Line 
1<?php
2
3/***************************************************************************\
4 *  SPIP, Systeme de publication pour l'internet                           *
5 *                                                                         *
6 *  Copyright (c) 2001-2016                                                *
7 *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
8 *                                                                         *
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\***************************************************************************/
12
13/**
14 * Gestion des textes et raccourcis SPIP
15 *
16 * Surcharge de ecrire/inc/texte
17 *
18 * @package SPIP\Textwheel\Texte
19 **/
20
21if (!defined('_ECRIRE_INC_VERSION')) {
22        return;
23}
24
25include_spip('inc/texte_mini');
26include_spip('inc/lien');
27
28include_spip('inc/textwheel');
29
30
31defined('_AUTOBR') || define('_AUTOBR', "<br class='autobr' />");
32define('_AUTOBR_IGNORER', _AUTOBR ? "<!-- ig br -->" : "");
33
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();
36if (!isset($GLOBALS['toujours_paragrapher'])) {
37        $GLOBALS['toujours_paragrapher'] = true;
38}
39
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
43//
44if (!isset($GLOBALS['class_spip'])) {
45        $GLOBALS['class_spip'] = '';
46}
47if (!isset($GLOBALS['class_spip_plus'])) {
48        $GLOBALS['class_spip_plus'] = ' class="spip"';
49}
50
51
52/**
53 * Échapper et affichier joliement les `<script` ...
54 *
55 * @param string $t
56 * @return string
57 */
58function echappe_js($t) {
59        static $wheel = null;
60
61        if (!isset($wheel)) {
62                $wheel = new TextWheel(
63                        SPIPTextWheelRuleset::loader($GLOBALS['spip_wheels']['echappe_js'])
64                );
65        }
66
67        try {
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
72                $t = textebrut($t);
73        }
74
75        return $t;
76}
77
78
79/**
80 * Paragrapher seulement
81 *
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'>`)
84 *
85 * @param string $t
86 *     Le texte
87 * @param null $toujours_paragrapher
88 *     true pour forcer les `<p>` même pour un seul paragraphe
89 * @return string
90 *     Texte paragraphé
91 */
92function paragrapher($t, $toujours_paragrapher = null) {
93        static $wheel = array();
94        if (is_null($toujours_paragrapher)) {
95                $toujours_paragrapher = $GLOBALS['toujours_paragrapher'];
96        }
97
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')
102                ) {
103                        $rule->disabled = true;
104                        $ruleset->addRules(array('toujours-paragrapher' => $rule));
105                }
106                $wheel[$toujours_paragrapher] = new TextWheel($ruleset);
107        }
108
109        try {
110                $t = $wheel[$toujours_paragrapher]->text($t);
111        } catch (Exception $e) {
112                erreur_squelette($e->getMessage());
113        }
114
115        return $t;
116}
117
118/**
119 * Empêcher l'exécution de code PHP et JS
120 *
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.
123 *
124 * De la même manière, la fonction empêche l'exécution de JS mais selon le mode
125 * de protection déclaré par la globale filtrer_javascript :
126 * - -1 : protection dans l'espace privé et public
127 * - 0  : protection dans l'espace public
128 * - 1  : aucune protection
129 *
130 * Il ne faut pas désactiver globalement la fonction dans l'espace privé car elle protège
131 * aussi les balises des squelettes qui ne passent pas forcement par propre ou typo après
132 * si elles sont appelées en direct
133 *
134 * @param string $arg
135 *     Code à protéger
136 * @return string
137 *     Code protégé
138 **/
139function interdire_scripts($arg) {
140        // on memorise le resultat sur les arguments non triviaux
141        static $dejavu = array();
142        static $wheel = array();
143
144        // Attention, si ce n'est pas une chaine, laisser intact
145        if (!$arg or !is_string($arg) or !strstr($arg, '<')) {
146                return $arg;
147        }
148        if (isset($dejavu[$GLOBALS['filtrer_javascript']][$arg])) {
149                return $dejavu[$GLOBALS['filtrer_javascript']][$arg];
150        }
151
152        if (!isset($wheel[$GLOBALS['filtrer_javascript']])) {
153                $ruleset = SPIPTextWheelRuleset::loader(
154                        $GLOBALS['spip_wheels']['interdire_scripts']
155                );
156                // Pour le js, trois modes : parano (-1), prive (0), ok (1)
157                // desactiver la regle echappe-js si besoin
158                if ($GLOBALS['filtrer_javascript'] == 1
159                        or ($GLOBALS['filtrer_javascript'] == 0 and !test_espace_prive())
160                ) {
161                        $ruleset->addRules(array('securite-js' => array('disabled' => true)));
162                }
163                $wheel[$GLOBALS['filtrer_javascript']] = new TextWheel($ruleset);
164        }
165
166        try {
167                $t = $wheel[$GLOBALS['filtrer_javascript']]->text($arg);
168        } catch (Exception $e) {
169                erreur_squelette($e->getMessage());
170                // sanitizer le contenu methode brute, puisqu'on a pas fait mieux
171                $t = textebrut($arg);
172        }
173
174        // Reinserer les echappements des modeles
175        if (defined('_PROTEGE_JS_MODELES')) {
176                $t = echappe_retour($t, "javascript" . _PROTEGE_JS_MODELES);
177        }
178        if (defined('_PROTEGE_PHP_MODELES')) {
179                $t = echappe_retour($t, "php" . _PROTEGE_PHP_MODELES);
180        }
181
182        return $dejavu[$GLOBALS['filtrer_javascript']][$arg] = $t;
183}
184
185
186/**
187 * Applique la typographie générale
188 *
189 * Effectue un traitement pour que les textes affichés suivent les règles
190 * de typographie. Fait une protection préalable des balises HTML et SPIP.
191 * Transforme les balises `<multi>`
192 *
193 * @filtre
194 * @uses traiter_modeles()
195 * @uses corriger_typo()
196 * @uses echapper_faux_tags()
197 * @see  propre()
198 *
199 * @param string $letexte
200 *     Texte d'origine
201 * @param bool $echapper
202 *     Échapper ?
203 * @param string|null $connect
204 *     Nom du connecteur à la bdd
205 * @param array $env
206 *     Environnement (pour les calculs de modèles)
207 * @return string $t
208 *     Texte transformé
209 **/
210function typo($letexte, $echapper = true, $connect = null, $env = array()) {
211        // Plus vite !
212        if (!$letexte) {
213                return $letexte;
214        }
215
216        // les appels directs a cette fonction depuis le php de l'espace
217        // prive etant historiquement ecrit sans argment $connect
218        // on utilise la presence de celui-ci pour distinguer les cas
219        // ou il faut passer interdire_script explicitement
220        // les appels dans les squelettes (de l'espace prive) fournissant un $connect
221        // ne seront pas perturbes
222        $interdire_script = false;
223        if (is_null($connect)) {
224                $connect = '';
225                $interdire_script = true;
226                $env['espace_prive'] = test_espace_prive();
227        }
228
229        $echapper = ($echapper ? 'TYPO' : false);
230        // Echapper les codes <html> etc
231        if ($echapper) {
232                $letexte = echappe_html($letexte, $echapper);
233        }
234
235        //
236        // Installer les modeles, notamment images et documents ;
237        //
238        // NOTE : propre() ne passe pas par ici mais directement par corriger_typo
239        // cf. inc/lien
240
241        $letexte = traiter_modeles($mem = $letexte, false, $echapper ? $echapper : '', $connect, null, $env);
242        if (!$echapper and $letexte != $mem) {
243                $echapper = '';
244        }
245        unset($mem);
246
247        $letexte = corriger_typo($letexte);
248        $letexte = echapper_faux_tags($letexte);
249
250        // reintegrer les echappements
251        if ($echapper !== false) {
252                $letexte = echappe_retour($letexte, $echapper);
253        }
254
255        // Dans les appels directs hors squelette, securiser ici aussi
256        if ($interdire_script) {
257                $letexte = interdire_scripts($letexte);
258        }
259
260        // Dans l'espace prive on se mefie de tout contenu dangereux
261        // https://core.spip.net/issues/3371
262        if (isset($env['espace_prive']) and $env['espace_prive']) {
263                $letexte = echapper_html_suspect($letexte);
264        }
265
266        return $letexte;
267}
268
269// Correcteur typographique
270
271define('_TYPO_PROTEGER', "!':;?~%-");
272define('_TYPO_PROTECTEUR', "\x1\x2\x3\x4\x5\x6\x7\x8");
273
274define('_TYPO_BALISE', ",</?[a-z!][^<>]*[" . preg_quote(_TYPO_PROTEGER) . "][^<>]*>,imsS");
275
276/**
277 * Corrige la typographie
278 *
279 * Applique les corrections typographiques adaptées à la langue indiquée.
280 *
281 * @pipeline_appel pre_typo
282 * @pipeline_appel post_typo
283 * @uses corriger_caracteres()
284 * @uses corriger_caracteres()
285 *
286 * @param string $t Texte
287 * @param string $lang Langue
288 * @return string Texte
289 */
290function corriger_typo($t, $lang = '') {
291        static $typographie = array();
292        // Plus vite !
293        if (!$t) {
294                return $t;
295        }
296
297        $t = pipeline('pre_typo', $t);
298
299        // Caracteres de controle "illegaux"
300        $t = corriger_caracteres($t);
301
302        // Proteger les caracteres typographiques a l'interieur des tags html
303        if (preg_match_all(_TYPO_BALISE, $t, $regs, PREG_SET_ORDER)) {
304                foreach ($regs as $reg) {
305                        $insert = $reg[0];
306                        // hack: on transforme les caracteres a proteger en les remplacant
307                        // par des caracteres "illegaux". (cf corriger_caracteres())
308                        $insert = strtr($insert, _TYPO_PROTEGER, _TYPO_PROTECTEUR);
309                        $t = str_replace($reg[0], $insert, $t);
310                }
311        }
312
313        // trouver les blocs multi et les traiter a part
314        $t = extraire_multi($e = $t, $lang, true);
315        $e = ($e === $t);
316
317        // Charger & appliquer les fonctions de typographie
318        $idxl = "$lang:" . (isset($GLOBALS['lang_objet']) ? $GLOBALS['lang_objet'] : $GLOBALS['spip_lang']);
319        if (!isset($typographie[$idxl])) {
320                $typographie[$idxl] = charger_fonction(lang_typo($lang), 'typographie');
321        }
322        $t = $typographie[$idxl]($t);
323
324        // Les citations en une autre langue, s'il y a lieu
325        if (!$e) {
326                $t = echappe_retour($t, 'multi');
327        }
328
329        // Retablir les caracteres proteges
330        $t = strtr($t, _TYPO_PROTECTEUR, _TYPO_PROTEGER);
331
332        // pipeline
333        $t = pipeline('post_typo', $t);
334
335        # un message pour abs_url - on est passe en mode texte
336        $GLOBALS['mode_abs_url'] = 'texte';
337
338        return $t;
339}
340
341
342//
343// Tableaux
344//
345
346define('_RACCOURCI_TH_SPAN', '\s*(:?{{[^{}]+}}\s*)?|<');
347
348/**
349 * Traitement des raccourcis de tableaux
350 *
351 * @param string $bloc
352 * @return string
353 */
354function traiter_tableau($bloc) {
355        // id "unique" pour les id du tableau
356        $tabid = substr(md5($bloc), 0, 4);
357
358        // Decouper le tableau en lignes
359        preg_match_all(',([|].*)[|]\n,UmsS', $bloc, $regs, PREG_PATTERN_ORDER);
360        $lignes = array();
361        $debut_table = $summary = '';
362        $l = 0;
363        $numeric = true;
364
365        // Traiter chaque ligne
366        $reg_line1 = ',^(\|(' . _RACCOURCI_TH_SPAN . '))+$,sS';
367        $reg_line_all = ',^(' . _RACCOURCI_TH_SPAN . ')$,sS';
368        $hc = $hl = array();
369        foreach ($regs[1] as $ligne) {
370                $l++;
371
372                // Gestion de la premiere ligne :
373                if ($l == 1) {
374                        // - <caption> et summary dans la premiere ligne :
375                        //   || caption | summary || (|summary est optionnel)
376                        if (preg_match(',^\|\|([^|]*)(\|(.*))?$,sS', rtrim($ligne, '|'), $cap)) {
377                                $cap = array_pad($cap, 4, null);
378                                $l = 0;
379                                if ($caption = trim($cap[1])) {
380                                        $debut_table .= "<caption>" . $caption . "</caption>\n";
381                                }
382                                $summary = ' summary="' . entites_html(trim($cap[3])) . '"';
383                        }
384                        // - <thead> sous la forme |{{titre}}|{{titre}}|
385                        //   Attention thead oblige a avoir tbody
386                        else {
387                                if (preg_match($reg_line1, $ligne, $thead)) {
388                                        preg_match_all('/\|([^|]*)/S', $ligne, $cols);
389                                        $ligne = '';
390                                        $cols = $cols[1];
391                                        $colspan = 1;
392                                        for ($c = count($cols) - 1; $c >= 0; $c--) {
393                                                $attr = '';
394                                                if ($cols[$c] == '<') {
395                                                        $colspan++;
396                                                } else {
397                                                        if ($colspan > 1) {
398                                                                $attr = " colspan='$colspan'";
399                                                                $colspan = 1;
400                                                        }
401                                                        // inutile de garder le strong qui n'a servi que de marqueur
402                                                        $cols[$c] = str_replace(array('{', '}'), '', $cols[$c]);
403                                                        $ligne = "<th id='id{$tabid}_c$c'$attr>$cols[$c]</th>$ligne";
404                                                        $hc[$c] = "id{$tabid}_c$c"; // pour mettre dans les headers des td
405                                                }
406                                        }
407
408                                        $debut_table .= "<thead><tr class='row_first'>" .
409                                                $ligne . "</tr></thead>\n";
410                                        $l = 0;
411                                }
412                        }
413                }
414
415                // Sinon ligne normale
416                if ($l) {
417                        // Gerer les listes a puce dans les cellules
418                        // on declenche simplement sur \n- car il y a les
419                        // -* -# -? -! (qui produisent des -&nbsp;!)
420                        if (strpos($ligne, "\n-") !== false) {
421                                $ligne = traiter_listes($ligne);
422                        }
423
424                        // tout mettre dans un tableau 2d
425                        preg_match_all('/\|([^|]*)/S', $ligne, $cols);
426
427                        // Pas de paragraphes dans les cellules
428                        foreach ($cols[1] as &$col) {
429                                if (strlen($col = trim($col))) {
430                                        $col = preg_replace("/\n{2,}/S", "<br /> <br />", $col);
431                                        if (_AUTOBR) {
432                                                $col = str_replace("\n", _AUTOBR . "\n", $col);
433                                        }
434                                }
435                        }
436
437                        // assembler le tableau
438                        $lignes[] = $cols[1];
439                }
440        }
441
442        // maintenant qu'on a toutes les cellules
443        // on prepare une liste de rowspan par defaut, a partir
444        // du nombre de colonnes dans la premiere ligne.
445        // Reperer egalement les colonnes numeriques pour les cadrer a droite
446        $rowspans = $numeric = array();
447        $n = count($lignes[0]);
448        $k = count($lignes);
449        // distinguer les colonnes numeriques a point ou a virgule,
450        // pour les alignements eventuels sur "," ou "."
451        $numeric_class = array(
452                '.' => 'point',
453                ',' => 'virgule',
454                true => ''
455        );
456        for ($i = 0; $i < $n; $i++) {
457                $align = true;
458                for ($j = 0; $j < $k; $j++) {
459                        $rowspans[$j][$i] = 1;
460                        if ($align and preg_match('/^[{+-]*(?:\s|\d)*([.,]?)\d*[}]*$/', trim($lignes[$j][$i]), $r)) {
461                                if ($r[1]) {
462                                        $align = $r[1];
463                                }
464                        } else {
465                                $align = '';
466                        }
467                }
468                $numeric[$i] = $align ? (" class='numeric " . $numeric_class[$align] . "'") : '';
469        }
470        for ($j = 0; $j < $k; $j++) {
471                if (preg_match($reg_line_all, $lignes[$j][0])) {
472                        $hl[$j] = "id{$tabid}_l$j"; // pour mettre dans les headers des td
473                } else {
474                        unset($hl[0]);
475                }
476        }
477        if (!isset($hl[0])) {
478                $hl = array();
479        } // toute la colonne ou rien
480
481        // et on parcourt le tableau a l'envers pour ramasser les
482        // colspan et rowspan en passant
483        $html = '';
484
485        for ($l = count($lignes) - 1; $l >= 0; $l--) {
486                $cols = $lignes[$l];
487                $colspan = 1;
488                $ligne = '';
489
490                for ($c = count($cols) - 1; $c >= 0; $c--) {
491                        $attr = $numeric[$c];
492                        $cell = trim($cols[$c]);
493                        if ($cell == '<') {
494                                $colspan++;
495
496                        } elseif ($cell == '^') {
497                                $rowspans[$l - 1][$c] += $rowspans[$l][$c];
498
499                        } else {
500                                if ($colspan > 1) {
501                                        $attr .= " colspan='$colspan'";
502                                        $colspan = 1;
503                                }
504                                if (($x = $rowspans[$l][$c]) > 1) {
505                                        $attr .= " rowspan='$x'";
506                                }
507                                $b = ($c == 0 and isset($hl[$l])) ? 'th' : 'td';
508                                $h = (isset($hc[$c]) ? $hc[$c] : '') . ' ' . (($b == 'td' and isset($hl[$l])) ? $hl[$l] : '');
509                                if ($h = trim($h)) {
510                                        $attr .= " headers='$h'";
511                                }
512                                // inutile de garder le strong qui n'a servi que de marqueur
513                                if ($b == 'th') {
514                                        $attr .= " id='" . $hl[$l] . "'";
515                                        $cols[$c] = str_replace(array('{', '}'), '', $cols[$c]);
516                                }
517                                $ligne = "\n<$b" . $attr . '>' . $cols[$c] . "</$b>" . $ligne;
518                        }
519                }
520
521                // ligne complete
522                $class = alterner($l + 1, 'odd', 'even');
523                $html = "<tr class='row_$class $class'>$ligne</tr>\n$html";
524        }
525
526        if(html5_permis()) $summary="";
527        return "\n\n<table" . $GLOBALS['class_spip_plus'] . $summary . ">\n"
528        . $debut_table
529        . "<tbody>\n"
530        . $html
531        . "</tbody>\n"
532        . "</table>\n\n";
533}
534
535
536/**
537 * Traitement des listes
538 *
539 * On utilise la wheel correspondante
540 *
541 * @param string $t
542 * @return string
543 */
544function traiter_listes($t) {
545        static $wheel = null;
546
547        if (!isset($wheel)) {
548                $wheel = new TextWheel(
549                        SPIPTextWheelRuleset::loader($GLOBALS['spip_wheels']['listes'])
550                );
551        }
552
553        try {
554                $t = $wheel->text($t);
555        } catch (Exception $e) {
556                erreur_squelette($e->getMessage());
557        }
558
559        return $t;
560}
561
562
563// Ces deux constantes permettent de proteger certains caracteres
564// en les remplacanat par des caracteres "illegaux". (cf corriger_caracteres)
565
566define('_RACCOURCI_PROTEGER', "{}_-");
567define('_RACCOURCI_PROTECTEUR', "\x1\x2\x3\x4");
568
569define('_RACCOURCI_BALISE', ",</?[a-z!][^<>]*[" . preg_quote(_RACCOURCI_PROTEGER) . "][^<>]*>,imsS");
570
571/**
572 * mais d'abord, une callback de reconfiguration des raccourcis
573 * a partir de globales (est-ce old-style ? on conserve quand meme
574 * par souci de compat ascendante)
575 *
576 * @param $ruleset
577 * @return string
578 */
579function personnaliser_raccourcis(&$ruleset) {
580        if ($ruleset) {
581                if (isset($GLOBALS['debut_intertitre']) and $rule = $ruleset->getRule('intertitres')) {
582                        $rule->replace[0] = preg_replace(',<[^>]*>,Uims', $GLOBALS['debut_intertitre'], $rule->replace[0]);
583                        $rule->replace[1] = preg_replace(',<[^>]*>,Uims', $GLOBALS['fin_intertitre'], $rule->replace[1]);
584                        $ruleset->addRules(array('intertitres' => $rule));
585                }
586                if (isset($GLOBALS['debut_gras']) and $rule = $ruleset->getRule('gras')) {
587                        $rule->replace[0] = preg_replace(',<[^>]*>,Uims', $GLOBALS['debut_gras'], $rule->replace[0]);
588                        $rule->replace[1] = preg_replace(',<[^>]*>,Uims', $GLOBALS['fin_gras'], $rule->replace[1]);
589                        $ruleset->addRules(array('gras' => $rule));
590                }
591                if (isset($GLOBALS['debut_italique']) and $rule = $ruleset->getRule('italiques')) {
592                        $rule->replace[0] = preg_replace(',<[^>]*>,Uims', $GLOBALS['debut_italique'], $rule->replace[0]);
593                        $rule->replace[1] = preg_replace(',<[^>]*>,Uims', $GLOBALS['fin_italique'], $rule->replace[1]);
594                        $ruleset->addRules(array('italiques' => $rule));
595                }
596                if (isset($GLOBALS['ligne_horizontale']) and $rule = $ruleset->getRule('ligne-horizontale')) {
597                        $rule->replace = preg_replace(',<[^>]*>,Uims', $GLOBALS['ligne_horizontale'], $rule->replace);
598                        $ruleset->addRules(array('ligne-horizontale' => $rule));
599                }
600                if (isset($GLOBALS['toujours_paragrapher']) and !$GLOBALS['toujours_paragrapher']
601                        and $rule = $ruleset->getRule('toujours-paragrapher')
602                ) {
603                        $rule->disabled = true;
604                        $ruleset->addRules(array('toujours-paragrapher' => $rule));
605                }
606        }
607
608        // retourner une signature de l'etat de la fonction, pour la mise en cache
609        return implode("/",
610                array(
611                        isset($GLOBALS['debut_intertitre']) ? $GLOBALS['debut_intertitre'] : "",
612                        isset($GLOBALS['debut_gras']) ? $GLOBALS['debut_gras'] : "",
613                        isset($GLOBALS['debut_italique']) ? $GLOBALS['debut_italique'] : "",
614                        isset($GLOBALS['ligne_horizontale']) ? $GLOBALS['ligne_horizontale'] : "",
615                        isset($GLOBALS['toujours_paragrapher']) ? $GLOBALS['toujours_paragrapher'] : 1,
616                )
617        );
618}
619
620/**
621 * Nettoie un texte, traite les raccourcis autre qu'URL, la typo, etc.
622 *
623 * @pipeline_appel pre_propre
624 * @pipeline_appel post_propre
625 *
626 * @param string $t
627 * @param bool $show_autobr
628 * @return string
629 */
630function traiter_raccourcis($t, $show_autobr = false) {
631        static $wheel = array(), $notes;
632        static $img_br_auto, $img_br_manuel, $img_br_no;
633        global $spip_lang, $spip_lang_rtl;
634
635        // hack1: respecter le tag ignore br
636        if (_AUTOBR_IGNORER
637                and strncmp($t, _AUTOBR_IGNORER, strlen(_AUTOBR_IGNORER)) == 0
638        ) {
639                $ignorer_autobr = true;
640                $t = substr($t, strlen(_AUTOBR_IGNORER));
641        } else {
642                $ignorer_autobr = false;
643        }
644
645        // Appeler les fonctions de pre_traitement
646        $t = pipeline('pre_propre', $t);
647
648        $key = "";
649        $key = personnaliser_raccourcis($key);
650        if (!isset($wheel[$key])) {
651                $ruleset = SPIPTextWheelRuleset::loader(
652                        $GLOBALS['spip_wheels']['raccourcis'], 'personnaliser_raccourcis'
653                );
654                $wheel[$key] = new TextWheel($ruleset);
655
656                if (_request('var_mode') == 'wheel'
657                        and autoriser('debug')
658                ) {
659                        $f = $wheel->compile();
660                        echo "<pre>\n" . spip_htmlspecialchars($f) . "</pre>\n";
661                        exit;
662                }
663                $notes = charger_fonction('notes', 'inc');
664        }
665
666        // Gerer les notes (ne passe pas dans le pipeline)
667        list($t, $mes_notes) = $notes($t);
668
669        try {
670                $t = $wheel[$key]->text($t);
671        } catch (Exception $e) {
672                erreur_squelette($e->getMessage());
673        }
674
675        // Appeler les fonctions de post-traitement
676        $t = pipeline('post_propre', $t);
677
678        if ($mes_notes) {
679                $notes($mes_notes, 'traiter', $ignorer_autobr);
680        }
681
682        if (_AUTOBR and !function_exists('aide_lang_dir')) {
683                include_spip('inc/lang');
684        }
685
686        // hack2: wrap des autobr dans l'espace prive, pour affichage css
687        // car en css on ne sait pas styler l'element BR
688        if ($ignorer_autobr and _AUTOBR) {
689                if (is_null($img_br_no)) {
690                        $img_br_no = ($show_autobr ? http_img_pack("br-no" . aide_lang_dir($spip_lang, $spip_lang_rtl) . "-10.png",
691                                _T("tw:retour_ligne_ignore"), "class='br-no'", _T("tw:retour_ligne_ignore")) : "");
692                }
693                $t = str_replace(_AUTOBR, $img_br_no, $t);
694        }
695        if ($show_autobr and _AUTOBR) {
696                if (is_null($img_br_manuel)) {
697                        $img_br_manuel = http_img_pack("br-manuel" . aide_lang_dir($spip_lang, $spip_lang_rtl) . "-10.png",
698                                _T("tw:retour_ligne_manuel"), "class='br-manuel'", _T("tw:retour_ligne_manuel"));
699                }
700                if (is_null($img_br_auto)) {
701                        $img_br_auto = http_img_pack("br-auto" . aide_lang_dir($spip_lang, $spip_lang_rtl) . "-10.png",
702                                _T("tw:retour_ligne_auto"), "class='br-auto'", _T("tw:retour_ligne_auto"));
703                }
704                if (false !== strpos(strtolower($t), '<br')) {
705                        $t = preg_replace("/<br\b.*>/UiS", "$img_br_manuel\\0", $t);
706                        $t = str_replace($img_br_manuel . _AUTOBR, $img_br_auto . _AUTOBR, $t);
707                }
708        }
709
710        return $t;
711}
712
713
714/**
715 * Transforme les raccourcis SPIP, liens et modèles d'un texte en code HTML
716 *
717 * Filtre à appliquer aux champs du type `#TEXTE*`
718 *
719 * @filtre
720 * @uses echappe_html()
721 * @uses expanser_liens()
722 * @uses traiter_raccourcis()
723 * @uses echappe_retour_modeles()
724 * @see  typo()
725 *
726 * @param string $t
727 *     Texte avec des raccourcis SPIP
728 * @param string|null $connect
729 *     Nom du connecteur à la bdd
730 * @param array $env
731 *     Environnement (pour les calculs de modèles)
732 * @return string $t
733 *     Texte transformé
734 **/
735function propre($t, $connect = null, $env = array()) {
736        // les appels directs a cette fonction depuis le php de l'espace
737        // prive etant historiquement ecrits sans argment $connect
738        // on utilise la presence de celui-ci pour distinguer les cas
739        // ou il faut passer interdire_script explicitement
740        // les appels dans les squelettes (de l'espace prive) fournissant un $connect
741        // ne seront pas perturbes
742        $interdire_script = false;
743        if (is_null($connect) and test_espace_prive()) {
744                $connect = '';
745                $interdire_script = true;
746        }
747
748        if (!$t) {
749                return strval($t);
750        }
751
752        $t = pipeline('pre_echappe_html_propre', $t);
753
754        $t = echappe_html($t);
755        $t = expanser_liens($t, $connect, $env);
756
757        $t = traiter_raccourcis($t, (isset($env['wysiwyg']) and $env['wysiwyg']) ? true : false);
758        $t = echappe_retour_modeles($t, $interdire_script);
759
760        $t = pipeline('post_echappe_html_propre', $t);
761
762        return $t;
763}
Note: See TracBrowser for help on using the repository browser.