Découper un texte en pages et/ou en onglets

Un nouveau raccourci typographique qui découpe le texte de vos rubriques ou de vos articles en plusieurs pages, ou crée pour vous des onglets... Rubis sur ongle !

Introduction

Les articles de votre site sont parfois un peu longs et vous vous êtes probablement déjà posé la question de savoir comment alléger vos belles tirades...

Que faire, donc, avec un couteau suisse ? Eh bien une découpe !

Voici notre solution : dans vos textes, il vous suffit d’utiliser quatre signes plus consécutifs (« ++++ ») à l’endroit où doit se trouver la coupure. Ce raccourci n’est pas sans rappeler les quatre signes moins consécutifs (« ---- ») qui indiquent à SPIP l’emplacement d’une ligne horizontale.

L’outil va ensuite ajouter automatiquement une petite zone de navigation en haut et en bas de votre texte, qui peut ressembler à ceci :

Si un extrait du texte est :

met jamais en quatre !
 
++++
 
Le chant à un : c'est le chant du palais

Alors, en passant la souris sur le chiffre « 2 », vous obtiendrez :

En passant la souris sur les liens de navigation, vous apercevez ci-dessus qu’un titre apparaît : il s’agit en fait du début de la première phrase de la page ciblée. Il pourrait également s’agir du premier titre... A vous de composer !

Lorsque votre article comporte plus de quatre pages, alors la navigation prend une forme plus complexe :

Un petit conseil : à l’intérieur de votre texte, il vaut mieux isoler ce raccourci en sautant une ligne de part et d’autre, SPIP saura alors mieux formater vos paragraphes. Vérifiez également qu’aucune balise HTML ou raccourci SPIP ne traverse les quatre plus (« ++++ ») : vous risquez d’endommager l’aspect de votre site, car chaque page ainsi découpée est considérée comme indépendante. Évitez par exemple :

{{Voici une fin de page en gras
 
++++
 
Voici un début de page en gras}}

La bonne syntaxe est :

{{Voici une fin de page en gras}}
 
++++
 
{{Voici un début de page en gras}}

Installation

Cet outil est une fonctionnalité du plugin « Le Couteau Suisse » que vous pouvez trouver ici : Le Couteau Suisse.

Pour avoir accès à la découpe de vos textes en plusieurs pages, il vous faut donc avoir installé ce plugin en suivant la procédure normale d’installation des plugins SPIP.

Ensuite, veuillez activer l’outil « Découpe un texte en pages » en vous rendant sur la page d’administration du plugin en espace privé (Bouton Configuration, et onglet "Le Couteau Suisse").

Petite astuce : afin d’éviter que le raccourci « ++++ » se retrouve automatiquement dans les résumés produits par la balise #INTRODUCTION, activez aussi l’outil « Balise #INTRODUCTION ».

Notes techniques

-  Techniquement parlant, cet outil agit sur toutes les balises #TEXTE trouvées dans vos squelettes et insère une coupure là où il trouve quatre signes plus (« ++++ »). Vous pouvez donc insérer des découpages dans vos articles, vos textes de rubrique, etc.

-  Une condition est cependant nécessaire : la découpe en page ne fonctionnera pas si votre squelette utilise la balise #TEXTE étoilée #TEXTE* »). En effet, cette syntaxe permet de s’affranchir de tous les filtres automatiques et SPIP renvoie donc le texte brut sans aucune transformation. Si vous tenez absolument à mettre une étoile, alors il faut ajouter à votre balise le filtre cs_decoupe, comme ceci : [(#TEXTE*|propre|cs_decoupe)]

-  Le plugin fonctionne tel quel avec la dist de SPIP. Cependant, si votre squelette est construit avec des inclusions, alors il est indispensable de transmettre à la noisette l’indicateur de page {artpage}, ainsi que les options éventuelles {cs} du Couteau Suisse. Par exemple :

<div id="page">
    <div id="contenu">
    <INCLURE {fond=inc-article-corps}{id_article}{id_rubrique}{artpage}{cs}>
    </div>
</div>

Notez que l’argument {env} vous permet de transmettre tout l’environnement au squelette inclus :

<div id="page">
    <div id="contenu">
    <INCLURE {fond=inc-article-corps}{env}>
    </div>
</div>

-  Le développement décrit dans le présent article est inspiré d’un ancien filtre que vous pouvez encore trouver ici : Découper un article en plusieurs pages. Afin d’assurer la compatibilité avec le séparateur « ----- », ajoutez le code suivant à votre fichier config/mes_options.php :

// Compatibilite ascendante avec l'ancien filtre 'decoupe'
@define('_decoupe_COMPATIBILITE', '-----');

Cette constante peut également servir à créer un nouveau raccourci de découpe.

Balise #CS_DECOUPE

Par défaut, le Couteau Suisse insère la pagination en tête et en pied d’article automatiquement. Mais vous avez la possibilité de placer cette pagination ailleurs dans votre squelette qu’en tête de votre article grâce à une balise #CS_DECOUPE. L’utilisation de cette balise doit être activée dans la page de configuration et annule ainsi l’insertion automatique des paginations dans votre article.

Cette balise renvoie la pagination seule quand elle existe (quand l’article est découpé), et se comporte un peu comme la balise #TEXTE : elle doit être placée à l’intérieur d’une boucle ARTICLES. Depuis la version 1.8.36.01 du Couteau Suisse, la balise #CS_DECOUPE accepte un paramètre numérique permettant d’accéder directement à un article par son id_article, évitant ainsi une boucle dédiée.

Exemples : #CS_DECOUPE{2}, #CS_DECOUPE{#GET{toto}} ou #CS_DECOUPE{#ENV{id_article}}.

Attention, ce raccourci ne doit pas être utilisé à l’intérieur d’une boucle du même article, sous peine d’un appel SQL inutile. Exemple évident à éviter : <BOUCLE01(ARTICLES)>#CS_DECOUPE{#ID_ARTICLE}</BOUCLE01>

Les Surcharges

Les images

Si vous désirez changer les images utilisées pour la navigation (par défaut, ce sont de petits triangles noirs), il est préférable de recopier le dossier couteau_suisse/img/decoupe/ directement dans votre squelette. En effet, SPIP va d’abord chercher le dossier en question dans votre squelette avant d’aller explorer les répertoires du plugin : c’est le mécanisme des surcharges. Du coup, vous pouvez créer un dossier monsquelette/img/decoupe/ afin de remplacer celui du Couteau Suisse et y mettre vos propres images. Ainsi, la mise à jour de votre plugin à tendance helvétique préféré pourra se faire sans crainte de perdre votre personnalisation.

Les images doivent obligatoirement se nommer ainsi : debut.gif, debut_off.gif, precedent.gif, precedent_off.gif, suivant.gif, suivant_off.gif, fin.gif, fin_off.gif. Si debut.gif ou fin.gif n’est pas trouvé, alors les images precedent.gif ou suivant.gif seront doublées (cf l’exemple ci-dessus).

Les fonds

Si les fonds proposés par défaut pour la pagination ne vous satisfont pas, alors il suffit pour vous de les surcharger dans votre propre squelette (y copier les originaux avant de les modifier). Les fichiers en question sont : fonds/decoupe_item.html (calcul des numéros) et fonds/decoupe.html (inclusion du fond précédent et ajout des flèches de navigation). Toutes les possibilités CSS vous seront alors ouvertes !

