Latex : Insérer du code source grâce au package listings

Partager cet article

Temps estimé pour la lecture de cet article : 22 min

Introduction

latex-listings-default

Pour insérer du code source dans un document latex, il est possible d’utiliser le package listings.

\usepackage{listings}

Il vous suffit alors d’utiliser l’environnement du même nom, comme ceci :

\begin{lstlisting}
Put your code here.
\end{lstlisting}

Si vous avez beaucoup de code à insérer ou même si vous ne voulez pas mélanger le texte de votre rapport avec du code (oui, ça peut largement alourdir le document), il est possible d’inclure le fichier source :

\lstinputlisting{source.c}

On va également alors pouvoir préciser le langage qui doit être utilisé pour la coloration et également un intervalle de ligne.

\lstinputlisting[language=C, firstline=37, lastline=45]{source.c}

Voici une liste non-exhausitve des langages supportés : Asm, Bash, C++, C#, Caml, Delphi, Erlang, Gnuplot, HTML, Java, Make, Objective-C, Perl, PHP, Python, SQL, XML…

Problèmes d’encodage

Malheureusement par défaut le package listings ne supporte pas l’encodage multi-bits. L’option extendedchar fonctionne seulement avec un encodage sur 8 bits comme l’encodage latin1.

Ainsi, si vous avez besoin de supporter l’UTF-8, il faut expliquer au package comment il doit se comporter quand il rencontre tel ou tel caractère. Pour ce faire, on utilise l’option literate grâce à la commande lstset qui permet de préciser des options.

