WikiNi

ActionSommaire

PagePrincipale :: DerniersChangements :: DerniersCommentaires :: ParametresUtilisateur :: Vous êtes 38.107.191.81
ListeActions

Introduction


Cette page décrit et commente un projet, initialement proposé par JeremieCook, pour ajouter une nouvelle action à WikiNi.
Cette nouvelle action, si elle est adoptée par l'équipe de développement, sera intégrée dans une future version de WikiNi.
D'ici là, ce travail constitue une ContributionsAvancees.

Fonctionnement


L'action {{tableofcontent}} crée un sommaire automatique de la page en cours.

Tous les titres de la page (== à =====) sont scannés et un sommaire est généré. Pour de longues pages, c'est très pratique. Des liens automatiques vers les titres (à l'aide d'une ancre) permettent d'accéder rapidement à toutes les sous rubriques.

Les modifications à apporter sont assez complexes mais ne pose aucun problème particulier. Si personne n'y voit d'inconvénient, je l'ajouterai à la version CVS quand j'en aurai la possibilité.

Toutes les suggestions sont les bienvenues. Les discussions peuvent prendre place sur la page ActionSommaireDiscussion.

Commentaires


C'est un vieux sujet que ta proposition : cf. AncresAutomatiquesPourLesTitres. Mais ton approche est plus pragmatique : les ancres ne servent qu'au sommaire à et à rien d'autre ce qui évite de se poser des questions métaphysiques sur l'usage des ancres ;) C'est toujours mieux que rien du tout... Une dernière question cependant, que je pose à tout le monde : idéalement, une page wiki devrait être très courte et les wikistes expérimentés conseillent la séparation en plusieurs pages lorsqu'une page prend de l'embonpoint (rendant donc tout sommaire inutile). Qu'avez-vous expérimenté ? Il vrai que sur wikini.net par exemple, il y a certaines pages assez longues... Pour l'intégration dans WikiNi je ne suis pas contre, la modification étant peu impactante, mais je préfèrerai avoir d'autres avis là-dessus et un petit délai de réflexion. -- CharlesNepote

Puisqu'un avis est demandé ;-) voici le mien. Les pages courtes c'est très bien mais ce n'est pas une obligation. J'utilise wikini pour rédiger des tutos (sur excel). Si pour avoir le cours complet il faut se cogner 12 pages différentes et les imprimer séparément ce n'est pas plus pratique que de faire une page un peu plus longue avec un sommaire. C'est comme en tout, une question de mesure... --MisAnge

C'est possible de créer des ancres qui possèdent le nom du titre. Je me suis inspiré, pour les numéros, de Dokuwiki. Pour éviter les problèmes de titres identiques (qui m'a fait renoncer à mettre le titre en toutes lettres), il suffit de le mettre sous la forme 1_Le_Titre, 2_La_Presentation etc. Si ça semble nécessaire je peux le faire. J'aimerais bien avoir d'autres avis également :) --JeremieCook


Bugs


Testé dans non nombreux cas, sans problème.

En cas d'erreur, prévenez moi que je corrige l'algorithme.
Le traitement avec les expressions régulières est très pénible. Penser à tous les de figure me semble assez illusoire (pour le nettoyage du code)

14/05/2005 -- JmPhilippe

Lorsqu'on pré-visualise une page, ce sont les titres de la page non modifiée qui apparaissent dans la page pré-visualisée. J'imagine qu'on peut récupérer le texte de la page modifiée, mais comment ????

02/06/2005 -- JmPhilippe

L'action ramasse aussi les titres qui sont dans des parties de code encadrées de %%. Là où ça devient vraiment gênant, c'est qu'il y a un nombre non négligeable de langages pour lesquels le signe == est utilisé pour les conditions... Je n'ai pas testé mais j'imagine qu'il y a le même genre de problème dans les parties de texte Html encadrées de "".

28/09/2005 -- AndreVignaud

Les titres de niveau 1 (======) sont pris en compte comme des titre de niveau 2 (cf. mes remarques en bas de page).
28/09/2005 -- LordFarquaad

Modifications à apporter


Dans formatters/wakka.php


