-
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 : code source, blog, python, highlight, coloration, syntaxique, programmation, linux
-
Commentaires