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 from __future__ import absolute_import
26 from __future__ import print_function
28 from builtins import object
31 from Extensions.i18n import tr
32 filePattern="'[^\(\)]([^\(\)]*\([^\(\)]*\))*[^\(\)]*'"
33 filePattern2='"[^\(\)]([^\(\)]*\([^\(\)]*\))*[^\(\)]*"'
35 class Formatage (object):
37 Cette classe contient toutes les méthodes nécessaires au formatage
38 de la chaine de caracteres issue d'un generator en un fichier
39 'lisible' ie avec indentations
41 L'objet attend en parametre du constructeur (argument l_jdc) une representation
42 du jeu de commandes sous la forme d'une liste.
44 Chaque element de la liste est la representation d'une etape.
46 La representation d'une etape est une liste dont le premier element est une chaine de
47 caracteres donnant le debut de la commande ("xxx=lire_maillage(", par exemple).
48 Les elements suivants sont les representations des mots cles simples et facteurs.
49 Elle se termine avec un element de fin : ");"
51 La representation d'un mot cle simple est une chaine de caracteres (info=2, par exemple).
53 La representation d'un mot cle facteur est semblable à celle de l'étape : premier element
54 caracteristique du mot cle facteur suivi d'elements representatifs des mots cles simples.
55 Elle se termine avec un element de fin : ")" ou "),".
57 def __init__(self,l_jdc,code=None,mode=None,sep='=',l_max=72):
58 # l_jdc représente le jeu de commandes brut sous forme de liste
71 def formate_jdc(self):
72 comment=re.compile("\n#")
74 for etape in self.l_jdc:
75 self.count = self.count+1
77 #if type(etape)==types.ListType:
79 # L'etape est sous la forme d'une liste dont le premier element est une chaine
81 self.indent.append(len(etape[0]))
82 self.indent_courant = self.indent[0]
83 self.texte_etape = '\n' + etape[0]
85 self.formate_etape(etape[1:])
87 # L'etape est deja sous forme de chaine de caracteres
89 self.texte_etape = etape
91 m=comment.match(self.texte_etape)
92 # si ce n est pas la premiere ligne
93 if self.jdc_fini != "" :
94 # si il n y avait pas de commentaire avant on met un saut de ligne
95 if commentaireavant == 0 :
96 self.jdc_fini = self.jdc_fini + '\n' + self.texte_etape
98 self.jdc_fini = self.jdc_fini + self.texte_etape
99 # si c est la premiere ligne
101 # on ne met pas de saut de ligne avant la premiere ligne
102 # si c est un commentaire on enleve le saut de ligne precedent
103 if m : self.texte_etape=self.texte_etape[1:]
104 self.jdc_fini = self.texte_etape
114 def formate_etape(self,liste):
116 Enrichissement de la chaine de caracteres representant l'etape (attribut
117 texte_etape de l'objet Formatage).
118 Les elements a ajouter sont dans l'argument liste de la methode.
119 L'objet "liste" à traiter a été produit par le module generator. En particulier
120 les parenthèses et les virgules ont été produites par ce module
122 l_patterns_fin_etape = ( ');' , ');\n' )
123 l_patterns_fin_mcf = ( ')' , '),' )
126 for element in liste :
127 if type(element) == types.ListType:
129 # il s'agit d'un mot-clé facteur
130 # on écrit son nom (element[0])
131 longueur = self.longueur(self.texte_etape)
133 increment = len(('\n'+self.indent_courant*' ')*ind + element[0])
138 self.texte_etape = self.texte_etape + (u'\n'+self.indent_courant*' ')*ind + element[0]
139 length = len(self.indent)
140 self.indent.insert(length,self.indent[length-1]+len(element[0]))
141 self.indent_courant = self.indent[length]
143 self.formate_etape(element[1:])
144 #elif type(element) == types.StringType:
145 elif type(element) == bytes:
147 # il s'agit d'un mot-clé simple ou de ')' ou ');' ou '),' ou ');\n'
149 if element in l_patterns_fin_mcf :
150 self.traite_mcfact(s_mcfact=element,ind=ind)
151 elif element in l_patterns_fin_etape :
152 self.traite_etape(s_etape=element,ind=ind)
154 self.traite_mcsimp(s_mcsimp=element,ind=ind)
158 def traite_etape(self,s_etape,ind) :
160 Traite une partie du jdc formaté : s_etape, une chaîne de caractères
162 L'attribut self.texte_etape est modifié (complété) par le traitement
163 L'attribut self.indent est modifié par le traitement
164 L'attribut self.indent_courant est modifié par le traitement
166 length = len(self.indent)
168 last = self.indent[length-1]
169 self.indent.remove(last)
170 self.indent_courant=self.indent[length-2]
172 self.indent_courant=self.indent[0]
173 self.texte_etape = self.texte_etape + s_etape.strip()
175 def traite_mcfact(self,s_mcfact,ind) :
177 Traite une partie du jdc formaté : s_mcfact, une chaîne de caractères
178 contenant un mot-clef facteur.
179 L'attribut self.texte_etape est modifié (complété) par le traitement
180 L'attribut self.indent est modifié par le traitement
181 L'attribut self.indent_courant est modifié par le traitement
183 self.texte_etape = self.texte_etape + s_mcfact.strip()
184 length = len(self.indent)
186 last = self.indent[length-1]
187 self.indent.remove(last)
188 self.indent_courant=self.indent[length-2]
190 self.indent_courant=self.indent[0]
194 def traite_mcsimp(self,s_mcsimp,ind) :
196 Traite une partie du jdc formaté : s_mcsimp, une chaîne de caractères
197 contenant un mot-clef simple.
198 L'attribut self.texte_etape est modifié (complété) par le traitement
201 # Ajout PN pour defi_fonction
202 if self.texte_etape.find("DEFI_FONCTION") > 1 :
204 if s_mcsimp.find("\n") > 1:
205 txt=""; bool = 0; numident=1
206 for l in s_mcsimp.splitlines() :
209 numident=s_mcsimp.find("=")+2
212 txt=txt+('\n'+self.indent_courant*' '+numident*' ')*ind+l
216 longueur = self.longueur(self.texte_etape)
217 increment = len((u'\n'+self.indent_courant*' ')*ind + s_mcsimp.strip())
218 if (bool_fonction == 1 ) :
219 self.texte_etape = self.texte_etape+'\n'+self.indent_courant*' ' +s_mcsimp
220 elif ( ((1-ind)*longueur+increment) <= self.l_max ) :
221 self.texte_etape = self.texte_etape + ('\n'+self.indent_courant*' ')*ind +s_mcsimp.strip()
224 #nom,valeur = string.split(s_mcsimp,self.sep,1)
225 nom,valeur = str.split(s_mcsimp,self.sep,1)
226 chaine = self.creer_chaine(nom,valeur,'\n'+self.indent_courant*' ',ind)
227 #self.jdc_fini = self.jdc_fini + ('\n'+self.indent_courant*' ')*ind + s_mcsimp.strip()
228 self.texte_etape = self.texte_etape + chaine
232 def longueur(self,texte):
234 texte est une string qui peut contenir des retours chariots
235 Cette méthode retourne la longueur de la dernière ligne de texte
237 #liste = texte.split('\n')
238 #return len(liste[-1])
239 if texte [-1] == '\n' : return 0
240 return len(texte[texte.rfind('\n'):-1])
243 def creer_chaine(self,nom,valeur,increment,ind):
245 La methode creer_chaine reconstitue un objet Eficas à partir de
250 if len(increment + nom + self.sep) <= self.l_max:
251 texte = increment*ind
252 label = nom + self.sep
254 longueur = len(increment + label)
256 if ('(' not in valeur) or (valeur[0:3]=='"""') :
257 # il s'agit d'une vraie chaîne de caractères
259 texte = (self.l_max-2-val)*' '+valeur
261 elif re.match(filePattern,valeur) or re.match(filePattern2,valeur):
263 texte = (self.l_max-2-val)*' '+valeur
266 # il s'agit d'une liste de tuple
267 # c est trop complique on ne splitte pas
268 if valeur[0:2]=='((' or valeur[0:2]=='[(':
271 # il s'agit d'une liste
272 liste = valeur.split(',')
276 if len(ajout) == 0 : continue
277 longueur = self.longueur(texte = (texte + label)) + len(ajout +',') + (1-i)*len(increment)
278 if longueur <= self.l_max:
280 texte = texte + ajout +','
282 texte = texte + ajout
286 texte = texte + increment + (len(label)+2)*' ' + ajout + ','
288 texte = texte + increment + (len(label)+2)*' ' + ajout
294 # On a une ( mais pas de , . On passe la chaine sans modification
296 texte = (self.l_max-2-val)*' '+valeur
301 class FormatageLigne(Formatage) :
302 def __init__(self,l_jdc,code=None,mode=None,sep='=',l_max="**"):
303 Formatage.__init__(self,l_jdc,code=None,mode=None,sep='=',l_max="**")
305 def formate_jdc(self):
306 texte1=Formatage.formate_jdc(self)
308 lignes=texte1.split("\n")
310 pattern_debut_blanc = re.compile(r"^ \s*.*")
311 pattern_commentaire = re.compile(r"^\s*#.*")
312 pattern_vide=re.compile(r"\s*^$")
314 if pattern_commentaire.match(l) or pattern_vide.match(l):
317 if not pattern_debut_blanc.match(l) : texte=l
318 else : texte+=re.sub(r'^ \s*',' ',l)