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>