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
25 from __future__ import absolute_import
27 from builtins import str
28 from builtins import object
29 from builtins import range
35 from Noyau import N_CR
36 from Noyau.N_utils import repr_float
39 from Extensions.parametre import ITEM_PARAMETRE
40 from .Formatage import Formatage
41 from .Formatage import FormatageLigne
42 from Extensions.param2 import Formula
43 from Extensions.eficas_exception import EficasException
44 from Extensions.i18n import tr
49 Retourne les informations necessaires pour le chargeur de plugins
51 Ces informations sont retournees dans un dictionnaire
56 # La factory pour creer une instance du plugin
57 'factory' : PythonGenerator,
61 class PythonGenerator(object):
63 Ce generateur parcourt un objet de type JDC et produit
64 un fichier au format python
66 L'acquisition et le parcours sont realises par la methode
67 generator.gener(objet_jdc,format)
69 L'ecriture du fichier au format ini par appel de la methode
70 generator.writefile(nom_fichier)
72 Ses caracteristiques principales sont exposees dans des attributs
74 - extensions : qui donne une liste d'extensions de fichier preconisees
77 # Les extensions de fichier preconisees
80 def __init__(self,cr=None):
81 # Si l'objet compte-rendu n'est pas fourni, on utilise le compte-rendu standard
85 self.cr=N_CR.CR(debut='CR generateur format python pour python',
86 fin='fin CR format python pour python')
87 # Le texte au format python est stocke dans l'attribut text
91 def writefile(self,filename):
96 def gener(self,obj,format='brut',config=None,appli=None):
98 Retourne une representation du JDC obj sous une
99 forme qui est parametree par format.
100 Si format vaut 'brut', retourne une liste de listes de ...
101 Si format vaut 'standard', retourne un texte obtenu par concatenation de la liste
102 Si format vaut 'beautifie', retourne le meme texte beautifie
104 self.appli=obj.get_jdc_root().appli
105 #self.appli=obj.appli
106 liste= self.generator(obj)
109 elif format == 'standard':
110 self.text=''.join(liste)
111 elif format == 'beautifie':
112 jdc_formate = Formatage(liste,mode='.py')
113 self.text=jdc_formate.formate_jdc()
114 elif format == 'Ligne':
115 jdc_formate = FormatageLigne(liste,mode='.py')
116 self.text=jdc_formate.formate_jdc()
118 raise EficasException(tr("Format non implemente ") +format)
121 def generator(self,obj):
123 Cette methode joue un role d'aiguillage en fonction du type de obj
124 On pourrait utiliser les methodes accept et visitxxx a la
125 place (depend des gouts !!!)
127 # ATTENTION a l'ordre des tests : il peut avoir de l'importance (heritage)
128 if isinstance(obj,Accas.PROC_ETAPE):
129 return self.generPROC_ETAPE(obj)
130 # Attention doit etre place avant MACRO (raison : heritage)
131 elif isinstance(obj,Accas.FORM_ETAPE):
132 return self.generFORM_ETAPE(obj)
133 elif isinstance(obj,Accas.MACRO_ETAPE):
134 return self.generMACRO_ETAPE(obj)
135 elif isinstance(obj,Accas.ETAPE):
136 return self.generETAPE(obj)
137 elif isinstance(obj,Accas.MCFACT):
138 return self.generMCFACT(obj)
139 elif isinstance(obj,Accas.MCList):
140 return self.generMCList(obj)
141 elif isinstance(obj,Accas.MCBLOC):
142 return self.generMCBLOC(obj)
143 elif isinstance(obj,Accas.MCSIMP):
144 return self.generMCSIMP(obj)
145 elif isinstance(obj,Accas.ASSD):
146 return self.generASSD(obj)
147 elif isinstance(obj,Accas.ETAPE_NIVEAU):
148 return self.generETAPE_NIVEAU(obj)
149 elif isinstance(obj,Accas.COMMENTAIRE):
150 return self.generCOMMENTAIRE(obj)
151 # Attention doit etre place avant PARAMETRE (raison : heritage)
152 elif isinstance(obj,Accas.PARAMETRE_EVAL):
153 return self.generPARAMETRE_EVAL(obj)
154 elif isinstance(obj,Accas.PARAMETRE):
155 return self.generPARAMETRE(obj)
156 elif isinstance(obj,Accas.EVAL):
157 return self.generEVAL(obj)
158 elif isinstance(obj,Accas.COMMANDE_COMM):
159 return self.generCOMMANDE_COMM(obj)
160 elif isinstance(obj,Accas.JDC):
161 return self.generJDC(obj)
162 elif isinstance(obj,Accas.MCNUPLET):
163 return self.generMCNUPLET(obj)
164 elif isinstance(obj,ITEM_PARAMETRE):
165 return self.generITEM_PARAMETRE(obj)
166 elif isinstance(obj,Formula):
167 return self.generFormula(obj)
169 raise EficasException(tr("Type d'objet non prevu") +obj)
171 def generJDC(self,obj):
173 Cette methode convertit un objet JDC en une liste de chaines de
174 caracteres a la syntaxe python
177 if obj.definition.l_niveaux == ():
178 # Il n'y a pas de niveaux
179 for etape in obj.etapes:
180 l.append(self.generator(etape))
183 for etape_niveau in obj.etapes_niveaux:
184 l.extend(self.generator(etape_niveau))
186 # Si au moins une etape, on ajoute le retour chariot sur la derniere etape
187 if type(l[-1])==list:
188 l[-1][-1] = l[-1][-1]+'\n'
189 elif type(l[-1])==bytes:
193 def generMCNUPLET(self,obj):
195 Methode generant une representation de self permettant son ecriture
196 dans le format python
200 for v in obj.mc_liste:
201 text = re.sub(".*=","",self.generator(v))
206 def generCOMMANDE_COMM(self,obj):
208 Cette methode convertit un COMMANDE_COMM
209 en une liste de chaines de caracteres a la syntaxe python
211 l_lignes = obj.valeur.split('\n')
213 for ligne in l_lignes:
214 txt = txt + '##'+ligne+'\n'
217 def generEVAL(self,obj):
219 Cette methode convertit un EVAL
220 en une liste de chaines de caracteres a la syntaxe python
222 return 'EVAL("""'+ obj.valeur +'""")'
224 def generCOMMENTAIRE(self,obj):
226 Cette methode convertit un COMMENTAIRE
227 en une liste de chaines de caracteres a la syntaxe python
229 # modification pour repondre a la demande de C. Durand, d'eviter
230 # l'ajout systematique d'un diese, a la suite du commentaire
231 # Dans la chaine de caracteres obj.valeur, on supprime le dernier
233 sans_saut = re.sub("\n$","",obj.valeur)
234 l_lignes = sans_saut.split('\n')
237 for ligne in l_lignes:
238 txt = txt + '#'+ligne+'\n'
240 # suppression du dernier saut de ligne
241 #txt = re.sub("\n$","",txt)
242 # on ajoute un saut de ligne avant
243 pattern=re.compile(" ?\#")
249 def generPARAMETRE_EVAL(self,obj):
251 Cette methode convertit un PARAMETRE_EVAL
252 en une liste de chaines de caracteres a la syntaxe python
254 if obj.valeur == None:
255 return obj.nom + ' = None ;\n'
257 return obj.nom + ' = '+ self.generator(obj.valeur) +';\n'
259 def generITEM_PARAMETRE(self,obj):
262 def generFormula(self,obj):
266 def generPARAMETRE(self,obj):
268 Cette methode convertit un PARAMETRE
269 en une liste de chaines de caracteres a la syntaxe python
271 return repr(obj) + ";\n"
273 def generETAPE_NIVEAU(self,obj):
275 Cette methode convertit une etape niveau
276 en une liste de chaines de caracteres a la syntaxe python
279 if obj.etapes_niveaux == []:
280 for etape in obj.etapes:
281 l.append(self.generator(etape))
283 for etape_niveau in obj.etapes_niveaux:
284 l.extend(self.generator(etape_niveau))
287 def generETAPE(self,obj):
289 Cette methode convertit une etape
290 en une liste de chaines de caracteres a la syntaxe python
293 sdname= self.generator(obj.sd)
294 if sdname.find('SD_') != -1: sdname='sansnom'
298 label=sdname + '='+obj.definition.nom+'('
300 if obj.reuse != None :
301 str = 'reuse ='+ self.generator(obj.reuse) + ','
303 for v in obj.mc_liste:
304 if isinstance(v,Accas.MCBLOC) :
305 liste=self.generator(v)
308 elif isinstance(v,Accas.MCSIMP) :
309 text=self.generator(v)
310 l.append(v.nom+'='+text)
313 liste=self.generator(v)
314 liste[0]=v.nom+'='+liste[0]
322 def generFORM_ETAPE(self,obj):
324 Methode particuliere pour les objets de type FORMULE
328 if nom == '' : nom = 'sansnom'
329 l.append(nom + ' = FORMULE(')
330 for v in obj.mc_liste:
331 text=self.generator(v)
332 l.append(v.nom+'='+text)
336 def generMACRO_ETAPE(self,obj):
338 Cette methode convertit une macro-etape
339 en une liste de chaines de caracteres a la syntaxe python
345 sdname= self.generator(obj.sd)+'='
349 label = sdname + obj.definition.nom+'('
351 if obj.reuse != None:
352 # XXX faut il la virgule ou pas ????
353 str = "reuse =" + self.generator(obj.reuse) + ','
355 for v in obj.mc_liste:
356 if isinstance(v,Accas.MCBLOC) :
357 liste=self.generator(v)
360 elif isinstance(v,Accas.MCSIMP) :
361 text=self.generator(v)
362 l.append(v.nom+'='+text)
365 liste=self.generator(v)
366 liste[0]=v.nom+'='+liste[0]
375 def generPROC_ETAPE(self,obj):
377 Cette methode convertit une PROC etape
378 en une liste de chaines de caracteres a la syntaxe python
381 label=obj.definition.nom+'('
383 for v in obj.mc_liste:
384 if isinstance(v,Accas.MCBLOC) :
385 liste=self.generator(v)
388 elif isinstance(v,Accas.MCSIMP) :
389 text=self.generator(v)
390 if text==None : text= ""
391 l.append(v.nom+'='+text)
394 liste=self.generator(v)
395 liste[0]=v.nom+'='+liste[0]
404 def generASSD(self,obj):
406 Convertit un objet derive d'ASSD en une chaine de caracteres a la
409 return obj.get_name()
411 def generMCFACT(self,obj):
413 Convertit un objet MCFACT en une liste de chaines de caracteres a la
418 for v in obj.mc_liste:
419 if not isinstance(v,Accas.MCSIMP) and not isinstance (v,Accas.MCBLOC) :
420 # on est en presence d'une entite composee : on recupere une liste
421 liste=self.generator(v)
422 liste[0]=v.nom+'='+liste[0]
424 elif isinstance(v,Accas.MCBLOC):
425 liste=self.generator(v)
429 # on est en presence d'un MCSIMP : on recupere une string
430 text =self.generator(v)
431 if text== None : text =""
432 if v.nom != "Consigne" : l.append(v.nom+'='+text)
433 # il faut etre plus subtil dans l'ajout de la virgule en differenciant
434 # le cas ou elle est obligatoire (si self a des freres cadets
435 # dans self.parent) ou non
436 # (cas ou self est seul ou le benjamin de self.parent)
440 def generMCList(self,obj):
442 Convertit un objet MCList en une liste de chaines de caracteres a la
445 if len(obj.data) > 1:
447 for mcfact in obj.data: l.append(self.generator(mcfact))
450 l= self.generator(obj.data[0])
453 def generMCBLOC(self,obj):
455 Convertit un objet MCBLOC en une liste de chaines de caracteres a la
459 for v in obj.mc_liste:
460 if isinstance(v,Accas.MCBLOC) :
461 liste=self.generator(v)
464 elif isinstance(v,Accas.MCFACT):
465 liste=self.generator(v)
466 elif isinstance(v,Accas.MCList):
467 liste=self.generator(v)
468 liste[0]=v.nom+'='+liste[0]
469 # PN essai de correction bug identation
470 if (hasattr(v,'data')) :
471 if (isinstance(v.data[0],Accas.MCFACT) and (len(v.data) == 1)):
480 data=self.generator(v)
481 if data==None : data= ""
482 if type(data) == list:
483 data[0]=v.nom+'='+data[0]
490 def format_item(self,valeur,etape,obj,vientDeListe=0):
491 if (type(valeur) == float or 'R' in obj.definition.type) and not(isinstance(valeur,Accas.PARAMETRE)) :
492 # Pour un flottant on utilise str ou repr si on vient d une liste
493 # ou la notation scientifique
494 # On ajoute un . si il n y en a pas dans la valeur
496 if vientDeListe and repr(valeur) != str(valeur) : s=repr(valeur)
497 if (s.find('.')== -1 and s.find('e')== -1 and s.find('E')==-1) : s=s+'.0'
498 clefobj=etape.get_sdname()
499 if self.appli.appliEficas and clefobj in self.appli.appliEficas.dict_reels:
500 if valeur in self.appli.appliEficas.dict_reels[clefobj]:
501 s=self.appli.appliEficas.dict_reels[clefobj][valeur]
503 elif type(valeur) == bytes :
504 if valeur.find('\n') == -1:
505 # pas de retour chariot, on utilise repr
507 elif valeur.find('"""') == -1:
508 # retour chariot mais pas de triple ", on formatte
512 elif isinstance(valeur,Accas.CO) or hasattr(etape,'sdprods') and valeur in etape.sdprods:
513 s = "CO('"+ self.generator(valeur) +"')"
514 elif isinstance(valeur,Accas.ASSD):
515 s = self.generator(valeur)
516 elif isinstance(valeur,Accas.PARAMETRE):
517 # il ne faut pas prendre la string que retourne gener
518 # mais seulement le nom dans le cas d'un parametre
521 #elif type(valeur) == types.InstanceType or isinstance(valeur,object):
522 # if valeur.__class__.__name__ == 'CO' or hasattr(etape,'sdprods') and valeur in etape.sdprods :
523 # s = "CO('"+ self.generator(valeur) +"')"
524 # elif isinstance(valeur,Accas.PARAMETRE):
525 # il ne faut pas prendre la string que retourne gener
526 # mais seulement le nom dans le cas d'un parametre
529 # s = self.generator(valeur)
532 # Pour les autres types on utilise repr
536 def generMCSIMP(self,obj) :
538 Convertit un objet MCSIMP en une liste de chaines de caracteres a la
542 if type(obj.valeur) in (tuple,list) :
544 for ss_type in obj.definition.type:
545 if repr(ss_type).find('Tuple') != -1 :
550 #s = str(obj.valeur) +','
551 #obj.valeurFormatee=obj.valeur
552 s = obj.GetText() +','
553 obj.valeurFormatee=obj.GetText()
555 obj.valeurFormatee=[]
556 for val in obj.valeur :
557 s =s +self.format_item(val,obj.etape,obj,1) + ','
559 obj.valeurFormatee.append(val)
561 obj.valeurFormatee.append(self.format_item(val,obj.etape,obj))
562 if len(obj.valeur) >= 1:
564 if obj.valeur==[] or obj.valeur==() : s="(),"
565 if obj.nbrColonnes() :
566 s=self.formatColonnes(obj.nbrColonnes(),obj.valeur,obj)
568 obj.valeurFormatee=obj.valeur
569 s=self.format_item(obj.valeur,obj.etape,obj) + ','
573 def formatColonnes(self,nbrColonnes,listeValeurs,obj):
578 while ( indice < len(listeValeurs) ) :
581 for l in range(nbrColonnes) :
582 texteVariable=self.format_item(listeValeurs[indice],obj.etape,obj)
583 textformat=textformat+texteVariable+" ,"
585 textformat=textformat+"\n"
588 while ( indice < len(listeValeurs) ) :
589 texteVariable=self.format_item(listeValeurs[indice],obj.etape,obj)
590 textformat=textformat+texteVariable+", "
592 textformat=textformat+"\n"
593 textformat=textformat[0:-1]+"),\n"
596 textformat=str(obj.valeur)