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):
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
100 liste= self.generator(obj)
103 elif format == 'standard':
104 self.text=string.join(liste)
105 elif format == 'beautifie':
106 jdc_formate = Formatage(liste,mode='.py')
107 self.text=jdc_formate.formate_jdc()
108 elif format == 'Ligne':
109 jdc_formate = FormatageLigne(liste,mode='.py')
110 self.text=jdc_formate.formate_jdc()
112 raise EficasException(tr("Format non implemente ") +format)
115 def generator(self,obj):
117 Cette methode joue un role d'aiguillage en fonction du type de obj
118 On pourrait utiliser les methodes accept et visitxxx a la
119 place (depend des gouts !!!)
121 # ATTENTION a l'ordre des tests : il peut avoir de l'importance (heritage)
122 if isinstance(obj,Accas.PROC_ETAPE):
123 return self.generPROC_ETAPE(obj)
124 # Attention doit etre place avant MACRO (raison : heritage)
125 elif isinstance(obj,Accas.FORM_ETAPE):
126 return self.generFORM_ETAPE(obj)
127 elif isinstance(obj,Accas.MACRO_ETAPE):
128 return self.generMACRO_ETAPE(obj)
129 elif isinstance(obj,Accas.ETAPE):
130 return self.generETAPE(obj)
131 elif isinstance(obj,Accas.MCFACT):
132 return self.generMCFACT(obj)
133 elif isinstance(obj,Accas.MCList):
134 return self.generMCList(obj)
135 elif isinstance(obj,Accas.MCBLOC):
136 return self.generMCBLOC(obj)
137 elif isinstance(obj,Accas.MCSIMP):
138 return self.generMCSIMP(obj)
139 elif isinstance(obj,Accas.ASSD):
140 return self.generASSD(obj)
141 elif isinstance(obj,Accas.ETAPE_NIVEAU):
142 return self.generETAPE_NIVEAU(obj)
143 elif isinstance(obj,Accas.COMMENTAIRE):
144 return self.generCOMMENTAIRE(obj)
145 # Attention doit etre place avant PARAMETRE (raison : heritage)
146 elif isinstance(obj,Accas.PARAMETRE_EVAL):
147 return self.generPARAMETRE_EVAL(obj)
148 elif isinstance(obj,Accas.PARAMETRE):
149 return self.generPARAMETRE(obj)
150 elif isinstance(obj,Accas.EVAL):
151 return self.generEVAL(obj)
152 elif isinstance(obj,Accas.COMMANDE_COMM):
153 return self.generCOMMANDE_COMM(obj)
154 elif isinstance(obj,Accas.JDC):
155 return self.generJDC(obj)
156 elif isinstance(obj,Accas.MCNUPLET):
157 return self.generMCNUPLET(obj)
158 elif isinstance(obj,ITEM_PARAMETRE):
159 return self.generITEM_PARAMETRE(obj)
160 elif isinstance(obj,Formula):
161 return self.generFormula(obj)
163 raise EficasException(tr("Type d'objet non prevu") +obj)
165 def generJDC(self,obj):
167 Cette methode convertit un objet JDC en une liste de chaines de
168 caracteres a la syntaxe python
171 if obj.definition.l_niveaux == ():
172 # Il n'y a pas de niveaux
173 for etape in obj.etapes:
174 l.append(self.generator(etape))
177 for etape_niveau in obj.etapes_niveaux:
178 l.extend(self.generator(etape_niveau))
180 # Si au moins une etape, on ajoute le retour chariot sur la derniere etape
181 if type(l[-1])==types.ListType:
182 l[-1][-1] = l[-1][-1]+'\n'
183 elif type(l[-1])==types.StringType:
187 def generMCNUPLET(self,obj):
189 Methode generant une representation de self permettant son ecriture
190 dans le format python
194 for v in obj.mc_liste:
195 text = re.sub(".*=","",self.generator(v))
200 def generCOMMANDE_COMM(self,obj):
202 Cette methode convertit un COMMANDE_COMM
203 en une liste de chaines de caracteres a la syntaxe python
205 l_lignes = string.split(obj.valeur,'\n')
207 for ligne in l_lignes:
208 txt = txt + '##'+ligne+'\n'
211 def generEVAL(self,obj):
213 Cette methode convertit un EVAL
214 en une liste de chaines de caracteres a la syntaxe python
216 return 'EVAL("""'+ obj.valeur +'""")'
218 def generCOMMENTAIRE(self,obj):
220 Cette methode convertit un COMMENTAIRE
221 en une liste de chaines de caracteres a la syntaxe python
223 # modification pour repondre a la demande de C. Durand, d'eviter
224 # l'ajout systematique d'un diese, a la suite du commentaire
225 # Dans la chaine de caracteres obj.valeur, on supprime le dernier
227 sans_saut = re.sub("\n$","",obj.valeur)
228 l_lignes = string.split(sans_saut,'\n')
231 for ligne in l_lignes:
232 txt = txt + '#'+ligne+'\n'
234 # suppression du dernier saut de ligne
235 #txt = re.sub("\n$","",txt)
236 # on ajoute un saut de ligne avant
237 pattern=re.compile(" ?\#")
243 def generPARAMETRE_EVAL(self,obj):
245 Cette methode convertit un PARAMETRE_EVAL
246 en une liste de chaines de caracteres a la syntaxe python
248 if obj.valeur == None:
249 return obj.nom + ' = None ;\n'
251 return obj.nom + ' = '+ self.generator(obj.valeur) +';\n'
253 def generITEM_PARAMETRE(self,obj):
256 def generFormula(self,obj):
260 def generPARAMETRE(self,obj):
262 Cette methode convertit un PARAMETRE
263 en une liste de chaines de caracteres a la syntaxe python
265 return repr(obj) + ";\n"
267 def generETAPE_NIVEAU(self,obj):
269 Cette methode convertit une etape niveau
270 en une liste de chaines de caracteres a la syntaxe python
273 if obj.etapes_niveaux == []:
274 for etape in obj.etapes:
275 l.append(self.generator(etape))
277 for etape_niveau in obj.etapes_niveaux:
278 l.extend(self.generator(etape_niveau))
281 def generETAPE(self,obj):
283 Cette methode convertit une etape
284 en une liste de chaines de caracteres a la syntaxe python
287 sdname= self.generator(obj.sd)
288 if string.find(sdname,'SD_') != -1: sdname='sansnom'
292 label=sdname + '='+obj.definition.nom+'('
294 if obj.reuse != None :
295 str = 'reuse ='+ self.generator(obj.reuse) + ','
297 for v in obj.mc_liste:
298 if isinstance(v,Accas.MCBLOC) :
299 liste=self.generator(v)
302 elif isinstance(v,Accas.MCSIMP) :
303 text=self.generator(v)
304 l.append(v.nom+'='+text)
307 liste=self.generator(v)
308 liste[0]=v.nom+'='+liste[0]
316 def generFORM_ETAPE(self,obj):
318 Methode particuliere pour les objets de type FORMULE
322 if nom == '' : nom = 'sansnom'
323 l.append(nom + ' = FORMULE(')
324 for v in obj.mc_liste:
325 text=self.generator(v)
326 l.append(v.nom+'='+text)
330 def generMACRO_ETAPE(self,obj):
332 Cette methode convertit une macro-etape
333 en une liste de chaines de caracteres a la syntaxe python
339 sdname= self.generator(obj.sd)+'='
343 label = sdname + obj.definition.nom+'('
345 if obj.reuse != None:
346 # XXX faut il la virgule ou pas ????
347 str = "reuse =" + self.generator(obj.reuse) + ','
349 for v in obj.mc_liste:
350 if isinstance(v,Accas.MCBLOC) :
351 liste=self.generator(v)
354 elif isinstance(v,Accas.MCSIMP) :
355 text=self.generator(v)
356 l.append(v.nom+'='+text)
359 liste=self.generator(v)
360 liste[0]=v.nom+'='+liste[0]
369 def generPROC_ETAPE(self,obj):
371 Cette methode convertit une PROC etape
372 en une liste de chaines de caracteres a la syntaxe python
375 label=obj.definition.nom+'('
377 for v in obj.mc_liste:
378 if isinstance(v,Accas.MCBLOC) :
379 liste=self.generator(v)
382 elif isinstance(v,Accas.MCSIMP) :
383 text=self.generator(v)
384 l.append(v.nom+'='+text)
387 liste=self.generator(v)
388 liste[0]=v.nom+'='+liste[0]
397 def generASSD(self,obj):
399 Convertit un objet derive d'ASSD en une chaine de caracteres a la
402 return obj.get_name()
404 def generMCFACT(self,obj):
406 Convertit un objet MCFACT en une liste de chaines de caracteres a la
411 for v in obj.mc_liste:
412 if not isinstance(v,Accas.MCSIMP) and not isinstance (v,Accas.MCBLOC) :
413 # on est en presence d'une entite composee : on recupere une liste
414 liste=self.generator(v)
415 liste[0]=v.nom+'='+liste[0]
417 elif isinstance(v,Accas.MCBLOC):
418 liste=self.generator(v)
422 # on est en presence d'un MCSIMP : on recupere une string
423 text =self.generator(v)
424 if v.nom != "Consigne" : l.append(v.nom+'='+text)
425 # il faut etre plus subtil dans l'ajout de la virgule en differenciant
426 # le cas ou elle est obligatoire (si self a des freres cadets
427 # dans self.parent) ou non
428 # (cas ou self est seul ou le benjamin de self.parent)
432 def generMCList(self,obj):
434 Convertit un objet MCList en une liste de chaines de caracteres a la
437 if len(obj.data) > 1:
439 for mcfact in obj.data: l.append(self.generator(mcfact))
442 l= self.generator(obj.data[0])
445 def generMCBLOC(self,obj):
447 Convertit un objet MCBLOC en une liste de chaines de caracteres a la
451 for v in obj.mc_liste:
452 if isinstance(v,Accas.MCBLOC) :
453 liste=self.generator(v)
456 elif isinstance(v,Accas.MCFACT):
457 liste=self.generator(v)
458 elif isinstance(v,Accas.MCList):
459 liste=self.generator(v)
460 liste[0]=v.nom+'='+liste[0]
461 # PN essai de correction bug identation
462 if (hasattr(v,'data')) :
463 if (isinstance(v.data[0],Accas.MCFACT) and (len(v.data) == 1)):
472 data=self.generator(v)
473 if type(data) == types.ListType:
474 data[0]=v.nom+'='+data[0]
481 def format_item(self,valeur,etape,obj):
482 if (type(valeur) == types.FloatType or 'R' in obj.definition.type) and not(isinstance(valeur,Accas.PARAMETRE)) :
483 # Pour un flottant on utilise str
484 # ou la notation scientifique
485 # On ajoute un . si il n y en a pas dans la 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
520 # s = self.generator(valeur)
523 # Pour les autres types on utilise repr
527 def generMCSIMP(self,obj) :
529 Convertit un objet MCSIMP en une liste de chaines de caracteres a la
533 if type(obj.valeur) in (types.TupleType,types.ListType) :
535 for ss_type in obj.definition.type:
536 if repr(ss_type).find('Tuple') != -1 :
541 #s = str(obj.valeur) +','
542 #obj.valeurFormatee=obj.valeur
543 s = obj.GetText() +','
544 obj.valeurFormatee=obj.GetText()
546 obj.valeurFormatee=[]
547 for val in obj.valeur :
548 s =s +self.format_item(val,obj.etape,obj) + ','
549 obj.valeurFormatee.append(self.format_item(val,obj.etape,obj))
550 if len(obj.valeur) > 1:
552 if obj.valeur==[] : s="(),"
553 if obj.nbrColonnes() :
554 s=self.formatColonnes(obj.nbrColonnes(),obj.valeur,obj)
556 obj.valeurFormatee=obj.valeur
557 s=self.format_item(obj.valeur,obj.etape,obj) + ','
561 def formatColonnes(self,nbrColonnes,listeValeurs,obj):
567 while ( indice < len(listeValeurs) ) :
570 for l in range(nbrColonnes) :
571 texteVariable=self.format_item(listeValeurs[indice],obj.etape,obj)
572 textformat=textformat+texteVariable+" ,"
574 textformat=textformat+"\n"
577 while ( indice < len(listeValeurs) ) :
578 texteVariable=self.format_item(listeValeurs[indice],obj.etape,obj)
579 textformat=textformat+texteVariable+", "
581 textformat=textformat+"\n"
582 textformat=textformat[0:-1]+"),\n"
585 textformat=str(obj.valeur)