Changeset 43337 in spip-zone


Ignore:
Timestamp:
Jan 5, 2011, 12:44:02 AM (10 years ago)
Author:
marcimat@…
Message:

Passage en version 2 du plugin

  • réécriture partielle et documentation du code
  • configuration pour appliquer ou non le sommaire automatiquement
  • possibilité d'utiliser #TABLE_MATIERES sur d'autres tables que articles (nécessite un champ 'texte', mais l'on pourrait facilement adapter pour réaliser #TABLE_MATIERES{descriptif} par exemple)
  • fonction «table_matieres()» permettant de générer une table à partir de n'importe quelle chaine (la fonction retourne la chaine précédée de la table des matieres, mais peut retourner seulement le texte ou seulement la tdm).

Par conséquent, on peut utiliser dans ses squelettes cette écriture (qui génère les ancres correctement dans le texte) :

#TABLE_MATIERES
[(#TEXTE**|table_matieres{texte}|propre)]
  • suppression du #FOREACH (on pourra utiliser plus tard des POUR ou DATA au besoin) dans le modèle de table des matières.
Location:
_plugins_/table_matieres
Files:
1 deleted
9 edited

Legend:

Unmodified
Added
Removed
  • _plugins_/table_matieres/fonds/cfg_table_matieres.html

    r14399 r43337  
    1 [(#REM) icone=images/tdm.png]
    2 [(#REM) titre= Table des Matières]
    3 [(#REM) descriptif= Les param&egrave;tres configurables de la Table des Mati&egrave;res sont les suivants&nbsp;:<ul>
     1<!-- icone=images/tdm.png -->
     2<!-- titre= Table des Mati&egrave;res -->
     3<!-- descriptif= Les param&egrave;tres configurables de la Table des Mati&egrave;res sont les suivants&nbsp;:<ul>
    44<li>la <strong>longueur</strong> d&eacute;finit le nombre de caract&egrave;res maximum que consituera chaque ancres,</li>
    55<li>le <strong>s&eacute;parateur</strong> d&eacute;finit le caract&egrave;re qui s'intercalera entre chaque mot pour remplacer les espaces,</li>
    66<li>et le nombre d'<strong>intertitres minimum</strong> d&eacute;finit le nombre d'intertitres d'un texte &agrave; partir duquel une table des mati&egrave;res sera affich&eacute;e.</li>
    7 <ul>]
     7<ul>
     8-->
    89#CACHE{0}
    910<form method="post">[
     
    1213                <legend><:tdm:config:>&nbsp;:</legend>
    1314
     15                <p>
     16                        <label for= "auto"><:tdm:automatique:>&nbsp;:</label>
     17                        <label for="auto_oui"><:tdm:automatique_oui:></label>
     18                        <input type="radio" name="auto" id="auto_oui" size="4" [checked="(#ENV{auto,#EVAL{_AUTO_ANCRE}}|=={oui}|?{checked})"] value='oui' />
     19                        <label for="auto_non"><:tdm:automatique_non:></label>
     20                        <input type="radio" name="auto" id="auto_non" size="4" [checked="(#ENV{auto,#EVAL{_AUTO_ANCRE}}|!={oui}|?{checked})"] value='non' />
     21                        <p class='explications'>(<:tdm:automatique_desription:>)</p>
     22                </p>
     23                <hr />
     24               
    1425                <p>
    1526                        <label for= "lg"><:tdm:longueur:>&nbsp;: </label>
  • _plugins_/table_matieres/lang/tdm_fr.php

    r17284 r43337  
    44
    55        $GLOBALS['i18n_tdm_fr'] = array(
     6                'automatique' => "La table des mati&egrave;res est-elle g&eacute;n&eacute;r&eacute;e automatiquement ?",
     7                'automatique_oui' => "Oui",
     8                'automatique_non' => "Non",
     9                'automatique_desription' => "D&eacute;sactivez cette option si vous placez vous-m&ecirc;me
     10                        la balise <code>#TABLE_MATIERES</code> dans vos squelettes.",
    611                'config' => 'Param&egrave;tres',
    712                'longueur' => 'Longueur',
  • _plugins_/table_matieres/modeles/table_matieres.html

    r13952 r43337  
    22        <h2 class="menu-titre"><:tdm:table_matiere:></h2>
    33        <ul>
    4                 (#FOREACH{TDM})
     4                (#ENV*{code})
    55        </ul>
    66</div>]
  • _plugins_/table_matieres/plugin.xml

    r43331 r43337  
    11<plugin>
    22        <nom>Table des Mati&#232;res</nom>
    3         <version>1.1</version>
     3        <version>2.0</version>
    44        <prefix>TableMatieres</prefix>
    55        <fonctions>table_matieres.php</fonctions>
  • _plugins_/table_matieres/table_matieres.php

    r43333 r43337  
    77$tm = @unserialize($GLOBALS['meta']['table_matieres']);
    88
     9define('_AUTO_ANCRE', isset($tm['auto']) ? $tm['auto'] : 'oui');
    910define('_LG_ANCRE', isset($tm['lg']) ? $tm['lg'] : 35);
    1011define('_SEP_ANCRE', isset($tm['sep']) ? $tm['sep'] : '-');
     
    1415        '" /></a>');
    1516
    16 
    17 function TableMatieres_Table($url = '', $titre = '', $cId = 0, $vider_table = false) {
    18         static $table = array();
    19         if($vider_table) return ($table = array());
    20         if($url == '') return $table;
    21         $url = array_key_exists($url, $table) ? $url.$cId : $url;
    22         $table[$url] = $titre;
    23         return $url;
    24 }
    25 
    26 function TableMatieres_SiNombreSuffisantIntertitres() {
    27         $table = TableMatieres_Table();
    28         if (count($table) < _MIN_ANCRE)
    29                 return array();
    30         return $table;
    31        
    32 }
    33 
    34 function TableMatieres_ViderTable() {
    35         return TableMatieres_Table('', '', 0, true);
    36 }
    37 
    38 function TableMatieres_BalisePresente($test = false) {
    39         static $flag = false;
    40         if($test) $flag = $test;
    41         return $flag;
    42 }
    43 
    44 function TableMatieres_Callback($matches, $retour_cId = false) {
    45         static $cId = 0;
    46         if($retour_cId) return $cId;
    47         $cId++;
    48         $titre = supprimer_tags(typo($matches[1]));
     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));
    49170        $titre = preg_replace(",\n[_\s]*,", " ", $titre);
    50171        $url = translitteration($titre);
     
    69190                if (strlen($url) < 2) $url = "ancre$cId";
    70191        }
    71         $url = TableMatieres_Table($url, $titre, $cId);
    72         return '{{{ ['.$url.'<-] '.$matches[1].' @@RETOUR_TDM@@ }}}';
    73 }
    74 
    75 function TableMatieres_AjouterAncres($texte) {
    76         static $textes = array();
    77         $md5 = md5($texte);
    78         if(!isset($textes[$md5])) {
    79                 // 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_ancre = echappe_html($texte, 'TDM', true);
    83                 $texte_ancre = preg_replace_callback("/{{{(.*)}}}/UmsS", 'TableMatieres_Callback', $texte_ancre);
    84                 $nb_ancres = TableMatieres_Callback('', true);
    85                 if ($nb_ancres >= _MIN_ANCRE) {
    86                         $textes[$md5] = echappe_retour($texte_ancre, 'TDM');
    87                 } else {
    88                         $textes[$md5] = $texte;
    89                 }
    90         }
    91         return $textes[$md5];
    92 }
    93 
    94 function TableMatieres_LienRetour($texte, $affiche_table = false) {
    95         $_RETOUR_TDM = preg_replace(',<img,i',
    96         '<img alt="'._T('tdm:retour_table_matiere').'" title="'._T('tdm:retour_table_matiere').'"',
    97         _RETOUR_TDM);
    98 
    99         // s'il y a moins d'ancres que ce que la config demande, on n'affiche rien
    100         if ($affiche_table AND !TableMatieres_SiNombreSuffisantIntertitres()) {
    101                 return $texte;
    102         }
    103 
     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 *
     244**/
     245function tdm_ajouter_liens_retour_table_matieres($texte) {
     246       
     247        // prendre en compte la langue en cours
     248        $_RETOUR_TDM = preg_replace(
     249                ',<img,i',
     250                '<img alt="' . _T('tdm:retour_table_matiere')
     251                .'" title="' . _T('tdm:retour_table_matiere') . '"',
     252                _RETOUR_TDM);
     253
     254        # Si demande en javascript... (pas tres propre, a refaire avec un js externe)
     255        if (TDM_JAVASCRIPT AND !test_espace_prive() AND !_AJAX # crayons
     256        ) {
     257                $_RETOUR_TDM = '<script type="text/javascript"><!--
     258                document.write("'.str_replace('"', '\\"', $_RETOUR_TDM).'");
     259                --></script>';
     260        }
     261       
     262        return str_replace('@@RETOUR_TDM@@', $_RETOUR_TDM, $texte);
     263}
     264
     265
     266/**
     267 * Générer une table des matieres a partir du tableau
     268 * d'intertitres donnes
     269 *
     270 * @param array couples liens/intertitres
     271 * @return string       Code HTML de la table des matieres
     272**/
     273function tdm_generer_table_des_matieres($intertitres) {
     274        // generer un code HTML
     275        $code = "";
     276        foreach ($intertitres as $url=>$titre) {
     277                $code .= "<li><a href='#$url'>$titre</a></li>\n";
     278        }
    104279        // code HTML de la table des matieres
    105         $_table = recuperer_fond('modeles/table_matieres');
     280        $_table = recuperer_fond('modeles/table_matieres', array(
     281                'code' => $code,
     282                'tableau'=>$intertitres
     283        ));
    106284
    107285        # version en javascript (pas tres propre, a refaire avec un js externe)
     
    114292                        $("div.encart").html($("div.encart").attr("rel")).attr("rel","");
    115293                        --></script>';
    116                 $_RETOUR_TDM = '<script type="text/javascript"><!--
    117                 document.write("'.str_replace('"', '\\"', $_RETOUR_TDM).'");
    118                 --></script>';
    119         }
    120 
    121         return $affiche_table ?
    122                 $_table :
    123                 (((TableMatieres_BalisePresente() OR !strlen(trim($_table))) ? //calcul :)
    124                         '' : $_table."\n\n").
    125                 str_replace('@@RETOUR_TDM@@', $_RETOUR_TDM, $texte));
     294        }
     295
     296        return $_table;
    126297}
    127298
     
    139310                        ), $p->id_boucle);
    140311                $p->code = "''";
    141         } elseif($p->type_requete != 'articles') {
    142                 erreur_squelette(_T('tdm:zbug_champ_tdm_hors_boucle_articles'), $p->id_boucle);
    143                 $p->code = "''";
    144312        } else {
    145                 if(TableMatieres_BalisePresente(true)) { //REcalcul :(
    146                         $_texte = champ_sql('texte', $p);
    147                         $p->code = "$_texte";
    148                 }
     313                $_texte = champ_sql('texte', $p);
     314                $p->code = "$_texte";
    149315        }
    150316        return $p;
     
    152318
    153319
    154 function balise_TDM_dist($p) {
    155         if(function_exists('balise_ENV'))
    156                 return balise_ENV($p, 'TableMatieres_SiNombreSuffisantIntertitres()');
    157         else
    158                 return balise_ENV_dist($p, 'TableMatieres_SiNombreSuffisantIntertitres()');
    159         return $p;
    160 }
    161320
    162321?>
  • _plugins_/table_matieres/tdm_pipelines.php

    r43331 r43337  
    1313function TableMatieres_declarer_tables_interfaces($interface){
    1414        include_spip('table_matieres');
    15         $interface['table_des_traitements']['TEXTE']['articles'] =
    16                 str_replace(
    17                         '%s',
    18                         'TableMatieres_LienRetour(TableMatieres_AjouterAncres(%s))',
     15
     16        // ne retourner que la table des matieres du texte fourni (champ texte)
     17        $interface['table_des_traitements']['TABLE_MATIERES'] = 'table_matieres(%s, \'tdm\')';
     18
     19        // traiter les articles si le sommaire automatique est actif
     20        if (_AUTO_ANCRE == 'oui') {
     21                $traitements_actuels =
    1922                        isset($interface['table_des_traitements']['TEXTE']['articles'])
    2023                                ? $interface['table_des_traitements']['TEXTE']['articles']
    21                                 : $interface['table_des_traitements']['TEXTE'][0]
    22                 );
    23         $interface['table_des_traitements']['TABLE_MATIERES']['articles']= 'TableMatieres_LienRetour(TableMatieres_AjouterAncres(%s), true)';
     24                                : $interface['table_des_traitements']['TEXTE'][0];
     25                               
     26                // completer les traitements actuels, mais le sommaire automatique passe en preum's
     27                $interface['table_des_traitements']['TEXTE']['articles'] =
     28                        str_replace('%s', 'table_matieres(%s)', $traitements_actuels);
     29        }
     30       
    2431        return $interface;
    2532}
  • _plugins_/table_matieres/tests/affichage_explicite.html

    r14611 r43337  
    77]
    88<BOUCLE_a(ARTICLES){texte==({{{)}{0,1}>
    9 [(#TABLE_MATIERE|?{OK,Erreur: pas de table affichée})]
     9[(#TABLE_MATIERES|?{OK,Erreur: pas de table affichée})]
    1010</BOUCLE_a>
    1111Il faut au moins un article avec des intertitres
  • _plugins_/table_matieres/tests/affichage_implicite.html

    r14611 r43337  
    22        TABLE_MATIERES page avec appel implicite
    33]
    4 <BOUCLE_a(ARTICLES){texte==({{{)}{0,1}>
    5 [(#TEXTE|match{<div class="encart">}|?{OK,Erreur: pas de table affichée})]
     4<BOUCLE_a(ARTICLES){texte==({{{)}{0,4}>
     5[(#TEXTE|match{<div class="encart"}|?{OK,Erreur: pas de table affichée})]
    66</BOUCLE_a>
    77Il faut au moins un article avec des intertitres
  • _plugins_/table_matieres/tests/bug1.php

    r17284 r43337  
    2424
    2525        //deux textes differents ne doivent pas renvoye un texte identique
    26         if(TableMatieres_AjouterAncres($c) ==
    27         TableMatieres_AjouterAncres($d))
     26        if(table_matieres($c) ==
     27        table_matieres($d))
    2828                die('bug reproduit');
    2929
    3030        //un texte qui passe une deuxieme fois pour afficher la balise #TABLE_MATIERE
    31         if(TableMatieres_AjouterAncres($c) !=
    32         TableMatieres_AjouterAncres($c))
     31        if(table_matieres($c) !=
     32        table_matieres($c))
    3333                die('bug introduit');
    3434
Note: See TracChangeset for help on using the changeset viewer.