import xml.dom.minidom
class TpXpic:
 "Python module to generate TpX drawings"
 def __init__(self):
   self.aXML = xml.dom.minidom.getDOMImplementation().createDocument(None, "TpX", None)
   self.XMLtop = self.aXML.documentElement
   self.XMLtop.setAttribute('v', '4')
 def __del__(self):
   self.aXML.unlink()
 def as_text(self):
   t = self.aXML.toprettyxml('  ', '\n')
   t = t.replace('<caption>\n    ','<caption>')
   t = t.replace('\n  </caption>','</caption>')
   t = t.replace('<comment>\n    ','<comment>')
   t = t.replace('\n  </comment>','</comment>')
   t = t.replace('">\n    ','">')
   t = t.replace('\n','\n%')
   j = t.find('\n')
   t = t[j+1:]
   j = t.rfind('\n')
   t = t[:j]
   return t
 def setRootAttribute(self, elID, s):
   self.XMLtop.setAttribute(elID, str(s))
 def setEl(self, elID):
   el = self.XMLtop.getElementsByTagName(elID)
   if len(el)>0:
     self.last = self.aXML.createElement(elID)
     self.XMLtop.removeChild(el[0]).unlink()
   else:
     self.last = self.aXML.createElement(elID)
   self.XMLtop.appendChild(self.last)
   return self.last
 def setCaption(self, s, label=None):
   self.setEl('caption').appendChild(self.aXML.createTextNode(s))
   if label!=None:
     self.a('label', label)
 def setComment(self, s):
   self.setEl('comment').appendChild(self.aXML.createTextNode(s))
 def addEl(self, elID):
   self.last = self.aXML.createElement(elID)
   self.XMLtop.appendChild(self.last)
   return self.last
 def a(self, elID, elValue, el=None):
   if el==None:
     self.last.setAttribute(elID, str(elValue))
   else:
     el.setAttribute(elID, str(elValue))
 def lc(self, cl, el=None):
   "set line color"
   self.a('lc', cl, el)
 def lw(self, w, el=None):
   "set line width"
   self.a('lw', w, el)
 def li(self, li, el=None):
   "set line style: none, dot, dash or solid (default)"
   self.a('li', li, el)
 def ha(self, ha, el=None):
   "set hatching: 1,...,6"
   self.a('ha', ha, el)
 def hc(self, cl, el=None):
   "set hatching color"
   self.a('hc', cl, el)
 def fill(self, cl, el=None):
   "set fill color"
   self.a('fill', cl, el)
 def addLine(self, x1, y1, x2, y2):
   "add line"
   self.last = self.addEl('line')
   self.a('x1', str(x1))
   self.a('y1', str(y1))
   self.a('x2', str(x2))
   self.a('y2', str(y2))
   return self.last
 def arr(self, arr1=None, arr2=None, arrs=None, el=None):
   "add arrow-heads; arr1,arr2: none, h40, h41, h42, h43, h44, h45, h46, h47, h48, t40, t43, t44, t45, h20, h21, h22, h23, h24, t20, t21, t22, t23, hr10, hr11, hr12, tr10, h10, h11, h12, h12c, t10, r0, r10, r11, r12, r20, r20c, r21, r33, ts10, ts11, ts12, hs10, hs12, ts20, ts21, ts23, hs20, hs23, o, oc, qq;"
   "arrs is arrow-head size factor"
   if arr1!=None:
     self.a('arr1', arr1, el)
   if arr2!=None:
     self.a('arr2', arr2, el)
   if arrs!=None:
     self.a('arrs', str(arrs), el)
 def addRect(self, x, y, w, h):
   "add rectangle"
   self.last = self.addEl('rect')
   self.a('x', str(x))
   self.a('y', str(y))
   self.a('w', str(w))
   self.a('h', str(h))
   return self.last
 def rotdeg(self, rotdeg, el=None):
   self.a('rotdeg', rotdeg, el)
 def addCircle(self, x, y, d):
   "add circle"
   self.last = self.addEl('circle')
   self.a('x', str(x))
   self.a('y', str(y))
   self.a('d', str(d))
   return self.last
 def addEllipse(self, x, y, dx, dy):
   "add ellipse"
   self.last = self.addEl('ellipse')
   self.a('x', str(x))
   self.a('y', str(y))
   self.a('dx', str(dx))
   self.a('dy', str(dy))
   return self.last
 def points_str(self, pp):
   s = ''
   for i in range(len(pp)):
     s = s + str(pp[i][0]) + ',' + str(pp[i][1]) + ' '
   return s
 def addPolyline(self, pp):
   "add polyline"
   self.last = self.addEl('polyline')
   self.last.appendChild(self.aXML.createTextNode(self.points_str(pp)))
   return self.last
 def addPolygon(self, pp):
   "add polygon"
   self.last = self.addEl('polygon')
   self.last.appendChild(self.aXML.createTextNode(self.points_str(pp)))
   return self.last
 def addCircular(self, aID, x, y, d, a1, a2):
   "add circular object"
   self.last = self.addEl(aID)
   self.a('x', str(x))
   self.a('y', str(y))
   self.a('d', str(d))
   self.a('a1', str(a1))
   self.a('a2', str(a2))
   return self.last
 def addArc(self, x, y, d, a1, a2):
   "add arc"
   return self.addCircular('arc', x, y, d, a1, a2)
 def addSegment(self, x, y, d, a1, a2):
   "add segment"
   return self.addCircular('segment', x, y, d, a1, a2)
 def addSector(self, x, y, d, a1, a2):
   "add sector"
   return self.addCircular('sector', x, y, d, a1, a2)
 def addCurve(self, pp):
   "add curve"
   self.last = self.addEl('curve')
   self.last.appendChild(self.aXML.createTextNode(self.points_str(pp)))
   return self.last
 def closed(self, el=None):
   "make a curve closed"
   self.a('closed', 1, el)
 def addBezier(self, pp):
   "add Bezier path"
   self.last = self.addEl('bezier')
   self.last.appendChild(self.aXML.createTextNode(self.points_str(pp)))
   return self.last
 def addText(self, x, y, h, t, tex=None):
   "add text label"
   self.last = self.addEl('text')
   self.a('x', str(x))
   self.a('y', str(y))
   self.a('h', str(h))
   self.a('t', t)
   if tex!=None:
     self.a('tex', tex)
   return self.last
 def jh(self, j, el=None):
   "set text horizontal justification: l (left, default), c (center) or r (right)"
   self.a('jh', j, el)
 def jv(self, j, el=None):
   "set text vertical justification: 0 (baseline, default), b (bottom), c (center) or t (top)"
   self.a('jv', j, el)
 def addStar(self, x, y, s=None):
   "add star"
   self.last = self.addEl('star')
   self.a('x', str(x))
   self.a('y', str(y))
   if s!=None:
     self.a('s', s)
   return self.last
 def starShape(self, s, el=None):
   "set star shape: circle (default), square, diamond, triup, tridown, penta, star4, star5, star6, cross, dcross, flower5, flower4, star4arc, maltese"
   self.a('s', s, el)
 def starD(self, d, el=None):
   "set star size factor"
   self.a('d', str(d), el)
 def addSymbol(self, x, y, d, s=None):
   "add symbol"
   self.last = self.addEl('symbol')
   self.a('x', str(x))
   self.a('y', str(y))
   self.a('d', str(d))
   if s!=None:
     self.a('s', s)
   return self.last
 def symbShape(self, s, el=None):
   "set symbol shape: process, decision, input-output, preparation, punch-card, manual-op, keyboard, punch-tape, document, documents, display, terminal, keying, alt-process, online-storage, magnetic-drum, magnetic-tape, hoarrow1, hoarrow1v, hoarrow2, hoarrow3, hoarrow4, star5, diamond8, baloon1, baloon2, cloud1, splash1, snowflake1"
   self.a('s', s, el)
 def SaveToFile(self, FileName):
   f = file(FileName, 'w')
   f.write(self.as_text())
   f.close()

def HTML_color(r,g,b):
 "Make HTML color from RGB levels"
 r=round(r);g=round(g);b=round(b)
 if r<0:r=0
 if r>255:r=255
 if g<0:g=0
 if g>255:g=255
 if b<0:b=0
 if b>255:b=255
 return '#%02X%02X%02X'%(r,g,b)