Reword and syntax coorrections
Thanks Eclipse, Duponin Heuzef and my wife
This commit is contained in:
parent
46b5c7989b
commit
1f151ee32e
1 changed files with 139 additions and 83 deletions
|
@ -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 <motif>` pour récupérer une liste de fichier dans le répersoire
|
||||
Notre macro `DOCUMENTS` est une imbrication de 3 fonctions :
|
||||
|
||||
1. `wildcard <motif>` pour récupérer une liste de fichiers dans le répertoire
|
||||
courant en fonction d'un motif;
|
||||
2. `patsubst <motif>,<remplacement>,<chaine>` pour substituer une partie de la
|
||||
chaine dans un chemin, `%` fait ici office de caractère joker;
|
||||
2. `patsubst <motif>,<remplacement>,<chaine>` pour substituer une partie de la
|
||||
chaîne dans un chemin, `%` fait ici office de caractère joker;
|
||||
3. `addprefix <prefix>, <chaine>` 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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue