Resalut les mecs,

Amélioration de ma fonction d'ajustement/reformattage d'un code python.

J'ai notamment ajouté:
* la prise en compte des chaînes string précédées de la lettre r;
* la prise en compte des opérateurs "|=", "|".
* la création de la fonction à associer au menu qui, applique le traitement soit au texte sélectionné, soit à tout le texte.

Attention les voici:

Début du code python

def adjustCode (s):
     # ajuste le code
    lstPt = []
    lstString = []
     # recencement des chaînes string
     # string avec triples quotes en appostrophes
    lstPt.append ("'{3,5}[\w\W]+?'{3,5}")
     # string avec triples quotes en guillemets
    lstPt.append ("\" {3, 5} [ \\w \\W] + ? \"{3,5}")
     # string avec appostrophes
    lstPt.append ("r'.*?'")
    lstPt.append (r"'.*?((?<!\\\\\\\\\\)|(?<!\\\\\\)|(?<!\\))'")
     # string avec guillemets
    lstPt.append ('r".*?"')
    lstPt.append (r'".*?((?<!\\\\\\\\\\)|(?<!\\\\\\)|(?<!\\))"')
     # commentaire uniligne
    lstPt.append ("\\#[^\\r\\n]*")
     # concaténation
    pt = "(" + "|".join (lstPt) + ")"
     # recherche
    lstString = re.finditer (pt, s)
     # remplacement des strings et commentaires par des génériques
    i = 0
    iStart = 0
    iEnd = 0
    s2 = s
    s = ""
    tag = "[___tag___yyd"
    for e in lstString:
        i = i + 1
        d, f = e.span (0)
        iEnd = d - 1
        s = s + s2 [iStart: iEnd + 1] + tag + str (i) + "]"
        iStart = f
     # end for
     # ajout de la dernière portion
    try: s = s + s2 [f:]
    except: pass
     # séparation des opérateurs des autres caractères par  des espaces
    pt = r"[ ]*(\+=|-=|\*=|/=|<=|>=|==|!=|\|=|=|\||\+|-|\*|/|!=|<|>|%)[ ]*"
    s = re.sub (pt, " \\1 ", s)
     # les englobeurs ouvrants doivent être
     # séparés des autres caractères par un espace à gauche
    pt = r"([\(\[\{]+)[ ]*"
    s = re.sub (pt, " \\1", s)
     # ceux desquels On doit retirer les espaces avant
    pt = r"([_]*[a-z][a-z_\d]*)[ ]+([\(\[\{]+)"
    s = re.sub (pt, "\\1\\2", s, re.I)
     # les englobeurs fermants
    pt = r"[ ]*([\)\]\}:]+)"
    s = re.sub (pt, "\\1", s)
     # ceux qui doivent avoir un espace avant, mais pas après
    pt = r"[ ]*([\\]+)[ ]*"
    s = re.sub (pt, " \\1", s)
     # ceux qui doivent avoir un espace après, mais pas avant
    pt = r"[ ]*([,]+)[ ]*"
    s = re.sub (pt, "\\1 ", s)
     # les espaces trop grands
    pt = r"[ ]{2,}"
    s = re.sub (pt, " ", s)
     # élimination des espaces et tabulations en fin de ligne
    pt = r"([^ \t]+)[ \t]+$"
    s = re.sub (pt, "\\1", s, re.M)
     # restauration des string à partir des génériques
    i = 0
    for e in lstString:
        i = i + 1
        s = s.replace (tag + str (i) + "]", e.group (0), 1)
     # end for
    return s
 # end def

def adjustCodeInCurPage ():
    # ajuste le code dans la page courante
    iLine = sp.window.curPage.curLine
    if sp.window.curPage.selectedText != "":
sp.window.curPage.selectedText = adjustCode(sp.window.curPage.selectedText)
    else:
     sp.window.curPage.text = adjustCode (sp.window.curPage.text)
    # end if
    sp.window.curPage.curLine = iLine
 # end def

Fin du code python

Amicalement,

Yannick Daniel Youalé
La programmation est une religion. Aimez-la, ou quittez-la.
www.visuweb.net




