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 le plugin generateur de fichier au format
26 import types,string,re
28 from Noyau import N_CR
29 from Noyau.N_utils import repr_float
32 from Extensions.parametre import ITEM_PARAMETRE
33 from Formatage import Formatage
34 from Formatage import FormatageLigne
35 from Extensions.param2 import Formula
36 from Extensions.eficas_exception import EficasException
37 from Extensions.i18n import tr
42 Retourne les informations necessaires pour le chargeur de plugins
44 Ces informations sont retournees dans un dictionnaire
49 # La factory pour creer une instance du plugin
50 'factory' : PythonGenerator,
54 class PythonGenerator:
56 Ce generateur parcourt un objet de type JDC et produit
57 un fichier au format python
59 L'acquisition et le parcours sont realises par la methode
60 generator.gener(objet_jdc,format)
62 L'ecriture du fichier au format ini par appel de la methode
63 generator.writefile(nom_fichier)
65 Ses caracteristiques principales sont exposees dans des attributs
67 - extensions : qui donne une liste d'extensions de fichier preconisees
70 # Les extensions de fichier preconisees
73 def __init__(self,cr=None):
74 # Si l'objet compte-rendu n'est pas fourni, on utilise le compte-rendu standard
78 self.cr=N_CR.CR(debut='CR generateur format python pour python',
79 fin='fin CR format python pour python')
80 # Le texte au format python est stocke dans l'attribut text
84 def writefile(self,filename):
89 def gener(self,obj,format='brut',config=None,appli=None):
91 Retourne une representation du JDC obj sous une
92 forme qui est parametree par format.
93 Si format vaut 'brut', retourne une liste de listes de ...
94 Si format vaut 'standard', retourne un texte obtenu par concatenation de la liste
95 Si format vaut 'beautifie', retourne le meme texte beautifie
97 self.appli=obj.get_jdc_root().appli
99 liste= self.generator(obj)
102 elif format == 'standard':
103 self.text=string.join(liste)
104 elif format == 'beautifie':
105 jdc_formate = Formatage(liste,mode='.py')
106 self.text=jdc_formate.formate_jdc()
107 elif format == 'Ligne':
108 jdc_formate = FormatageLigne(liste,mode='.py')
109 self.text=jdc_formate.formate_jdc()
111 raise EficasException(tr("Format non implemente ") +format)
114 def generator(self,obj):
116 Cette methode joue un role d'aiguillage en fonction du type de obj
117 On pourrait utiliser les methodes accept et visitxxx a la
118 place (depend des gouts !!!)
120 # ATTENTION a l'ordre des tests : il peut avoir de l'importance (heritage)
121 if isinstance(obj,Accas.PROC_ETAPE):
122 return self.generPROC_ETAPE(obj)
123 # Attention doit etre place avant MACRO (raison : heritage)
124 elif isinstance(obj,Accas.FORM_ETAPE):
125 return self.generFORM_ETAPE(obj)
126 elif isinstance(obj,Accas.MACRO_ETAPE):
127 return self.generMACRO_ETAPE(obj)
128 elif isinstance(obj,Accas.ETAPE):
129 return self.generETAPE(obj)
130 elif isinstance(obj,Accas.MCFACT):
131 return self.generMCFACT(obj)
132 elif isinstance(obj,Accas.MCList):
133 return self.generMCList(obj)
134 elif isinstance(obj,Accas.MCBLOC):
135 return self.generMCBLOC(obj)
136 elif isinstance(obj,Accas.MCSIMP):
137 return self.generMCSIMP(obj)
138 elif isinstance(obj,Accas.ASSD):
139 return self.generASSD(obj)
140 elif isinstance(obj,Accas.ETAPE_NIVEAU):
141 return self.generETAPE_NIVEAU(obj)
142 elif isinstance(obj,Accas.COMMENTAIRE):
143 return self.generCOMMENTAIRE(obj)
144 # Attention doit etre place avant PARAMETRE (raison : heritage)
145 elif isinstance(obj,Accas.PARAMETRE_EVAL):
146 return self.generPARAMETRE_EVAL(obj)
147 elif isinstance(obj,Accas.PARAMETRE):
148 return self.generPARAMETRE(obj)
149 elif isinstance(obj,Accas.EVAL):
150 return self.generEVAL(obj)
151 elif isinstance(obj,Accas.COMMANDE_COMM):
152 return self.generCOMMANDE_COMM(obj)
153 elif isinstance(obj,Accas.JDC):
154 return self.generJDC(obj)
155 elif isinstance(obj,Accas.MCNUPLET):
156 return self.generMCNUPLET(obj)
157 elif isinstance(obj,ITEM_PARAMETRE):
158 return self.generITEM_PARAMETRE(obj)
159 elif isinstance(obj,Formula):
160 return self.generFormula(obj)
162 raise EficasException(tr("Type d'objet non prevu") +obj)
164 def generJDC(self,obj):
166 Cette methode convertit un objet JDC en une liste de chaines de
167 caracteres a la syntaxe python
170 if obj.definition.l_niveaux == ():
171 # Il n'y a pas de niveaux
172 for etape in obj.etapes:
173 l.append(self.generator(etape))
176 for etape_niveau in obj.etapes_niveaux:
177 l.extend(self.generator(etape_niveau))
179 # Si au moins une etape, on ajoute le retour chariot sur la derniere etape
180 if type(l[-1])==types.ListType:
181 l[-1][-1] = l[-1][-1]+'\n'
182 elif type(l[-1])==types.StringType:
186 def generMCNUPLET(self,obj):
188 Methode generant une representation de self permettant son ecriture
189 dans le format python
193 for v in obj.mc_liste:
194 text = re.sub(".*=","",self.generator(v))
199 def generCOMMANDE_COMM(self,obj):
201 Cette methode convertit un COMMANDE_COMM
202 en une liste de chaines de caracteres a la syntaxe python
204 l_lignes = string.split(obj.valeur,'\n')
206 for ligne in l_lignes:
207 txt = txt + '##'+ligne+'\n'
210 def generEVAL(self,obj):
212 Cette methode convertit un EVAL
213 en une liste de chaines de caracteres a la syntaxe python
215 return 'EVAL("""'+ obj.valeur +'""")'
217 def generCOMMENTAIRE(self,obj):
219 Cette methode convertit un COMMENTAIRE
220 en une liste de chaines de caracteres a la syntaxe python
222 # modification pour repondre a la demande de C. Durand, d'eviter
223 # l'ajout systematique d'un diese, a la suite du commentaire
224 # Dans la chaine de caracteres obj.valeur, on supprime le dernier
226 sans_saut = re.sub("\n$","",obj.valeur)
227 l_lignes = string.split(sans_saut,'\n')
230 for ligne in l_lignes:
231 txt = txt + '#'+ligne+'\n'
233 # suppression du dernier saut de ligne
234 #txt = re.sub("\n$","",txt)
235 # on ajoute un saut de ligne avant
236 pattern=re.compile(" ?\#")
242 def generPARAMETRE_EVAL(self,obj):
244 Cette methode convertit un PARAMETRE_EVAL
245 en une liste de chaines de caracteres a la syntaxe python
247 if obj.valeur == None:
248 return obj.nom + ' = None ;\n'
250 return obj.nom + ' = '+ self.generator(obj.valeur) +';\n'
252 def generITEM_PARAMETRE(self,obj):
255 def generFormula(self,obj):
259 def generPARAMETRE(self,obj):
261 Cette methode convertit un PARAMETRE
262 en une liste de chaines de caracteres a la syntaxe python
264 return repr(obj) + ";\n"
266 def generETAPE_NIVEAU(self,obj):
268 Cette methode convertit une etape niveau
269 en une liste de chaines de caracteres a la syntaxe python
272 if obj.etapes_niveaux == []:
273 for etape in obj.etapes:
274 l.append(self.generator(etape))
276 for etape_niveau in obj.etapes_niveaux:
277 l.extend(self.generator(etape_niveau))
280 def generETAPE(self,obj):
282 Cette methode convertit une etape
283 en une liste de chaines de caracteres a la syntaxe python
286 sdname= self.generator(obj.sd)
287 if string.find(sdname,'SD_') != -1: sdname='sansnom'
291 label=sdname + '='+obj.definition.nom+'('
293 if obj.reuse != None :
294 str = 'reuse ='+ self.generator(obj.reuse) + ','
296 for v in obj.mc_liste:
297 if isinstance(v,Accas.MCBLOC) :
298 liste=self.generator(v)
301 elif isinstance(v,Accas.MCSIMP) :
302 text=self.generator(v)
303 l.append(v.nom+'='+text)
306 liste=self.generator(v)
307 liste[0]=v.nom+'='+liste[0]
315 def generFORM_ETAPE(self,obj):
317 Methode particuliere pour les objets de type FORMULE
321 if nom == '' : nom = 'sansnom'
322 l.append(nom + ' = FORMULE(')
323 for v in obj.mc_liste:
324 text=self.generator(v)
325 l.append(v.nom+'='+text)
329 def generMACRO_ETAPE(self,obj):
331 Cette methode convertit une macro-etape
332 en une liste de chaines de caracteres a la syntaxe python
338 sdname= self.generator(obj.sd)+'='
342 label = sdname + obj.definition.nom+'('
344 if obj.reuse != None:
345 # XXX faut il la virgule ou pas ????
346 str = "reuse =" + self.generator(obj.reuse) + ','
348 for v in obj.mc_liste:
349 if isinstance(v,Accas.MCBLOC) :
350 liste=self.generator(v)
353 elif isinstance(v,Accas.MCSIMP) :
354 text=self.generator(v)
355 l.append(v.nom+'='+text)
358 liste=self.generator(v)
359 liste[0]=v.nom+'='+liste[0]
368 def generPROC_ETAPE(self,obj):
370 Cette methode convertit une PROC etape
371 en une liste de chaines de caracteres a la syntaxe python
374 label=obj.definition.nom+'('
376 for v in obj.mc_liste:
377 if isinstance(v,Accas.MCBLOC) :
378 liste=self.generator(v)
381 elif isinstance(v,Accas.MCSIMP) :
382 text=self.generator(v)
383 l.append(v.nom+'='+text)
386 liste=self.generator(v)
387 liste[0]=v.nom+'='+liste[0]
396 def generASSD(self,obj):
398 Convertit un objet derive d'ASSD en une chaine de caracteres a la
401 return obj.get_name()
403 def generMCFACT(self,obj):
405 Convertit un objet MCFACT en une liste de chaines de caracteres a la
410 for v in obj.mc_liste:
411 if not isinstance(v,Accas.MCSIMP) and not isinstance (v,Accas.MCBLOC) :
412 # on est en presence d'une entite composee : on recupere une liste
413 liste=self.generator(v)
414 liste[0]=v.nom+'='+liste[0]
416 elif isinstance(v,Accas.MCBLOC):
417 liste=self.generator(v)
421 # on est en presence d'un MCSIMP : on recupere une string
422 text =self.generator(v)
423 if v.nom != "Consigne" : l.append(v.nom+'='+text)
424 # il faut etre plus subtil dans l'ajout de la virgule en differenciant
425 # le cas ou elle est obligatoire (si self a des freres cadets
426 # dans self.parent) ou non
427 # (cas ou self est seul ou le benjamin de self.parent)
431 def generMCList(self,obj):
433 Convertit un objet MCList en une liste de chaines de caracteres a la
436 if len(obj.data) > 1:
438 for mcfact in obj.data: l.append(self.generator(mcfact))
441 l= self.generator(obj.data[0])
444 def generMCBLOC(self,obj):
446 Convertit un objet MCBLOC en une liste de chaines de caracteres a la
450 for v in obj.mc_liste:
451 if isinstance(v,Accas.MCBLOC) :
452 liste=self.generator(v)
455 elif isinstance(v,Accas.MCFACT):
456 liste=self.generator(v)
457 elif isinstance(v,Accas.MCList):
458 liste=self.generator(v)
459 liste[0]=v.nom+'='+liste[0]
460 # PN essai de correction bug identation
461 if (hasattr(v,'data')) :
462 if (isinstance(v.data[0],Accas.MCFACT) and (len(v.data) == 1)):
471 data=self.generator(v)
472 if type(data) == types.ListType:
473 data[0]=v.nom+'='+data[0]
480 def format_item(self,valeur,etape,obj,vientDeListe=0):
481 if (type(valeur) == types.FloatType or 'R' in obj.definition.type) and not(isinstance(valeur,Accas.PARAMETRE)) :
482 # Pour un flottant on utilise str ou repr si on vient d une liste
483 # ou la notation scientifique
484 # On ajoute un . si il n y en a pas dans la valeur
486 if vientDeListe and repr(valeur) != str(valeur) : s=repr(valeur)
487 if (s.find('.')== -1 and s.find('e')== -1 and s.find('E')==-1) : s=s+'.0'
488 clefobj=etape.get_sdname()
489 if self.appli.appliEficas and self.appli.appliEficas.dict_reels.has_key(clefobj):
490 if self.appli.appliEficas.dict_reels[clefobj].has_key(valeur):
491 s=self.appli.appliEficas.dict_reels[clefobj][valeur]
493 elif type(valeur) == types.StringType :
494 if valeur.find('\n') == -1:
495 # pas de retour chariot, on utilise repr
497 elif valeur.find('"""') == -1:
498 # retour chariot mais pas de triple ", on formatte
502 elif isinstance(valeur,Accas.CO) or hasattr(etape,'sdprods') and valeur in etape.sdprods:
503 s = "CO('"+ self.generator(valeur) +"')"
504 elif isinstance(valeur,Accas.ASSD):
505 s = self.generator(valeur)
506 elif isinstance(valeur,Accas.PARAMETRE):
507 # il ne faut pas prendre la string que retourne gener
508 # mais seulement le nom dans le cas d'un parametre
511 #elif type(valeur) == types.InstanceType or isinstance(valeur,object):
512 # if valeur.__class__.__name__ == 'CO' or hasattr(etape,'sdprods') and valeur in etape.sdprods :
513 # s = "CO('"+ self.generator(valeur) +"')"
514 # elif isinstance(valeur,Accas.PARAMETRE):
515 # il ne faut pas prendre la string que retourne gener
516 # mais seulement le nom dans le cas d'un parametre
519 # s = self.generator(valeur)
522 # Pour les autres types on utilise repr
526 def generMCSIMP(self,obj) :
528 Convertit un objet MCSIMP en une liste de chaines de caracteres a la
532 if type(obj.valeur) in (types.TupleType,types.ListType) :
534 for ss_type in obj.definition.type:
535 if repr(ss_type).find('Tuple') != -1 :
540 #s = str(obj.valeur) +','
541 #obj.valeurFormatee=obj.valeur
542 s = obj.GetText() +','
543 obj.valeurFormatee=obj.GetText()
545 obj.valeurFormatee=[]
546 for val in obj.valeur :
547 s =s +self.format_item(val,obj.etape,obj,1) + ','
549 obj.valeurFormatee.append(val)
551 obj.valeurFormatee.append(self.format_item(val,obj.etape,obj))
552 if len(obj.valeur) >= 1:
554 if obj.valeur==[] or obj.valeur==() : s="(),"
555 if obj.nbrColonnes() :
556 s=self.formatColonnes(obj.nbrColonnes(),obj.valeur,obj)
558 obj.valeurFormatee=obj.valeur
559 s=self.format_item(obj.valeur,obj.etape,obj) + ','
563 def formatColonnes(self,nbrColonnes,listeValeurs,obj):
568 while ( indice < len(listeValeurs) ) :
571 for l in range(nbrColonnes) :
572 texteVariable=self.format_item(listeValeurs[indice],obj.etape,obj)
573 textformat=textformat+texteVariable+" ,"
575 textformat=textformat+"\n"
578 while ( indice < len(listeValeurs) ) :
579 texteVariable=self.format_item(listeValeurs[indice],obj.etape,obj)
580 textformat=textformat+texteVariable+", "
582 textformat=textformat+"\n"
583 textformat=textformat[0:-1]+"),\n"
586 textformat=str(obj.valeur)