Scribus – table des matières avec un script

Scribus est un fabuleux logiciel libre de mise en page (oui, fabuleux, j’assume !) même s’il souffre encore de manques (en passe de disparaître, la prochaine version est encore plus fabuleuse). Par exemple, la création d’une table des matières est lourde et peu pratique. Voir l’article Réaliser une table des matières que j’avais écrit il y a presque quatre ans (et que je remets sur ce blog) et qui n’a, malheureusement, pas pris une ride.

Ayant quelques compétences en programmation et connaissant un peu le format SLA (Scribus Layout), le format de travail de Scribus, je me suis dit qu’on pouvait automatiser la recherche de titres. J’ai donc écrit un script Perl qui extrait tous les titres ayant un style clairement identifié.

Pourquoi Perl et pas Python, le langage de prédilection des extensions de Scribus ? Déjà, je connais mieux Perl que Python et j’avais une contrainte de temps. D’autre part, le format SLA est amené à évoluer d’ici la sortie de Scribus 1.6 de même que le moteur interne de scripts. Enfin, le script que je vous présente là est indépendant de Scribus, vu qu’il lit directement le SLA (qui n’est autre que du XML). Ce script est donc une solution intermédiaire, temporaire. À la sortie quelqu’un (moi peut-être) sera toujours à temps de s’atteler à la tâche (si le mécanisme de table des matières n’a pas été amélioré d’ici-là).

Conditions de base

Lorsque vous réalisez votre maquette, vous devez insérer vos titres dans des cadres de textes séparés du reste et surtout, non liés. Vous devez appliquer un style de paragraphe directement sur le cadre de texte.

Vous pouvez insérer des retours à la ligne (Maj + Entrée), c’est-à-dire, sans changement de paragraphe. Cela peut servir à mieux présenter un titre sur plusieurs lignes. Le script concatène les différentes lignes.

Enfin, vous pouvez utiliser plusieurs styles différents pourvu qu’ils aient une partie du nom commune (c’est le cas dans l’exemple ci-dessous).

Enfin, pour la bonne exécution du script, vous devez avoir installé l’interpréteur Perl (c’est le cas par défaut sous Linux), ainsi que le module XML::DOM.

Le script

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#!/usr/bin/perl -w
use strict;
use Data::Dumper;
use utf8;
 
# Chargement du module XML::DOM pour parser du XML
use XML::DOM;
 
# Création de l'objet parser et chargement du fichier XML passé en paramètre
my $parser = new XML::DOM::Parser;
my $doc = $parser->parsefile(shift);
 
# Sélection des éléments de type PAGEOBJECT et calcul de leur nombre
my $frameobject = $doc->getElementsByTagName("PAGEOBJECT");
my $n = $frameobject->getLength;
 
# Une table de hachage pour accueillir la table des matières
my %tdm = ();
 
# Tri des PAGEOBJECT
for (my $i = 0; $i < $n; $i++) { # Sélection du nœud my $node = $frameobject-&gt;item ($i);
 
	# Récupération du style de parapgraphe (PSTYLE)
	my $style = $node->getAttribute ("PSTYLE");
 
	# S'il ne contient pas -TF- on passe au suivant
	next unless ($style =~ m/-TF-/);
 
	# Sinon on récupère le numéro de la page (OwnPage)
	my $pageNum = $node->getAttribute ("OwnPage") + 1; # Attention OwnPage commence à 0
 
	# Ainsi que les sous-éléments de type ITEXT.
	# S'il y a des retours à la ligne (Maj + Entrée) il y a plusieurs ITEXT
	# qu'il nous faut concaténer
	my $itext = $node->getElementsByTagName("ITEXT");
	my $nt = $itext->getLength;
	my $title = "";
	for (my $j = 0; $j < $nt; $j++) { my $t = $itext->item($j);
 
		# Pour une obscure raison, le texte est stocké dans un paramètre CH
		$title .= $t->getAttribute("CH")." ";
	}
 
	# Encodage du texte en UTF-8
	utf8::encode($title);
 
	# Les titres seront automatiquement classés par leur numéro de page
	# Pour cela il faut que ces numéros soient classés dans le bon ordre.
	# On rajoute un zéro pour les numéros inférieurs à 10.
	$pageNum = sprintf("%.2u", $pageNum);
 
	# L'affectation du titre dans la table de hachage trie automatiquement
	# par numéro de page
	$tdm{$pageNum} = $title;
}
 
# Réécriture propre de la table des matières
foreach my $k (sort(keys(%tdm)))
{
	printf("%s\t%u\n", $tdm{$k}, $k);
}

