[couverture de Linux Magazine 85]

Perles de Mongueurs (25)

Article publié dans Linux Magazine 85, juillet/août 2006.

[+ del.icio.us] [+ Developers Zone] [+ Bookmarks.fr] [Digg this] [+ My Yahoo!]

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).

Améliorer les impressions de code source

Introduction

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équat

Aprè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 :

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.

Le code

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 -%]

Conclusion

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 ?

Références

[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

À vous !

Envoyez vos perles à perles@mongueurs.net, elles seront peut-être publiées dans un prochain numéro de Linux Magazine.

[IE7, par Dean Edwards] [Validation du HTML] [Validation du CSS]