[Doc-SIG] Tex OO Rumbaugh classes drawer.
Manuel Gutierrez Algaba
Manuel Gutierrez Algaba <irmina@ctv.es>
Mon, 9 Nov 1998 21:03:29 +0000 (GMT)
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