5h12 du matin: je n’arrive pas à me rendormir… Je viens d’avoir une idée en tête et comme je ne suis pas procrastinateur, je me lève pour la concrétiser. L’idée du jour (enfin… de la nuit): comment extraire automatiquement la portion de code \(\LaTeX\) contenue entre deux balises \begin{python} et \end{python}, et enregistrer cette portion de code dans un fichier, le tout avec Python ?
À vrai dire, ce n’est pas très compliqué, et c’est valable pour n’importe quelle extension de fichier (ce n’est pas nécessairement un .tex) et n’importe quelle balise (cela peut être du HTML et extraire un code entre les balises <div> et </div> avec Python). Mais je vais prendre le cas que j’ai en tête.
J’écris actuellement des livres dans lesquels j’ai mis pas mal de code Python entre deux balises \begin{python} et \end{python}, et pour chacun d’eux, je les ai testé bien évidemment en les interprétant avec un IDE, mais je ne les ai pas enregistrés séparément dans des fichiers .py.
Avec du recul, j’aimerais quand-même créer ces fichiers afin de les proposer aux acheteurs des livres.
Parcourir le répertoire
Imaginons que mes fichiers \(\LaTeX\) soient dans le répertoire courant de mon fichier Python.
from os import listdir fics = listdir('.')
crée une liste contenant tous les fichiers du répertoire courant. Je vais donc parcourir cette liste et ne choisir que les fichiers qui se terminent par “.tex” avec la méthode endswith(‘.tex’).
Parcourir les fichiers
Pour ce qui est de la manipulation de fichiers, vous pouvez consulter cette page.
Je vais donc parcourir ligne par ligne tous les fichiers rencontrés avec la logique suivante:
- si je rencontre “\begin{python}” alors je commence à enregistrer le contenu du fichier;
- si je rencontre “\end{python}” alors j’arrête l’enregistrement et je mets tout dans un fichier Python.
Je vais me servir d’un booléen pour savoir si je dois enregistrer la ligne rencontrée, et d’une chaîne de caractère nommée container pour stocker les lignes à retenir. Je vais aussi créer un compteur pour nommer les fichiers Python. Et cela donne :
counter = 0 for file in listdir('.'): if file.endswith('.tex'): container = '' start = False with open(file, 'r' , encoding = 'utf8') as Fichier: for ligne in Fichier: if '\\end{python}' in ligne: start = False counter += 1 record_file(counter,container) container = '' elif start == True: container += ligne elif '\\begin{python}' in ligne: start = True
Il ne me reste plus qu’à définir ma fonction record_file.
Enregistrer les fichiers Python
def record_file(c , text): makedirs('Python', exist_ok = True) name = 'Python/' + str(c) + '.py' file_python = open(name, 'w' , encoding='utf8') file_python.write( text ) file_python.close()
Ici, rien de bien méchant: je commence par créer un répertoire “Python” dans lequel je souhaite enregistrer tous mes fichiers Python. Notez la présence du paramètre “exist_ok = True” dans la fonction makedirs du module os, qui signifie que si le répertoire existe déjà, aucune erreur ne doit être retournée.
Et au final… extraire du code entre deux balises avec Python
from os import listdir, makedirs def record_file(c , text): makedirs('Python', exist_ok = True) name = 'Python/' + str(c) + '.py' file_python = open(name , 'w' , encoding = 'utf8') file_python.write( text ) file_python.close() counter = 0 for file in listdir('.'): if file.endswith('.tex'): container = '' start = False with open(file, 'r' , encoding = 'utf8') as Fichier: for ligne in Fichier: if '\\end{python}' in ligne: start = False counter += 1 record_file(counter,container) container = '' elif start == True: container += ligne elif '\\begin{python}' in ligne: start = True