File "notes.php"
Full path: /home/argothem/www/v4_old/plugins-dist/textwheel/inc/notes.php
File size: 7.39 KB
MIME-type: text/x-php
Charset: utf-8
<?php
/***************************************************************************\
* SPIP, Système de publication pour l'internet *
* *
* Copyright © avec tendresse depuis 2001 *
* Arnaud Martin, Antoine Pitrou, Philippe Rivière, Emmanuel Saint-James *
* *
* Ce programme est un logiciel libre distribué sous licence GNU/GPL. *
* Pour plus de détails voir le fichier COPYING.txt ou l'aide en ligne. *
\***************************************************************************/
/**
* Gestion des notes de bas de page
*
* @package SPIP\Textwheel\Notes
**/
if (!defined('_ECRIRE_INC_VERSION')) {
return;
}
//
// Notes de bas de page
//
if (!defined('_NOTES_OUVRE_REF')) {
define('_NOTES_OUVRE_REF', '<span class="spip_note_ref"> [');
}
if (!defined('_NOTES_FERME_REF')) {
define('_NOTES_FERME_REF', ']</span>');
}
if (!defined('_NOTES_OUVRE_NOTE')) {
define('_NOTES_OUVRE_NOTE', '<span class="spip_note_ref">[');
}
if (!defined('_NOTES_FERME_NOTE')) {
define('_NOTES_FERME_NOTE', '] </span>');
}
if (!defined('_NOTES_RACCOURCI')) {
define('_NOTES_RACCOURCI', ',\[\[(\s*(<([^>\'"]*)>)?(.*?))\]\],msS');
}
/**
* Empile ou dépile des notes de bas de page
*
* Point d'entrée pour la gestion des notes.
*
* @note
* C'est stocké dans la globale `$les_notes`, mais pas besoin de le savoir
* @param bool|string|array $arg
* Argument :
*
* - true : empiler l'etat courant, initialiser un nouvel état
* - false : restaurer l'état précédent, dénonce un état courant perdu
* - chaîne : on y recherche les notes et on les renvoie en tableau
* - tableau : texte de notes à rajouter dans ce qu'on a déjà
*
* Ce dernier cas retourne la composition totale, en particulier,
* envoyer un tableau vide permet de tout récupérer.
* @param string $operation
* En complément du format attendu dans `$arg`, on indique ici
* le type d'oopétation à réaliser (traiter | empiler | depiler |
* sauver_etat | restaurer_etat | contexter_cache)
* @param bool $ignorer_autobr
* True pour ne pas prendre en compte les retours à la ligne comme
* des tags br (mais 2 à la suite font un paragraphe tout de même).
* @return string|array
**/
function inc_notes_dist($arg, $operation = 'traiter', $ignorer_autobr = false) {
static $pile = [];
static $next_marqueur = 1;
static $marqueur = 1;
global $les_notes, $compt_note, $notes_vues;
switch ($operation) {
case 'traiter':
if (is_array($arg)) {
return traiter_les_notes($arg, $ignorer_autobr);
} else {
return traiter_raccourci_notes($arg, $marqueur > 1 ? $marqueur : '');
}
break;
case 'empiler':
if ($compt_note == 0) { // si le marqueur n'a pas encore ete utilise, on le recycle dans la pile courante
array_push($pile, [@$les_notes, @$compt_note, $notes_vues, 0]);
} else {
// sinon on le stocke au chaud, et on en cree un nouveau
array_push($pile, [@$les_notes, @$compt_note, $notes_vues, $marqueur]);
$next_marqueur++; // chaque fois qu'on rempile on incremente le marqueur general
$marqueur = $next_marqueur; // et on le prend comme marqueur courant
}
$les_notes = '';
$compt_note = 0;
break;
case 'depiler':
#$prev_notes = $les_notes;
if (strlen($les_notes)) {
spip_log('notes perdues');
}
// si le marqueur n'a pas servi, le liberer
if (!strlen($les_notes) and $marqueur == $next_marqueur) {
$next_marqueur--;
}
// on redepile tout suite a une fin d'inclusion ou d'un affichage des notes
[$les_notes, $compt_note, $notes_vues, $marqueur] = array_pop($pile);
#$les_notes .= $prev_notes;
// si pas de marqueur attribue, on le fait
if (!$marqueur) {
$next_marqueur++; // chaque fois qu'on rempile on incremente le marqueur general
$marqueur = $next_marqueur; // et on le prend comme marqueur courant
}
break;
case 'sauver_etat':
if ($compt_note or $marqueur > 1 or $next_marqueur > 1) {
return [$les_notes, $compt_note, $notes_vues, $marqueur, $next_marqueur];
} else {
return '';
} // rien a sauver
break;
case 'restaurer_etat':
if ($arg and is_array($arg)) { // si qqchose a restaurer
[$les_notes, $compt_note, $notes_vues, $marqueur, $next_marqueur] = $arg;
}
break;
case 'contexter_cache':
if ($compt_note or $marqueur > 1 or $next_marqueur > 1) {
return ["$compt_note:$marqueur:$next_marqueur"];
} else {
return '';
}
break;
case 'reset_all': // a n'utiliser qu'a fins de test
if (strlen($les_notes)) {
spip_log('notes perdues [reset_all]');
}
$pile = [];
$next_marqueur = 1;
$marqueur = 1;
$les_notes = '';
$compt_note = 0;
$notes_vues = [];
break;
}
}
function traiter_raccourci_notes($letexte, $marqueur_notes) {
global $compt_note, $notes_vues;
if (
strpos($letexte, '[[') === false
or !preg_match_all(_NOTES_RACCOURCI, $letexte, $m, PREG_SET_ORDER)
) {
return [$letexte, []];
}
// quand il y a plusieurs series de notes sur une meme page
$mn = !$marqueur_notes ? '' : ($marqueur_notes . '-');
$mes_notes = [];
foreach ($m as $r) {
[$note_source, $note_all, $ref, $nom, $note_texte] = $r;
// reperer une note nommee, i.e. entre chevrons
// On leve la Confusion avec une balise en regardant
// si la balise fermante correspondante existe
// Cas pathologique: [[ <a> <a href="x">x</a>]]
if (
!(isset($nom) and $ref
and ((strpos($note_texte, '</' . $nom . '>') === false)
or preg_match(",<$nom\W.*</$nom>,", $note_texte)))
) {
$nom = ++$compt_note;
$note_texte = $note_all;
}
// eliminer '%' pour l'attribut id
$ancre = $mn . str_replace('%', '_', rawurlencode($nom));
// ne mettre qu'une ancre par appel de note (XHTML)
if (!isset($notes_vues[$ancre])) {
$notes_vues[$ancre] = 0;
}
$att = ($notes_vues[$ancre]++) ? '' : " id='nh$ancre'";
// creer le popup 'title' sur l'appel de note
// propre est couteux => nettoyer_raccourcis_typo
if ($title = supprimer_tags(nettoyer_raccourcis_typo($note_texte))) {
$title = " title='" . couper($title, 80) . "'";
}
// ajouter la note aux notes precedentes
if ($note_texte) {
$mes_notes[] = [$ancre, $nom, $note_texte];
}
// dans le texte, mettre l'appel de note a la place de la note
if ($nom) {
$nom = _NOTES_OUVRE_REF . "<a href='#nb$ancre' class='spip_note' rel='appendix'$title$att>$nom</a>" . _NOTES_FERME_REF;
}
$pos = strpos($letexte, (string) $note_source);
$letexte = rtrim(substr($letexte, 0, $pos), ' ')
. code_echappement($nom)
. substr($letexte, $pos + strlen($note_source));
}
return [$letexte, $mes_notes];
}
function traiter_les_notes($notes, $ignorer_autobr) {
$mes_notes = '';
if ($notes) {
$title = _T('info_notes');
foreach ($notes as $r) {
[$ancre, $nom, $texte] = $r;
$atts = " href='#nh$ancre' class='spip_note' title='$title $ancre' rev='appendix'";
$mes_notes .= "\n\n"
. "<div id='nb$ancre'><p" . ($GLOBALS['class_spip'] ? " class='spip_note'" : '') . '>'
. code_echappement($nom
? _NOTES_OUVRE_NOTE . '<a' . $atts . ">$nom</a>" . _NOTES_FERME_NOTE
: '')
. trim($texte)
. '</div>';
}
if ($ignorer_autobr) {
$mes_notes = _AUTOBR_IGNORER . $mes_notes;
}
$mes_notes = propre($mes_notes);
}
return ($GLOBALS['les_notes'] .= $mes_notes);
}