Plone 5 : Inclure du code avec la coloration synthaxique (restructuredText)

Pygments permet de rendre du code informatique plus lisible en y ajoutant des informations de style et des couleurs. Après une introduction au module Pygments, nous verrons comment l'intégrer dans Plone 5 afin de pouvoir utiliser la coloration syntaxique dans nos articles rédigés en "text/restructured".

Coloration syntaxique avec Pygments

Introduction à Pygments

La coloration syntaxique permet de donner une couleur et un style particulier à chaque élément constituant un code source informatique, l'objectif étant de rendre ce code plus lisible et agréable à lire.

Pygments est une library Python qui permet la coloration syntaxique d'un très grand nombre de langages informatiques tel que Python, HTML, CSS, Javascript, PHP, Ruby, etc. Cet outil peut être utilisé directement avec la ligne de commande ou en tant que librairie intégrée dans un projet, permettant ainsi l'affichage de codes sources informatiques dans un site web, un wiki, un forum, etc.

Installer Pygments

Rien de plus simple, dans votre environnement virtuel Python :

pip install pygments

Générer la version HTML d'un "bout de code"

Soit le fichier code.py contenant le code Python suivant :

# Fibonacci numbers
def fib(n):    # write Fibonacci series up to n
    a, b = 0, 1
    while b < n:
        print(b, end=' ')
        a, b = b, a+b
    print()

La version HTML de ce code s'obtient avec la commande suivante :

pygmentize -f html -l python -o code.html code.py

Où :

  • -f est le format de sortie souhaité (ici html)
  • -o est le nom du fichier de sortie
  • -l est le module utilisé pour parser le code, appelé lexer (ici python)

Le code HTML ainsi généré est le suivant :

<div class="highlight"><pre><span class="c1"># Fibonacci numbers</span>
<span class="k">def</span> <span class="nf">fib</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>    <span class="c1"># write Fibonacci series up to n</span>
    <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span>
    <span class="k">while</span> <span class="n">b</span> <span class="o">&lt;</span> <span class="n">n</span><span class="p">:</span>
        <span class="k">print</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="s1">&#39; &#39;</span><span class="p">)</span>
        <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="n">b</span><span class="p">,</span> <span class="n">a</span><span class="o">+</span><span class="n">b</span>
    <span class="k">print</span><span class="p">()</span>
</pre></div>

Pygments offres d'autres options pour améliorer le résultat, tel que l'ajout des numéros de ligne ou encore la génération d'un ficher HTML complet directement utilisable dans un navigateur.

Générer la feuille de style CSS : pygments.css

Le code HTML généré par Pygments n'inclu pas les informations de style CSS mais uniquement des balises <span> avec les classes nécessaires (ex: <span class="c1"># Fibonacci numbers</span>). Il nous faut par conséquent générer la feuille de styles CSS nécessaire au bon affichage, à inclure dans notre page web :

Pour générer cette feuille de style, utilisez la commande suivante :

pygmentize -f html -S colorful > pygments.css

Le fichier pygments.css contient alors (extrait) :

.hll { background-color: #ffffcc }
.c { color: #888888 } /* Comment */
.err { color: #FF0000; background-color: #FFAAAA } /* Error */
.k { color: #008800; font-weight: bold } /* Keyword */
.o { color: #333333 } /* Operator */
.ch { color: #888888 } /* Comment.Hashbang */
.cm { color: #888888 } /* Comment.Multiline */
.cp { color: #557799 } /* Comment.Preproc */
...

Intégrer et utiliser Pygments dans Plone

Écrire ses articles dans le format "text/restructured"

Pour pouvoir utiliser le format "text/restructured" dans l'éditeur WYSIWYG de Plone, il est nécessaire de l'activer dans la page de configuration "Configuration du site > Contenu > Formatage du texte": cochez "text/restructured".

Le format apparaît alors dans la liste de choix se situant juste en dessous de l'éditeur WYSIWYG.

Ajouter Pygments dans le buildout du projet

# buildout.cfg file

[buildout]
eggs =
    Plone
    Pillow
    Pygments
...

[versions]
Pygments = 2.0.2
...
bin/buildout

Saisir du code source en "text/restructured" dans un article

Exemple pour du code Python :

.. sourcecode:: python

    # Fibonacci numbers
    def fib(n):    # write Fibonacci series up to n
        a, b = 0, 1
        while b < n:
            print(b, end=' ')
            a, b = b, a+b
        print()

En savoir plus sur la directive sourcecode.

Le code HTML généré par Plone est le suivant :

<pre class="code python literal-block"><span class="comment"># Fibonacci numbers</span>
<span class="keyword">def</span> <span class="name function">fib</span><span class="punctuation">(</span><span class="name">n</span><span class="punctuation">):</span>       <span class="comment"># write Fibonacci series up to n</span>
    <span class="name">a</span><span class="punctuation">,</span> <span class="name">b</span> <span class="operator">=</span> <span class="literal number integer">0</span><span class="punctuation">,</span> <span class="literal number integer">1</span>
    <span class="keyword">while</span> <span class="name">b</span> <span class="operator">&lt;</span> <span class="name">n</span><span class="punctuation">:</span>
        <span class="keyword">print</span><span class="punctuation">(</span><span class="name">b</span><span class="punctuation">,</span> <span class="name">end</span><span class="operator">=</span><span class="literal string">' '</span><span class="punctuation">)</span>
        <span class="name">a</span><span class="punctuation">,</span> <span class="name">b</span> <span class="operator">=</span> <span class="name">b</span><span class="punctuation">,</span> <span class="name">a</span><span class="operator">+</span><span class="name">b</span>
    <span class="keyword">print</span><span class="punctuation">()</span>
</pre>

Générer la feuille de style CSS : pygments.css

Le code HTML généré par Pygments n'inclu pas les informations de style CSS mais uniquement des balises <span> avec les classes nécessaires (ex: <span class="c1"># Fibonacci numbers</span>). Il nous faut par conséquent générer la feuille de styles CSS nécessaire au bon affichage :

cd <zeocluster-directory>
bin/pygmentize -f html -S colorful -a pre.code > pygments.css

Cette commande va générer un fichier pygments.css utilisant le thème "colorful" pour le sélecteur "pre.code" afin de ne pas styler d'autres éléments de notre page.

Malheureusement l'intégration de cette feuille de style dans Plone ne suffira pas pour que la coloration soit effective sur notre code :(

En effet, le code HTML généré par Plone contient des noms de classe css longs, comme par exemple <span class="comment"># Fibonacci numbers</span> alors que la feuille de style fournit par Pygments permet de traiter des noms de classe css courts comme <span class="c1"># Fibonacci numbers</span>.

Un contributeur sur stackoverflow propose une solution à ce problème
en utilisant un script Python qui permet de générer une feuille de style Pygments contenant à la fois les noms de classe css courts et les noms de classe css long, solutionnant ainsi notre problème.

Intégrer pygments.css dans Plone

Pour finaliser le tout il ne reste plus qu'à intégrer la feuille de style Pygments dans Plone.

En ce qui me concerne je l'ai ajouté dans mon thème et je l'ai inclu dans mon fichier less principal avec la directive "(css)" qui permet d'inclure tel quel du code CSS dans un fichier less :

// Pygments
@import (css) "pygments.css";

Et voilà !

Le présent article utilise cette technique !

Add comment

Vous pouvez ajouter un commentaire en complétant le formulaire ci-dessous. Le format doit être plain text. Les commentaires sont modérés.

Question: Write nine cipher.
Votre réponse: