Du LaTeX sans LaTeX avec Pandoc !
Table des matières
Dans l’article précédent, je vous expliquais en quoi et pourquoi LaTeX ne me convenait plus. J’étais donc à la recherche d’un système de composition de document qui permettrait de m’affranchir des contraintes de LaTeX, tout en gardant une qualité de document (typographiquement et organisationnellement parlant) similaire. Sachez que j’ai trouvé chaussure à mon pied, en testant deux produits. Le premier étant txt2tags et le deuxième étant Pandoc. Sachez que le deuxième l’emporte haut la main ! Voyons ça !
Les deux logiciels que je vais présenter ici produisent des PDF en utilisant LaTeX, il vous faut donc une distribution LaTeX. Pour ceux qui n’en disposent pas et qui souhaitent en installer une, l’ami Maxime Auvy vous propose un tutoriel pour le faire !
Le but
Suite à une explication sur «LaTeX c’est cool, mais on en a gros», je résume rapidement ce que je cherche actuellement, à savoir un système de composition avec les points suivants:
- Syntaxe simple et texte brut
Une syntaxe simple, de préférence à balise légère ou marquage simple, donc exit les cochoncetées du genre HTML ou BBCode, c’est trop de perte de temps. Idéalement le markdown, syntaxe que j’utilise énormément, je fais des CR de réunions, des notes, et bien sûr mes articles avec ce langage (Git-Flavored-Markdown concernant Unixmail). Avec les bons outils, l’éditeur fait la moitié du boulot (coucou Emacs). Tout simplement parce que les symboles \
et dérivés sont chiants et relativement loins de mes doigts et que j’en ai marre de me tordre en 4 pour taper un symbole qui revient relativement souvent (et que j’avais remappé sous Emacs tellement c’était peu accessible).
- Pas de compilation, ou alors transparente
Ça coule de source avec le point précédent. Si le balisage du texte est simple, les erreurs sont moins nombreuses et généralement plus visibles, ce qui aide grandement en cas de crise de gros doigts (ce qui, avouons-le, arrive souvent).
- Souple
Je souhaite quelque chose d’aussi souple que LaTeX dans les dispositions de page et possibilités syntaxiques, comme l’inclusion de code source, des listes, des niveaux hiérarchiques de titre, des notes de bas de page, des environnements mathématiques, des images, des tableaux, etc. Bref, je ne veux pas être restreint et borné à un seul type de document que je ne peux pas modifier.
Déjà si on dispose de tout ça, ça sera un bon début ! Dans mes recherches, j’ai vu deux produits qui correspondent plus ou moins à ce que je souhaite…
txt2tags
Le premier étant txt2tags. Une syntaxe Markdown, 18 formats d’exports. Il fonctionne plutôt bien mais à mon goût il n’est pas assez flexible et il y a parfois besoin de retoucher la sortie. Je vous explique…
Fonctionnement de txt2tags
On écrit une fois, on exporte en ce qu’on souhaite. De manière personnelle, j’ai souvent besoin de 2 formats de sortie, le HTML et le PDF. Le principe est simple. Le document de base avec l’extension .t2t
est la source de la forme suivante:
Titre
Auteur
Date
OPTIONS
Corps du document
Bien évidement, les options dépendent du format de sortie. Pour un document compilé soit en HTML ou en LaTeX, il est quand même préférable de passer par un Makefile.
Un fichier Makefile est une suite d’instructions qui va contenir des informations sur comment traiter des fichiers sources, les relations entre elle, l’éventuelle transformation. Il va «construire» votre fichier de sortie.
Un makefile pour txt2tags peut être construit de la manière suivante:
DOCUMENT = newdoc
TXT2TAGS = /home/zilkos/Outils/txt2taggs/txt2tags
all: pdf clean html
html:
$(TXT2TAGS) -t xhtml --toc --css-inside --outfile $(DOCUMENT).html $(DOCUMENT).t2t
pdf:
$(TXT2TAGS) -t tex --outfile $(DOCUMENT).tex $(DOCUMENT).t2t
-pdflatex -interaction batchmode $(DOCUMENT).tex
clean:
-rm *~
-rm .*~
-rm $(DOCUMENT).toc
-rm $(DOCUMENT).tex
-rm *.log
-rm *.out
-rm *.aux
Ainsi, un make pdf
dans le dossier en question me sort un PDF et garde les fichiers intermédiaires (.tex, .log et conssorts). Un make all
me sort un HTML, un PDF et nettoie les fichiers intérmédiaires car il va executer la partie pdf, la partie, html, et la partie clean définies dans le makefile.
Pour passer des options au document LaTeX, il faut procéder de la manière suivante:
% Packages supplémentaires
%!style(tex): babel
%!style(tex): mathdesign
%!style(tex): geometry
% Gestion babel français + font
%!postproc(tex): {babel} [frenchb]{babel}
%!postproc(tex): {mathdesign} [charter]{mathdesign}
% Enlever le clearpage + ajouter la geometry
%!postproc(tex): "\\clearpage" ""
Les lignes commencant par %
sont des commentaires, les %!
étant les options. Une bête ligne du type %!style(tex): package
rajoute tout simplement un \usepackage{package}
dans votre préambule. On y voit des lignes postproc(xxx) : xx xx
, le fonctionnement est tout simplement du «cherche et remplace». Par exemple pour %!postproc(tex): {babel} [frenchb]{babel}
il va chercher le morceau de texte {babel}
et le remplacer par [frenchb]{babel}
. Cette partie intervient uniquement après le parse et le process, car il doit agir sur le .tex généré. Il existe le même principe mais qui oeuvre sur la source avant le parse et process, c’est les preproc
qui permet de remplacer à la volée.
Exemple, vous écrivez une lettre et vous voulez qu’elle soit générique. Vos preprocs
seront de la sorte:
%!preproc: NOM "Jean DUPOND"
%!preproc: RELEASE "0.2"
%!preproc: SOFT "TuxZord 2000"
%!proproc: SITE "http://unixmail.fr"
Bonjour, je suis NOM et je suis l'auteur du logiciel SOFT dont je vous présente la release n° RELEASE. Vous pouvez la trouver sur mon site personnel: SITE
Même fonctionnement, du «cherche et remplace». Plutôt pratique, mais ça ne fonctionne pas sur les headers ou les options du document, uniquement sur le corps du document !
Le fichier LaTeX de base utilisé par txt2tags est le suivant:
\documentclass{article}
\usepackage{graphicx}
\usepackage{paralist} % needed for compact lists
\usepackage[normalem]{ulem} % needed by strike
\usepackage[urlcolor=blue,colorlinks=true]{hyperref}
\usepackage[utf8]{inputenc} % char encoding
\usepackage[frenchb]{babel} % user defined
\usepackage[charter]{mathdesign} % user defined
\usepackage{geometry} % user defined
\title{Titre}
\author{Auteur}
\begin{document}
\date{Date}
\maketitle
% LaTeX2e code generated by txt2tags 2.6 (http://txt2tags.org)
% cmdline: txt2tags -t tex test.t2t
\end{document}
Assez concis et très générique. Sans doute trop générique. Pour avoir ce que je voulais, je fus obligé de modifier le .tex de sortie puis de le compiler via pdflatex
ensuite.
En bref, c’est un peu lourd et trop long en ce qui me concerne (le Makefile, les options selon le document, la modification obligatoire du tex puis la compilation). Et puis j’ai découvert Pandoc.
Pandoc
Il est similaire à txt2tags mais est, à mon sens, plus abouti et beaucoup souple. Son but est le même, une application en ligne de commande qui permet de convertir un fichier texte balisé dans les formats suivants:
- Markdown,
- ReStructuredText
- Textile
- HTML
- DocBook
- LaTeX
Vers les formats suivants:
Famille | Format |
---|---|
HTML | XHTML, HTML5, Slidy, S5, DZSlide |
Traitements de texte | Word (docx), ODT, OpenDocument XML |
Ebooks | EPUB |
Documentation | DocBook, GNU TexInfo, Groff man pages |
Tex | LaTeX, ConTeXt, Beamer |
Via LaTeX | |
Balisages légers | Markdown, ReStructuredText, AsciiDoc, MediaWiki, Emacs Org-mode, Textile |
Oui, rien que ça ! C’est parti pour un petit tutoriel rapide qui utilisera:
- Un fichier de base avec le langage de balisage de Pandoc (extrêmement similaire au Markdown, mais étendu)
- Des options pour modifier le PDF de sortie (plus précisément le tex qui sera généré silencieusement)
- Du PDF en sortie via LaTeX
Installation
Plusieurs options s’offrent à vous:
- Via les dépôts de votre distribution
- Via les packages disponibles sur le site de Pandoc
- Compiler via les sources
Très honnêtement, les binaires disponibles sur le site sont largement plus à jour que la version présente dans les dépôts.
Allez donc sur le repo de pandoc récupérer le binaire (ou les sources), selon votre OS et selon votre architecture et installez ça tendrement.
Fonctionnement général
Via la console
Le fonctionnement est très simple. Un fichier d’entrée, une spécification de fichier de sortie. Dans le cas d’un fichier court, il est possible de faire ça directement dans un terminal, de la manière suivante:
Les lignes ou fins de ligne débutant par !! sont des commentaires uniquement pour le bien de cet article, ce n’est pas le symbole utilisé pour indiquer un commentaire dans les fichiers sources Pandoc.
pandoc !! Lance pandoc, il "attend" sur la sortie standard
!! On tape le contenu:
Coucou *unixmail*
- Un
- Deux
Quand vous avez fini, tapez Ctrl + D
et hop, Pandoc vous retourne le code HTML correspondant à votre entrée. C’est tout simplement comme ça que ça fonctionne, sauf qu’en passant par les fichiers on va pouvoir spécifier des options supplémentaires qui vont changer plein de choses, soit dans les fichiers, soit dans la ligne de commande permettant de «transformer» le fichier.
Via un fichier
Placez-vous dans un dossier et créez votre fichier Pandoc, en markdown, donc avec l’extension .md
.
Un fichier source Pandoc en markdown est formaté de la manière suivante:
---
title: Votre titre
author: Votre nom
date: 11 mars 2016
---
Corps du document
Ouvrez un terminal et placez vous dans le dossier contenant votre fichier. La ligne suivante permet de convertir votre fichier d’entrée (donc le fichier markdown) en un fichier PDF.
pandoc mondocument.md -o mondocument.pdf
-o
comme out qui veut dire sortie, quoi de plus logique ! Et voilà un PDF tout choupinet généré en un rien de temps rien que pour vous.
Sauf que, il y a quand même des soucis avec ce PDF, non ? Essayez d’écrire un document un peu plus long. Personnellement, je trouve que les marges sont beaucoup trop grandes. LaTeX nous permet de fixer les marges avec le package geometry
puis l’instruction \geometry{hmargin=2.5cm,vmargin=1.5cm}
. Très bien, mais comment fait-on étant donné que n’avons pas de .tex ? Rassurez vous, Pandoc a tout prévu !
Utilisons un template !
Pour nous donner beaucoup plus de souplesse, on va utiliser un template. Ce template sera modulaire et pourra contenir énormément de configurations de base. Nous allons utiliser la collection de template de John MacFarlane disponible sur GitHub.
Pandoc «regarde» l’existence de template à un endroit bien précis par défaut, cet emplacement est situé ici: /home/$USER/.pandoc/templates
. Vous pouvez modifier ce comportement en passant en paramètre de pandoc l’options --data-dir
comme ceci:
$ pandoc --data-dir=/votre/chemin/
Téléchargez les templates depuis GitHub en ligne de commande ou directement depuis le site et placez les fichiers de templates dans ~/.pandoc/templates
wget https://github.com/jgm/pandoc-templates/archive/master.zip
unzip -e master.zip
mkdir -p ~/.pandoc/templates && mv pandoc-templates-master/* ~/.pandoc/templates
Voilà, nous avons tout ce qu’il faut. Autant vous le dire tout de suite, j’ai rencontré un soucis avec le template LaTeX. Il me sortait une erreur (à la con, comme beaucoup d’erreur LaTeX) comme quoi un circledS
était déjà défini quelque part. Vu que je ne me sers absolument jamais de ce symbole, j’ai édité légèrement le template LaTeX en enlevant un package. C’est situé à la ligne 11 et le package en question est amssymb
. Ainsi, plus d’erreur.
Regardez un peu le fichier de template. Il est certes, long mais relativement instructif. Vous voyez beaucoup de $if$
, c’est normal. Si vous définissez une option, vous passez dans le $if$
pour «activer» le package correspondant.
Des options par défaut pour un bon document PDF
Par exemple, on peut voir dans le template à la ligne 64 des définitions d’hypersetup
, qui je le rappelle permet d’indiquer diverses choses comme:
- Différentes informations dans les méta-données du PDF (auteur, titre)
- Une gestion de la coupure des liens trop longs
- Une colorisation des liens
- Et bien d’autres choses
Le code correspondant est celui-ci:
\hypersetup{breaklinks=true,
bookmarks=true,
pdfauthor={$author-meta$},
pdftitle={$title-meta$},
colorlinks=true,
citecolor=$if(citecolor)$$citecolor$$else$blue$endif$,
urlcolor=$if(urlcolor)$$urlcolor$$else$blue$endif$,
linkcolor=$if(linkcolor)$$linkcolor$$else$magenta$endif$,
pdfborder={0 0 0}}
Et bien tout ce qui est entre $
est tout simplement une option. En fait, nous avons déjà passé des options lors de notre premier test, sans le savoir ! En effet, regardez dans le template à la ligne 160, on y trouve ce bloc:
$if(title)$
\title{$title$$if(subtitle)$\\\vspace{0.5em}{\large $subtitle$}$endif$}
$endif$
$if(author)$
\author{$for(author)$$author$$sep$ \and $endfor$}
$endif$
\date{$date$}
Qui dit très clairement, Si il y a un titre, tu construis le \title
et idem pour l’auteur et la date. Souvenez-vous du début de notre document de test…
---
title: Votre titre
author: Votre nom
date: 2 octobre 2015
---
Corps du document
Oh, title
, author
et date
! Et oui, les lignes dans le bloc entouré de tiret (-
) au début du document sont des options. Et des options, autant vous dire de suite qu’il y en a pléthore ! Pour information, le $author-title
dans le hypersetup
est l’équivalent du $title$
, inutile de l’indiquer en plus dans les options… Options qu’on va fixer de suite, notamment pour les marges, avant que je me fasse fâcher !
Bon ça vient ces marges !
Ha, les marges ! Et bien les marges, c’est une option ! En rajoutant ceci, nous avons les marges à notre convenance:
geometry: margin=1in
Et hop, on rentre dans les bons $if$
et notre option est passée au .tex ! Les templates, c’est puissant ! Pour information, la liste des options est disponible ici. Faites le tri, c’est en vrac !
De manière personnelle, pour les choses que je sais que je ne vais jamais modifier, comme la police utilisée dans le document, j’ai directement surchargé le template en y passant ma police, comme dans un document LaTeX standard. Une fois défini dans le template, je n’ai plus besoin d’y toucher !
Extrêmement pratique. Notez aussi que par défaut, et ça txt2tags ne le gère pas par défaut, si vous incluez du code source, il sera mis automatiquement en forme (et en couleur si vous indiquez le langage de la même manière qu’en Markdown):
def check_sqrt(a, cache)
if cache.key?(a)
return cache[a]
end
cache[a] = Math.sqrt(a)
return cache[a]
end
cache = Hash.new()
puts check_sqrt(9, cache)
puts check_sqrt(9, cache)
Et bien votre PDF de sortie contiendra cet exemple de code source… coloré selon le langage indiqué ! Notez que ça fonctionne sans template, tout simplement car c’est inclus de base. Tout est inclu pour que 100% de votre balisage en markdown soit correctement rendu dans votre PDF de sortie.
La syntaxe utilisée
La syntaxe des documents en presque-markdown pour une transformation en n’importe quel format est très simple, dérivée du markdown, et enrichie. Vraiment enrichie. La documentation est très claire, mais longue car elle couvre tous les cas de figures.
Absolument TOUT est indiqué dedans. C’est clair, dans un anglais simple et compréhensible, même pour des étudiants. Attention toutefois, certaines options et pratiques sont très puissantes, mais pas forcément évidentes à prendre en main.
Pandoc et Emacs
Emacs, mon amour de toujours dispose bien évidemment d’un mode pour Pandoc créé par Joost Kremers, qui est aussi l’auteur de l’excellent writeroom-mode qui est un mode d’écriture sans distraction pour Emacs. pandoc-mode
est disponible ici.
Pour faire simple, il suffit d’installer pandoc-mode depuis MELPA via un M-x package-install <RET> pandoc-mode <RET>
(RET
pour la touche entrée). Puis d’ajouter à votre init la ligne suivante:
(load "pandoc-mode")
Ensuite, tapez un M-x pandoc-mode
pour l’activer.
Si vous souhaitez l’activer automatiquement à l’ouverture d’un fichier markdown, ajoutez le hook suivant à votre fichier d’init:
(add-hook 'markdown-mode-hook 'pandoc-mode)
Pour le reste, je vous invite à consulter le site de Joost Kremers cité plus haut.
Fin
J’espère que ceci vous aidera dans votre choix de workflow de document. Je croise pas mal de personne en ce moment qui rencontrent le problème, sachez que Pandoc est l’une des nombreuses solutions possibles. De manière personnelle je le sors quand j’ai besoin de faire un gros document. De manière habituelle, j’utilise Markdown pour les choses courantes (CR de réunion, notes, procédures, etc) et j’utilise Pandoc là où, avant, je sortais LaTeX. Au final, je suis plus rapide sous Pandoc que sous LaTeX, mais en gardant la même qualité de document, c’est donc… parfait !