Newer
Older
$letexte);
// Supprimer les <p xx></p> vides
$letexte = preg_replace(',<p\s[^>]*></p>\s*,iS', '',
// Renommer les paragraphes normaux
$letexte);
}
return $letexte;
}
//
// Raccourcis ancre [#ancre<-]
//
define('_RACCOURCI_ANCRE', "|\[#?([^][]*)<-\]|S");
function traiter_raccourci_ancre($letexte)
{
if (preg_match_all(_RACCOURCI_ANCRE, $letexte, $m, PREG_SET_ORDER))
foreach ($m as $regs)
$letexte = str_replace($regs[0],
'<a name="'.entites_html($regs[1]).'"></a>', $letexte);
return $letexte;
}
//
// Raccourcis automatiques [?SPIP] vers un glossaire
//
define('_RACCOURCI_GLOSSAIRE', "|\[\?+\s*([^][<>]+)\]|S");
function traiter_raccourci_glossaire($letexte)
{
static $glosateur = NULL, $subst = NULL;
if ($glosateur === NULL) {
$glosateur = tester_variable('url_glossaire_externe',
"http://@lang@.wikipedia.org/wiki/");
$subst = strpos($glosateur,"%s") !== false;
}
if (empty($glosateur)
OR !preg_match_all(_RACCOURCI_GLOSSAIRE, $letexte, $m, PREG_SET_ORDER))
return $letexte;
$glosateur = str_replace("@lang@", $GLOBALS['spip_lang'], $glosateur);
foreach ($m as $regs) {
list($tout, $terme) = $regs;
// Eviter les cas particulier genre "[?!?]"
if (preg_match(',^(.*\w\S*)\s*$,', $terme, $r)) {
$terme = $r[1];
$_terme = preg_replace(',\s+,', '_', $terme);
// faire sauter l'eventuelle partie "|bulle d'aide" du lien
// cf. http://fr.wikipedia.org/wiki/Wikip%C3%A9dia:Conventions_sur_les_titres
$_terme = preg_replace(',[|].*,', '', $_terme);
if ($subst)
$url = str_replace("%s", rawurlencode($_terme), $glosateur);
else $url = $glosateur. $_terme;
list($terme, $bulle, $hlang) = traiter_raccourci_lien_atts($terme);
$url = traiter_raccourci_lien_lang($url, 'spip_glossaire', $terme, $hlang, '', $bulle);
$letexte = str_replace($tout, $url, $letexte);
}
}
return $letexte;
}
//
// Raccourcis liens [xxx->url]
// Note : complique car c'est ici qu'on applique typo(),
// et en plus on veut pouvoir les passer en pipeline
//
// Regexp des raccouris, aussi utilisee pour la fusion de sauvegarde Spip
// Laisser passer des paires de crochets pour la balise multi
// mais refuser plus d'imbrications ou de mauvaises imbrications
// sinon les crochets ne peuvent plus servir qu'a ce type de raccourci
define('_RACCOURCI_LIEN', ",\[([^][]*?([[]\w*[]][^][]*)*)->(>?)([^]]*)\],msS");
function expanser_liens($letexte, $connect='')
{
$inserts = array();
if (preg_match_all(_RACCOURCI_LIEN, $letexte, $matches, PREG_SET_ORDER)) {
$i = 0;
foreach ($matches as $regs) {
$n = count($regs);
list($texte, $bulle, $hlang) = traiter_raccourci_lien_atts($regs[1]);
list ($lien, $class, $texte, $lang) =
calculer_url($regs[$n-1], $texte, 'tout', $connect);
$inserts[++$i] = traiter_raccourci_lien_lang($lien, $class, $texte, $hlang, $lang, $bulle, $connect);
$letexte = str_replace($regs[0], "@@SPIP_ECHAPPE_LIEN_$i@@",
$letexte);
}
}
$letexte = corriger_typo(traiter_modeles($letexte, false, false, $connect));
foreach ($inserts as $i => $insert) {
$letexte = str_replace("@@SPIP_ECHAPPE_LIEN_$i@@", $insert, $letexte);
}
return $letexte;
}
/*
// Inserer un lien a partir du preg_match du raccourci [xx->url]
// Le preg-match a change, cette fonction est inutilisable
// $regs:
// 0=>tout le raccourci
// 1=>texte (ou texte|hreflang ou texte|bulle ou texte|bulle{hreflang})
// 2=>double fleche (historiquement, liens ouvrants)
// 3=>url
Christian Lefebvre
a validé
// http://doc.spip.org/@traiter_raccourci_lien
function traiter_raccourci_lien($regs, $connect='') {
list(,$texte, ,$url) = $regs;
list($texte, $bulle, $hlang) = traiter_raccourci_lien_atts($texte);
list ($lien, $class, $texte, $lang) =
calculer_url($url, $texte, 'tout', $connect);
return traiter_raccourci_lien_lang($lien, $class, $texte, $hlang, $lang, $bulle, $connect);
*/
function traiter_raccourci_lien_lang($lien, $class, $texte, $hlang, $lang, $bulle, $connect='')
// Si l'objet n'est pas de la langue courante, on ajoute hreflang
if (!$hlang AND $lang!=$GLOBALS['spip_lang'])
$hlang = $lang;
$lang = ($hlang ? ' hreflang="'.$hlang.'"' : '') . $bulle;
# ceci s'execute heureusement avant les tableaux et leur "|".
# Attention, le texte initial est deja echappe mais pas forcement
# celui retourne par calculer_url.
# Penser au cas [<imgXX|right>->URL], qui exige typo('<a>...</a>')
return typo('<a href="'.$lien
. ($class ? '" class="'.$class : '')
. '"'.$lang.'>'
. $texte.'</a>', true, $connect);
}
// Repere dans la partie texte d'un raccourci [texte->...]
// la langue et la bulle eventuelles
function traiter_raccourci_lien_atts($texte) {
$bulle = $hlang = '';
// title et hreflang donnes par le raccourci ?
if (preg_match(',^(.*?)([|]([^<>]*?))?([{]([a-z_]+)[}])?$,', $texte, $m)) {
// |infobulle ?
$bulle = ' title="'.texte_backend($m[3]).'"';
// si c'est un code de langue connu, on met un hreflang
if (traduire_nom_langue($m[5]) <> $m[5]) {
$hlang = $m[5];
}
// sinon c'est un italique
else {
$m[1] .= $m[4];
}
// S'il n'y a pas de hreflang sous la forme {}, ce qui suit le |
// est peut-etre une langue
} else if (preg_match(',^[a-z_]+$,', $m[3])) {
// si c'est un code de langue connu, on met un hreflang
// mais on laisse le title (c'est arbitraire tout ca...)
if (traduire_nom_langue($m[3]) <> $m[3]) {
$hlang = $m[3];
}
}
}
$texte = $m[1];
return array($texte, $bulle, $hlang);
}
// Fonction pour les champs chapo commencant par =, redirection qui peut etre:
// 1. un raccourci Spip habituel (premier If) [texte->TYPEnnn]
// 2. un ultra raccourci TYPEnnn voire nnn (article) (deuxieme If)
// 3. une URL std
// renvoie une tableau structure comme ci-dessus mais sans calcul d'URL
// (cf fusion de sauvegardes)
define('_RACCOURCI_CHAPO', ',^(\W*)(\W*)(\w*\d+([?#].*)?)$,');
function chapo_redirige($chapo, $url=false)
{
if (!preg_match(_RACCOURCI_LIEN, $chapo, $m))
if (!preg_match(_RACCOURCI_CHAPO, $chapo, $m))
return $chapo;
return !$url ? $m[3] : calculer_url($m[3]);
}
function chapo_redirigetil($chapo) { return $chapo && $chapo[0] == '=';}
function traiter_poesie($letexte)
{
if (preg_match_all(",<(poesie|poetry)>(.*)<\/(poesie|poetry)>,UimsS",
$letexte, $regs, PREG_SET_ORDER)) {
foreach ($regs as $reg) {
$lecode = preg_replace(",\r\n?,S", "\n", $reg[2]);
$lecode = preg_replace("/\n[\s]*\n/", "\n \n",$lecode);
$lecode = "<blockquote class=\"spip_poesie\">\n<div>".preg_replace("/\n+/", "</div>\n<div>", trim($lecode))."</div>\n</blockquote>\n\n";
$letexte = str_replace($reg[0], $lecode, $letexte);
}
}
return $letexte;
}
// callback pour la fonction traiter_raccourci_liens()
function autoliens_callback($r) {
Fil
a validé
if (strlen($l = $r[1])) {
if (preg_match(',^(http:/*),S', $l, $m))
$l = substr($l, strlen($m[1]));
if (preg_match(
'/^(?:[^\W_]((?:[^\W_]|-){0,61}[^\W_])?\.)+[a-zA-Z]{2,6}\b/S', $l)) {
$l = inserer_attribut(expanser_liens('[->http://'.$l.']'),
'rel', 'nofollow');
// si le texte ne contanait pas le 'http:' on le supprime aussi
Fil
a validé
if (!$m)
$l = str_replace('>http://', '>', $l);
return $l;
}
}
return $r[0];
}
// extraire les liens ecrits en mode texte brut
function traiter_raccourci_liens($texte) {
return preg_replace_callback(
',\[[^\[\]]*->.*?\]|<[^<>]*>|((http:|www\.)[^"\'\s\[\]]+),S',
'autoliens_callback', $texte);
return $texte;
}
// Harmonise les retours chariots et mange les paragraphes html
function traiter_retours_chariots($letexte) {
$letexte = preg_replace(",\r\n?,S", "\n", $letexte);
$letexte = preg_replace(",<p[>[:space:]],iS", "\n\n\\0", $letexte);
$letexte = preg_replace(",</p[>[:space:]],iS", "\\0\n\n", $letexte);
return $letexte;
}
// Nettoie un texte, traite les raccourcis autre qu'URL, la typo, etc.
// http://doc.spip.org/@traiter_raccourcis
function traiter_raccourcis($letexte) {
// Appeler les fonctions de pre_traitement
$letexte = pipeline('pre_propre', $letexte);
// Gerer les notes (ne passe pas dans le pipeline)
list($letexte, $mes_notes) = traite_raccourci_notes($letexte);
// A present on introduit des attributs class_spip*
// Init de leur valeur et connexes au premier appel
// Tableaux
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
// ne pas oublier les tableaux au debut ou a la fin du texte
$letexte = preg_replace(",^\n?[|],S", "\n\n|", $letexte);
$letexte = preg_replace(",\n\n+[|],S", "\n\n\n\n|", $letexte);
$letexte = preg_replace(",[|](\n\n+|\n?$),S", "|\n\n\n\n", $letexte);
if (preg_match_all(',[^|](\n[|].*[|]\n)[^|],UmsS', $letexte,
$regs, PREG_SET_ORDER))
foreach ($regs as $tab) {
$letexte = str_replace($tab[1], traiter_tableau($tab[1]), $letexte);
}
$letexte = "\n".trim($letexte);
// les listes
if (strpos($letexte,"\n-*")!==false OR strpos($letexte,"\n-#")!==false)
$letexte = traiter_listes($letexte);
// Proteger les caracteres actifs a l'interieur des tags html
$protege = "{}_-";
$illegal = "\x1\x2\x3\x4";
if (preg_match_all(",</?[a-z!][^<>]*[".preg_quote($protege)."][^<>]*>,imsS",
$letexte, $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, $protege, $illegal);
$letexte = str_replace($reg[0], $insert, $letexte);
}
}
// autres raccourcis
$letexte = preg_replace($remplace[0], $remplace[1], $letexte);
$letexte = preg_replace('@^\n<br />@S', '', $letexte);
// Retablir les caracteres proteges
$letexte = strtr($letexte, $illegal, $protege);
// Fermer les paragraphes ; mais ne pas en creer si un seul
$letexte = paragrapher($letexte, $GLOBALS['toujours_paragrapher']);
// Appeler les fonctions de post-traitement
$letexte = pipeline('post_propre', $letexte);
if ($mes_notes) traiter_les_notes($mes_notes);
return $letexte;
}
//
// Notes de bas de page
//
function traite_raccourci_notes($letexte)
{
global $compt_note, $marqueur_notes, $les_notes;
global $ouvre_ref, $ferme_ref, $ouvre_note, $ferme_note; #static ok
static $notes_vues = NULL;
if ($notes_vues === NULL) {
$ouvre_ref = tester_variable('ouvre_ref', ' [');
$ferme_ref = tester_variable('ferme_ref', ']');
$ouvre_note = tester_variable('ouvre_note', '[');
$ferme_note = tester_variable('ferme_note', '] ');
$les_notes = tester_variable('les_notes', '');
$compt_note = tester_variable('compt_note', 0);
$notes_vues === array();
}
$mes_notes = '';
$regexp = ', *\[\[(.*?)\]\],msS';
if (preg_match_all($regexp, $letexte, $matches, PREG_SET_ORDER))
foreach ($matches as $regs) {
if (preg_match(",^<([^>'\"]*)>,", ltrim($note_texte), $r)
AND strpos($note_texte, '</' . $r[1] .'>') === false) {
$num_note = $r[1];
$note_texte = substr_replace(ltrim($note_texte), '', 0, strlen($r[0]));
if ($marqueur_notes) // quand il y a plusieurs series
// de notes sur une meme page
$mn = $marqueur_notes.'-';
$ancre = $mn.rawurlencode($num_note);
// ne mettre qu'une ancre par appel de note (XHTML)
if (!$notes_vues[$ancre]++)
$name_id = " name=\"nh$ancre\" id=\"nh$ancre\"";
else
$name_id = "";
$lien = "<a href=\"#nb$ancre\"$name_id class=\"spip_note\" rel=\"footnote\">";
// creer le popup 'title' sur l'appel de note
if ($title = supprimer_tags(propre($note_texte))) {
$title = couper($title,80);
$lien = inserer_attribut($lien, 'title', $title);
$insert = "$ouvre_ref$lien$num_note</a>$ferme_ref";
// on l'echappe
$insert = code_echappement($insert);
$appel = "$ouvre_note<a href=\"#nh$ancre\" name=\"nb$ancre\" class=\"spip_note\" title=\"" . _T('info_notes') . " $ancre\" rev=\"footnote\">$num_note</a>$ferme_note";
// l'ajouter "tel quel" (echappe) dans les notes
if ($mes_notes)
$mes_notes .= "\n\n";
$mes_notes .= code_echappement($appel) . $note_texte;
}
// dans le texte, mettre l'appel de note a la place de la note
$pos = strpos($letexte, $note_source);
$letexte = substr($letexte, 0, $pos) . $insert
. substr($letexte, $pos + strlen($note_source));
Fil
a validé
}
return array($letexte, $mes_notes);
esj
a validé
}
// http://doc.spip.org/@traiter_les_notes
function traiter_les_notes($mes_notes) {
$mes_notes = propre('<p>'.$mes_notes);
if ($GLOBALS['class_spip'])
$mes_notes = str_replace('<p class="spip">', '<p class="spip_note">', $mes_notes);
$GLOBALS['les_notes'] .= $mes_notes;
esj
a validé
}
// Filtre a appliquer aux champs du type #TEXTE*
// http://doc.spip.org/@propre
function propre($t, $connect='') {
return !$t ? '' :
echappe_retour_modeles(
traiter_raccourcis(
expanser_liens(echappe_html($t),$connect)));