2 @define
('_decoupe_NB_CARACTERES', 60);
4 define('_onglets_CONTENU', '<div class="onglets_contenu"><h2 class="cs_onglet"><a href="#">');
5 define('_onglets_CONTENU2', '</a></h2>'); // sans le </div> !
6 define('_onglets_DEBUT', '<div class="onglets_bloc_initial">');
7 define('_onglets_REGEXPR', ',<onglets([0-9]*)>(.*?)</onglets\1>,ms');
9 // aide le Couteau Suisse a calculer la balise #INTRODUCTION
10 $GLOBALS['cs_introduire'][] = 'decoupe_nettoyer_raccourcis';
12 // filtre ajoutant 'artpage' a l'url
13 function decoupe_url($url, $page, $num_pages) {
14 return parametre_url($url, 'artpage',$page>1?
"{$page}-{$num_pages}":'');
17 function onglets_callback($matches) {
18 // cas des onglets imbriques
19 if (strpos($matches[2], '<onglets')!==false)
20 $matches[2] = preg_replace_callback(_onglets_REGEXPR
, 'onglets_callback', $matches[2]);
21 // nettoyage apres les separateurs
22 $matches[2] = preg_replace(','.preg_quote(_decoupe_SEPARATEUR
,',').'\s+,', _decoupe_SEPARATEUR
, $matches[2]);
23 // au cas ou on ne veuille pas d'onglets, on remplace les '++++' par un filet et on entoure d'une classe.
24 if (defined('_CS_PRINT')) {
25 @define
(_decoupe_FILET
, '<p style="border-bottom:1px dashed #666; padding:0; margin:1em 20%; font-size:4pt;" > </p>');
26 $t = preg_split(',(\n\n|\r\n\r\n|\r\r),', $matches[2], 2);
27 $texte = preg_replace(','.preg_quote(_decoupe_SEPARATEUR
, ',').'(.*?)(\n\n|\r\n\r\n|\r\r),ms', _decoupe_FILET
."<h4>$1</h4>\n\n", $t[1]);
29 str_replace(_decoupe_SEPARATEUR
, _decoupe_FILET
, $texte);
30 return '<div class="onglets_print"><h4>' . textebrut(echappe_retour($t[0],'CS')) . "</h4>\n\n$texte\n\n</div>";
32 $onglets = $contenus = array();
33 $pages = explode(_decoupe_SEPARATEUR
, $matches[2]);
34 foreach ($pages as $p) {
35 $t = preg_split(',(\n\n|\r\n\r\n|\r\r),', $p, 2);
36 $t = array(trim(textebrut(nettoyer_raccourcis_typo(echappe_retour($t[0],'CS')))), cs_safebalises($t[1]));
37 if(strlen($t[0].$t[1])) $contenus[] = _onglets_CONTENU
.$t[0]._onglets_CONTENU2
."<div>\n\n".$t[1]."\n\n</div></div>";
39 return _onglets_DEBUT
.join('', $contenus).'</div>'._onglets_FIN
;
42 // fonction appellee sur les parties du texte non comprises entre les balises : html|code|cadre|frame|script|acronym|cite
43 function decouper_en_onglets_rempl(&$texte) {
44 // compatibilite avec la syntaxe de Pierre Troll
45 if (strpos($texte, '<onglet|')!==false) {
46 $texte = str_replace('<onglet|fin>', '</onglets>', $texte);
47 $texte = preg_replace(',<onglet\|debut[^>]*\|titre=([^>]*)>\s*,', "<onglets>\\1\n\n", $texte);
48 $texte = preg_replace(',\s*<onglet\|titre=([^>]*)>\s*,', "\n\n++++\\1\n\n", $texte);
50 // il faut un callback pour analyser l'interieur du texte
51 return preg_replace_callback(_onglets_REGEXPR
, 'onglets_callback', $texte);
54 // fonction appellee sur les parties du textes non comprises entre les balises : html|code|cadre|frame|script|acronym|cite
55 function decouper_en_pages_rempl($texte, $pagination_seule=false) {
56 // un seul id par page...
57 static $id_decoupe = '';
59 // si pas de separateur, on sort
60 if (strpos($texte, _decoupe_SEPARATEUR
)===false) return $pagination_seule?
'':$texte;
62 // au cas ou on ne veuille pas de decoupe, on remplace les '++++' par un filet.
63 if (defined('_CS_PRINT') && !$pagination_seule) {
64 @define
(_decoupe_FILET
, '<p style="border-bottom:1px dashed #666; padding:0; margin:1em 20%; font-size:4pt;" > </p>');
65 return str_replace(_decoupe_SEPARATEUR
, _decoupe_FILET
, $texte);
67 // recherche du sommaire s'il existe
68 if (defined('_sommaire_REM') && (substr_count($texte, _sommaire_REM
)==2)) {
69 $pages = explode(_sommaire_REM
, $texte);
70 $sommaire = $pages[0].$pages[1];
72 } else $sommaire = '';
74 // traitement des pages
75 $pages = explode(_decoupe_SEPARATEUR
, $texte);
76 $num_pages = count($pages);
77 if ($num_pages == 1) return $pagination_seule?
'':$texte;
78 $artpage = max(intval(artpage()), 1);
79 $artpage = min($artpage, $num_pages);
81 // si numero illegal ou si var_recherche existe, alors renvoyer toutes les pages, separees par une ligne <hr/>.
82 // la surbrillance pourra alors fonctionner correctement.
83 if (strlen($_GET['var_recherche']) || $artpage < 1 || $artpage > $num_pages)
84 return join("<hr/>", $pages);
87 // si la balise #CS_DECOUPE est utilisee on renvoie le texte sans pagination
88 if (!$pagination_seule) {
90 $page = cs_safebalises($pages[$artpage-1]);
91 if (isset($_GET['decoupe_recherche'])) {
92 include_spip('inc/surligne');
93 $page = surligner_mots($page, $_GET['decoupe_recherche']);
95 if (defined('_decoupe_BALISE')) return $sommaire.$page;
98 $self = nettoyer_uri();//self();//$GLOBALS['REQUEST_URI'];
100 // liens des differentes pages sous forme : 1 2 3 4
102 for ($i = 1; $i <= $num_pages; $i++
) {
103 $page_ = supprimer_tags(cs_safebalises(cs_introduire(echappe_retour($pages[$i-1],'CS'))));
104 $title = preg_split("/[\r\n]+/", trim($page_), 2);
105 $title = attribut_html(/*propre*/(couper($title[0], _decoupe_NB_CARACTERES
)));//.' (...)';
106 $milieu .= recuperer_fond('fonds/decoupe_item', array(
107 'page'=>$i, 'artpage'=>$artpage, 'derniere_page'=>$num_pages,
108 'title_page'=>_T('couteau:page_lien', array('page' => $i, 'title' => $title)),
114 $pagination = recuperer_fond('fonds/decoupe', array(
115 'artpage'=>$artpage, 'derniere_page'=>$num_pages,
119 if ($pagination_seule) {
120 if(trim($pagination)=="") return "";
121 $pagination = "<div id='decoupe_balise$id_decoupe' class='pagination decoupe_balise'>\n$pagination\n</div>\n";
124 // ici $pagination_seule est false, $page est definie
125 $pagination1 = "<div id='decoupe_haut$id_decoupe' class='pagination decoupe_haut'>\n$pagination\n</div>\n";
126 $pagination2 = "<div id='decoupe_bas$id_decoupe' class='pagination decoupe_bas'>\n$pagination\n</div>\n";
128 return $sommaire.$pagination1.$page.$pagination2;
131 // supprime les notes devenues orphelines
132 function decoupe_notes_orphelines(&$texte) {
133 if($GLOBALS['les_notes']=='') return;
134 $notes = $GLOBALS['les_notes'];
135 /* if(function_exists('tester_variable')) tester_variable('ouvre_note', '['); // tester_variable() depreciee sous SPIP 2.0
136 else*/ if (!isset($GLOBALS['ouvre_note'])) $GLOBALS['ouvre_note'] = '[';
137 $ouvre = preg_quote($GLOBALS['ouvre_note'],',');
138 $appel = ",<p[^>]*>.*?$ouvre<a [^>]*(?:name|id)=[\"']nb([0-9]+)[\"'] class=[\"']spip_note[\"'] [^>]+>[^<]+</a>.*?</p>,s";
139 preg_match_all($appel, $GLOBALS['les_notes'], $tableau);
140 for($i=0;$i<count($tableau[0]);$i++
) {
141 if (!preg_match(",<a href=[\"']#nb{$tableau[1][$i]}[\"'],",$texte))
142 $notes = str_replace($tableau[0][$i], '', $notes);
144 $GLOBALS['les_notes'] = trim($notes);
147 function cs_decoupe_compat($texte){
148 // surcharge possible de _decoupe_SEPARATEUR par _decoupe_COMPATIBILITE
150 . preg_quote(_decoupe_SEPARATEUR
,',')
151 . (defined('_decoupe_COMPATIBILITE')?
'|'.preg_quote(_decoupe_COMPATIBILITE
,','):'')
153 // mise au clair des separateurs : pour les onglets ET la decoupe en page
154 $texte = preg_replace($rempl, "\n\n"._decoupe_SEPARATEUR
."\n\n", $texte);
155 // si pas d'onglets ou pagination seule demandee, on sort
156 if (strpos($texte, '<onglet')===false) return $texte;
157 // traitement des onglets
158 return decouper_en_onglets_rempl($texte);
161 // ici on est en pre_propre, tests de compatibilite requis, puis traitement des onglets
162 function cs_onglets($texte){
163 return cs_echappe_balises('html|code|cadre|frame|script|cite|jeux', 'cs_decoupe_compat', $texte);
166 // ici on est en post_propre, tests de compatibilite effectues
167 function cs_decoupe($texte, $pagination_seule=false){
168 // si pas de separateur, on sort
169 if (strpos($texte, _decoupe_SEPARATEUR
)===false) return $pagination_seule?
'':$texte;
170 $texte = cs_echappe_balises('html|code|cadre|frame|script|cite|table|jeux', 'decouper_en_pages_rempl', $texte, $pagination_seule);
171 if (!$pagination_seule) decoupe_notes_orphelines($texte);
176 function decouper_en_pages($texte){ return cs_decoupe($texte); }
178 // Balises pour des onglets en squelette
179 function balise_ONGLETS_DEBUT($p) {
180 $arg = sinon(interprete_argument_balise(1,$p),'??');
181 $p->code
= "calcul_balise_onglet($arg,1)";
182 $p->interdire_scripts
= false;
185 function balise_ONGLETS_TITRE($p) {
186 $arg = sinon(interprete_argument_balise(1,$p),'??');
187 $p->code
= "calcul_balise_onglet($arg,2)";
188 $p->interdire_scripts
= false;
191 function balise_ONGLETS_FIN($p) {
192 $p->code
= "calcul_balise_onglet('',3)";
193 $p->interdire_scripts
= false;
196 function calcul_balise_onglet($arg, $type) {
197 /* dans un onglet principal (non imbrique), on peut omettre #ONGLETS_DEBUT : pratique a l'interieur d'une boucle
198 Sinon il faut jouer avec #COMPTEUR_BOUCLE :
199 <BOUCLE_sites(SITES)>
200 [(#COMPTEUR_BOUCLE|=={1}|?{' '})#ONGLETS_DEBUT{#NOM_SITE}]
201 [(#COMPTEUR_BOUCLE|>{1}|?{' '})#ONGLETS_TITRE{#NOM_SITE}]
205 static $onglets_stade;
206 if($type==2 && !isset($onglets_stade)) $type = 1;
209 case 1:$onglets_stade=1; return _onglets_DEBUT
._onglets_CONTENU
.$arg._onglets_CONTENU2
;
211 case 2:$onglets_stade=1; return '</div>'._onglets_CONTENU
.$arg._onglets_CONTENU2
;
213 case 3:unset($onglets_stade); return '</div></div>';
217 // decode le parametre artpage=page-total
218 // attention, artpage n'est pas toujours present
219 function artpage($t=false, $index=0) {
220 if($t===false) $t=_request('artpage');
221 $t=strlen($t)?
explode('-', $t, 2):array('1','0');
224 function artpage_fin($t=false) {
225 if($t===false) $t=_request('artpage');
226 $t=strlen($t)?
explode('-', $t, 2):array('1','0');
227 return $t[0]>0 && $t[0]==$t[1];
229 function artpage_debut($t=false) {
230 return artpage($t)==1;
233 // si on veut la balise #CS_DECOUPE (pagination uniquement)
234 if (defined('_decoupe_BALISE')) {
235 function balise_CS_DECOUPE_dist($p) {
236 // id de l'article a trouver pour retourner son texte
237 $texte = ($v = interprete_argument_balise(1,$p))!==NULL ?
'cs_champ_sql('.$v.')' : champ_sql('texte', $p);
238 if ($p->type_requete
== 'articles' ||
$v!==NULL) {
239 $p->code
= 'cs_decoupe(propre(cs_onglets(cs_supprime_notes('.$texte.'))), true)';
243 $p->interdire_scripts
= true;
249 filtre |decoupe_type_pagination qui renvoie :
250 1 si le nombre doit etre affiche
251 2 si le nombre ne doit pas etre affiche
252 3 s'il faut afficher '...'
253 voir le modele : modeles/decoupe_item.html
255 function decoupe_type_pagination($page, $artpage, $page_fin, $rayon=4, $extremes=2) {
256 $diametre = $rayon*2;
257 if($page_fin<=$diametre+
$extremes+
1 ||
$page<=$extremes ||
$page>$page_fin-$extremes) return 1;
258 $depart = max(1, $artpage - $rayon);
259 $arrivee = $artpage +
$rayon;
260 if($arrivee-$depart<$diametre) $arrivee=$depart+
$diametre;
261 if($arrivee>$page_fin) $arrivee = $page_fin;
262 if($arrivee-$depart<$diametre) $depart=$arrivee-$diametre;
263 if($depart<=$extremes+
1) $depart = 1;
264 if($arrivee>=$page_fin-$extremes) $arrivee = $page_fin;
265 if($page<$depart-1 ||
$page>$arrivee+
1) return 2;
266 if($page==$depart-1 ||
$page==$arrivee+
1) return 3;