• Highlight : pour mettre du code source avec coloration syntaxique sur votre blog

     

     

    Lors de la création de ce blog, j'ai rencontré un problème dont la solution (plusieurs existent) - enfin - la solution idéale et facile à mettre en place n'a pas été si facile à dénicher. Dans ce blog, je voulais pouvoir facilement intégrer du code source, si possible avec un beau rendu. Je passerai ici les diverses tentatives infructueuses pour aller directement vous parler de highlight. Ce programme existe sous Linux, Mac et Windows, et est capable après avoir parsé votre code source de créer une page html avec le rendu de votre choix. Ce rendu est obtenu à partir de divers paramètres que vous aurez passé à highlight, comme la police d'écriture, le thème à appliquer, etc...

    Highlight est capable de reconnaitre plusieurs dizaines de langages et possède autant de modèles (thèmes) de coloration syntaxique. Ses différentes configurations sont stockées dans des fichiers séparés (situés dans /usr/share/highlight sous linux) pour chacun de ces langages et de ces styles. Pour le moment, je partage essentiellement des scripts Python sur ce blog, je me suis donc essentiellement attaché à créer une configuration qui me plaise pour ce langage.

    Après téléchargement et installation (page de téléchargement ici), j'ai donc modifié le fichier python.lang situé dans le répertoire /usr/share/highlight/langDefs/ (attention, vous devrez soit modifier les droits pour accéder en écriture à ce répertoire, soit y aller en root...). Cela m'a permis de paramétrer finement la police, le style (gras/italique) et les couleurs pour toutes les définitions de fonctions, définitions de classe, mots clé, méthodes, type de données, etc... Vous pouvez télécharger ce fichier ici.

    Pour les couleurs, je suis parti du fichier de base /usr/share/highlight/themes/molokai.theme que j'ai modifié légèrement pour obtenir le fichier /usr/share/highlight/themes/monokaisub.theme que vous pouvez télécharger ici.

     

    1 / Principe de fonctionnement :

    Pour arriver à produire un morceau de code HTML représentatif d'un code source directement intégrable dans le blog, au moins 2 étapes sont nécessaires :

    a/ Lancement de la commande "highlight" avec les paramètres qui vont bien dans un terminal afin de produire le fichier de base HTML représentatif du code source.

    b/ Affinement de ce fichier HTML de base afin de lui retirer toutes les balises qui risquent d'être gênantes pour l'intégration, et rajout de balises manquantes afin de faire tenir tout l'affichage du code source entre 2 balises <div> et </div>. Pour automatiser cette seconde partie, Python3 est mon meilleur ami :-)

     

    2 / Les étapes a/ et b/ en détail :

    Étape a/: voici un exemple type de l'utilisation de highlight en ligne de commande : 

    you@yourComputer: highlight -i pyFC.py -o pyFC_headless.html -Il --encoding=utf-8 --font-size=8 --font="Dejavu Sans Mono" --style=monokaisub

    L'option -i indique le fichier d'entrée (ici, pyFC.py), l'option -o indique le fichier de sortie (ici, pyFC_headless.html), les options suivantes parlent d'elles-même : encodage, taille de police, police choisie, puis choix du thème utilisé. Comme indiqué dans la section 1/ ci-dessus, on va exécuter cette commande "highlight" par l'intermédiaire d'un script python que j'ai nommé codeToHTML.py. Ce script pourra ensuite effectuer le post-traitement de l'étape b/, qui sont les opérations nécessaires à l'obtention du fichier final directement intégrable sur le blog.

    Étape b/: le "post-traitement" :

    Le fichier produit par highlight est un fichier html complet. Il contient donc le head, le body, tout le squelette normal utile à toute page html normalement constituée. Le soucis ici est que l'on a besoin d'intégrer notre code html représentatif de notre code source dans une page déjà existante, donc contenant déjà toutes les balises <head>, <body>, etc...

    Le script codeToHTML.py va donc retirer ces balises gênantes, et simplement ajouter 2 balises <div> et </div> en début et en fin de fichier, la 1ère balise <div> contenant quelques options que je vous laisse découvrir en explorant le script...

     

    3 / Utilisation du script :

    Le plus simplement du monde, placez-vous dans le répertoire du fichier du code source que vous voulez traiter, puis dans une console :

     you@yourComputer: /chemin/vers/codeToHTML.py monFichierSource.py

    Vous obtiendrez alors un nouveau fichier 'monFichierSource_headless.html. Il ny a plus qu'à copier/coller son contenu dans la page de votre blog, là où il doit s'afficher. Vous pouvez télécharger le script ici. C'est une archive zip qui contient un répertoire 'codeToHTML' qui lui-même contient le fichier codeToHTML.py. ... Enjoy :-)

     

    Script codeToHTML.py :

        1 #!/usr/bin/env python3
        2 # -*- coding: utf-8 -*-
        3 # Version 0.1 du 03/07/2019
        4 
        5 
        6 ####
        7 #    Ce script permet de créer un fichier html représentant un code source quelconque avec coloration syntaxique.
        8 #    Ce fichier html pourra être directement intégré dans votre blog afin d'y afficher le code source de votre
        9 #    choix.
       10 #
       11 #    NB : Ce script est prévu pour fonctionner sous Linux essentiellement (mais doit être adaptable assez
       12 #    facilement pour d'autres OS...)
       13 #
       14 #    Pré-requis : l'exécutable highlight (à télécharger sur http://www.andre-simon.de/zip/download.php)
       15 #    doit être installé. La documentation complète se trouve ici :
       16 #    http://www.andre-simon.de/doku/highlight/en/highlight.php
       17 #
       18 #
       19 #    Utilisation : python3 codeToHTML.py nom_Du_Fichier_A_Traiter
       20 #
       21 #    NB : Ce script a été testé sous python3.6.
       22 ####
       23 
       24 
       25 
       26 
       27 import os
       28 import sys
       29 import string
       30 
       31 
       32 def removeRNFromListe(listName):
       33     ''' Permet de supprimer les \r\n des fins de lignes avant ajout à la stringlist '''
       34     newList = []
       35     for oneLine in listName:
       36         if oneLine.endswith("\r\n"):
       37             oneLine = oneLine[0:(len(oneLine)-2)]
       38         if oneLine.endswith("\n"):
       39             oneLine = oneLine[0:(len(oneLine)-1)]
       40         if len(oneLine) > 0:
       41             newList.append(oneLine)
       42     return newList
       43 
       44 
       45 def readFileLines(filename):
       46     ''' Ouverture du fichier filename et stockage des lignes lues dans newList'''
       47     if os.path.exists(filename):
       48         myFile = open(filename, 'r')
       49         oneStringList = myFile.readlines()
       50         myFile.close()
       51         newList = removeRNFromListe(oneStringList)
       52         return newList
       53     else:
       54         return ("Le fichier "+filename+" n'existe pas!")
       55 
       56 
       57 def writeFile(filename, lines):
       58     ''' Ecriture des lignes 'lines' dans le fichier filename '''
       59     myFile = open(filename, 'w')
       60     for line in lines:
       61         oneStr = line + "\r\n"
       62         myFile.write(oneStr)
       63     myFile.close()
       64     return ("Écriture du fichier OK")
       65 
       66 
       67 
       68 
       69 ###################### Lancement du programme principal
       70 #
       71 if __name__ == "__main__":
       72 
       73     if os.path.isfile(sys.argv[1]):
       74         dirname = os.path.dirname(sys.argv[1])
       75         basename = os.path.basename(sys.argv[1])
       76         noextName = basename.split('.')[0]
       77         if len(basename.split('.'))==0:
       78             noextName = basename
       79         outFileName = dirname+'/'+noextName
       80         if len(dirname)==0:
       81             outFileName = noextName
       82         systemCommand = 'highlight -i '+sys.argv[1]+ ' -o ' +outFileName+ '_headless.html -Il --encoding=utf-8'+\
       83                         ' --font-size=8 --font="Dejavu Sans Mono" --style=monokaisub'
       84         os.system(systemCommand)  # On créé ici le fichier outFileName_headless.html
       85 
       86         myLinesList = readFileLines(outFileName+ '_headless.html')
       87         for _ in range(5):
       88             del myLinesList[0]  # On enlève les 5 1ères lignes du fichier html produit par highlight, ces lignes
       89                                 # correspondent à l'entête html (inutile car cette partie html doit s'intégrer
       90                                 # dans une page déjà existante)
       91         for _ in range(3):
       92             del myLinesList[-1]  # On enlève les 3 dernières lignes du fichier html produit par highlight
       93     
       94         nindex = len(myLinesList)-1
       95 
       96         # On va balayer toutes les lignes de la fin vers le début du fichier afin de retirer les lignes contenant
       98         while (nindex>-1):
      100                 del myLinesList[nindex]
      101             if 'body class="hl"' in myLinesList[nindex] or '</head>' in myLinesList[nindex]:
      102                 del myLinesList[nindex]
      103             if 'pre.hl	{' in myLinesList[nindex]:  # Permettra de basculer sur arial pour affichage du code source
      104                 myLinesList[nindex] = myLinesList[nindex].replace('\';}', '\', arial;}') # si la police déjavu sans 
      105             nindex -= 1                                                                  # mono est absente (windows)
      106         myLinesList.insert(0, '<div style="overflow:auto;height:600px;">')
      107         myLinesList.append('</div>')
      108         status = writeFile(outFileName+'_headless.html', myLinesList)
      109         print('Fichier '+outFileName+'_headless.html écrit')
      110         print()
      111 
      112 
    

    Tags Tags : , , , , , , ,
  • Commentaires

    Aucun commentaire pour le moment

    Suivre le flux RSS des commentaires


    Ajouter un commentaire

    Nom / Pseudo :

    E-mail (facultatif) :

    Site Web (facultatif) :

    Commentaire :