Hello, This is my 'saying hello to this list' email. I have the problem that I have to do lots and lots of drawing of classes for the documentation of my thesis. Although I could use any drawing utility, I think it could be easier to produce Texdraw code... So this is what I've done: ''' 1998 Manuel Gutierrez Algaba You are free to use , modify, distribute and copy this piece of python code, if you keep this free copyright notice in it. By the way , I dont mind change this copyright notice to GPL, pythonish or whatever, if you like constructor of diagrams: Given a frame of classes and relationships among clases, it generates latex code ,that represents those classes in the Rumbaugh OO notation. ''' ''' The first idea is this : If we have a box representing the class we stablish *contact_points* in its borders, so we can connect them , the positions inside a box are absolute to a relative point, the self.x , self.y in the a_simple_class. a_simple_class just draw a box , with the name of the class the next steps are to do: - union_derivation - union_atribution and create complex drawings. The position of the boxes are determined by the position of a base a_simple_class, whose contact_points will be supplied to the boxes conected (by unions) to it , so that the other boxes can obtain an absolute positioning. Currently it generates only tex code, but it will be interesting ,perhaps, to generate tcl/tk code, and do a small drawing utility in canvas. But now, my only target is to generate tex code, my inmediate target. ''' ''' scale: it is just a factor for adjusting the length of the lines. ''' class scale: def __init__(self,l): self.l = l def what_scale(self): return self.l class line: def __init__(self,length,dx,dy): self.l = length self.dx = dx self.dy = dy def what_length(self): return self.l def what_x(self): return self.dx def what_y(self): return self.dy class horizontal_line(line): def __init__(self,dx): line.__init__(self,dx,dx,0) class vertical_line(line): def __init__(self,dy): line.__init__(self,dy,0,dy) class contact_point: def __init__(self,name): self.name = name def what_name(self): return self.name def what_x(self): return self.x def what_y(self): return self.y def do_x(self,x): self.x = x def do_y(self,y): self.y = y ''' a_simple_class: This one should generate code for a class, that is , if we say : class frutas, attributes: perecedera , dulce, seca, carnosa, del tiempo, tropical, then it generates code that represents: __________ | frutas | |--------| |pereced | |dulce | |seca | |.... | |________| Besides contact_points should be stablished to insert another classes ''' class a_simple_class(scale): def __init__(self): scale.__init__(self,2) self.list_of_lines = [] self.x = 0 self.y = 0 def do_origin_x(self, x): self.originx = x def do_origin_y(self, y): self.originy = y def do_name_clase(self,name_clase): self.name_clase = name_clase def do_attributes(self, list_of_atributes): self.list_of_atributes = list_of_atributes def do_lines(self): self.do_line_upwards() self.do_lines_of_the_right() self.do_downwards_line() self.do_lines_of_the_left() def do_line_upwards(self): j = len(self.name_clase) parte_uno = j * self.what_scale() / 2 self.virtually_drawing([horizontal_line(parte_uno), contact_point('superior'), horizontal_line(parte_uno)]) def virtually_drawing(self,l): for i in l: if isinstance(i,vertical_line): self.y = self.y + i.what_y() elif isinstance(i, horizontal_line): self.x = self.x + i.what_x() else: # es un punto de contacto i.do_x(self.x) i.do_y(self.y) self.list_of_lines.append(i) def do_lines_of_the_left(self): j = len(self.list_of_atributes) + 2 self.virtually_drawing([vertical_line(j), contact_point('leftsided'), vertical_line(j)]) def do_lines_of_the_right(self): j = len(self.list_of_atributes) + 2 self.virtually_drawing([vertical_line(-j), contact_point('rightsided'), vertical_line(-j)]) def do_downwards_line(self): j = len(self.name_clase) parte_uno = j * self.what_scale() / 2 self.virtually_drawing([horizontal_line(-parte_uno), contact_point('inferior'), horizontal_line(-parte_uno)]) def imprime_list_of_lines(self): self.x = 0 self.y = 0 print self.list_of_lines for i in self.list_of_lines: if isinstance(i,vertical_line): self.y = self.y + i.what_y() print "vertical_line", self.y elif isinstance(i, horizontal_line): self.x = self.x + i.what_x() print "horizontal_line", self.x else: # it is a contact point print "contact point", i.what_name(), i.what_x(), i.what_y() def generate_latex_code(self,f): fi = open(f,'w') print "\\begin{center}" print "\\begin{texdraw}" print " \\drawdim {cm}" print " \\linewd 0.02" fi.write( "\\begin{center}\n"+ "\\begin{texdraw}\n"+ " \\drawdim {cm}\n \setunitscale 0.3"+ " \\linewd 0.02\n" ) self.genera_labels(fi) for i in self.list_of_lines: if isinstance(i,vertical_line): print "\\rlvec(0 ",i.what_y()," )" fi.write("\\rlvec(0 "+`i.what_y()`+" )\n") elif isinstance(i, horizontal_line): self.x = self.x + i.what_x() fi.write( "\\rlvec( "+`i.what_x()`+" 0)\n") fi.write( "\\end{texdraw}\n"+ "\\end{center}\n") fi.close() def genera_labels(self,f): f.write(" \\move(0 0)\\lvec(0 0) \\textref h:L v:C \\htext(1.5 -1){"+self.name_clase+"}\n ") counter = -1.8 for i in self.list_of_atributes: counter = counter - 1.5 f.write(" \\htext(1.5 "+`counter`+"){"+i+"}\n ") j = len(self.name_clase) j = j * self.what_scale() f.write("\\move(0 -2.4)\\rlvec("+`j` +" 0 )\\move(0 0)\n") def test(): c = a_simple_class() c.do_name_clase('fruta') c.do_attributes(['perecedera' , 'dulce', 'seca', 'carnosa', 'del tiempo', 'tropical']) c.do_lines() c.imprime_list_of_lines() c.generate_latex_code('result') d = a_simple_class() d.do_name_clase('empleado') d.do_attributes(['paga por horas' , 'sueldo']) d.do_lines() d.imprime_list_of_lines() d.generate_latex_code('result2') if __name__=='__main__': test() And that's what you can find in the 'result' file: \begin{center} \begin{texdraw} \drawdim {cm} \setunitscale 0.3 \linewd 0.02 \move(0 0)\lvec(0 0) \textref h:L v:C \htext(1.5 -1){fruta} \htext(1.5 -3.3){perecedera} \htext(1.5 -4.8){dulce} \htext(1.5 -6.3){seca} \htext(1.5 -7.8){carnosa} \htext(1.5 -9.3){del tiempo} \htext(1.5 -10.8){tropical} \move(0 -2.4)\rlvec(10 0 )\move(0 0) \rlvec( 5 0) \rlvec( 5 0) \rlvec(0 -8 ) \rlvec(0 -8 ) \rlvec( -5 0) \rlvec( -5 0) \rlvec(0 8 ) \rlvec(0 8 ) \end{texdraw} \end{center} It's not too much. I'll improve the code until it does all what I need. Do you want to join ? If so, email irmina@ctv.es I've created a web page for such a project in : www.ctv.es/USERS/irmina/texpython.htm I think it's a very easy and interesting project,... provide with Tex documentation python sources!!! At last for those who use python and tex in their theses. ideas? Regards Manolo
participants (1)
-
Manuel Gutierrez Algaba