Génération automatique de numérotation, table des matières et références

Voici un ensemble de nouveaux raccourcis typographiques pour gérer les titres de sections de façon plus évoluée. On obtient ainsi des titres à plusieurs niveaux, automatiquement numérotés et recensés avec une table des matières.

Nouveaux Raccourcis

Avec Tex (par exemple), on peut définir un certain nombre de titre de section et sous section. Ils seront ensuite numérotés automatiquement et si c’est nécessaire, une table des matières sera construite.

Par contre, dans SPIP, on ne peut définir qu’un niveau de section avec le raccourcis : {{{ma section}}}. Cette contrib utilise les points d’entrée dans inc_texte.php3 pour ajouter trois nouveaux raccourcis :

  1. {{{* ma section <référence>}}} {{{** ma sous section}}} etc...
  2. #TABLEMATIERES
  3. <référence>

Le premier jeux de raccourcis permet de faire une hiérarchisation des sections dans l’article. On pourra ainsi tapper :

{{{* Section de haut niveau }}}

du texte plein ...

{{{** Section de 2e niveau }}}

du texte plein ...

{{{*** Section de 3e niveau }}}

du texte plein ...

{{{*** autre Section de 3e niveau }}}

du texte plein ...

{{{* une autre Section de haut niveau }}}

du texte plein ...

et l’on obtiendra :


1 Section de haut niveau

du texte plein ...

1.1 Section de 2e niveau

du texte plein ...

1.1.1 Section de 3e niveau

du texte plein ...

1.1.2 autre Section de 3e niveau

du texte plein ...

2 une autre Section de haut niveau

du texte plein ...


La balise #TABLEMATIERES placée dans un article sera, quant à elle remplacée, par une liste des sections, avec des liens vers l’emplacement des sections dans la page [1]. Par exemple :


  • 1 Section de haut niveau
    • 1.1 Section de 2e niveau
      • 1.1.1 Section de 3e niveau
      • 1.1.2 autre Section de 3e niveau
  • 2 une autre Section de haut niveau

La dernière balise permet de référencer un numéro de section. Comme en Tex, on peut associer un raccourci à chaque section, grâce à : {{{** ma section <raccourci>}}}. On peut ensuite mettre dans le texte une référence qui sera plus tard remplacée par le numéro de la section et un lien dans le document.

on peut trouver un exemple ici.

Limitations

Deux sections ne peuvent pas avoir exactement le même titre (en comptant les espaces). On peut contourner cette limitation en mettant des espaces de plus à la fin de chaque titre.

On ne peut pas utiliser de < dans les titres de section. De même, pas de raccourcis docXXX, embXXX ou imgXXX.

Si vous voulez m’aider à réécrire cette expression régulière :

(($debut_intertitre(\\*+)([^<]*)(<([^>]*)>)?$fin_intertitre))

ça pourrait aider.

Code

Ce code s’insère dans mes_options.php3.