Quelques explications de codage :

  • lignes 1 à 7, en-tête assez classique d’un script Perl : à noter le chargement du module Data::Dumper, indispensable au débug et XML::DOM, indispensable pour la suite ;
  • ligne 11 : la fonction shift récupère automatiquement le premier argument passé en ligne de commande et le supprime, de sorte qu’un nouvel appel à shift donnera le suivant ;
  • ligne 14 : dans le format SLA, les cadres sont des nœuds PAGEOBJECT, c’est donc ceux-là uniquement qu’il faut rechercher ;
  • ligne 27 : on récupère le style de paragraphe (PSTYLE) du cadre ;
  • ligne 30 : si le nom du style ne contient pas la chaîne de caractères recherchée (je veux ici récupérer les styles nommés 1-TF-creer, 2-TF-info-comm, 3-TF-programmer, etc.) on force la fin du tour de boucle (on passe au cadre suivant) ;
  • ligne 33 : sinon, on extrait le numéro de page (attribut OwnPage) en ajoutant 1, la première page ayant le numéro 0 (ah, ces informaticiens 😉 ) ;
  • lignes 38 à 47 : le contenu du cadre de texte se trouve dans des nœuds de type ITEXT : la boucle permet de les mettre bout à bout (ne pas oublier l’ajout d’une espace pour éviter que les mots des différentes lignes ne se touchent (ligne 46)) ;
  • ligne 50 : encodez le titre ainsi généré en UTF-8 pour une bonne gestion des caractères accentués (entre-autres) ;
  • ligne 59 : on copie le titre trouvé dans la table de hachage avec comme clé le numéro de page (ce qui interdit d’avoir deux titres sur la même page, il faudrait pour cela créer un tableau) ;
  • lignes 62 à 66 : la table de hachage est trié suivant ses clés (donc, les numéros de page) et, pour chacune, on affiche le titre suivi du numéro de page séparés par une tabulation.

Créer la table des matières

Passons à l’action. Enregistrez ce script dans un fichier nommé, par exemple, tdm-sla.pl. Ajoutez-lui les droits d’exécution :

chmod +x tdm-sla.pl

Puis exécutez-le en passant en argument votre document Scribus. L’affichage de la table des matières se fait sur la sortie standard, donc, redirigez-la vers un fichier texte.

./tdm-sla.pl document.sla > tdm.txt

Dans Scribus il ne vous reste plus qu’à créer un cadre de texte et insérer ce texte.

Un style pour les entrées de la table

Dernière étape : créer un style de paragraphe pour les entrées de la table des matières. Dans Scribus allez dans le gestionnaire de styles (Édition → Styles) et créez un style nommé TDM (par exemple).

Il faut gérer la tabulation que le script insère entre le titre et le numéro de page. Cliquez sur la ligne graduée en bas pour créer une tabulation. Vous pouvez en saisir une valeur précise dans le champ prévu à cet effet (dans le rectangle vert sur la capture ci-dessous). Vous pouvez également choisir l’alignement du numéro de page (liste déroulante à gauche de la position de la tabulation). Ici, les numéros de page seront centrés.

Gestionnaire de styles Scribus

En personnalisant un peu le script ci-dessus j’ai donc pu extraire plusieurs niveaux de titres et générer automatiquement la table des matières donc voici un extrait ci-dessous. Il s’agit du catalogue de formations d’Artefacts, encore en cours d’élaboration (mais la sortie est imminente).

Table des matières dans le catalogue de formations d'Artefacts

Astuce : si vous souhaitez extraire plusieurs niveaux de titre (donc à partir de cadres de textes de styles différents) il faut d’abord les gérer dans le script. Vous pouvez ajouter un symbole en début de ligne pour distinguer ces différents niveaux. Par exemple, vous ajoutez un dièse devant les titres de rubrique.

Ensuite, dans Scribus, vous pouvez importer votre table des matières comme texte avec filtrage (plutôt que texte simple). Définissez ensuite des filtres comme ceci.

Importer un texte avec filtrage

Scribus – réaliser une table des matières

Créer une table des matières avec Scribus n’est pas aussi intuitif qu’avec un traitement de texte, mais c’est possible. Une fois que l’on a assimilé le fonctionnement, la pratique devient aisée. Voici comment faire.

Note : cet article a été écrit 24 mars 2013, il date donc beaucoup. La technique fonctionne toujours. Cependant, j’ai écrit un script Perl pour générer une table des matières d’une autre façon. En attendant mieux dans une future version de Scribus.

Un cadre pour la table des matières