Le 23/03/2016 17:22, Yannick Youalé a écrit :
Salut les mecs,
Je viens de finir de polir une fonction sensée ajuster un code python qui lui serait passé en paramètre.
Par ajuster, je veux dire concrètement:
* séparer les opérateurs des autres caractères par un espace à gauche et à droite; * mettre un caractère d'espace à gauche avant les englobants ouvrants que sont les caractères "([{" et veiller à ce qu'il n'y en ait pas à droite; * éliminer les espaces à gauche des englobants fermants que sont les caractères ")]}"
* éliminer les espaces à gauches du caractère ":";
* éliminer les espaces superflux (c'est-à-dire plus de 2 espaces hormis les chaînes string ou commentaires) dans tout le code;
* éliminer les espaces et tabulation à la fin des lignes nonvides.
D'autres traitements peuvent encore être réalisés, mais ceux sus-cités rendent déjà le code plus homogène, plus synchrone et plus propre. Petite précision: cette fonction prend le soin d'écarter du code toutes les chaînes string et commentaires avant d'appliquer ces ajustement, pour finir par restaurer ces chaînes string et commentaires exactement aux endroits qu'ils occupaient. Je pense que cette fonctionnalité peut se proposer sous la forme d'un élément de menu pour permettre à l'utilisateur d'ajuster/formatter le code au moment voulu; ou être intégrée à la vérification automatique d'une ligne qui vient d'être modifiée afin de rapidement correctement formatter la dite ligne. Mais pour le moment, à la fin de cette fonction, au lieu de remplacer le texte, je me contente d'un print qui sert à apprécier la convertions dans la pseudo console de 6pad++. Je réfléchis actuellement sur l'étape supérieure vers son évolution qui est la re-écriture des mots clés. Essayez d'imaginer la possibilité que si vous avez déjà écrit un nom de variable plus haut dans le code, que vous n'ayez plus à vous soucier du respect de la cass lors de son écriture plus bas à cause du fait que le script ajuste automatiquement cette cass. Cependant, ce comportement sous-entendrait par exemple que les variables a (minuscule) et A (majuscule) ne seraient plus différenciées et que leur cass serait ajusté selon la première de leur écriture, d'où ma préoccupation d'aujourd'hui. Je trouve que ceci n'est pas anodin et va au dela d'une simple mise en forme du code. Peut-on véritablement coder en python comme on coderait en vb6 sans ce soucier de la cass ? Ce serait toute une autre philosophie de programmation et les conséquences pour les anciens codes risquent de ne pas être si négligeables que ça.
Souhaitez-vous que j'aille dans cette direction ?
Y trouvez-vous des inconvénients ? Des raisons de me dissuader de volontairement ainsi brider le python ?
Je vous colle quand même le code de la fonction que j'ai fais jusqu'ici.
Début du code python
def adjustCode(s):
 # ajuste le code
 lstPt = []
 lstString = []
 # recencement des chaînes string
 # string avec triples quotes en appostrophes
 lstPt.append ("'{3,5}[\w\W]+?'{3,5}")
 # string avec triples quotes en guillemets
 lstPt.append("\"{3,5}[\\w\\W]+?\"{3,5}")
 # string avec appostrophes
 lstPt.append (r"'.*?((?<!\\\\\\\\\\)|(?<!\\\\\\)|(?<!\\))'")
 # string avec guillemets
 lstPt.append (r'".*?((?<!\\\\\\\\\\)|(?<!\\\\\\)|(?<!\\))"')
 # commentaire uniligne
 lstPt.append ("\\#[^\\r\\n <file://%5C%5C#[%5E%5C%5Cr%5C%5Cn>]*")
 # concaténation
 pt = "("+"|".join(lstPt)+")"
 # recherche
 lstString = re.finditer(pt, s)
 # remplacement des strings et commentaires par des génériques
 i = 0
 iStart = 0
 iEnd = 0
 s2=s
 s = ""
 tag = "[___tag___yyd"
 for e in lstString:
  i=i+1
  d, f = e.span(0)
  iEnd = d-1
  s= s + s2[iStart: iEnd+1] + tag + str(i) + "]"
  iStart = f
 # end for
 # ajout de la dernière portion
 try: s = s + s2[f:]
 except: pass
 # séparation des opérateurs des autres caractères par  des espaces
 pt = r"[ ]*(\+=|-=|\*=|/=|<=|>=|==|!=|=|\+|-|\*|/|!=|<|>|%)[ ]*"
 s = re.sub(pt, " \\1 <file://%5C%5C1> ", s)
 # les englobeurs ouvrants doivent être
 # séparés des autres caractères par un espace à gauche
 pt = r"([\(\[\{]+)[ ]*"
 s = re.sub(pt, " \\1 <file://%5C%5C1>", s)
 # ceux desquels On doit retirer les espaces avant
 pt = r"([_]*[a-z][a-z_\d]*)[ ]+([\(\[\{]+)"
 s = re.sub(pt, "\\1\\2 <file://%5C%5C1%5C%5C2>", s, re.I)
 # les englobeurs fermants
 pt = r"[ ]*([\)\]\}:]+)"
 s = re.sub(pt, "\\1 <file://%5C%5C1>", s)
 # ceux qui doivent avoir un espace avant, mais pas après
 pt = r"[ ]*([\\]+)[ ]*"
 s = re.sub(pt, " \\1 <file://%5C%5C1>", s)
 # ceux qui doivent avoir un espace après, mais pas avant
 pt = r"[ ]*([,]+)[ ]*"
 s = re.sub(pt, "\\1 <file://%5C%5C1> ", s)
 # les espaces trop grands
 pt = r"[ ]{2,}"
 s = re.sub(pt, " ", s)
 # élimination des espaces et tabulations en fin de ligne
 pt = r"([^ \t]+)[ \t]+$"
 s = re.sub(pt, "\\1 <file://%5C%5C1>", s, re.M)
 # restauration des string à partir des génériques
 i = 0
 for e in lstString:
  i = i+1
  s = s.replace(tag+str(i)+"]", e.group(0), 1)
 # end for
 print(s)
# end def
Fin du code python
Yannick Daniel Youalé
La programmation est une religion. Aimez-la, ou quittez-la.
www.visuweb.net <http://www.visuweb.net>

Répondre à