/*
 *   +----------------------------------+
 *    Nom :   Table des matieres                                               
 *   +----------------------------------+
 *    Date : aout 2004
 *    Auteur :  Mortimer Porte mortimer.pa@free.fr                                     
 *   +-------------------------------------+
 *    Fonctions de ce filtre :
 *     affiche une table des matières et génère automatiquement la numérotation des titres.
 *   +-------------------------------------+ 
 *  
 * Pour toute suggestion, remarque, proposition d'ajout
 * reportez-vous au forum de l'article :
 * http://www.spip-contrib.net/article.php3?id_article=627
*/
function table_des_matieres($texte) {
  global $debut_intertitre, $fin_intertitre;

   // définition de la balise pour les titres des sections %num% sera remplacé 
  // par la profondeur de la section
  $css_debut_intertitre = "\n<h3 class=\"spiphead%num%\">";
  $css_fin_intertitre = "</h3>\n";

  // on cherche les noms de section commençant par des *  
  $count = preg_match_all("(($debut_intertitre(\\*+)(.*?)(<(.*?)>)?$fin_intertitre))",$texte,$matches);
  $table = '';
  //initialisation du compteur
  $cnt[0] = 0;
  //initialisation du code de la table des matières
  $table = "\n<ins><div id=\"tablematiere\">\n";
  $lastlevel = 1;
  $cite[''] = '';

  //pour chaque titre trouvé
  for ($j=0; $j< $count; $j++) {
	$level = $matches[2][$j];
	$titre = $matches[3][$j];
	$ref = $matches[5][$j];
	if(strlen($level) == 1) {
           //on est au niveau de base
          //on réinitialise les compteurs
	  for ($i=1; $i < count($cnt); $i++) {
		$cnt[$i] = 0;
	  } 
          //on génère le titre et le numéros
	  $numeros = ++$cnt[0];
	  $titre = $numeros.' '.$titre;
	} else {
           //on est à un niveau plus profond
          // on construit le numéros
	  $numeros = $cnt[0].'.';
	  for ($i=1; $i < strlen($level)-1; $i++) {
		$numeros .= $cnt[$i].".";
	  }
	  $numeros = $numeros.(++$cnt[$i]);
          //on génère le titre
	  $titre = $numeros.' '.$titre;
	}

        //gestion de la liste dans la table
	if($lastlevel < strlen($level)) {
          //on ouvre une sous liste
	  $table .= "<ul>\n";
	}
	if($lastlevel > strlen($level)) {
          //on doit fermer les derniers niveaux
	  for ($i=0; $i < ($lastlevel - strlen($level)); $i++) {
             if($i+1==$lastlevel) {
               $table .= "\n</div></ins>";	// derniere fermeture
             } else {
               $table .= "</li>\n</ul>"; 
             }	
	  }
	}
	if($lastlevel >= strlen($level)) {
          //on doit fermer l'item précédent
	  if($cnt[0] > 1 || strlen($level) > 1) {
		$table .= "</li>\n";
	  }
	} 
       //on se rappelle du raccourcis
	$cite[$ref] = $numeros;
	$table .= "<li><a href=\"#$numeros\">$titre</a>";

       //on mémorise le niveau de ce titre
	$lastlevel = strlen($level);

        //on génère la balise avec le bon style pour le niveau
	$mdebut_intertitre = str_replace('%num%',$lastlevel,$css_debut_intertitre);
	$mfin_intertitre = str_replace('%num%',$lastlevel,$css_fin_intertitre);
        //on remplace le titre dans le texte
	$texte = str_replace($matches[0][$j],"$mdebut_intertitre<a name='$numeros'></a>$titre$mfin_intertitre",$texte);
  }
  //on fini la table
  for ($i=0; $i < $lastlevel; $i++) {
	$table .= "</li>\n</ul>";		
  }
  //on remplace les raccourcis par les numéros des sections.
  foreach ($cite as $ref => $num) {
	$texte = str_replace("<$ref>","<a href=\"#$num\">$num</a>",$texte);	
  }
  //on place la table des matières dans le texte
  $texte = str_replace('#TABLEMATIERES',$table,$texte);
  return $texte;
}

Il faut ensuite l’appeler depuis apres_propre, par exemple :

function apres_propre($texte) {
  $new_texte = table_des_matieres($texte);
  return $new_texte;
}

Style

le style de la table des matières ainsi que des différents niveaux sont gérés par du css. Il faut donc ajouter à vos fichier css, les classes spiphead1, spiphead2, ... (autant que de niveaux utilisés) ainsi que l’id #tablematiere

Notes

[1en utilisant des ancres html

Discussion

Aucune discussion

Ajouter un commentaire

Avant de faire part d’un problème sur un plugin X, merci de lire ce qui suit :

  • Désactiver tous les plugins que vous ne voulez pas tester afin de vous assurer que le bug vient bien du plugin X. Cela vous évitera d’écrire sur le forum d’une contribution qui n’est finalement pas en cause.
  • Cherchez et notez les numéros de version de tout ce qui est en place au moment du test :
    • version de SPIP, en bas de la partie privée
    • version du plugin testé et des éventuels plugins nécessités
    • version de PHP (exec=info en partie privée)
    • version de MySQL / SQLite
  • Si votre problème concerne la partie publique de votre site, donnez une URL où le bug est visible, pour que les gens puissent voir par eux-mêmes.
  • En cas de page blanche, merci d’activer l’affichage des erreurs, et d’indiquer ensuite l’erreur qui apparaît.

Merci d’avance pour les personnes qui vous aideront !

Par ailleurs, n’oubliez pas que les contributeurs et contributrices ont une vie en dehors de SPIP.

Qui êtes-vous ?
[Se connecter]

Pour afficher votre trombine avec votre message, enregistrez-la d’abord sur gravatar.com (gratuit et indolore) et n’oubliez pas d’indiquer votre adresse e-mail ici.

Ajoutez votre commentaire ici

Ce champ accepte les raccourcis SPIP {{gras}} {italique} -*liste [texte->url] <quote> <code> et le code HTML <q> <del> <ins>. Pour créer des paragraphes, laissez simplement des lignes vides.

Ajouter un document

Suivre les commentaires : RSS 2.0 | Atom