Tout d'abord, une modification du fichier formatter de base. Pour ajouter les "ancres" qui permettront de faire un lien direct depuis le sommaire.
Le code était illisible, compliqué et fatiguant à comprendre parfaitement. J'ai commenté et éclairci les parties qui m'intéressaient. C'est un peu plus long, mais beaucoup plus facile à comprendre et modifier par la suite.

Il est même certainement possible de regrouper en un seul test les 5 types de header. Je m'en occuperai à l'occasion


1ere partie


Declaration de la variable statique numTitre vers le haut du fichier :







2ème partie


Le code de base :

// header level 5
                else if ($thing == "==")
                {
                        static $l5 = 0;
            $br = 0;
                        return (++$l5 % 2 ? "<h5>" : "</h5>");
                }
        // header level 4
                else if ($thing == "===")
                {
                        static $l4 = 0;
            $br = 0;
                        return (++$l4 % 2 ? "<h4>" : "</h4>");
                }
        // header level 3
                else if ($thing == "====")
                {
                        static $l3 = 0;
            $br = 0;
                        return (++$l3 % 2 ? "<h3>" : "</h3>");
                }
        // header level 2
                else if ($thing == "=====")
                {
                        static $l2 = 0;
            $br = 0;
                        return (++$l2 % 2 ? "<h2>" : "</h2>");
                }
        // header level 1
                else if ($thing == "======")
                {
                        static $l1 = 0;
            $br = 0;
                        return (++$l1 % 2 ? "<h1>" : "</h1>");
                }


à remplacer en :

// header level 5
                else if ($thing == "==")
                {
                        static $l5 = 0;
                        $br = 0;
                        
                        // Nouvelle occurence
                        ++$l5;

                        // Ouverture d'une balise de titre
                        if ($l5 % 2) 
                        {
                           ++$numTitre;
                           return "<h5><a name=\"$numTitre\">";
                        }

                        // Fermeture du titre precedent
                        else  
                        {
                           return "</a></h5>\n";
                        }

                }


        // header level 4
                else if ($thing == "===")
                {
                        static $l4 = 0;
                        $br = 0;
                        
                        // Nouvelle occurence
                        ++$l4;

                        // Ouverture d'une balise de titre
                        if ($l4 % 2)
                        {
                           ++$numTitre;
                           return "<h4><a name=\"$numTitre\">";
                        }

                        // Fermeture du titre precedent
                        else  
                        {
                           return "</a></h4>\n";
                        }
                }

        // header level 3
                else if ($thing == "====")
                {
                        static $l3 = 0;
                        $br = 0;

                        // Nouvelle occurence
                        ++$l3;

                        // Ouverture d'une balise de titre
                        if ($l3 % 2)
                        {
                           ++$numTitre;
                           return "<h3><a name=\"$numTitre\">";
                        }

                        // Fermeture du titre precedent
                        else
                        {
                           return "</a></h3>\n";
                        }
                }
                

        // header level 2
                else if ($thing == "=====")
                {
                        static $l2 = 0;
                        $br = 0;

                        // Nouvelle occurence
                        ++$l2;

                        // Ouverture d'une balise de titre
                        if ($l2 % 2)
                        {
                           ++$numTitre;
                           return "<h2><a name=\"$numTitre\">";
                        }

                        // Fermeture du titre precedent
                        else
                        {
                           return "</a></h2>\n";
                        }
                }
                

        // header level 1
                else if ($thing == "======")
                {
                        static $l1 = 0;
                        $br = 0;

                        // Nouvelle occurence
                        ++$l1;

                        // Ouverture d'une balise de titre
                        if ($l1 % 2)
                        {
                           ++$numTitre;
                           return "<h1><a name=\"$numTitre\">";
                        }

                        // Fermeture du titre precedent
                        else
                        {
                           return "</a></h1>\n";
                        }
                }

-- JeremieCook

Note : l'attribut "name" disparaît de la norme XHTML 1.1. Il serait peut-être plus judicieux d'utiliser "id" ? -- CharlesNepote


Dans actions/tableofcontent.php


Dans le répertoire actions, créer le fichier tableofcontent.php

en voila le contenu :

