source: spip-zone/_plugins_/table_matieres/trunk/table_matieres.php @ 54334

Last change on this file since 54334 was 54334, checked in by kent1@…, 9 years ago

Toutes les chaines de langue de la conf sont internationalisées

Ce qui était en descriptif de la page de conf passe en explications dans le formulaire de conf

On évite le camelcase dans le préfixe

Le fichier de langue en utf-8

File size: 8.8 KB
Line 
1<?php
2
3if (!defined("_ECRIRE_INC_VERSION")) return;
4
5
6// tester la presence de CFG
7$tm = @unserialize($GLOBALS['meta']['table_matieres']);
8
9define('_AUTO_ANCRE', isset($tm['auto']) ? $tm['auto'] : 'oui');
10define('_LG_ANCRE', isset($tm['lg']) ? $tm['lg'] : 35);
11define('_SEP_ANCRE', isset($tm['sep']) ? $tm['sep'] : '-');
12define('_MIN_ANCRE', isset($tm['min']) ? $tm['min'] : 3);
13define('_RETOUR_TDM', '<a href="'.ancre_url($GLOBALS['REQUEST_URI'],'tdm').'" class="tdm"><img src="' .
14        find_in_path('images/tdm.png') . 
15        '" /></a>');
16
17/**
18 * Fonction d'API.
19 *
20 * Elle reçoit un texte ayant encore les raccourcis SPIP
21 * et donc les codes des éventuels intertitres tel que "{{{ intertitre }}}".
22 *
23 * Elle ajoute une table des matières en entête du texte (par défaut)
24 * Et retourne le texte avec les intertitres complétés d'un lien de retour
25 * vers le sommaire automatique.
26 *
27 * En option, on peut demander à la fonction de ne retourner
28 * QUE la table des matières.
29 *
30 * @param string $texte Texte en entrée
31 * @param string $retourner Retourner quoi ? (tout, tdm, texte)
32 * @return string       Texte avec une table des matières
33 */
34function table_matieres($texte, $retourner = 'tout') {
35        static $table_matieres = false;
36
37        if (!$texte) {
38                return $texte;
39        }
40        if (!$table_matieres) {
41                $table_matieres = charger_fonction('table_matieres', 'inc');
42        }
43       
44        return $table_matieres($texte, $retourner);
45}
46
47/**
48 * Fonction principale du plugin
49 * cf. description sur la fonction d'appel table_matieres()
50 *
51 * @param string $texte Texte en entrée
52 * @param bool $retourner Retourner quoi ?
53 *              - 'tout' : tout (tdm + texte)
54 *              - 'tdm' : la table des matieres
55 *              - 'texte' : le texte (et les ancres)
56 * @return string       Texte avec une table des matières
57 */
58function inc_table_matieres_dist($texte, $retourner = 'tout') {
59
60        // sauvegarde pour ne pas calculer 2 fois les mêmes choses
61        static $textes = array();
62        $md5 = md5($texte);
63
64        if (!in_array($retourner, array('tout', 'tdm', 'texte'))) {
65                $retourner = 'tout';
66                spip_log("Erreur de parametre sur la fonction table_matieres.");
67        }
68       
69        // deja calculé ? on s'en retourne.
70        if (isset($textes[$md5])) {
71                if ($retourner == 'tout') {
72                        return $textes[$md5]['tdm'] . $textes[$md5]['texte'];
73                }
74                return $textes[$md5][$retourner];
75        }
76
77        // protection des expressions qui ne font pas partie de la table des matières
78        //
79        // le 3e à true pour ne pas utiliser les fonctions d'echappement predefinis
80        // et garder les textes tels quels (ex: <code><balise></code>)
81        // sinon la transformation est effectuee 2 fois.
82        $texte_protege = echappe_html($texte, 'TDM', true);
83
84        // vider les caches d'intertitres trouves
85        tdm_vider_intertitres();
86       
87        // dans un premier temps, on traverse le texte à la recherche d'intertitres.
88        // et pour chaque intertitre trouvé, on ajoute un marqueur qui
89        // permettra d'ajouter un lien de retour vers l'intertitre.
90        // On réalise l'opétation pour chaque type d'intertitre : {{{}}}, ===, {2{...
91        // si leurs définitions sont présentes.
92        foreach( tdm_remplacements_intertitres() as $regexp => $callback ) {
93                $texte_protege = preg_replace_callback($regexp, $callback, $texte_protege);
94        }
95
96        // si l'on a trouvé moins d'intertitres que le minimum vital (configurable)
97        // on rétablit le texte d'origine et on s'en va !
98        $intertitres = tdm_get_intertitres();
99        if ( count($intertitres) < _MIN_ANCRE ) {
100                $textes[$md5] = array(
101                        'tdm' => '',
102                        'texte' => $texte
103                );
104                if ($retourner == 'tout') {
105                        return $textes[$md5]['tdm'] . $textes[$md5]['texte'];
106                }
107                return $textes[$md5][$retourner];
108        }
109       
110        // dévérouillage des protections
111        $texte = echappe_retour($texte_protege, 'TDM');
112
113        // calculer la table des matières
114        $tdm = tdm_generer_table_des_matieres($intertitres);
115
116        // ajouter les icones de retour vers la table des matieres
117        $texte = tdm_ajouter_liens_retour_table_matieres($texte);
118
119        // sauver
120        $textes[$md5] = array(
121                'tdm' => $tdm,
122                'texte' => $texte
123        );
124
125        // c'est fini !
126        if ($retourner == 'tout') {
127                return $textes[$md5]['tdm'] . $textes[$md5]['texte'];
128        }
129        return $textes[$md5][$retourner];
130}
131
132/**
133 * Retourne la liste des raccourcis d'intertitres / fonction de remplacements
134 * pour la recherche d'intertitres.
135 *
136 * Cette fonction pourra être étendue
137 * par un pipeline ou une globale
138 *
139 * @return arrray  expression régulière / fonction de remplacement
140 */
141function tdm_remplacements_intertitres() {
142        return array(
143                "/{{{(.*)}}}/UmsS" => 'tdm_remplacement_raccourcis_standard_callback'
144        );
145}
146
147
148/**
149 * Intertitre en entrée.
150 * L'analyse, stocke l'information et retourne l'intertitre complété
151 *
152 * @param string $matches       Captures de l'expression régulière
153 * @return l'intertitre complété du code de lien de retour.
154 */
155function tdm_remplacement_raccourcis_standard_callback($matches) {
156        list($titre, $url) = tdm_calculer_titre( $matches[1] ); // intertitre dans /1
157        $url = tdm_stocker_intertitre($url, $titre);
158        return '{{{ [' . $url . '<-] ' . $matches[1] . ' @@RETOUR_TDM@@ }}}';
159}
160
161/**
162 * Calcule le titre et l'url de l'ancre
163 * a partir d'un intertitre donné
164 *
165 * @param string $intertitre
166 * @return array titre/url
167 */
168function tdm_calculer_titre($intertitre) {
169        $titre = supprimer_tags(typo($intertitre));
170        $titre = preg_replace(",\n[_\s]*,", " ", $titre);
171        $url = translitteration($titre);
172        $url = @preg_replace(',[[:punct:][:space:]]+,u', ' ', $url);
173
174        // S'il reste des caracteres non latins, utiliser l'id a la place
175        if (preg_match(",[^a-zA-Z0-9 ],", $url)) {
176                $url = "ancre$cId";
177        }
178        else {
179                $mots = explode(' ', $url);
180                $url = '';
181                foreach ($mots as $mot) {
182                        if (!$mot) continue;
183                        $url2 = $url._SEP_ANCRE.$mot;
184                        if (strlen($url2) > _LG_ANCRE) {
185                                break;
186                        }
187                        $url = $url2;
188                }
189                $url = substr($url, 1);
190                if (strlen($url) < 2) $url = "ancre$cId";
191        }
192
193        return array($titre, $url);
194}
195
196
197/**
198 * Remet à zéro la liste des intertitres trouvés
199 */
200function tdm_vider_intertitres() {
201        tdm_stocker_intertitre('', '', true);
202}
203
204/**
205 * Retourne la liste des intertitres trouvés
206 * @return array        Liste des intertitres (url/titre)
207 */
208function tdm_get_intertitres() {
209        return tdm_stocker_intertitre('');
210}
211
212
213/**
214 * Stocke les intertitres trouves.
215 * Si une url est deja presente, on identifie l'url d'un numero
216 *
217 * Passer une url vide pour recuperer le tableau.
218 *
219 * @param string $url   url de l'ancre
220 * @param string $titre titre de l'ancre
221 * @param bool $vider   effacer les sauvegarde ?
222 * @return
223 */
224function tdm_stocker_intertitre($url='', $titre='', $vider = false) {
225        static $table = array();
226        static $cpt = 0;
227        if($vider_table) return ($table = array());
228        if (!$url) return $table;
229        $cpt++;
230        $url = array_key_exists($url, $table) ? $url.$cpt : $url;
231        $table[$url] = $titre;
232        return $url;
233}
234
235
236
237/**
238 * Remplace les @@RETOUR_TDM@@ laissés par les callback de recherche d'intertitres
239 * par le lien de retour correspondant
240 *
241 * @param string $texte Texte d'entrée
242 * @return string Texte avec retours remplacés
243 */
244function tdm_ajouter_liens_retour_table_matieres($texte) {
245       
246        // prendre en compte la langue en cours
247        $_RETOUR_TDM = preg_replace(
248                ',<img,i',
249                '<img alt="' . _T('tdm:retour_table_matiere')
250                .'" title="' . _T('tdm:retour_table_matiere') . '"',
251                _RETOUR_TDM);
252
253        # Si demande en javascript... (pas tres propre, a refaire avec un js externe)
254        if (TDM_JAVASCRIPT AND !test_espace_prive() AND !_AJAX # crayons
255        ) {
256                $_RETOUR_TDM = '<script type="text/javascript"><!--
257                document.write("'.str_replace('"', '\\"', $_RETOUR_TDM).'");
258                --></script>';
259        }
260       
261        return str_replace('@@RETOUR_TDM@@', $_RETOUR_TDM, $texte);
262}
263
264
265/**
266 * Générer une table des matieres a partir du tableau
267 * d'intertitres donnes
268 *
269 * @param array couples liens/intertitres
270 * @return string       Code HTML de la table des matieres
271 */
272function tdm_generer_table_des_matieres($intertitres) {
273        // generer un code HTML
274        $code = "";
275        foreach ($intertitres as $url=>$titre) {
276                $code .= "<li><a href='".ancre_url($GLOBALS['REQUEST_URI'],$url)."'>$titre</a></li>\n";
277        }
278
279        // code HTML de la table des matieres
280        $_table = recuperer_fond('modeles/table_matieres', array(
281                'code' => $code,
282                'tableau'=>$intertitres
283        ));
284
285        # version en javascript (pas tres propre, a refaire avec un js externe)
286        if (TDM_JAVASCRIPT AND $_table AND !test_espace_prive()
287        AND !_AJAX # crayons
288        ) {
289                $_table = inserer_attribut('<div class="encart"></div>',
290                        'rel', $_table)
291                        .'<script type="text/javascript"><!--
292                        $("div.encart").html($("div.encart").attr("rel")).attr("rel","");
293                        --></script>';
294        }
295
296        return $_table;
297}
298
299/**
300 * Balise #TABLE_MATIERES
301 * Affiche la table des matieres à l'endroit indique
302 * A utiliser dans une boucle Articles
303 */
304function balise_TABLE_MATIERES_dist($p) {
305        $b = $p->nom_boucle ? $p->nom_boucle : $p->descr['id_mere'];
306        if ($b === '') {
307                erreur_squelette(
308                        _T('zbug_champ_hors_boucle',
309                                array('champ' => '#TABLE_MATIERES')
310                        ), $p->id_boucle);
311                $p->code = "''";
312        } else {
313                $_texte = champ_sql('texte', $p);
314                $p->code = "$_texte";
315        }
316        return $p;
317}
318
319
320
321?>
Note: See TracBrowser for help on using the repository browser.