[SPIP] +2.1.12
[velocampus/web/www.git] / www / plugins / auto / couteau_suisse / couteau_suisse / outils / decoupe_fonctions.php
1 <?php
2 @define('_decoupe_NB_CARACTERES', 60);
3
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');
8
9 // aide le Couteau Suisse a calculer la balise #INTRODUCTION
10 $GLOBALS['cs_introduire'][] = 'decoupe_nettoyer_raccourcis';
11
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}":'');
15 }
16
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;" >&nbsp; &nbsp;</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]);
28 // on sait jamais...
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>";
31 }
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>";
38 }
39 return _onglets_DEBUT.join('', $contenus).'</div>'._onglets_FIN;
40 }
41
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);
49 }
50 // il faut un callback pour analyser l'interieur du texte
51 return preg_replace_callback(_onglets_REGEXPR, 'onglets_callback', $texte);
52 }
53
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 = '';
58
59 // si pas de separateur, on sort
60 if (strpos($texte, _decoupe_SEPARATEUR)===false) return $pagination_seule?'':$texte;
61
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;" >&nbsp; &nbsp;</p>');
65 return str_replace(_decoupe_SEPARATEUR, _decoupe_FILET, $texte);
66 }
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];
71 $texte = $pages[2];
72 } else $sommaire = '';
73
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);
80 /*
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);
85 */
86
87 // si la balise #CS_DECOUPE est utilisee on renvoie le texte sans pagination
88 if (!$pagination_seule) {
89 // page demandee
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']);
94 }
95 if (defined('_decoupe_BALISE')) return $sommaire.$page;
96 }
97
98 $self = nettoyer_uri();//self();//$GLOBALS['REQUEST_URI'];
99
100 // liens des differentes pages sous forme : 1 2 3 4
101 $milieu = '';
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)),
109 'self' =>$self,
110 ));
111 }
112
113 // pagination finale
114 $pagination = recuperer_fond('fonds/decoupe', array(
115 'artpage'=>$artpage, 'derniere_page'=>$num_pages,
116 'items'=>$milieu,
117 'self' =>$self,
118 ));
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";
122 return $pagination;
123 }
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";
127 $id_decoupe++;
128 return $sommaire.$pagination1.$page.$pagination2;
129 }
130
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);
143 }
144 $GLOBALS['les_notes'] = trim($notes);
145 }
146
147 function cs_decoupe_compat($texte){
148 // surcharge possible de _decoupe_SEPARATEUR par _decoupe_COMPATIBILITE
149 $rempl = ',\s*('
150 . preg_quote(_decoupe_SEPARATEUR,',')
151 . (defined('_decoupe_COMPATIBILITE')?'|'.preg_quote(_decoupe_COMPATIBILITE,','):'')
152 . ')\s*,';
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);
159 }
160
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);
164 }
165
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);
172 return $texte;
173 }
174
175 // Compatibilite
176 function decouper_en_pages($texte){ return cs_decoupe($texte); }
177
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;
183 return $p;
184 }
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;
189 return $p;
190 }
191 function balise_ONGLETS_FIN($p) {
192 $p->code = "calcul_balise_onglet('',3)";
193 $p->interdire_scripts = false;
194 return $p;
195 }
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}]
202 (...)
203 </BOUCLE_sites>
204 */
205 static $onglets_stade;
206 if($type==2 && !isset($onglets_stade)) $type = 1;
207 switch($type) {
208 // #ONGLETS_DEBUT
209 case 1:$onglets_stade=1; return _onglets_DEBUT._onglets_CONTENU.$arg._onglets_CONTENU2;
210 // #ONGLETS_TITRE
211 case 2:$onglets_stade=1; return '</div>'._onglets_CONTENU.$arg._onglets_CONTENU2;
212 // #ONGLETS_FIN
213 case 3:unset($onglets_stade); return '</div></div>';
214 }
215 }
216
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');
222 return $t[$index];
223 }
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];
228 }
229 function artpage_debut($t=false) {
230 return artpage($t)==1;
231 }
232
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)';
240 } else {
241 $p->code = "''";
242 }
243 $p->interdire_scripts = true;
244 return $p;
245 }
246 }
247
248 /*
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
254 */
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;
267 return 1;
268 }
269 ?>