<?php
/*

toc.php : Affiche le sommaire de la page en cours



Copyright 2003  Jeremie COOK

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/


// Fonction de creation de sommaire


    
function creerSommaire ($tokens)
    {
       
$token $tokens[1];
       static 
$numTitre 0;

       return 
"<li>$token</li>";
    
    }


// Recuperation du contenu de la page

$page  $this->LoadPage($this->getPageTag());
$toc   $page["body"];

// Mise en forme du sommaire

$toc str_replace("\r"""$toc);
$toc chop($toc)."\n";




// Nettoyage des donnees (on ne garde que les titres)

$nonEgEg "([^=]*=?[^=]+)*"// Suite de caractères sans ==

$toc preg_replace("($nonEgEg((=){2,5})$nonEgEg((=){2,5})$nonEgEg)ms""\\2#NumTitre#\\4\\2 "$toc);


// Ajout des liens (dans l'ordre)

$toc preg_replace_callback("(#NumTitre#)ms",
      
create_function (
         
'$matches',
         
'static $numTitre = 0; return "#".++$numTitre."#";'
       
)
   , 
$toc);

// Remplacement des balises

$toc preg_replace("((=){6}#(([0-9]+))#($nonEgEg)(=){6} )""<li><h1><a href=\"#\\3\">\\4</h1></a></li>\n"$toc);
$toc preg_replace("((=){5}#(([0-9]+))#($nonEgEg)(=){5} )""<li><h2><a href=\"#\\3\">\\4</h2></a></li>\n"$toc);
$toc preg_replace("((=){4}#(([0-9]+))#($nonEgEg)(=){4} )""<li><h3><a href=\"#\\3\">\\4</h3></a></li>\n"$toc);
$toc preg_replace("((=){3}#(([0-9]+))#($nonEgEg)(=){3} )""<li><h4><a href=\"#\\3\">\\4</h4></a></li>\n"$toc);
$toc preg_replace("((=){2}#(([0-9]+))#($nonEgEg)(=){2} )""<li><h5><a href=\"#\\3\">\\4</h5></a></li>\n"$toc);




$toc preg_replace("/<br \/>$/",""trim($toc));

// Affichage

echo '<div id="sommaire">';
echo 
'<h2>Sommaire</h2>'."\n";
echo 
'<ul>'."\n";
echo 
$toc;
echo 
"\n".'</ul>'."\n";
echo 
'</div>';


?>


Dans la feuille de styles CSS


Reste à mettre quelques styles dans le CSS pour un format un peu plus présentable.



Commentaires et contributions


Je viens d'implémenter ces modifications. J'ai fait quelques modif dans le CSS pour obtenir un affichage "sympa". Seul problème, les ancres sont toutes nommées "1" !!! Je ne comprend pas ? -- JeanMorlet

Je viens d'ajouter dans cette page (1ere partie) la déclaration de la variable statique numTitre que j'avais oubliée dans le code à modifier. Une simple ligne parmi les déclarations et le problème doit être résolu. Pardon pour la confusion. --JeremieCook



Bonjour,
Je viens d'installer en local cette fonction et j'ai le lien ancre qui reste bloqué à "#1". De plus, la page ne s'affiche pas sous IE alors qu'elle s'affiche sous Firefox mais avec "#1" à chaque titre. J'ai recommencé les modifs deux fois. Une idée ?
Michel


Bonjour, n'est-ce pas le même problème que ci dessus ? As tu correctement ajouté la déclaration static $numTitre = 0; // <= Ajout de cette ligne ?

Merci pour cette contribution mais j'ai le même problème pour la numérotation des ancres. Elles restent toutes à "#1". Je pense avoir bien déclaré et édité les fichiers indiqués. Quelques idées ? -- SylvainBaillet.


Je trouve cette fonction intéressante, pourquoi ne pas l'intégrer dans la prochaine version ?


12/05/2005

Très pratique cette action mais je lui trouve quelques imperfections. J'en ai donc fait une variante disponible à la page ActionSommaireDiscussion afin de résoudre les problèmes suivants :

On trouvera sur la page ActionSommaireDiscussion le Php modifié ainsi que le CSS qui va bien. En espérant que ça serve...

-- JmPhilippe


27/09/2005

C'est la fonction que je cherchai à implémenté dans mon wiki...
Toutefois aprés l'avoir ajoutée à mon wiki, j'ai 3 remarques sur le code PHP :


09/01/2006
Pour ma part, je préfère ne pas avoir ces balises hX dans mon sommaire, pour qu'il reste léger graphiquement. A toutes fin utile, voici la portion de code a modifier pour avoir de simples liens dans une liste a puce. Les class .h1, .h2, etc permettent de modifier l'indentation.

// Remplacement des balises

$toc = preg_replace("((=){6}#(([0-9]+))#($nonEgEg)(=){6} )", "<li class=\"h1\"><a href=\"#\\3\">\\4</a></li>\n", $toc);
$toc = preg_replace("((=){5}#(([0-9]+))#($nonEgEg)(=){5} )", "<li class=\"h2\"><a href=\"#\\3\">\\4</a></li>\n", $toc);
$toc = preg_replace("((=){4}#(([0-9]+))#($nonEgEg)(=){4} )", "<li class=\"h3\"><a href=\"#\\3\">\\4</a></li>\n", $toc);
$toc = preg_replace("((=){3}#(([0-9]+))#($nonEgEg)(=){3} )", "<li class=\"h4\"><a href=\"#\\3\">\\4</a></li>\n", $toc);
$toc = preg_replace("((=){2}#(([0-9]+))#($nonEgEg)(=){2} )", "<li class=\"h5\"><a href=\"#\\3\">\\4</a></li>\n", $toc);



19/01/2006
Je viens d'essayer et avec quelques modifications trouvées dans la page de Discussion, ça marche très bien. Par contre j'ai des soucis quand un lien est dans un titre comme ici :
http://bookcrossing.apinc.org/wakka.php?wiki=FoireAuxQuestionsOfficielle

Je suis pour l'intégration de cette fonction dans les prochaines versions de WikiNi à condition de corriger deux trois bugs (celui que je cite mais aussi l'intégration des formatage dans le sommaire.
BriCe

Je pense aussi que ça devrait faire partie du package de base, c'est pourquoi dans les MaquettesStyleWikiniParDefaut il y a un sommaire affiché dans la page ! Malheureusement je crains de ne pas connaître suffisamment le moteur Wikini pour pouvoir aller plus loin dans le code de l'action. Il faudrait le soutien d'une personne plus compétente en la matière, notamment en Php ;-) . -- JmPhilippe


2006-08-22
Si je ne me trompe, cette action présente l'inconvéniant de ne pas bien fonctionner dans le cas où il y a des pages inclues (qui ne seront pas correctement prises en compte) ou s'il y a du code dans la page (le problème des ==). Je viens d'avoir une idée d'implémentation plus "poussée" mais qui devrait être fiable à 100%:
  1. en cours de rendu de la page, le formatteur wakka génère les encres pour les titres, et les sauve toutes quelque part (si on utilise la possibilité de GererLesActionsSousFormeDObjets, il pourrait transmettre directement cette information à l'ActionSommaire)
  2. lorsque l'ActionSommaire est appelée, elle fait deux choses:
    1. informer le formateur qu'il y a une demande d'affichage du sommaire
    2. "afficher" une balise spéciale, ne pouvant normalement figurer dans le texte (html) de sortie. Je pense que cette balise devrait faire l'affaire:
      • ""%%summary%%""
  3. après le formatage (attention aux appels récursifs du formateur !), deux cas sont possibles:
    1. l'ActionSommaire n'a pas été appelée
    2. l'ActionSommaire a été appelée
      • le formateur remplace les occurences de la balise spéciale par le résultat d'un appel "spécial" (une méthode) de l'ActionSommaire

De cette magnière on peut être certain que tous les titres seront correctement affichés et qu'il n'y aura aucun problème d'ancres - puisque tous les titres doivent passer obligatoirement par le formateur, qui en informe directement l'ActionSommaire.
Qu'en pensez-vous ?
-- LordFarquaad

Bonjour, rien de nouveau sur le sujet ????? -- JdX (implementation quelconque ??) -- JdX
Il y a un commentaire sur cette page. [Afficher commentaires/formulaire]