diff --git a/.gitattributes b/.gitattributes index cc218a41e18841b66c2f1e7fd93ccbd604675f1f..112dc70eef3767bb6e0269cff1f19aaa9bd8958d 100644 --- a/.gitattributes +++ b/.gitattributes @@ -286,6 +286,11 @@ ecrire/safehtml/classes/safehtml.php -text ecrire/safehtml/license.txt -text ecrire/safehtml/readme-SPIP.txt -text ecrire/safehtml/readme.txt -text +plugins/ancres/version.php -text +plugins/podcast_client/podcast_client.php -text +plugins/podcast_client/version.php -text +plugins/revision_nbsp/version.php -text +plugins/smallcaps/version.php -text /puce.gif -text /puce_rtl.gif -text /rien.gif -text diff --git a/ecrire/inc_filtres.php3 b/ecrire/inc_filtres.php3 index bae957dcc76fb3acc728c79b421b59aedfbb5aa8..371c7b8510939a9bfea355f504e51c47359f6212 100644 --- a/ecrire/inc_filtres.php3 +++ b/ecrire/inc_filtres.php3 @@ -373,7 +373,7 @@ function antispam($texte) { // |sinon{rien} : affiche "rien" si la chaine est vide, affiche la chaine si non vide function sinon ($texte, $sinon='') { - if ($texte) + if (strlen($texte)) return $texte; else return $sinon; @@ -1026,24 +1026,6 @@ function extraire_multi ($letexte) { } -// Raccourci ancre [#ancre<-] -function avant_propre_ancres($texte) { - $regexp = "|\[#?([^][]*)<-\]|"; - if (preg_match_all($regexp, $texte, $matches, PREG_SET_ORDER)) - foreach ($matches as $regs) - $texte = str_replace($regs[0], - '<a name="'.entites_html($regs[1]).'"></a>', $texte); - return $texte; -} - -// Raccourci typographique <sc></sc> -function avant_typo_smallcaps($texte) { - $texte = str_replace("<sc>", "<span style=\"font-variant: small-caps\">", $texte); - $texte = str_replace("</sc>", "</span>", $texte); - - return $texte; -} - // // Ce filtre retourne la donnee si c'est la premiere fois qu'il la voit ; // possibilite de gerer differentes "familles" de donnees |unique{famille} diff --git a/ecrire/inc_sites.php3 b/ecrire/inc_sites.php3 index f6ab932da6947162ababcd6c4967c72c5c1fd22f..e44fe5a3117bcf7f8a6c12b134ec0369b9707025 100644 --- a/ecrire/inc_sites.php3 +++ b/ecrire/inc_sites.php3 @@ -243,6 +243,10 @@ function my_strtotime($la_date) { function analyser_site($url) { include_ecrire("inc_filtres.php3"); # pour filtrer_entites() + // Accepter les URLs au format feed:// ou qui ont oublie le http:// + $url = preg_replace(',^feed://,i', 'http://', $url); + if (!preg_match(',^[a-z]+://,i', $url)) $url = 'http://'.$url; + $texte = recuperer_page($url, true); if (!$texte) return false; @@ -261,6 +265,7 @@ function analyser_site($url) { $result['url_site'] = filtrer_entites($regs[1]); else if (preg_match(',<link[^>]*>,Uims', $header, $regs)) $result['url_site'] = filtrer_entites(extraire_attribut($regs[0], 'href')); + $result['url_site'] = url_absolue($result['url_site'], $url); if (preg_match('<(description|tagline)([[:space:]][^>]*)?' .'>(.*)</\1>,Uims', $header, $r)) @@ -290,71 +295,6 @@ function analyser_site($url) { return $result; } -// Inserer les references aux fichiers joints -// presentes sous la forme microformat <a rel="enclosure"> -function traiter_les_enclosures_rss($enclosures,$id_syndic,$le_lien) { - if (!preg_match_all( - ',<a([[:space:]][^>]*)?[[:space:]]rel=[\'"]enclosure[^>]*>,', - $enclosures, $regs, PREG_PATTERN_ORDER)) - return false; - $enclosures = $regs[0]; - - include_ecrire('inc_filtres.php3'); # pour extraire_attribut - - list($id_syndic_article) = spip_fetch_array(spip_query( - "SELECT id_syndic_article FROM spip_syndic_articles - WHERE id_syndic=$id_syndic AND url='".addslashes($le_lien)."'")); - - // Attention si cet article est deja vu, ne pas doubler les references - spip_query("DELETE FROM spip_documents_syndic - WHERE id_syndic_article=$id_syndic_article"); - - // Integrer les enclosures - foreach ($enclosures as $enclosure) { - // href et type sont obligatoires - if ($enc_regs_url = extraire_attribut($enclosure,'href') - AND $enc_regs_type = extraire_attribut($enclosure,'type')) { - - $url = substr(urldecode($enc_regs_url), 0,255); - $url = addslashes(abs_url($url, $le_lien)); - $type = $enc_regs_type; - - // Verifier que le content-type nous convient - list($id_type) = spip_fetch_array(spip_query("SELECT id_type - FROM spip_types_documents WHERE mime_type='$type'")); - if (!$id_type) { - spip_log("enclosure de type inconnu ($type) $url"); - list($id_type) = spip_fetch_array(spip_query("SELECT id_type - FROM spip_types_documents WHERE extension='bin'")); - // si les .bin ne sont pas autorises, on ignore ce document - if (!$id_type) continue; - } - - // length : optionnel (non bloquant) - $taille = intval(extraire_attribut($enclosure, 'length')); - - // Inserer l'enclosure dans la table spip_documents - if ($t = spip_fetch_array(spip_query("SELECT id_document FROM - spip_documents WHERE fichier='$url' AND distant='oui'"))) - $id_document = $t['id_document']; - else { - spip_query("INSERT INTO spip_documents - (id_type, titre, fichier, date, distant, taille, mode) - VALUES ($id_type,'','$url',NOW(),'oui',$taille, 'document')"); - $id_document = spip_insert_id(); - } - - // lier avec l'article syndique - spip_query("INSERT INTO spip_documents_syndic - (id_document, id_syndic, id_syndic_article) - VALUES ($id_document, $id_syndic, $id_syndic_article)"); - - $n++; - } - } - - return $n; #nombre d'enclosures integrees -} // A partir d'un <dc:subject> ou autre essayer de recuperer // le mot et son url ; on cree <a href="url" rel="tag">mot</a> @@ -404,7 +344,7 @@ function ajouter_tags($matches, $item) { // prend un fichier backend et retourne un tableau des items lus, // et une chaine en cas d'erreur -function analyser_backend($rss) { +function analyser_backend($rss, $url_syndic='') { include_ecrire("inc_texte.php3"); # pour couper() include_ecrire("inc_filtres.php3"); # pour filtrer_entites() @@ -420,6 +360,9 @@ function analyser_backend($rss) { } } + // supprimer les commentaires + $rss = preg_replace(',<!--\s+.*\s-->,Ums', '', $rss); + // chercher auteur/lang dans le fil au cas ou les items n'en auraient pas list($header) = preg_split(',<(item|entry)[[:space:]>],', $rss, 2); if (preg_match(',<((dc:)(author|creator))>(.*)</\1>,Uims',$header,$regs)) { @@ -456,6 +399,8 @@ function analyser_backend($rss) { else $data['url'] = false; + $data['url'] = url_absolue($data['url'], $url_syndic); + // Titre (semi-obligatoire) # note http://static.userland.com/gems/backend/gratefulDead.xml # n'a que des enclosures, sans url ni titre... tant pis... @@ -650,12 +595,14 @@ function inserer_article_syndique ($data, $now_id_syndic, $statut, $url_site, $u tags='".addslashes($tags)."' WHERE id_syndic='$now_id_syndic' AND url='".addslashes($le_lien)."'"); - // Inserer les enclosures - if ($GLOBALS['integrer_enclosures'] - AND $data['enclosures']) { - traiter_les_enclosures_rss($data['enclosures'], - $now_id_syndic, $le_lien); - } + // Point d'entree post_syndication + pipeline('post_syndication', + array( + $le_lien, + $now_id_syndic, + $data + ) + ); return $ajout; } @@ -694,7 +641,7 @@ function syndic_a_jour($now_id_syndic, $statut = 'off') { if (!$rss) $articles = _T('avis_echec_syndication_02'); else - $articles = analyser_backend($rss); + $articles = analyser_backend($rss, $url_syndic); // Les enregistrer dans la base if (is_array($articles)) { @@ -962,19 +909,6 @@ function afficher_syndic_articles($titre_table, $requete, $afficher_site = false if (strlen($lesauteurs) > 0) $date = $lesauteurs.', '.$date; $s.= " ($date)"; - // S'il y a des fichiers joints (enclosures), on les affiche ici -/* if (spip_num_rows($q = spip_query("SELECT docs.* FROM spip_documents AS docs, spip_documents_syndic AS lien WHERE lien.id_syndic_article = $id_syndic_article AND lien.id_document = docs.id_document"))) { - include_ecrire('inc_documents.php3'); - while ($t = spip_fetch_array($q)) { - $t = $t['fichier']; - $s .= ' ' . - http_href_img($t, - 'attachment.gif', - 'height="15" width="15" border="0"', - entites_html($t)); - } - } -*/ // Tags : d'un cote les enclosures, de l'autre les liens if($e = afficher_enclosures($row['tags'])) $s .= ' '.$e; diff --git a/ecrire/inc_texte.php3 b/ecrire/inc_texte.php3 index de17870625a6e7c6fc6df50b395129ab72190f43..e16123dfdfe773054436e29c98332b17aaf01c71 100644 --- a/ecrire/inc_texte.php3 +++ b/ecrire/inc_texte.php3 @@ -65,47 +65,6 @@ function nettoyer_chapo($chapo){ return $chapo; } -// points d'entree de pre- et post-traitement pour propre() et typo() -function spip_avant_propre ($letexte) { - $letexte = avant_propre_ancres($letexte); - $letexte = extraire_multi($letexte); - - if (function_exists('avant_propre')) - $letexte = avant_propre($letexte); - - return $letexte; -} - -function spip_apres_propre ($letexte) { - if (function_exists('apres_propre')) - $letexte = apres_propre($letexte); - - return $letexte; -} - -function spip_avant_typo ($letexte) { - $letexte = extraire_multi($letexte); - $letexte = avant_typo_smallcaps($letexte); - - if (function_exists('avant_typo')) - $letexte = avant_typo($letexte); - - return $letexte; -} - -function spip_apres_typo ($letexte) { - - // relecture des - if (!_DIR_RESTREINT AND $GLOBALS['revision_nbsp']) - $letexte = str_replace(' ', - '<span class="spip-nbsp"> </span>', $letexte); - - if (function_exists('apres_typo')) - $letexte = apres_typo($letexte); - - return quote_amp($letexte); -} - // // Mise de cote des echappements @@ -487,8 +446,11 @@ function typo_en($letexte) { function typo_generale($letexte) { global $spip_lang; - // Appeler la fonction de pre-traitement - $letexte = spip_avant_typo ($letexte); + // Appeler les fonctions de pre-traitement + $letexte = pipeline('pre_typo', $letexte); + // old style + if (function_exists('avant_typo')) + $letexte = avant_typo($letexte); // Caracteres de controle "illegaux" $letexte = corriger_caracteres($letexte); @@ -526,8 +488,11 @@ function typo_generale($letexte) { // Retablir les caracteres proteges $letexte = strtr($letexte, $illegal, $protege); - // Appeler la fonction de post-traitement - $letexte = spip_apres_typo ($letexte); + // Appeler les fonctions de post-traitement + $letexte = pipeline('post_typo', $letexte); + // old style + if (function_exists('apres_typo')) + $letexte = apres_typo($letexte); # un message pour abs_url - on est passe en mode texte $GLOBALS['mode_abs_url'] = 'texte'; @@ -847,8 +812,11 @@ function traiter_raccourcis_generale($letexte) { global $ferme_note; global $lang_dir; - // Appeler la fonction de pre_traitement - $letexte = spip_avant_propre ($letexte); + // Appeler les fonctions de pre_traitement + $letexte = pipeline('pre_propre', $letexte); + // old style + if (function_exists('avant_propre')) + $letexte = avant_propre($letexte); // Puce if (!$lang_dir) { @@ -1054,8 +1022,11 @@ function traiter_raccourcis_generale($letexte) { $letexte = preg_replace(',</ul>[[:space:]]*(</p>)?,ms', '</ul>', $letexte); $letexte = preg_replace(',<p class="spip">[[:space:]]*</p>,ms', "\n", $letexte); - // Appeler la fonction de post-traitement - $letexte = spip_apres_propre ($letexte); + // Appeler les fonctions de post-traitement + $letexte = pipeline('post_propre', $letexte); + // old style + if (function_exists('apres_propre')) + $letexte = apres_propre($letexte); return array($letexte,$mes_notes); } diff --git a/ecrire/inc_version.php3 b/ecrire/inc_version.php3 index b3ad7b7a652b639cade74f2bf8eeb52ab9c96d82..12f080f03c3e03b9bbb95452a19c68fe5abf5153 100644 --- a/ecrire/inc_version.php3 +++ b/ecrire/inc_version.php3 @@ -25,6 +25,7 @@ function define_once ($constant, $valeur) { define('_EXTENSION_PHP', '.php3'); # a etendre define('_DIR_RESTREINT_ABS', 'ecrire/'); define('_DIR_RESTREINT', (!@is_dir(_DIR_RESTREINT_ABS) ? "" : _DIR_RESTREINT_ABS)); +define('_DIR_RACINE', _DIR_RESTREINT ? '' : '../'); define('_FILE_OPTIONS', _DIR_RESTREINT . 'mes_options.php3'); define('_FILE_CONNECT_INS', (_DIR_RESTREINT . "inc_connect")); define('_FILE_CONNECT', @@ -171,7 +172,36 @@ spip_register_globals(); +// un pipeline est lie a une action et une valeur +// chaque element du pipeline est autorise a modifier la valeur +// +// le pipeline execute les elements disponibles pour cette action, +// les uns apres les autres, et retourne la valeur finale + +function pipeline($cause, $val) { + global $spip_pipeline, $spip_matrice; + if (!is_array($spip_pipeline[$cause])) return $val; + + foreach ($spip_pipeline[$cause] as $plug) { + + // charger un fichier le cas echeant + if (!function_exists($plug)) { + if ($f = $spip_matrice[$plug]) { + include($f); + $ok = function_exists($plug); + } + if (!$ok) { + spip_log("Erreur - $plug n'est pas definie ($f)"); + return $val; + } + } + // appliquer le filtre + $val = $plug($val); + } + + return $val; +} // // *** Parametrage par defaut de SPIP *** @@ -237,15 +267,6 @@ $mysql_rappel_nom_base = true; // faut-il afficher en rouge les chaines non traduites ? $test_i18n = false; -// faut-il souligner en gris, dans articles.php3, les espaces insecables ? -$activer_revision_nbsp = false; - -// Syndication : faut-il integrer les <enclosure> des flux RSS sous -// forme de documents distants dans la table spip_documents ? -// (par defaut, on se contente de conserver une trace de ces documents -// dans le champ #TAGS de l'article syndique). -$integrer_enclosures = false; - // gestion des extras (voir inc_extra.php3 pour plus d'informations) $champs_extra = false; $champs_extra_proposes = false; @@ -287,6 +308,27 @@ $ortho_servers = array ('http://ortho.spip.net/ortho_serveur.php'); // Produire du TeX ou du MathML ? $traiter_math = 'tex'; + +// +// Plugins +// +// (plus tard on fera une interface graphique qui les liste et permet de +// les activer un par un, dans tel ordre, etc) +# les pipeline standards (traitements derivables aka points d'entree) +$spip_pipeline = array( + 'pre_typo' => array('extraire_multi'), + 'post_typo' => array('quote_amp'), + 'pre_propre' => array('extraire_multi'), + 'post_propre' => array(), + 'post_syndication' => array() +); +# la matrice standard (fichiers definissant les fonctions a inclure) +$spip_matrice = array (); +# les plugins a activer +$plugins = array(); // voir le contenu du repertoire /plugins/ + + + // Masquer les warning error_reporting(E_ALL ^ E_NOTICE); @@ -309,14 +351,27 @@ $extension_squelette = 'html'; // Droits d'acces maximum par defaut @umask(0); + // -// Definition des repertoires standards, _FILE_OPTIONS ayant priorite +// Inclure le fichier ecrire/mes_options.php3 (ou equivalent) // - if (@file_exists(_FILE_OPTIONS)) { include(_FILE_OPTIONS); } +// charger les definitions des plugins +if ($plugins) { + foreach ($plugins as $plug) { + include(_DIR_RACINE.'plugins/'.$plug.'/version.php'); + } +#var_dump($plugins);var_dump($spip_pipeline);var_dump($spip_matrice);exit; +} + +// +// Definition des repertoires standards +// + + // la taille maxi des logos (0 : pas de limite) define_once('_LOGO_MAX_SIZE', 0); # poids en ko define_once('_LOGO_MAX_WIDTH', 0); # largeur en pixels diff --git a/plugins/ancres/version.php b/plugins/ancres/version.php new file mode 100644 index 0000000000000000000000000000000000000000..af60666a6bd83c029a249dc7fb742095f267fdfc --- /dev/null +++ b/plugins/ancres/version.php @@ -0,0 +1,31 @@ +<?php + +/* + * ancres + * + * introduit le raccourci [#ancre<-] pour les ancres + * + * Auteur : collectif + * © 2005 - Distribue sous licence BSD + * + */ + +$nom = 'ancres'; +$version = 0.1; + +// s'inserer dans le pipeline 'avant_propre' @ ecrire/inc_texte.php3 +$GLOBALS['spip_pipeline']['post_propre'][] = 'ancres'; + +// la fonction est tres legere on la definit directement ici +function ancres($texte) { + $regexp = "|\[#?([^][]*)<-\]|"; + if (preg_match_all($regexp, $texte, $matches, PREG_SET_ORDER)) + foreach ($matches as $regs) + $texte = str_replace($regs[0], + '<a name="'.entites_html($regs[1]).'"></a>', $texte); + return $texte; +} + +#$GLOBALS['spip_matrice']['ancres'] = dirname(__FILE__).'/ancres.php'; + +?> diff --git a/plugins/podcast_client/podcast_client.php b/plugins/podcast_client/podcast_client.php new file mode 100644 index 0000000000000000000000000000000000000000..c430ea44a98f5b65ee57390c552bcce7946ff4da --- /dev/null +++ b/plugins/podcast_client/podcast_client.php @@ -0,0 +1,87 @@ +<?php + +// Syndication : ce plugin permet d'integrer les <enclosure> +// des flux RSS sous la forme de documents distants dans la +// table spip_documents +// (par defaut, on se contente de conserver une trace de ces +// documents dans le champ #TAGS de l'article syndique). + + +// +// recupere les donnees du point d'entree 'post_syndication' +// +function podcast_client() { + list($le_lien, $id_syndic, $data) = func_get_arg(0); + traiter_les_enclosures_rss($data['enclosures'],$id_syndic,$le_lien); +} + +// +// Inserer les references aux fichiers joints +// presentes sous la forme microformat <a rel="enclosure"> +// +function traiter_les_enclosures_rss($enclosures,$id_syndic,$le_lien) { + if (!preg_match_all( + ',<a([[:space:]][^>]*)?[[:space:]]rel=[\'"]enclosure[^>]*>,', + $enclosures, $regs, PREG_PATTERN_ORDER)) + return false; + $enclosures = $regs[0]; + include_ecrire('inc_filtres.php3'); # pour extraire_attribut + + list($id_syndic_article) = spip_fetch_array(spip_query( + "SELECT id_syndic_article FROM spip_syndic_articles + WHERE id_syndic=$id_syndic AND url='".addslashes($le_lien)."'")); + + // Attention si cet article est deja vu, ne pas doubler les references + spip_query("DELETE FROM spip_documents_syndic + WHERE id_syndic_article=$id_syndic_article"); + + // Integrer les enclosures + foreach ($enclosures as $enclosure) { + + // href et type sont obligatoires + if ($enc_regs_url = extraire_attribut($enclosure,'href') + AND $enc_regs_type = extraire_attribut($enclosure,'type')) { + + $url = substr(urldecode($enc_regs_url), 0,255); + $url = addslashes(abs_url($url, $le_lien)); + $type = $enc_regs_type; + + // Verifier que le content-type nous convient + list($id_type) = spip_fetch_array(spip_query("SELECT id_type + FROM spip_types_documents WHERE mime_type='$type'")); + if (!$id_type) { + spip_log("podcast_client: enclosure inconnue ($type) $url"); + list($id_type) = spip_fetch_array(spip_query("SELECT id_type + FROM spip_types_documents WHERE extension='bin'")); + // si les .bin ne sont pas autorises, on ignore ce document + if (!$id_type) continue; + } + + // length : optionnel (non bloquant) + $taille = intval(extraire_attribut($enclosure, 'length')); + + // Inserer l'enclosure dans la table spip_documents + if ($t = spip_fetch_array(spip_query("SELECT id_document FROM + spip_documents WHERE fichier='$url' AND distant='oui'"))) + $id_document = $t['id_document']; + else { + spip_query("INSERT INTO spip_documents + (id_type, titre, fichier, date, distant, taille, mode) + VALUES ($id_type,'','$url',NOW(),'oui',$taille, 'document')"); + $id_document = spip_insert_id(); + spip_log("podcast_client: '$url' => id_document=$id_document"); + } + + // lier avec l'article syndique + spip_query("INSERT INTO spip_documents_syndic + (id_document, id_syndic, id_syndic_article) + VALUES ($id_document, $id_syndic, $id_syndic_article)"); + + $n++; + } + } + + return $n; #nombre d'enclosures integrees +} + +?> diff --git a/plugins/podcast_client/version.php b/plugins/podcast_client/version.php new file mode 100644 index 0000000000000000000000000000000000000000..b32d968cc59dfaf9d0f78e706a7ba5a8102a1d78 --- /dev/null +++ b/plugins/podcast_client/version.php @@ -0,0 +1,22 @@ +<?php + +/* + * podcast_client + * + * Client de podcast pour SPIP + * + * Auteur : fil@rezo.net + * © 2005 - Distribue sous licence GNU/GPL + * + * Voir la documentation dans podcast_client.php + * (ou, plus tard, dans documentation.html) + */ + +$nom = 'podcast_client'; +$version = 0.1; + +// s'inserer dans le pipeline 'post_syndication' @ ecrire/inc_sites.php3 +$GLOBALS['spip_pipeline']['post_syndication'][] = 'podcast_client'; +$GLOBALS['spip_matrice']['podcast_client'] = dirname(__FILE__).'/podcast_client.php'; + +?> diff --git a/plugins/revision_nbsp/version.php b/plugins/revision_nbsp/version.php new file mode 100644 index 0000000000000000000000000000000000000000..b8a0610a159357f4c6d9666ee8b5f476e69ea186 --- /dev/null +++ b/plugins/revision_nbsp/version.php @@ -0,0 +1,28 @@ +<?php + +/* + * revision_nbsp + * + * Dans l'espace prive, souligne en grise les espaces insecables + * + * Auteur : fil@rezo.net + * © 2005 - Distribue sous licence GNU/GPL + * + */ + +$nom = 'revision_nbsp'; +$version = 0.1; + +// s'inserer dans le pipeline 'apres_typo' @ ecrire/inc_texte.php3 +if (!_DIR_RESTREINT) + $GLOBALS['spip_pipeline']['post_typo'][] = 'revision_nbsp'; + +// la fonction est tres legere on la definit directement ici +function revision_nbsp($letexte) { + return str_replace(' ', + '<span class="spip-nbsp"> </span>', $letexte); +} + +#$GLOBALS['spip_matrice']['revision_nbsp'] = dirname(__FILE__).'/revision_nbsp.php'; + +?> diff --git a/plugins/smallcaps/version.php b/plugins/smallcaps/version.php new file mode 100644 index 0000000000000000000000000000000000000000..2eee10bb4fee0ad892ba45258b466058f5735c9d --- /dev/null +++ b/plugins/smallcaps/version.php @@ -0,0 +1,31 @@ +<?php + +/* + * smallcaps + * + * introduit le raccourci <sc>...</sc> pour les petites majuscules + * + * Auteur : arno@scarabee.com + * © 2005 - Distribue sous licence GNU/GPL + * + */ + +$nom = 'smallcaps'; +$version = 0.1; + +// s'inserer dans le pipeline 'apres_typo' @ ecrire/inc_texte.php3 +$GLOBALS['spip_pipeline']['post_typo'][] = 'smallcaps'; + +// la fonction est tres legere on la definit directement ici +#$GLOBALS['spip_matrice']['smallcaps'] = dirname(__FILE__).'/smallcaps.php'; + +// Raccourci typographique <sc></sc> +function smallcaps($texte) { + $texte = str_replace("<sc>", + "<span style=\"font-variant: small-caps\">", $texte); + $texte = str_replace("</sc>", "</span>", $texte); + return $texte; +} + + +?>