3 @define
('_sommaire_NB_TITRES_MINI', 2);
4 @define
('_sommaire_SANS_FOND', '[!fond]');
6 // aide le Couteau Suisse a calculer la balise #INTRODUCTION
7 $GLOBALS['cs_introduire'][] = 'sommaire_nettoyer_raccourcis';
9 // renvoie le sommaire d'une page d'article
10 // $page=false reinitialise le compteur interne des ancres
11 function sommaire_d_une_page(&$texte, &$nbh3, $page=0, $num_pages=0) {
13 if($page===false) $index = 0;
16 $self = str_replace('&', '&', nettoyer_uri());//self();//$GLOBALS['REQUEST_URI'];
17 if($page===false) return;
18 // trouver quel <hx> est utilise
19 include_spip('outils/sommaire');
20 $root = $niveau = $match = sommaire_niveau_intertitres();
21 @define
('_sommaire_NB_CARACTERES', 30);
22 @define
('_sommaire_PROFONDEUR', 1);
23 if(_sommaire_PROFONDEUR
>1)
24 $match = $match .'-' . ($match+_sommaire_PROFONDEUR
-1);
25 // traitement des intertitres <hx>
26 preg_match_all(",(<h([$match])[^>]*)>(.*)</h\\2>,Umsi", $texte, $regs);
27 $nbh3 +
= count($regs[0]);
28 $pos = 0; $sommaire = '';
30 $suffixe = $page?
_T('couteau:sommaire_page', array('page'=>$page)):'';
31 $fct_lien_retour = function_exists('sommaire_lien_retour')?
'sommaire_lien_retour':'sommaire_lien_retour_dist';
32 $fct_id_ancre = defined('_sommaire_JOLIES_ANCRES')?
'sommaire_id_ancre_ex'
33 :(function_exists('sommaire_id_ancre')?
'sommaire_id_ancre':'sommaire_id_ancre_dist');
34 $nb = count($regs[0]);
35 for($i=0;$i<$nb;$i++
,$index++
){
36 $w = &$regs[0][$i]; $h = &$regs[1][$i]; $n = &$regs[2][$i];
37 if (($pos2 = strpos($texte, $w, $pos))!==false) {
39 // calcul de l'ancre, $t peut etre modifie
40 $ancre = $fct_id_ancre($index, $t, $n);
41 $id = " id=\"$ancre\">";
42 //$titre = preg_replace(',^<p[^>]*>(.*)</p>$,Umsi', '\\1', trim($t));
43 // ancre 'retour au sommaire', sauf :
44 // si on imprime, ou si les blocs depliables utilisent h{$n}...
45 $titre = (defined('_CS_PRINT') OR (strpos($w, 'blocs_titre')!==false))
47 :$fct_lien_retour($self, $t);//$titre);
48 $texte = substr($texte, 0, $pos2) . $h . $id . $titre
49 . substr($texte, $pos2 +
strlen($h)+
1 +
strlen($regs[3][$i]));
50 $pos = $pos2 +
strlen($id) +
strlen($w);
51 $brut = sommaire_nettoyer_titre($t);
52 // pas trop long quand meme...
53 $lien = cs_propre(couper($brut, _sommaire_NB_CARACTERES
));
54 // eviter une ponctuation a la fin, surtout si la page est precisee
55 $lien = preg_replace('/( |\s)*'.($page?
'[!?,;.:]+$/':'[,;.:]+$/'), '', $lien);
56 $titre = attribut_html(couper($brut, 100));
57 // si la decoupe en page est active...
58 $artpage = (function_exists('decoupe_url') && (strlen(_request('artpage')) ||
$page>1) )
59 ?
decoupe_url($self, $page, $num_pages):$self;
60 $artpage = "\n<li><a $st title=\"$titre\" href=\"{$artpage}#$ancre\">$lien</a>$suffixe";
61 if($niveau==$n) $sommaire .= ($sommaire?
'</li>':'').$artpage;
62 elseif($niveau<$n) $sommaire .= "\n<ul>".$artpage;
63 else $sommaire .= '</li></ul></li>'.$artpage;
67 return $sommaire?
$sommaire.'</li>'.($niveau!=$root?
'</ul>':''):'';
70 function sommaire_nettoyer_titre($t) {
72 $brut = preg_replace(',\[<a href=["\']#nb.*?</a>\],','', echappe_retour($t,'CS'));
74 if(function_exists('cs_retire_glossaire')) $brut = cs_retire_glossaire($brut);
76 $brut2 = trim(preg_replace(',[\n\r]+,',' ',textebrut($brut)));
77 // cas des intertitres en image_typo
78 if(!strlen($brut2)) $brut2 = trim(extraire_attribut($brut, 'alt'));
83 Fonction surchargeable qui reconstruit les titres de la page
84 en ajoutant une ancre de retour au sommaire.
85 La fonction de surcharge a placer dans config/mes_options.php est :
86 sommaire_lien_retour($self, $titre)
87 Exemple sans lien de retour :
88 function sommaire_lien_retour($self, $titre) { return $titre; }
90 function sommaire_lien_retour_dist($self, $titre) {
93 $haut = '<a title="'._T('couteau:sommaire_titre').'" href="'.$self.'#outil_sommaire" class="sommaire_ancre"> </a>';
94 return $haut . $titre;
98 Fonction surchargeable qui calcule l'ancre d'un intertitre
99 La fonction de surcharge a placer dans config/mes_options.php est :
100 sommaire_id_ancre($index, &$titre, $hn)
101 $titre peut etre modifie par cette fonction : utile pour traiter le format {{{Mon titre<mon_ancre>}}}
103 function sommaire_id_ancre_dist($index, &$titre, $hn) {
104 return 'outil_sommaire_'.$index;
107 // Surcharge compatible avec les intertitres en image : jolies ancres
108 function sommaire_id_ancre_ex($index, &$titre, $hn) {
109 // traiter le format {{{Mon titre<mon_ancre>}}} (ou alt='Mon titre<mon_ancre>')
110 if(preg_match(',<(\w+)>$,', $titre, $r) ||
preg_match(',<(\w+)>(?=\'),', $titre, $r)) {
111 $titre = str_replace($r[0], '', $titre);
114 // calculer les ancres d'apres le titre
115 $a = strtolower(translitteration(sommaire_nettoyer_titre($titre)));
116 $a = trim(preg_replace(',[^a-z0-9_]+,', '_', $a), '_');
117 return strlen($a)>2?
$a:"sommaire_$index";
120 // fonction appellee sur les parties du textes non comprises entre les balises : html|code|cadre|frame|script|acronym|cite
121 function sommaire_d_article_rempl($texte0, $sommaire_seul=false) {
122 // pour sommaire_nettoyer_raccourcis()
123 include_spip('outils/sommaire');
124 // si le sommaire est malvenu ou s'il n'y a pas de balise <hx>, alors on laisse tomber
125 $inserer_sommaire = defined('_sommaire_AUTOMATIQUE')
126 ?
strpos($texte0, _CS_SANS_SOMMAIRE
)===false
127 :strpos($texte0, _CS_AVEC_SOMMAIRE
)!==false;
128 if (!$inserer_sommaire ||
strpos($texte0, '<h')===false)
129 return $sommaire_seul?
'':sommaire_nettoyer_raccourcis($texte0);
130 // on retire les raccourcis du texte
131 $texte = sommaire_nettoyer_raccourcis($texte0);
132 // on masque les onglets s'il y en a
133 if(defined('_onglets_FIN'))
134 $texte = preg_replace_callback(',<div class="onglets_bloc_initial.*'._onglets_FIN
.',Ums',
135 create_function('$matches','return cs_code_echappement($matches[0], \'SOMM\');'), $texte);
137 $sommaire = ''; $i = 1; $nbh3 = 0;
138 // reinitialisation de l'index interne de la fonction
139 sommaire_d_une_page($texte, $nbh3, false);
140 // couplage avec l'outil 'decoupe_article'
141 if(defined('_decoupe_SEPARATEUR') && !defined('_CS_PRINT')) {
142 $pages = explode(_decoupe_SEPARATEUR
, $texte);
143 if (($num_page=count($pages)) == 1) $sommaire = sommaire_d_une_page($texte, $nbh3);
145 foreach($pages as $p=>$page) { $sommaire .= sommaire_d_une_page($page, $nbh3, $i++
, $num_page); $pages[$p] = $page; }
146 $texte = join(_decoupe_SEPARATEUR
, $pages);
148 } else $sommaire = sommaire_d_une_page($texte, $nbh3);
149 if(!strlen($sommaire) ||
$nbh3<_sommaire_NB_TITRES_MINI
)
150 return $sommaire_seul?
'':sommaire_nettoyer_raccourcis($texte0);
152 // calcul du sommaire
153 include_spip('public/assembler');
154 $sommaire = recuperer_fond('fonds/sommaire', array(
155 'sommaire'=>$sommaire,
156 'fond_css'=>strpos($texte0, _sommaire_SANS_FOND
)===false ?
'avec':'sans',
159 // si on ne veut que le sommaire, on renvoie le sommaire
160 // sinon, on n'insere ce sommaire en tete de texte que si la balise #CS_SOMMAIRE n'est pas activee
161 if($sommaire_seul) return $sommaire;
162 if(defined('_onglets_FIN')) $texte = echappe_retour($texte, 'SOMM');
163 if(defined('_sommaire_BALISE')) return $texte;
164 return _sommaire_REM
.$sommaire._sommaire_REM
.$texte;
167 // fonction appelee par le traitement de #TEXTE/articles
168 function sommaire_d_article($texte) {
169 // s'il n'y a aucun intertitre, on ne fait rien
170 // si la balise est utilisee, il faut quand meme inserer les ancres de retour
171 if((strpos($texte, '<h')===false)) return $texte;
172 return cs_echappe_balises('html|code|cadre|frame|script|acronym|cite|onglets|table', 'sommaire_d_article_rempl', $texte, false);
175 // fonction appelee par le traitement post_propre de #CS_SOMMAIRE
176 function sommaire_d_article_balise($texte) {
177 // si la balise n'est pas utilisee ou s'il n'y a aucun intertitre, on ne fait rien
178 if(!defined('_sommaire_BALISE') ||
(strpos($texte, '<h')===false)) return '';
179 return cs_echappe_balises('html|code|cadre|frame|script|acronym|cite|onglets|table', 'sommaire_d_article_rempl', $texte, true);
182 // si on veut la balise #CS_SOMMAIRE
183 if (defined('_sommaire_BALISE')) {
184 // fonction traitant la balise
185 function balise_CS_SOMMAIRE_dist($p) {
186 // id de l'article a trouver pour retourner son texte
187 $texte = ($v = interprete_argument_balise(1,$p))!==NULL ?
'cs_champ_sql('.$v.')' : champ_sql('texte', $p);
188 if ($p->type_requete
== 'articles' ||
$v!==NULL) {
189 $p->code
= 'cs_supprime_notes('.$texte.')';
193 $p->interdire_scripts
= true;