Attention : toute modification d’un fichier ou d’un dossier surchargé nécessite une recompilation des outils du Couteau suisse, obtenue en se rendant simplement sur la page de configuration du plugin ou en ré-affichant celle-ci.

La découpe en AJAX

AJAX est une petite merveille qui permet d’isoler un fragment HTML au sein d’une page et réagissant aux localement clics. En gros, plus besoin de charger la page entière pour en modifier seulement qu’une partie... Ici, la découpe de vos articles se marie très bien avec cette idée, puisqu’il n’est pas nécessaire de tout reconstruire la page (les menus, les entêtes, etc.) alors qu’on ne fait que changer de fragment d’article découpé, comme si on feuilletait les pages d’un livre.

Si vous êtes sous SPIP 2.0 minimum, on continue, sinon, sautez à l’intertitre suivant en attendant de mettre à jour votre CMS préféré.

Pour mettre en place un fragment AJAX, il faut isoler ce qui concerne l’article proprement dit dans un fichier à part que l’on nommera inc-article-corps.html, et y mettre par exemple la boucle suivante (mettez-y, bien sûr, le contenu que vous voulez, le plus important, c’est d’y avoir la balise #TEXTE) :

<div class="inc_article">
<BOUCLE_inc_article(ARTICLES){id_article}>
	<div class="#EDIT{titre} titrearticle">#TITRE</div>
	[<div class="#EDIT{chapo} chapo">(#CHAPO)</div>]
	<div class="#EDIT{texte} texte">#TEXTE</div>
</BOUCLE_inc_article>
</div>

Ensuite, dans votre fichier article.html, censé afficher la page complète, mettez simplement quelque chose comme :

<BOUCLE_article_page(ARTICLES){id_article}>
<!DOCTYPE bla bla bla>
<head>bla bla bla, notamment un #TITRE</head>
<body>
Divers trucs de présentation, avant...
... Et surtout :
	<INCLURE{fond=inc-article-corps}{ajax}{id_article}{artpage}{cs}>
Divers trucs de présentation, après...
</body>
</html>
</BOUCLE_article_page>
</B_article_page>
<INCLUDE{fond=404}>
<//B_article_page>

Avec ce mécanisme, la pagination ne fonctionnera qu’à l’intérieur du <div class="inc_article"> et un clic de souris ne rechargera pas la page entière, mais bien le seul fragment concernant les contenus SPIP de votre article (dans l’exemple ci-dessus : le titre, le chapo éventuel et le texte).

Notez le critère magique {ajax} disponible à partir de SPIP 2.0, l’id de l’article {id_article} nécessaire à la boucle BOUCLE_inc_article, l’indispensable indicateur de page {artpage} à transmettre au fragment, et les options éventuelles {cs} du Couteau Suisse.

Les filtres

Un paramètre artpage ajouté à l’URL de votre article permet au plugin de connaître le numéro de la page à afficher. Il est composé de deux nombres séparés par un tiret : artpage=PC-NB, où PC est le numéro de la page en cours et NB est le nombre total de pages.

Il existe trois filtres pour tirer partie de ce paramètre :

-  artpage($artpage=false, $index=0) : renvoie l’un ou l’autre des deux nombres.
Par défaut (si $index=0), la fonction renvoie la page en cours.
Si $index=1, la fonction renvoie le nombre de pages. Attention : si ce nombre est absent du paramètre artpage ou si ce paramètre est introuvable, alors la fonction renvoie 0.

-  artpage_fin($artpage=false) : renvoie vrai si la page en cours est la dernière. Si le nombre de pages est absent du paramètre artpage ou si ce paramètre est introuvable, alors la fonction renvoie faux.

-  artpage_debut($artpage=false) : renvoie vrai si la page en cours est la première.

Dans vos squelettes, il vous uffit donc d’utiliser :

-  #ENV{artpage}|artpage pour la page en cours
-  #ENV{artpage}|artpage{1} pour le nb de pages, s’il est présent

Deux exemples équivalents :

-  [(#ENV{artpage}|artpage|=={1}|oui) Youpi, ceci est la première page !]
-  [(#ENV{artpage}|artpage_debut|oui) Youpi, ceci est la première page !]

Notez que le filtre oui est introduit par SPIP 2.0. Il permet de rendre vraie une expression au sens SPIP et doit notamment être appliqué sur un filtre de type boolean (vrai/faux). Pour les versions antérieures de SPIP, les exemples précédents sont également valides : le Couteau Suisse contient les filtres oui et non dans ses fonctions et vous permet de les utiliser sans crainte dans vos squelettes.

Astuces

-  En manipulant les styles css, Il vous est possible de désactiver une des deux lignes de navigation (ou les deux si vous le souhaitez, mais le bon sens n’y vois aucun intérêt !). Dans le head de votre squelette ou dans un fichier css, il vous suffit d’insérer « div.decoupe_haut{display:none !important;} » pour supprimer la navigation placée en haut du texte, et « div.decoupe_bas{display:none !important;} » pour supprimer celle d’en bas.

-  Dans les fichiers de votre squelette, vous avez peut-être une balise #TEXTE destinée à l’impression du texte complet, non découpé en pages. Le Couteau Suisse met à votre disposition un filtre « cs_imprimer » qui produira le texte dans son ensemble, où les pages sont simplement séparées par un mince filet pointillé. La syntaxe pourrait être celle-ci : [(#TEXTE*|cs_imprimer|propre)]. Mais ceci est un peu lourd, lisez le point suivant.

-  Dans votre navigateur, ajouter à l’adresse d’une page le paramêtre « cs=print » permet d’obtenir le même effet décrit ci-dessus et force le Couteau Suisse à afficher l’article entier. Par exemple : www.monsite.ici/spip?article999&cs=print
Aussi, ce paramétrage est automatique dans les squelettes suivants : « print.html », « imprimer.html », « imprimir_articulo.html », « imprimir_breve.html » ou « article_pdf.html » (donc ici : « page=print », « page=imprimer », etc.). Lisez ici le paragraphe « Particularités » pour en savoir davantage.

-  Le découpage d’un article peut permettre très facilement de se composer rapidement un diaporama que vous pouvez éventuellement commenter (astuce de Ch. Guigueno). Il suffit de placer une photo par page et le tour est joué ! Voici un exemple (emb1 et emb2 doivent être des images) :

{{{Mon titre 1}}}
Voici ma photo 1 : <emb1|center>
<center>{Remarquez ces couleurs !}</center>
++++
{{{Mon titre 2}}}
Voici ma photo 2 : <emb2|center>
<center>{Remarquez ces textures !}</center>
++++
etc. !

-  Cet outil « Découpe un texte en pages » se marie très bien avec l’utilisation d’un outil voisin, le Sommaire Automatique : « Un sommaire pour vos articles ». Si ce dernier est activé, le sommaire détecte en effet les découpages et ajoute le numéro de la page où les différents intertitres SPIP ont été trouvés.

Les onglets dans vos articles

Vous pouvez trouver de très nombreux exemples d’utilisation des onglets dans les articles : par ici ou par ici...

Depuis la version 1.7.8.07 du plugin, l’outil « Découpe un texte en pages » offre (pour peu de code supplémentaire !) la possibilité de construire des onglets dans vos articles (ou même dans vos squelettes). La syntaxe est basée sur le même séparateur (« ++++ ») que l’on place très simplement à l’intérieur des balises <onglets> et </onglets>. Par exemple :

<onglets>
Titre 1
 
Mon 1er Texte après deux sauts de ligne
++++
Titre 2
 
Mon 2ème Texte après deux sauts de ligne
</onglets>

Voici en image ce que donne un usage par défaut :

Dont voici le code :

<onglets>Introduction
  
blah blah
++++Développement
 
blah blah blah
++++Conclusion
 
blah blah blah blah
</onglets>

Cette fonctionnalité utilise les librairies JQuery, simplifiant grandement la tâche des programmeurs et utilisées par SPIP lui-même.

Afin d’afficher correctement les onglets demandés par le rédacteur, le plugin fournit le code HTML suivant :

<div class="onglets_bloc_initial">
   <div class="onglets_contenu">
        <h2 class="cs_onglet"><a href="#">Introduction</a></h2>
        blah blah
   </div>
   <div class="onglets_contenu">
        <h2 class="cs_onglet"><a href="#">Développement</a></h2>
        blah blah blah
   </div>
   <div class="onglets_contenu">
        <h2 class="cs_onglet"><a href="#">Conclusion</a></h2>
        blah blah blah blah
   </div>
</div>

jQuery va ensuite construire à la volée le système d’onglets et mettre en rapport les onglets cliquables et les contenus. Les ancres sont introduites dans certaines balises <div> sous forme : id="mon_ancre".

Cela donne donc au final le code HTML suivant :

<div class="onglets_bloc" id="ongl_0">
  <div class="onglets_liste">
      <h2 class="onglets_titre" id="onglets_titre_0">
         <a href="#">Introduction</a>
      </h2>
      <h2 class="onglets_titre selected" id="onglets_titre_1">
         <a href="#">Développement</a>
      </h2>
      <h2 class="onglets_titre" id="onglets_titre_2">
         <a href="#">Conclusion</a>
      </h2>
  </div>
  <div class="onglets_contenu" id="onglets_contenu_0">
      blah blah
  </div>
  <div class="onglets_contenu selected" id="onglets_contenu_1">
      blah blah blah
  </div>
  <div class="onglets_contenu" id="onglets_contenu_2">
      blah blah blah blah
  </div>
</div>

Aspect visuel

Dans le code ci-dessus, il est facile de repérer les différents blocs <div> ou <h2>, affublés de classes qui vous permettrons de changer l’aspect des onglets à votre guise, comme ceci par exemple, les onglets créés par Douglas Bowman :

dont j’ai reconstitué pour vous le fichier CSS adapté au Couteau Suisse qui devra être interprété APRES les styles définis par défaut :

Voici d’autres onglets créés par Douglas Bowman :

Je mentionne également une contribution similaire de Pi r, ayant adapté pour SPIP les scripts d’Erik Arvidsson, programmés en Javascript pur. Mais aujourd’hui, autant utiliser directement les librairies jQuery de SPIP et alléger le temps de chargement des pages. Les versions 1.7.9.12 et suivantes du Couteau Suisse comprennent la syntaxe de ce plugin, assurant ainsi une compatibilité pour d’anciens articles basés sur ces travaux.

Ancres et paramètres

Chaque bloc d’onglets est affublé d’une ancre : #ongl_0, #ongl_1, etc. Ajoutée à l’url de votre page, l’ancre placera automatiquement le navigateur en tête de bloc.

Pour activer un onglet particulier sur une page lors du chargement de cette dernière, il vous suffit d’ajouter un paramètre dans votre url. Par exemple : « onglet=2 » (ou "http://www.spip-contrib.net/Decouper-un-texte-en-pages-et-ou?onglet=2").

Notez que le premier onglet est noté zéro ; l’exemple précédent activera donc le troisième onglet de la page entière.

Les onglets dans vos squelettes

Depuis la version 1.7.9.12 du plugin, de nouvelles balises (#ONGLETS_DEBUT, #ONGLETS_TITRE et #ONGLETS_FIN) ont été introduites afin de vous permettre de construire des onglets directement dans votre squelette (fichiers *.html). Voici un exemple de syntaxe :

[(#ONGLETS_DEBUT{Introduction})]
	blah blah
[(#ONGLETS_TITRE{Développement})]
	blah blah blah 
[(#ONGLETS_TITRE{Conclusion})]
	blah blah blah blah
#ONGLETS_FIN

Au sein d’une boucle SPIP et sur un bloc d’onglets principal (non imbriqué dans un autre bloc d’onglets), vous pouvez omettre #ONGLETS_DEBUT, le Couteau Suisse construira quand même le bloc correctement (version 1.8.06.01 minimum du plugin). Si votre bloc d’onglet est imbriqué, alors il faut jouer avec la balise #COMPTEUR_BOUCLE et vérifier que le premier appel de balise est bien #ONGLETS_DEBUT. L’intérêt ici est de pouvoir placer un champ de cette boucle dans le titre des onglets.

Par exemple, le code :

<B_sites>
<BOUCLE_sites(SITES){syndication=oui}>
	[(#COMPTEUR_BOUCLE|=={1}|?{' '})#ONGLETS_DEBUT{#NOM_SITE}]
	[(#COMPTEUR_BOUCLE|>{1}|?{' '})#ONGLETS_TITRE{#NOM_SITE}]
	<BOUCLE_articles(SYNDIC_ARTICLES){id_syndic}{par date}{inverse}>
	&bull; #TITRE<br/>
	</BOUCLE_articles>
</BOUCLE_sites>
#ONGLETS_FIN
</B_sites> 

s’il n’est pas contenu dans un autre bloc d’onglets, peut être simplifié en :

<B_sites>
<BOUCLE_sites(SITES){syndication=oui}>
	#ONGLETS_TITRE{#NOM_SITE}
	<BOUCLE_articles(SYNDIC_ARTICLES){id_syndic}{par date}{inverse}>
	&bull; #TITRE<br/>
	</BOUCLE_articles>
</BOUCLE_sites>
#ONGLETS_FIN
</B_sites> 

Dépendances

-  La librairie jQuery est requise pour le fonctionnement des Onglets, dans la construction et la manipulation des jeux d’onglets présents sur la page finale. Ces fonctions Javascript très utile a été intégré au core dès la version 1.9.2 de SPIP. Pour les versions inférieures, il vous faut installer et activer le plugin Jquery que vous pouvez télécharger ici : http://zone.spip.org/files/spip-zon....

-  Les styles CSS et les fonctions Javascript du plugin sont insérés grâce à la balise #INSERT_HEAD qui doit absolument être présente (en un seul exemplaire) dans le head de vos squelettes (entre les balises <head> et </head> des fichiers HTML). Si vous ne trouvez pas cette balise dans vos codes et que les liens n’ont pas l’apparence voulue, alors activer l’outil "Balise #INSERT_HEAD" permet au Couteau Suisse d’insérer automatiquement cette balise sans manipulation de votre part.

-  Bug ! Manu_TJ nous a écrit : « sur mon site, l’utilisation des onglets ne fonctionne pas sur de très longs articles : la page affichée est blanche, le texte est bien en base mais ne s’affiche pas à l’écran (espace public comme privé). Dès que j’enlève les balises "onglets", l’article réapparaît. Et sur les articles avec moins de texte, pas de soucis non plus ». Il s’avère que son site est interprété par PHP v5.2.9 et il semble que sous cette version du célèbre langage, la fonction preg_replace_callback() en mode "ungreedy" perd le texte en cours de route s’il est trop long : l’expression ',<onglets([0-9]*)>(.*?)</onglets\1>,ms' ne fonctionne plus alors que ',<onglets([0-9]*)>(.*)</onglets\1>,ms' fonctionne toujours... En regardant le début du fichier outils/decoupe_fonctions.php on voit l’expression régulière qui nous intéresse en define(). Il suffit donc de la surcharger dans le fichier /config/mes_options.php en ajoutant la ligne suivante :

define('_onglets_REGEXPR', ',<onglets([0-9]*)>(.*)</onglets\1>,ms');

Cela annulera l’effet ungreedy de l’expression mais interdira du coup les multiples systèmes d’onglets dans un article. Cependant, cette expression contourne le bug de PHP 5.2.9 ...

Voir aussi

-  Le plugin autonome (non dépendant du couteau suisse) : En onglets dans le texte de SPIP, ou ailleurs...

Discussion

103 discussions

  • 4

    Bonjour,
    J’ai un petit problème (téléchargement de ce jour, dernière version du plugin) : le premier paragraphe après chaque onglet n’est plus justifié (par exemple ici ou . C’est le style
    <p class="spip" align="justify"> qui est éliminé par le style des onglets
    <div class="onglets_bloc_initial"><div class="onglets_contenu"><h2 class="cs_onglet">.

    Si je mets deux lignes de paragraphe après le titre de l’onglet, la mise en page est récupérée pour ce premier paragraphe... mais le titre de l’onglet n’est plus dans l’onglet.

    Suis-je la seule ? Que faire pour garder la mise en page homogène ?

    Merci

    • Merci pour ce message, les liens sont très explicites. Je viens de corriger ce pb dans la version 1.7.9.16 du CS.

      Un petit conseil de présentation peut-être qui vaut ce qu’il vaut... Dans la surcharge de decoups.css que tu as faite dans ton squelette, pkoi ne pas mettre plutot :

      div.onglets_bloc .onglets_contenu {
        top:-12px; /* a la place de -10px */
      }

      C’est vrai que le CSS h2, #conteneur #content h2 contenu dans blog.css vient pas mal modifier l’aspect des titres d’onglet...

    • Il doit y avoir un petit oubli quelque part car la page ne ressemble plus à rien (une suite des textes sans fin ni présentation).
      Pour info, elle commence par

      Array
      (
          [0] =>  
    • Toutes mes excuses, j’avais oublié une ligne de debug... C’est corrigé.

    • Une ligne de débug qui fait bugger... les joies de l’informatique < :-)
      Ca marche nickel, je suis super contente, j’ai rectifié mon css, les onglets parfaits. Très beau plugin, félicitations !

    Répondre à ce message

  • 13

    Cette contribution est incompatible avec En onglets dans le texte ?
    Chez moi, ça ne fonctionne pas.

    Et pourtant j’aimerais installer ce système, mais comme j’ai des nombreuses utilisations de l’autres, il me faudrait garder l’autre pour la lecture de l’existant.
    Est-ce possible ?
    Merci.

    • le couteau suisse et le plugin onglets dans le texte n’utilisent pas les mêmes balises et class css... des onglets qui fonctionent avec le premier ne « tourneront » donc pas avec le deuxième et vice versa.

      En revanche tu peux parfaitement garder tout ce que tu as fait avec le plugin « onglets dans le texte » et créer de nouveaux onglets avec le couteau suisse...

      A toi de voir...

    • Oui, effectivement, maintenant ça marche, j’avais dû faire une erreur quelque part.
      Une petite demande : peut-on accrocher des ancres à ces onglets, de manière à envoyer des liens directement sur la partie onglets que l’on veut ,
      Avec le plugin en onglets dans le texte ce n’est pas possible.

      Merci.

    • Depuis la toute dernière mouture du CS, la compatibilité avec la contrib de Pierre est assurée. Peux-tu vérifier cela avec tes anciens articles ? Plus besoin donc de cohabitation, même si elle fonctionne. Attention toutefois aux CSS...

      De plus, je vais poster ce soir une version du CS qui permettra d’activer un onglet au moyen d’un parametre « onglet » dans l’url. Si on veut activer le 5e onglet de la page (entière !), mettre : « onglet=4 ».

    • J’oubliais que l’ancre associée aux blocs d’onglets est par exemple : #ongl_1

      Il suffit de regarder le code final produit par jQuery.

    • Mon code source n’indique pas d’ancre, et, normal, ça ne marche pas. Depuis quand le système d’ancre est-il implémenté ?
      Merci

    • D’abord, il faut mettre à jour le plugin avant tout message ici. J’ai bien précisé, me semble-t-il : « depuis la toute dernière mouture du CS ».

      Ensuite, je parle du code source final, modifié par jQuery, non du code source. Ce code est facilement visible sous FF.

      Le code final doit ressembler à celui-ci : <div id="ongl_0" class="onglets_bloc">. Du coup, l’ancre est : #ongl_0.

      Si ça ne fonctionne toujours pas alors laisse-nous un lien public si tu en as un, c’est toujours plus efficace que de grands discours.

    • Euh, oui... mais non !
      Effectivement tout est nickel selon les spécifications. De ce côté pas de problème.
      Mais.... J’avais des onglets, avec titres et choix possible d’un coup d’oeil.
      Maintenant, automatiquement, sur les anciens j’ai un découpage avec des chiffres de page non significatifs.
      Et je ne vais pas me coltiner des centaines d’articles à changer.
      Je proposerai donc un petit changement :

      si on est dans la configuration ancienne (de en_onglets_dans_le_texte, alors soit au lieu du numéro de page on a le titre de l’onglet, pour choisir correctement (ma préférence, car tout le monde aura un jour ou l’autre cette envie, les chiffres des pages n’étant pas explicites) ;
      Soit l’ajout automatique d’un sommaire reprenant les titres des onglets, avec lien vers la page concernée (j’aime beaucoup aussi),
      soit un script pour changer la configuration de ce qui préexistait dans tous les articles ou brèves concernés en changeant :

      <onglet|debut|id=x|titre=titre de l'onglet> en <onglet> puis titre de l'onglet puis deux sauts de ligne
      
      <onglet|titre=titre de l'onglet> en ++++  puis titre de l'onglet puis deux sauts de ligne
      
      <onglet|fin> en </onglet>

      soit une autre solution, à chercher.

      En tous cas, merci c’est vraiment la bonne voie.

    • Euh, oui... mais non !

      J’ai peur de pas tout comprendre ton message... Toujours pas de lien ?

      je n’avais pas pris en compte le « |id=x ». Donc voila chose faite.

      Je précise que le raccourcis ici est au pluriel : <onglets>

    • Non, je ne parle pas de l’ancre, mais je n’ai plus les onglets pour l’ancienne notation : je n’ai que les numéros de page pour les clics d’un grand titre (anciennement onglet) à l’autre, pas les onglets.
      Je veux dire que l’ancienne notation onglets devient des numéros de page et non pas des onglets.
      De plus, les numéros de page en haut et en bas et au milieux, ce n’est pas très très joli, mais ça c’est une autre affaire < :-)

    • Merci de mettre à jour le plugin (rev. 17085) avant de répondre à ce message !! Les id devraient être pris en compte.

    • Super, les onglets marchent, merci beaucoup, reste plus qu’à adapter les css.
      En revanche les ancres non, et le code source d’ailleurs ne les donne pas (je parle bien du code source, ce qui signifie celui de la page, pas celui du programmeur) :<div class="onglets_contenu"><h2 class="cs_onglet"><a href="#">.
      A ce propos, je crois que pour limiter la confusionil vaudrait mieux ajouter artificiellement 1 au compteur pour que l’onglet numéro 1 s’appelle vraiment par #ongl_1 et non pas #ongl_0.

      Exemple : http://lipietz.net/?page=blog&id_breve=269#ongl_1

    • Mais les ancres pour quoi ? La seule ancre exploitable est celle du bloc entier : #ongl_0. Si un onglet est invisible, ses ancres ne servent à rien.

      Un système pour activer un onglet ? J’ai déja répondu à cette question...

      Les onglets s’activent grâce à un paramètre d’url. Exemple :
      http://lipietz.net/?page=blog&id_breve=269&onglet=1

      A cela on peut aussi ajouter l’ancre #ongl_0

    • Bon, désolée, j’avais pas tout compris, j’ai dû rater des trucs.
      Maintenant c’est nickel.
      Ne reste plus que ma suggestion (si possible) de mettre le compteur des onglets selon la logique humaine et non informatique < :-).
      Encore merci pour ce joli travail.

    Répondre à ce message

  • 1

    Bonjour,

    Un soucis avec cet outil. La découpe du texte en page fonctionne très bien,
    par contre toutes les notes de bas de page ont disparues.

    SPIP 1.9.2c + Version : 1.7.9.06 du couteau suisse.
    JQuery, #INSERT_HEAD sont pourtant bien activée.
    Je teste avec Firefox

    • je me répond à moi même.
      J’avais oublié de mettre dans mon squelettes la balise #NOTES …

    Répondre à ce message

  • 1
    thierrybo

    Bonjour,

    avec le squelette SPIP par défaut (Version : 1.7.9.04 du couteau suisse), j’obtiens ceci quelque soit les retours à la ligne avec le code suivant :

    A la rédaction du texte de l’article procédez comme suit :
    
    <onglets>Onglet1
    
    
    contenu du premier onglet
    
    ++++onglet2
    
    
    contenu du deuxième onglet
    
    ++++onglet3
    
    
    contenu du troisième onglet
    etc...
    </onglets>
    
    <onglets>Introduction
     
    blah blah blah
    ++++Développement
                   
    blah blah blah
    ++++Conclusion
                   
     blah blah blah
    </onglets>
    • Ah, tu es peut-être sous Mac ? sous Windows ? Je viens de renforcer la compatibilité entre plateformes au sujet du double saut de ligne.

      Qu’en est-il après mise à jour (v1.7.9.06 du couteau suisse, dispo à 14h04) ?

    Répondre à ce message

  • 2

    Bravo pour ce super plugin qui marche nickel sauf un léger soucis :

    Lorsque j’utilise la séparation en pages, les documents insérés dans l’article apparaissent en bas d’article alors que ce n’est pas le cas sans la séparation en pages activée. Avez-vous une idée de l’origine du problème ?

    PS : j’utilise Beespip 1.9.1 et un plugin pour insérer les animations Tracenpoche et Instrumenpoche

    • Tu as un lien à montrer ?

    • J’ai aussi le même effet. En fait, chaque doc n’apparait qu’une seule fois par défaut : si on a inclus un doc dans le corps du texte, il n’est plus censé apparaitre dans le portfolio. Mais avec ce plugin, la notion de pages est bouleversée : chaque mini page est considérée comme une entité à part entière, or les docs appartiennent à l’article dans son ensemble. Du coup, les docs joints apparaissent tous dans la portfolio, sauf ceux qui sont dans la corps de la mini page.

      Ce serait sympa de pouvoir disposer d’une option qui recense tous les docs joints à toutes les mini pages d’un article, afin qu’on n’ait pas cette suite de docs répétés dans le portfolio.

    Répondre à ce message

  • 3
    Thierry

    Bonjour,

    J’ai installé cette fonction sur un site en SPIP 1.9.2b et ça fonctionne presque parfaitement si ce n’est que les numéros des notes de bas de page ne sont pas les mêmes dans l’espace privé et dans l’espace public.

    Ainsi la note 1 dans l’espace privé se retrouve en ligne avec, par exemple, le numéro 25... la note 2 dans l’espace privé avec le numéro 26 dans l’espace public... et ainsi de suite...

    Comment corriger ce problème ?

    Merci pour votre aide,

    Cordialement,

    TS

    • A propos des notes de bas de page, j’ai un article coupé en plusieurs pages avec une seule note de bas de page qui se trouve dans la première page. Or toutes les autres pages affichent également le titre « Notes » sans rien dessous évidemment...

      Je ne vois pas comment empêcher cet affichage inutile.

    • Effectivement. Je viens d’optimiser le traitement des notes afin d’éviter ce problème.

      il te reste à mettre à jour le plugin. Merci pour le retour.

    • bravo ça fonctionne parfaitement :
      dans un article paginé dont certaines pages ont des notes et d’autres non,
      la section « Notes » s’affiche quand il y a une ou des notes dans la pages et ne s’affiche plus quand la page n’en a pas

      bref, ça le fait !

    Répondre à ce message

  • Bonjour à tous et un grand merci aux auteurs du Plugin.

    J’ai une petite idée de plugin complémentaire : que la découpe en pages soit faîte automatiquement de façon à avoir une hauteur de page fixe.

    La hauteur pourrait être spécifiée en pixel, par exemple. Il s’agirait de la hauteur de la zone corresponsant à #TEXTE. Il faudrait prendre en compte l’insertion des images et des paramètres css du texte. Pas simple hein ?

    Une option pourrait être que la découpe se fasse entre deux paragraphes consécutifs, pour éviter une découpe en plein milieu du texte. Une autre option : découpe automatique avant un intertitre.

    Mais toujours en respectant une hauteur de page max.

    Cela existe déjà ? ou dois-je mettre au défi les kadors du spip et du php ?

    ciao

    Répondre à ce message

  • Bonjour,

    Déjà merci pour ce plugins !

    Ayant un site avec un grand nombre de page déjà publiée, j’ai modifié le script pour que la découpe se fasse automatiquement tous les x nbre de caractère.

    Pour ne pas découper n’importe où dans le texte, la fonction cherche une fin de paragraphe

    pour insérer le séparateur. Il y a un contrôle pour éviter de couper dans une DIV.

    Serait-il possible d’incorper cette fonction, si pour autant elle peut être utile, au script du couteaux suisse ?

    voici le nouveaux code de « decoupe_fonction.php » :

    define('_decoupe_NB_CARACTERES', 10000);
    
    // Filtre local utilise par le filtre 'cs_imprimer' afin d'eviter la decoupe
    // Exemple : lors d'une impression a l'aide du squelette imprimer.html,
    // remplacer la balise #TEXTE par [(#TEXTE*|propre|cs_imprimer)].
    function decoupe_imprimer($texte) {
    	return str_replace(_decoupe_SEPARATEUR, '<p style="border-bottom:1px dashed #666; padding:0; margin:1em 20%; font-size:4pt;" >&nbsp; &nbsp;</p>', $texte);
    }
    
    // aide le Couteau Suisse a calculer la balise #INTRODUCTION
    function decoupe_introduire($texte) {
    	return str_replace(_decoupe_SEPARATEUR, '<p>&nbsp;</p>', $texte);
    }
    $GLOBALS['cs_introduire'][] = 'decoupe_introduire';
    
    // fonction appellee sur les parties du textes non comprises entre les balises : html|code|cadre|frame|script|acronym|cite
    function decouper_en_pages_rempl($texte) {
    	// Nettoyage des anciens caractère de découpe
    	$texte = decoupe_supp_anc_car($texte);
    	// Découpage automatique si plus grand que _decoupe_NB_CARACTERES et qu'il n'y a pas de _decoupe_SEPARATEUR dans le texte.	
    	if ((strlen($texte) <= _decoupe_NB_CARACTERES) && (strpos($texte, _decoupe_SEPARATEUR)===false)){
    		return $texte; 
    	} elseif (strpos($texte, _decoupe_SEPARATEUR) !== false) {
    		$auto = false;	
    	} elseif (strpos($texte, _decoupe_SEPARATEUR) === false) {
    		$auto = true; 
    	}
    	// au cas ou on ne veuille pas de decoupe
    	if ($_GET['artpage']=='print') return decoupe_imprimer($texte);
    	// recherche du sommaire s'il existe
    	if (defined('_sommaire_REM') && (substr_count($texte, _sommaire_REM)==2)) {
    		$pages = explode(_sommaire_REM, $texte);
    		$sommaire = $pages[0].$pages[1];
    		$texte = $pages[2];
    	} else $sommaire = ''; 
    
    	// Insertion automatique du séparateur de page après la balise </p> la plus proche tous les _decoupe_NB_CARACTERES
    	if ($auto) {
    		$look = '</p>';
    		$len_look = strlen($look); 
    		// Offset de découpe
    		$offset = _decoupe_NB_CARACTERES ;
    		$len = strlen($texte);
    		$len_toc = strlen($sommaire);
    		$pos = 0;
    		
    		do  { 
    		// Trouve la position pour insérer les caractères de découpage:
    		// Trouve la fin de paragraphe la plus proche depuis l'offset (ajoute la longueur du sommaire si existant)
    		$pos = strpos($texte, $look, $offset + $len_toc); 
    		// Déterimine si on est dans une DIV ou non
    		$div = 0;
    		if (strpos($texte, '</div>', $pos) < strpos($texte,'<div', $pos)) {
    			$div = 1;
    			}
    		// Si on est dans un DIV, on déplace la position jusqu'à la fin de la DIV
    		if ($div) {
    			$pos = strpos($texte, '</div>', $pos);
    			$len_look = strlen('</div>');
    		} 
    		// Découpe le texte depuis la position trouvée
    		$old = substr($texte, $pos + $len_look);
    		// Insère les caractères de découpage à la position définie
    		$texte = substr_replace($texte, _decoupe_SEPARATEUR.$old, $pos + $len_look);
    		$offset = $offset + _decoupe_NB_CARACTERES;
    		} while ($offset <($len - (_decoupe_NB_CARACTERES) ));
    		// Nettoyage des caractères de découpe inséré à la suite
    		$texte = str_replace(_decoupe_SEPARATEUR._decoupe_SEPARATEUR, _decoupe_SEPARATEUR, $texte);
    	}
    	
    	// traitement des pages	
    	$pages = explode(_decoupe_SEPARATEUR, $texte);
    	$num_pages = count($pages);
    	if ($num_pages == 1) return $texte;
    	$artpage = max(intval($_GET['artpage']), 1);
    	$artpage = min($artpage, $num_pages);
    /*
    	// si numero illegal ou si var_recherche existe, alors renvoyer toutes les pages, separees par une ligne <hr/>.
    	// la surbrillance pourra alors fonctionner correctement.
    	if (strlen($_GET['var_recherche']) || $artpage < 1 || $artpage > $num_pages)
    		return join("<hr/>", $pages);
    */
    	$self = self();//$GLOBALS['REQUEST_URI'];
    
    	// images calculees par decoupe_installe()
    	$images = unserialize($GLOBALS['meta']['cs_decoupe']);
    
    	// images et liens pour la navigation sous forme : << < ... > >>
    	// precedent
    	$alt = _T('cout:page_precedente');
    	$alt = "title=\"$alt\" alt=\"$alt\"";
    	$precedent = '<a href="' . parametre_url($self,'artpage', $artpage - 1) . '">'; 
    	$precedent = $artpage == 1?$images['precedent_off']." $alt />"
    		:$precedent.$images['precedent']."$alt /></a>";
    	// suivant
    	$alt = _T('cout:page_suivante');
    	$alt = "title=\"$alt\" alt=\"$alt\"";
    	$suivant = '<a href="' . parametre_url($self,'artpage', $artpage + 1) . '">'; 
    	$suivant = ($artpage == $num_pages)?$images['suivant_off']." $alt />"
    		:$suivant.$images['suivant']."$alt /></a>";
    	// s'il existe plus de trois pages on calcule les liens << et >>
    	if ($num_pages>3) {
    		// debut
    		$alt = _T('cout:page_debut');
    		$alt = "title=\"$alt\" alt=\"$alt\"";
    		$debut = '<a href="' . parametre_url($self,'artpage', 0) . '">'; 
    		$debut = $artpage == 1?($temp=$images['precedent_off']." $alt />").$temp
    			:$debut.($temp=$images['precedent']." $alt />").$temp.'</a>';
    		// fin
    		$alt = _T('cout:page_fin');
    		$alt = "title=\"$alt\" alt=\"$alt\"";
    		$fin = '<a href="' . parametre_url($self,'artpage', $num_pages) . '">';
    		$fin = ($artpage == $num_pages)?($temp=$images['suivant_off']." $alt />").$temp
    			:$fin.($temp=$images['suivant']." $alt />").$temp.'</a>';
    	}
    	// liens des differentes pages sous forme : 1 2 3 4
    	$milieu = array();
    	for ($i = 1; $i <= $num_pages; $i++) {
    		if ($i == $artpage) {
    			$milieu[] = "<span style=\"color: lightgrey; font-weight: bold; text-decoration: underline;\">$i</span>";
    		} else {
    			// isoler la premiere ligne non vide de chaque page pour l'attribut title
    			$page = trim(safehtml(cs_imprimer($pages[$i-1])));
    			$title = preg_split("/[\r\n]+/", $page, 2);
    			$title = attribut_html(propre(couper($title[0], _decoupe_NB_CARACTERES)));//.' (...)';
    			$milieu[] = '<a href="' . parametre_url($self,'artpage', $i) . "\" title=\"$title\">$i</a>";
    		}
    	}
    	$milieu = join(' ', $milieu);
    
    	// s'il existe plus de trois pages on retourne la pagination << < 1 2 3 4 > >>
    	// sinon une forme simplifiee : < 1 2 3 >
    	$pagination = $num_pages>3?"$debut $precedent $milieu $suivant $fin":"$precedent $milieu $suivant";
    	$pagination1 = "<a name='decoupe_haut' id='decoupe_haut'></a><div class='pagination decoupe_haut'>$pagination</div>";
    	$pagination2 = "<a name='decoupe_bas' id='decoupe_bas'></a><div class='pagination decoupe_bas'>$pagination</div>";
    	$page = trim($pages[$artpage-1]);
    	if (isset($_GET['decoupe_recherche'])) {
    		include_spip('inc/surligne');
    		$page = surligner_mots($page, $_GET['decoupe_recherche']);
    	}
    	return $sommaire.$pagination1.$page.$pagination2;
    }
    
    // meme chose que la fonction precedente, mais pour les notes
    function decouper_en_pages_rempl_notes($texte) {
    	if (strpos($texte, _decoupe_SEPARATEUR)===false) return $texte;
    	// au cas ou on ne veuille pas de decoupe
    	if ($_GET['artpage']=='print') return decoupe_imprimer($texte);
    	
    	// traitement des pages
    	$pages = explode(_decoupe_SEPARATEUR, $texte);
    	$num_pages = count($pages);
    	if ($num_pages == 1) return $texte;
    	$artpage = max(intval($_GET['artpage']), 1);
    	$artpage = min($artpage, $num_pages);
    
    	return trim($pages[$artpage-1]);
    }
    
    // supprime les notes devenues orphelines
    function decoupe_affichage_final($texte){
    	if (strpos($texte, "spip_note")===false) return $texte;
    	global $ouvre_note;
    	tester_variable('ouvre_note', '[');
    	$ouvre_note = str_replace('[', '\[', $ouvre_note);
    	$appel = "<p[^>]*>$ouvre_note<a [^>]*name=\"nb([0-9]+)\" class=\"spip_note\" [^>]+>[^<]+</a>.*?</p>";
    	preg_match_all(",$appel,", $texte,$tableau);
    	for($i=0;$i<count($tableau[0]);$i++) {
    		if (!preg_match(",<a href=\"#nb{$tableau[1][$i]}\",",$texte)) 
    			$texte = str_replace($tableau[0][$i], '', $texte);
    	}
    	return $texte;
    }
    
    function cs_decoupe($texte){
    	//if (strpos($texte, _decoupe_SEPARATEUR)===false) return $texte;
    	if (strlen($texte) <= _decoupe_NB_CARACTERES) {
    	$texte = decoupe_supp_anc_car($texte);
    	return $texte;
    	}
    	// verification des metas qui stockent les liens d'image
    	if (!isset($GLOBALS['meta']['cs_decoupe']) || isset($GLOBALS['var_mode'])) {
    		include_spip('outils/decoupe');
    		decoupe_installe();
    	}
    	return cs_echappe_balises('html|code|cadre|frame|script|acronym|cite', 'decouper_en_pages_rempl', $texte);
    }
    
    // Compatibilite
    function decouper_en_pages($texte){
    	return cs_decoupe($texte);
    }
    
    // Suppression des anciens caractères de découpe "////"
    function decoupe_supp_anc_car($texte){
    	$anc_car = "////";
    	if (strpos($texte,$anc_car) !== false){
    	$texte = str_replace($anc_car, "", $texte);
    	}
    	return $texte;
    }

    et pour que le sommaire fonctionne, « sommaire_fonction.php »

    define('_sommaire_NB_TITRES_MINI', 2);
    define('_sommaire_SANS_FOND', '[!fond]');
    
    // TODO : ajouter un fichier css pour le sommaire
    
    // Filtre local utilise par le filtre 'cs_imprimer' afin d'eviter la decoupe
    // Exemple : lors d'une impression a l'aide du squelette imprimer.html,
    // remplacer la balise #TEXTE par [(#TEXTE*|propre|cs_imprimer)].
    function sommaire_imprimer($texte) {
    	return str_replace(array(_sommaire_SANS_FOND, _sommaire_SANS_SOMMAIRE), '', $texte);
    }
    
    // aide le Couteau Suisse a calculer la balise #INTRODUCTION
    $GLOBALS['cs_introduire'][] = 'sommaire_imprimer';
    
    // renvoie le sommaire d'une page d'article
    function sommaire_d_une_page(&$texte, &$nbh3, $page=0) {
    	static $index; if(!$index) $index=0;
    	define('_sommaire_NB_CARACTERES', 30);
    	// image de retour au sommaire
    	$titre = _T('cout:sommaire');
    	$img = 'spip_out.gif';
    	$path = dirname(find_in_path(($GLOBALS['spip_version']<1.92?"img_pack/":"images/").$img));
    	list(,,,$size) = @getimagesize("$path/$img");
    	$haut = "<img class=\"no_image_filtrer\" alt=\"$titre\" title=\"$titre\" src=\"".cs_htmlpath($path)."/$img\" $size/>";
    	$haut = "<a title=\"$titre\" href=\"".self()."#outil_sommaire\">$haut</a> ";
    	// traitement des titres <h3>
    	preg_match_all(',(<h3[^>]*>)(.*)</h3>,Umsi',$texte, $regs);
    	$nbh3 += count($regs[0]);
    	$pos = 0; $sommaire = '';
    	$p = $page?",&nbsp;p$page":'';
    	for($i=0;$i<count($regs[0]);$i++,$index++){
    		$ancre = "\n<a id=\"outil_sommaire_$index\" name=id=\"outil_sommaire_$index\"></a>";
    		if (($pos2 = strpos($texte, $regs[0][$i], $pos))!==false) {
    			$titre = preg_replace(',^<p[^>]*>(.*)</p>$,Umsi', '\\1', trim($regs[2][$i]));
    			$texte = substr($texte, 0, $pos2) . $ancre . $regs[1][$i] 
    				. $haut	. $titre 
    				. substr($texte, $pos2 + strlen($regs[1][$i]) + strlen($regs[2][$i]));
    			$pos = $pos2 + strlen($ancre) + strlen($regs[0][$i]);
    			$lien = couper($regs[2][$i], _sommaire_NB_CARACTERES);
    			$lien = preg_replace('/[!?,;.:]+$/', '', $lien); // eviter une ponctuation a la fin
    			$titre = attribut_html(propre(couper($regs[2][$i], 100)));
    			$sommaire .= "<li><a $st title=\"$titre\" href=\"".parametre_url(self(),'artpage', $page)."#outil_sommaire_$index\">$lien</a>$p</li>";
    		}
    	}
    	return $sommaire;
    }
    
    // fonction appellee sur les parties du textes non comprises entre les balises : html|code|cadre|frame|script|acronym|cite
    function sommaire_d_article_rempl($texte) {
    	// s'il n'y a pas de balise <h3> ou si le raccourcis _sommaire_SANS_SOMMAIRE est present dans le texte, alors on laisse tomber
    	if (strpos($texte, '<h3')===false || strpos($texte, _sommaire_SANS_SOMMAIRE)!==false) 
    		return sommaire_imprimer($texte);
    	$sommaire = ''; $i = 1; $nbh3 = 0;
    	$texte0 = $texte;
    	// couplage avec l'outil 'decoupe_article'
    	if(defined('_decoupe_SEPARATEUR')) {
    	// Découpage automatique si plus grand que _decoupe_NB_CARACTERES et qu'il n'y a pas de _decoupe_SEPARATEUR dans le texte.	
    	if ((strlen($texte) <= _decoupe_NB_CARACTERES) && (strpos($texte, _decoupe_SEPARATEUR)===false)){
    		return $texte; 
    	} elseif (strpos($texte, _decoupe_SEPARATEUR) !== false) {
    		$auto = false;	
    	} elseif (strpos($texte, _decoupe_SEPARATEUR) === false) {
    		$auto = true; 
    	}
    	// Insertion automatique du séparateur de page après la balise </p> la plus proche tous les _decoupe_NB_CARACTERES
    	if ($auto) {
    		$look = '</p>';
    		$len_look = strlen($look); 
    		// Offset de découpe
    		$offset = _decoupe_NB_CARACTERES ;
    		$len = strlen($texte);
    		$len_toc = strlen($sommaire);
    		$pos = 0;
    		
    		do  { 
    		// Trouve la position pour insérer les caractères de découpage:
    		// Trouve la fin de paragraphe la plus proche depuis l'offset (ajoute la longueur du sommaire si existant)
    		$pos = strpos($texte, $look, $offset + $len_toc); 
    		// Déterimine si on est dans une DIV ou non
    		$div = 0;
    		if (strpos($texte, '</div>', $pos) < strpos($texte,'<div', $pos)) {
    			$div = 1;
    			}
    		// Si on est dans un DIV, on déplace la position jusqu'à la fin de la DIV
    		if ($div) {
    			$pos = strpos($texte, '</div>', $pos);
    			$len_look = strlen('</div>');
    		} 
    		// Découpe le texte depuis la position trouvée
    		$old = substr($texte, $pos + $len_look);
    		// Insère les caractères de découpage à la position définie
    		$texte = substr_replace($texte, _decoupe_SEPARATEUR.$old, $pos + $len_look);
    		$offset = $offset + _decoupe_NB_CARACTERES;
    		} while ($offset <($len - (_decoupe_NB_CARACTERES) ));
    		// Nettoyage des caractères de découpe inséré à la suite
    		$texte = str_replace(_decoupe_SEPARATEUR._decoupe_SEPARATEUR, _decoupe_SEPARATEUR, $texte);
    	}// Insertion automatique du séparateur de page après la balise </p> la plus proche tous les _decoupe_NB_CARACTERES
    	if ($auto) {
    		$look = '</p>';
    		$len_look = strlen($look); 
    		// Offset de découpe
    		$offset = _decoupe_NB_CARACTERES ;
    		$len = strlen($texte);
    		$len_toc = strlen($sommaire);
    		$pos = 0;
    		
    		do  { 
    		// Trouve la position pour insérer les caractères de découpage:
    		// Trouve la fin de paragraphe la plus proche depuis l'offset (ajoute la longueur du sommaire si existant)
    		$pos = strpos($texte, $look, $offset + $len_toc); 
    		// Déterimine si on est dans une DIV ou non
    		$div = 0;
    		if (strpos($texte, '</div>', $pos) < strpos($texte,'<div', $pos)) {
    			$div = 1;
    			}
    		// Si on est dans un DIV, on déplace la position jusqu'à la fin de la DIV
    		if ($div) {
    			$pos = strpos($texte, '</div>', $pos);
    			$len_look = strlen('</div>');
    		} 
    		// Découpe le texte depuis la position trouvée
    		$old = substr($texte, $pos + $len_look);
    		// Insère les caractères de découpage à la position définie
    		$texte = substr_replace($texte, _decoupe_SEPARATEUR.$old, $pos + $len_look);
    		$offset = $offset + _decoupe_NB_CARACTERES;
    		} while ($offset <($len - (_decoupe_NB_CARACTERES) ));
    		// Nettoyage des caractères de découpe inséré à la suite
    		$texte = str_replace(_decoupe_SEPARATEUR._decoupe_SEPARATEUR, _decoupe_SEPARATEUR, $texte);
    	}
    	
    		$pages = explode(_decoupe_SEPARATEUR, $texte);
    		if (count($pages) == 1) $sommaire = sommaire_d_une_page($texte, $nbh3);
    		else {
    			foreach($pages as $p=>$page) { $sommaire .= sommaire_d_une_page($page, $nbh3, $i++); $pages[$p] = $page; }
    			$texte = join(_decoupe_SEPARATEUR, $pages);
    		}
    	} else $sommaire = sommaire_d_une_page($texte, $nbh3);
    	if(!strlen($sommaire) || $nbh3<_sommaire_NB_TITRES_MINI) return $texte0;
    
    	$img = find_in_path('img/sommaire/coin.gif');
    	$sansfond = !$img || strpos($texte, _sommaire_SANS_FOND)!==false;
    	if ($sansfond) {
    		$texte = str_replace(_sommaire_SANS_FOND, '', $texte);
    		$fond = 'background-color:white; border:thin solid gray;';
    	} else {
    		$img = cs_htmlpath($img);
    		$fond = "background:transparent url($img) no-repeat scroll left top; border-bottom:thin solid #999999; border-right:1px solid #999999;";
    	}
    
    
    $sommaire='<a name="outil_sommaire" id="outil_sommaire"></a><div id="outil_sommaire" class="cs_sommaire" style="'.$fond.'"><div style="margin:3pt;"><div style="
    border-bottom:1px dotted silver;
    line-height:1;
    position:inherit;
    font-weight:bold;'.($sansfond?'':'margin-left:15px;').'
    text-align:center;">'._T('cout:sommaire').'</div>
    <ul style="font-size:84%;
    list-style-image:none;
    list-style-position:outside;
    list-style-type:none;
    margin:0.3em 0.5em 0.1em 0.7em;
    padding:0pt;">'.$sommaire.'</ul></div></div>';
    
    	return _sommaire_REM.$sommaire._sommaire_REM.$texte;
    }
    
    function sommaire_d_article($texte){
    	if (strpos($texte, '<h3')===false) return $texte;
    	return cs_echappe_balises('html|code|cadre|frame|script|acronym|cite', 'sommaire_d_article_rempl', $texte);
    }

    Désolé pour le post un peu long :-))

    Vince

    Répondre à ce message

  • 2

    Bonjour,

    J’utilise ce plugin depuis peu et je le trouve vraiment tres bien.

    J’aimerai cependant savoir s’il est possible d’afficher une boucle particulière (comme les documents attachés) en derniere page et pas à chaque page.

    Merci beaucoup.

    • Cela devrait être possible, oui. Ecrire un filtre déjà permettrait de répondre à cette question.

    • Merci beaucoup

      Mais mes connaissances en programmation spip ne sont pas suffisantes pour ecrire un tel filtre ;)

    Répondre à ce message

  • ya un pb

    Bonjour,

    je découvre spip 1.9 et j’ai un petit souci avec le découpage des pages et l’impression.
    L’impression sur une seule page ne fonctionne pas. Plus précisement je ne comprend pas où il faut mettre « artpage=print » et le filtre « cs_imprimer » ne fonctionne pas non plus.

    JE suis novice...

    help

    Répondre à ce message

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