Newer
Older
//
// 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
define('_RACCOURCI_LIEN', ",\[([^][]*)->(>?)([^]]*)\],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) {
$inserts[++$i] = traiter_raccourci_lien($regs, $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]
// $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
// A terme, il faudrait tenir compte de $connect
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;
# Penser au cas [<imgXX|right>->URL]
# ceci s'execute heureusement avant les tableaux et leur "|".
# Attention, le texte initial est deja echappe mais pas forcement
# celui retourne par calculer_url.
$texte = typo($texte, true, $connect);
return "<a href=\"$lien\" class=\"$class\"$lang>$texte</a>";
}
// 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[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;
}
// 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);
$letexte = traiter_poesie($letexte);
// Harmoniser les retours chariot
$letexte = preg_replace(",\r\n?,S", "\n", $letexte);
// Recuperer les paragraphes HTML
$letexte = preg_replace(",<p[>[:space:]],iS", "\n\n\\0", $letexte);
$letexte = preg_replace(",</p[>[:space:]],iS", "\\0\n\n", $letexte);
$letexte = traiter_raccourci_glossaire($letexte);
$letexte = traiter_raccourci_ancre($letexte);
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
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
// 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)));