La table des matières a besoin d’un cadre dédié pour être affichée. Créez un cadre de texte et donnez-lui un nom pertinent (« cadreTDM » par exemple). Pour renommer un cadre, passez par la fenêtre des Propriétés puis l’onglet X, Y, Z ou par la fenêtre Plan du document.

Nom du cadre

Pour le texte contenu dans ce cadre, vous devez également définir un style de paragraphe. Dans un premier temps seul le nom compte, nous l’affinerons par la suite.
Appelons-le « TDM ».

Définir un style de paragraphe

 

Définir la table des matières

Dans les propriétés du document, vous devez définir un attribut qui reliera la table des matières et les différents cadres porteurs d’une information à y intégrer. Cela se fait via Fichier → Réglage du document → Réglage du document (en l’occurrence, l’onglet porte le même nom que la fenêtre).

Définir un attribut dans le document

 

Toujours dans la fenêtre Réglage du document mais dans l’onglet Table des matières et index nous pouvons maintenant définir la table.

Définir la table des matières

Commencez par lui donner un nom dans le champ juste au-dessus du bouton Ajouter.
Ce dernier l’ajoute à la liste.

Définissez ensuite l’attribut, le cadre de destination et le style de paragraphe avec ceux créés précédemment.

Choisissez également la position du folio (numéro de page). Sachez que le folio sera séparé du titre par une tabulation. Nous exploiterons cette caractéristique via le style de paragraphe.

Ajoutez une entrée dans la table

Sélectionnez un cadre de texte contenant un titre que vous voulez faire apparaître dans la table des matières puis éditez ses attributs (clic droit puis Attributs).

Ajoutez un attribut. Renseignez le nom (« TDM » faisant ainsi le lien avec la table des matières) et la valeur (le titre que vous souhaitez faire apparaître dans la table des matières).

Ajouter une entrée

Faites ainsi pour chacune des entrées que vous souhaitez faire apparaître.

Notez que le cadre porteur de l’attribut n’est pas forcément un cadre de texte.

Note Contrairement à un traitement de texte, la génération automatique d’une table des matières ne se base pas sur les styles de titres, mais sur un attribut fixé au niveau d’un cadre.

Générez la table des matières

Pour générer automatiquement la table des matières dans le cadre « cadreTDM » utilisez le menu Extra → Générer la table des matières. Vérifiez ensuite le résultat sur le cadre « cadreTDM ».

Premier essai de table des matières

Ce cadre de texte reste toutefois modifiable et rien ne vous empêche de rajouter la mention « Table des matières ». Attention, à chaque fois que vous la générez, cette opération efface tout le contenu.

Peaufinez le style « TDM »

Si vous optez pour un folio en fin de ligne dans la table des matières, vous risquez d’être déçu au premier abord.

Deuxième essai, folio à la fin
Il faut donc modifier le style de paragraphe pour forcer les points de tabulation.

Dans les paramètres du style « TDM » créez un point de tabulation à environ un centimètre du bord droit du cadre « cadreTDM » (si votre cadre fait 10 cm de large, placez la tabulation à environ 9 cm). Définissez également ce point comme centré, cela aura pour effet de centrer le texte qui suit, même si le style indique autre chose.

Régler les tabulations

Ce qui, une fois appliqué, produit ceci :

Alignement correct des folios

Scribus : lier des cadres de texte

Dans Scribus, pour insérer du texte vous êtes obligés de créer des cadres de texte au préalable. Lorsque le texte est trop long pour être contenu dans un cadre, on peut lier des cadres de texte ensemble pour que ce dernier coule de l’un à l’autre, en suivant les liens.

J’ai reçu cette question récemment sur le formulaire de contact (n’hésitez pas à poser vos questions).

Comment peut-on lier tous les cadres de texte en même temps (et non un par un) sous Scribus ? L’idée étant de gagner du temps quand on veut transformer en Pdf un bouquin par exemple. Si oui, existe-t-il une procédure qui créée le nombre de cadres de texte nécessaires pour le volume de caractère collés ?

Voici la réponse en vidéo. Prenons comme exemple le livre Contes choisis de la famille des frères Grimm diffusé dans le domaine public par le projet Gutenberg.

La première méthode consiste à créer un document avec l’option Cadres de texte automatique. Dans ce cas, chaque nouvelle page créée le sera avec un cadre de texte lié à celui de la page précédente.

La seconde méthode part du cas d’un document classique et montre comment créer deux cadres de texte et les lier. Puis nous utiliserons la fonction Insérer → Cadres pour créer le nombre souhaité de cadres de texte, liés entre-eux.