Retour Suite
sylvainmahe.site LE SITE de Sylvain Mahé contact@sylvainmahe.site
Article : Sylvain Mahé contact@sylvainmahe.site Création automatique d'un livre à partir d'une arborescence de fichiers Cette routine (pour le système d'exploitation Linux que j'utilise) permet de générer automatiquement un livre complet sous la forme d'un seul fichier, via une arborescence de fichiers (organisation hiérarchique des fichiers dans des répertoires). Face à l'obsolescence progressive, mais bien réelle, des systèmes analogiques et numériques dans le paysage informatique complexe actuel (formats différents, supports de sauvegarde plus ou moins hétérogènes, multitude d'algorithmes de lecture/écriture et de compression/décompression, etc...), nul ne sait si un matériel standard considéré de nos jours pourra encore être lu (ouvert en lecture) dans les décennies à venir, et ce malgré le soin apporté à la propagation dans le temps des normes de standardisation de l'analogique et du numérique dans son ensemble. Le support physique imprimé comme le livre peut, dans de bonnes conditions de conservation, rester lisible après plusieurs siècles, voir millénaires. Contrairement aux supports de sauvegarde analogiques ou numériques, sa lecture s'affranchit d'utiliser un matériel spécifique pour être compréhensible ou décodable, ce qui en fait un candidat relativement pérenne pour archiver et transmettre des informations aux générations futures (éventuellement seule une translation des langages utilisés sera nécessaire afin de comprendre la logique et les algorithmes mis en œuvre dans les fichiers). Ainsi ce que je propose ici est un outil qui, bien utilisé, vous permettra de sauvegarder vos fichiers sur des supports physiques imprimés (livres, documents divers), via la simple génération d'un seul fichier à texte continu .txt (texte) qu'il convient par la suite de convertir en .pdf (pour "portable document format" ou format de document portable, c'est le format de fichier pris en charge par tous les imprimeurs) à l'aide du programme gedit (le programme gedit conserve à la perfection la pagination du livre). gedit est généralement installé par défaut sur les distributions Linux, mais si vous ne possédez par ce programme (ou paquet), voici la ligne de commande (à écrire dans le terminal) pour l'installer : sudo apt-get install gedit Ma routine d'automatisation prend donc en entrée une arborescence de fichiers, elle permet de choisir les dimensions des pages du livre en nombre de caractères pour la largeur, et en nombre de lignes pour la hauteur (cohérent avec votre conversion en PDF). Si besoin, il est possible également de trier manuellement l'ordre d'apparition des fichiers dans le livre, ce qui peut être intéressant si le tri alphanumérique par défaut n'est pas souhaité. Après quoi un fichier nommé book.txt est créé. Ce fichier répertorie tout le contenu des fichiers de l'arborescence, avec la pagination, la numérotation des lignes, la numérotation des pages (paires et impaires), et la table des fichiers en toute fin du livre. Cette routine (.sh) contient le programme suivant : #!/bin/bash nTable=0 next=false countLineTotal=0 rm book.txt -f echo "Page width (line length) ?" read widthPage echo -e "\nPage height (line number) ?" read heightPage clear shopt -s globstar for dir in */ do for file in $dir**/* do if [ -f $file ] then fileTable[countTable]=$file ((countTable++)) fi done done while [ $next == false ] do echo "Sort option ?" echo "a = Alphanumeric sort" echo "m = Manual sort" read menuOptionSort if [ $menuOptionSort == "a" ] || [ $menuOptionSort == "m" ] then next=true fi clear done if [ $menuOptionSort == "m" ] then next=false while [ $next == false ] do echo "Manual sort :" echo "e = Exit" echo "s = Save file tree (file.tree)" echo "l = Load file tree (file.tree)" echo "d = Delete file tree (file.tree)" echo "" echo "File tree :" for ((n=0; n < countTable; n++)) do if [ $n == $nTable ] then echo $(($n+1))" = "${fileTable[n]}" <" else echo $(($n+1))" = "${fileTable[n]} fi done read menuManualSort if [ $menuManualSort == "e" ] then next=true elif [ $menuManualSort == "s" ] then rm file.tree -f for ((n=0; n < countTable; n++)) do echo ${fileTable[n]} >> file.tree done elif [ $menuManualSort == "l" ] then nLine=0 while read line do fileTable[$nLine]=$line ((nLine++)) done < file.tree elif [ $menuManualSort == "d" ] then rm file.tree -f elif (($menuManualSort >= 1 && $menuManualSort <= $countTable)) then saveTable=${fileTable[$nTable]} fileTable[$nTable]=${fileTable[$((menuManualSort-1))]} fileTable[$((menuManualSort-1))]=$saveTable fi clear if (($nTable == $countTable - 1)) then nTable=0 else ((nTable++)) fi done fi for ((nTable=0; nTable < countTable; nTable++)) do echo ${fileTable[nTable]} echo "Fichier "${fileTable[nTable]}" :" | fold -s -w$widthPage >> book.txt echo "" >> book.txt cp ${fileTable[nTable]} tmp1 sed -i tmp1 -e "s/ /BASH_SPACE/g" -e "s/\t/BASH_TABULATION/g" -e "s/*/BASH_STAR/g" countTmpLine=$(wc -l < tmp1) nTmpLine=1 while read line do if (($countTmpLine < 10)) then fillSpace="" elif (($countTmpLine < 100)) then if (($nTmpLine < 10)) then fillSpace="BASH_SPACE" else fillSpace="" fi elif (($countTmpLine < 1000)) then if (($nTmpLine < 10)) then fillSpace="BASH_SPACEBASH_SPACE" elif (($nTmpLine < 100)) then fillSpace="BASH_SPACE" else fillSpace="" fi elif (($countTmpLine < 10000)) then if (($nTmpLine < 10)) then fillSpace="BASH_SPACEBASH_SPACEBASH_SPACE" elif (($nTmpLine < 100)) then fillSpace="BASH_SPACEBASH_SPACE" elif (($nTmpLine < 1000)) then fillSpace="BASH_SPACE" else fillSpace="" fi elif (($countTmpLine < 100000)) then if (($nTmpLine < 10)) then fillSpace="BASH_SPACEBASH_SPACEBASH_SPACEBASH_SPACE" elif (($nTmpLine < 100)) then fillSpace="BASH_SPACEBASH_SPACEBASH_SPACE" elif (($nTmpLine < 1000)) then fillSpace="BASH_SPACEBASH_SPACE" elif (($nTmpLine < 10000)) then fillSpace="BASH_SPACE" else fillSpace="" fi fi echo -e $fillSpace$nTmpLine" : "$line >> tmp2 ((nTmpLine++)) done < tmp1 rm tmp1 sed -i tmp2 -e "s/BASH_SPACE/ /g" -e "s/BASH_TABULATION/ /g" -e "s/BASH_STAR/*/g" echo "$(> book.txt rm tmp2 countLine=$(wc -l < book.txt) nLine=0 fillPage=$((heightPage-2)) for ((n=0; n < countLine - 1; n++)) do if (($nLine == $heightPage - 3)) then fillPage=$((fillPage+(heightPage-2))) nLine=0 else ((nLine++)) fi done for ((n=0; n < fillPage - countLine; n++)) do echo "" >> book.txt done titlePageTable[nTable]=${fileTable[nTable]} if [ $countLineTotal == 0 ] then numberPageTable[nTable]=1 else numberPageTable[nTable]=$(((countLineTotal/(heightPage-2))+1)) fi countLineTotal=$(wc -l < book.txt) done nLine=0 numberPageContent=1 flipFlop=false echo "" for ((n=0; n < countLineTotal; n++)) do if (($nLine == $heightPage - 1)) then echo "Pagination "$((n+1)) sed -i book.txt -e "$n i \\\\" if [ $flipFlop == false ] then lenghtNumberPageContent=${#numberPageContent} space="\ " for ((nCharacter=1; nCharacter < widthPage - lenghtNumberPageContent; nCharacter++)) do space=$space"\ " done sed -i book.txt -e "$((n+1)) i $space$numberPageContent" flipFlop=true else sed -i book.txt -e $((n+1))"i"$numberPageContent flipFlop=false fi ((numberPageContent++)) elif [ $nLine == $heightPage ] then nLine=0 fi countLineTotal=$(wc -l < book.txt) ((nLine++)) done if [ $flipFlop == false ] then lenghtNumberPageContent=${#numberPageContent} space="BASH_SPACE" for ((n=1; n < widthPage - lenghtNumberPageContent; n++)) do space=$space"BASH_SPACE" done echo -e "\n"$space$numberPageContent >> book.txt sed -i book.txt -e "s/BASH_SPACE/ /g" else echo -e "\n"$numberPageContent >> book.txt fi echo "" echo -e "Table des fichiers :\n" >> book.txt for ((nTable=0; nTable < countTable; nTable++)) do echo "File table "${numberPageTable[nTable]} lenghtTitleNumber=$((${#numberPageTable[nTable]}+${#titlePageTable[nTable]})) nCharacter=0 fillLine=$widthPage for ((nCharacter=0; nCharacter < lenghtTitleNumber - 1; nCharacter++)) do if (($nCharacter == $widthPage - 1)) then fillLine=$((fillLine+widthPage)) nCharacter=0 else ((nCharacter++)) fi done point="." for ((nCharacter=3; nCharacter < fillLine - lenghtTitleNumber; nCharacter++)) do point=$point"." done echo ${titlePageTable[nTable]}" "$point" "${numberPageTable[nTable]} | fold -s -w$widthPage >> book.txt done countLine=$(wc -l < book.txt) nLine=0 fillPage=$heightPage for ((n=0; n < countLine - 1; n++)) do if (($nLine == $heightPage - 1)) then fillPage=$((fillPage+heightPage)) nLine=0 else ((nLine++)) fi done for ((n=0; n < fillPage - countLine; n++)) do echo "" >> book.txt done exit 0 Lorsque vous exécutez la routine (.sh), se propose à vous une question "Page width (line lenght) ?", il vous faut alors renseigner le nombre de caractères souhaités pour la largeur des pages (la police de caractère utilisée doit être à espacement unique) : Par exemple si vous indiquez en largeur de page le nombre 50, vous verrez que le nombre de caractères maximums d'une ligne dans les pages ne dépassera jamais 50, une coupure et un retour à la ligne des phrases trop longues sera effectuée (coupure qui s'effectue entre les mots d'une façon naturelle). Ensuite une autre question "Page height (line number) ?" apparaît, il convient cette fois-ci de renseigner le nombre de lignes souhaités pour la hauteur des pages : Si vous indiquez en hauteur de page le nombre 75, le nombre de lignes total sur une page de votre livre ne dépassera jamais 75 (numérotation des pages y compris). Lorsque vous validez cette deuxième question, se propose à vous le choix "Sort option ?". Choisissez a (pour "Alphanumeric sort" ou tri alphanumérique) puis validez pour trier automatiquement les fichiers dans l'ordre alphanumérique, ou choisissez m (pour "Manual sort" ou tri manuel) pour effectuer vous-même le tri. Si vous avez choisi l'option de tri m, le menu "Manual sort :" (tri manuel) s'affiche à l'écran suivi de quelques commandes (détaillées ci-dessous), ainsi que l'arborescence des fichiers qui vont être inclus dans le livre, avec successivement le numéro d'apparition des fichiers et le chemin d'accès, c'est à ce moment que vous pouvez modifier l'ordre du tri. Voici ci-dessous le détail des commandes possibles : Détail des commandes du menu "Manual sort :" :
- e (pour "Exit" ou sortie) permet de sortir du menu et commencer la génération du livre.
- s (pour "Save" ou sauvegarde) permet de sauvegarder l'arborescence de fichiers dans un fichier nommé file.tree.
- l (pour "Load" ou chargement) permet de charger le fichier nommé file.tree contenant l'arborescence de fichiers.
- d (pour "Delete" ou suppression) permet de supprimer le fichier nommé file.tree contenant l'arborescence de fichiers.

Utilisez ces options pour sauvegarder l'arborescence avec la commande "a", la modifier en ouvrant manuellement le fichier file.tree avec un éditeur de texte (comme gedit par exemple). Puis rechargez cette arborescence modifiée avec la commande "l", vous verrez les modifications s'afficher dans le menu "File tree :".
Plus bas le menu "File tree :" est affiché, c'est l'arborescence de fichiers : La flèche orientée vers la gauche en suffixe des chemins d'accès aux fichiers indique la position de la destination d'un autre fichier source que vous pouvez choisir de déplacer. Validez pour décaler ce curseur vers une autre destination (c'est-à-dire vers le bas), ou écrivez un nombre, puis validez afin de changer la position dans l'arborescence (l'ordre de tri) du fichier indiqué en source (soit le nombre indiqué) vers la destination (soit le curseur en forme de flèche). Exemple :
- Le curseur est positionné sur le fichier numéro 3, c'est la destination.
- J'indique le numéro 10, c'est la source, puis je valide.
- Le fichier en position 10 (la source) prend la position 3 (la destination), et inversement, le 3 prend la position 10.
Lorsque l'ordre de tri des fichiers correspond à ce que vous souhaitez, indiquez la commande e puis validez pour sortir du menu et débuter la génération du livre. La génération du livre commence alors. Elle prend logiquement un temps proportionnel à la complexité de l'arborescence de fichiers utilisée comme source, ainsi que le nombre de lignes et de caractères dans la programmation et l'encodage de chaque fichiers. Une fois la génération du livre terminée, un fichier texte (à texte continu) nommé book.txt est constitué, qui doit être converti en PDF (naturellement aux bonnes dimensions largeur et hauteur) afin d'en apercevoir les différentes pages et la structure de pagination d'une manière cohérente. Vous pourrez par exemple ajouter des pages de titres et de sous-titres à ce fichier, ainsi qu'une préface, etc... (c'est-à-dire tout ce que vous souhaitez voir paraître dans le livre en plus du contenu principal utile), puis compiler le tout en un seul fichier .pdf, pour ensuite l'envoyer à un imprimeur. Libre à vous de faire une utilisation de ce petit programme de génération automatique de livre, lorsque vous aurez besoin de sauvegarder vos fichiers sur un autre support que ceux habituellement utilisés dans le monde du numérique !