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
30 Cette classe contient toutes les méthodes nécessaires au formatage
31 de la chaine de caracteres issue d'un generator en un fichier
32 'lisible' ie avec indentations
34 L'objet attend en parametre du constructeur (argument l_jdc) une representation
35 du jeu de commandes sous la forme d'une liste.
37 Chaque element de la liste est la representation d'une etape.
39 La representation d'une etape est une liste dont le premier element est une chaine de
40 caracteres donnant le debut de la commande ("xxx=lire_maillage(", par exemple).
41 Les elements suivants sont les representations des mots cles simples et facteurs.
42 Elle se termine avec un element de fin : ");"
44 La representation d'un mot cle simple est une chaine de caracteres (info=2, par exemple).
46 La representation d'un mot cle facteur est semblable à celle de l'étape : premier element
47 caracteristique du mot cle facteur suivi d'elements representatifs des mots cles simples.
48 Elle se termine avec un element de fin : ")" ou "),".
50 def __init__(self,l_jdc,code=None,mode=None,sep='=',l_max=72):
51 # l_jdc représente le jeu de commandes brut sous forme de liste
64 def formate_jdc(self):
65 comment=re.compile("\n#")
67 for etape in self.l_jdc:
68 self.count = self.count+1
70 if type(etape)==types.ListType:
71 # L'etape est sous la forme d'une liste dont le premier element est une chaine
73 self.indent.append(len(etape[0]))
74 self.indent_courant = self.indent[0]
75 self.texte_etape = '\n' + etape[0]
77 self.formate_etape(etape[1:])
79 # L'etape est deja sous forme de chaine de caracteres
81 self.texte_etape = etape
83 m=comment.match(self.texte_etape)
84 # si ce n est pas la premiere ligne
85 if self.jdc_fini != "" :
86 # si il n y avait pas de commentaire avant on met un saut de ligne
87 if commentaireavant == 0 :
88 self.jdc_fini = self.jdc_fini + '\n' + self.texte_etape
90 self.jdc_fini = self.jdc_fini + self.texte_etape
91 # si c est la premiere ligne
93 # on ne met pas de saut de ligne avant la premiere ligne
94 # si c est un commentaire on enleve le saut de ligne precedent
95 if m : self.texte_etape=self.texte_etape[1:]
96 self.jdc_fini = self.texte_etape
106 def formate_etape(self,liste):
108 Enrichissement de la chaine de caracteres representant l'etape (attribut
109 texte_etape de l'objet Formatage).
110 Les elements a ajouter sont dans l'argument liste de la methode.
111 L'objet "liste" à traiter a été produit par le module generator. En particulier
112 les parenthèses et les virgules ont été produites par ce module
114 l_patterns_fin_etape = ( ');' , ');\n' )
115 l_patterns_fin_mcf = ( ')' , '),' )
118 for element in liste :
119 if type(element) == types.ListType:
121 # il s'agit d'un mot-clé facteur
122 # on écrit son nom (element[0])
123 longueur = self.longueur(self.texte_etape)
125 increment = len(('\n'+self.indent_courant*' ')*ind + element[0])
130 self.texte_etape = self.texte_etape + (u'\n'+self.indent_courant*' ')*ind + element[0]
131 length = len(self.indent)
132 self.indent.insert(length,self.indent[length-1]+len(element[0]))
133 self.indent_courant = self.indent[length]
135 self.formate_etape(element[1:])
136 elif type(element) == types.StringType:
138 # il s'agit d'un mot-clé simple ou de ')' ou ');' ou '),' ou ');\n'
140 if element in l_patterns_fin_mcf :
141 self.traite_mcfact(s_mcfact=element,ind=ind)
142 elif element in l_patterns_fin_etape :
143 self.traite_etape(s_etape=element,ind=ind)
145 self.traite_mcsimp(s_mcsimp=element,ind=ind)
149 def traite_etape(self,s_etape,ind) :
151 Traite une partie du jdc formaté : s_etape, une chaîne de caractères
153 L'attribut self.texte_etape est modifié (complété) par le traitement
154 L'attribut self.indent est modifié par le traitement
155 L'attribut self.indent_courant est modifié par le traitement
157 length = len(self.indent)
159 last = self.indent[length-1]
160 self.indent.remove(last)
161 self.indent_courant=self.indent[length-2]
163 self.indent_courant=self.indent[0]
164 self.texte_etape = self.texte_etape + string.strip(s_etape)
166 def traite_mcfact(self,s_mcfact,ind) :
168 Traite une partie du jdc formaté : s_mcfact, une chaîne de caractères
169 contenant un mot-clef facteur.
170 L'attribut self.texte_etape est modifié (complété) par le traitement
171 L'attribut self.indent est modifié par le traitement
172 L'attribut self.indent_courant est modifié par le traitement
174 self.texte_etape = self.texte_etape + string.strip(s_mcfact)
175 length = len(self.indent)
177 last = self.indent[length-1]
178 self.indent.remove(last)
179 self.indent_courant=self.indent[length-2]
181 self.indent_courant=self.indent[0]
185 def traite_mcsimp(self,s_mcsimp,ind) :
187 Traite une partie du jdc formaté : s_mcsimp, une chaîne de caractères
188 contenant un mot-clef simple.
189 L'attribut self.texte_etape est modifié (complété) par le traitement
192 # Ajout PN pour defi_fonction
193 if self.texte_etape.find("DEFI_FONCTION") > 1 :
195 if s_mcsimp.find("\n") > 1:
196 txt=""; bool = 0; numident=1
197 for l in s_mcsimp.splitlines() :
200 numident=s_mcsimp.find("=")+2
203 txt=txt+('\n'+self.indent_courant*' '+numident*' ')*ind+l
207 longueur = self.longueur(self.texte_etape)
208 increment = len((u'\n'+self.indent_courant*' ')*ind + string.strip(s_mcsimp))
209 if (bool_fonction == 1 ) :
210 self.texte_etape = self.texte_etape+'\n'+self.indent_courant*' ' +s_mcsimp
211 elif ( ((1-ind)*longueur+increment) <= self.l_max ) :
212 self.texte_etape = self.texte_etape + ('\n'+self.indent_courant*' ')*ind + string.strip(s_mcsimp)
215 nom,valeur = string.split(s_mcsimp,self.sep,1)
216 chaine = self.creer_chaine(nom,valeur,'\n'+self.indent_courant*' ',ind)
217 #self.jdc_fini = self.jdc_fini + ('\n'+self.indent_courant*' ')*ind + string.strip(s_mcsimp)
218 self.texte_etape = self.texte_etape + chaine
222 def longueur(self,texte):
224 texte est une string qui peut contenir des retours chariots
225 Cette méthode retourne la longueur de la dernière ligne de texte
227 liste = string.split(texte,'\n')
228 return len(liste[-1])
230 def creer_chaine(self,nom,valeur,increment,ind):
232 La methode creer_chaine reconstitue un objet Eficas à partir de
237 if len(increment + nom + self.sep) <= self.l_max:
238 texte = increment*ind
239 label = nom + self.sep
241 longueur = len(increment + label)
243 if ('(' not in valeur) or (valeur[0:3]=='"""'):
244 # il s'agit d'une vraie chaîne de caractères
246 texte = (self.l_max-2-val)*' '+valeur
250 # il s'agit d'une liste de tuple
251 # c est trop complique on ne splitte pas
252 if valeur[0:2]=='((' or valeur[0:2]=='[(':
255 # il s'agit d'une liste
256 liste = string.split(valeur,',')
259 ajout = string.strip(arg)
260 if len(ajout) == 0 : continue
261 longueur = self.longueur(texte = (texte + label)) + len(ajout +',') + (1-i)*len(increment)
262 if longueur <= self.l_max:
264 texte = texte + ajout +','
266 texte = texte + ajout
270 texte = texte + increment + (len(label)+2)*' ' + ajout + ','
272 texte = texte + increment + (len(label)+2)*' ' + ajout
278 # On a une ( mais pas de , . On passe la chaine sans modification
280 texte = (self.l_max-2-val)*' '+valeur
285 class FormatageLigne(Formatage) :
286 def __init__(self,l_jdc,code=None,mode=None,sep='=',l_max="**"):
287 Formatage.__init__(self,l_jdc,code=None,mode=None,sep='=',l_max="**")
289 def formate_jdc(self):
290 texte1=Formatage.formate_jdc(self)
292 lignes=texte1.split("\n")
294 pattern_debut_blanc = re.compile(r"^ \s*.*")
295 pattern_commentaire = re.compile(r"^\s*#.*")
296 pattern_vide=re.compile(r"\s*^$")
298 if pattern_commentaire.match(l) or pattern_vide.match(l):
301 if not pattern_debut_blanc.match(l) : texte=l
302 else : texte+=re.sub(r'^ \s*',' ',l)