Article publié dans Linux Magazine 85, juillet/août 2006.
La perle de ce mois-ci a été rédigée par Emmanuel Di Prétoro
<manu@bjornoya.net>
, un habitué du canal #perlfr
(serveur irc.mongueurs.net
).
Avec la sortie récente de Perl Best Practices de Damian Conway[1], et sa lecture, j'ai été pris d'un envie soudaine de me plonger dans le code de quelques modules employés régulièrement. D'une part, cela me permettait d'améliorer ma culture Perl, et d'autre part, de mettre en application les conseils donnés par Damian.
Seulement voilà, quand j'ai du temps à consacrer à cette lecture, je n'ai pas toujours un ordinateur à portée de main, ainsi dans les transports en commun, je peux facilement grappiller une petite heure par jour, ce qui n'est pas rien au final. J'ai ainsi imprimé quelques pages de code. Malheureusement, les résultats n'ont pas été aussi lisibles qu'attendu, les fontes employées par défaut pour l'impression de fichier texte ne m'étant pas fort agréables à l'œil.
J'ai commencé à réfléchir à ce qui pourrait offrir un rendu plus agréable, et cela m'a rappelé les codes sources que j'avais dû inclure dans des rapports à l'université. J'utilisais LaTeX pour ces rapports, et donc, je me suis dit que ce logiciel pouvait encore me rendre service.
Listings
, l'outil adéquatAprès avoir consulté la FAQ LaTeX[2], j'ai trouvé le package qu'il me
fallait : listings
[3]. Ce dernier permet de traiter un traiter un nombre
impressionnant de langages et même si dans un premier temps je ne
comptais lire que du code Perl, je pourrai êtendre assez facilement
mon script à d'autres langages.
Il permet en plus de définir un certain nombre de comportements intéressants, comme par exemple :
la numérotation des lignes ;
une mise en évidence syntaxique ;
...
Dans le cadre de ce script, je n'ai pas été plus loin dans l'exploitation des
fonctionnalités de listings
, mais les possibilités sont nombreuses, et
j'invite le lecteur à consulter la documentation de ce package.
Template::Toolkit
et Perl::Tidy
La description du projet à ce stade était d'inclure le fichier source que
je souhaitais imprimer dans un fichier modèle, et de le compiler au moyen de
LaTeX (enfin, pdflatex pour être plus précis). Cela ressemble beaucoup à une
tâche pour Template::Toolkit
, et en vérifiant sur le CPAN[4], j'ai pu
constater que ce dernier gérait le format LaTeX, via la distribution
Template-Latex
. Un coup d'œil sur la documentation me décrivait
comment je pouvais m'y prendre.
La dernière chose à faire était d'embellir le code source avant d'en générer
une sortie PDF, ce qui est le travail de Perl::Tidy
. Cette opération a été
rendue nécessaire car après quelques utilisations, je suis tombé sur quelques
modules dont les lignes dépassaient nettement d'une page A4. L'utilisation de
Perl::Tidy
permet de résoudre ce problème de mise en page.
Quelques remarques concernant le code, j'utilise le handle de fichier
prédéfini DATA
pour stocker le modèle de fichier LaTeX. Le premier argument
attendu par process
, c'est-à-dire la fonction effectuant le traitement du
modèle, pouvant être une référence à un handle de fichier, c'est ce que j'ai
fait dans le cas présent, sous la forme d'un \*DATA
.
Au final, voici le script que cela donne :
#!/usr/bin/perl -w use strict; use warnings; use Template; use Getopt::Long; use Perl::Tidy; use File::Temp; # options par défaut my $config = { output => './prettyprinter-output.pdf', config => '/Users/manu/bin/.perltidyrc', }; my $usage = "$0: [ --config file ] --input file [ --output file ]\n"; # paramètres de ligne de commande GetOptions( $config, "input=s", "output=s", "config=file" ) or die $usage; die $usage if ! exists $config->{input}; my $template = Template->new(); # création d'un fichier temporaire # afin d'y mettre la version embellie du fichier source my $tmp_source = File::Temp->new( UNLINK => 1, SUFFIX => ".tmp" ); # mise en forme du code source par Perl::Tidy perltidy( source => $config->{input}, destination => $tmp_source->filename, perltidyrc => $config->{config}, ); my $output = $config->{output}; # traitement du template $template->process( \*DATA, { file => $tmp_source->filename }, $output ) or die $template->error(); __DATA__ [% FILTER latex("pdf") -%] \documentclass[9pt]{article} \usepackage{color} \usepackage{times} \usepackage{pifont} \usepackage{pslatex} \usepackage{fancyhdr} \usepackage{fancybox} \usepackage{fullpage} \usepackage[T1]{fontenc} \usepackage[french]{babel} \usepackage[latin1]{inputenc} \usepackage{listings} \begin{document} \lstset{ language=Perl, % le langage showspaces=false, % afficher les espaces de manière visible ou non showstringspaces=false, % idem dans les chaînes showtabs=false, % idem pour les tabulations numbers=left, % où afficher les numéros de lignes numberstyle=\tiny, % le style à employer pour les numéros de lignes stepnumber=2, % le pas d'affichage des numéros de ligne numbersep=5pt,} \lstinputlisting{[% file -%]} \end{document} [% END -%]
Et voilà, grâce à ce petit script, je peux maintenant lire le code souhaité à
mon aise dans les transports en commun. Dans le futur, je pourrai exploiter
éventuellement les langages reconnus par listings en incluant un mécanisme
de reconnaissance du langage employé dans le fichier donné en argument,
pourquoi pas en utilisant File::MMagic
?
[1] Perl Best Practices - Damian Conway, O'Reilly & Associates, 2005, ISBN 0-596-00173-8, http://www.oreilly.com/catalog/perlbp/ ; Disponible en français sous le titre De l'art de programmer en Perl (O'Reilly 2006, ISBN 2-84177-369-8).
[2] FAQ LaTeX - http://www.grappa.univ-lille3.fr/FAQ-LaTeX/
[3] Comment insérer un code source dans un document ? - http://www.grappa.univ-lille3.fr/FAQ-LaTeX/29.53.html
[4] CPAN - http://www.cpan.org/ pour les modules cités
Envoyez vos perles à perles@mongueurs.net
, elles seront peut-être
publiées dans un prochain numéro de Linux Magazine.
Copyright © Les Mongueurs de Perl, 2001-2011
pour le site.
Les auteurs conservent le copyright de leurs articles.