Convertisseur fichier caml -> fichier html

Contenu du snippet

Je débute en python et il s'agit là de mon premier programme complet. Toute remarque constructive tant sur les malfonctionnements du programme que sur ma façon de programmer en python est la bienvenue.

Le programme 1 : ml2html.py prend en argument une liste des noms de fichiers Caml Light / Objective Caml (extension .ml) et génère une page html contenant le code des programmes donnés en arguments en conservant l'indentation et en ajoutant une coloration syntaxique rudimentaire (facilement modifiable) nommée ml2html_resultat.html.

Le programme 2 : ml2html-tk.py est une interface graphique à ml2html utilisant Tkinter qui donne deux arguments optionnels supplémentaires : le nom du fichier à générer et le répertoire des fichiers à convertir, les valeurs par défaut étant ml2html_resultat.html et le répertoire courant.

Note : testé uniquement sous Linux.

Source / Exemple :


#Programme 1 : ml2html.py

#! /usr/bin/python
# -*- coding:Utf-8 -*-

##############################################################
#                                                             
# ml2html : convertit les fichiers donnés en arguments en un  
#           fichier html conservant l'indentation et ajoutant 
#           la coloration syntaxique des mots_clé.            
#                                                             
##############################################################

import sys

mots_cle0=["let","and","in","for","do","done","while","if","then","else"]
mots_cle1=["load","include","begin","end","match","with","try","fun","function","rec","ref"]

#fonte à invoquer pour mots_cle0
font_0="<FONT COLOR='BLUE'>"
#fonte à invoquer pour mots_cle0
font_1="<FONT COLOR='RED'>"
#fonte à invoquer pour les commentaires
font_comment="<FONT COLOR='GREEN'>"
#fonte à invoquer pour les chaînes de commentaire
font_string="<FONT COLOR='#FF00FF'>"
#fin de fonte
font_end="</FONT>"

class Statut:
    """Classe chargée de gérer le type de texte lu (commentaires ou code ou chaine de caractères)"""
    def __init__(self,comment=False,string=False):
        self.comment=comment
        self.string=string
    def __repr__(self):
        "Comment : %d\nString : %d" %(self.comment,self.string)

def parse(texte):
    """Prend en argument une chaîne de caractères correspondant à un programme CAML et renvoie du code HTML conservant l'indentation et avec coloration syntaxique"""
    #mot en cours
    m=''
    #chaine rendue par ml2html
    t=''
    #statut
    s=Statut()

    #concatène le mot lu à la chaine t avec la coloration syntaxique
    def vide_mot(m):
        if not s.string and not s.comment:
            if m in mots_cle0:
                return '%s%s%s' %(font_0,m,font_end)
            elif m in mots_cle1:
                return '%s%s%s' %(font_1,m,font_end)
            else:
                return m
        else:
            return m

    #parcourt le texte à la recherche des caractères de changement de statut
    for i in range(len(texte)):
        c=texte[i]

        if c =='\"' and not texte[i-1]=='\\':
            if s.string:
                #fin de la chaîne de caractères
                t+=vide_mot(m)+c+font_end
                m=''
                s.string=False
            elif not s.comment:
                #début de la chaîne de caractères
                t+=vide_mot(m)+font_string+c
                m=''
                s.string=True
            else:
                #c'est un commentaire : '\"' est un caractère comme les autres
                t+=vide_mot(m)+c
                m=''

        elif c=='(':
            if texte[i+1]=='*':
                if not s.string:
                    #début de commentaire
                    t+=vide_mot(m)+font_comment+c
                    s.comment=True
                    mot=''
                else:
                    #on est dans une chaîne de caractères
                    t+=vide_mot(m)+c
                    m=''
            else:
                t+=vide_mot(m)+c
                m=''

        elif c==')' and texte[i-1]=='*':
            if s.comment and not s.string:
                #fin d'une chaîne de caractères
                t+=vide_mot(m)+c+font_end
                m=''
                s.comment=False
            else:
                t+=vide_mot(m)+c
                m=''
        elif c in [' ','\n','=']:
            #le mot se termine
            t+=vide_mot(m)+c
            m=''
        else:
            #on incrémente le mot m
            m+=c
    t+=vide_mot(m)
    mot=''
    return t

if __name__ == "__main__":
    resultat=open("ml2html_resultat.html",'w')
    resultat.write("<HTML><BODY><PRE>\n\n")
    for fichier in sys.argv[1:]:
        resultat.write("%s \n\n" %(parse(file(fichier).read())))
    resultat.write("</PRE></BODY></HTML>")
    resultat.close()

#fin

#Programme 2 : ml2html-tk.py

#! /usr/bin/python
# -*- coding:Utf-8 -*-

##############################################################
#                                                            
# ml2html-tk : interface graphique pour le programme ml2html 
#                                                            
##############################################################

import os
from ml2html import *
from Tkinter import *

def popup(texte=''):
    #envoie un popup
    pop=Tk()
    txt=Label(pop,text=texte)
    txt.pack()
    pop.mainloop()

def convertir():
    #répertoire courant
    cur_dir=os.getcwd()

    # 'répertoire' est une entrée facultative,
    # évaluée au répertoire courant si elle n'est pas donnée
    if ent0.get()=='':
        e0=cur_dir
    else:
        e0=ent0.get()
        
    e1=ent1.get()

    # 'fichier à générer' est une entrée facultative,
    # évaluée à "ml2html.ml" si elle n'est pas donnée
    if ent2.get()=='':
        e2='ml2html_resultat.html'
    else:
        e2=ent2.get()
        
    if e1=='':
        # Aucun fichier à convertir
        popup("Donner un argument svp.")
    else:
        resultat=open(e2,'w')
        resultat.write("<HTML><BODY><PRE>\n\n")
        for fichier in e1.split():
            resultat.write("%s \n\n" %(parse(file(os.path.join(e0,fichier)).read())))
        resultat.write("</PRE></BODY></HTML>")
        resultat.close()
        popup("### Fini! ###\n%s généré dans %s." %(e2,cur_dir))

# mise en place de l'interface graphique
fen=Tk()
fen.title('ml2html: ml -> html')

txt0=Label(fen,text='répertoire')
txt1=Label(fen,text='fichier(s) à convertir')
txt2=Label(fen,text='fichier à générer')

ent0=Entry(fen)
ent1=Entry(fen)
ent2=Entry(fen)

bouton1=Button(fen,text='Convertir',command=convertir)
bouton2=Button(fen,text='Quitter',command=fen.quit)

txt0.grid()
txt1.grid(row=1)
txt2.grid(row=2)
ent0.grid(row=0,column=1)
ent1.grid(row=1,column=1)
ent2.grid(row=2,column=1)
bouton1.grid(row=3)
bouton2.grid(row=3,column=1)

fen.mainloop()

# fin

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.