From 1f151ee32ed75ced17f9a8f0b998188d55ac22fe Mon Sep 17 00:00:00 2001 From: Yorick Barbanneau Date: Mon, 4 Sep 2023 22:01:33 +0200 Subject: [PATCH] Reword and syntax coorrections Thanks Eclipse, Duponin Heuzef and my wife --- .../articles/2023/make_avec_latex/index.md | 222 +++++++++++------- 1 file changed, 139 insertions(+), 83 deletions(-) diff --git a/content/articles/2023/make_avec_latex/index.md b/content/articles/2023/make_avec_latex/index.md index d6de86a..329d27e 100644 --- a/content/articles/2023/make_avec_latex/index.md +++ b/content/articles/2023/make_avec_latex/index.md @@ -5,11 +5,10 @@ Date: 2023-08-30 12:10 cover: assets/backgrounds/machine_zorba.jpg status: draft -Dans mon précédent [article]({filename}../fonctionnement_makefile/index.md), -nous avons vu comment fonctionne *make* et son langague utilisé dans les -`Makefile`. Comme promis, voici le premier example d'utilisation : la -construction de document *PDF* à partir de fichiers sources LaTeX, de fichiers -*SVG* et d'images matricielles. +Dans mon [précédent article]({filename}../fonctionnement_makefile/index.md), +nous avons parlé du fonctionnement de *make* et des `Makefile`. Comme promis, +voici le premier exemple d'utilisation : la construction de documents *PDF* à +partir de fichiers sources LaTeX, de fichiers *SVG* et d'images matricielles. Nous allons avancer progressivement tout au long de cet article, ainsi nous commencerons avec un `Makefile` des plus basique pour l'améliorer au fur et à @@ -22,7 +21,7 @@ archive]({attach}./files/examples.tar.xz). Les corrections sont disponibles dans le répertoire `Makefile/`. Faites attention aux copiés/collés : les tabulations sont transformées en -espace dans les blocs de code de cet article. Or *make* se sert des tabulations +espaces dans les blocs de code de cet article. Or *make* se sert des tabulations pour déterminer les actions relatives aux cibles. Lors de l'exécution de *make*, vous aurez l'erreur `Makefile:23: *** missing separator. Stop.`, il suffira de revoir votre indentation. @@ -46,18 +45,32 @@ clean: @rm document.aux document.log documents.pdf ``` - Nous utilisons ce qui se fait déjà pour la compilation de programme en `C`, à -savoir placer le compitateur et ses paramètres dans des variables. Nous avons +savoir placer le compilateur et ses paramètres dans des variables. Nous avons donc `$(LC)` pour *LaTeX Compiler* -- j'utilise LuaLatex -- et `$(LCFLAGS)` pour les paramètres. +La cible `default` sera lancée automatiquement si aucune autre est spécifiée +dans la ligne de commande. Ainsi la compilation se lance avec un simple `make`. + ## un répertoire pour les compiler tous À la premièrer compilation, on s'aperçoit vite que plusieurs fichiers -apparaissent dans notre répertoire (fichiers `aux`, `log`, `toc` etc.) Il -devient alors un peu confus, nous allons faire en sorte de placer tous ces -fichiers (ainsi que le fichier PDF généré) dans un répertoire séparé. +apparaissent dans notre répertoire (fichiers `aux`, `log`, `toc` etc.) comme +ceci: + +```shell +$ ls -l +-rw-r--r-- 1 user group 186 Aug 31 13:14 document.aux +-rw-r--r-- 1 user group 19650 Aug 31 13:14 document.log +-rw-r--r-- 1 user group 41023 Aug 31 13:14 document.pdf +-rw-r--r-- 1 user group 1203 Aug 29 23:27 document.tex +-rw-r--r-- 1 user group 191 Aug 29 23:27 Makefile +``` + +Notre répertoire devient alors un peu confus, nous allons faire en sorte de +placer tous ces fichiers (ainsi que le fichier PDF généré) dans un +sous-répertoire. ```make LC = lualatex @@ -73,18 +86,31 @@ $(OUTPUT)/document.pdf: document.tex clean: @rm -rf $(OUTPUT) ``` -Nous définissons la variables `OUTPUT` qui contient le répertoire dans lequel -placer tous les fichiers générés par `lualatex`. L'options qui va bien est +Nous définissons la variable `OUTPUT` qui contient le répertoire dans lequel +placer tous les fichiers générés par `lualatex`. L'option qui va bien est ajoutée à `LCFLAGS`. `OUTPUT` est aussi utilisée pour la cible `clean`, notre -nettoyage n'en est que plus simple!. +nettoyage n'en est que plus simple! -Tout ces fichiers sont maintenant dans le répertoire `build/`. +Tous ces fichiers sont maintenant dans le répertoire `build/`: -## Tous ne s'appellent pas document +```shell +$ tree +. +├── build +│   ├── document.aux +│   ├── document.log +│   └── document.pdf +├── document.tex +└── Makefile -Tous nos documents de s'appellent pas *document*, leurs noms dépendent souvent +2 directories, 5 files +``` + +## Mais où est document? + +Tous nos documents ne s'appellent pas *document*, leurs noms dépendent souvent du contexte. Rendons donc ce `Makefile` plus générique grâce aux variables et -macros +macros. ```make LC = lualatex @@ -102,35 +128,35 @@ $(OUTPUT)/%.pdf: %.tex clean: @rm -rf $(OUTPUT) ``` -notre macro `DOCUMENTS` est un imbrication de 3 fonction : - 1. `wildcard ` pour récupérer une liste de fichier dans le répersoire +Notre macro `DOCUMENTS` est une imbrication de 3 fonctions : + + 1. `wildcard ` pour récupérer une liste de fichiers dans le répertoire courant en fonction d'un motif; - 2. `patsubst ,,` pour substituer une partie de la - chaine dans un chemin, `%` fait ici office de caractère joker; + 2. `patsubst ,,` pour substituer une partie de la + chaîne dans un chemin, `%` fait ici office de caractère joker; 3. `addprefix , ` pour ajouter un préfixe à chacun des éléments - d'une chaine de caracères. Pour *make*, les éléments d'une chaine de - caractère sond délimités par des espaces. + d'une chaîne de caractères. N'oubliez pas, pour *make*, les éléments d'une + chaîne de caractères sont délimités par des espaces. -Elle permet d'obtenir le nom d'une cible en fonction des fichiers `tex` contenu +Elle permet d'obtenir le nom d'une cible en fonction des fichiers `tex` contenus dans notre répertoire : `document.tex` deviendra alors `build/document.pdf`. `$(DOCUMENTS)` est maintenant une dépendance de notre cible `default`. Et chacun -de ses élémets appelle la cible `$(OUTPUT)/%.pdf: %.tex` qui dépend de `%.tex` : -la source LaTeX, `%` étant remplacé par le nom donné dans la cible : -`build/document.pdf` donnerait `document.tex` comme dépendance. +de ses élémets appelleront la cible `$(OUTPUT)/%.pdf: %.tex` qui se charge de +contruite un fichier PDF en fonction de sa source LaTeX. -Cette solution nous permet maintenant d'appeler notre source LaTeX comme bon -nous semble. Mieux encore nous nouvons **avoir plusieurs fichiers** à la racine -de notre répertoire, il seront tous compilés indépendament. C'est très pratique -lorsque vous avez un rapport et la présentation dans un même dépôt par exemple. +Cette solution nous permet d'appeler notre source LaTeX comme bon nous semble. +Mieux encore nous pouvons **avoir plusieurs fichiers** à la racine de notre +répertoire, ils seront tous compilés indépendamment. C'est très pratique lorsque +vous avez un rapport et la présentation dans un même dépôt par exemple. ## Les images matricielles -Il n'est pas rare qu'un document contienne des **images au format matriciel** : -des photos au format JPEG ou des captures d'écran au format PNG par exemple. Il -est alors nécessaire de prendre en compte la modification de ces images pour la -compilation de nos documents. +Il n'est pas rare qu'un document contienne des **images matricielles** : des +photos JPEG ou des captures d'écran PNG par exemple. Il est alors nécessaire de +prendre en compte la modification de ces images pour la compilation de nos +documents. ```make LC = lualatex @@ -155,26 +181,43 @@ clean: Nous avons maintenant une variable `IMAGES_DIR` qui nous permet de spécifier le répertoire dans lequel sont stockées les images -- nous verrons plus tard que d'autres sous-dossiers d'*images* apparaîtront. La liste des images est -récupérée grace à la macro `IMAGES` qui utilise la fonction `wildcard` pour +récupérée grâce à la macro `IMAGES` qui utilise la fonction `wildcard` pour récupérer **tous les fichiers de ce répertoire**. -Le résultat de cette macro est donné en dépendance de notre cible de -contruction des documents `$(OUTPUT)/%.pdf: %.tex`. **Ainsi si une image est +Le résultat de cette macro est donné en dépendance de notre cible permettant la +construction des documents : `$(OUTPUT)/%.pdf: %.tex`. **Ainsi si une image est modifiée ou ajoutée, alors la compilation du fichier PDF sera relancée**. -Notre technique a cependant deux défauts. D'abord si une image est ajoutée mais -n'est pas utilisée le document sera quand même compilé alors que ce n'est pas -nécessaire. +Notre technique a cependant deux défauts. -Enfin si une image utilisée **seulement** dans le document *B* est modifiée, *A* -et *C* **seraient aussi compilés**. Ce dernier problème pourrait être résolu, -mais au prix d'une complexification de notre processus de compilation. +D'abord, si nous ajoutons une image sans l'utiliser dans notre document et +nous relançons la compilation alors notre document sera tout de même +recompilé sans que se soit nécessaire. *make* ne fait pas d'analyse sytaxique, +il n'est pas **capable d'analyser le fichier source pour determiner s'il doit +être compilé ou non**. + +Ensuite prenons l'exemple d'un dossier contenant trois fichiers LaTeX *A*, *B*, +et *C*. Si une image utilisée **seulement** dans le document *B* est modifiée, +*A* et *C* **seront tout de même recompilés**. + +Dans l'exemple de code fourni (dans le répertoire `4_images`), vous trouverex un +script (`change_image.sh`) qui se charge de changer l'image du document +`presentation.tex`. Vous pouvez tester la compilation avant et après la +modification du `Makefile` et observer les actions effectuées. + +Ce scrits se lance sans paramètres : + +```shell +$ ./change_image.sh +Flip images ... +Done! +``` ## Les images SVG -Personnellement j'utilise beaucoup *Inkscape* pour produire diverses images. -Mais le format SVG n'est pas utilisable tel quel en LaTeX[^n_svgtex]. Il est -nécesssaire de passer par une étape intermédiaire pour le transformer en PDF. +J'utilise beaucoup *Inkscape* pour produire diverses images. Mais le format SVG +n'est pas utilisable tel quel en LaTeX[^n_svgtex]. Il est nécesssaire de passer +par une étape intermédiaire et le transformer en PDF. ```make LC = lualatex @@ -207,31 +250,30 @@ clean: @rm -rf $(OUTPUT ``` -Le principe est ici simple : nous allons utiliser *Inkscape* pour exporter les -fichiers au format PDF. Pourquoi exporter en PDF? C'est un format bien supporté -par les moteurs *LaTeX*. Il permet aussi de conserver au maximum le format +Le principe est simple : nous utilisons *Inkscape* pour exporter les fichiers au +format PDF. Pourquoi exporter en PDF? C'est un format bien supporté par les +moteurs *LaTeX*. Il permet aussi de conserver au maximum le format vectoriel[^n_svgpdf]. Quatres variables font leur apparition : * `SC` pour *SVG compiler*, nous utilisons *Inkscape*; - * `SCFLAGS` qui contient les paramètres de la commande `Inkcape`; + * `SCFLAGS` qui contient les paramètres de la commande `Inkscape`; * `SVG_DIR` qui contient le chemin vers les fichiers SVG; * `SVG_EXPORTED_DIR` qui contient le chemin vers les fichiers PDF exportés depuis *Inkscape*. -Nous avons aussi deux macros +Et deux deux macros : - * `SVG` liste les fichiers SVG, cette macro utilise la fonction `wildcard` - interne à *make* qui permet de récupérer une liste de fichiers en fonction - d'un motif; - * `SVG_EXPORTED` transforme la liste de fichiers SVG en liste de fichiers PDF. - Deux fonctions imbriquées sont nécessaires :`subst` qui permet de remplacer - un motif dans des chaines et `patsubst` que nous avons vu précédemment. Cette - macro est donnée en dépendance de la cible de compilation des documents. + * `SVG` liste les fichiers SVG via la fonction `wildcard`; + * `SVG_EXPORTED` transforme la liste contenu dans`SVG` en liste de fichiers + PDF. Deux fonctions imbriquées sont nécessaires :`subst` qui permet de + remplacer un motif dans des chaînes et `patsubst` que nous avons vu + précédemment. Cette macro est donnée en dépendance de la cible de compilation + des documents. Ensuite la cible qui nous permet de convertir les fichiers : -`$(SVG_EXPORTED_DIR)/%.pdf: $(SVG_DIR)/%.svg` et la commande associée. +`$(SVG_EXPORTED_DIR)/%.pdf: $(SVG_DIR)/%.svg`. [^n_svgtex]: Ce n'est pas tout à fait vrai, il est possible d'utiliser le package LaTeX *svg* et sa commande `\includesvg` mais les contraintes sont @@ -243,15 +285,15 @@ Ensuite la cible qui nous permet de convertir les fichiers : ## Les cibles accessoires -Nous avons vu jusqu'ici les cibles principales, nous allons maintenant ajouter -deux cibles qui pourront nous faciliter la vie. +Nous avons vu jusqu'ici les cibles principales, ajoutons maintenant deux cibles +qui pourront nous faciliter la vie. ### Afficher des informations Notre `Makefile` est maintenant conséquent, il contient quelques **macros qu'il -est parfois utiles d'afficher**. Cette affichage nous permettra par exemple de +est parfois utile d'afficher**. Cet affichage nous permettra par exemple de vérifier les images matricielles prises en compte ou encore les fichiers SVG qui -seront exportées. +seront exportés. ```make LC = lualatex @@ -291,14 +333,25 @@ info: @echo "exported SVG images..'$(SVG_EXPORTED)'" ``` -Nous n'utilisons pas la commande relatives au messages (`info`, `warning` et +Nous n'utilisons pas les commandes relatives aux messages (`info`, `warning` et `error`) que nous avons vu dans le précédent article, sinon un message `make: Nothing to be done for 'info'.` apparaît après les informations. +Voici le résultat de cette cible: + +```shell +$ make info +document.............'build/presentation.pdf' +bitmap images........'images/bitmap/ferret.jpg' +SVG images...........'images/svg/souris.svg' +exported SVG images..'images/generated/souris.pdf' +``` + ### Lancer l'application de visualisation des PDF Lancer la compilation d'un document et l'afficher ensuite dans notre visionneur -de document permet souvent de gagner du temps. +de documents permet souvent de gagner du temps. Partons du principe que nous +utilisons [Zathura][l_zathura] comme visionneur de documents. ```make LC = lualatex @@ -347,41 +400,44 @@ view: default Deux nouvelles variables font leur apparition : - * `VIEWER` qui contient le nom du programme utilisé comme visionneur, - [zathura][l_zathura] dans l'exemple. + * `VIEWER` qui contient le nom du programme utilisé comme visionneur * `VIEWER_FLAGS` qui contient les options de notre visionneur Nous avons aussi une nouvelle cible `view`, comme elle ne réalise aucune -création de fichier nous ladéclarons comme cible `.PHONY`. La seule dépendance -ce cette cible est `default`. Ainsi lors de l'appel de `view`, **notre document -sera recompilé si nécessaire**. - +création de fichiers nous la déclarons comme cible `.PHONY`. La seule dépendance +de cette cible est `default` : ainsi lors de l'appel de `view`, notre document +sera recompilé **si nécessaire**. + [l_zathura]:https://pwmt.org/projects/zathura/ ## En conclusion Partant d'un `Makefile` standard, nous l'avons amélioré au fur et à mesure en -utilisant les fonctionnalités proposé par *make*. Bien entendu cet exemple est -valable pour les documents simple, il sera alors nécessaire de l'adapter pour +utilisant les fonctionnalités proposées par *make*. Bien entendu cet exemple est +valable pour les documents simples, il sera alors nécessaire de l'adapter pour prendre en compte les **compilations multi-passes** pour la gestion des -bibiographies par exemple. +bibliographies par exemple. -De mon côté j'ai profité de l'écriture de cet article pour améliorer mon -processus de compilation de mes documents LaTeX. Au final, chaque dépôt de code -contenant des documents prend la forme suivante : +De mon côté, j'utilise énormément LaTeX pour les courriers officiels, les rendu +des différents TD pour l'Université, mes présentations. J'ai profité de +l'écriture de cet article pour améliorer mon processus de compilation de tous +mes documents. Au final, chaque dépôt de code contenant des documents prend la +forme suivante : ``` -├── images -│   ├── bitmap +├── images/ +│   ├── bitmap/ │ │ └── ... -│   ├── generated +│   ├── generated/ │   └── svg │ └── ... ├── Makefile -├── build +├── build/ ├── README.md └── document.tex ``` *[PDF]: Portable Document Format *[SVG]: Scalable Vector Graphics +*[JPEG]:Join Photographic Experts Group +*[PNG]: Portable Network Graphic