1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2007-2013 EDF R&D
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License.
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # Lesser General Public License for more details.
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 Ce module contient la classe Formatage qui permet le formatage d'une
22 liste de chaines de caractères dans une syntaxe représentative d'un
23 jeu de commandes en un texte présentable
25 import types,string,re
26 from Extensions.i18n import tr
27 filePattern="'[^\(\)]([^\(\)]*\([^\(\)]*\))*[^\(\)]*'"
28 filePattern2='"[^\(\)]([^\(\)]*\([^\(\)]*\))*[^\(\)]*"'
32 Cette classe contient toutes les méthodes nécessaires au formatage
33 de la chaine de caracteres issue d'un generator en un fichier
34 'lisible' ie avec indentations
36 L'objet attend en parametre du constructeur (argument l_jdc) une representation
37 du jeu de commandes sous la forme d'une liste.
39 Chaque element de la liste est la representation d'une etape.
41 La representation d'une etape est une liste dont le premier element est une chaine de
42 caracteres donnant le debut de la commande ("xxx=lire_maillage(", par exemple).
43 Les elements suivants sont les representations des mots cles simples et facteurs.
44 Elle se termine avec un element de fin : ");"
46 La representation d'un mot cle simple est une chaine de caracteres (info=2, par exemple).
48 La representation d'un mot cle facteur est semblable à celle de l'étape : premier element
49 caracteristique du mot cle facteur suivi d'elements representatifs des mots cles simples.
50 Elle se termine avec un element de fin : ")" ou "),".
52 def __init__(self,l_jdc,code=None,mode=None,sep='=',l_max=72):
53 # l_jdc représente le jeu de commandes brut sous forme de liste
66 def formate_jdc(self):
67 comment=re.compile("\n#")
69 for etape in self.l_jdc:
70 self.count = self.count+1
72 if type(etape)==types.ListType:
73 # L'etape est sous la forme d'une liste dont le premier element est une chaine
75 self.indent.append(len(etape[0]))
76 self.indent_courant = self.indent[0]
77 self.texte_etape = '\n' + etape[0]
79 self.formate_etape(etape[1:])
81 # L'etape est deja sous forme de chaine de caracteres
83 self.texte_etape = etape
85 m=comment.match(self.texte_etape)
86 # si ce n est pas la premiere ligne
87 if self.jdc_fini != "" :
88 # si il n y avait pas de commentaire avant on met un saut de ligne
89 if commentaireavant == 0 :
90 self.jdc_fini = self.jdc_fini + '\n' + self.texte_etape
92 self.jdc_fini = self.jdc_fini + self.texte_etape
93 # si c est la premiere ligne
95 # on ne met pas de saut de ligne avant la premiere ligne
96 # si c est un commentaire on enleve le saut de ligne precedent
97 if m : self.texte_etape=self.texte_etape[1:]
98 self.jdc_fini = self.texte_etape
108 def formate_etape(self,liste):
110 Enrichissement de la chaine de caracteres representant l'etape (attribut
111 texte_etape de l'objet Formatage).
112 Les elements a ajouter sont dans l'argument liste de la methode.
113 L'objet "liste" à traiter a été produit par le module generator. En particulier
114 les parenthèses et les virgules ont été produites par ce module
116 l_patterns_fin_etape = ( ');' , ');\n' )
117 l_patterns_fin_mcf = ( ')' , '),' )
120 for element in liste :
121 if type(element) == types.ListType:
123 # il s'agit d'un mot-clé facteur
124 # on écrit son nom (element[0])
125 longueur = self.longueur(self.texte_etape)
127 increment = len(('\n'+self.indent_courant*' ')*ind + element[0])
132 self.texte_etape = self.texte_etape + (u'\n'+self.indent_courant*' ')*ind + element[0]
133 length = len(self.indent)
134 self.indent.insert(length,self.indent[length-1]+len(element[0]))
135 self.indent_courant = self.indent[length]
137 self.formate_etape(element[1:])
138 elif type(element) == types.StringType:
140 # il s'agit d'un mot-clé simple ou de ')' ou ');' ou '),' ou ');\n'
142 if element in l_patterns_fin_mcf :
143 self.traite_mcfact(s_mcfact=element,ind=ind)
144 elif element in l_patterns_fin_etape :
145 self.traite_etape(s_etape=element,ind=ind)
147 self.traite_mcsimp(s_mcsimp=element,ind=ind)
151 def traite_etape(self,s_etape,ind) :
153 Traite une partie du jdc formaté : s_etape, une chaîne de caractères
155 L'attribut self.texte_etape est modifié (complété) par le traitement
156 L'attribut self.indent est modifié par le traitement
157 L'attribut self.indent_courant est modifié par le traitement
159 length = len(self.indent)
161 last = self.indent[length-1]
162 self.indent.remove(last)
163 self.indent_courant=self.indent[length-2]
165 self.indent_courant=self.indent[0]
166 self.texte_etape = self.texte_etape + string.strip(s_etape)
168 def traite_mcfact(self,s_mcfact,ind) :
170 Traite une partie du jdc formaté : s_mcfact, une chaîne de caractères
171 contenant un mot-clef facteur.
172 L'attribut self.texte_etape est modifié (complété) par le traitement
173 L'attribut self.indent est modifié par le traitement
174 L'attribut self.indent_courant est modifié par le traitement
176 self.texte_etape = self.texte_etape + string.strip(s_mcfact)
177 length = len(self.indent)
179 last = self.indent[length-1]
180 self.indent.remove(last)
181 self.indent_courant=self.indent[length-2]
183 self.indent_courant=self.indent[0]
187 def traite_mcsimp(self,s_mcsimp,ind) :
189 Traite une partie du jdc formaté : s_mcsimp, une chaîne de caractères
190 contenant un mot-clef simple.
191 L'attribut self.texte_etape est modifié (complété) par le traitement
194 # Ajout PN pour defi_fonction
195 if self.texte_etape.find("DEFI_FONCTION") > 1 :
197 if s_mcsimp.find("\n") > 1:
198 txt=""; bool = 0; numident=1
199 for l in s_mcsimp.splitlines() :
202 numident=s_mcsimp.find("=")+2
205 txt=txt+('\n'+self.indent_courant*' '+numident*' ')*ind+l
209 longueur = self.longueur(self.texte_etape)
210 increment = len((u'\n'+self.indent_courant*' ')*ind + string.strip(s_mcsimp))
211 if (bool_fonction == 1 ) :
212 self.texte_etape = self.texte_etape+'\n'+self.indent_courant*' ' +s_mcsimp
213 elif ( ((1-ind)*longueur+increment) <= self.l_max ) :
214 self.texte_etape = self.texte_etape + ('\n'+self.indent_courant*' ')*ind + string.strip(s_mcsimp)
217 nom,valeur = string.split(s_mcsimp,self.sep,1)
218 chaine = self.creer_chaine(nom,valeur,'\n'+self.indent_courant*' ',ind)
219 #self.jdc_fini = self.jdc_fini + ('\n'+self.indent_courant*' ')*ind + string.strip(s_mcsimp)
220 self.texte_etape = self.texte_etape + chaine
224 def longueur(self,texte):
226 texte est une string qui peut contenir des retours chariots
227 Cette méthode retourne la longueur de la dernière ligne de texte
229 liste = string.split(texte,'\n')
230 return len(liste[-1])
232 def creer_chaine(self,nom,valeur,increment,ind):
234 La methode creer_chaine reconstitue un objet Eficas à partir de
239 if len(increment + nom + self.sep) <= self.l_max:
240 texte = increment*ind
241 label = nom + self.sep
243 longueur = len(increment + label)
245 if ('(' not in valeur) or (valeur[0:3]=='"""') :
246 # il s'agit d'une vraie chaîne de caractères
248 texte = (self.l_max-2-val)*' '+valeur
250 elif re.match(filePattern,valeur) or re.match(filePattern2,valeur):
252 texte = (self.l_max-2-val)*' '+valeur
255 # il s'agit d'une liste de tuple
256 # c est trop complique on ne splitte pas
257 if valeur[0:2]=='((' or valeur[0:2]=='[(':
260 # il s'agit d'une liste
261 liste = string.split(valeur,',')
264 ajout = string.strip(arg)
265 if len(ajout) == 0 : continue
266 longueur = self.longueur(texte = (texte + label)) + len(ajout +',') + (1-i)*len(increment)
267 if longueur <= self.l_max:
269 texte = texte + ajout +','
271 texte = texte + ajout
275 texte = texte + increment + (len(label)+2)*' ' + ajout + ','
277 texte = texte + increment + (len(label)+2)*' ' + ajout
283 # On a une ( mais pas de , . On passe la chaine sans modification
285 texte = (self.l_max-2-val)*' '+valeur
290 class FormatageLigne(Formatage) :
291 def __init__(self,l_jdc,code=None,mode=None,sep='=',l_max="**"):
292 Formatage.__init__(self,l_jdc,code=None,mode=None,sep='=',l_max="**")
294 def formate_jdc(self):
295 texte1=Formatage.formate_jdc(self)
297 lignes=texte1.split("\n")
299 pattern_debut_blanc = re.compile(r"^ \s*.*")
300 pattern_commentaire = re.compile(r"^\s*#.*")
301 pattern_vide=re.compile(r"\s*^$")
303 if pattern_commentaire.match(l) or pattern_vide.match(l):
306 if not pattern_debut_blanc.match(l) : texte=l
307 else : texte+=re.sub(r'^ \s*',' ',l)