"); define('_AUTOBR_IGNORER', _AUTOBR?"":""); // 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 $GLOBALS['spip_raccourcis_typo'] = array(); if (!isset($GLOBALS['toujours_paragrapher'])) $GLOBALS['toujours_paragrapher'] = true; // class_spip : savoir si on veut class="spip" sur p i strong & li // class_spip_plus : class="spip" sur les ul ol h3 hr quote table... // la difference c'est que des css specifiques existent pour les seconds // if (!isset($GLOBALS['class_spip'])) $GLOBALS['class_spip'] = ''; if (!isset($GLOBALS['class_spip_plus'])) $GLOBALS['class_spip_plus'] = ' class="spip"'; /** * echapper les < script ... * * @param string $t * @return string */ function echappe_js($t) { static $wheel = null; if (!isset($wheel)) $wheel = new TextWheel( SPIPTextWheelRuleset::loader($GLOBALS['spip_wheels']['echappe_js']) ); return $wheel->text($t); } /** * paragrapher seulement * * @param string $t * @param null $toujours_paragrapher * @return string */ function paragrapher($t, $toujours_paragrapher = null) { static $wheel = array(); if (is_null($toujours_paragrapher)) $toujours_paragrapher = $GLOBALS['toujours_paragrapher']; if (!isset($wheel[$toujours_paragrapher])) { $ruleset = SPIPTextWheelRuleset::loader($GLOBALS['spip_wheels']['paragrapher']); if (!$toujours_paragrapher AND $rule=$ruleset->getRule('toujours-paragrapher')) { $rule->disabled = true; $ruleset->addRules(array('toujours-paragrapher'=>$rule)); } $wheel[$toujours_paragrapher] = new TextWheel($ruleset); } return $wheel[$toujours_paragrapher]->text($t); } /** * Securite : empecher l'execution de code PHP, en le transformant en joli code * dans l'espace prive, cette fonction est aussi appelee par propre et typo * si elles sont appelees en direct * il ne faut pas desactiver globalement la fonction dans l'espace prive car elle protege * aussi les balises des squelettes qui ne passent pas forcement par propre ou typo apres * * http://code.spip.net/@interdire_scripts * * @param string $arg * @return string */ function interdire_scripts($arg) { // on memorise le resultat sur les arguments non triviaux static $dejavu = array(); static $wheel = array(); // Attention, si ce n'est pas une chaine, laisser intact if (!$arg OR !is_string($arg) OR !strstr($arg, '<')) return $arg; if (isset($dejavu[$GLOBALS['filtrer_javascript']][$arg])) return $dejavu[$GLOBALS['filtrer_javascript']][$arg]; if (!isset($wheel[$GLOBALS['filtrer_javascript']])){ $ruleset = SPIPTextWheelRuleset::loader( $GLOBALS['spip_wheels']['interdire_scripts'] ); // Pour le js, trois modes : parano (-1), prive (0), ok (1) // desactiver la regle echappe-js si besoin if ($GLOBALS['filtrer_javascript']==1 OR ($GLOBALS['filtrer_javascript']==0 AND !test_espace_prive())) $ruleset->addRules (array('securite-js'=>array('disabled'=>true))); $wheel[$GLOBALS['filtrer_javascript']] = new TextWheel($ruleset); } $t = $wheel[$GLOBALS['filtrer_javascript']]->text($arg); // Reinserer les echappements des modeles if (defined('_PROTEGE_JS_MODELES')) $t = echappe_retour($t,"javascript"._PROTEGE_JS_MODELES); if (defined('_PROTEGE_PHP_MODELES')) $t = echappe_retour($t,"php"._PROTEGE_PHP_MODELES); return $dejavu[$GLOBALS['filtrer_javascript']][$arg] = $t; } /** * Typographie generale * avec protection prealable des balises HTML et SPIP * * http://code.spip.net/@typo * * @param string $letexte * @param bool $echapper * @param null $connect * @param array $env * @return string */ function typo($letexte, $echapper=true, $connect=null, $env=array()) { // Plus vite ! if (!$letexte) return $letexte; // les appels directs a cette fonction depuis le php de l'espace // prive etant historiquement ecrit sans argment $connect // on utilise la presence de celui-ci pour distinguer les cas // ou il faut passer interdire_script explicitement // les appels dans les squelettes (de l'espace prive) fournissant un $connect // ne seront pas perturbes $interdire_script = false; if (is_null($connect)){ $connect = ''; $interdire_script = true; } $echapper = ($echapper?'TYPO':false); // Echapper les codes etc if ($echapper) $letexte = echappe_html($letexte, $echapper); // // Installer les modeles, notamment images et documents ; // // NOTE : propre() ne passe pas par ici mais directement par corriger_typo // cf. inc/lien $letexte = traiter_modeles($mem = $letexte, false, $echapper ? $echapper : '', $connect, null, $env); if (!$echapper AND $letexte != $mem) $echapper = ''; unset($mem); $letexte = corriger_typo($letexte); $letexte = echapper_faux_tags($letexte); // reintegrer les echappements if ($echapper!==false) $letexte = echappe_retour($letexte, $echapper); // Dans les appels directs hors squelette, securiser ici aussi if ($interdire_script) $letexte = interdire_scripts($letexte); return $letexte; } // Correcteur typographique define('_TYPO_PROTEGER', "!':;?~%-"); define('_TYPO_PROTECTEUR', "\x1\x2\x3\x4\x5\x6\x7\x8"); define('_TYPO_BALISE', ",?[a-z!][^<>]*[".preg_quote(_TYPO_PROTEGER)."][^<>]*>,imsS"); /** * http://code.spip.net/@corriger_typo * * @param string $t * @param string $lang * @return string */ function corriger_typo($t, $lang='') { static $typographie = array(); // Plus vite ! if (!$t) return $t; $t = pipeline('pre_typo', $t); // Caracteres de controle "illegaux" $t = corriger_caracteres($t); // Proteger les caracteres typographiques a l'interieur des tags html if (preg_match_all(_TYPO_BALISE, $t, $regs, PREG_SET_ORDER)) { foreach ($regs as $reg) { $insert = $reg[0]; // hack: on transforme les caracteres a proteger en les remplacant // par des caracteres "illegaux". (cf corriger_caracteres()) $insert = strtr($insert, _TYPO_PROTEGER, _TYPO_PROTECTEUR); $t = str_replace($reg[0], $insert, $t); } } // trouver les blocs multi et les traiter a part $t = extraire_multi($e = $t, $lang, true); $e = ($e === $t); // Charger & appliquer les fonctions de typographie $idxl = "$lang:" . (isset($GLOBALS['lang_objet'])? $GLOBALS['lang_objet']: $GLOBALS['spip_lang']); if (!isset($typographie[$idxl])) $typographie[$idxl] = charger_fonction(lang_typo($lang), 'typographie'); $t = $typographie[$idxl]($t); // Les citations en une autre langue, s'il y a lieu if (!$e) $t = echappe_retour($t, 'multi'); // Retablir les caracteres proteges $t = strtr($t, _TYPO_PROTECTEUR, _TYPO_PROTEGER); // pipeline $t = pipeline('post_typo', $t); # un message pour abs_url - on est passe en mode texte $GLOBALS['mode_abs_url'] = 'texte'; return $t; } // // Tableaux // define('_RACCOURCI_TH_SPAN', '\s*(:?{{[^{}]+}}\s*)?|<'); /** * http://code.spip.net/@traiter_tableau * * @param sring $bloc * @return string */ function traiter_tableau($bloc) { // id "unique" pour les id du tableau $tabid = substr(md5($bloc),0,4); // Decouper le tableau en lignes preg_match_all(',([|].*)[|]\n,UmsS', $bloc, $regs, PREG_PATTERN_ORDER); $lignes = array(); $debut_table = $summary = ''; $l = 0; $numeric = true; // Traiter chaque ligne $reg_line1 = ',^(\|(' . _RACCOURCI_TH_SPAN . '))+$,sS'; $reg_line_all = ',^(' . _RACCOURCI_TH_SPAN . ')$,sS'; $hc = $hl = array(); foreach ($regs[1] as $ligne) { $l ++; // Gestion de la premiere ligne : if ($l == 1) { // -
\n".spip_htmlspecialchars($f)."\n"; exit; } $notes = charger_fonction('notes', 'inc'); } // Gerer les notes (ne passe pas dans le pipeline) list($t, $mes_notes) = $notes($t); $t = $wheel->text($t); // Appeler les fonctions de post-traitement $t = pipeline('post_propre', $t); if ($mes_notes) $notes($mes_notes,'traiter',$ignorer_autobr); // hack2: wrap des autobr dans l'espace prive, pour affichage css // car en css on ne sait pas styler l'element BR if ($ignorer_autobr AND _AUTOBR) { if (is_null($img_br_no)) $img_br_no = ($show_autobr?http_img_pack("br-no-10.png",_T("tw:retour_ligne_ignore"),"class='br-no'",_T("tw:retour_ligne_ignore")):""); $t = str_replace(_AUTOBR, $img_br_no, $t); } if ($show_autobr AND _AUTOBR) { if (is_null($img_br_manuel)) $img_br_manuel = http_img_pack("br-manuel-10.png",_T("tw:retour_ligne_manuel"),"class='br-manuel'",_T("tw:retour_ligne_manuel")); if (is_null($img_br_auto)) $img_br_auto = http_img_pack("br-auto-10.png",_T("tw:retour_ligne_auto"),"class='br-auto'",_T("tw:retour_ligne_auto")); if (false !== strpos(strtolower($t), '