\lstset{
  literate=
  {á}{{\'a}}1 {é}{{\'e}}1 {í}{{\'i}}1 {ó}{{\'o}}1 {ú}{{\'u}}1
  {Á}{{\'A}}1 {É}{{\'E}}1 {Í}{{\'I}}1 {Ó}{{\'O}}1 {Ú}{{\'U}}1
  {à}{{\`a}}1 {è}{{\`e}}1 {ì}{{\`i}}1 {ò}{{\`o}}1 {ù}{{\`u}}1
  {À}{{\`A}}1 {È}{{\'E}}1 {Ì}{{\`I}}1 {Ò}{{\`O}}1 {Ù}{{\`U}}1
  {ä}{{\"a}}1 {ë}{{\"e}}1 {ï}{{\"i}}1 {ö}{{\"o}}1 {ü}{{\"u}}1
  {Ä}{{\"A}}1 {Ë}{{\"E}}1 {Ï}{{\"I}}1 {Ö}{{\"O}}1 {Ü}{{\"U}}1
  {â}{{\^a}}1 {ê}{{\^e}}1 {î}{{\^i}}1 {ô}{{\^o}}1 {û}{{\^u}}1
  {Â}{{\^A}}1 {Ê}{{\^E}}1 {Î}{{\^I}}1 {Ô}{{\^O}}1 {Û}{{\^U}}1
  {œ}{{\oe}}1 {Œ}{{\OE}}1 {æ}{{\ae}}1 {Æ}{{\AE}}1 {ß}{{\ss}}1
  {ű}{{\H{u}}}1 {Ű}{{\H{U}}}1 {ő}{{\H{o}}}1 {Ő}{{\H{O}}}1
  {ç}{{\c c}}1 {Ç}{{\c C}}1 {ø}{{\o}}1 {å}{{\r a}}1 {Å}{{\r A}}1
  {€}{{\EUR}}1 {£}{{\pounds}}1
}

Exemple de mise en forme

Mais lstset permet bien sur beaucoup plus que ça, on peut ainsi mettre en forme son code, avec l’apparence qu’on le désire, par exemple, voici ce que l’on peut obtenir :

latex-listings-custom

Voici, le code latex correspondant :

\documentclass{report}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[english]{babel}
\usepackage{fullpage}
\usepackage{color}
\usepackage[table]{xcolor}
\usepackage{listings}

\definecolor{darkWhite}{rgb}{0.94,0.94,0.94}

\lstset{
  aboveskip=3mm,
  belowskip=-2mm,
  backgroundcolor=\color{darkWhite},
  basicstyle=\footnotesize,
  breakatwhitespace=false,
  breaklines=true,
  captionpos=b,
  commentstyle=\color{red},
  deletekeywords={...},
  escapeinside={\%*}{*)},
  extendedchars=true,
  framexleftmargin=16pt,
  framextopmargin=3pt,
  framexbottommargin=6pt,
  frame=tb,
  keepspaces=true,
  keywordstyle=\color{blue},
  language=C,
  literate=
  {²}{{\textsuperscript{2}}}1
  {⁴}{{\textsuperscript{4}}}1
  {⁶}{{\textsuperscript{6}}}1
  {⁸}{{\textsuperscript{8}}}1
  {€}{{\euro{}}}1
  {é}{{\'e}}1
  {è}{{\`{e}}}1
  {ê}{{\^{e}}}1
  {ë}{{\¨{e}}}1
  {É}{{\'{E}}}1
  {Ê}{{\^{E}}}1
  {û}{{\^{u}}}1
  {ù}{{\`{u}}}1
  {â}{{\^{a}}}1
  {à}{{\`{a}}}1
  {á}{{\'{a}}}1
  {ã}{{\~{a}}}1
  {Á}{{\'{A}}}1
  {Â}{{\^{A}}}1
  {Ã}{{\~{A}}}1
  {ç}{{\c{c}}}1
  {Ç}{{\c{C}}}1
  {õ}{{\~{o}}}1
  {ó}{{\'{o}}}1
  {ô}{{\^{o}}}1
  {Õ}{{\~{O}}}1
  {Ó}{{\'{O}}}1
  {Ô}{{\^{O}}}1
  {î}{{\^{i}}}1
  {Î}{{\^{I}}}1
  {í}{{\'{i}}}1
  {Í}{{\~{Í}}}1,
  morekeywords={*,...},
  numbers=left,
  numbersep=10pt,
  numberstyle=\tiny\color{black},
  rulecolor=\color{black},
  showspaces=false,
  showstringspaces=false,
  showtabs=false,
  stepnumber=1,
  stringstyle=\color{gray},
  tabsize=4,
  title=\lstname,
}

\begin{document}

\begin{lstlisting}
#include <stdio.h>

int main(void) {
  printf("Hello World\n");
  return EXIT_SUCCESS;
}
\end{lstlisting}

\end{document}

Regardons les options les plus pertinentes :

  • aboveskip : permet de définir une marge juste avant l’insertion du code source
  • belowskip : permet de définir une marge après l’insertion du code source
  • backgroundcolor : permet de définir la couleur de fond du code
  • keywordstyle : permet de définir l’apparence des mots-clés du langage
  • numbers : permet de définir la position des chiffres pour compter les lignes, on peut également masquer les chiffres grâce à l’option none
  • numbersep : la taille des espaces entre les chiffres
  • tabsize : le nombre d’espace pour une indentation

Pour plus d’informations, rien ne vaut la documentation officielle 🙂 !

L’alternative avec le package minted

latex-source-code-minted

Minted, c’est un package qui est devenu populaire, il utilise le programme externe pygments, qui est une libraire python pour colorer du code. Cette dernière supporte plus de 300 langages différents.

Comme le package utilise un code python externe, il demande un peu plus de réglages qu’avec un package classique. Je vous laisse suivre la documentation officielle ou ce sympathique petit tutoriel.

Bonus: avoir un cadre complètement fermé grâce au package tcolorbox

Le problème est le suivant, si votre code source est assez long, la mise en forme du package ne plaira pas forcément à tout le monde car le cadre se retrouve coupé et continue sur la page d’après, voici ce qu’on obtient alors :

latex source code issue frame

Pour répondre à la question de Francis, il est possible grâce au package tcolorbox de corriger ce comportement. On va redéfinir le style du cadre et créée un nouvel environnement de listing grâce à la commande newtcblisting (pour plus d’informations sur la commande, je vous laisse lire la documentation officielle). Toutefois, par rapport à mon article comme on gère maintenant le style du cadre avec tcolorbox, il ne faut pas oublier de supprimer quelques lignes de notre lstset, sinon, on va se retrouver avec deux cadres qui vont se marcher dessus. Bref, en adaptant un peu, j’ai ceci :

\documentclass{article}

\usepackage{tcolorbox,listings}
\usepackage{fullpage}
\usepackage{color}

\definecolor{darkWhite}{rgb}{0.94,0.94,0.94}

\lstset{
	backgroundcolor=\color{darkWhite},
	breakatwhitespace=false,
	breaklines=true,
	captionpos=b,
	commentstyle=\color{red},
	deletekeywords={...},
	escapeinside={\%*}{*)},
	extendedchars=true,
	keepspaces=true,
	keywordstyle=\color{blue},
	language=C,
	morekeywords={*,...},
	showspaces=false,
	showstringspaces=false,
	showtabs=false,
	stepnumber=1,
	stringstyle=\color{gray},
	tabsize=4,
	title=\lstname,
}

\lstdefinestyle{frameStyle}{
	basicstyle=\footnotesize,
	numbers=left,
	numbersep=20pt,
	numberstyle=\tiny\color{black}
}

\tcbuselibrary{listings,skins,breakable}

\newtcblisting{customFrame}{
	arc=0mm,
	top=0mm,
	bottom=0mm,
	left=3mm,
	right=0mm,
	width=\textwidth,
	listing only,
	listing options={style=frameStyle},
	breakable
}

\begin{document}

\begin{customFrame}
...
\end{customFrame}

\end{document}

Ce qui va nous donner ce magnifique cadre :

latex source  code frame solution

On remerciera le forum tex de stackexchange ! En espérant que ça puisse aider quelqu’un d’autre !

3 comments

  1. Existe-il un moyen de faire qu’un listing qui s’étale sur plusieurs pages ait un cadre complètement fermé à chaque page?
    Actuellement j’ai un cadre qui reste ouvert en bas de page à la première. et ouvert en haut à la deuxième

    • Oui, c’est possible, j’ai mis à jour l’article, en espérant que les précisions supplémentaires auront pu vous aider.
      Bon week-end à vous !

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.