Browse Source
ainsi que de la lame sommaire du couteau suisse Fonctionnement : Par configuration on peut choisir de : ne jamais inserer automatiquement le sommaire dans le texte de l'article, l'inserer à la demande uniquement, en presence du reccourci <sommaire>, l'inserer toujours Le plugin fournit egalement les outils pour afficher le sommaire depuis les squelettes : #SOMMAIRE{#TEXTE} affiche le sommaire correspondant aux intertitres de #TEXTE, en prenant soin d'eviter toute duplication des notes [(#TEXTE|ancres_sommaire)] ajoute les ancres sur les intertitres complementaires du sommaire [(#TEXTE|retire_sommaire)] retire le sommaire eventuellement ajoute automatiquement a un #TEXTE [(#TEXTE|retire_ancres_sommaire)] retire les ancres sur les intertitres ajoutees automatiquement a un #TEXTE Le plugin ajoute automatiquement la css css/sommaire.css surchargeable dans le squelette Le sommaire est construit a partir de modeles/sommaire.html qui reçoit la hierarchie complète des titres, charge a lui de n'afficher qu'un niveau ou de tronquer les titres si besoin dans le sommaire.svn/root/tags/v1.2.5

commit
058a3bd491
15 changed files with 438 additions and 0 deletions
@ -0,0 +1,15 @@
|
||||
* text=auto !eol |
||||
css/img/sommaire-up-16.png -text |
||||
css/sommaire.css -text |
||||
formulaires/configurer_sommaire.html -text |
||||
lang/paquet-sommaire_fr.php -text |
||||
lang/sommaire_fr.php -text |
||||
modeles/sommaire.html -text |
||||
/paquet.xml -text |
||||
prive/squelettes/contenu/configurer_sommaire.html -text |
||||
prive/style_prive_plugin_sommaire.html -text |
||||
prive/themes/spip/images/sommaire-128.png -text |
||||
prive/themes/spip/images/sommaire-32.png -text |
||||
prive/themes/spip/images/sommaire-64.png -text |
||||
prive/themes/spip/images/sommaire-up-16.png -text |
||||
/sommaire_fonctions.php -text |
After Width: | Height: | Size: 47 KiB |
@ -0,0 +1,5 @@
|
||||
.nav-sommaire {border: 1px solid #eee;margin-left: 30%;margin-bottom: 1.5em;} |
||||
.nav-sommaire h2 {font-size: inherit;text-transform: uppercase;} |
||||
.nav-sommaire ul {} |
||||
|
||||
a.sommaire-back {color:#DDD;display:block;width:16px;height:16px;background:url(img/sommaire-up-16.png) no-repeat center;float: right;opacity:0.5;} |
@ -0,0 +1,45 @@
|
||||
<div class="formulaire_spip formulaire_configurer formulaire_#FORM"> |
||||
|
||||
<h3 class="titrem"><:sommaire:cfg_titre_parametrages:></h3> |
||||
|
||||
[<p class="reponse_formulaire reponse_formulaire_ok">(#ENV*{message_ok})</p>] |
||||
[<p class="reponse_formulaire reponse_formulaire_erreur">(#ENV*{message_erreur})</p>] |
||||
|
||||
<form method="post" action="#ENV{action}"> |
||||
<div> |
||||
#ACTION_FORMULAIRE{#ENV{action}} |
||||
<input type="hidden" name="_meta_table" value="meta" /> |
||||
|
||||
#SET{fl,sommaire} |
||||
<ul> |
||||
#SET{name,sommaire_automatique}#SET{obli,''}#SET{defaut,'on'}#SET{erreurs,#ENV**{erreurs}|table_valeur{#GET{name}}} |
||||
<li class="editer editer_[(#GET{name})][ (#GET{obli})][ (#GET{erreurs}|oui)erreur]"> |
||||
<label>[(#GET{fl}|concat{':label_',#GET{name}}|_T)]</label>[ |
||||
<span class='erreur_message'>(#GET{erreurs})</span> |
||||
] |
||||
#SET{val,off} |
||||
<div class="choix"> |
||||
<input type="radio" name="#GET{name}" class="radio" id="#GET{name}_#GET{val}" value="#GET{val}"[(#ENV{#GET{name},#GET{defaut}}|=={#GET{val}}|oui)checked="checked"] /> |
||||
<label for="#GET{name}_#GET{val}">[(#GET{fl}|concat{':label_',#GET{name},'_',#GET{val}}|_T)]</label> |
||||
<p class="explication"><:sommaire:explication_sommaire_automatique_off:></p> |
||||
<br/> |
||||
</div> |
||||
#SET{val,ondemand} |
||||
<div class="choix"> |
||||
<input type="radio" name="#GET{name}" class="radio" id="#GET{name}_#GET{val}" value="#GET{val}"[(#ENV{#GET{name},#GET{defaut}}|=={#GET{val}}|oui)checked="checked"] /> |
||||
<label for="#GET{name}_#GET{val}">[(#GET{fl}|concat{':label_',#GET{name},'_',#GET{val}}|_T)]</label> |
||||
<p class="explication"><:sommaire:explication_sommaire_automatique_ondemand:></p> |
||||
<br/> |
||||
</div> |
||||
#SET{val,on} |
||||
<div class="choix"> |
||||
<input type="radio" name="#GET{name}" class="radio" id="#GET{name}_#GET{val}" value="#GET{val}"[(#ENV{#GET{name},#GET{defaut}}|=={#GET{val}}|oui)checked="checked"] /> |
||||
<label for="#GET{name}_#GET{val}">[(#GET{fl}|concat{':label_',#GET{name},'_',#GET{val}}|_T)]</label> |
||||
</div> |
||||
</li> |
||||
</ul> |
||||
|
||||
<p class="boutons"><span class="image_loading"> </span><input type="submit" class="submit" value="<:bouton_enregistrer:>" /></p> |
||||
</div> |
||||
</form> |
||||
</div> |
@ -0,0 +1,14 @@
|
||||
<?php |
||||
// This is a SPIP language file -- Ceci est un fichier langue de SPIP |
||||
|
||||
if (!defined('_ECRIRE_INC_VERSION')) return; |
||||
|
||||
$GLOBALS[$GLOBALS['idx_lang']] = array( |
||||
|
||||
// S |
||||
'sommaire_description' => 'Générer un sommaire automatique pour les articles.', |
||||
'sommaire_nom' => 'Sommaire automatique', |
||||
'sommaire_slogan' => 'Un sommaire pour vos articles', |
||||
); |
||||
|
||||
?> |
@ -0,0 +1,31 @@
|
||||
<?php |
||||
// This is a SPIP language file -- Ceci est un fichier langue de SPIP |
||||
|
||||
if (!defined('_ECRIRE_INC_VERSION')) return; |
||||
|
||||
$GLOBALS[$GLOBALS['idx_lang']] = array( |
||||
|
||||
// S |
||||
'sommaire_titre' => 'Sommaire automatique', |
||||
|
||||
// C |
||||
'cfg_exemple' => 'Exemple', |
||||
'cfg_exemple_explication' => 'Explication de cet exemple', |
||||
'cfg_titre_parametrages' => 'Paramétrages', |
||||
|
||||
// L |
||||
'label_sommaire_automatique' => 'Insertion du sommaire d\'article', |
||||
'label_sommaire_automatique_off' => 'Aucune insertion dans le texte des articles', |
||||
'explication_sommaire_automatique_off' => 'Le sommaire est inséré dans le squelette par le webmestre.', |
||||
'label_sommaire_automatique_ondemand' => 'Insertion dans le texte des articles à la demande', |
||||
'explication_sommaire_automatique_ondemand' => 'Le sommaire est inséré uniquement en présence du raccourci <tt><sommaire></tt> dans le texte des articles.', |
||||
'label_sommaire_automatique_on' => 'Insertion automatique sur tous les articles', |
||||
|
||||
// T |
||||
'titre_page_configurer_sommaire' => 'Sommaire automatique', |
||||
|
||||
'titre_retour_sommaire' => 'Retour au sommaire', |
||||
'titre_cadre_sommaire' => 'Sommaire', |
||||
); |
||||
|
||||
?> |
@ -0,0 +1,8 @@
|
||||
<div class="well nav-sommaire"> |
||||
<h2><:sommaire:titre_cadre_sommaire:></h2> |
||||
<B_somm> |
||||
<BOUCLE_somm(POUR){tableau #ENV{sommaire}}> |
||||
-[(#VAL{*}|str_pad{#VALEUR{niveau},'*'})] [#VALEUR{id}<-][#VALEUR{titre}->#VALEUR{href}]</BOUCLE_somm> |
||||
</B_somm> |
||||
</div> |
||||
#FILTRE{propre} |
@ -0,0 +1,24 @@
|
||||
<paquet |
||||
prefix="sommaire" |
||||
categorie="edition" |
||||
version="1.0.3" |
||||
etat="test" |
||||
compatibilite="[3.0.0;3.0.*]" |
||||
logo="prive/themes/spip/images/sommaire-64.png" |
||||
documentation="" |
||||
> |
||||
|
||||
<nom>Sommaire automatique</nom> |
||||
|
||||
<!-- cette balise peut être présente plusieurs fois s'il y a plusieurs auteurs --> |
||||
<auteur lien="http://contrib.spip.net/auteur5384">Cédric</auteur> |
||||
<credit lien="http://contrib.spip.net/auteur6809">James</credit> |
||||
<credit lien="http://contrib.spip.net/auteur5714">Patrice Vanneufville</credit> |
||||
<credit lien="http://contrib.spip.net/auteur83">NoPlay</credit> |
||||
|
||||
<licence>GNU/GPL</licence> |
||||
|
||||
<pipeline nom="declarer_tables_interfaces" inclure="sommaire_fonctions.php" /> |
||||
<pipeline nom="insert_head_css" inclure="sommaire_fonctions.php" /> |
||||
|
||||
</paquet> |
@ -0,0 +1,7 @@
|
||||
[(#AUTORISER{configurer,_sommaire}|sinon_interdire_acces)] |
||||
|
||||
<h1 class="grostitre"><:sommaire:titre_page_configurer_sommaire:></h1> |
||||
|
||||
<div class="ajax"> |
||||
#FORMULAIRE_CONFIGURER_SOMMAIRE |
||||
</div> |
@ -0,0 +1,18 @@
|
||||
[(#REM) |
||||
|
||||
Ce squelette definit les styles de l'espace prive |
||||
|
||||
Note: l'entete "Vary:" sert a repousser l'entete par |
||||
defaut "Vary: Cookie,Accept-Encoding", qui est (un peu) |
||||
genant en cas de "rotation du cookie de session" apres |
||||
un changement d'IP (effet de clignotement). |
||||
|
||||
ATTENTION: il faut absolument le charset sinon Firefox croit que |
||||
c'est du text/html ! |
||||
<style> |
||||
] |
||||
#wysiwyg .nav-sommaire {border: 1px solid #eee;margin-left: 30%;margin-bottom: 1.5em;} |
||||
#wysiwyg .nav-sommaire h2 {background: #eee;font-size: inherit;text-transform: uppercase;padding:0.5em;} |
||||
#wysiwyg .nav-sommaire ul {} |
||||
|
||||
a.sommaire-back {color:#DDD;display:block;width:16px;height:16px;background:url(#CHEMIN_IMAGE{sommaire-up-16.png}) no-repeat center;float: #ENV{right};opacity:0.5;} |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 47 KiB |
@ -0,0 +1,271 @@
|
||||
<?php |
||||
/** |
||||
* Plugin Sommaire automatique |
||||
* (c) 2013 Cédric |
||||
* Licence GNU/GPL |
||||
*/ |
||||
|
||||
if (!defined('_ECRIRE_INC_VERSION')) return; |
||||
|
||||
/** |
||||
* Filtre |retire_sommaire |
||||
* pour retirer le sommaire automatique et les ancres d'un texte |
||||
* @param string $texte |
||||
* @return string |
||||
*/ |
||||
function retire_sommaire($texte){ |
||||
// retirer le sommaire |
||||
if (strpos($texte,"<!--sommaire-->")!==false) |
||||
$texte = preg_replace(",<!--sommaire-->.*<!--/sommaire-->,Uims","",$texte); |
||||
return $texte; |
||||
} |
||||
|
||||
/** |
||||
* Filtre |retire_ancres_sommaire |
||||
* pour retirer les ancres vers le sommaire qui aont ete ajoutee automatiquement sur un texte |
||||
* @param $texte |
||||
* @return mixed |
||||
*/ |
||||
function retire_ancres_sommaire($texte){ |
||||
// retirer les liens de retour au sommaire |
||||
if (strpos($texte,"sommaire-back")!==false) |
||||
$texte = preg_replace(",<a class='sommaire-back'[^>]*></a>,Uims","",$texte); |
||||
return $texte; |
||||
} |
||||
|
||||
/** |
||||
* Filtre |ancres_sommaire |
||||
* pour ajouter les ancres de sommaire du les intertitres d'un texte |
||||
* @param string $texte |
||||
* @return string |
||||
*/ |
||||
function ancres_sommaire($texte){ |
||||
$texte = sommaire_post_propre($texte, false); |
||||
return $texte; |
||||
} |
||||
|
||||
/** |
||||
* Balise #SOMMAIRE pour afficher le sommaire d'un contenu |
||||
* #SOMMAIRE{#TEXTE} |
||||
* gere les notes pour eviter leur doublement |
||||
* |
||||
* @param $p |
||||
* @return mixed |
||||
*/ |
||||
function balise_SOMMAIRE_dist($p){ |
||||
$_texte = interprete_argument_balise(1,$p); |
||||
|
||||
$p->code = "sommaire_empile_note().affiche_sommaire($_texte).sommaire_depile_note()"; |
||||
$p->interdire_scripts = false; // le contenu vient d'un modele |
||||
return $p; |
||||
} |
||||
|
||||
/* |
||||
* Protected |
||||
*/ |
||||
|
||||
function sommaire_insert_head_css($flux){ |
||||
$flux .= '<link rel="stylesheet" type="text/css" href="'.find_in_path('css/sommaire.css').'"/>'."\n"; |
||||
return $flux; |
||||
} |
||||
|
||||
/** |
||||
* Affiche le sommaire d'un texte |
||||
* @param string $texte |
||||
* @return string |
||||
*/ |
||||
function affiche_sommaire($texte){ |
||||
// retirer le(s) sommaire(s) eventuel(s) deja la avant de re-calculer le sommaire |
||||
return sommaire_post_propre(retire_sommaire($texte), $ajoute=true, $sommaire_seul=true); |
||||
} |
||||
|
||||
/** |
||||
* Empile les notes avant evaluation du texte sur lequel est calcule #SOMMAIRE |
||||
* @return string |
||||
*/ |
||||
function sommaire_empile_note(){$notes = charger_fonction('notes','inc');$notes('','empiler');return '';} |
||||
/** |
||||
* Depile les notes apres calcul de #SOMMAIRE |
||||
* @return string |
||||
*/ |
||||
function sommaire_depile_note(){$notes = charger_fonction('notes','inc');$notes('','depiler');return '';} |
||||
|
||||
|
||||
/** |
||||
* Ajouter le calcul du sommaire automatique sur les textes d'article |
||||
* @param $interfaces |
||||
* @return mixed |
||||
*/ |
||||
function sommaire_declarer_tables_interfaces($interfaces){ |
||||
$traitement = $interfaces['table_des_traitements']['TEXTE'][0]; |
||||
if (isset($interfaces['table_des_traitements']['TEXTE']['articles'])) |
||||
$traitement = $interfaces['table_des_traitements']['TEXTE']['articles']; |
||||
|
||||
$traitement = str_replace("propre(","sommaire_propre(",$traitement); |
||||
$interfaces['table_des_traitements']['TEXTE']['articles']= $traitement; |
||||
|
||||
return $interfaces; |
||||
} |
||||
|
||||
function sommaire_propre($texte, $connect, $env){ |
||||
$texte = propre($texte,$connect,$env); |
||||
if ( |
||||
!isset($GLOBALS['meta']['sommaire_automatique']) |
||||
OR $GLOBALS['meta']['sommaire_automatique']=="on" |
||||
OR ($GLOBALS['meta']['sommaire_automatique']=="ondemand" AND strpos($texte,"<sommaire>")!==false) |
||||
){ |
||||
$texte = sommaire_post_propre($texte); |
||||
} |
||||
return $texte; |
||||
} |
||||
|
||||
/** |
||||
* evite les transformations typo dans les balises $balises |
||||
* par exemple pour <html>, <cadre>, <code>, <frame>, <script>, <acronym> et <cite>, $balises = 'html|code|cadre|frame|script|acronym|cite' |
||||
* |
||||
* @param $texte |
||||
* $texte a filtrer |
||||
* @param $filtre |
||||
* le filtre a appliquer pour transformer $texte |
||||
* si $filtre = false, alors le texte est retourne protege, sans filtre |
||||
* @param $balises |
||||
* balises concernees par l'echappement |
||||
* si $balises = '' alors la protection par defaut est sur les balises de _PROTEGE_BLOCS |
||||
* si $balises = false alors le texte est utilise tel quel |
||||
* @param null|array $args |
||||
* arguments supplementaires a passer au filtre |
||||
* @return string |
||||
*/ |
||||
function sommaire_filtre_texte_echappe($texte, $filtre, $balises='', $args=NULL){ |
||||
if(!strlen($texte)) return ''; |
||||
|
||||
if ($filtre!==false){ |
||||
$fonction = chercher_filtre($filtre,false); |
||||
if (!$fonction) { |
||||
spip_log("sommaire_filtre_texte_echappe() : $filtre() non definie",_LOG_ERREUR); |
||||
return $texte; |
||||
} |
||||
$filtre = $fonction; |
||||
} |
||||
|
||||
// protection du texte |
||||
if($balises!==false) { |
||||
if(!strlen($balises)) $balises = _PROTEGE_BLOCS;//'html|code|cadre|frame|script'; |
||||
else $balises = ',<('.$balises.')(\s[^>]*)?>(.*)</\1>,UimsS'; |
||||
if (!function_exists('echappe_html')) |
||||
include_spip('inc/texte_mini'); |
||||
$texte = echappe_html($texte, 'FILTRETEXTECHAPPE', true, $balises); |
||||
} |
||||
// retour du texte simplement protege |
||||
if ($filtre===false) return $texte; |
||||
// transformation par $fonction |
||||
if (!$args) |
||||
$texte = $filtre($texte); |
||||
else { |
||||
array_unshift($args,$texte); |
||||
$texte = call_user_func_array($filtre, $args); |
||||
} |
||||
|
||||
// deprotection des balises |
||||
return echappe_retour($texte, 'FILTRETEXTECHAPPE'); |
||||
} |
||||
|
||||
function sommaire_filtre($texte, $ajoute=true, $sommaire_seul=false){ |
||||
$sommaire = sommaire_recenser($texte); |
||||
|
||||
if ($ajoute OR $sommaire_seul){ |
||||
$sommaire = recuperer_fond("modeles/sommaire",array('sommaire'=>$sommaire)); |
||||
$sommaire = "<!--sommaire-->$sommaire<!--/sommaire-->"; |
||||
if ($sommaire_seul) |
||||
return $sommaire; |
||||
if ($p = strpos($texte,"<sommaire>")){ |
||||
$texte = substr_replace($texte,$sommaire,$p,strlen("<sommaire>")); |
||||
} |
||||
else |
||||
$texte = $sommaire . $texte; |
||||
} |
||||
|
||||
return $texte; |
||||
} |
||||
|
||||
function sommaire_post_propre($texte, $ajoute=true, $sommaire_seul=false){ |
||||
if (strpos($texte, '<h')!==false) |
||||
$texte = sommaire_filtre_texte_echappe($texte,'sommaire_filtre','html|code|cadre|frame|script|acronym|cite',array($ajoute,$sommaire_seul)); |
||||
return $texte; |
||||
} |
||||
|
||||
// renvoie le sommaire d'une page d'article |
||||
// $page=false reinitialise le compteur interne des ancres |
||||
function sommaire_recenser(&$texte) { |
||||
$sommaire = array(); |
||||
$ancres_vues = array(); |
||||
|
||||
// traitement des intertitres <hx> |
||||
preg_match_all(",(<h([123456])[^>]*>)(.*)(</h\\2>),Uims", $texte, $matches,PREG_SET_ORDER); |
||||
if (!count($matches)) |
||||
return $texte; |
||||
|
||||
$debutsommairedejala = strpos($texte,'<!--sommaire-->'); |
||||
$finsommairedejala = strpos($texte,'<!--/sommaire-->'); |
||||
|
||||
// trouver le niveau mini des hn qui consitue le niveau 1 du sommaire |
||||
$toplevel = 6; |
||||
foreach($matches as $m){ |
||||
$toplevel = min($toplevel,$m[2]); |
||||
if ($toplevel==1) break; |
||||
} |
||||
#var_dump($toplevel); |
||||
|
||||
$currentpos = 0; |
||||
$titleretour = attribut_html(_T('sommaire:titre_retour_sommaire')); |
||||
|
||||
foreach($matches as $m){ |
||||
if (($pos = strpos($texte, $m[0], $currentpos))!==false |
||||
AND ($pos<$debutsommairedejala OR $pos>=$finsommairedejala)) { |
||||
|
||||
$titre = $m[3]; |
||||
$titre = preg_replace(",</?a\b[^>]*>,Uims","",$titre); |
||||
$ancre = sommaire_intertitre_ancre($titre,$m,$ancres_vues); |
||||
$ancres_vues[] = $ancre; |
||||
|
||||
$sommaire[] = array('niveau'=>$m[2]-$toplevel+1,'titre'=>$titre,'href'=>"#$ancre",'id'=>"s-$ancre"); |
||||
|
||||
$lien_back = "<a class='sommaire-back' href='#s-$ancre' title='$titleretour'></a>"; |
||||
$h = inserer_attribut($m[1],"id",$ancre).retire_ancres_sommaire($m[3]).$lien_back.$m[4]; |
||||
$texte = substr_replace($texte,$h,$pos,strlen($m[0])); |
||||
$currentpos = $pos + strlen($h); |
||||
} |
||||
} |
||||
|
||||
#var_dump($sommaire); |
||||
return $sommaire; |
||||
} |
||||
|
||||
function sommaire_intertitre_ancre($titre, $h, $ancres_vues=array()){ |
||||
// un id sur le hn deja ? |
||||
if ($id = extraire_attribut($h[1],"id")) |
||||
return $id; |
||||
|
||||
// generer une ancre a partir du titre |
||||
$ancre = trim(textebrut($titre)); |
||||
$ancre = translitteration($ancre); |
||||
$ancre = couper($ancre,80); |
||||
$ancre = preg_replace(",\W+,","-",$ancre); |
||||
$ancre = trim($ancre,"-"); |
||||
if (!preg_match(",^[a-z],i",$ancre)) |
||||
$ancre = "t$ancre"; |
||||
|
||||
if (!in_array($ancre,$ancres_vues)) |
||||
return $ancre; |
||||
|
||||
$md5 = substr(md5($titre),0,4); |
||||
if (!in_array("$ancre-$md5",$ancres_vues)) |
||||
return "$ancre-$md5"; |
||||
|
||||
$i = 2; |
||||
while (in_array("$ancre-$i",$ancres_vues)){ |
||||
$i++; |
||||
} |
||||
return "$ancre-$i"; |
||||
} |
||||
?> |
Loading…
Reference in new issue