In [1]:
# name: SVG_lib.py
# type: text/x-python
# size: 4256 bytes 
# ---- 
from collections import OrderedDict as Dict

class point(object):
    def __init__(self, x = 0, y = 0):
        iterator = {type([]),type(())}
        if type(x) in iterator and y==0:
            x,y = x
        self.x = x
        self.y = y
    
    def __repr__(self):
        txt = 'class: point(x = %g, y = %g)'%(self.x, self.y)
        return txt
    
    def __iter__(self):
        yield [self.x,self.y]
    
    def offset_y(self,val):
        return point(self.x,self.y+val)
    def offset_x(self,val):
        return point(self.x+val,self.y)
    def List(self):
        return [self.x, self.y]

colors = Dict()

with open('SVG_colors.txt','r') as f:
    for i, line in enumerate(f):
        if i==0:
            continue
        line = line.strip()
        parts = line.split('\t')
        pieces = []
        for part in parts:
            p = part.strip()
            if len(p)==0:
                continue
            pieces.append(part)
        colors[pieces[0].strip()]=pieces

class Line(object):
    def __init__(self, p0=point(0,0), p1=point(100,100)):
        """p0, and p1 must be passed in as point class memebers or named tuples with x and y"""
        if type(p0)==list:
            p0=point(p0[0],p0[1])
        self.p0 = p0
        if type(p1)==list:
            p1=point(p1[0],p1[1])
        self.p1 = p1
        self.color = 'black'
        self.width = 1
        
    def svg_line_txt(self):
        txt  = '<line x1="%g" y1="%g" '%(self.p0.x, self.p0.y)
        txt += 'x2="%g" y2="%g" '%(self.p1.x, self.p1.y)
        txt += 'style="stroke:%s;'%self.color
        txt += 'stroke-width:%d" />'%self.width
        return txt
    
    
    def svg_txt(self):
        return self.svg_line_txt()

    @property
    def svg(self):
        txt = '<svg>'
        txt += '<line x1="%g" y1="%g" '%(self.p0.x, self.p0.y)
        txt += 'x2="%g" y2="%g" '%(self.p1.x, self.p1.y)
        txt += 'style="stroke:%s;'%self.color
        txt += 'stroke-width:%d" />'%self.width
        txt += '</svg>'
        return txt
    
    def _repr_svg_(self):
        return self.svg
    
    @property
    def color(self):
        return self._color
    @color.setter
    def color(self, value):
        value = value.lower()
        check = False
        if value in colors.keys():
            #name
            self._color = value
            check = True
        elif ',' in value:
            #rgb
            try:
                r,g,b = value.split(',')
                self._color = 'rgb(%d,%d,%d)'%(r,g,b)
                check = True
            except:
                pass
        elif 6<=len(value)<=7:
            #hex
            value = value.strip('#')
            try:
                r = int(value[0:2],16)
                g = int(value[2:4],16)
                b = int(value[4:6],16)
                self._color = 'rgb(%d,%d,%d)'%(r,g,b)
                check = True
            except:
                pass
        if not check:
            er = '%s is not a valid SVG color'%value
            raise(ValueError(er))
    
    @property
    def colors(self):
        print(', '.join(colors.keys()))
    
    @property
    def length(self):
        x0,y0 = self.p0.List()
        x1,y1 = self.p1.List()
        return ((x1-x0)**2+(y1-y0)**2)**0.5
    @property
    def direction(self):
        x0,y0 = self.p0.List()
        x1,y1 = self.p1.List()
        return [(x1-x0),(y1-y0)]

class arrow(Line):
    def __init__(self, p0=point(0,0), p1=point(100,100)):
        Line.__init__(self, p0, p1)
    
    @property
    def svg(self):
        txt = '<svg viewBox = "0 0 400 200"> '
        txt += '  <defs>'
        txt += '    <marker id="head" orient="auto" markerWidth="50" markerHeight="100"'
        txt += '            refX="0.25" refY="5">'
        txt += '      <path d="M0,0 V10 L5,5 " fill="red" />'
        txt += '    </marker>'
        txt += '  </defs>    '
        txt += '  <path'
        txt += '    marker-end="url(#head)"'
        txt += '    stroke-width="%d" fill="none" stroke=%s  '%(self.width, self.color)
        txt += '    d="M%d,%d '%(self.p0.x, self.p0.y)
        txt += 'L%d,%d"'%(self.p1.x, self.p1.y)
        txt += '    />    '
#         txt += '<line x1="%d" y1="%d" '%(self.p0.x, self.p0.y)
#         txt += 'x2="%d" y2="%d" '%(self.p1.x, self.p1.y)
#         txt += 'marker-end=url(#head); '
#         txt += 'style="stroke:%s;'%self.color
#         txt += 'stroke-width:%d" />'%self.width
        txt += '</svg>'
        return txt
    
    def _repr_svg_(self):
        return self.svg

In [2]:
a = [0,1]
point(*a)


Out[2]:
class: point(x = 0, y = 1)