svgwrite-1.1.8/0000777000000000000000000000000012723217123011525 5ustar 00000000000000svgwrite-1.1.8/examples/0000777000000000000000000000000012723217123013343 5ustar 00000000000000svgwrite-1.1.8/examples/basic_shapes.py0000666000000000000000000000317512574313463016357 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman # Purpose: svg examples # Created: 07.11.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License try: import svgwrite except ImportError: # if svgwrite is not 'installed' append parent dir of __file__ to sys.path import sys, os sys.path.insert(0, os.path.abspath(os.path.split(os.path.abspath(__file__))[0]+'/..')) import svgwrite from svgwrite import cm, mm def basic_shapes(name): dwg = svgwrite.Drawing(filename=name, debug=True) hlines = dwg.add(dwg.g(id='hlines', stroke='green')) for y in range(20): hlines.add(dwg.line(start=(2*cm, (2+y)*cm), end=(18*cm, (2+y)*cm), style="")) vlines = dwg.add(dwg.g(id='vline', stroke='blue')) for x in range(17): vlines.add(dwg.line(start=((2+x)*cm, 2*cm), end=((2+x)*cm, 21*cm))) shapes = dwg.add(dwg.g(id='shapes', fill='red')) # set presentation attributes at object creation as SVG-Attributes shapes.add(dwg.circle(center=(15*cm, 8*cm), r='2.5cm', stroke='blue', stroke_width=3)) # override the 'fill' attribute of the parent group 'shapes' shapes.add(dwg.rect(insert=(5*cm, 5*cm), size=(45*mm, 45*mm), fill='blue', stroke='red', stroke_width=3)) # or set presentation attributes by helper functions of the Presentation-Mixin ellipse = shapes.add(dwg.ellipse(center=(10*cm, 15*cm), r=('5cm', '10mm'))) ellipse.fill('green', opacity=0.5).stroke('black', width=5).dasharray([20, 20]) dwg.save() if __name__ == '__main__': basic_shapes('basic_shapes.svg') svgwrite-1.1.8/examples/checkerboard.py0000666000000000000000000000416712012651617016342 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman # Purpose: svg example: inline stylesheets, css, viewbox, groups # Created: 09.06.2012 # Copyright (C) 2012, Manfred Moitzi # License: MIT License import sys import os try: import svgwrite except ImportError: sys.path.insert(0, os.path.abspath(os.path.split(os.path.abspath(__file__))[0]+'/..')) import svgwrite if svgwrite.version < (1,0,1): print("This script requires svgwrite 1.0.1 or newer for internal stylesheets.") sys.exit() BOARD_WIDTH = "10cm" BOARD_HEIGHT = "10cm" BOARD_SIZE = (BOARD_WIDTH, BOARD_HEIGHT) CSS_STYLES = """ .background { fill: lavenderblush; } .line { stroke: firebrick; stroke-width: .1mm; } .blacksquare { fill: indigo; } .whitesquare { fill: hotpink; } """ def draw_board(dwg): def group(classname): return dwg.add(dwg.g(class_=classname)) # setup element groups lines = group("line") white_squares = group("whitesquare") black_squares = group("blacksquare") # draw lines for i in range(9): y = i * 10 lines.add(dwg.line(start=(0, y), end=(80, y))) x = i * 10 lines.add(dwg.line(start=(x, 0), end=(x, 80))) # draw squares for x in range(8): for y in range(8): xc = x * 10 + 1 yc = y * 10 + 1 square = dwg.rect(insert=(xc, yc), size=(8, 8)) (white_squares if (x+y) % 2 else black_squares).add(square) def main(): dwg = svgwrite.Drawing('checkerboard.svg', size=BOARD_SIZE) dwg.viewbox(0, 0, 80, 80) # checkerboard has a size of 10cm x 10cm; # defining a viewbox with the size of 80x80 means, that a length of 1 # is 10cm/80 == 0.125cm (which is for now the famous USER UNIT) # but I don't have to care about it, I just draw 8x8 squares, each 10x10 USER-UNITS # always use css for styling dwg.defs.add(dwg.style(CSS_STYLES)) # set background dwg.add(dwg.rect(size=('100%','100%'), class_='background')) draw_board(dwg) dwg.save() if __name__== '__main__': main() svgwrite-1.1.8/examples/defs_test.py0000666000000000000000000000572311762175602015713 0ustar 00000000000000import svgwrite PROGNAME = 'defs_test' STYLESHEET = PROGNAME + '.css' STYLES = """.red { fill: red; stroke=none; } .green { fill: green; stroke: none; } .blue { fill: blue; stroke: yellow; stroke-width: 5; } .yellow { fill: yellow; stroke: none; } .text { font-family: serif; fill: white; } """ def create_svg(name): svg_size_width = 900 svg_size_height = 900 font_size = 20 triangle_size = 50 title1 = name + ': Example of creating your own colors and defs/use.' dwg = svgwrite.Drawing(name, (svg_size_width, svg_size_height), debug=True) # To separate structure from visual presentation, better use stylesheets # inline stylesheets requires svgwrite version >= 1.0.1 # available at http://bitbucket.org/mozman/svgwrite if svgwrite.version >= (1, 0, 1): dwg.defs.add(dwg.style(STYLES)) else: # or use an external stylesheet with open(STYLESHEET, 'w') as f: f.write(STYLES) dwg.add_stylesheet(STYLESHEET, 'noname') # Background will be dark but not black so the background does not overwhelm the colors. dwg.add(dwg.rect(insert=(0, 0), size=('100%', '100%'), fill='grey')) # http://www.w3.org/TR/SVG11/struct.html#Head # "sometimes it is desired to define a graphical object and prevent it from being directly # rendered. it is only there to be referenced elsewhere. To do this, and to allow convenient # grouping defined content, SVG provides the 'defs' element." # 1. create template polygons half_size = triangle_size / 2 points = [ (-half_size, -half_size), (half_size, -half_size), (0, triangle_size * 0.433013) ] # 2. create the symbol symbol_without_fill = dwg.symbol(id='symbol_without_fill') # 3. add symbols to the defs section dwg.defs.add(symbol_without_fill) # 4. important: define viewbox of the symbol! symbol_without_fill.viewbox(-half_size, -half_size, triangle_size, triangle_size) # and define how the symbol should behave on resizing by # default parameters for fit(horiz="center", vert="middle", scale="meet") # seems not necessary # symbol_without_fill.fit() # 5. add triangles to the symbol containers symbol_without_fill.add(dwg.polygon(points)) # 6. use symbols - param size is necessary - and only unset params can be overwritten dwg.add(dwg.use(symbol_without_fill, insert=(200, 200), size=(triangle_size, triangle_size), class_='yellow')) dwg.add(dwg.use(symbol_without_fill, insert=(300, 300), size=(triangle_size*1.2, triangle_size*1.2), class_ ='red')) dwg.add(dwg.use(symbol_without_fill, insert=(400, 400), size=(triangle_size*0.5, triangle_size*0.5), class_ ='blue')) # Give the name of the example and a title. y = font_size + 5 dwg.add(dwg.text(title1, insert=(0, y), class_='text', font_size=font_size)) dwg.save() if __name__ == '__main__': create_svg(PROGNAME + '.svg') # vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 textwidth=99 svgwrite-1.1.8/examples/fePointLight.py0000666000000000000000000000206411465447402016322 0ustar 00000000000000try: import svgwrite except ImportError: # if svgwrite is not 'installed' append parent dir of __file__ to sys.path import sys, os sys.path.insert(0, os.path.abspath(os.path.split(os.path.abspath(__file__))[0]+'/..')) import svgwrite dwg = svgwrite.Drawing("fePointLight.svg") filtr = dwg.defs.add( dwg.filter(id="DL", start=(0, 0), size=(500, 500), filterUnits="userSpaceOnUse")) diffuse_lighting = filtr.feDiffuseLighting( start=(0, 0), size=(500, 500), surfaceScale=10, diffuseConstant=1, kernelUnitLength=1, lighting_color="#f8f") point_light = diffuse_lighting.fePointLight( (500, 250, 250) ) point_light.add( dwg.animate('x', values=(0,100,500,100,0), dur='30s', repeatDur='indefinite')) point_light.add( dwg.animate('y', values=(0,500,400,-100,0), dur='31s', repeatDur='indefinite')) point_light.add( dwg.animate('z', values=(0,1000,500,-100,0), dur='37s', repeatDur='indefinite')) dwg.save() svgwrite-1.1.8/examples/koch_snowflake.py0000666000000000000000000000703712012650560016716 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman # Purpose: svg examples # Created: 08.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License try: import svgwrite except ImportError: # if svgwrite is not 'installed' append parent dir of __file__ to sys.path import sys, os sys.path.insert(0, os.path.abspath(os.path.split(os.path.abspath(__file__))[0]+'/..')) import math import svgwrite def koch_snowflake(name): # Koch Snowflake and Sierpinski Triangle combination fractal using recursion # ActiveState Recipe 577156 # Created by FB36 on Sat, 27 Mar 2010 (MIT) # http://code.activestate.com/recipes/577156-koch-snowflake-and-sierpinski-triangle-combination/ def tf (x0, y0, x1, y1, x2, y2): a = math.sqrt((x1 - x0) ** 2 + (y1 - y0) ** 2) b = math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2) c = math.sqrt((x0 - x2) ** 2 + (y0 - y2) ** 2) if (a < stop_val) or (b < stop_val) or (c < stop_val): return x3 = (x0 + x1) / 2 y3 = (y0 + y1) / 2 x4 = (x1 + x2) / 2 y4 = (y1 + y2) / 2 x5 = (x2 + x0) / 2 y5 = (y2 + y0) / 2 points = [(x3, y3), (x4, y4), (x5, y5)] # append new polygon to snowflake element snowflake.add(dwg.polygon(points)) tf(x0, y0, x3, y3, x5, y5) tf(x3, y3, x1, y1, x4, y4) tf(x5, y5, x4, y4, x2, y2) def sf (ax, ay, bx, by): f = math.sqrt((bx - ax) ** 2 + (by - ay) ** 2) if f < 1.: return f3 = f / 3 cs = (bx - ax) / f sn = (by - ay) / f cx = ax + cs * f3 cy = ay + sn * f3 h = f3 * math.sqrt(3) / 2 dx = (ax + bx) / 2 + sn * h dy = (ay + by) / 2 - cs * h ex = bx - cs * f3 ey = by - sn * f3 tf(cx, cy, dx, dy, ex, ey) sf(ax, ay, cx, cy) sf(cx, cy, dx, dy) sf(dx, dy, ex, ey) sf(ex, ey, bx, by) # const values stop_val = 8. imgx = 512 imgy = 512 # create a new drawing dwg = svgwrite.Drawing(name, (imgx, imgy), profile='tiny', debug=True) # create a new element, we will insert the snowflake by the element # here we set stroke, fill and stroke-width for all subelements # attention: 'stroke-width' is not a valid Python identifier, so use 'stroke_witdth' # underlines '_' will be converted to dashes '-', this is true for all svg-keyword-attributs # if no 'id' is given ( like dwg.g(id="sflake") ), an automatic generated 'id' will be generated snowflake = dwg.g(stroke="blue", fill="rgb(90%,90%,100%)", stroke_width=0.25) # add the element to the element of the drawing dwg.defs.add(snowflake) mx2 = imgx / 2 my2 = imgy / 2 r = my2 a = 2 * math.pi / 3 for k in range(3): x0 = mx2 + r * math.cos(a * k) y0 = my2 + r * math.sin(a * k) x1 = mx2 + r * math.cos(a * (k + 1)) y1 = my2 + r * math.sin(a * (k + 1)) sf(x0, y0, x1, y1) x2 = mx2 + r * math.cos(a) y2 = my2 + r * math.sin(a) tf(x0, y0, x1, y1, x2, y2) # create an element use_snowflake = dwg.use(snowflake) # you can transform each element # use_snowflake.rotate(15, center=(imgx/2, imgy/2)) # insert snowflake by the element dwg.add(use_snowflake) # and save the drawing dwg.save() if __name__ == '__main__': koch_snowflake("koch_snowflake.svg") svgwrite-1.1.8/examples/linearGradient.py0000666000000000000000000000573712171414630016660 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman # Purpose: svg examples # Created: 08.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License try: import svgwrite except ImportError: # if svgwrite is not 'installed' append parent dir of __file__ to sys.path import sys, os sys.path.insert(0, os.path.abspath(os.path.split(os.path.abspath(__file__))[0]+'/..')) import svgwrite def linearGradient(name): dwg = svgwrite.Drawing(name, size=('20cm', '15cm'), profile='full', debug=True) # set user coordinate space dwg.viewbox(width=200, height=150) # create a new linearGradient element horizontal_gradient = dwg.linearGradient((0, 0), (1, 0)) vertical_gradient = dwg.linearGradient((0, 0), (0, 1)) diagonal_gradient = dwg.linearGradient((0, 0), (1, 1)) tricolor_gradient = dwg.linearGradient((0, 0), (1, 1)) # add gradient to the defs section of the drawing dwg.defs.add(horizontal_gradient) dwg.defs.add(vertical_gradient) dwg.defs.add(diagonal_gradient) dwg.defs.add(tricolor_gradient) # define the gradient from white to red horizontal_gradient.add_stop_color(0, 'white') horizontal_gradient.add_stop_color(1, 'red') # define the gradient from white to green vertical_gradient.add_stop_color(0, 'white') vertical_gradient.add_stop_color(1, 'green') # define the gradient from white to blue diagonal_gradient.add_stop_color(0, 'white') diagonal_gradient.add_stop_color(1, 'blue') # define the gradient from white to red to green to blue tricolor_gradient.add_stop_color(0, 'white') tricolor_gradient.add_stop_color(.33, 'red') tricolor_gradient.add_stop_color(.66, 'green') tricolor_gradient.add_stop_color(1, 'blue') # use gradient for filling the rect dwg.add(dwg.rect((10,10), (50,50), fill=horizontal_gradient.get_paint_server(default='currentColor'))) dwg.add(dwg.rect((70,10), (50,50), fill=vertical_gradient.get_paint_server(default='currentColor'))) dwg.add(dwg.rect((130,10), (50,50), fill=diagonal_gradient.get_paint_server(default='currentColor'))) dwg.add(dwg.rect((10,70), (50,50), fill=tricolor_gradient.get_paint_server(default='currentColor'))) # rotate gradient about 90 degree # first copy gradient tricolor2_gradient = tricolor_gradient.copy() # rotate the gradient tricolor2_gradient.rotate(90, (.5, .5)) # add gradient to the defs section of the drawing dwg.defs.add(tricolor2_gradient) # use the gradient dwg.add(dwg.rect((70,70), (50,50), fill=tricolor2_gradient.get_paint_server(default='currentColor'))) updown = dwg.linearGradient() dwg.defs.add(updown) updown.add_colors(['red', 'white', 'red', 'white', 'red'], sweep=(.2, .8)) dwg.add(dwg.rect((130,70), (50,50), fill=updown.get_paint_server(default='currentColor'))) dwg.save() if __name__ == '__main__': linearGradient("linearGradient.svg") svgwrite-1.1.8/examples/LSystem.py0000666000000000000000000000726112012650557015326 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman # Purpose: svg examples # Created: 08.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License try: import svgwrite except ImportError: # if svgwrite is not 'installed' append parent dir of __file__ to sys.path import sys, os sys.path.insert(0, os.path.abspath(os.path.split(os.path.abspath(__file__))[0]+'/..')) import math import svgwrite LevyDragon = {'length':1, 'numAngle':4, 'level':16, 'init': 'FX', 'target': 'X', 'replacement': 'X+YF+', 'target2': 'Y', 'replacement2': '-FX-Y'} KochSnowflake = {'length':1, 'numAngle':6, 'level':6, 'init': 'F++F++F', 'target': 'F', 'replacement': 'F-F++F-F', 'target2': '', 'replacement2': ''} LevyCurve = {'length':1, 'numAngle':8, 'level':17, 'init': 'F', 'target': 'F', 'replacement': '+F--F+', 'target2': '', 'replacement2': ''} HilbertSpaceFillingCurve = {'length':1, 'numAngle':4, 'level':5, 'init': 'L', 'target': 'L', 'replacement': '+RF-LFL-FR+', 'target2': 'R', 'replacement2': '-LF+RFR+FL-'} def LSystem(name, formula=LevyCurve): ## {{{ http://code.activestate.com/recipes/577159/ (r1) # L-System Fractals # FB - 201003276 # image size # generate the fractal drawing string def _LSystem(formula): state = formula['init'] target = formula['target'] replacement = formula['replacement'] target2 = formula['target2'] replacement2 = formula['replacement2'] level = formula['level'] for counter in range(level): state2 = '' for character in state: if character == target: state2 += replacement elif character == target2: state2 += replacement2 else: state2 += character state = state2 return state print("creating: %s\n" % name) xmin, ymin = (100000, 100000) xmax, ymax = (-100000, -100000) numAngle = formula['numAngle'] length = formula['length'] fractal = _LSystem(formula) na = 2.0 * math.pi / numAngle sn = [] cs = [] for i in range(numAngle): sn.append(math.sin(na * i)) cs.append(math.cos(na * i)) x = 0.0 y = 0.0 # jx = int((x - xa) / (xb - xa) * (imgx - 1)) # jy = int((y - ya) / (yb - ya) * (imgy - 1)) k = 0 dwg = svgwrite.Drawing(name, debug=True) curve = dwg.polyline(points=[(x, y)], stroke='green', fill='none', stroke_width=0.1) for ch in fractal: if ch == 'F': # turtle forward(length) x += length * cs[k] y += length * sn[k] curve.points.append( (x, y) ) # find maxima xmin = min(xmin, x) xmax = max(xmax, x) ymin = min(ymin, y) ymax = max(ymax, y) elif ch == '+': # turtle right(angle) k = (k + 1) % numAngle elif ch == '-': # turtle left(angle) k = ((k - 1) + numAngle) % numAngle print("L-System with %d segements.\n" % (len(curve.points)-1)) dwg.viewbox(xmin, ymin, xmax-xmin, ymax-ymin) dwg.add(curve) dwg.save() ## end of http://code.activestate.com/recipes/577159/ }}} if __name__ == '__main__': LSystem('lsys_hilbertspacefillingcurve.svg', formula=HilbertSpaceFillingCurve) LSystem('lsys_levydragon.svg', formula=LevyDragon) LSystem('lsys_levycurve.svg', formula=LevyCurve) LSystem('lsys_kochsnowflake.svg', formula=KochSnowflake) svgwrite-1.1.8/examples/ltattrie/0000777000000000000000000000000012723217123015173 5ustar 00000000000000svgwrite-1.1.8/examples/ltattrie/bezier.py0000666000000000000000000001727511763614230017044 0ustar 00000000000000#!/usr/bin/env python # Author: L. Tattrie # Purpose: svgwrite examples # Created: 2012/5/31 # Copyright (C) 2012, L. Tattrie # License: LGPL # Python version 2.7 import sys import svgwrite from itertools import * PROGNAME = sys.argv[0].rstrip('.py') # http://code.activestate.com/recipes/66472-frange-a-range-function-with-float-increments/ # but instead of parameter for float increments there is a parameter for n points. def nfrange(fstart, fstop, n): # n = number of points delta = (fstop - fstart) / n return [ fstart + delta * i for i in range(n) ] def create_svg(name): class bezier(object): def __init__(self, val_x, val_y): # The main point self.x = val_x self.y = val_y # control point before main point self.cbx = None self.cby = None # control point after main point self.cax = None self.cay = None def displayf(self): # display formatted with brackets and commas if self.cbx: self.s_cb = '({:f}, {:f})'.format(self.cbx, self.cby) else: self.s_cb = '(None, None)' if self.cax: self.s_ca = '({:f}, {:f})'.format(self.cax, self.cay) else: self.s_ca = ' (None, None)' return '({:s}, ({:f}, {:f}), {:s})'.format(self.s_cb, self.x, self.y, self.s_ca) def display(self): # display without formatted with brackets and commas if self.cbx: self.s_cb = '{:f} {:f}'.format(self.cbx, self.cby) else: self.s_cb = 'None None' if self.cax: self.s_ca = '{:f} {:f}'.format(self.cax, self.cay) else: self.s_ca = ' None None' return '{:s} {:f} {:f} {:s}'.format(self.s_cb, self.x, self.y, self.s_ca) svg_size = 900 font_size = 20 title = name + ': Example of Bezier curves' dwg = svgwrite.Drawing(name, (svg_size, svg_size), debug=True) # background will be white. dwg.add(dwg.rect(insert=(0, 0), size=('100%', '100%'), rx=None, ry=None, fill='white')) # give the name of the example and a title. dwg.add(dwg.text(title, insert=(0, (font_size + 5)), font_family="serif", font_size=font_size, fill='black')) # http://www.w3.org/TR/SVG11/paths.html # M=move to L=line to z=close path. # Uppercase means absolute coordinates, lowercase means relative coordinates # H=draw horizonal line V=draw vertical line # # C (absolute) c (relative) curveto (x1 y1 x2 y2 x y)+ # Draws a cubic Bezier curve from the current point to (x,y) using (x1,y1) as the control point at the beginning of the curve and (x2,y2) as the control point at the end of the curve. C (uppercase) indicates that absolute coordinates will follow; c (lowercase) indicates that relative coordinates will follow. Multiple sets of coordinates may be specified to draw a polybezier. At the end of the command, the new current point becomes the final (x,y) coordinate pair used in the polybezier. # S (absolute) s (relative) shorthand/smooth curveto (x2 y2 x y)+ # Draws a cubic Bezier curve from the current point to (x,y). The first control point is assumed to be the reflection of the second control point on the previous command relative to the current point. (If there is no previous command or if the previous command was not an C, c, S or s, assume the first control point is coincident with the current point.) (x2,y2) is the second control point (i.e., the control point at the end of the curve). S (uppercase) indicates that absolute coordinates will follow; s (lowercase) indicates that relative coordinates will follow. Multiple sets of coordinates may be specified to draw a polybezier. At the end of the command, the new current point becomes the final (x,y) coordinate pair used in the polybezier. # Q (absolute) q (relative) quadratic Bezier curveto (x1 y1 x y)+ # Draws a quadratic Bezier curve from the current point to (x,y) using (x1,y1) as the control point. Q (uppercase) indicates that absolute coordinates will follow; q (lowercase) indicates that relative coordinates will follow. Multiple sets of coordinates may be specified to draw a polybezier. At the end of the command, the new current point becomes the final (x,y) coordinate pair used in the polybezier. # T (absolute) t (relative) Shorthand/smooth quadratic Bezier curveto (x y)+ # Draws a quadratic Bezier curve from the current point to (x,y). The control point is assumed to be the reflection of the control point on the previous command relative to the current point. (If there is no previous command or if the previous command was not a Q, q, T or t, assume the control point is coincident with the current point.) T (uppercase) indicates that absolute coordinates will follow; t (lowercase) indicates that relative coordinates will follow. At the end of the command, the new current point becomes the final (x,y) coordinate pair used in the polybezier. # # Draw rectangle but with wiggly Bezier line. start = [50.0, 100.0] size = [200.0, 200.0] pts_per_side = 7 ctl_pt_weight = 2.50 # what weight is given to control point? (distance to next point) x ctl_pt_weight vert_pt_weight = .80 # what weight is given to vertical distance? (distance to next point) x vert_pt_weight plus_minus = cycle([1, -1]) # create iterator which alternates between +1 and -1 forever. # s1 = 'M {0[0]} {0[1]}'.format(start) p3 = dwg.path(d=s1, stroke_width=1, stroke='red', fill='none') # top left to top right l1 = nfrange(start[0], (start[0] + size[0]), 7) for item in l1: circle_3 = dwg.circle(center=(item, start[1]), r=3) circle_3.fill('green', opacity=0.5).stroke('black', width=1) dwg.add(circle_3) pm = next(plus_minus) l1l = [] for i, item in enumerate(l1): # Do not add the starting point because the starting point is given by the M command ## TODO: change the loop to have the starting point M done within the loop. if i != 0: # create control point for the previous point ctl_pt_dist = ctl_pt_weight * (item - l1[i - 1]) vert_dist_chg = vert_pt_weight * (item - l1[i - 1]) * pm # vertical distance off off straight line. l1l.append(l1[i - 1] + ctl_pt_dist) # x l1l.append(start[1] + vert_dist_chg) # y circle_1 = dwg.circle(center=(l1[i - 1] + ctl_pt_dist, start[1] + vert_dist_chg), r=1) circle_1.fill('blue', opacity=0.5).stroke('black', width=1) dwg.add(circle_1) pm = next(plus_minus) vert_dist_chg = vert_pt_weight * (item - l1[i - 1]) * pm # vertical distance off off straight line. # create control point for the current point l1l.append(item - ctl_pt_dist) # x l1l.append(start[1] + vert_dist_chg) # y circle_1 = dwg.circle(center=(item - ctl_pt_dist, start[1] + vert_dist_chg), r=1) circle_1.fill('purple', opacity=0.5).stroke('black', width=1) dwg.add(circle_1) # create the current point l1l.append(item) l1l.append(start[1] + vert_dist_chg) circle_3 = dwg.circle(center=(item, start[1] + vert_dist_chg), r=3) circle_3.fill('blue', opacity=0.5).stroke('black', width=1) dwg.add(circle_3) p3.push('C', l1l) dwg.add(p3) dwg.save() if __name__ == '__main__': create_svg(PROGNAME + '.svg') # vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 textwidth=99 svgwrite-1.1.8/examples/ltattrie/circle_blur.py0000666000000000000000000000356511763624071020052 0ustar 00000000000000import sys import svgwrite PROGNAME = sys.argv[0].rstrip('.py') def create_svg(name): SVG_SIZE = 900 FONT_SIZE = 20 title = name + ': Test to see if feGaussianBlur filter can be used.' dwg = svgwrite.Drawing(name, (SVG_SIZE, SVG_SIZE), debug=True) #myfilter = dwg.defs.add(dwg.filter(id="myfilter", filterUnits="userSpaceOnUse")) myfilter = dwg.defs.add(dwg.filter()) # the short way, using auto ids myfilter.feGaussianBlur(in_='SourceGraphic', stdDeviation=2) defs_g_text = dwg.defs.add(dwg.g(id='defs_g_text')) defs_g_text.add(dwg.text("SVGWRITE", insert=(0, 0), font_family="serif", font_size=FONT_SIZE)) # background will be white. dwg.add(dwg.rect(insert=(0, 0), size=('100%', '100%'), fill='white')) # give the name of the example and a title. y = FONT_SIZE + 5 dwg.add(dwg.text(title, insert=(0, y), font_family="serif", font_size=FONT_SIZE, fill='black')) y += 50 circle_1 = dwg.circle(center=(100, y), r=30) circle_1.fill('green', opacity=0.5).stroke('black', width=5).scale([2,2]) dwg.add(circle_1) # setting the filter attribute # at the constructor by filter=myfilter.get_funciri() # get_funciri() returns the string 'url(#myfilter)' for id='myfilter' y += 30 circle_2 = dwg.circle(center=(100, y), r=30, filter=myfilter.get_funciri()) circle_2.fill('green', opacity=0.5).stroke('black', width=5).scale([2,2]) # or by setting the 'filter' attribute of the circle_2 object # HINT: all svg attributes can be set by this way, but you have to use # the REAL svg-attribute-name like: 'font-size' or 'class' circle_2['filter'] = myfilter.get_funciri() dwg.add(circle_2) dwg.save() if __name__ == '__main__': create_svg(PROGNAME + '.svg') # vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 textwidth=99 svgwrite-1.1.8/examples/ltattrie/color_names.py0000666000000000000000000002017711763614266020071 0ustar 00000000000000#!/usr/bin/env python # Author: L. Tattrie # Purpose: svgwrite examples # Created: 2012/5/31 # Copyright (C) 2012, L. Tattrie # License: LGPL # Python version 2.7 import sys import svgwrite # # http://www.w3.org/TR/SVG11/types.html#ColorKeywords # Note both grey and gray are valid but only color not colour is valid. # PROGNAME = sys.argv[0].rstrip('.py') def create_svg(name): svg_size_width = 900 svg_size_height = 4500 font_size = 20 title1 = name + ': Example of svg predefined color names.' sample = ( ('aliceblue', 'rgb(240, 248, 255)'), ('antiquewhite', 'rgb(250, 235, 215)'), ('aqua', 'rgb( 0, 255, 255)'), ('aquamarine', 'rgb(127, 255, 212)'), ('azure', 'rgb(240, 255, 255)'), ('beige', 'rgb(245, 245, 220)'), ('bisque', 'rgb(255, 228, 196)'), ('black', 'rgb( 0, 0, 0)'), ('blanchedalmond', 'rgb(255, 235, 205)'), ('blue', 'rgb( 0, 0, 255)'), ('blueviolet', 'rgb(138, 43, 226)'), ('brown', 'rgb(165, 42, 42)'), ('burlywood', 'rgb(222, 184, 135)'), ('cadetblue', 'rgb( 95, 158, 160)'), ('chartreuse', 'rgb(127, 255, 0)'), ('chocolate', 'rgb(210, 105, 30)'), ('coral', 'rgb(255, 127, 80)'), ('cornflowerblue', 'rgb(100, 149, 237)'), ('cornsilk', 'rgb(255, 248, 220)'), ('crimson', 'rgb(220, 20, 60)'), ('cyan', 'rgb( 0, 255, 255)'), ('darkblue', 'rgb( 0, 0, 139)'), ('darkcyan', 'rgb( 0, 139, 139)'), ('darkgoldenrod', 'rgb(184, 134, 11)'), ('darkgray', 'rgb(169, 169, 169)'), ('darkgreen', 'rgb( 0, 100, 0)'), ('darkgrey', 'rgb(169, 169, 169)'), ('darkkhaki', 'rgb(189, 183, 107)'), ('darkmagenta', 'rgb(139, 0, 139)'), ('darkolivegreen', 'rgb( 85, 107, 47)'), ('darkorange', 'rgb(255, 140, 0)'), ('darkorchid', 'rgb(153, 50, 204)'), ('darkred', 'rgb(139, 0, 0)'), ('darksalmon', 'rgb(233, 150, 122)'), ('darkseagreen', 'rgb(143, 188, 143)'), ('darkslateblue', 'rgb( 72, 61, 139)'), ('darkslategray', 'rgb( 47, 79, 79)'), ('darkslategrey', 'rgb( 47, 79, 79)'), ('darkturquoise', 'rgb( 0, 206, 209)'), ('darkviolet', 'rgb(148, 0, 211)'), ('deeppink', 'rgb(255, 20, 147)'), ('deepskyblue', 'rgb( 0, 191, 255)'), ('dimgray', 'rgb(105, 105, 105)'), ('dimgrey', 'rgb(105, 105, 105)'), ('dodgerblue', 'rgb( 30, 144, 255)'), ('firebrick', 'rgb(178, 34, 34)'), ('floralwhite', 'rgb(255, 250, 240)'), ('forestgreen', 'rgb( 34, 139, 34)'), ('fuchsia', 'rgb(255, 0, 255)'), ('gainsboro', 'rgb(220, 220, 220)'), ('ghostwhite', 'rgb(248, 248, 255)'), ('gold', 'rgb(255, 215, 0)'), ('goldenrod', 'rgb(218, 165, 32)'), ('gray', 'rgb(128, 128, 128)'), ('grey', 'rgb(128, 128, 128)'), ('green', 'rgb( 0, 128, 0)'), ('greenyellow', 'rgb(173, 255, 47)'), ('honeydew', 'rgb(240, 255, 240)'), ('hotpink', 'rgb(255, 105, 180)'), ('indianred', 'rgb(205, 92, 92)'), ('indigo', 'rgb( 75, 0, 130)'), ('ivory', 'rgb(255, 255, 240)'), ('khaki', 'rgb(240, 230, 140)'), ('lavender', 'rgb(230, 230, 250)'), ('lavenderblush', 'rgb(255, 240, 245)'), ('lawngreen', 'rgb(124, 252, 0)'), ('lemonchiffon', 'rgb(255, 250, 205)'), ('lightblue', 'rgb(173, 216, 230)'), ('lightcoral', 'rgb(240, 128, 128)'), ('lightcyan', 'rgb(224, 255, 255)'), ('lightgoldenrodyellow', 'rgb(250, 250, 210)'), ('lightgray', 'rgb(211, 211, 211)'), ('lightgreen', 'rgb(144, 238, 144)'), ('lightgrey', 'rgb(211, 211, 211)'), ('lightpink', 'rgb(255, 182, 193)'), ('lightsalmon', 'rgb(255, 160, 122)'), ('lightseagreen', 'rgb( 32, 178, 170)'), ('lightskyblue', 'rgb(135, 206, 250)'), ('lightslategray', 'rgb(119, 136, 153)'), ('lightslategrey', 'rgb(119, 136, 153)'), ('lightsteelblue', 'rgb(176, 196, 222)'), ('lightyellow', 'rgb(255, 255, 224)'), ('lime', 'rgb( 0, 255, 0)'), ('limegreen', 'rgb( 50, 205, 50)'), ('linen', 'rgb(250, 240, 230)'), ('magenta', 'rgb(255, 0, 255)'), ('maroon', 'rgb(128, 0, 0)'), ('mediumaquamarine', 'rgb(102, 205, 170)'), ('mediumblue', 'rgb( 0, 0, 205)'), ('mediumorchid', 'rgb(186, 85, 211)'), ('mediumpurple', 'rgb(147, 112, 219)'), ('mediumseagreen', 'rgb( 60, 179, 113)'), ('mediumslateblue', 'rgb(123, 104, 238)'), ('mediumspringgreen', 'rgb( 0, 250, 154)'), ('mediumturquoise', 'rgb( 72, 209, 204)'), ('mediumvioletred', 'rgb(199, 21, 133)'), ('midnightblue', 'rgb( 25, 25, 112)'), ('mintcream', 'rgb(245, 255, 250)'), ('mistyrose', 'rgb(255, 228, 225)'), ('moccasin', 'rgb(255, 228, 181)'), ('navajowhite', 'rgb(255, 222, 173)'), ('navy', 'rgb( 0, 0, 128)'), ('oldlace', 'rgb(253, 245, 230)'), ('olive', 'rgb(128, 128, 0)'), ('olivedrab', 'rgb(107, 142, 35)'), ('orange', 'rgb(255, 165, 0)'), ('orangered', 'rgb(255, 69, 0)'), ('orchid', 'rgb(218, 112, 214)'), ('palegoldenrod', 'rgb(238, 232, 170)'), ('palegreen', 'rgb(152, 251, 152)'), ('paleturquoise', 'rgb(175, 238, 238)'), ('palevioletred', 'rgb(219, 112, 147)'), ('papayawhip', 'rgb(255, 239, 213)'), ('peachpuff', 'rgb(255, 218, 185)'), ('peru', 'rgb(205, 133, 63)'), ('pink', 'rgb(255, 192, 203)'), ('plum', 'rgb(221, 160, 221)'), ('powderblue', 'rgb(176, 224, 230)'), ('purple', 'rgb(128, 0, 128)'), ('red', 'rgb(255, 0, 0)'), ('rosybrown', 'rgb(188, 143, 143)'), ('royalblue', 'rgb( 65, 105, 225)'), ('saddlebrown', 'rgb(139, 69, 19)'), ('salmon', 'rgb(250, 128, 114)'), ('sandybrown', 'rgb(244, 164, 96)'), ('seagreen', 'rgb( 46, 139, 87)'), ('seashell', 'rgb(255, 245, 238)'), ('sienna', 'rgb(160, 82, 45)'), ('silver', 'rgb(192, 192, 192)'), ('skyblue', 'rgb(135, 206, 235)'), ('slateblue', 'rgb(106, 90, 205)'), ('slategray', 'rgb(112, 128, 144)'), ('slategrey', 'rgb(112, 128, 144)'), ('snow', 'rgb(255, 250, 250)'), ('springgreen', 'rgb( 0, 255, 127)'), ('steelblue', 'rgb( 70, 130, 180)'), ('tan', 'rgb(210, 180, 140)'), ('teal', 'rgb( 0, 128, 128)'), ('thistle', 'rgb(216, 191, 216)'), ('tomato', 'rgb(255, 99, 71)'), ('turquoise', 'rgb( 64, 224, 208)'), ('violet', 'rgb(238, 130, 238)'), ('wheat', 'rgb(245, 222, 179)'), ('white', 'rgb(255, 255, 255)'), ('whitesmoke', 'rgb(245, 245, 245)'), ('yellow', 'rgb(255, 255, 0)'), ('yellowgreen', 'rgb(154, 205, 50)') ) dwg = svgwrite.Drawing(name, (svg_size_width, svg_size_height), debug=True) # background will be a color not on the list so all listed colors will show. # Background will be dark but not black so the background does not overwhelm the colors. dwg.add(dwg.rect(insert=(0, 0), size=('100%', '100%'), fill='rgb(50,50,50)')) # give the name of the example and a title. dwg.add(dwg.text(title1, insert=(0, (font_size + 5)), font_family="serif", font_size=font_size, fill='white')) for i, sample_item in enumerate(sample): y_loc = 1.5 * font_size * (i + 2) dwg.add(dwg.rect(insert=(font_size, (y_loc - font_size)), size=(font_size, font_size), fill=sample_item[0])) dwg.add(dwg.text(sample_item[0] + " " + sample_item[1], insert=(3 * font_size, y_loc), font_family="serif", font_size=font_size, fill=sample_item[0])) dwg.save() if __name__ == '__main__': create_svg(PROGNAME + '.svg') # vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 textwidth=99 svgwrite-1.1.8/examples/ltattrie/color_triangles_function.py0000666000000000000000000000746211763614166022664 0ustar 00000000000000#!/usr/bin/env python # Author: L. Tattrie # Purpose: svgwrite examples # Created: 2012/5/31 # Copyright (C) 2012, L. Tattrie # License: LGPL # Python version 2.7 import math, sys import svgwrite from svgwrite import rgb # # http://www.w3.org/TR/SVG11/types.html#ColorKeywords # Note both grey and gray are valide but only color not colour is valid. # PROGNAME = sys.argv[0].rstrip('.py') def create_svg(name): WIDTH = 900 HEIGHT = 900 FONT_SIZE = 20 COMPLETE_SIZE = 800 # size of the whole set of triangles. TRIANGLES_PER_SIDE = 50 # How many triangles there will be per side. integer. TRIHEIGHT = math.sqrt(3)/2.0 title1 = name + ': Example of creating your own colors.' start = ((WIDTH - COMPLETE_SIZE)/2, (HEIGHT - COMPLETE_SIZE)/2) # center triangle #tri_color = ((255, 0, 0), (0, 255, 0), (0, 0, 255)) #tri_color = ((128, 0, 0), (0, 128, 0), (0, 0, 128)) tri_color = ((20, 128, 30), (10, 0, 50), (0, 0, 128)) dwg = svgwrite.Drawing(name, (WIDTH, HEIGHT), debug=True) def draw_triangle(insert, size, fill, rotate=None): x, y = insert points = [insert, (x + size, y), ((x + size / 2.0), (y + size * TRIHEIGHT))] triangle = dwg.add(dwg.polygon(points, fill=fill, stroke='none')) if rotate: triangle.rotate(rotate, center=insert) def nfrange(fstart, fstop, n): # n = number of points delta = (fstop - fstart) / n return [ fstart + delta * i for i in range(n) ] # Background will be dark but not black so the background does not overwhelm the colors. dwg.add(dwg.rect(insert=(0, 0), size=('100%', '100%'), fill='grey')) # Give the name of the example and a title. y = FONT_SIZE + 5 dwg.add(dwg.text(title1, insert=(0, y), font_family="serif", font_size=FONT_SIZE, fill='white')) tri_size = COMPLETE_SIZE / TRIANGLES_PER_SIDE tri_height = tri_size * TRIHEIGHT ratio_side = nfrange(0.0, 1.0, TRIANGLES_PER_SIDE) for i in range(TRIANGLES_PER_SIDE, 0, -1): # The number of triangle in the row is the sum of the point up and the point down # triangles. num_tri_in_row = 2 * i - 1 num_tri_drawn_in_row = 0 # Calculate color start_color = [int(tri_color[0][k] * ratio_side[i-1] + tri_color[2][k] * (1 - ratio_side[i-1])) for k in range(3)] end_color = [int(tri_color[1][k] * ratio_side[i-1] + tri_color[2][k] * (1 -ratio_side[i-1])) for k in range(3)] # calculate ratios of the two ending colors. ratio_row = nfrange(0.0, 1.0, num_tri_in_row) if num_tri_in_row > 1 else [0.5] for j in range(i): x = start[0] + (j + ((TRIANGLES_PER_SIDE - i) / 2.0)) * tri_size y = start[1] + (TRIANGLES_PER_SIDE - i) * tri_height # Calculate color new_color = [int(start_color[k] * (1 - ratio_row[num_tri_drawn_in_row ]) + end_color[k] * ratio_row[num_tri_drawn_in_row]) for k in range(3)] draw_triangle((x, y), tri_size, rgb(*new_color)) num_tri_drawn_in_row += 1 if j != (i - 1): # The on screen point up triangles have one fewer per row. x += tri_size # Calculate color new_color = [int(start_color[k] * (1 - ratio_row[num_tri_drawn_in_row ]) + end_color[k] * ratio_row[num_tri_drawn_in_row]) for k in range(3)] draw_triangle((x, y), tri_size, rgb(*new_color), rotate=60) num_tri_drawn_in_row += 1 dwg.save() if __name__ == '__main__': create_svg(PROGNAME + '.svg') # vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 textwidth=99 svgwrite-1.1.8/examples/ltattrie/length_units.py0000666000000000000000000000420511763614504020260 0ustar 00000000000000#!/usr/bin/env python # Author: L. Tattrie # Purpose: svgwrite examples # Created: 2012/5/31 # Copyright (C) 2012, L. Tattrie # License: LGPL # Python version 2.7 import sys import svgwrite # # http://www.w3.org/TR/SVG/coords.html#Units # The supported length unit identifiers are: em, ex, px, pt, pc, cm, mm, in, and percentages. # PROGNAME = sys.argv[0].rstrip('.py') def create_svg(name): SVG_SIZE = 900 FONT_SIZE = 20 title1 = name + ': Example of units of length' title2 = name + ': Example of class Unit and import from svgwrite cm, mm' sample = ( ('px', ' one user unit which may or may not be pixels. This is the default if no units are specified.'), ('pt', ' 1.25px.'), ('mm', ' 3.543307px.'), ('ex', " the current font's height of the character x."), ('%', ' percent of the size of the viewport.'), ('pc', ' 15px.'), ('em', " the current font's height."), ('cm', ' 35.43307px.'), ('in', ' 90px.') ) dwg = svgwrite.Drawing(name, (SVG_SIZE, SVG_SIZE)) # background will be white. dwg.add(dwg.rect(insert=(0, 0), size=('100%', '100%'), fill='white')) # give the name of the example and a title. y = FONT_SIZE + 5 x = 5 linespace = FONT_SIZE * 2 group = dwg.add(dwg.g(font_family="serif", font_size=FONT_SIZE, fill='black')) group.add(dwg.text(title1, insert=(x, y))) for i, sample_item in enumerate(sample): y += linespace unit = sample_item[0] group.add(dwg.rect(insert=(0, y), size=('1' + unit, '3px'), fill='red')) group.add(dwg.text("size='1%s': %s" % sample_item, insert=('2in', y+3))) # Show the use of class Unit y += linespace textlines = ( title2, 'The Unit class overrides the right hand multiply', '2*3*cm returns the string "6cm"' ) for txt in textlines: group.add(dwg.text(txt, insert=(x, y))) y += linespace dwg.save() if __name__ == '__main__': create_svg(PROGNAME + '.svg') # vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 textwidth=99 svgwrite-1.1.8/examples/ltattrie/line_cap_join.py0000666000000000000000000000516111763614512020347 0ustar 00000000000000#!/usr/bin/env python # Author: L. Tattrie # Purpose: svgwrite examples # Created: 2012/5/31 # Copyright (C) 2012, L. Tattrie # License: LGPL # Python version 2.7 import sys import svgwrite PROGNAME = sys.argv[0].rstrip('.py') def create_svg(name): svg_size = 900 font_size = 20 title = name + ': Example of stroke_linecap, stroke_linejoin' dwg = svgwrite.Drawing(name, (svg_size, svg_size), debug=True) # background will be white. dwg.add(dwg.rect(insert=(0, 0), size=('100%', '100%'), fill='white')) # give the name of the example and a title. text = dwg.add(dwg.g(font_family="sans-serif", font_size=font_size, fill='black')) lines = dwg.add(dwg.g(stroke_width=10, stroke='green', fill='none')) text.add(dwg.text(title, insert=(0, (font_size + 5)))) lines.add(dwg.line(start=(50, 100), end=(150, 100))) text.add(dwg.text("Default is butt", insert=('175', '100'))) lines.add(dwg.line(start=(50, 130), end=(150, 130), stroke_linecap='butt')) text.add(dwg.text("stroke_linecap='butt'", insert=('175', '130'))) lines.add(dwg.line(start=(50, 160), end=(150, 160), stroke_linecap='square')) text.add(dwg.text("stroke_linecap='square'", insert=('175', '160'))) lines.add(dwg.line(start=(50, 190), end=(150, 190), stroke_linecap='round')) text.add(dwg.text("stroke_linecap='round'", insert=('175', '190'))) lines.add(dwg.polyline([(50, 250), (50, 300), (75, 250), (100, 300), (120, 250), (150, 250), (150, 300)])) text.add(dwg.text("Default is miter", insert=('175', '280'))) lines.add(dwg.polyline([(50, 350), (50, 400), (75, 350), (100, 400), (120, 350), (150, 350), (150, 400)], stroke_linejoin='miter')) text.add(dwg.text("stroke_linejoin='miter'", insert=('175', '380'))) lines.add(dwg.polyline([(50, 450), (50, 500), (75, 450), (100, 500), (120, 450), (150, 450), (150, 500)], stroke_linejoin='bevel')) text.add(dwg.text("stroke_linejoin='bevel'", insert=('175', '480'))) lines.add(dwg.polyline([(50, 550), (50, 600), (75, 550), (100, 600), (120, 550), (150, 550), (150, 600)], stroke_linejoin='round')) text.add(dwg.text("stroke_linejoin='round'", insert=('175', '580'))) lines.add(dwg.polyline([(50, 650), (50, 700), (75, 650), (100, 700), (120, 650), (150, 650), (150, 700)], stroke_linejoin='round', stroke_linecap='round')) text.add(dwg.text("stroke_linejoin='round', stroke_linecap='round'", insert=('175', '680'))) dwg.save() if __name__ == '__main__': create_svg(PROGNAME + '.svg') # vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 textwidth=99 svgwrite-1.1.8/examples/ltattrie/rgb.txt0000666000000000000000000004545511545113535016526 0ustar 00000000000000cloudy blue #acc2d9 dark pastel green #56ae57 dust #b2996e electric lime #a8ff04 fresh green #69d84f light eggplant #894585 nasty green #70b23f really light blue #d4ffff tea #65ab7c warm purple #952e8f yellowish tan #fcfc81 cement #a5a391 dark grass green #388004 dusty teal #4c9085 grey teal #5e9b8a macaroni and cheese #efb435 pinkish tan #d99b82 spruce #0a5f38 strong blue #0c06f7 toxic green #61de2a windows blue #3778bf blue blue #2242c7 blue with a hint of purple #533cc6 booger #9bb53c bright sea green #05ffa6 dark green blue #1f6357 deep turquoise #017374 green teal #0cb577 strong pink #ff0789 bland #afa88b deep aqua #08787f lavender pink #dd85d7 light moss green #a6c875 light seafoam green #a7ffb5 olive yellow #c2b709 pig pink #e78ea5 deep lilac #966ebd desert #ccad60 dusty lavender #ac86a8 purpley grey #947e94 purply #983fb2 candy pink #ff63e9 light pastel green #b2fba5 boring green #63b365 kiwi green #8ee53f light grey green #b7e1a1 orange pink #ff6f52 tea green #bdf8a3 very light brown #d3b683 egg shell #fffcc4 eggplant purple #430541 powder pink #ffb2d0 reddish grey #997570 baby shit brown #ad900d liliac #c48efd stormy blue #507b9c ugly brown #7d7103 custard #fffd78 darkish pink #da467d deep brown #410200 greenish beige #c9d179 manilla #fffa86 off blue #5684ae battleship grey #6b7c85 browny green #6f6c0a bruise #7e4071 kelley green #009337 sickly yellow #d0e429 sunny yellow #fff917 azul #1d5dec darkgreen #054907 green/yellow #b5ce08 lichen #8fb67b light light green #c8ffb0 pale gold #fdde6c sun yellow #ffdf22 tan green #a9be70 burple #6832e3 butterscotch #fdb147 toupe #c7ac7d dark cream #fff39a indian red #850e04 light lavendar #efc0fe poison green #40fd14 baby puke green #b6c406 bright yellow green #9dff00 charcoal grey #3c4142 squash #f2ab15 cinnamon #ac4f06 light pea green #c4fe82 radioactive green #2cfa1f raw sienna #9a6200 baby purple #ca9bf7 cocoa #875f42 light royal blue #3a2efe orangeish #fd8d49 rust brown #8b3103 sand brown #cba560 swamp #698339 tealish green #0cdc73 burnt siena #b75203 camo #7f8f4e dusk blue #26538d fern #63a950 old rose #c87f89 pale light green #b1fc99 peachy pink #ff9a8a rosy pink #f6688e light bluish green #76fda8 light bright green #53fe5c light neon green #4efd54 light seafoam #a0febf tiffany blue #7bf2da washed out green #bcf5a6 browny orange #ca6b02 nice blue #107ab0 sapphire #2138ab greyish teal #719f91 orangey yellow #fdb915 parchment #fefcaf straw #fcf679 very dark brown #1d0200 terracota #cb6843 ugly blue #31668a clear blue #247afd creme #ffffb6 foam green #90fda9 grey/green #86a17d light gold #fddc5c seafoam blue #78d1b6 topaz #13bbaf violet pink #fb5ffc wintergreen #20f986 yellow tan #ffe36e dark fuchsia #9d0759 indigo blue #3a18b1 light yellowish green #c2ff89 pale magenta #d767ad rich purple #720058 sunflower yellow #ffda03 green/blue #01c08d leather #ac7434 racing green #014600 vivid purple #9900fa dark royal blue #02066f hazel #8e7618 muted pink #d1768f booger green #96b403 canary #fdff63 cool grey #95a3a6 dark taupe #7f684e darkish purple #751973 true green #089404 coral pink #ff6163 dark sage #598556 dark slate blue #214761 flat blue #3c73a8 mushroom #ba9e88 rich blue #021bf9 dirty purple #734a65 greenblue #23c48b icky green #8fae22 light khaki #e6f2a2 warm blue #4b57db dark hot pink #d90166 deep sea blue #015482 carmine #9d0216 dark yellow green #728f02 pale peach #ffe5ad plum purple #4e0550 golden rod #f9bc08 neon red #ff073a old pink #c77986 very pale blue #d6fffe blood orange #fe4b03 grapefruit #fd5956 sand yellow #fce166 clay brown #b2713d dark blue grey #1f3b4d flat green #699d4c light green blue #56fca2 warm pink #fb5581 dodger blue #3e82fc gross green #a0bf16 ice #d6fffa metallic blue #4f738e pale salmon #ffb19a sap green #5c8b15 algae #54ac68 bluey grey #89a0b0 greeny grey #7ea07a highlighter green #1bfc06 light light blue #cafffb light mint #b6ffbb raw umber #a75e09 vivid blue #152eff deep lavender #8d5eb7 dull teal #5f9e8f light greenish blue #63f7b4 mud green #606602 pinky #fc86aa red wine #8c0034 shit green #758000 tan brown #ab7e4c darkblue #030764 rosa #fe86a4 lipstick #d5174e pale mauve #fed0fc claret #680018 dandelion #fedf08 orangered #fe420f poop green #6f7c00 ruby #ca0147 dark #1b2431 greenish turquoise #00fbb0 pastel red #db5856 piss yellow #ddd618 bright cyan #41fdfe dark coral #cf524e algae green #21c36f darkish red #a90308 reddy brown #6e1005 blush pink #fe828c camouflage green #4b6113 lawn green #4da409 putty #beae8a vibrant blue #0339f8 dark sand #a88f59 purple/blue #5d21d0 saffron #feb209 twilight #4e518b warm brown #964e02 bluegrey #85a3b2 bubble gum pink #ff69af duck egg blue #c3fbf4 greenish cyan #2afeb7 petrol #005f6a royal #0c1793 butter #ffff81 dusty orange #f0833a off yellow #f1f33f pale olive green #b1d27b orangish #fc824a leaf #71aa34 light blue grey #b7c9e2 dried blood #4b0101 lightish purple #a552e6 rusty red #af2f0d lavender blue #8b88f8 light grass green #9af764 light mint green #a6fbb2 sunflower #ffc512 velvet #750851 brick orange #c14a09 lightish red #fe2f4a pure blue #0203e2 twilight blue #0a437a violet red #a50055 yellowy brown #ae8b0c carnation #fd798f muddy yellow #bfac05 dark seafoam green #3eaf76 deep rose #c74767 dusty red #b9484e grey/blue #647d8e lemon lime #bffe28 purple/pink #d725de brown yellow #b29705 purple brown #673a3f wisteria #a87dc2 banana yellow #fafe4b lipstick red #c0022f water blue #0e87cc brown grey #8d8468 vibrant purple #ad03de baby green #8cff9e barf green #94ac02 eggshell blue #c4fff7 sandy yellow #fdee73 cool green #33b864 pale #fff9d0 blue/grey #758da3 hot magenta #f504c9 greyblue #77a1b5 purpley #8756e4 baby shit green #889717 brownish pink #c27e79 dark aquamarine #017371 diarrhea #9f8303 light mustard #f7d560 pale sky blue #bdf6fe turtle green #75b84f bright olive #9cbb04 dark grey blue #29465b greeny brown #696006 lemon green #adf802 light periwinkle #c1c6fc seaweed green #35ad6b sunshine yellow #fffd37 ugly purple #a442a0 medium pink #f36196 puke brown #947706 very light pink #fff4f2 viridian #1e9167 bile #b5c306 faded yellow #feff7f very pale green #cffdbc vibrant green #0add08 bright lime #87fd05 spearmint #1ef876 light aquamarine #7bfdc7 light sage #bcecac yellowgreen #bbf90f baby poo #ab9004 dark seafoam #1fb57a deep teal #00555a heather #a484ac rust orange #c45508 dirty blue #3f829d fern green #548d44 bright lilac #c95efb weird green #3ae57f peacock blue #016795 avocado green #87a922 faded orange #f0944d grape purple #5d1451 hot green #25ff29 lime yellow #d0fe1d mango #ffa62b shamrock #01b44c bubblegum #ff6cb5 purplish brown #6b4247 vomit yellow #c7c10c pale cyan #b7fffa key lime #aeff6e tomato red #ec2d01 lightgreen #76ff7b merlot #730039 night blue #040348 purpleish pink #df4ec8 apple #6ecb3c baby poop green #8f9805 green apple #5edc1f heliotrope #d94ff5 yellow/green #c8fd3d almost black #070d0d cool blue #4984b8 leafy green #51b73b mustard brown #ac7e04 dusk #4e5481 dull brown #876e4b frog green #58bc08 vivid green #2fef10 bright light green #2dfe54 fluro green #0aff02 kiwi #9cef43 seaweed #18d17b navy green #35530a ultramarine blue #1805db iris #6258c4 pastel orange #ff964f yellowish orange #ffab0f perrywinkle #8f8ce7 tealish #24bca8 dark plum #3f012c pear #cbf85f pinkish orange #ff724c midnight purple #280137 light urple #b36ff6 dark mint #48c072 greenish tan #bccb7a light burgundy #a8415b turquoise blue #06b1c4 ugly pink #cd7584 sandy #f1da7a electric pink #ff0490 muted purple #805b87 mid green #50a747 greyish #a8a495 neon yellow #cfff04 banana #ffff7e carnation pink #ff7fa7 tomato #ef4026 sea #3c9992 muddy brown #886806 turquoise green #04f489 buff #fef69e fawn #cfaf7b muted blue #3b719f pale rose #fdc1c5 dark mint green #20c073 amethyst #9b5fc0 blue/green #0f9b8e chestnut #742802 sick green #9db92c pea #a4bf20 rusty orange #cd5909 stone #ada587 rose red #be013c pale aqua #b8ffeb deep orange #dc4d01 earth #a2653e mossy green #638b27 grassy green #419c03 pale lime green #b1ff65 light grey blue #9dbcd4 pale grey #fdfdfe asparagus #77ab56 blueberry #464196 purple red #990147 pale lime #befd73 greenish teal #32bf84 caramel #af6f09 deep magenta #a0025c light peach #ffd8b1 milk chocolate #7f4e1e ocher #bf9b0c off green #6ba353 purply pink #f075e6 lightblue #7bc8f6 dusky blue #475f94 golden #f5bf03 light beige #fffeb6 butter yellow #fffd74 dusky purple #895b7b french blue #436bad ugly yellow #d0c101 greeny yellow #c6f808 orangish red #f43605 shamrock green #02c14d orangish brown #b25f03 tree green #2a7e19 deep violet #490648 gunmetal #536267 blue/purple #5a06ef cherry #cf0234 sandy brown #c4a661 warm grey #978a84 dark indigo #1f0954 midnight #03012d bluey green #2bb179 grey pink #c3909b soft purple #a66fb5 blood #770001 brown red #922b05 medium grey #7d7f7c berry #990f4b poo #8f7303 purpley pink #c83cb9 light salmon #fea993 snot #acbb0d easter purple #c071fe light yellow green #ccfd7f dark navy blue #00022e drab #828344 light rose #ffc5cb rouge #ab1239 purplish red #b0054b slime green #99cc04 baby poop #937c00 irish green #019529 pink/purple #ef1de7 dark navy #000435 greeny blue #42b395 light plum #9d5783 pinkish grey #c8aca9 dirty orange #c87606 rust red #aa2704 pale lilac #e4cbff orangey red #fa4224 primary blue #0804f9 kermit green #5cb200 brownish purple #76424e murky green #6c7a0e wheat #fbdd7e very dark purple #2a0134 bottle green #044a05 watermelon #fd4659 deep sky blue #0d75f8 fire engine red #fe0002 yellow ochre #cb9d06 pumpkin orange #fb7d07 pale olive #b9cc81 light lilac #edc8ff lightish green #61e160 carolina blue #8ab8fe mulberry #920a4e shocking pink #fe02a2 auburn #9a3001 bright lime green #65fe08 celadon #befdb7 pinkish brown #b17261 poo brown #885f01 bright sky blue #02ccfe celery #c1fd95 dirt brown #836539 strawberry #fb2943 dark lime #84b701 copper #b66325 medium brown #7f5112 muted green #5fa052 robin's egg #6dedfd bright aqua #0bf9ea bright lavender #c760ff ivory #ffffcb very light purple #f6cefc light navy #155084 pink red #f5054f olive brown #645403 poop brown #7a5901 mustard green #a8b504 ocean green #3d9973 very dark blue #000133 dusty green #76a973 light navy blue #2e5a88 minty green #0bf77d adobe #bd6c48 barney #ac1db8 jade green #2baf6a bright light blue #26f7fd light lime #aefd6c dark khaki #9b8f55 orange yellow #ffad01 ocre #c69c04 maize #f4d054 faded pink #de9dac british racing green #05480d sandstone #c9ae74 mud brown #60460f light sea green #98f6b0 robin egg blue #8af1fe aqua marine #2ee8bb dark sea green #11875d soft pink #fdb0c0 orangey brown #b16002 cherry red #f7022a burnt yellow #d5ab09 brownish grey #86775f camel #c69f59 purplish grey #7a687f marine #042e60 greyish pink #c88d94 pale turquoise #a5fbd5 pastel yellow #fffe71 bluey purple #6241c7 canary yellow #fffe40 faded red #d3494e sepia #985e2b coffee #a6814c bright magenta #ff08e8 mocha #9d7651 ecru #feffca purpleish #98568d cranberry #9e003a darkish green #287c37 brown orange #b96902 dusky rose #ba6873 melon #ff7855 sickly green #94b21c silver #c5c9c7 purply blue #661aee purpleish blue #6140ef hospital green #9be5aa shit brown #7b5804 mid blue #276ab3 amber #feb308 easter green #8cfd7e soft blue #6488ea cerulean blue #056eee golden brown #b27a01 bright turquoise #0ffef9 red pink #fa2a55 red purple #820747 greyish brown #7a6a4f vermillion #f4320c russet #a13905 steel grey #6f828a lighter purple #a55af4 bright violet #ad0afd prussian blue #004577 slate green #658d6d dirty pink #ca7b80 dark blue green #005249 pine #2b5d34 yellowy green #bff128 dark gold #b59410 bluish #2976bb darkish blue #014182 dull red #bb3f3f pinky red #fc2647 bronze #a87900 pale teal #82cbb2 military green #667c3e barbie pink #fe46a5 bubblegum pink #fe83cc pea soup green #94a617 dark mustard #a88905 shit #7f5f00 medium purple #9e43a2 very dark green #062e03 dirt #8a6e45 dusky pink #cc7a8b red violet #9e0168 lemon yellow #fdff38 pistachio #c0fa8b dull yellow #eedc5b dark lime green #7ebd01 denim blue #3b5b92 teal blue #01889f lightish blue #3d7afd purpley blue #5f34e7 light indigo #6d5acf swamp green #748500 brown green #706c11 dark maroon #3c0008 hot purple #cb00f5 dark forest green #002d04 faded blue #658cbb drab green #749551 light lime green #b9ff66 snot green #9dc100 yellowish #faee66 light blue green #7efbb3 bordeaux #7b002c light mauve #c292a1 ocean #017b92 marigold #fcc006 muddy green #657432 dull orange #d8863b steel #738595 electric purple #aa23ff fluorescent green #08ff08 yellowish brown #9b7a01 blush #f29e8e soft green #6fc276 bright orange #ff5b00 lemon #fdff52 purple grey #866f85 acid green #8ffe09 pale lavender #eecffe violet blue #510ac9 light forest green #4f9153 burnt red #9f2305 khaki green #728639 cerise #de0c62 faded purple #916e99 apricot #ffb16d dark olive green #3c4d03 grey brown #7f7053 green grey #77926f true blue #010fcc pale violet #ceaefa periwinkle blue #8f99fb light sky blue #c6fcff blurple #5539cc green brown #544e03 bluegreen #017a79 bright teal #01f9c6 brownish yellow #c9b003 pea soup #929901 forest #0b5509 barney purple #a00498 ultramarine #2000b1 purplish #94568c puke yellow #c2be0e bluish grey #748b97 dark periwinkle #665fd1 dark lilac #9c6da5 reddish #c44240 light maroon #a24857 dusty purple #825f87 terra cotta #c9643b avocado #90b134 marine blue #01386a teal green #25a36f slate grey #59656d lighter green #75fd63 electric green #21fc0d dusty blue #5a86ad golden yellow #fec615 bright yellow #fffd01 light lavender #dfc5fe umber #b26400 poop #7f5e00 dark peach #de7e5d jungle green #048243 eggshell #ffffd4 denim #3b638c yellow brown #b79400 dull purple #84597e chocolate brown #411900 wine red #7b0323 neon blue #04d9ff dirty green #667e2c light tan #fbeeac ice blue #d7fffe cadet blue #4e7496 dark mauve #874c62 very light blue #d5ffff grey purple #826d8c pastel pink #ffbacd very light green #d1ffbd dark sky blue #448ee4 evergreen #05472a dull pink #d5869d aubergine #3d0734 mahogany #4a0100 reddish orange #f8481c deep green #02590f vomit green #89a203 purple pink #e03fd8 dusty pink #d58a94 faded green #7bb274 camo green #526525 pinky purple #c94cbe pink purple #db4bda brownish red #9e3623 dark rose #b5485d mud #735c12 brownish #9c6d57 emerald green #028f1e pale brown #b1916e dull blue #49759c burnt umber #a0450e medium green #39ad48 clay #b66a50 light aqua #8cffdb light olive green #a4be5c brownish orange #cb7723 dark aqua #05696b purplish pink #ce5dae dark salmon #c85a53 greenish grey #96ae8d jade #1fa774 ugly green #7a9703 dark beige #ac9362 emerald #01a049 pale red #d9544d light magenta #fa5ff7 sky #82cafc light cyan #acfffc yellow orange #fcb001 reddish purple #910951 reddish pink #fe2c54 orchid #c875c4 dirty yellow #cdc50a orange red #fd411e deep red #9a0200 orange brown #be6400 cobalt blue #030aa7 neon pink #fe019a rose pink #f7879a greyish purple #887191 raspberry #b00149 aqua green #12e193 salmon pink #fe7b7c tangerine #ff9408 brownish green #6a6e09 red brown #8b2e16 greenish brown #696112 pumpkin #e17701 pine green #0a481e charcoal #343837 baby pink #ffb7ce cornflower #6a79f7 blue violet #5d06e9 chocolate #3d1c02 greyish green #82a67d scarlet #be0119 green yellow #c9ff27 dark olive #373e02 sienna #a9561e pastel purple #caa0ff terracotta #ca6641 aqua blue #02d8e9 sage green #88b378 blood red #980002 deep pink #cb0162 grass #5cac2d moss #769958 pastel blue #a2bffe bluish green #10a674 green blue #06b48b dark tan #af884a greenish blue #0b8b87 pale orange #ffa756 vomit #a2a415 forrest green #154406 dark lavender #856798 dark violet #34013f purple blue #632de9 dark cyan #0a888a olive drab #6f7632 pinkish #d46a7e cobalt #1e488f neon purple #bc13fe light turquoise #7ef4cc apple green #76cd26 dull green #74a662 wine #80013f powder blue #b1d1fc off white #ffffe4 electric blue #0652ff dark turquoise #045c5a blue purple #5729ce azure #069af3 bright red #ff000d pinkish red #f10c45 cornflower blue #5170d7 light olive #acbf69 grape #6c3461 greyish blue #5e819d purplish blue #601ef9 yellowish green #b0dd16 greenish yellow #cdfd02 medium blue #2c6fbb dusty rose #c0737a light violet #d6b4fc midnight blue #020035 bluish purple #703be7 red orange #fd3c06 dark magenta #960056 greenish #40a368 ocean blue #03719c coral #fc5a50 cream #ffffc2 reddish brown #7f2b0a burnt sienna #b04e0f brick #a03623 sage #87ae73 grey green #789b73 white #ffffff robin's egg blue #98eff9 moss green #658b38 steel blue #5a7d9a eggplant #380835 light yellow #fffe7a leaf green #5ca904 light grey #d8dcd6 puke #a5a502 pinkish purple #d648d7 sea blue #047495 pale purple #b790d4 slate blue #5b7c99 blue grey #607c8e hunter green #0b4008 fuchsia #ed0dd9 crimson #8c000f pale yellow #ffff84 ochre #bf9005 mustard yellow #d2bd0a light red #ff474c cerulean #0485d1 pale pink #ffcfdc deep blue #040273 rust #a83c09 light teal #90e4c1 slate #516572 goldenrod #fac205 dark yellow #d5b60a dark grey #363737 army green #4b5d16 grey blue #6b8ba4 seafoam #80f9ad puce #a57e52 spring green #a9f971 dark orange #c65102 sand #e2ca76 pastel green #b0ff9d mint #9ffeb0 light orange #fdaa48 bright pink #fe01b1 chartreuse #c1f80a deep purple #36013f dark brown #341c02 taupe #b9a281 pea green #8eab12 puke green #9aae07 kelly green #02ab2e seafoam green #7af9ab blue green #137e6d khaki #aaa662 burgundy #610023 dark teal #014d4e brick red #8f1402 royal purple #4b006e plum #580f41 mint green #8fff9f gold #dbb40c baby blue #a2cffe yellow green #c0fb2d bright purple #be03fd dark red #840000 pale blue #d0fefe grass green #3f9b0b navy #01153e aquamarine #04d8b2 burnt orange #c04e01 neon green #0cff0c bright blue #0165fc rose #cf6275 light pink #ffd1df mustard #ceb301 indigo #380282 lime #aaff32 sea green #53fca1 periwinkle #8e82fe dark pink #cb416b olive green #677a04 peach #ffb07c pale green #c7fdb5 light brown #ad8150 hot pink #ff028d black #000000 lilac #cea2fd navy blue #001146 royal blue #0504aa beige #e6daa6 salmon #ff796c olive #6e750e maroon #650021 bright green #01ff07 dark purple #35063e mauve #ae7181 forest green #06470c aqua #13eac9 cyan #00ffff tan #d1b26f dark blue #00035b lavender #c79fef turquoise #06c2ac dark green #033500 violet #9a0eea light purple #bf77f6 lime green #89fe05 grey #929591 sky blue #75bbfd yellow #ffff14 magenta #c20078 light green #96f97b orange #f97306 teal #029386 light blue #95d0fc red #e50000 brown #653700 pink #ff81c0 blue #0343df green #15b01a purple #7e1e9c svgwrite-1.1.8/examples/ltattrie/runall.bat0000777000000000000000000000005411467443401017166 0ustar 00000000000000@echo off for %%e in (*.py) do python %%e svgwrite-1.1.8/examples/ltattrie/runall.sh0000666000000000000000000000010411465723167017033 0ustar 00000000000000#!/bin/sh for f in `ls *.py` do echo running $f ... python $f done svgwrite-1.1.8/examples/ltattrie/runall3.bat0000777000000000000000000000005511762040454017251 0ustar 00000000000000@echo off for %%e in (*.py) do python3 %%e svgwrite-1.1.8/examples/ltattrie/tenticles.py0000666000000000000000000003437511763614703017563 0ustar 00000000000000#!/usr/bin/env python # Author: L. Tattrie # Purpose: svgwrite examples # Created: 2012/5/31 # Copyright (C) 2012, L. Tattrie # License: LGPL # Python version 2.7 import math, sys import random import svgwrite # globals PROGNAME = sys.argv[0].rstrip('.py') file_log = '' dwg = '' def gen_colour(start_p, end_p, n_p): """ gen_colour generates a list of colours from start to end. Colours are linearly interpreted between start and end. start and end must be (int, int, int), n integer is how many colours are to be generated. """ c_start = start_p c_end = end_p n = n_p # yielding a c_end separately gives the exact c_end thus not something that is 99.99% c_end which is slightly off colour. for i in range(n): ccolour = (int(c_start[0] + (float(i) / float(n))*(c_end[0] - c_start[0])), int(c_start[1] + (float(i) / float(n))*(c_end[1] - c_start[1])), int(c_start[2] + (float(i) / float(n))*(c_end[2] - c_start[2]))) yield ccolour yield c_end def gen_incr_num(): i = 0 while True: i += 1 yield i unique_num = gen_incr_num() class tendrile: #global angle_max #global angle_min global file_log global dwg global unique_num def __init__(self, p_x, p_y, p_width, p_angle, p_step, p_v, p_curl, p_n, p_scolour, p_ecolour, p_can_branch): """tendrile class instance for each arm """ self.x = p_x self.y = p_y self.width = p_width #self.angle = max(min(p_angle, angle_max), angle_min) # limit value of angle self.angle_set(p_angle) # limit value of angle self.step = p_step self.v = p_v self.curl = p_curl self.n = p_n # length of tendrile self.scolour = p_scolour # starting colour self.ecolour = p_ecolour # ending colour self.can_branch = p_can_branch # Can tendrile branch? self.stroke_width = 1 self.lin_colour = gen_colour(self.scolour, self.ecolour, self.n) self.r = self.width # The purpose of having a group for all of the circles is be able to add all of the circles # of a tendrile to the drawing at the same time. If a tendrile branches, creating a new # tendrile the new tendrile will be drawn completely before the older tendrile is drawn. # This puts the new tendrile in the background and the old tendrile in front. When the # program had been written to start writting the old tendrile, write the new tendrile, then # finish the old tendrile there was a problem that slivers of some of the new tendrile's # colour was over top of the old tendrile causing a confusing mix of colour. # Using a group does create a small problem. The whole new tendrile is in the background of # the whole old tendrile. This is not perspectively correct because if a old tendrile # branches near the end of the tendrile the new tendrile should be in front of any part of # of the beginning part of the old tendrile but instead the new tendrile will be behind all # of the old tendrile. self.group = dwg.g(id='branch' + str(next(unique_num))) #file_log.write("new tend x="+ str(self.x)+ # " y="+str(self.y)+ # " width="+str(self.width)+ # " angle="+str(self.angle)+ # " step="+str(self.step)+ # " v="+str(self.v)+ # " curl="+str(self.curl)+ # " n="+str(self.n)+ # "\n") def angle_set(self, p_val): # limit the angle to range -2*math.pi to 2*math.pi which is +- full circle. # Use math.fmod because % returns with the sign of the second number. self.angle = math.fmod(p_val, (2 * math.pi)) def create(self): global file_log #green_light1 =(102, 229, 132) # starting colour. Colour will linearly change to ending colour. #green_dark1=(25, 76, 37) #v =0.0 #branch_at = (self.n * 1) / 10 for i in range(self.n): if i != 0: # if (i == 2) #random.randint(1, 100) #if (i == branch_at) and self.can_branch: if (random.randint(1, 100) == 1) and self.can_branch: distance = self.r * .8 # The new circle is % of the previouse circle's width x_temp = self.x + math.cos(self.angle) * distance y_temp = self.y + math.sin(self.angle) * distance # separate angles for branches #v_rand = 3*random.uniform(-self.step, self.step) #v_rand = random.uniform(-self.step, self.step) v_delta_split = math.pi / 31.4 # .05 degrees #v_rand = random.uniform(0.0, self.step) +math.pi/6.0 #30 degrees self.v = self.v + v_delta_split + random.uniform(-self.step, self.step) self.v *= 0.9 + self.curl * 0.1 #self.angle += self.v self.angle_set(self.angle + self.v) # limit value of angle #self.angle = max(min(self.angle, angle_max), angle_min) # limit value of angle # draw branch #tend = tendrile(x_temp, y_temp, self.r, angle_temp, self.step, self.v, (-1*self.curl), (self.n-i-1), new_colour, self.ecolour, False) #file_log.write("before new tend x="+ str(self.x)+ # " y="+str(self.y)+ # " r="+str(self.r)+ # " angle="+str(self.angle)+ # " step="+str(self.step)+ # " curl="+str(self.curl)+ # " i="+str(i)+ # " v="+str(self.v)+ # "\n") #file_log.write("******************************************************************"+ #"\n") ## Branch creating a new smaller tendrile #pink1=(251,170,176) # debug #tend = tendrile(x_temp, y_temp, self.r, self.angle, (self.step*1.2), (-1.0*self.v), self.curl, (self.n-i-1), green_dark1, green_light1, False) # create the tendrile # The use of the original colour, usually darker green, to start the new tendrile gives a slight look # of shadow on the the start of the new tendrile. It also gives a clear visual # separation between the existing tendrile and the new tendrile. tend = tendrile(x_temp, y_temp, self.r, self.angle, (self.step * 1.2), (-1.0 * self.v), self.curl, (self.n - i - 1), self.scolour, self.ecolour, False) # create the tendrile as svg elements tend.create() # draw the tendrile as svg elements tend.draw() #file_log.write("******************************************************************"+ #"\n") #file_log.write("after tend x="+ str(self.x)+ # " y="+str(self.y)+ # " r="+str(self.r)+ # " angle="+str(self.angle)+ # " step="+str(self.step)+ # " curl="+str(self.curl)+ # " i="+str(i)+ # " v="+str(self.v)+ # "\n") #self.v = self.v - v_rand -math.pi/6.0 # change angle of tendrile #self.v = self.v - v_rand #self.v *= 0.9 + self.curl*0.1 #self.angle += self.v self.x += math.cos(self.angle) * distance self.y += math.sin(self.angle) * distance # set up angle for next circle self.v += random.uniform(-self.step, self.step) self.v *= 0.9 + self.curl * 0.1 self.angle_set(self.angle + self.v) # limit value of angle #self.angle += self.v #self.angle = max(min(self.angle, angle_max), angle_min) # limit value of angle else: distance = self.r * .8 # The new circle is % of the previouse circle's width self.x += math.cos(self.angle) * distance self.y += math.sin(self.angle) * distance #file_log.write("tend x="+ str(self.x)+ # " y="+str(self.y)+ # " r="+str(self.r)+ # " angle="+str(self.angle)+ # " step="+str(self.step)+ # " curl="+str(self.curl)+ # " i="+str(i)+ # " v="+str(self.v)+ # "\n") self.v += random.uniform(-self.step, self.step) self.v *= 0.9 + self.curl * 0.1 #self.angle += self.v self.angle_set(self.angle + self.v) # limit value of angle #self.angle = max(min(self.angle, angle_max), angle_min) # limit value of angle self.r = (1 - float(i) / self.n) * self.width # radius size gradually decreases. ## new_colour = next(self.lin_colour) stroke_colour = 'rgb(%s,%s,%s)' % new_colour fill_colour = 'rgb(%s,%s,%s)' % new_colour self.group.add(dwg.circle(center=(self.x, self.y), r=self.r, fill=fill_colour, stroke=stroke_colour, stroke_width=3)) def draw(self): global file_log dwg.add(self.group) def create_svg(name): """ Create many circles in a curling tentril fashion. """ global file_log global dwg svg_size_width = 900 svg_size_height = 900 dwg = svgwrite.Drawing(name, (svg_size_width, svg_size_height), debug=True) # Background will be black so the background does not overwhelm the colors. dwg.add(dwg.rect(insert=(0, 0), size=('100%', '100%'), rx=None, ry=None, fill='black')) #angle_max = 2*math.pi # maximum angle allowed. 360 degrees. #angle_min = -1 * angle_max # minimum angle allowed -360 degrees. #file_log = open("tendriles_branch.log", "w") # Create effect instance and apply it. # option values. n = 100 # number of circles default 100 #n = 20 # number of circles default 100 num_arms = 5 # number of tendriles default 5 #num_arms = 10 # number of tendriles default 5 #num_arms = 1 # number of tendriles default 5 d_width = svg_size_width d_height = svg_size_height ########################### #x_org = d_height / 10 #y_org = d_width / 10 #delta_x = d_width / 6 #delta_y = d_width / 10 ########################### stroke_width = 1 #n = 200 #number of circles #n = 75 #number of circles #num_arms = 9 #step = 0.05 #step = 0.02 step = 4.0 / n #curl = 1.0 #c_width= d_width/12.0 #c_width= d_width/50.0 green_light1 = (102, 229, 132) # starting colour. Colour will linearly change to ending colour. green_dark1 = (25, 76, 37) salmon1 = (240, 184, 178) pink1 = (251, 170, 176) pink2 = (255, 170, 204) pink2light = (255, 215, 231) pink2dsat = (247, 225, 234) blue1 = (193, 197, 251) grey7_5 = (236, 236, 236) grey80 = (51, 51, 51) # starting colour. Colour will linearly change to ending colour. #start_colour = pink2light #end_colour = blue1 start_colour = green_dark1 end_colour = green_light1 #distance = 9.0 #distance = c_width/3.0 # The next circle is 1/3 the original circle's width from the centre. #n - number of circles in each tendrile. #num_arms - number of arms that is tendriles. # x, y - centre of current circle, 0,0 is top left of screen # c_width - initial circle width. # r - radius of current circle. gradually decreases. # distance - length to next circle. # angle - angle to next circle. value -pi to +pi. # step - range of randomness of angle. constant. # curl - how much curl will happen. constant. .1*curl incremented to v, angle. # v - change in angle. random value -step to +step plus curl # can_branch - true or false. Can this tendrile branch? can_branch = True #can_branch = False ########################### # The change in the starting colour is small so all of the tenticles seem like a group but # still have a very slight variation to give individuality. If the starting colour is too # different the arms look like they are not connected at the centre. #start_lin_colour = gen_colour(start_colour, blue1, num_arms) # debug start_lin_colour = gen_colour(start_colour, end_colour, num_arms * 8) # Create all tendriles for j in range(num_arms): # set start of arm x y x = d_height / 2 y = d_width / 2 angle = random.uniform((-1.0 * math.pi), math.pi) # random angle in radians. 2*pi radians = 360 degrees v = 0.0 # variety to the size of the starting circle c_width = random.uniform((d_width * .015), (d_width * .025)) r = random.uniform((c_width * .9), (c_width * 1.1)) new_start_colour = next(start_lin_colour) #curl = random.choice((-1, 1)) # random.choice picks random item from list #curl = random.choice((-1.1, 1.1)) # random.choice picks random item from list #curl = random.choice((-1.05, 1.05)) # random.choice picks random item from list #curl = 1.1 curl = 1.0 # create a tendrile tend = tendrile(x, y, r, angle, step, v, curl, n, new_start_colour, end_colour, can_branch) #tend = tendrile(x, y, r, angle, step, v, curl, n, blue1, end_colour, can_branch) # create the tendrile as svg elements tend.create() # draw the tendrile as svg elements tend.draw() #file_log.close() dwg.save() if __name__ == '__main__': create_svg(PROGNAME + '.svg') # vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 textwidth=99 svgwrite-1.1.8/examples/ltattrie/text_font_generic_family.py0000666000000000000000000000325511763614542022632 0ustar 00000000000000#!/usr/bin/env python # Author: L. Tattrie # Purpose: svgwrite examples # Created: 2012/5/31 # Copyright (C) 2012, L. Tattrie # License: LGPL # Python version 2.7 import sys import svgwrite # http://www.w3.org/TR/2008/REC-CSS2-20080411/fonts.html#propdef-font-family # 'serif', 'sans-serif', 'cursive', 'fantasy', and 'monospace' from the CSS specification PROGNAME = sys.argv[0].rstrip('.py') def create_svg(name): svg_size = 900 font_size = 20 title = name + ': Example of text using generic family fonts' font_family_sample = (('serif', 'have finishing strokes, flared or tapering ends.'), ('sans-serif', 'have stroke endings that are plain.'), ('cursive', 'the characters are partially or completely connected'), ('fantasy', ' primarily decorative characters.'), ('monospace', 'all characters have the same fixed width.')) dwg = svgwrite.Drawing(name, (svg_size, svg_size), debug=True) # background will be white. dwg.add(dwg.rect(insert=(0, 0), size=('100%', '100%'), fill='white')) # give the name of the example and a title. dwg.add(dwg.text(title, insert=(0, (font_size + 5)), font_family="serif", font_size=font_size, fill='black')) for i, font_family_item in enumerate(font_family_sample): dwg.add(dwg.text("font_family='" + font_family_item[0] + "': " + font_family_item[1], insert=(font_size, font_size * (i * 2 + 4)), font_family=font_family_item[0], font_size=font_size, fill='black')) dwg.save() if __name__ == '__main__': create_svg(PROGNAME + '.svg') # vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 textwidth=99 svgwrite-1.1.8/examples/ltattrie/text_font_size.py0000666000000000000000000000406411763614611020623 0ustar 00000000000000#!/usr/bin/env python # Author: L. Tattrie # Purpose: svgwrite examples # Created: 2012/5/31 # Copyright (C) 2012, L. Tattrie # License: LGPL # Python version 2.7 import sys import svgwrite PROGNAME = sys.argv[0].rstrip('.py') # http://www.w3.org/TR/2008/REC-CSS2-20080411/fonts.html#font-size-props def create_svg(name): svg_size = 900 font_size = 20 title = name + ': Example of text font_sizes' sample = (8, 10, 12, 15, 20, 30, 40, 50) dwg = svgwrite.Drawing(name, (svg_size, svg_size), debug=True) # background will be white. dwg.add(dwg.rect(insert=(0, 0), size=('100%', '100%'), fill='white')) # give the name of the example and a title. y = font_size + 5 dwg.add(dwg.text(title, insert=(0, y), font_family="serif", font_size=font_size, fill='black')) for i, item in enumerate(sample): # font_size has many properties and adjustments which can be done. See the web page listed # above for the complete description. y += item + 10 dwg.add(dwg.text("font_size='" + str(item) + "'", insert=(font_size, y), font_family="serif", font_size=item, fill='black')) y += font_size + 10 dwg.add(dwg.text('Since svg fonts are usually vectors, font_size can be very large.', insert=(0, y), font_family="serif", font_size=font_size, fill='black')) y += font_size + 10 # Show just the top of the single letter 'f'. The whole letter will not fit in the view area. dwg.add(dwg.text('Enlarged small parts of a character are like looking through a microscope. (font_size=4000)', insert=(0, y), font_family="serif", font_size=font_size, fill='black')) y += 2800 + 10 # Note the insert value of x is a negative number which is actually outside the view area. dwg.add(dwg.text('f', insert=(-1100, y), font_family="serif", font_size=4000, fill='black')) dwg.save() if __name__ == '__main__': create_svg(PROGNAME + '.svg') # vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 textwidth=99 svgwrite-1.1.8/examples/ltattrie/text_justify.py0000666000000000000000000000327411763614666020334 0ustar 00000000000000#!/usr/bin/env python # Author: L. Tattrie # Purpose: svgwrite examples # Created: 2012/5/31 # Copyright (C) 2012, L. Tattrie # License: LGPL # Python version 2.7 import sys import svgwrite PROGNAME = sys.argv[0].rstrip('.py') def create_svg(name): svg_size = 900 font_size = 20 title = name + ': Example of text_anchor (justified) text' dwg = svgwrite.Drawing(name, (svg_size, svg_size), debug=True) # background will be white. dwg.add(dwg.rect(insert=(0, 0), size=('100%', '100%'), fill='white')) # give the name of the example and a title. dwg.add(dwg.text(title, insert=(0, (font_size + 5)), font_family="serif", font_size=font_size, fill='black')) # Show default dwg.add(dwg.text("No specified text_anchor means 'start' justified text", insert=('50%', font_size * 3), font_family="sans-serif", font_size=font_size, fill='black')) # add a circle to show the anchor point printing on top of the text. dwg.add(dwg.circle(('50%', font_size * 3), r='3px', fill='red')) for i, anchor in enumerate(['start', 'end', 'middle']): # also 'inherit' which inherits from parent. dwg.add(dwg.text("text_anchor='" + anchor + "' means " + anchor + " justified text", insert=('50%', font_size * (i + 4)), text_anchor=anchor, font_family="sans-serif", font_size=font_size, fill='black')) # add a circle to show the anchor point printing on top of the text. dwg.add(dwg.circle(('50%', font_size * (i + 4)), r='3px', fill='red')) dwg.save() if __name__ == '__main__': create_svg(PROGNAME + '.svg') # vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 textwidth=99 svgwrite-1.1.8/examples/ltattrie/tiling_part_1.py0000666000000000000000000002377111763616021020316 0ustar 00000000000000#!/usr/bin/python # -*- coding: utf-8 -*- # Author: L. Tattrie # Purpose: svgwrite examples # Created: 2012/5/31 # Copyright (C) 2012, L. Tattrie # License: LGPL # Python version 2.7 import sys import svgwrite # http://www.w3.org/TR/SVG11/struct.html#UseElement # # For more information on tesselation / tiling see http://en.wikipedia.org/wiki/Wallpaper_group # The organization of these tilings are from the interesting book # Designing Testellations: The Secrets of Interlocking Patterns by Jinny Beyer. PROGNAME = sys.argv[0].rstrip('.py') def create_svg(name): svg_size_width = 900 svg_size_height = 2800 font_size = 20 square_size = 30 title1 = name + ': Part 1 tiling with multiple def, groups, use, translate and scale.' sample = () dwg = svgwrite.Drawing(name, (svg_size_width, svg_size_height), debug=True) # clip path to prevent drawing outside of tile # Having a clip path seems to increase the visibility of the lines between the tiles. # A clipping path may be necessary if the shapes go outside the triangle. # defs_g_kite = dwg.defs.add(dwg.g(id='defs_g_kite', clip_path='url(#clipkite)')) clip_path = dwg.defs.add(dwg.clipPath(id='clipsq')) # clip_path.add(dwg.circle((100, 100), 50)) clip_path.add(dwg.rect((0, 0), (square_size, square_size))) # define the group (tile) which will be repeated. defs_g = dwg.defs.add(dwg.g(id='defs_g', clip_path='url(#clipsq)')) defs_g.add(dwg.rect((0, 0), (square_size, square_size))) #defs_g.add(dwg.circle(center=(0, 5), r=6, stroke='blue', fill='green', stroke_width=1)) defs_g.add(dwg.ellipse(center=(5, 5), r=(5, 10), fill='green')) defs_g.add(dwg.polygon([(square_size / 2.0, 0), (square_size, square_size), (0, square_size)], stroke='none', fill='navy')) #defs_g.add(dwg.line(start=(0, 0), end=(square_size, square_size), stroke_width=2, stroke='black')) # Background will be dark but not black so the background does not overwhelm the colors. dwg.add(dwg.rect(insert=(0, 0), size=('100%', '100%'), rx=None, ry=None, fill='grey')) # Give the name of the example and a title. y = font_size + 5 dwg.add(dwg.text(title1, insert=(0, y), font_family='serif', font_size=font_size, fill='white')) y = y + font_size + 20 # show sample of tile sq_created = dwg.use(defs_g, insert=(10, y), fill='yellow') dwg.add(sq_created) y += square_size title2 = 'Translation, math name: p1' dwg.add(dwg.text(title2, insert=(50, y + square_size), font_family='serif', font_size=font_size, fill='white')) y = y + font_size for i in range(8): y += square_size for j in range(16): sq_created = dwg.use(defs_g, insert=(50 + j * square_size, y), fill='yellow') dwg.add(sq_created) y += square_size # p2 (180 rotation to side) title2 = '180 rotation to side, math name: p2' dwg.add(dwg.text(title2, insert=(50, y + square_size), font_family='serif', font_size=font_size, fill='white')) y = y + font_size for i in range(8): y += square_size for j in range(16): x = 50 + j * square_size sq_created = dwg.use(defs_g, insert=(x, y), fill='yellow') # rotate every second square if j % 2: sq_created.rotate(180, center=(x + square_size / 2.0, y + square_size / 2.0)) dwg.add(sq_created) y += square_size # p2 (180 rotation below) title2 = '180 rotation below, math name: p2' dwg.add(dwg.text(title2, insert=(50, y + square_size), font_family='serif', font_size=font_size, fill='white')) y = y + font_size for i in range(8): y += square_size for j in range(16): x = 50 + j * square_size sq_created = dwg.use(defs_g, insert=(x, y), fill='yellow') # rotate every second row if i % 2 == 1: sq_created.rotate(180, center=(x + square_size / 2.0, y + square_size / 2.0)) dwg.add(sq_created) y += square_size # p2 (180 rotation side, below, and diagonally) title2 = '180 rotation below, math name: p2' dwg.add(dwg.text(title2, insert=(50, y + square_size), font_family='serif', font_size=font_size, fill='white')) y = y + font_size for i in range(8): y += square_size for j in range(16): x = 50 + j * square_size sq_created = dwg.use(defs_g, insert=(x, y), fill='yellow') # rotate every second square if i % 2 != j % 2: sq_created.rotate(180, center=(x + square_size / 2.0, y + square_size / 2.0)) dwg.add(sq_created) y += square_size # p4 (90 rotation effectively rotating around the lower right corner.) title2 = '90 degree rotation around lower right, math name: p4' dwg.add(dwg.text(title2, insert=(50, y + square_size), font_family='serif', font_size=font_size, fill='white')) y = y + font_size for i in range(8): y += square_size for j in range(16): x = 50 + j * square_size sq_created = dwg.use(defs_g, insert=(x, y), fill='yellow') # rotate every second square if i % 2 == 1: # odd row if j % 2: sq_created.rotate(-90, center=(x + square_size / 2.0, y + square_size / 2.0)) else: sq_created.rotate(180, center=(x + square_size / 2.0, y + square_size / 2.0)) elif j % 2: sq_created.rotate(90, center=(x + square_size / 2.0, y + square_size / 2.0)) dwg.add(sq_created) y += square_size # p4 (90 rotation effectively rotating around the upper left corner.) title2 = '90 degree rotation around upper left, math name: p4' dwg.add(dwg.text(title2, insert=(50, y + square_size), font_family='serif', font_size=font_size, fill='white')) y = y + font_size for i in range(8): y += square_size for j in range(16): x = 50 + j * square_size sq_created = dwg.use(defs_g, insert=(x, y), fill='yellow') # rotate every second square if i % 2: # even row if j % 2: sq_created.rotate(180, center=(x + square_size / 2.0, y + square_size / 2.0)) else: sq_created.rotate(-90, center=(x + square_size / 2.0, y + square_size / 2.0)) elif j % 2: sq_created.rotate(90, center=(x + square_size / 2.0, y + square_size / 2.0)) dwg.add(sq_created) y += square_size # pg (moved horizontally then flipped vertically) # scale(1,-1) title2 = 'Glide: move horizontally then flip vertically, math name: pg' dwg.add(dwg.text(title2, insert=(50, y + square_size), font_family='serif', font_size=font_size, fill='white')) y = y + font_size for i in range(8): y += square_size for j in range(16): x = 50 + j * square_size sq_created = dwg.use(defs_g, fill='yellow') # flip vertically every second square if j % 2: # odd column 1, 3, 5 sq_created.translate(x, y + square_size) sq_created.scale(1, -1) else: # even column 0, 2, 4 sq_created.translate(x, y) dwg.add(sq_created) y += square_size # pg (moved vertically then flipped horizontally) title2 = 'Glide: move vertically then flip horizontally, math name: pg' dwg.add(dwg.text(title2, insert=(50, y + square_size), font_family='serif', font_size=font_size, fill='white')) y = y + font_size for i in range(8): y += square_size for j in range(16): x = 50 + j * square_size sq_created = dwg.use(defs_g, fill='yellow') # flip horizontally every second row if i % 2: # odd row 1, 3, 5 sq_created.translate(x + square_size, y) sq_created.scale(-1, 1) else: # even row 0, 2, 4 sq_created.translate(x, y) dwg.add(sq_created) y += square_size # pgg (moved horizontally then flipped vertically, moved vertically then flipped horizontally) title2 = 'Double Glide: Move vert, flip horiz. Move horiz flip vert. math name: pgg' dwg.add(dwg.text(title2, insert=(50, y + square_size), font_family='serif', font_size=font_size, fill='white')) y = y + font_size for i in range(8): y += square_size for j in range(16): x = 50 + j * square_size sq_created = dwg.use(defs_g, fill='yellow') if i % 2: # odd row 1, 3, 5 if j % 2: # odd column 1, 3, 5 # flip vertically and horizontally every second square sq_created.translate(x + square_size, y + square_size) sq_created.scale(-1, -1) else: # even column 0, 2, 4 # flip vertically every second square sq_created.translate(x + square_size, y) sq_created.scale(-1, 1) elif j % 2: # even row 0, 2, 4 # odd column 1, 3, 5 # flip vertically every second square but start with the first square sq_created.translate(x, y + square_size) sq_created.scale(1, -1) else: # even row 0, 2, 4 # even column 0, 2, 4 sq_created.translate(x, y) dwg.add(sq_created) dwg.save() if __name__ == '__main__': create_svg(PROGNAME + '.svg') # vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 textwidth=99 svgwrite-1.1.8/examples/ltattrie/tiling_part_2.py0000666000000000000000000002635711763616347020335 0ustar 00000000000000#!/usr/bin/python # -*- coding: utf-8 -*- import sys import svgwrite PROGNAME = sys.argv[0].rstrip('.py') # # http://www.w3.org/TR/SVG11/struct.html#UseElement # # For more information on tesselation / tiling see http://en.wikipedia.org/wiki/Wallpaper_group # The organization of these tilings are from the interesting book # Designing Testellations: The Secrets of Interlocking Patterns by Jinny Beyer. def create_svg(name): svg_size_width = 900 svg_size_height = 2200 font_size = 20 square_size = 30 title1 = name + ': Part 2 tiling with multiple def, groups, use, translate and scale.' sample = () dwg = svgwrite.Drawing(name, (svg_size_width, svg_size_height), debug=True) # Having a clip path seems to increase the visibility of the lines between the tiles. # A clipping path may be necessary if the shapes go outside the triangle. # clip path to prevent drawing outside of tile clip_path = dwg.defs.add(dwg.clipPath(id='clipsq')) clip_path.add(dwg.rect((0, 0), (square_size, square_size))) # define the group (tile) which will be repeated. defs_g = dwg.defs.add(dwg.g(id='defs_g', clip_path='url(#clipsq)')) defs_g.add(dwg.rect((0, 0), (square_size, square_size))) defs_g.add(dwg.circle(center=(0, 10), r=5, stroke='blue', fill='green', stroke_width=1)) defs_g.add(dwg.polygon([(square_size, 0), (square_size, square_size), (0, square_size)], stroke='none', fill='navy')) # Background will be dark but not black so the background does not overwhelm the colors. dwg.add(dwg.rect(insert=(0, 0), size=('100%', '100%'), fill='grey')) # Give the name of the example and a title. y = font_size + 5 dwg.add(dwg.text(title1, insert=(0, y), font_family='serif', font_size=font_size, fill='white')) y = y + font_size + 20 # Sample of tile. y = y + 20 sq_created = dwg.use(defs_g, insert=(10, y), fill='yellow') dwg.add(sq_created) y += square_size # pm (mirror horizontally) title2 = 'Mirror horizontally, math name: pm' dwg.add(dwg.text(title2, insert=(50, y + square_size), font_family='serif', font_size=font_size, fill='white')) y = y + font_size for i in range(8): y += square_size for j in range(16): x = 50 + j * square_size sq_created = dwg.use(defs_g, fill='yellow') # flip vertically every second square if j % 2: # odd column 1, 3, 5 sq_created.translate(x + square_size, y) sq_created.scale(-1, 1) else: # even column 0, 2, 4 sq_created.translate(x, y) dwg.add(sq_created) y = y + square_size # pm (mirror vertically) title2 = 'Mirror vertically, math name: pm' dwg.add(dwg.text(title2, insert=(50, y + square_size), font_family='serif', font_size=font_size, fill='white')) y = y + font_size for i in range(8): y += square_size for j in range(16): x = 50 + j * square_size sq_created = dwg.use(defs_g, fill='yellow') # flip vertically every second row if i % 2: # odd row 1, 3, 5 sq_created.translate(x, y + square_size) sq_created.scale(1, -1) else: # even row 0, 2, 4 sq_created.translate(x, y) dwg.add(sq_created) y += square_size # cm (move horizontally then mirror. That pair is then moved vertically and staggered.) title2 = 'Move horiz & mirror vert. Move vert & mirror vert, math name: cm' dwg.add(dwg.text(title2, insert=(50, y + square_size), font_family='serif', font_size=font_size, fill='white')) y = y + font_size for i in range(8): y += square_size for j in range(16): x = 50 + j * square_size sq_created = dwg.use(defs_g, fill='yellow') if i % 2: # odd row 1, 3, 5 if j % 2: # odd row 1, 3, 5 # odd column 1, 3, 5 sq_created.translate(x, y) else: # odd row 1, 3, 5 # even column 0, 2, 4 # flip vertically every second square sq_created.translate(x + square_size, y) sq_created.scale(-1, 1) elif j % 2: # even row 0, 2, 4 # odd column 1, 3, 5 # flip vertically every second square sq_created.translate(x + square_size, y) sq_created.scale(-1, 1) else: # even row 0, 2, 4 # even column 0, 2, 4 sq_created.translate(x, y) dwg.add(sq_created) y += square_size # cm (move vertically then mirror. That pair is then moved horizontally and staggered.) title2 = 'Move horiz & mirror horiz, Move vert & mirror horiz, math name: cm' dwg.add(dwg.text(title2, insert=(50, y + square_size), font_family='serif', font_size=font_size, fill='white')) y = y + font_size for i in range(8): y += square_size for j in range(16): x = 50 + j * square_size sq_created = dwg.use(defs_g, fill='yellow') if i % 2: # odd row 1, 3, 5 if j % 2: # odd row 1, 3, 5 # odd column 1, 3, 5 sq_created.translate(x, y) else: # odd row 1, 3, 5 # even column 0, 2, 4 # flip horizontally every second square sq_created.translate(x, y + square_size) sq_created.scale(1, -1) elif j % 2: # even row 0, 2, 4 # odd column 1, 3, 5 # flip horizontally every second square sq_created.translate(x, y + square_size) sq_created.scale(1, -1) else: # even row 0, 2, 4 # even column 0, 2, 4 sq_created.translate(x, y) dwg.add(sq_created) y += square_size # pmg (moved horizontally flip vertically. That pair is then moved vertically, mirrored and # staggered.) title2 = 'Move horiz mirror horiz. Pair is glided horiz and mirrored horiz, math name: pmg' dwg.add(dwg.text(title2, insert=(50, y + square_size), font_family='serif', font_size=font_size, fill='white')) y = y + font_size for i in range(8): y += square_size for j in range(16): x = 50 + j * square_size sq_created = dwg.use(defs_g, fill='yellow') if i % 2: # odd row 1, 3, 5 if j % 2: # odd row 1, 3, 5 # odd column 1, 3, 5 # flip horizontally every second square sq_created.translate(x, y + square_size) sq_created.scale(1, -1) else: # odd row 1, 3, 5 # even column 0, 2, 4 # flip vertically and horizontally every second square sq_created.translate(x + square_size, y + square_size) sq_created.scale(-1, -1) elif j % 2: # even row 0, 2, 4 # odd column 1, 3, 5 # flip vertically every second square sq_created.translate(x + square_size, y) sq_created.scale(-1, 1) else: # even row 0, 2, 4 # even column 0, 2, 4 sq_created.translate(x, y) dwg.add(sq_created) y += square_size # pmg (moved vertically flip horizontally. That pair is then moved horizontally, mirrored and # staggered.) title2 = 'Move vert mirror vert. Pair is glided vert and mirrored horiz, math name: pmg' dwg.add(dwg.text(title2, insert=(50, y + square_size), font_family='serif', font_size=font_size, fill='white')) y = y + font_size for i in range(8): y += square_size for j in range(16): x = 50 + j * square_size sq_created = dwg.use(defs_g, fill='yellow') if i % 2: # odd row 1, 3, 5 if j % 2: # odd row 1, 3, 5 # odd column 1, 3, 5 # flip vertically every second square sq_created.translate(x + square_size, y) sq_created.scale(-1, 1) else: # odd row 1, 3, 5 # even column 0, 2, 4 # flip horizontally every second square sq_created.translate(x, y + square_size) sq_created.scale(1, -1) elif j % 2: # even row 0, 2, 4 # odd column 1, 3, 5 # flip vertically and horizontally every second square sq_created.translate(x + square_size, y + square_size) sq_created.scale(-1, -1) else: # even row 0, 2, 4 # even column 0, 2, 4 sq_created.translate(x, y) dwg.add(sq_created) y += square_size # pmm (as if mirrors were placed on all sides of square and diagonally.) title2 = 'Mirror all sides, math name: pm' dwg.add(dwg.text(title2, insert=(50, y + square_size), font_family='serif', font_size=font_size, fill='white')) y = y + font_size for i in range(8): y += square_size for j in range(16): x = 50 + j * square_size sq_created = dwg.use(defs_g, fill='yellow') if i % 2: # odd row 1, 3, 5 if j % 2: # odd row 1, 3, 5 # odd column 1, 3, 5 # flip vertically and horizontally every second square sq_created.translate(x + square_size, y + square_size) sq_created.scale(-1, -1) else: # odd row 1, 3, 5 # even column 0, 2, 4 # flip horizontally every second square sq_created.translate(x, y + square_size) sq_created.scale(1, -1) elif j % 2: # even row 0, 2, 4 # odd column 1, 3, 5 # flip vertically every second square sq_created.translate(x + square_size, y) sq_created.scale(-1, 1) else: # even row 0, 2, 4 # even column 0, 2, 4 sq_created.translate(x, y) dwg.add(sq_created) # All items have been added so save the svg to a the file. dwg.save() if __name__ == '__main__': create_svg(PROGNAME + '.svg') # vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 textwidth=99 svgwrite-1.1.8/examples/ltattrie/tiling_part_3.py0000666000000000000000000003772011763616406020326 0ustar 00000000000000#!/usr/bin/python # -*- coding: utf-8 -*- import sys import svgwrite # http://www.w3.org/TR/SVG11/struct.html#UseElement # # For more information on tesselation / tiling see http://en.wikipedia.org/wiki/Wallpaper_group # The organization of these tilings are from the interesting book # Designing Testellations: The Secrets of Interlocking Patterns by Jinny Beyer. PROGNAME = sys.argv[0].rstrip('.py') def create_svg(name): svg_size_width = 900 svg_size_height = 2000 font_size = 20 square_size = 30 title1 = name + ': Part 3 tiling with multiple def, groups, use, translate and scale.' sample = () dwg = svgwrite.Drawing(name, (svg_size_width, svg_size_height), debug=True) # clip path to prevent drawing outside of tile clip_path = dwg.defs.add(dwg.clipPath(id='clipsq')) # clip_path.add(dwg.circle((100, 100), 50)) clip_path.add(dwg.rect((0, 0), (square_size, square_size))) # define the group (tile) which will be repeated. defs_g = dwg.defs.add(dwg.g(id='defs_g', clip_path='url(#clipsq)')) # defs_g.add(dwg.rect((0,0), (square_size, square_size))) defs_g.add(dwg.rect((0, 0), (square_size, square_size))) defs_g.add(dwg.circle(center=(0, 10), r=5, stroke='blue', fill='green', stroke_width=1)) defs_g.add(dwg.polygon([(square_size, 0), (square_size, square_size), (0, square_size)], stroke='none', fill='navy')) # Background will be dark but not black so the background does not overwhelm the colors. dwg.add(dwg.rect(insert=(0, 0), size=('100%', '100%'), rx=None, ry=None, fill='grey')) # Give the name of the example and a title. y = font_size + 5 dwg.add(dwg.text(title1, insert=(0, y), font_family='serif', font_size=font_size, fill='white')) y = y + font_size # # Sample of tile. y = y + 20 sq_created = dwg.use(defs_g, insert=(10, y), fill='yellow') dwg.add(sq_created) y += square_size # cmm variation 1 (as if mirrors were placed on all sides of square and diagonally.) # similar to pmm but the group of four tiles will be mirrored, staggered, or centered. title2 = 'Mirror all sides, then all are moved, variation 1, math name: cmm' dwg.add(dwg.text(title2, insert=(50, y + square_size), font_family='serif', font_size=font_size, fill='white')) y = y + font_size for i in range(8): y += square_size for j in range(16): x = 50 + j * square_size sq_created = dwg.use(defs_g, fill='yellow') if i % 2: # row 1, 3, 5 if j % 4 == 0: # column 0, 4, 8 # flip horizontally sq_created.translate(x, y + square_size) sq_created.scale(1, -1) elif j % 4 == 1: # column 1, 5, 9 # flip vertically and horizontally sq_created.translate(x + square_size, y + square_size) sq_created.scale(-1, -1) elif j % 4 == 2: # column 2, 6, 10 sq_created.translate(x, y) else: # column 3, 7, 11 # flip vertically sq_created.translate(x + square_size, y) sq_created.scale(-1, 1) else: # row 0, 2, 4 if j % 4 == 0: # column 0, 4, 8 sq_created.translate(x, y) elif j % 4 == 1: # column 1, 5, 9 # flip vertically sq_created.translate(x + square_size, y) sq_created.scale(-1, 1) elif j % 4 == 2: # column 2, 6, 10 # flip horizontally sq_created.translate(x, y + square_size) sq_created.scale(1, -1) else: # column 3, 7, 11 # flip vertically and horizontally sq_created.translate(x + square_size, y + square_size) sq_created.scale(-1, -1) dwg.add(sq_created) y += square_size # cmm variation 2 (as if mirrors were placed on all sides of square and diagonally.) # similar to pmm but the group of four tiles will be mirrored, staggered, or centered. title2 = 'Mirror all sides, then all are moved, variation 2, math name: cmm' dwg.add(dwg.text(title2, insert=(50, y + square_size), font_family='serif', font_size=font_size, fill='white')) y = y + font_size for i in range(8): y += square_size for j in range(16): x = 50 + j * square_size sq_created = dwg.use(defs_g, fill='yellow') if i % 2: # row 1, 3, 5 if j % 4 == 0: # column 0, 4, 8 # flip horizontally sq_created.translate(x, y + square_size) sq_created.scale(1, -1) elif j % 4 == 1: # column 1, 5, 9 sq_created.translate(x, y) elif j % 4 == 2: # column 2, 6, 10 # flip vertically and horizontally sq_created.translate(x + square_size, y + square_size) sq_created.scale(-1, -1) else: # column 3, 7, 11 # flip horizontally sq_created.translate(x, y + square_size) sq_created.scale(1, -1) else: # row 0, 2, 4 if j % 4 == 0: # column 0, 4, 8 # flip vertically and horizontally sq_created.translate(x + square_size, y + square_size) sq_created.scale(-1, -1) elif j % 4 == 1: # column 1, 5, 9 # flip horizontally sq_created.translate(x, y + square_size) sq_created.scale(1, -1) elif j % 4 == 2: # column 2, 6, 10 # flip vertically sq_created.translate(x + square_size, y) sq_created.scale(-1, 1) else: # column 3, 7, 11 sq_created.translate(x, y) dwg.add(sq_created) y += square_size # Instead of writing the p4g four times this code would have been better if it had been # put into a function and called indicating which corner is to be used for rotation. # p4g variation 1 (mirrored pinwheel which depending on which corner is the rotation center.) # lower right is the rotation corner defs_g_p4g_v1_size = square_size * 2 defs_g_lr_90 = dwg.defs.add(dwg.g(id='defs_g_lr_90')) defs_g_lr_90.add(dwg.use(defs_g, insert=(0, 0))) defs_g_lr_90.rotate(90, center=(square_size, square_size)) defs_g_lr_m90 = dwg.defs.add(dwg.g(id='defs_g_lr_m90')) defs_g_lr_m90.add(dwg.use(defs_g, insert=(0, 0))) defs_g_lr_m90.rotate(-90, center=(square_size, square_size)) defs_g_lr_180 = dwg.defs.add(dwg.g(id='defs_g_lr_180')) defs_g_lr_180.add(dwg.use(defs_g, insert=(0, 0))) defs_g_lr_180.rotate(180, center=(square_size, square_size)) defs_g_p4g_v1 = dwg.defs.add(dwg.g(id='defs_g_p4g_v1')) defs_g_p4g_v1.add(dwg.use(defs_g, insert=(0, 0))) defs_g_p4g_v1.add(dwg.use(defs_g_lr_90, insert=(0, 0))) defs_g_p4g_v1.add(dwg.use(defs_g_lr_m90, insert=(0, 0))) defs_g_p4g_v1.add(dwg.use(defs_g_lr_180, insert=(0, 0))) title2 = 'Mirrored pinwheel, rotate lower right, math name: p4g' dwg.add(dwg.text(title2, insert=(50, y + square_size), font_family='serif', font_size=font_size, fill='white')) # y = y + font_size for i in range(4): y += defs_g_p4g_v1_size for j in range(8): x = 50 + j * defs_g_p4g_v1_size sq_created = dwg.use(defs_g_p4g_v1, fill='yellow') if i % 2: # row 1, 3, 5 if j % 2: # column 1, 3, 5 sq_created.translate(x, y) else: # column 0, 2, 4 # flip horizontally sq_created.translate(x, y + defs_g_p4g_v1_size) sq_created.scale(1, -1) else: # row 0, 2, 4 if j % 2: # column 1, 3, 5 # flip vertically sq_created.translate(x + defs_g_p4g_v1_size, y) sq_created.scale(-1, 1) else: # column 0, 2, 4 sq_created.translate(x, y) dwg.add(sq_created) y += defs_g_p4g_v1_size # p4g variation 2 (mirrored pinwheel which depending on which corner is the rotation center.) # upper right is the rotation corner title2 = 'Mirrored pinwheel, rotate upper right, math name: p4g' dwg.add(dwg.text(title2, insert=(50, y + square_size), font_family='serif', font_size=font_size, fill='white')) # y = y + font_size defs_g_p4g_v2_size = square_size * 2 defs_g_ur_90 = dwg.defs.add(dwg.g(id='defs_g_ur_90')) defs_g_ur_90.add(dwg.use(defs_g, insert=(0, 0))) defs_g_ur_90.rotate(90, center=(square_size, 0)) defs_g_ur_m90 = dwg.defs.add(dwg.g(id='defs_g_ur_m90')) defs_g_ur_m90.add(dwg.use(defs_g, insert=(0, 0))) defs_g_ur_m90.rotate(-90, center=(square_size, 0)) defs_g_ur_180 = dwg.defs.add(dwg.g(id='defs_g_ur_180')) defs_g_ur_180.add(dwg.use(defs_g, insert=(0, 0))) defs_g_ur_180.rotate(180, center=(square_size, 0)) defs_g_p4g_v2 = dwg.defs.add(dwg.g(id='defs_g_p4g_v2')) defs_g_p4g_v2.add(dwg.use(defs_g, insert=(0, square_size))) defs_g_p4g_v2.add(dwg.use(defs_g_ur_90, insert=(0, square_size))) defs_g_p4g_v2.add(dwg.use(defs_g_ur_m90, insert=(0, square_size))) defs_g_p4g_v2.add(dwg.use(defs_g_ur_180, insert=(0, square_size))) for i in range(4): y += defs_g_p4g_v2_size for j in range(8): x = 50 + j * defs_g_p4g_v2_size sq_created = dwg.use(defs_g_p4g_v2, fill='yellow') if i % 2: # row 1, 3, 5 if j % 2: # column 1, 3, 5 sq_created.translate(x, y) else: # column 0, 2, 4 # flip horizontally sq_created.translate(x, y + defs_g_p4g_v2_size) sq_created.scale(1, -1) else: # row 0, 2, 4 if j % 2: # column 1, 3, 5 # flip vertically sq_created.translate(x + defs_g_p4g_v2_size, y) sq_created.scale(-1, 1) else: # column 0, 2, 4 sq_created.translate(x, y) dwg.add(sq_created) y += defs_g_p4g_v2_size # p4g variation 3 (mirrored pinwheel which depending on which corner is the rotation center.) # upper left is the rotation corner defs_g_p4g_v3_size = square_size * 2 defs_g_ul_90 = dwg.defs.add(dwg.g(id='defs_g_ul_90')) defs_g_ul_90.add(dwg.use(defs_g, insert=(0, 0))) defs_g_ul_90.rotate(90, center=(0, 0)) defs_g_ul_m90 = dwg.defs.add(dwg.g(id='defs_g_ul_m90')) defs_g_ul_m90.add(dwg.use(defs_g, insert=(0, 0))) defs_g_ul_m90.rotate(-90, center=(0, 0)) defs_g_ul_180 = dwg.defs.add(dwg.g(id='defs_g_ul_180')) defs_g_ul_180.add(dwg.use(defs_g, insert=(0, 0))) defs_g_ul_180.rotate(180, center=(0, 0)) defs_g_p4g_v3 = dwg.defs.add(dwg.g(id='defs_g_p4g_v3')) defs_g_p4g_v3.add(dwg.use(defs_g, insert=(square_size, square_size))) defs_g_p4g_v3.add(dwg.use(defs_g_ul_90, insert=(square_size, square_size))) defs_g_p4g_v3.add(dwg.use(defs_g_ul_m90, insert=(square_size, square_size))) defs_g_p4g_v3.add(dwg.use(defs_g_ul_180, insert=(square_size, square_size))) title2 = 'Mirrored pinwheel, rotate upper left, math name: p4g' dwg.add(dwg.text(title2, insert=(50, y + square_size), font_family='serif', font_size=font_size, fill='white')) # y = y + font_size for i in range(4): y += defs_g_p4g_v3_size for j in range(8): x = 50 + j * defs_g_p4g_v3_size sq_created = dwg.use(defs_g_p4g_v3, fill='yellow') if i % 2: # row 1, 3, 5 if j % 2: # column 1, 3, 5 sq_created.translate(x, y) else: # column 0, 2, 4 # flip horizontally sq_created.translate(x, y + defs_g_p4g_v3_size) sq_created.scale(1, -1) else: # row 0, 2, 4 if j % 2: # column 1, 3, 5 # flip vertically sq_created.translate(x + defs_g_p4g_v3_size, y) sq_created.scale(-1, 1) else: # column 0, 2, 4 sq_created.translate(x, y) dwg.add(sq_created) y += defs_g_p4g_v3_size # p4g variation 4 (mirrored pinwheel which depending on which corner is the rotation center.) # lower left is the rotation corner defs_g_p4g_v4_size = square_size * 2 defs_g_ll_90 = dwg.defs.add(dwg.g(id='defs_g_ll_90')) defs_g_ll_90.add(dwg.use(defs_g, insert=(0, 0))) defs_g_ll_90.rotate(90, center=(0, square_size)) defs_g_ll_m90 = dwg.defs.add(dwg.g(id='defs_g_ll_m90')) defs_g_ll_m90.add(dwg.use(defs_g, insert=(0, 0))) defs_g_ll_m90.rotate(-90, center=(0, square_size)) defs_g_ll_180 = dwg.defs.add(dwg.g(id='defs_g_ll_180')) defs_g_ll_180.add(dwg.use(defs_g, insert=(0, 0))) defs_g_ll_180.rotate(180, center=(0, square_size)) defs_g_p4g_v4 = dwg.defs.add(dwg.g(id='defs_g_p4g_v4')) defs_g_p4g_v4.add(dwg.use(defs_g, insert=(square_size, 0))) defs_g_p4g_v4.add(dwg.use(defs_g_ll_90, insert=(square_size, 0))) defs_g_p4g_v4.add(dwg.use(defs_g_ll_m90, insert=(square_size, 0))) defs_g_p4g_v4.add(dwg.use(defs_g_ll_180, insert=(square_size, 0))) title2 = 'Mirrored pinwheel, rotate lower left, math name: p4g' dwg.add(dwg.text(title2, insert=(50, y + square_size), font_family='serif', font_size=font_size, fill='white')) # y = y + font_size for i in range(4): y += defs_g_p4g_v4_size for j in range(8): x = 50 + j * defs_g_p4g_v4_size sq_created = dwg.use(defs_g_p4g_v4, fill='yellow') if i % 2: # row 1, 3, 5 if j % 2: # column 1, 3, 5 sq_created.translate(x, y) else: # column 0, 2, 4 # flip horizontally sq_created.translate(x, y + defs_g_p4g_v4_size) sq_created.scale(1, -1) else: # row 0, 2, 4 if j % 2: # column 1, 3, 5 # flip vertically sq_created.translate(x + defs_g_p4g_v4_size, y) sq_created.scale(-1, 1) else: # column 0, 2, 4 sq_created.translate(x, y) dwg.add(sq_created) # All items have been added so save the svg to a the file. dwg.save() if __name__ == '__main__': create_svg(PROGNAME + '.svg') # vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 textwidth=99 svgwrite-1.1.8/examples/ltattrie/tiling_part_4.py0000666000000000000000000005026211763617125020322 0ustar 00000000000000#!/usr/bin/python # -*- coding: utf-8 -*- import math, sys import svgwrite # http://www.w3.org/TR/SVG11/struct.html#UseElement # # For more information on tesselation / tiling see http://en.wikipedia.org/wiki/Wallpaper_group # The organization of these tilings are from the interesting book # Designing Testellations: The Secrets of Interlocking Patterns by Jinny Beyer. PROGNAME = sys.argv[0].rstrip('.py') def create_svg(name): svg_size_width = 900 svg_size_height = 2200 font_size = 20 triangle_size = 30 square_size = 30 title1 = name + ': Part 4 tiling with multiple def, groups, use, translate and scale.' sqrt3 = math.sqrt(3) # do this calc once instead of repeating the calc many times. # sqrt2 = math.sqrt(2) # do this calc once instead of repeating the calc many times. 1.41421356237 dwg = svgwrite.Drawing(name, (svg_size_width, svg_size_height), debug=True) # 45 degrees, 90 degrees, 45 degrees Right angle triangle triright = dwg.defs.add(dwg.polygon([(0, 0), (triangle_size, 0), (triangle_size, triangle_size)], id='triangle', stroke='none')) # clip path to prevent drawing outside of tile clip_path_triright = dwg.defs.add(dwg.clipPath(id='cliptriright')) clip_path_triright.add(dwg.polygon([(0, 0), (triangle_size, 0), (triangle_size, triangle_size)])) # define the group (tile) which will be repeated. # Having a clip path seems to increase the visibility of the lines which can occur between tiles and patterns. defs_g_triright = dwg.defs.add(dwg.g(id='defs_g_triright', clip_path='url(#cliptriright)')) defs_g_triright.add(dwg.polygon([(0, 0), (triangle_size, 0), (triangle_size, triangle_size)], stroke='none')) defs_g_triright.add(dwg.polygon([(3 * triangle_size / 4.0, 0), (triangle_size, 0), (triangle_size, triangle_size)], stroke='none', fill='navy')) defs_g_triright.add(dwg.circle(center=(triangle_size / 2.0, triangle_size / 2.0), r=5, stroke='blue', fill='green', stroke_width=1)) # define the mirror of defs_g_triright defs_g_tr_m = dwg.defs.add(dwg.g(id='defs_g_tr_m')) defs_g_tr_m.add(dwg.use(defs_g_triright, insert=(0, 0))) defs_g_tr_m.rotate(90, center=(triangle_size / 2.0, triangle_size / 2.0)) defs_g_tr_m.translate(0, triangle_size) defs_g_tr_m.scale(1, -1) # defs_g_tr_m.rotate(-90, center=(triangle_size, triangle_size)) # defs_g_tr_m.rotate(-90, center=(0, 0)) # sq_created.translate(x, (y + defs_g_p4g_v1_size)) # create the cell by using one triangle and one mirrored triangle defs_g_p4m_cell_size = triangle_size defs_g_p4m_cell = dwg.defs.add(dwg.g(id='defs_g_p4m_cell')) # defs_g_p4m_cell.add(dwg.use(defs_g_triright, insert=(0, 0), fill='aqua')) defs_g_p4m_cell.add(dwg.use(defs_g_triright, insert=(0, 0))) defs_g_p4m_cell.add(dwg.use(defs_g_tr_m, insert=(0, 0))) # Create rotations of the cell. defs_g_p4m_cell_lr_90 = dwg.defs.add(dwg.g(id='defs_g_p4m_cell_lr_90')) defs_g_p4m_cell_lr_90.add(dwg.use(defs_g_p4m_cell, insert=(0, 0))) defs_g_p4m_cell_lr_90.rotate(90, center=(square_size, square_size)) defs_g_p4m_cell_lr_m90 = dwg.defs.add(dwg.g(id='defs_g_p4m_cell_lr_m90')) defs_g_p4m_cell_lr_m90.add(dwg.use(defs_g_p4m_cell, insert=(0, 0))) defs_g_p4m_cell_lr_m90.rotate(-90, center=(square_size, square_size)) defs_g_p4m_cell_lr_180 = dwg.defs.add(dwg.g(id='defs_g_p4m_cell_lr_180')) defs_g_p4m_cell_lr_180.add(dwg.use(defs_g_p4m_cell, insert=(0, 0))) defs_g_p4m_cell_lr_180.rotate(180, center=(square_size, square_size)) # Now use the cell and three rotated cells to create the pattern. defs_g_p4m_pattern_size = 2 * defs_g_p4m_cell_size defs_g_p4m_pattern = dwg.defs.add(dwg.g(id='defs_g_p4m_pattern')) defs_g_p4m_pattern.add(dwg.use(defs_g_p4m_cell, insert=(0, 0))) defs_g_p4m_pattern.add(dwg.use(defs_g_p4m_cell_lr_90, insert=(0, 0))) defs_g_p4m_pattern.add(dwg.use(defs_g_p4m_cell_lr_m90, insert=(0, 0))) defs_g_p4m_pattern.add(dwg.use(defs_g_p4m_cell_lr_180, insert=(0, 0))) # #################### # p3 - rombus - For the purpose of these tessellations a rombus is 4 * 30-60-90 triangles. # 30, 60, 90 angle triangle # The length of the sides are 1:sqrt(3):2 2 is the hypotenuse # invsqrt2 = 1/sqrt2 # invsqrt2_2 = invsqrt2 * invsqrt2 = 1/2 = .5 by definition # sin and cos(45 degrees) is 1/sqrt2 = 0.707106781187 # cos(30 degrees) is sqrt3/2 # sin(30 degrees) is 1/2 defs_g_rombus_size_x = square_size defs_g_rombus_scale = defs_g_rombus_size_x / (sqrt3 * 2.0) defs_g_rombus_size_y = 2 * defs_g_rombus_scale # Having a clip path seems to increase the visibility of the lines between the tiles. # A clipping path may be necessary if the shapes go outside the triangle. # defs_g_rombus = dwg.defs.add(dwg.g(id='defs_g_rombus', clip_path='url(#cliprombus)')) defs_g_rombus = dwg.defs.add(dwg.g(id='defs_g_rombus')) defs_g_rombus.add(dwg.polygon([(0, defs_g_rombus_size_y / 2.0), (defs_g_rombus_size_x / 2.0, 0), (0, -defs_g_rombus_size_y / 2), (-defs_g_rombus_size_x / 2.0, 0)], stroke='none')) defs_g_rombus.add(dwg.polygon([(0, -defs_g_rombus_size_y / 2.0), (defs_g_rombus_size_x / 4.0, defs_g_rombus_size_y / 4.0), (0, defs_g_rombus_size_y / 2.0)], stroke='none', fill='darkolivegreen')) # (0, defs_g_rombus_size_y/2.0) ], stroke='none', fill='aqua')) # (0, defs_g_rombus_size_y/2.0) ], stroke='none')) # (defs_g_rombus_size_x/4.0, defs_g_rombus_size_y/4.0), # (defs_g_rombus_size_x*invsqrt2_2/2.0, defs_g_rombus_size_y*invsqrt2_2/2.0), defs_g_rombus.add(dwg.polygon([(0, -defs_g_rombus_size_y / 2.0), (-defs_g_rombus_size_x / 2.0, 0), (0, 0)], stroke='none', fill='palegreen')) # Create rotations of the rombus. defs_g_rombus_120 = dwg.defs.add(dwg.g(id='defs_g_rombus_120')) defs_g_rombus_120.add(dwg.use(defs_g_rombus, insert=(0, 0))) defs_g_rombus_120.rotate(120, center=(0, 0)) defs_g_rombus_m120 = dwg.defs.add(dwg.g(id='defs_g_rombus_m120')) defs_g_rombus_m120.add(dwg.use(defs_g_rombus, insert=(0, 0))) defs_g_rombus_m120.rotate(-120, center=(0, 0)) # Create the pattern by using the cell and two rotated cells defs_g_rombus_pattern_size_x = defs_g_rombus_size_x defs_g_rombus_pattern_size_y = 2.0 * defs_g_rombus_size_y defs_g_rombus_pattern = dwg.defs.add(dwg.g(id='defs_g_rombus_pattern')) defs_g_rombus_pattern.add(dwg.use(defs_g_rombus, insert=(defs_g_rombus_size_x / 2.0, 3 * defs_g_rombus_size_y / 2.0))) defs_g_rombus_pattern.add(dwg.use(defs_g_rombus_120, insert=(defs_g_rombus_size_x / 4.0, 3 * defs_g_rombus_size_y / 4.0))) defs_g_rombus_pattern.add(dwg.use(defs_g_rombus_m120, insert=(.75 * defs_g_rombus_size_x, 3 * defs_g_rombus_size_y / 4.0))) # #################### # p6 - Equilateral triangle # All three sides are the same length, all three angles are 60 degrees. # The height of the triangle h = sqrt(3)/2.0 * length of a side # The centre of the triangle is sqrt(3)/6.0 * length of a side defs_g_trieq_size_x = square_size defs_g_trieq_size_y = defs_g_trieq_size_x * sqrt3 / 2.0 defs_g_trieq_centre = sqrt3 / 6.0 * defs_g_trieq_size_x # width of equilateral triangle at the centre defs_g_trieq_centre_size_x = defs_g_trieq_size_x - defs_g_trieq_size_x * defs_g_trieq_centre / defs_g_trieq_size_y # defs_g_trieq = dwg.defs.add(dwg.g(id='defs_g_trieq', clip_path='url(#cliptrieq)')) defs_g_trieq = dwg.defs.add(dwg.g(id='defs_g_trieq')) defs_g_trieq.add(dwg.polygon([(0, -defs_g_trieq_size_y + defs_g_trieq_centre), (defs_g_trieq_size_x / 2.0, defs_g_trieq_centre), (-defs_g_trieq_size_x / 2.0, defs_g_trieq_centre)], stroke='none')) defs_g_trieq.add(dwg.polygon([(-defs_g_trieq_size_x / 2.0, defs_g_trieq_centre), (-defs_g_trieq_centre_size_x / 2.0, 0), (defs_g_trieq_centre_size_x / 2.0, 0), (0, defs_g_trieq_centre)], stroke='none', fill='yellow')) # Create rotations of the equilateral triangle. defs_g_trieq_60 = dwg.defs.add(dwg.g(id='defs_g_trieq_60')) defs_g_trieq_60.add(dwg.use(defs_g_trieq, insert=(0, 0))) defs_g_trieq_60.rotate(60, center=(defs_g_trieq_size_x / 2.0, defs_g_trieq_centre)) defs_g_trieq_120 = dwg.defs.add(dwg.g(id='defs_g_trieq_120')) defs_g_trieq_120.add(dwg.use(defs_g_trieq, insert=(0, 0))) defs_g_trieq_120.rotate(120, center=(defs_g_trieq_size_x / 2.0, defs_g_trieq_centre)) defs_g_trieq_180 = dwg.defs.add(dwg.g(id='defs_g_trieq_180')) defs_g_trieq_180.add(dwg.use(defs_g_trieq, insert=(0, 0))) defs_g_trieq_180.rotate(180, center=(defs_g_trieq_size_x / 2.0, defs_g_trieq_centre)) defs_g_trieq_m60 = dwg.defs.add(dwg.g(id='defs_g_trieq_m60')) defs_g_trieq_m60.add(dwg.use(defs_g_trieq, insert=(0, 0))) defs_g_trieq_m60.rotate(-60, center=(defs_g_trieq_size_x / 2.0, defs_g_trieq_centre)) defs_g_trieq_m120 = dwg.defs.add(dwg.g(id='defs_g_trieq_m120')) defs_g_trieq_m120.add(dwg.use(defs_g_trieq, insert=(0, 0))) defs_g_trieq_m120.rotate(-120, center=(defs_g_trieq_size_x / 2.0, defs_g_trieq_centre)) # Now use the cell and five rotated cells to create the pattern. defs_g_trieq_pattern_size_x = 2 * defs_g_trieq_size_x defs_g_trieq_pattern_size_y = 2 * defs_g_trieq_size_y defs_g_trieq_pattern = dwg.defs.add(dwg.g(id='defs_g_trieq_pattern')) defs_g_trieq_pattern.add(dwg.use(defs_g_trieq, insert=(0, 0))) defs_g_trieq_pattern.add(dwg.use(defs_g_trieq_60, insert=(0, 0))) defs_g_trieq_pattern.add(dwg.use(defs_g_trieq_120, insert=(0, 0))) defs_g_trieq_pattern.add(dwg.use(defs_g_trieq_180, insert=(0, 0))) defs_g_trieq_pattern.add(dwg.use(defs_g_trieq_m60, insert=(0, 0))) defs_g_trieq_pattern.add(dwg.use(defs_g_trieq_m120, insert=(0, 0))) # Create centered rotations of the equilateral triangle. defs_g_trieq_c60 = dwg.defs.add(dwg.g(id='defs_g_trieq_c60')) defs_g_trieq_c60.add(dwg.use(defs_g_trieq, insert=(0, 0))) defs_g_trieq_c60.rotate(60, center=(0, 0)) defs_g_trieq_c120 = dwg.defs.add(dwg.g(id='defs_g_trieq_c120')) defs_g_trieq_c120.add(dwg.use(defs_g_trieq, insert=(0, 0))) defs_g_trieq_c120.rotate(120, center=(0, 0)) defs_g_trieq_c180 = dwg.defs.add(dwg.g(id='defs_g_trieq_c180')) defs_g_trieq_c180.add(dwg.use(defs_g_trieq, insert=(0, 0))) defs_g_trieq_c180.rotate(180, center=(0, 0)) defs_g_trieq_cm60 = dwg.defs.add(dwg.g(id='defs_g_trieq_cm60')) defs_g_trieq_cm60.add(dwg.use(defs_g_trieq, insert=(0, 0))) defs_g_trieq_cm60.rotate(-60, center=(0, 0)) defs_g_trieq_cm120 = dwg.defs.add(dwg.g(id='defs_g_trieq_cm120')) defs_g_trieq_cm120.add(dwg.use(defs_g_trieq, insert=(0, 0))) defs_g_trieq_cm120.rotate(-120, center=(0, 0)) # Now use the cell and five rotated cells to create the pattern variation 2. # Variation 2 is the equilateral triangle rotated around a the upper corner. defs_g_trieq_pattern_v2_size_x = 2 * defs_g_trieq_size_x defs_g_trieq_pattern_v2_size_y = 2 * defs_g_trieq_size_y defs_g_trieq_pattern_v2 = dwg.defs.add(dwg.g(id='defs_g_trieq_pattern_v2')) defs_g_trieq_pattern_v2.add(dwg.use(defs_g_trieq, insert=(0, defs_g_trieq_size_y - defs_g_trieq_centre))) defs_g_trieq_pattern_v2.add(dwg.use(defs_g_trieq_c60, insert=(-defs_g_trieq_size_x / 2.0, defs_g_trieq_centre))) defs_g_trieq_pattern_v2.add(dwg.use(defs_g_trieq_c120, insert=(-defs_g_trieq_size_x / 2.0, -defs_g_trieq_centre))) defs_g_trieq_pattern_v2.add(dwg.use(defs_g_trieq_c180, insert=(0, defs_g_trieq_centre - defs_g_trieq_size_y))) defs_g_trieq_pattern_v2.add(dwg.use(defs_g_trieq_cm60, insert=(defs_g_trieq_size_x / 2.0, defs_g_trieq_centre))) defs_g_trieq_pattern_v2.add(dwg.use(defs_g_trieq_cm120, insert=(defs_g_trieq_size_x / 2.0, -defs_g_trieq_centre))) # Now use the cell and five rotated cells to create the pattern variation 3. # Variation 3 is the equilateral triangle rotated around a the lower left corner. defs_g_trieq_pattern_v3_size_x = 2 * defs_g_trieq_size_x defs_g_trieq_pattern_v3_size_y = 2 * defs_g_trieq_size_y defs_g_trieq_pattern_v3 = dwg.defs.add(dwg.g(id='defs_g_trieq_pattern_v3')) defs_g_trieq_pattern_v3.add(dwg.use(defs_g_trieq, insert=(defs_g_trieq_size_x / 2.0, -defs_g_trieq_centre))) defs_g_trieq_pattern_v3.add(dwg.use(defs_g_trieq_c60, insert=(defs_g_trieq_size_x / 2.0, defs_g_trieq_centre))) defs_g_trieq_pattern_v3.add(dwg.use(defs_g_trieq_c120, insert=(0, defs_g_trieq_size_y - defs_g_trieq_centre))) defs_g_trieq_pattern_v3.add(dwg.use(defs_g_trieq_c180, insert=(-defs_g_trieq_size_x / 2.0, defs_g_trieq_centre))) defs_g_trieq_pattern_v3.add(dwg.use(defs_g_trieq_cm60, insert=(0, defs_g_trieq_centre - defs_g_trieq_size_y))) defs_g_trieq_pattern_v3.add(dwg.use(defs_g_trieq_cm120, insert=(-defs_g_trieq_size_x / 2.0, -defs_g_trieq_centre))) # ######################## # Background will be dark but not black so the background does not overwhelm the colors. dwg.add(dwg.rect(insert=(0, 0), size=('100%', '100%'), rx=None, ry=None, fill='grey')) # Give the name of the example and a title. y = font_size + 5 dwg.add(dwg.text(title1, insert=(0, y), font_family='serif', font_size=font_size, fill='white')) y = y + font_size # # p4m 45 45 90 triangle title2 = '45 45 90 triangle mirrored and rotated, math name: p4m' dwg.add(dwg.text(title2, insert=(50, y), font_family='serif', font_size=font_size, fill='white')) y = y + font_size # Sample of tile. y = y + triangle_size tri_created = dwg.use(defs_g_triright, insert=(50, y), fill='yellow') dwg.add(tri_created) tri_created = dwg.use(defs_g_p4m_cell, insert=(150, y), fill='yellow') dwg.add(tri_created) tri_created = dwg.use(defs_g_p4m_pattern, insert=(250, y), fill='yellow') dwg.add(tri_created) y = y + defs_g_p4m_pattern_size for i in range(4): y += defs_g_p4m_pattern_size for j in range(8): x = 50 + j * defs_g_p4m_pattern_size sq_created = dwg.use(defs_g_p4m_pattern, fill='yellow') sq_created.translate(x, y) dwg.add(sq_created) y += 2 * defs_g_p4m_pattern_size # p4m rombus title2 = 'Rombus rotated, math name: p3' dwg.add(dwg.text(title2, insert=(50, y), font_family='serif', font_size=font_size, fill='white')) y = y + font_size # Sample of tile. # rombus_created = dwg.use(defs_g_rombus, insert=(100, y ), fill='yellow') rombus_created = dwg.use(defs_g_rombus, insert=(75, y), fill='black') dwg.add(rombus_created) tile_created = dwg.use(defs_g_rombus_120, insert=(150, y), fill='black') dwg.add(tile_created) pattern_created = dwg.use(defs_g_rombus_pattern, insert=(250, y), fill='black') dwg.add(pattern_created) y = y + defs_g_rombus_size_y y_offset = defs_g_rombus_size_y / 2.0 for i in range(12): y += defs_g_rombus_pattern_size_y - y_offset for j in range(16): if i % 2: x = 50 + defs_g_rombus_pattern_size_x / 2.0 + j * defs_g_rombus_pattern_size_x else: x = 50 + j * defs_g_rombus_pattern_size_x pattern_created = dwg.use(defs_g_rombus_pattern, fill='black') pattern_created.translate(x, y) dwg.add(pattern_created) y += 2 * defs_g_rombus_pattern_size_y # p6 Equilateral triangle title2 = 'Equilateral triangle rotated lower right point, math name: p6' dwg.add(dwg.text(title2, insert=(50, y), font_family='serif', font_size=font_size, fill='white')) y = y + font_size # Sample of tile. y = y + triangle_size tri_created = dwg.use(defs_g_trieq, insert=(50 + defs_g_trieq_size_x / 2.0, y), fill='navy') dwg.add(tri_created) dwg.add(dwg.circle(center=(50 + defs_g_trieq_size_x / 2.0, y), r=3, stroke='none', fill='purple', opacity='0.5')) tile_created = dwg.use(defs_g_trieq_pattern, insert=(150 + defs_g_trieq_pattern_size_x / 2, y), fill='navy') dwg.add(tile_created) dwg.add(dwg.circle(center=(150 + defs_g_trieq_pattern_size_x / 2, y), r=3, stroke='none', fill='purple', opacity='0.5')) y += defs_g_trieq_pattern_size_y for i in range(9): y += defs_g_trieq_pattern_size_y / 2.0 for j in range(6): if i % 2: x = 50 + j * 1.5 * defs_g_trieq_pattern_size_x else: x = 50 + 1.5 * defs_g_trieq_size_x + j * 1.5 * defs_g_trieq_pattern_size_x pattern_created = dwg.use(defs_g_trieq_pattern, fill='navy') pattern_created.translate(x, y) dwg.add(pattern_created) y += defs_g_trieq_pattern_size_y title2 = 'Equilateral triangle rotated upper point, math name: p6' dwg.add(dwg.text(title2, insert=(50, y), font_family='serif', font_size=font_size, fill='white')) y = y + font_size + defs_g_trieq_pattern_size_y # sample centered rotated eqilateral triangle variation 2 tri_created = dwg.use(defs_g_trieq, insert=(50 + defs_g_trieq_size_x / 2.0, y), fill='navy') dwg.add(tri_created) dwg.add(dwg.circle(center=(50 + defs_g_trieq_size_x / 2.0, y), r=3, stroke='none', fill='purple', opacity='0.5')) tile_created = dwg.use(defs_g_trieq_c60, insert=(150 + defs_g_trieq_size_x / 2, y), fill='navy') dwg.add(tile_created) dwg.add(dwg.circle(center=(150 + defs_g_trieq_size_x / 2, y), r=3, stroke='none', fill='purple', opacity='0.5')) tile_created = dwg.use(defs_g_trieq_pattern_v2, insert=(250 + defs_g_trieq_pattern_size_x / 2, y), fill='navy') dwg.add(tile_created) dwg.add(dwg.circle(center=(250 + defs_g_trieq_pattern_size_x / 2, y), r=3, stroke='none', fill='purple', opacity='0.5')) y += defs_g_trieq_pattern_size_y for i in range(9): y += defs_g_trieq_pattern_v2_size_y / 2.0 for j in range(6): if i % 2: x = 50 + j * 1.5 * defs_g_trieq_pattern_v2_size_x else: x = 50 + 1.5 * defs_g_trieq_size_x + j * 1.5 * defs_g_trieq_pattern_v2_size_x pattern_created = dwg.use(defs_g_trieq_pattern_v2, fill='navy') pattern_created.translate(x, y) dwg.add(pattern_created) y += defs_g_trieq_pattern_size_y title2 = 'Equilateral triangle rotated lower left, math name: p6' dwg.add(dwg.text(title2, insert=(50, y), font_family='serif', font_size=font_size, fill='white')) y = y + font_size + defs_g_trieq_pattern_size_y # sample centered rotated eqilateral triangle variation 3 tri_created = dwg.use(defs_g_trieq, insert=(50 + defs_g_trieq_size_x / 2.0, y), fill='navy') dwg.add(tri_created) dwg.add(dwg.circle(center=(50 + defs_g_trieq_size_x / 2.0, y), r=3, stroke='none', fill='purple', opacity='0.5')) tile_created = dwg.use(defs_g_trieq_c60, insert=(150 + defs_g_trieq_size_x / 2, y), fill='navy') dwg.add(tile_created) dwg.add(dwg.circle(center=(150 + defs_g_trieq_size_x / 2, y), r=3, stroke='none', fill='purple', opacity='0.5')) tile_created = dwg.use(defs_g_trieq_pattern_v3, insert=(250 + defs_g_trieq_pattern_size_x / 2, y), fill='navy') dwg.add(tile_created) dwg.add(dwg.circle(center=(250 + defs_g_trieq_pattern_size_x / 2, y), r=3, stroke='none', fill='purple', opacity='0.5')) y += defs_g_trieq_pattern_size_y for i in range(9): y += defs_g_trieq_pattern_v3_size_y / 2.0 for j in range(6): if i % 2: x = 50 + j * 1.5 * defs_g_trieq_pattern_v3_size_x else: x = 50 + 1.5 * defs_g_trieq_size_x + j * 1.5 * defs_g_trieq_pattern_v3_size_x pattern_created = dwg.use(defs_g_trieq_pattern_v3, fill='navy') pattern_created.translate(x, y) dwg.add(pattern_created) y += defs_g_trieq_pattern_size_y # All items have been added so save the svg to a the file.# Sample of tile. dwg.save() if __name__ == '__main__': create_svg(PROGNAME + '.svg') # vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 textwidth=99 svgwrite-1.1.8/examples/ltattrie/tiling_part_5.py0000666000000000000000000004155211763616515020327 0ustar 00000000000000#!/usr/bin/python # -*- coding: utf-8 -*- import math, sys import svgwrite # # http://www.w3.org/TR/SVG11/struct.html#UseElement # # For more information on tesselation / tiling see http://en.wikipedia.org/wiki/Wallpaper_group # The organization of these tilings are from the interesting book # Designing Testellations: The Secrets of Interlocking Patterns by Jinny Beyer. PROGNAME = sys.argv[0].rstrip('.py') def create_svg(name): svg_size_width = 900 svg_size_height = 1600 font_size = 20 square_size = 30 title1 = name + ': Part 5 tiling with multiple def, groups, use, translate and scale.' sqrt3 = math.sqrt(3) # do this calc once instead of repeating the calc many times. dwg = svgwrite.Drawing(name, (svg_size_width, svg_size_height), debug=True) # #################### # p3m1 - Mirror and Three rotations # - Equilateral triangle mirrored, rotated # All three sides are the same length, all three angles are 60 degrees. # The height of the triangle h = sqrt(3)/2.0 * length of a side # The centre of the triangle is sqrt(3)/6.0 * length of a side defs_g_trieq_size_x = square_size defs_g_trieq_size_y = defs_g_trieq_size_x * sqrt3 / 2.0 defs_g_trieq_centre = sqrt3 / 6.0 * defs_g_trieq_size_x # width of equilateral triangle at the centre defs_g_trieq_centre_size_x = defs_g_trieq_size_x - defs_g_trieq_size_x * defs_g_trieq_centre / defs_g_trieq_size_y # defs_g_trieq = dwg.defs.add(dwg.g(id='defs_g_trieq', clip_path='url(#cliptrieq)')) defs_g_trieq = dwg.defs.add(dwg.g(id='defs_g_trieq')) defs_g_trieq.add(dwg.polygon([(0, -defs_g_trieq_size_y + defs_g_trieq_centre), (defs_g_trieq_size_x / 2.0, defs_g_trieq_centre), (-defs_g_trieq_size_x / 2.0, defs_g_trieq_centre)], stroke='none')) defs_g_trieq.add(dwg.polygon([(-defs_g_trieq_size_x / 2.0, defs_g_trieq_centre), (-defs_g_trieq_centre_size_x / 2.0, 0), (defs_g_trieq_centre_size_x / 2.0, 0), (0, defs_g_trieq_centre)], stroke='none', fill='yellow')) # Create mirror of the equilateral triangle. defs_g_trieq_m = dwg.defs.add(dwg.g(id='defs_g_trieq_m')) defs_g_trieq_m.add(dwg.use(defs_g_trieq, insert=(0, 0))) defs_g_trieq_m.scale(-1, -1) # Create combined cell defs_g_trieq_cc_size_x = 1.5 * defs_g_trieq_size_x defs_g_trieq_cc_size_y = defs_g_trieq_size_y defs_g_trieq_cc = dwg.defs.add(dwg.g(id='defs_g_trieq_cc')) defs_g_trieq_cc.add(dwg.use(defs_g_trieq, insert=(-defs_g_trieq_size_x / 4.0, defs_g_trieq_size_y / 2.0 - defs_g_trieq_centre))) defs_g_trieq_cc.add(dwg.use(defs_g_trieq_m, insert=(defs_g_trieq_size_x / 4.0, -(defs_g_trieq_size_y / 2.0 - defs_g_trieq_centre)))) # Create rotations of combined cell defs_g_trieq_cc_120 = dwg.defs.add(dwg.g(id='defs_g_trieq_cc_120')) defs_g_trieq_cc_120.add(dwg.use(defs_g_trieq_cc, insert=(0, 0), fill='mediumblue')) defs_g_trieq_cc_120.rotate(120, center=(0, 0)) defs_g_trieq_cc_m120 = dwg.defs.add(dwg.g(id='defs_g_trieq_cc_m120')) defs_g_trieq_cc_m120.add(dwg.use(defs_g_trieq_cc, insert=(0, 0), fill='navy')) defs_g_trieq_cc_m120.rotate(-120, center=(0, 0)) # Create pattern from rotations of combined cell defs_g_trieq_pattern_size_x = 2 * defs_g_trieq_size_x defs_g_trieq_pattern_size_y = 2 * defs_g_trieq_size_y defs_g_trieq_pattern = dwg.defs.add(dwg.g(id='defs_g_trieq_pattern')) defs_g_trieq_pattern.add(dwg.use(defs_g_trieq_cc, insert=(-defs_g_trieq_size_x / 4.0, -defs_g_trieq_cc_size_y / 2.0))) defs_g_trieq_pattern.add(dwg.use(defs_g_trieq_cc_120, insert=(defs_g_trieq_size_x / 2.0, 0))) defs_g_trieq_pattern.add(dwg.use(defs_g_trieq_cc_m120, insert=(-defs_g_trieq_size_x / 4.0, defs_g_trieq_cc_size_y / 2.0))) # #################### # p31m - Three rotations and a mirror # - A Kite shape, half hexagon, and half of a 60 degree diamond will all work for this # symmetry. This one will use a kite. # 30, 60, 90 angle triangle # The length of the sides are 1:sqrt(3):2 2 is the hypotenuse # invsqrt2 = 1/sqrt2 # invsqrt2_2 = invsqrt2 * invsqrt2 = 1/2 = .5 by definition # sin and cos(45 degrees) is 1/sqrt2 = 0.707106781187 # cos(30 degrees) is sqrt3/2 # sin(30 degrees) is 1/2 # tan(30) = 1/sqrt(3) # The height of equilateral triangle h = sqrt(3)/2.0 * length of a side # The centre of equilateral triangle is sqrt(3)/6.0 * length of a side defs_g_kite_size_x = square_size defs_g_kite_size_y = defs_g_kite_size_x * sqrt3 / 2.0 + defs_g_kite_size_x * sqrt3 / 6.0 # Having a clip path seems to increase the visibility of the lines between the tiles. # A clipping path may be necessary if the shapes go outside the triangle. # defs_g_kite = dwg.defs.add(dwg.g(id='defs_g_kite', clip_path='url(#clipkite)')) defs_g_kite = dwg.defs.add(dwg.g(id='defs_g_kite')) defs_g_kite.add(dwg.polygon([(0, 0), (defs_g_kite_size_x / 2.0, defs_g_kite_size_x / (sqrt3 * 2.0)), (0, defs_g_kite_size_y), (-defs_g_kite_size_x / 2.0, defs_g_kite_size_x / (sqrt3 * 2.0))], stroke='none')) #defs_g_kite.add(dwg.polygon([(0, 0), # (defs_g_kite_size_x / 4.0, (defs_g_kite_size_y + defs_g_kite_size_x / (sqrt3 * 2.0)) / 2.0), # (-defs_g_kite_size_x / 2.0, defs_g_kite_size_x / (sqrt3 * 2.0))], stroke='none', fill='yellow')) defs_g_kite.add(dwg.polygon([(0, 0), (defs_g_kite_size_x / 2.0, defs_g_kite_size_x / (sqrt3 * 2.0)), (0, defs_g_kite_size_y / 12.0), (-defs_g_kite_size_x / 2.0, defs_g_kite_size_x / (sqrt3 * 2.0))], stroke='none', fill='black')) defs_g_kite.add(dwg.polygon([(0, defs_g_kite_size_y), (defs_g_kite_size_x / 2.0, defs_g_kite_size_x / (sqrt3 * 2.0)), (0, defs_g_kite_size_y * 8.0 / 12.0), (-defs_g_kite_size_x / 2.0, defs_g_kite_size_x / (sqrt3 * 2.0))], stroke='none', fill='green')) # Create rotations of the kite. defs_g_kite_120 = dwg.defs.add(dwg.g(id='defs_g_kite_120')) defs_g_kite_120.add(dwg.use(defs_g_kite, insert=(0, 0))) defs_g_kite_120.rotate(120, center=(0, 0)) defs_g_kite_m120 = dwg.defs.add(dwg.g(id='defs_g_kite_m120')) defs_g_kite_m120.add(dwg.use(defs_g_kite, insert=(0, 0))) defs_g_kite_m120.rotate(-120, center=(0, 0)) # Now use the cell, rotated cells to create the combined cell. # The height of equilateral triangle h = sqrt(3) / 2.0 * length of a side defs_g_kite_cc_size_x = 2 * defs_g_kite_size_x defs_g_kite_cc_size_y = defs_g_kite_size_x * sqrt3 # 2*(sqrt(3)/2.0) defs_g_kite_cc = dwg.defs.add(dwg.g(id='defs_g_kite_cc')) defs_g_kite_cc.add(dwg.use(defs_g_kite, insert=(0, 0))) defs_g_kite_cc.add(dwg.use(defs_g_kite_120, insert=(0, 0))) defs_g_kite_cc.add(dwg.use(defs_g_kite_m120, insert=(0, 0))) # Now use the combined cell to create a mirrored combined cell defs_g_kite_mcc = dwg.defs.add(dwg.g(id='defs_g_kite_mcc')) defs_g_kite_mcc.add(dwg.use(defs_g_kite_cc, insert=(0, 0))) defs_g_kite_mcc.scale(-1, -1) # Now use the combined cell, and mirrored combined cell to create a pattern defs_g_kite_pattern_size_x = 1.5 * defs_g_kite_cc_size_x defs_g_kite_pattern_size_y = defs_g_kite_cc_size_y defs_g_kite_pattern = dwg.defs.add(dwg.g(id='defs_g_kite_pattern')) defs_g_kite_pattern.add(dwg.use(defs_g_kite_cc, insert=(-defs_g_kite_cc_size_x / 4.0, -sqrt3 / 12.0 * defs_g_kite_cc_size_x))) defs_g_kite_pattern.add(dwg.use(defs_g_kite_mcc, insert=(defs_g_kite_cc_size_x / 4.0, sqrt3 / 12.0 * defs_g_kite_cc_size_x))) # #################### # p6m - Kaleidoscope Either of the two long sides of the primary triangle is mirrored. The # resulting shape is rotated six times. # 30, 60, 90 angle triangle # The length of the sides are 1:sqrt(3):2 2 is the hypotenuse # invsqrt2 = 1/sqrt2 # invsqrt2_2 = invsqrt2 * invsqrt2 = 1/2 = .5 by definition # sin and cos(45 degrees) is 1/sqrt2 = 0.707106781187 # cos(30 degrees) is sqrt3/2 # sin(30 degrees) is 1/2 # tan(30) = 1/sqrt(3) # # The height of equilateral triangle h = sqrt(3) / 2.0 * length of a side # # The centre of equilateral triangle is sqrt(3) / 6.0 * length of a side defs_g_kale_tri_size_x = square_size defs_g_kale_tri_size_y = defs_g_kale_tri_size_x * 4.0 / sqrt3 # Having a clip path seems to increase the visibility of the lines between the tiles. # A clipping path may be necessary if the shapes go outside the triangle. # defs_g_kale_tri = dwg.defs.add(dwg.g(id='defs_g_kale_tri', clip_path='url(#clipkale)')) defs_g_kale_tri = dwg.defs.add(dwg.g(id='defs_g_kale_tri')) defs_g_kale_tri.add(dwg.polygon([(0, -defs_g_kale_tri_size_y), (0, 0), (-defs_g_kale_tri_size_x, defs_g_kale_tri_size_x / sqrt3 - defs_g_kale_tri_size_y)], stroke='none')) defs_g_kale_tri.add(dwg.polygon([(-defs_g_kale_tri_size_x, defs_g_kale_tri_size_x / sqrt3 - defs_g_kale_tri_size_y), (0, 2.0 * defs_g_kale_tri_size_x / sqrt3 - defs_g_kale_tri_size_y), (0, 3.0 * defs_g_kale_tri_size_x / sqrt3 - defs_g_kale_tri_size_y)], stroke='none', fill='yellow')) # Create mirror of the kale. defs_g_kale_tri_m = dwg.defs.add(dwg.g(id='defs_g_kale_tri_m')) defs_g_kale_tri_m.add(dwg.use(defs_g_kale_tri, insert=(0, 0))) defs_g_kale_tri_m.scale(-1, 1) # Now use the tri, rotated tri to create the combined cell. defs_g_kale_cc_size_x = 2 * defs_g_kale_tri_size_x defs_g_kale_cc_size_y = defs_g_kale_tri_size_y defs_g_kale_cc = dwg.defs.add(dwg.g(id='defs_g_kale_cc')) defs_g_kale_cc.add(dwg.use(defs_g_kale_tri, insert=(0, 0))) defs_g_kale_cc.add(dwg.use(defs_g_kale_tri_m, insert=(0, 0))) # Now rotate the combined cell. defs_g_kale_cc_60 = dwg.defs.add(dwg.g(id='defs_g_kale_cc_60')) defs_g_kale_cc_60.add(dwg.use(defs_g_kale_cc, insert=(0, 0))) defs_g_kale_cc_60.rotate(60, center=(0, 0)) defs_g_kale_cc_120 = dwg.defs.add(dwg.g(id='defs_g_kale_cc_120')) defs_g_kale_cc_120.add(dwg.use(defs_g_kale_cc, insert=(0, 0))) defs_g_kale_cc_120.rotate(120, center=(0, 0)) defs_g_kale_cc_180 = dwg.defs.add(dwg.g(id='defs_g_kale_cc_180')) defs_g_kale_cc_180.add(dwg.use(defs_g_kale_cc, insert=(0, 0))) defs_g_kale_cc_180.rotate(180, center=(0, 0)) defs_g_kale_cc_m60 = dwg.defs.add(dwg.g(id='defs_g_kale_cc_m60')) defs_g_kale_cc_m60.add(dwg.use(defs_g_kale_cc, insert=(0, 0))) defs_g_kale_cc_m60.rotate(-60, center=(0, 0)) defs_g_kale_cc_m120 = dwg.defs.add(dwg.g(id='defs_g_kale_cc_m120')) defs_g_kale_cc_m120.add(dwg.use(defs_g_kale_cc, insert=(0, 0))) defs_g_kale_cc_m120.rotate(-120, center=(0, 0)) # Now use the cell and five rotated cells to create the pattern. defs_g_kale_pattern_size_x = 2 * defs_g_kale_cc_size_x defs_g_kale_pattern_size_y = 2 * defs_g_kale_cc_size_y defs_g_kale_pattern = dwg.defs.add(dwg.g(id='defs_g_kale_pattern')) defs_g_kale_pattern.add(dwg.use(defs_g_kale_cc, insert=(0, 0))) defs_g_kale_pattern.add(dwg.use(defs_g_kale_cc_60, insert=(0, 0))) defs_g_kale_pattern.add(dwg.use(defs_g_kale_cc_120, insert=(0, 0))) defs_g_kale_pattern.add(dwg.use(defs_g_kale_cc_180, insert=(0, 0))) defs_g_kale_pattern.add(dwg.use(defs_g_kale_cc_m60, insert=(0, 0))) defs_g_kale_pattern.add(dwg.use(defs_g_kale_cc_m120, insert=(0, 0))) # ######################## # Background will be dark but not black so the background does not overwhelm the colors. dwg.add(dwg.rect(insert=(0, 0), size=('100%', '100%'), rx=None, ry=None, fill='grey')) # Give the name of the example and a title. y = font_size + 5 dwg.add(dwg.text(title1, insert=(0, y), font_family='serif', font_size=font_size, fill='white')) y = y + font_size # p3m1 - Mirror and three rotations title2 = 'Mirror and three rotations, math name: p3m1' dwg.add(dwg.text(title2, insert=(50, y), font_family='serif', font_size=font_size, fill='white')) y = y + font_size + defs_g_trieq_size_x cell_created = dwg.use(defs_g_trieq, insert=(50 + defs_g_trieq_size_x, y), fill='lightblue') dwg.add(cell_created) dwg.add(dwg.circle(center=(50 + defs_g_trieq_size_x, y), r=3, stroke='none', fill='purple', opacity='0.5')) cc_created = dwg.use(defs_g_trieq_cc, insert=(150 + defs_g_trieq_cc_size_x, y), fill='lightblue') dwg.add(cc_created) dwg.add(dwg.circle(center=(150 + defs_g_trieq_cc_size_x, y), r=3, stroke='none', fill='purple', opacity='0.5')) pattern_created = dwg.use(defs_g_trieq_pattern, insert=(250 + defs_g_trieq_cc_size_x, y), fill='lightblue') dwg.add(pattern_created) dwg.add(dwg.circle(center=(250 + defs_g_trieq_cc_size_x, y), r=3, stroke='none', fill='purple', opacity='0.5')) y += defs_g_trieq_pattern_size_y for i in range(8): y += defs_g_trieq_pattern_size_y / 2.0 for j in range(6): if i % 2: x = 50 + j * 1.5 * defs_g_trieq_pattern_size_x else: x = 50 + 1.5 * defs_g_trieq_size_x + j * 1.5 * defs_g_trieq_pattern_size_x pattern_created = dwg.use(defs_g_trieq_pattern, fill='lightblue') pattern_created.translate(x, y) dwg.add(pattern_created) y += defs_g_trieq_pattern_size_y # # p31m sample cell, combined cell and tile title2 = 'Kite rotated and mirrored, math name: p31m' dwg.add(dwg.text(title2, insert=(50, y), font_family='serif', font_size=font_size, fill='white')) y = y + font_size + defs_g_kite_size_y cell_created = dwg.use(defs_g_kite, insert=(50 + defs_g_kite_size_x / 2.0, y), fill='navy') dwg.add(cell_created) dwg.add(dwg.circle(center=(50 + defs_g_kite_size_x / 2.0, y), r=3, stroke='none', fill='purple', opacity='0.5')) cc_created = dwg.use(defs_g_kite_cc, insert=(150 + defs_g_kite_size_x / 2.0, y), fill='navy') dwg.add(cc_created) dwg.add(dwg.circle(center=(150 + defs_g_kite_size_x / 2.0, y), r=3, stroke='none', fill='purple', opacity='0.5')) mcc_created = dwg.use(defs_g_kite_mcc, insert=(250 + defs_g_kite_cc_size_x / 2, y), fill='navy') dwg.add(mcc_created) dwg.add(dwg.circle(center=(250 + defs_g_kite_cc_size_x / 2, y), r=3, stroke='none', fill='purple', opacity='0.5')) pattern_created = dwg.use(defs_g_kite_pattern, insert=(350 + defs_g_kite_cc_size_x, y), fill='navy') dwg.add(pattern_created) dwg.add(dwg.circle(center=(350 + defs_g_kite_cc_size_x, y), r=3, stroke='none', fill='purple', opacity='0.5')) y += defs_g_kite_pattern_size_y for i in range(6): y += defs_g_kite_pattern_size_y for j in range(8): if i % 2: x = 100 + (j + 0.5) * defs_g_kite_cc_size_x else: x = 100 + j * defs_g_kite_cc_size_x pattern_created = dwg.use(defs_g_kite_pattern, fill='navy') pattern_created.translate(x, y) dwg.add(pattern_created) y += defs_g_kite_pattern_size_y # ## # p6m kaleidoscope title2 = 'Kaleidoscope 30, 60, 90 triangle mirrored and rotated, math name: p6m' dwg.add(dwg.text(title2, insert=(50, y), font_family='serif', font_size=font_size, fill='white')) y = y + font_size y += defs_g_kale_tri_size_y cell_created = dwg.use(defs_g_kale_tri, insert=(50 + defs_g_kale_tri_size_x, y), fill='navy') dwg.add(cell_created) dwg.add(dwg.circle(center=(50 + defs_g_kale_tri_size_x, y), r=3, stroke='none', fill='purple', opacity='0.5')) cc_created = dwg.use(defs_g_kale_cc, insert=(150 + defs_g_kale_cc_size_x / 2.0, y), fill='navy') dwg.add(cc_created) dwg.add(dwg.circle(center=(150 + defs_g_kale_cc_size_x / 2.0, y), r=3, stroke='none', fill='purple', opacity='0.5')) pattern_created = dwg.use(defs_g_kale_pattern, insert=(250 + defs_g_kale_pattern_size_x / 2.0, y), fill='navy') dwg.add(pattern_created) dwg.add(dwg.circle(center=(250 + defs_g_kale_pattern_size_x / 2.0, y), r=3, stroke='none', fill='purple', opacity='0.5')) y += defs_g_kale_pattern_size_y / 2.0 for i in range(4): y += defs_g_kale_pattern_size_y - defs_g_kale_pattern_size_x / (sqrt3 * 2) for j in range(6): if i % 2: x = 100 + j * defs_g_kale_pattern_size_x else: x = 100 + defs_g_kale_cc_size_x + j * defs_g_kale_pattern_size_x pattern_created = dwg.use(defs_g_kale_pattern, fill='navy') pattern_created.translate(x, y) dwg.add(pattern_created) y += defs_g_kale_pattern_size_y # All items have been added so save the svg to a the file. dwg.save() if __name__ == '__main__': create_svg(PROGNAME + '.svg') # vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 textwidth=99 svgwrite-1.1.8/examples/ltattrie/xkcd_colour_data_svgwrite_3.py0000666000000000000000000001216611764314764023251 0ustar 00000000000000from __future__ import print_function import sys import os import colorsys import svgwrite PROGNAME = sys.argv[0].rstrip('.py') RGB_TXT = 'rgb.txt' # To Do # Automate the file name and title and axis swatch_y # Create multiple layers and put the third component divided into 10 layers? # Create new examples for svgwrite # text follow path based on http://www.w3.org/TR/SVG/text.html example toap01 # text stroke, stroke colour # text font names # colour names, colour by rbg, colour by hex, colour by hsl. # clipping and masking perhaps use http://www.w3.org/TR/SVG/masking.html example opacity01 # multishapes with various opacities overlapping. ex rounded corner rectangles. # Are clones an inkscape feature? # View examples by following links at http://tavmjong.free.fr/INKSCAPE/ # Table of contents page to show example svgs. Links go to each svg. # It does this by looking at the current dir and listing *.svg or example*.svg # Drop shadow? # Create sample programs which match the svg test in the www.? pages # Complain / document that # sq_created.translate(x, (y+square_size)) # sq_created.scale(1, -1) is not the same as # sq_created.scale(1, -1) # sq_created.translate(x, (y+square_size)) # www.? said that evaluation is done RIGHT to LEFT! But the program puts the most recent on # the left so what appears in the program to happen first actually happens last! To me this # should be changed and is likely that the author of svgwrite did not know of the Right to # Left evaluation. Needs example from www.? # Note that sq_created.scale='(1, -1)' does not work and is incorrect but does not produce an # error. The program ignores it and caused me a lot of debugging time. # # read the name and colour data provided by xkcd and change to svg diagram. # http://blog.xkcd.com/2010/05/03/color-survey-results/ # # The file format is tab delimeted: colour name tab hex colour tab newline # max name length =26 # # http://stackoverflow.com/questions/214359/converting-hex-to-rgb-and-vice-versa # A hex value is just RGB numbers represented in hexadecimal. So you just have to take each pair of hex digits # and convert them to decimal. Example: #FF6400 = RGB(0xFF, 0x64, 0x00) = RGB(255, 100, 0) def hex_to_rgb(value): value = value.lstrip('#') def get_int(pos): start = pos * 2 return int(value[start:start+2], 16) return get_int(0), get_int(1), get_int(2) def create_svg(name): swatch_w = 10 # swatch width swatch_h = 10 # swatch height if not os.path.exists(RGB_TXT): print("Error. The data file is not readable. File name is: %s" % RGB_TXT) sys.exit(1) # 1050 = 1000 width of color + width of last rectangle which might start at 1000 + approx width of font name text svg_size = 1050 dwg = svgwrite.Drawing(name, (svg_size, svg_size)) dwg.add(dwg.rect(insert=(0, 0), size=('100%', '100%'), fill='grey')) dwg.add(dwg.text('XKCD.com color name survey x=hue, y=lightness', insert=(svg_size/2, '28px'), text_anchor='middle', font_family="sans-serif", font_size='25px', fill='black')) # http://www.svgbasics.com/using_fonts.html # http://www.w3.org/TR/2008/REC-CSS2-20080411/fonts.html#propdef-font-family # 'serif', 'sans-serif', 'cursive', 'fantasy', and 'monospace' from the CSS specification # You can also use other family names like "Times", "Baskerville", "Verdena", and "Symbol." I got those names from the CSS specification and some experimenting, but I'm looking for more. # 'font-weight' Value: normal | bold + others. for line_count, line in enumerate(open(RGB_TXT)): colour_item = line.split('\t') # strip the trailing newline \n char then split by the tab chars colour_item = line.strip().split('\t') rgb = hex_to_rgb(colour_item[1]) # hsl is also called hls #hsl = #h, l, s = colorsys.rgb_to_hls(r, g, b) # rgb values are integer but colorsys wants float(0..1) and returns float h, l, s = colorsys.rgb_to_hls(rgb[0]/255.0, rgb[1]/255.0, rgb[2]/255.0) hsl = (h, s, l) swatch_x=int(h*1000) # hue by lightness swatch_y=svg_size - 25 - int(l*1000) # hue by saturation #swatch_y=int(s*1000) + 25 ## svg can handle colors in hex mode so no conversion is necessary. group_rec_text = dwg.add(dwg.g()) group_rec_text.add(dwg.rect(insert=(swatch_x, swatch_y), size=(swatch_w, swatch_h), rx=None, ry=None, fill=colour_item[1])) # text is to start on the right side of swatch in the middle. tx_x = int(swatch_x + swatch_w) tx_y = int(swatch_y + swatch_h/2) group_rec_text.add(dwg.text(colour_item[0], insert = (tx_x, tx_y), font_family="sans-serif", font_size='6px', fill='white', stroke='black', stroke_width='0.1px')) dwg.save() if __name__ == '__main__': create_svg(PROGNAME + '_hl.svg') # vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 textwidth=99 svgwrite-1.1.8/examples/mandelbrot.py0000666000000000000000000000320012012650557016042 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman # Purpose: svg examples # Created: 08.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License try: import svgwrite except ImportError: # if svgwrite is not 'installed' append parent dir of __file__ to sys.path import sys, os sys.path.insert(0, os.path.abspath(os.path.split(os.path.abspath(__file__))[0]+'/..')) import svgwrite from svgwrite import rgb def mandelbrot(name): ## {{{ http://code.activestate.com/recipes/577111/ (r2) # Mandelbrot fractal # FB - 201003254 def putpixel(pos, color): mandelbrot_group.add(dwg.circle(center=pos, r=.5, fill=color)) # image size imgx = 160 imgy = 100 # drawing defines the output size dwg = svgwrite.Drawing(name, ('32cm', '20cm'), debug=True) # define a user coordinate system with viewbox() dwg.viewbox(0, 0, imgx, imgy) mandelbrot_group = dwg.add(dwg.g(stroke_width=0, stroke='none')) # drawing area xa = -2.0 xb = 1.0 ya = -1.5 yb = 1.5 maxIt = 255 # max iterations allowed for y in range(imgy): zy = y * (yb - ya) / (imgy - 1) + ya for x in range(imgx): zx = x * (xb - xa) / (imgx - 1) + xa z = zx + zy * 1j c = z for i in range(maxIt): if abs(z) > 2.0: break z = z * z + c putpixel((x, y), rgb(i % 4 * 64, i % 8 * 32, i % 16 * 16)) dwg.save() ## end of http://code.activestate.com/recipes/577111/ }}} if __name__ == '__main__': mandelbrot("mandelbrot.svg") svgwrite-1.1.8/examples/marker.py0000666000000000000000000000663712346556113015220 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman # Purpose: svg examples # Created: 08.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License try: import svgwrite except ImportError: # if svgwrite is not 'installed' append parent dir of __file__ to sys.path import sys, os sys.path.insert(0, os.path.abspath(os.path.split(os.path.abspath(__file__))[0]+'/..')) import svgwrite def marker(name): # Shows how to use the element. # W3C reference: http://www.w3.org/TR/SVG11/painting.html#MarkerElement # dwg = svgwrite.Drawing(name, size=('20cm', '15cm'), profile='full', debug=True) # set user coordinate space dwg.viewbox(width=200, height=150) #--start-- A red point as marker-start element # 'insert' represents the insertation point in user coordinate space # in this example its the midpoint of the circle, see below marker_start = dwg.marker(insert=(0, 0), size=(5, 5)) # target size of the marker # setting a user coordinate space for the appanded graphic elements # bounding coordinates for this example: # minx = -5, maxx = +5, miny = -5, maxy = +5 marker_start.viewbox(minx=-5, miny=-5, width=10, height=10) # the marker user coordinate space marker_start.add(dwg.circle((0, 0), r=5)).fill('red', opacity=0.5) #--end-- A blue point as marker-end element # a shorter form of the code above: marker_end = dwg.marker(size=(5, 5)) # marker defaults: insert=(0,0) # set viewbox to the bounding coordinates of the circle marker_end.viewbox(-1, -1, 2, 2) marker_end.add(dwg.circle(fill='blue', fill_opacity=0.5)) # circle defaults: insert=(0,0), r=1 #--mid-- A green point as marker-mid element # if you don't setup a user coordinate space, the default ucs is # minx = 0, miny = 0, maxx=size[0], maxy=size[1] # default size = (3, 3) defined by the SVG standard # bounding coordinates for this example: # minx = 0, maxx = 6, miny = 0, maxy = 6 # => center of the viewbox = (3, 3)! marker_mid = dwg.marker(insert=(3, 3), size=(6, 6)) marker_mid.add(dwg.circle((3, 3), r=3)).fill('green', opacity=0.7) # The drawing size of the 'start-marker' is greater than the drawing size of # the 'marker-mid' (r=5 > r=3), but the resulting size is defined by the # 'size' parameter of the marker object (size=(6,6) > size=(5,5)), so the # 'marker-start' is smaller than the 'marker-mid'. # add marker to defs section of the drawing dwg.defs.add(marker_start) dwg.defs.add(marker_mid) dwg.defs.add(marker_end) # create a new line object, fill='none' is important, because by default # the polyline and the polygon object is filled (tested with FF, Chrome). # I am not sure, if this is concurring to the SVG Standard. line = dwg.add(dwg.polyline( [(10, 10), (50, 20), (70, 50), (100, 30), (120, 140), (170, 100)], stroke='black', fill='none')) # set markers 3-tuple = ('marker-start', 'marker-mid', 'marker-end') line.set_markers( (marker_start, marker_mid, marker_end) ) # or set markers direct as SVG Attributes 'marker-start', 'marker-mid', # 'marker-end' or 'marker' if all markers are the same. # line['marker'] = marker.get_funciri() # but 'marker' works only with Firefox (26.10.2010) dwg.save() if __name__ == '__main__': marker("marker.svg") svgwrite-1.1.8/examples/pattern.py0000666000000000000000000000160112012651621015364 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman # Purpose: svg examples # Created: 08.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License try: import svgwrite except ImportError: # if svgwrite is not 'installed' append parent dir of __file__ to sys.path import sys, os sys.path.insert(0, os.path.abspath(os.path.split(os.path.abspath(__file__))[0]+'/..')) import svgwrite def pattern(name): dwg = svgwrite.Drawing(name, size=('20cm', '15cm'), profile='full', debug=True) # set user coordinate space dwg.viewbox(width=200, height=150) pattern = dwg.defs.add( dwg.pattern(size=(20, 20), patternUnits="userSpaceOnUse")) pattern.add(dwg.circle((10, 10), 5)) dwg.add(dwg.circle((100, 100), 50, fill=pattern.get_paint_server())) dwg.save() if __name__ == '__main__': pattern("pattern.svg") svgwrite-1.1.8/examples/radialGradient.py0000666000000000000000000000234612012651621016630 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman # Purpose: svg examples # Created: 08.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License try: import svgwrite except ImportError: # if svgwrite is not 'installed' append parent dir of __file__ to sys.path import sys, os sys.path.insert(0, os.path.abspath(os.path.split(os.path.abspath(__file__))[0]+'/..')) import svgwrite def radialGradient(name): dwg = svgwrite.Drawing(name, size=('20cm', '15cm'), profile='full', debug=True) # set user coordinate space dwg.viewbox(width=200, height=150) # create a new radialGradient element and add it to the defs section of # the drawing gradient1 = dwg.defs.add(dwg.radialGradient()) # define the gradient from red to white gradient1.add_stop_color(0, 'red').add_stop_color(1, 'white') # use gradient for filling the rect dwg.add(dwg.rect((10,10), (50,50), fill=gradient1.get_paint_server())) wave = dwg.defs.add(dwg.radialGradient()) wave.add_colors(['blue', 'lightblue'] * 8) dwg.add(dwg.rect((70,10), (50,50), fill=wave.get_paint_server())) dwg.save() if __name__ == '__main__': radialGradient("radialGradient.svg") svgwrite-1.1.8/examples/runall.bat0000777000000000000000000000005012157476621015341 0ustar 00000000000000@echo off for %%e in (*.py) do py %%e svgwrite-1.1.8/examples/runall.sh0000666000000000000000000000010411465723167015203 0ustar 00000000000000#!/bin/sh for f in `ls *.py` do echo running $f ... python $f done svgwrite-1.1.8/examples/runall3.bat0000777000000000000000000000005312157476603015427 0ustar 00000000000000@echo off for %%e in (*.py) do py -3 %%e svgwrite-1.1.8/examples/runallpypy.bat0000777000000000000000000000007212157477715016274 0ustar 00000000000000@echo off for %%e in (*.py) do c:\pypy-2.0\pypy.exe %%e svgwrite-1.1.8/examples/simple_text.py0000666000000000000000000000321012716244317016255 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman # Purpose: svg examples # Created: 08.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License from __future__ import unicode_literals try: import svgwrite except ImportError: # if svgwrite is not 'installed' append parent dir of __file__ to sys.path import sys, os sys.path.insert(0, os.path.abspath(os.path.split(os.path.abspath(__file__))[0]+'/..')) import svgwrite def simple_text(name): dwg = svgwrite.Drawing(name, (200, 200), debug=True) paragraph = dwg.add(dwg.g(font_size=14)) paragraph.add(dwg.text("This is a Test!", (10, 20))) # 'x', 'y', 'dx', 'dy' and 'rotate' has to be a or a !!! # 'param'[0] .. first letter, 'param'[1] .. second letter, and so on # if there are more letters than values, the last list-value is used # # different 'y' coordinates does not work with Firefox 3.6 paragraph.add(dwg.text("This is a Test", x=[10], y=[40, 45, 50, 55, 60])) # different formats can be used by the TSpan element # The atext.tspan(...) method is a shortcut for: atext.add(dwg.tspan(...)) atext = dwg.text("A", insert=(10, 80), style="text-shadow: 2px 2px;") # text color is set by the 'fill' property and 'stroke sets the outline color. atext.add(dwg.tspan(' Word', font_size='1.5em', fill='red')) atext.add(dwg.tspan(' is a Word!', dy=['1em'], font_size='0.7em', fill='green')) paragraph.add(dwg.text("Das ist ein Test mit ÖÄÜäüö!", (10, 120))) paragraph.add(atext) dwg.save() if __name__ == '__main__': simple_text("simple_text.svg") svgwrite-1.1.8/examples/use.py0000666000000000000000000000274612012650555014523 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman # Purpose: svg examples # Created: 08.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License try: import svgwrite except ImportError: # if svgwrite is not 'installed' append parent dir of __file__ to sys.path import sys, os sys.path.insert(0, os.path.abspath(os.path.split(os.path.abspath(__file__))[0]+'/..')) import svgwrite from svgwrite import cm, mm, rgb, deg def use(name): # Shows how to use the 'use' element. # w, h = '100%', '100%' dwg = svgwrite.Drawing(filename=name, size=(w, h), debug=True) dwg.add(dwg.rect(insert=(0,0), size=(w, h), fill='lightgray', stroke='black')) # add a group of graphic elements to the defs section of the main drawing g = dwg.defs.add(dwg.g(id='g001')) unit=40 g.add(dwg.rect((0,0), (unit, unit))) for y in range(10): for x in range(5): x1 = 2*unit+2*unit*x y1 = 2*unit+2*unit*y cx = x1 + unit/2 cy = y1 + unit/2 cval = (y*5 + x)*2 # reference the group by the 'use' element, you can overwrite # graphical properties, ... u = dwg.use(g, insert=(x1, y1), fill=rgb(cval, cval, cval)) # ... and you can also transform the the whole reference object. u.rotate(y*5+x, center=(cx, cy)) dwg.add(u) dwg.save() if __name__ == '__main__': use("use.svg") svgwrite-1.1.8/LICENSE.TXT0000666000000000000000000000427512004155061013212 0ustar 00000000000000Copyright (c) 2012, Manfred Moitzi Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Deutsche Übersetzung: Copyright (c) 2012, Manfred Moitzi Hiermit wird unentgeltlich, jeder Person, die eine Kopie der Software und der zugehörigen Dokumentationen (die "Software") erhält, die Erlaubnis erteilt, uneingeschränkt zu benutzen, inklusive und ohne Ausnahme, dem Recht, sie zu verwenden, kopieren, ändern, fusionieren, verlegen, verbreiten, unterlizenzieren und/oder zu verkaufen, und Personen, die diese Software erhalten, diese Rechte zu geben, unter den folgenden Bedingungen: Der obige Urheberrechtsvermerk und dieser Erlaubnisvermerk sind in allen Kopien oder Teilkopien der Software beizulegen. DIE SOFTWARE WIRD OHNE JEDE AUSDRÜCKLICHE ODER IMPLIZIERTE GARANTIE BEREITGESTELLT, EINSCHLIESSLICH DER GARANTIE ZUR BENUTZUNG FÜR DEN VORGESEHENEN ODER EINEM BESTIMMTEN ZWECK SOWIE JEGLICHER RECHTSVERLETZUNG, JEDOCH NICHT DARAUF BESCHRÄNKT. IN KEINEM FALL SIND DIE AUTOREN ODER COPYRIGHTINHABER FÜR JEGLICHEN SCHADEN ODER SONSTIGE ANSPRÜCHE HAFTBAR ZU MACHEN, OB INFOLGE DER ERFÜLLUNG EINES VERTRAGES, EINES DELIKTES ODER ANDERS IM ZUSAMMENHANG MIT DER SOFTWARE ODER SONSTIGER VERWENDUNG DER SOFTWARE ENTSTANDEN. svgwrite-1.1.8/MANIFEST.in0000666000000000000000000000021712721462742013272 0ustar 00000000000000include NEWS.rst README.rst LICENSE.TXT include requirements.txt recursive-include examples *.py *.bat *.sh *.txt recursive-include tests *.py svgwrite-1.1.8/NEWS.rst0000666000000000000000000000627112723216605013045 0ustar 00000000000000 NEWS ==== Version 1.1.8 - 2016-05-31 * BUGFIX: None checks: 'if value:' -> 'if value is not None:' Version 1.1.7 - 2016-05-22 * BUGFIX: color accepts percentage values as floats like "rgb(10.2%, 3.78%, 20%)" Version 1.1.6 - 2014-05-30 * BUGFIX: sign for offset-value wasn't optional Version 1.1.5 - 2014-03-26 * BUGFIX: xml serialization for CPython 3.4.0 Version 1.1.4 - 2014-03-16 * simplified path parser * pyparsing as external dependency (by jenselme) Version 1.1.3 - 2013-10-01 * updated pyparsing for Python 3 to version 2.0.1 (prior version caused memory leaks) * BUGFIX: utf8 to unicode encoding error for Python 2.7 * Tests for Python 3 require CPython3.3 or newer, using the 'u' prefix. Version 1.1.2 - 2013-01-08 * prevent setup.py from compiling all modules - error with 'pyparsing_py2.py' and Python3 * BUGFIX: all tests run with CPython3.3 Version 1.1.1 - 2012-08-15 * License changed to MIT License * tested with CPython2.7, CPython3.2, CPython3.3 and pypy-1.9 on Win7 Pro 32-bit * BUGFIX: dwg.animateTranform() -> dwg.animateTransform() * BUGFIX: in examples, replaced width and height params by size parameter * added examples * edit docs Version 1.0.1 - 2012-06-08 * added inline stylesheets * added examples created by Lawrence Tattrie Version 1.0.0 - 2012-05-27 * stable * tested with CPython 2.7, CPython 3.2, pypy-1.8 * added script tag - thx to jmahmood * docs also available at: http://readthedocs.org/docs/svgwrite Version 0.2.4 - 2011-12-30 * beta version * Python 2.7: all strings will be converted by the unicode() function, for strings containing none-ascii-characters use prefix ``u""`` or better use ``from __future__ import unicode_literals``, because this is Python 3 compatible. * tested with CPython 2.7, CPython 3.2, and PyPy 1.7 * BUGFIX: color parsing accepts white spaces in ``rgb()`` like ``rgb(0, 0, 0)`` Version 0.2.3 - 2010-11-13 * beta version * Python 3.1 support * splitted examples.py into several files and moved them to the subdir 'examples' Version 0.2.2 - 2010-11-05 * alpha version * removed 'attribs' parameter from all constructors * new elements: Set, Animate, AnimateMotion, AnimateColor, AnimateTransform, all filter elements * added set_desc(title, desc), set_metadata(xmldata) to BaseElement class * moved content of interfaces.py to mixins.py, (ITransform -> Transform and so on) Version 0.2.1 - 2010-10-31 * alpha version * new elements: Marker, ClipPath, Mask * paint service: LinearGradient, RadialGradient, Pattern Version 0.2.0 - 2010-10-24 * alpha version * validator rewritten as validator2.py * debug and profile options separated for each drawing object * important change: create objects with factory functions of the *Drawing* class: drawing.(...) * added mixins for setting stroke and fill properties * new elements: Hyperlink, Image, TextArea, Version 0.1.0 - 2010-09-26 * alpha version * new elements: * basic shapes: Line, Rect, Circle, Ellipse, Polyline, Polygon, Path * text elements: Text, TSpan, TRef, TextPath * container elements: Group, Symbol, SVG, Use, Defs * for examples see: examples.py svgwrite-1.1.8/PKG-INFO0000666000000000000000000001600412723217123012623 0ustar 00000000000000Metadata-Version: 1.1 Name: svgwrite Version: 1.1.8 Summary: A Python library to create SVG drawings. Home-page: http://bitbucket.org/mozman/svgwrite Author: Manfred Moitzi Author-email: mozman@gmx.at License: MIT License Download-URL: http://bitbucket.org/mozman/svgwrite/downloads Description: svgwrite ======== .. image:: https://readthedocs.org/projects/pip/badge/ :target: https://svgwrite.readthedocs.io :alt: Read The Docs .. image:: https://img.shields.io/pypi/l/svgwrite.svg :target: https://pypi.python.org/pypi/svgwrite/ :alt: License .. image:: https://img.shields.io/pypi/pyversions/svgwrite.svg :target: https://pypi.python.org/pypi/svgwrite/ :alt: Python Versions .. image:: https://img.shields.io/pypi/wheel/svgwrite.svg :target: https://pypi.python.org/pypi/svgwrite/ :alt: Wheel Status .. image:: https://img.shields.io/pypi/status/svgwrite.svg :target: https://pypi.python.org/pypi/svgwrite/ :alt: Status Abstract ======== A Python library to create SVG drawings. a simple example:: import svgwrite dwg = svgwrite.Drawing('test.svg', profile='tiny') dwg.add(dwg.line((0, 0), (10, 0), stroke=svgwrite.rgb(10, 10, 16, '%'))) dwg.add(dwg.text('Test', insert=(0, 0.2), fill='red')) dwg.save() for more examples see: examples.py Installation ============ with pip:: pip install svgwrite or from source:: python setup.py install Documentation ============= * http://packages.python.org/svgwrite * http://readthedocs.org/docs/svgwrite/ send feedback to mozman@gmx.at svgwrite can be found on bitbucket.org at: http://bitbucket.org/mozman/svgwrite NEWS ==== Version 1.1.8 - 2016-05-31 * BUGFIX: None checks: 'if value:' -> 'if value is not None:' Version 1.1.7 - 2016-05-22 * BUGFIX: color accepts percentage values as floats like "rgb(10.2%, 3.78%, 20%)" Version 1.1.6 - 2014-05-30 * BUGFIX: sign for offset-value wasn't optional Version 1.1.5 - 2014-03-26 * BUGFIX: xml serialization for CPython 3.4.0 Version 1.1.4 - 2014-03-16 * simplified path parser * pyparsing as external dependency (by jenselme) Version 1.1.3 - 2013-10-01 * updated pyparsing for Python 3 to version 2.0.1 (prior version caused memory leaks) * BUGFIX: utf8 to unicode encoding error for Python 2.7 * Tests for Python 3 require CPython3.3 or newer, using the 'u' prefix. Version 1.1.2 - 2013-01-08 * prevent setup.py from compiling all modules - error with 'pyparsing_py2.py' and Python3 * BUGFIX: all tests run with CPython3.3 Version 1.1.1 - 2012-08-15 * License changed to MIT License * tested with CPython2.7, CPython3.2, CPython3.3 and pypy-1.9 on Win7 Pro 32-bit * BUGFIX: dwg.animateTranform() -> dwg.animateTransform() * BUGFIX: in examples, replaced width and height params by size parameter * added examples * edit docs Version 1.0.1 - 2012-06-08 * added inline stylesheets * added examples created by Lawrence Tattrie Version 1.0.0 - 2012-05-27 * stable * tested with CPython 2.7, CPython 3.2, pypy-1.8 * added script tag - thx to jmahmood * docs also available at: http://readthedocs.org/docs/svgwrite Version 0.2.4 - 2011-12-30 * beta version * Python 2.7: all strings will be converted by the unicode() function, for strings containing none-ascii-characters use prefix ``u""`` or better use ``from __future__ import unicode_literals``, because this is Python 3 compatible. * tested with CPython 2.7, CPython 3.2, and PyPy 1.7 * BUGFIX: color parsing accepts white spaces in ``rgb()`` like ``rgb(0, 0, 0)`` Version 0.2.3 - 2010-11-13 * beta version * Python 3.1 support * splitted examples.py into several files and moved them to the subdir 'examples' Version 0.2.2 - 2010-11-05 * alpha version * removed 'attribs' parameter from all constructors * new elements: Set, Animate, AnimateMotion, AnimateColor, AnimateTransform, all filter elements * added set_desc(title, desc), set_metadata(xmldata) to BaseElement class * moved content of interfaces.py to mixins.py, (ITransform -> Transform and so on) Version 0.2.1 - 2010-10-31 * alpha version * new elements: Marker, ClipPath, Mask * paint service: LinearGradient, RadialGradient, Pattern Version 0.2.0 - 2010-10-24 * alpha version * validator rewritten as validator2.py * debug and profile options separated for each drawing object * important change: create objects with factory functions of the *Drawing* class: drawing.(...) * added mixins for setting stroke and fill properties * new elements: Hyperlink, Image, TextArea, Version 0.1.0 - 2010-09-26 * alpha version * new elements: * basic shapes: Line, Rect, Circle, Ellipse, Polyline, Polygon, Path * text elements: Text, TSpan, TRef, TextPath * container elements: Group, Symbol, SVG, Use, Defs * for examples see: examples.py Platform: OS Independent Classifier: Development Status :: 5 - Production/Stable Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Intended Audience :: Developers Classifier: Topic :: Multimedia :: Graphics Classifier: Topic :: Software Development :: Libraries :: Python Modules Provides: svgwrite svgwrite-1.1.8/README.rst0000666000000000000000000000250412721462676013232 0ustar 00000000000000 svgwrite ======== .. image:: https://readthedocs.org/projects/pip/badge/ :target: https://svgwrite.readthedocs.io :alt: Read The Docs .. image:: https://img.shields.io/pypi/l/svgwrite.svg :target: https://pypi.python.org/pypi/svgwrite/ :alt: License .. image:: https://img.shields.io/pypi/pyversions/svgwrite.svg :target: https://pypi.python.org/pypi/svgwrite/ :alt: Python Versions .. image:: https://img.shields.io/pypi/wheel/svgwrite.svg :target: https://pypi.python.org/pypi/svgwrite/ :alt: Wheel Status .. image:: https://img.shields.io/pypi/status/svgwrite.svg :target: https://pypi.python.org/pypi/svgwrite/ :alt: Status Abstract ======== A Python library to create SVG drawings. a simple example:: import svgwrite dwg = svgwrite.Drawing('test.svg', profile='tiny') dwg.add(dwg.line((0, 0), (10, 0), stroke=svgwrite.rgb(10, 10, 16, '%'))) dwg.add(dwg.text('Test', insert=(0, 0.2), fill='red')) dwg.save() for more examples see: examples.py Installation ============ with pip:: pip install svgwrite or from source:: python setup.py install Documentation ============= * http://packages.python.org/svgwrite * http://readthedocs.org/docs/svgwrite/ send feedback to mozman@gmx.at svgwrite can be found on bitbucket.org at: http://bitbucket.org/mozman/svgwrite svgwrite-1.1.8/requirements.txt0000666000000000000000000000002012311240722014773 0ustar 00000000000000pyparsing>=2.0.1svgwrite-1.1.8/setup.cfg0000666000000000000000000000010012723217123013335 0ustar 00000000000000[egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 svgwrite-1.1.8/setup.py0000666000000000000000000000333712723215572013253 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman # Purpose: setup # Created: 08.09.2010 # License: MIT License # Copyright (C) 2010-2012 Manfred Moitzi import os from setuptools import setup VERSION = '1.1.8' # also update __init__.py AUTHOR_NAME = 'Manfred Moitzi' AUTHOR_EMAIL = 'mozman@gmx.at' def read(fname): try: return open(os.path.join(os.path.dirname(__file__), fname)).read() except IOError: return "File '%s' not found.\n" % fname setup(name='svgwrite', version=VERSION, description='A Python library to create SVG drawings.', author=AUTHOR_NAME, url='http://bitbucket.org/mozman/svgwrite', download_url='http://bitbucket.org/mozman/svgwrite/downloads', author_email=AUTHOR_EMAIL, packages=['svgwrite', 'svgwrite/data'], provides=['svgwrite'], install_requires=['pyparsing>=2.0.1'], long_description=read('README.rst') + read('NEWS.rst'), platforms="OS Independent", license="MIT License", classifiers=[ "Development Status :: 5 - Production/Stable", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Intended Audience :: Developers", "Topic :: Multimedia :: Graphics", "Topic :: Software Development :: Libraries :: Python Modules", ] ) svgwrite-1.1.8/svgwrite/0000777000000000000000000000000012723217123013377 5ustar 00000000000000svgwrite-1.1.8/svgwrite/animate.py0000666000000000000000000001500112342007205015357 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: animate elements # Created: 31.10.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License from svgwrite.base import BaseElement from svgwrite.mixins import XLink from svgwrite.utils import strlist, is_string class Set(BaseElement, XLink): """ The **set** element provides a simple means of just setting the value of an attribute for a specified duration. It supports all attribute types, including those that cannot reasonably be interpolated, such as string and boolean values. The **set** element is non-additive. The additive and accumulate attributes are not allowed, and will be ignored if specified. """ elementname = 'set' def __init__(self, href=None, **extra): """ Set constructor. :param href: target svg element, if **href** is not `None`; else the target SVG Element is the parent SVG Element. """ super(Set, self).__init__(**extra) if href is not None: self.set_href(href) def get_xml(self): self.update_id() # if href is an object - 'id' - attribute may be changed! return super(Set, self).get_xml() def set_target(self, attributeName, attributeType=None): """ Set animation attributes :ref:`attributeName` and :ref:`attributeType`. """ self['attributeName'] = attributeName if attributeType is not None: self['attributeType'] = attributeType def set_event(self, onbegin=None, onend=None, onrepeat=None, onload=None): """ Set animation attributes :ref:`onbegin`, :ref:`onend`, :ref:`onrepeat` and :ref:`onload`. """ if onbegin is not None: self['onbegin'] = onbegin if onend is not None: self['onend'] = onend if onrepeat is not None: self['onrepeat'] = onrepeat if onload is not None: self['onload'] = onload def set_timing(self, begin=None, end=None, dur=None, min=None, max=None, restart=None, repeatCount=None, repeatDur=None): """ Set animation attributes :ref:`begin`, :ref:`end`, :ref:`dur`, :ref:`min`, :ref:`max`, :ref:`restart`, :ref:`repeatCount` and :ref:`repeatDur`. """ if begin is not None: self['begin'] = begin if end is not None: self['end'] = end if dur is not None: self['dur'] = dur if min is not None: self['min'] = min if max is not None: self['max'] = max if restart is not None: self['restart'] = restart if repeatCount is not None: self['repeatCount'] = repeatCount if repeatDur is not None: self['repeatDur'] = repeatDur def freeze(self): """ Freeze the animation effect. (see also :ref:`fill `) """ self['fill'] = 'freeze' class AnimateMotion(Set): """ The **animateMotion** element causes a referenced element to move along a motion path. """ elementname = 'animateMotion' def __init__(self, path=None, href=None, **extra): """ :param path: the motion path :param href: target svg element, if **href** is not `None`; else the target SVG Element is the parent SVG Element. """ super(AnimateMotion, self).__init__(href=href, **extra) if path is not None: self['path'] = path def set_value(self, path=None, calcMode=None, keyPoints=None, rotate=None): """ Set animation attributes `path`, `calcMode`, `keyPoints` and `rotate`. """ if path is not None: self['path'] = path if calcMode is not None: self['calcMode'] = calcMode if keyPoints is not None: self['keyPoints'] = keyPoints if rotate is not None: self['rotate'] = rotate class Animate(Set): """ The **animate** element allows scalar attributes and properties to be assigned different values over time . """ elementname = 'animate' def __init__(self, attributeName=None, values=None, href=None, **extra): """ :param attributeName: name of the SVG Attribute to animate :param values: interpolation values, `string` as `` or a python `list` :param href: target svg element, if **href** is not `None`; else the target SVG Element is the parent SVG Element. """ super(Animate, self).__init__(href=href, **extra) if values is not None: self.set_value(values) if attributeName is not None: self.set_target(attributeName) def set_value(self, values, calcMode=None, keyTimes=None, keySplines=None, from_=None, to=None, by=None): """ Set animation attributes :ref:`values`, :ref:`calcMode`, :ref:`keyTimes`, :ref:`keySplines`, :ref:`from`, :ref:`to` and :ref:`by`. """ if values is not None: if not is_string(values): values = strlist(values, ';') self['values'] = values if calcMode is not None: self['calcMode'] = calcMode if keyTimes is not None: self['keyTimes'] = keyTimes if keySplines is not None: self['keySplines'] = keySplines if from_ is not None: self['from'] = from_ if to is not None: self['to'] = to if by is not None: self['by'] = by class AnimateColor(Animate): """ The **animateColor** element specifies a color transformation over time. """ elementname = 'animateColor' class AnimateTransform(Animate): """ The **animateTransform** element animates a transformation attribute on a target element, thereby allowing animations to control translation, scaling, rotation and/or skewing. """ elementname = 'animateTransform' def __init__(self, transform, element=None, **extra): """ :param element: target svg element, if element is not `None`; else the target svg element is the parent svg element. :param string transform: ``'translate | scale | rotate | skewX | skewY'`` """ super(AnimateTransform, self).__init__(element, **extra) self['type'] = transform svgwrite-1.1.8/svgwrite/base.py0000666000000000000000000001760012270366736014703 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman # Purpose: svg base element # Created: 08.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License """ The **BaseElement** is the root for all SVG elements. """ from svgwrite.etree import etree import copy from svgwrite.params import Parameter from svgwrite.utils import AutoID, to_unicode, PYTHON3 class BaseElement(object): """ The **BaseElement** is the root for all SVG elements. The SVG attributes are stored in **attribs**, and the SVG subelements are stored in **elements**. """ elementname = 'baseElement' def __init__(self, **extra): """ :param extra: extra SVG attributes (keyword arguments) * add trailing '_' to reserved keywords: ``'class_'``, ``'from_'`` * replace inner '-' by '_': ``'stroke_width'`` SVG attribute names will be checked, if **debug** is `True`. workaround for removed **attribs** parameter in Version 0.2.2:: # replace element = BaseElement(attribs=adict) #by element = BaseElement() element.update(adict) """ # the keyword 'factory' specifies the object creator factory = extra.pop('factory', None) if factory is not None: # take parameter from 'factory' self._parameter = factory._parameter else: # default parameter debug=True profile='full' self._parameter = Parameter() # override debug setting debug = extra.pop('debug', None) if debug is not None: self._parameter.debug = debug # override profile setting profile = extra.pop('profile', None) if profile is not None: self._parameter.profile = profile self.attribs = dict() self.update(extra) self.elements = list() def update(self, attribs): """ Update SVG Attributes from `dict` attribs. Rules for keys: 1. trailing '_' will be removed (``'class_'`` -> ``'class'``) 2. inner '_' will be replaced by '-' (``'stroke_width'`` -> ``'stroke-width'``) """ for key, value in attribs.items(): # remove trailing underscores # and replace inner underscores key = key.rstrip('_').replace('_', '-') self.__setitem__(key, value) def copy(self): newobj = copy.copy(self) # shallow copy of object newobj.attribs = copy.copy(self.attribs) # shallow copy of attributes newobj.elements = copy.copy(self.elements) # shallow copy of subelements if 'id' in newobj.attribs: # create a new 'id' newobj['id'] = newobj.next_id() return newobj @property def debug(self): return self._parameter.debug @property def profile(self): return self._parameter.profile @property def validator(self): return self._parameter.validator @property def version(self): return self._parameter.get_version() def set_parameter(self, parameter): self._parameter = parameter def next_id(self, value=None): return AutoID.next_id(value) def get_id(self): """ Get the object `id` string, if the object does not have an `id`, a new `id` will be created. :returns: `string` """ if 'id' not in self.attribs: self.attribs['id'] = self.next_id() return self.attribs['id'] def get_iri(self): """ Get the `IRI` reference string of the object. (i.e., ``'#id'``). :returns: `string` """ return "#%s" % self.get_id() def get_funciri(self): """ Get the `FuncIRI` reference string of the object. (i.e. ``'url(#id)'``). :returns: `string` """ return "url(%s)" % self.get_iri() def __getitem__(self, key): """ Get SVG attribute by `key`. :param string key: SVG attribute name :return: SVG attribute value """ return self.attribs[key] def __setitem__(self, key, value): """ Set SVG attribute by `key` to `value`. :param string key: SVG attribute name :param object value: SVG attribute value """ # Attribute checking is only done by using the __setitem__() method or # by self['attribute'] = value if self.debug: self.validator.check_svg_attribute_value(self.elementname, key, value) self.attribs[key] = value def add(self, element): """ Add an SVG element as subelement. :param element: append this SVG element :returns: the added element """ if self.debug: self.validator.check_valid_children(self.elementname, element.elementname) self.elements.append(element) return element def tostring(self): """ Get the XML representation as unicode `string`. :return: unicode XML string of this object and all its subelements """ xml = self.get_xml() xml_utf8_str = etree.tostring(xml, encoding='utf-8') return xml_utf8_str.decode('utf-8') def get_xml(self): """ Get the XML representation as `ElementTree` object. :return: XML `ElementTree` of this object and all its subelements """ xml = etree.Element(self.elementname) if self.debug: self.validator.check_all_svg_attribute_values(self.elementname, self.attribs) for attribute, value in self.attribs.items(): # filter 'None' values if value is not None: value = self.value_to_string(value) if value: # just add not empty attributes xml.set(attribute, value) for element in self.elements: xml.append(element.get_xml()) return xml def value_to_string(self, value): """ Converts *value* into a includes a value check, depending on :attr:`self.debug` and :attr:`self.profile`. """ if isinstance(value, (int, float)): if self.debug: self.validator.check_svg_type(value, 'number') if isinstance(value, float) and self.profile == 'tiny': value = round(value, 4) return to_unicode(value) def set_desc(self, title=None, desc=None): """ Insert a **title** and/or a **desc** element as first subelement. """ if desc is not None: self.elements.insert(0, Desc(desc)) if title is not None: self.elements.insert(0, Title(title)) def set_metadata(self, xmldata): """ :param xmldata: an xml.etree.ElementTree - Element() object. """ metadata = Metadata(xmldata) if len(self.elements) == 0: self.elements.append(metadata) else: pos = 0 while self.elements[pos].elementname in ('title', 'desc'): pos += 1 if pos == len(self.elements): self.elements.append(metadata) return self.elements.insert(pos, metadata) class Title(object): elementname = 'title' def __init__(self, text): self.xml = etree.Element(self.elementname) self.xml.text = to_unicode(text) def get_xml(self): return self.xml class Desc(Title): elementname = 'desc' class Metadata(Title): elementname = 'metadata' def __init__(self, xmldata): """ :param xmldata: an xml.etree.ElementTree - Element() object. """ self.xml = etree.Element('metadata') self.xml.append(xmldata) svgwrite-1.1.8/svgwrite/container.py0000666000000000000000000002162512723216061015741 0ustar 00000000000000#coding:utf-8 # Author: mozman # Purpose: svg container classes # Created: 15.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License """ The **container** module provides following structural objects: * :class:`svgwrite.Group` * :class:`svgwrite.SVG` * :class:`svgwrite.Defs` * :class:`svgwrite.Symbol` * :class:`svgwrite.Marker` * :class:`svgwrite.Use` * :class:`svgwrite.Hyperlink` * :class:`svgwrite.Script` * :class:`svgwrite.Style` set/get SVG attributes:: element['attribute'] = value value = element['attribute'] """ from svgwrite.base import BaseElement from svgwrite.mixins import ViewBox, Transform, XLink from svgwrite.mixins import Presentation, Clipping from svgwrite.etree import CDATA class Group(BaseElement, Transform, Presentation): """ The **Group** (SVG **g**) element is a container element for grouping together related graphics elements. Grouping constructs, when used in conjunction with the **desc** and **title** elements, provide information about document structure and semantics. Documents that are rich in structure may be rendered graphically, as speech, or as braille, and thus promote accessibility. A group of elements, as well as individual objects, can be given a name using the **id** attribute. Named groups are needed for several purposes such as animation and re-usable objects. """ elementname = 'g' class Defs(Group): """ The **defs** element is a container element for referenced elements. For understandability and accessibility reasons, it is recommended that, whenever possible, referenced elements be defined inside of a **defs**. """ elementname = 'defs' class Symbol(BaseElement, ViewBox, Presentation, Clipping): """ The **symbol** element is used to define graphical template objects which can be instantiated by a **use** element. The use of **symbol** elements for graphics that are used multiple times in the same document adds structure and semantics. Documents that are rich in structure may be rendered graphically, as speech, or as braille, and thus promote accessibility. """ # ITransform interface is not valid for Symbol -> do not inherit from Group elementname = 'symbol' class Marker(BaseElement, ViewBox, Presentation): """ The **marker** element defines the graphics that is to be used for drawing arrowheads or polymarkers on a given **path**, **line**, **polyline** or **polygon** element. Add Marker definitions to a **defs** section, preferred to the **defs** section of the **main drawing**. """ elementname = 'marker' def __init__(self, insert=None, size=None, orient=None, **extra): """ :param 2-tuple insert: reference point (**refX**, **refY**) :param 2-tuple size: (**markerWidth**, **markerHeight**) :param orient: ``'auto'`` | `angle` :param extra: additional SVG attributes as keyword-arguments """ super(Marker, self).__init__(**extra) if insert is not None: self['refX'] = insert[0] self['refY'] = insert[1] if size is not None: self['markerWidth'] = size[0] self['markerHeight'] = size[1] if orient is not None: self['orient'] = orient if 'id' not in self.attribs: # an 'id' is necessary self['id'] = self.next_id() class SVG(Symbol): """ An SVG document fragment consists of any number of SVG elements contained within an **svg** element. An SVG document fragment can range from an empty fragment (i.e., no content inside of the **svg** element), to a very simple SVG document fragment containing a single SVG graphics element such as a **rect**, to a complex, deeply nested collection of container elements and graphics elements. """ elementname = 'svg' def __init__(self, insert=None, size=None, **extra): """ :param 2-tuple insert: insert position (**x**, **y**) :param 2-tuple size: (**width**, **height**) :param extra: additional SVG attributes as keyword-arguments """ super(SVG, self).__init__(**extra) if insert is not None: self['x'] = insert[0] self['y'] = insert[1] if size is not None: self['width'] = size[0] self['height'] = size[1] self.defs = Defs(factory=self) # defs container self.add(self.defs) # add defs as first element class Use(BaseElement, Transform, XLink, Presentation): """ The **use** element references another element and indicates that the graphical contents of that element is included/drawn at that given point in the document. Link to objects by href = ``'#object-id'`` or use the object itself as href-argument, if the given element has no **id** attribute it gets an automatic generated id. """ elementname = 'use' def __init__(self, href, insert=None, size=None, **extra): """ :param string href: object link (id-string) or an object with an id-attribute :param 2-tuple insert: insert point (**x**, **y**) :param 2-tuple size: (**width**, **height**) :param extra: additional SVG attributes as keyword-arguments """ super(Use, self).__init__(**extra) self.set_href(href) if insert is not None: self['x'] = insert[0] self['y'] = insert[1] if size is not None: self['width'] = size[0] self['height'] = size[1] def get_xml(self): self.update_id() # if href is an object - 'id' - attribute may be changed! return super(Use, self).get_xml() class Hyperlink(BaseElement, Transform, Presentation): """ The **a** element indicate links (also known as Hyperlinks or Web links). The remote resource (the destination for the link) is defined by a `` specified by the XLink **xlink:href** attribute. The remote resource may be any Web resource (e.g., an image, a video clip, a sound bite, a program, another SVG document, an HTML document, an element within the current document, an element within a different document, etc.). By activating these links (by clicking with the mouse, through keyboard input, voice commands, etc.), users may visit these resources. A **Hyperlink** is defined for each separate rendered element contained within the **Hyperlink** class; add sublements as usual with the `add` method. """ elementname = 'a' def __init__(self, href, target='_blank', **extra): """ :param string href: hyperlink to the target resource :param string target: ``'_blank|_replace|_self|_parent|_top|'`` :param extra: additional SVG attributes as keyword-arguments """ super(Hyperlink, self).__init__(**extra) self['xlink:href'] = href self['target'] = target class Script(BaseElement): """ The **script** element indicate links to a client-side language. This is normally a (also known as Hyperlinks or Web links). The remote resource (the source of the script) is defined by a `` specified by the XLink **xlink:href** attribute. The remote resource must be a text-file that contains the script contents. This script can be used within the SVG file by catching events or adding the mouseover/mousedown/ mouseup elements to the markup. """ elementname = 'script' def __init__(self, href=None, content="", **extra): """ :param string href: hyperlink to the target resource or *None* if using *content* :param string content: script content :param extra: additional attributes as keyword-arguments Use *href* **or** *content*, but not both at the same time. """ # removed type parameter, default is "application/ecmascript" super(Script, self).__init__(**extra) if href is not None: self['xlink:href'] = href self._content = content def get_xml(self): xml = super(Script, self).get_xml() if self._content: xml.append(CDATA(self._content)) return xml def append(self, content): """ Append content to the existing element-content. """ self._content += content class Style(Script): """ The *style* element allows style sheets to be embedded directly within SVG content. SVG's *style* element has the same attributes as the corresponding element in HTML. """ elementname = 'style' def __init__(self, content="", **extra): """ :param string content: stylesheet content """ super(Style, self).__init__(content=content, **extra) self['type'] = "text/css" svgwrite-1.1.8/svgwrite/data/0000777000000000000000000000000012723217123014310 5ustar 00000000000000svgwrite-1.1.8/svgwrite/data/colors.py0000666000000000000000000000543512012650555016173 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: colornames # Created: 06.10.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License colornames = frozenset([ 'aliceblue', 'antiquewhite', 'aqua', 'aquamarine', 'azure', 'beige', 'bisque', 'black', 'blanchedalmond', 'blue', 'blueviolet', 'brown', 'burlywood', 'cadetblue', 'chartreuse', 'chocolate', 'coral', 'cornflowerblue', 'cornsilk', 'crimson', 'cyan', 'darkblue', 'darkcyan', 'darkgoldenrod', 'darkgray', 'darkgreen', 'darkgrey', 'darkkhaki', 'darkmagenta', 'darkolivegreen', 'darkorange', 'darkorchid', 'darkred', 'darksalmon', 'darkseagreen', 'darkslateblue', 'darkslategray', 'darkslategrey', 'darkturquoise', 'darkviolet', 'deeppink', 'deepskyblue', 'dimgray', 'dimgrey', 'dodgerblue', 'firebrick', 'floralwhite', 'forestgreen', 'fuchsia', 'gainsboro', 'ghostwhite', 'gold', 'goldenrod', 'gray', 'green', 'greenyellow', 'grey', 'honeydew', 'hotpink', 'indianred', 'indigo', 'ivory', 'khaki', 'lavender', 'lavenderblush', 'lawngreen', 'lemonchiffon', 'lightblue', 'lightcoral', 'lightcyan', 'lightgoldenrodyellow', 'lightgray', 'lightgreen', 'lightgrey', 'lightpink', 'lightsalmon', 'lightseagreen', 'lightskyblue', 'lightslategray', 'lightslategrey', 'lightsteelblue', 'lightyellow', 'lime', 'limegreen', 'linen', 'magenta', 'maroon', 'mediumaquamarine', 'mediumblue', 'mediumorchid', 'mediumpurple', 'mediumseagreen', 'mediumslateblue', 'mediumspringgreen', 'mediumturquoise', 'mediumvioletred', 'midnightblue', 'mintcream', 'mistyrose', 'moccasin', 'navajowhite', 'navy', 'oldlace', 'olive', 'olivedrab', 'orange', 'orangered', 'orchid', 'palegoldenrod', 'palegreen', 'paleturquoise', 'palevioletred', 'papayawhip', 'peachpuff', 'peru', 'pink', 'plum', 'powderblue', 'purple', 'red', 'rosybrown', 'royalblue', 'saddlebrown', 'salmon', 'sandybrown', 'seagreen', 'seashell', 'sienna', 'silver', 'skyblue', 'slateblue', 'slategray', 'slategrey', 'snow', 'springgreen', 'steelblue', 'tan', 'teal', 'thistle', 'tomato', 'turquoise', 'violet', 'wheat', 'white', 'whitesmoke', 'yellow', 'yellowgreen',]) svgwrite-1.1.8/svgwrite/data/full11.py0000666000000000000000000022524512102124054015767 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: full11 data # Created: 15.10.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License from svgwrite.data.types import SVGAttribute, SVGMultiAttribute from svgwrite.data.types import SVGElement from svgwrite.data.typechecker import Full11TypeChecker as TypeChecker empty_list = [] attributes = { 'accent-height': SVGAttribute('accent-height', anim=False, types=frozenset(['number']), const=empty_list), 'accumulate': SVGAttribute('accumulate', anim=False, types=empty_list, const=frozenset(['none', 'sum'])), 'additive': SVGAttribute('additive', anim=False, types=empty_list, const=frozenset(['sum', 'replace'])), 'alignment-baseline': SVGAttribute('alignment-baseline', anim=True, types=empty_list, const=frozenset(['mathematical', 'before-edge', 'central', 'baseline', 'auto', 'hanging', 'ideographic', 'inherit', 'middle', 'alphabetic', 'text-before-edge', 'text-after-edge', 'after-edge'])), 'alphabetic': SVGAttribute('alphabetic', anim=False, types=frozenset(['number']), const=empty_list), 'amplitude': SVGAttribute('amplitude', anim=True, types=frozenset(['number']), const=empty_list), 'arabic-form': SVGAttribute('arabic-form', anim=False, types=empty_list, const=frozenset(['terminal', 'initial', 'isolated', 'medial'])), 'ascent': SVGAttribute('ascent', anim=False, types=frozenset(['number']), const=empty_list), 'attributeName': SVGAttribute('attributeName', anim=False, types=frozenset(['name']), const=empty_list), 'attributeType': SVGAttribute('attributeType', anim=False, types=empty_list, const=frozenset(['XML', 'auto', 'CSS'])), 'azimuth': SVGAttribute('azimuth', anim=True, types=frozenset(['number']), const=empty_list), 'baseFrequency': SVGAttribute('baseFrequency', anim=True, types=frozenset(['number-optional-number']), const=empty_list), 'baseline-shift': SVGAttribute('baseline-shift', anim=True, types=frozenset(['percentage', 'length']), const=frozenset(['super', 'baseline', 'inherit', 'sub'])), 'baseProfile': SVGAttribute('baseProfile', anim=False, types=empty_list, const=frozenset(['full', 'tiny', 'basic', 'none'])), 'bbox': SVGAttribute('bbox', anim=False, types=frozenset(['string']), const=empty_list), 'begin': SVGAttribute('begin', anim=True, types=frozenset(['timing-value-list']), const=frozenset(['indefinite'])), 'bias': SVGAttribute('bias', anim=True, types=frozenset(['number']), const=empty_list), 'by': SVGAttribute('by', anim=False, types=frozenset(['string']), const=empty_list), 'calcMode': SVGAttribute('calcMode', anim=False, types=empty_list, const=frozenset(['discrete', 'linear', 'paced', 'spline'])), 'cap-height': SVGAttribute('cap-height', anim=False, types=frozenset(['number']), const=empty_list), 'class': SVGAttribute('class', anim=True, types=frozenset(['list-of-name']), const=empty_list), 'clip': SVGAttribute('clip', anim=True, types=frozenset(['shape']), const=frozenset(['auto', 'inherit'])), 'clip-path': SVGAttribute('clip-path', anim=True, types=frozenset(['IRI']), const=frozenset(['none', 'inherit'])), 'clip-rule': SVGAttribute('clip-rule', anim=True, types=empty_list, const=frozenset(['nonzero', 'evenodd', 'inherit'])), 'clipPathUnits': SVGAttribute('clipPathUnits', anim=True, types=empty_list, const=frozenset(['userSpaceOnUse', 'objectBoundingBox'])), 'color': SVGAttribute('color', anim=True, types=frozenset(['color']), const=frozenset(['inherit'])), 'color-interpolation': SVGAttribute('color-interpolation', anim=True, types=empty_list, const=frozenset(['auto', 'sRGB', 'inherit', 'linearRGB'])), 'color-interpolation-filters': SVGAttribute('color-interpolation-filters', anim=True, types=empty_list, const=frozenset(['auto', 'sRGB', 'inherit', 'linearRGB'])), 'color-profile': SVGAttribute('color-profile', anim=True, types=frozenset(['FuncIRI', 'name']), const=frozenset(['auto', 'sRGB', 'inherit'])), 'color-rendering': SVGAttribute('color-rendering', anim=True, types=empty_list, const=frozenset(['auto', 'optimizeQuality', 'optimizeSpeed', 'inherit'])), 'contentScriptType': SVGAttribute('contentScriptType', anim=True, types=frozenset(['string']), const=empty_list), 'contentStyleType': SVGAttribute('contentStyleType', anim=True, types=frozenset(['string']), const=empty_list), 'cursor': SVGAttribute('cursor', anim=True, types=frozenset(['list-of-FuncIRI']), const=frozenset(['sw-resize', 'n-resize', 'help', 'text', 'move', 'auto', 'w-resize', 'pointer', 'wait', 's-resize', 'e-resize', 'default', 'inherit', 'nw-resize', 'ne-resize', 'crosshair', 'se-resize'])), 'cx': SVGAttribute('cx', anim=True, types=frozenset(['coordinate']), const=empty_list), 'cy': SVGAttribute('cy', anim=True, types=frozenset(['coordinate']), const=empty_list), 'd': SVGMultiAttribute({ '* path': SVGAttribute( # '*' means default attribute 'd', anim=True, types=frozenset(['path-data']), const=empty_list ), 'glyph missing-glyph': SVGAttribute( 'd', anim=False, types=frozenset(['path-data']), const=empty_list ), }), 'descent': SVGAttribute('descent', anim=False, types=frozenset(['number']), const=empty_list), 'diffuseConstant': SVGAttribute('diffuseConstant', anim=True, types=frozenset(['number']), const=empty_list), 'direction': SVGAttribute('direction', anim=False, types=empty_list, const=frozenset(['ltr', 'inherit', 'rtl'])), 'display': SVGAttribute('display', anim=True, types=empty_list, const=frozenset(['inline-table', 'table-header-group', 'table-footer-group', 'none', 'table-row', 'table-caption', 'table-column', 'marker', 'table', 'compact', 'table-row-group', 'run-in', 'inherit', 'list-item', 'table-cell', 'inline', 'block', 'table-column-group'])), 'divisor': SVGAttribute('divisor', anim=True, types=frozenset(['number']), const=empty_list), 'dominant-baseline': SVGAttribute('dominant-baseline', anim=True, types=empty_list, const=frozenset(['mathematical', 'use-script', 'ideographic', 'central', 'reset-size', 'auto', 'hanging', 'inherit', 'middle', 'alphabetic', 'text-before-edge', 'text-after-edge', 'no-change'])), 'dur': SVGAttribute('dur', anim=True, types=frozenset(['time']), const=frozenset(['media', 'indefinite'])), 'dx': SVGMultiAttribute({ '* altGlyph text tref tspan': SVGAttribute( 'dx', anim=True, types=frozenset(['list-of-length']), const=empty_list), 'feOffset': SVGAttribute( 'dx', anim=True, types=frozenset(['number']), const=empty_list), 'glyphRef': SVGAttribute( 'dx', anim=False, types=frozenset(['number']), const=empty_list), }), 'dy': SVGMultiAttribute({ '* altGlyph text tref tspan': SVGAttribute( 'dy', anim=True, types=frozenset(['list-of-length']), const=empty_list), 'feOffset': SVGAttribute( 'dy', anim=True, types=frozenset(['number']), const=empty_list), 'glyphRef': SVGAttribute( 'dy', anim=False, types=frozenset(['number']), const=empty_list), }), 'edgeMode': SVGAttribute('edgeMode', anim=True, types=empty_list, const=frozenset(['wrap', 'duplicate', 'none'])), 'elevation': SVGAttribute('elevation', anim=True, types=frozenset(['number']), const=empty_list), 'enable-background': SVGAttribute('enable-background', anim=True, types=frozenset(['string']), const=frozenset(['accummulate', 'new', 'inherit'])), 'end': SVGAttribute('end', anim=False, types=frozenset(['timing-value-list']), const=frozenset(['indefinite'])), 'exponent': SVGAttribute('exponent', anim=True, types=frozenset(['number']), const=empty_list), 'externalResourcesRequired': SVGAttribute('externalResourcesRequired', anim=True, types=empty_list, const=frozenset(['true', 'false'])), 'fill': SVGMultiAttribute({ '*': SVGAttribute( 'fill', anim=True, types=frozenset(['paint']), const=empty_list), 'set animateMotion animate animateColor animateTransform': SVGAttribute( 'fill', anim=False, types=empty_list, const=frozenset(['freeze', 'remove'])) }), 'fill-opacity': SVGAttribute('fill-opacity', anim=True, types=frozenset(['number']), const=frozenset(['inherit'])), 'fill-rule': SVGAttribute('fill-rule', anim=True, types=empty_list, const=frozenset(['nonzero', 'evenodd', 'inherit'])), 'filter': SVGAttribute('filter', anim=True, types=frozenset(['FuncIRI']), const=frozenset(['none', 'inherit'])), 'filterRes': SVGAttribute('filterRes', anim=True, types=frozenset(['number-optional-number']), const=empty_list), 'filterUnits': SVGAttribute('filterUnits', anim=True, types=empty_list, const=frozenset(['userSpaceOnUse', 'objectBoundingBox'])), 'flood-color': SVGAttribute('flood-color', anim=True, types=frozenset(['color', 'icccolor']), const=frozenset(['currentColor', 'inherit'])), 'flood-opacity': SVGAttribute('flood-opacity', anim=True, types=frozenset(['number']), const=frozenset(['inherit'])), 'font': SVGAttribute('font', anim=True, types=frozenset(['string']), const=empty_list), 'font-family': SVGAttribute('font-family', anim=False, types=frozenset(['string']), const=empty_list), 'font-size': SVGAttribute('font-size', anim=False, types=frozenset(['length']), const=frozenset(['inherit'])), 'font-size-adjust': SVGAttribute('font-size-adjust', anim=True, types=frozenset(['number']), const=frozenset(['none', 'inherit'])), 'font-stretch': SVGAttribute('font-stretch', anim=False, types=empty_list, const=frozenset(['condensed', 'normal', 'ultra-condensed', 'expanded', 'narrower', 'inherit', 'semi-condensed', 'extra-condensed', 'ultra-expanded', 'wider', 'semi-expanded', 'extra-expanded'])), 'font-style': SVGAttribute('font-style', anim=False, types=empty_list, const=frozenset(['oblique', 'inherit', 'italic', 'normal'])), 'font-variant': SVGAttribute('font-variant', anim=False, types=empty_list, const=frozenset(['small-caps', 'inherit', 'normal'])), 'font-weight': SVGAttribute('font-weight', anim=False, types=empty_list, const=frozenset(['200', '900', 'bold', 'bolder', 'normal', '300', '700', 'inherit', 'lighter', '400', '100', '800', '500', '600'])), 'format': SVGAttribute('format', anim=False, types=frozenset(['string']), const=empty_list), 'from': SVGAttribute('from', anim=False, types=frozenset(['string']), const=empty_list), 'fx': SVGAttribute('fx', anim=True, types=frozenset(['coordinate']), const=empty_list), 'fy': SVGAttribute('fy', anim=True, types=frozenset(['coordinate']), const=empty_list), 'g1': SVGAttribute('g1', anim=False, types=frozenset(['list-of-name']), const=empty_list), 'g2': SVGAttribute('g2', anim=False, types=frozenset(['list-of-name']), const=empty_list), 'glyph-name': SVGAttribute('glyph-name', anim=False, types=frozenset(['list-of-name']), const=empty_list), 'glyph-orientation-horizontal': SVGAttribute('glyph-orientation-horizontal', anim=True, types=frozenset(['angle']), const=frozenset(['inherit'])), 'glyph-orientation-vertical': SVGAttribute('glyph-orientation-vertical', anim=True, types=frozenset(['angle']), const=frozenset(['auto', 'inherit'])), 'glyphRef': SVGAttribute('glyphRef', anim=False, types=frozenset(['string']), const=empty_list), 'gradientTransform': SVGAttribute('gradientTransform', anim=True, types=frozenset(['transform-list']), const=empty_list), 'gradientUnits': SVGAttribute('gradientUnits', anim=True, types=empty_list, const=frozenset(['userSpaceOnUse', 'objectBoundingBox'])), 'hanging': SVGAttribute('hanging', anim=False, types=frozenset(['number']), const=empty_list), 'height': SVGAttribute('height', anim=True, types=frozenset(['length']), const=empty_list), 'horiz-adv-x': SVGAttribute('horiz-adv-x', anim=False, types=frozenset(['number']), const=empty_list), 'horiz-origin-x': SVGAttribute('horiz-origin-x', anim=False, types=frozenset(['number']), const=empty_list), 'horiz-origin-y': SVGAttribute('horiz-origin-y', anim=False, types=frozenset(['number']), const=empty_list), 'id': SVGAttribute('id', anim=False, types=frozenset(['name']), const=empty_list), 'ideographic': SVGAttribute('ideographic', anim=False, types=frozenset(['number']), const=empty_list), 'image-rendering': SVGAttribute('image-rendering', anim=True, types=empty_list, const=frozenset(['auto', 'optimizeQuality', 'optimizeSpeed', 'inherit'])), 'in': SVGAttribute('in', anim=True, types=frozenset(['name']), const=frozenset(['SourceAlpha', 'SourceGraphic', 'BackgroundAlpha', 'BackgroundImage', 'StrokePaint', 'FillPaint'])), 'in2': SVGAttribute('in2', anim=True, types=frozenset(['name']), const=frozenset(['SourceAlpha', 'SourceGraphic', 'BackgroundAlpha', 'BackgroundImage', 'StrokePaint', 'FillPaint'])), 'intercept': SVGAttribute('intercept', anim=True, types=frozenset(['number']), const=empty_list), 'k': SVGAttribute('k', anim=False, types=frozenset(['number']), const=empty_list), 'k1': SVGAttribute('k1', anim=True, types=frozenset(['number']), const=empty_list), 'k2': SVGAttribute('k2', anim=True, types=frozenset(['number']), const=empty_list), 'k3': SVGAttribute('k3', anim=True, types=frozenset(['number']), const=empty_list), 'k4': SVGAttribute('k4', anim=True, types=frozenset(['number']), const=empty_list), 'kernelMatrix': SVGAttribute('kernelMatrix', anim=True, types=frozenset(['list-of-number']), const=empty_list), 'kernelUnitLength': SVGAttribute('kernelUnitLength', anim=True, types=frozenset(['number-optional-number']), const=empty_list), 'kerning': SVGAttribute('kerning', anim=True, types=frozenset(['length']), const=frozenset(['auto', 'inherit'])), 'keyPoints': SVGAttribute('keyPoints', anim=False, types=frozenset(['semicolon-list']), const=empty_list), 'keySplines': SVGAttribute('keySplines', anim=False, types=frozenset(['semicolon-list']), const=empty_list), 'keyTimes': SVGAttribute('keyTimes', anim=False, types=frozenset(['semicolon-list']), const=empty_list), 'lang': SVGAttribute('lang', anim=False, types=frozenset(['name']), const=empty_list), 'lengthAdjust': SVGAttribute('lengthAdjust', anim=True, types=empty_list, const=frozenset(['spacingAndGlyphs', 'spacing'])), 'letter-spacing': SVGAttribute('letter-spacing', anim=True, types=frozenset(['length']), const=frozenset(['inherit', 'normal'])), 'lighting-color': SVGAttribute('lighting-color', anim=True, types=frozenset(['color', 'icccolor']), const=frozenset(['currentColor', 'inherit'])), 'limitingConeAngle': SVGAttribute('limitingConeAngle', anim=True, types=frozenset(['number']), const=empty_list), 'local': SVGAttribute('local', anim=True, types=frozenset(['string']), const=empty_list), 'marker': SVGAttribute('marker', anim=True, types=frozenset(['FuncIRI']), const=frozenset(['none', 'inherit'])), 'marker-end': SVGAttribute('marker-end', anim=True, types=frozenset(['FuncIRI']), const=frozenset(['none', 'inherit'])), 'marker-mid': SVGAttribute('marker-mid', anim=True, types=frozenset(['FuncIRI']), const=frozenset(['none', 'inherit'])), 'marker-start': SVGAttribute('marker-start', anim=True, types=frozenset(['FuncIRI']), const=frozenset(['none', 'inherit'])), 'markerHeight': SVGAttribute('markerHeight', anim=True, types=frozenset(['length']), const=empty_list), 'markerUnits': SVGAttribute('markerUnits', anim=True, types=empty_list, const=frozenset(['userSpaceOnUse', 'strokeWidth'])), 'markerWidth': SVGAttribute('markerWidth', anim=True, types=frozenset(['length']), const=empty_list), 'mask': SVGAttribute('mask', anim=True, types=frozenset(['FuncIRI']), const=frozenset(['none', 'inherit'])), 'maskContentUnits': SVGAttribute('maskContentUnits', anim=True, types=empty_list, const=frozenset(['userSpaceOnUse', 'objectBoundingBox'])), 'maskUnits': SVGAttribute('maskUnits', anim=True, types=empty_list, const=frozenset(['userSpaceOnUse', 'objectBoundingBox'])), 'mathematical': SVGAttribute('mathematical', anim=False, types=frozenset(['number']), const=empty_list), 'max': SVGAttribute('max', anim=False, types=frozenset(['time']), const=frozenset(['media'])), 'media': SVGAttribute('media', anim=False, types=empty_list, const=frozenset(['all', 'aureal', 'braille', 'embossed', 'handheld', 'print', 'projection', 'screen', 'tty', 'tv'])), 'method': SVGAttribute('method', anim=True, types=empty_list, const=frozenset(['stretch', 'align'])), 'min': SVGAttribute('min', anim=False, types=frozenset(['time']), const=frozenset(['media'])), 'mode': SVGAttribute('mode', anim=True, types=empty_list, const=frozenset(['multiply', 'screen', 'darken', 'lighten', 'normal'])), 'name': SVGMultiAttribute({ '* font-face-name': SVGAttribute( 'name', anim=False, types=frozenset(['anything']), const=empty_list), 'color-profile': SVGAttribute( 'name', anim=False, types=frozenset(['name']), const=empty_list), }), 'numOctaves': SVGAttribute('numOctaves', anim=True, types=frozenset(['integer']), const=empty_list), 'offset': SVGMultiAttribute({ '*': SVGAttribute( 'offset', anim=True, types=frozenset(['number']), const=empty_list), 'stop': SVGAttribute( 'offset', anim=True, types=frozenset(['number', 'percentage']), const=empty_list), }), 'onabort': SVGAttribute('onabort', anim=False, types=frozenset(['anything']), const=empty_list), 'onactivate': SVGAttribute('onactivate', anim=False, types=frozenset(['anything']), const=empty_list), 'onbegin': SVGAttribute('onbegin', anim=False, types=frozenset(['anything']), const=empty_list), 'onclick': SVGAttribute('onclick', anim=False, types=frozenset(['anything']), const=empty_list), 'onend': SVGAttribute('onend', anim=True, types=frozenset(['anything']), const=empty_list), 'onerror': SVGAttribute('onerror', anim=False, types=frozenset(['anything']), const=empty_list), 'onfocusin': SVGAttribute('onfocusin', anim=False, types=frozenset(['anything']), const=empty_list), 'onfocusout': SVGAttribute('onfocusout', anim=False, types=frozenset(['anything']), const=empty_list), 'onload': SVGAttribute('onload', anim=False, types=frozenset(['anything']), const=empty_list), 'onmousedown': SVGAttribute('onmousedown', anim=False, types=frozenset(['anything']), const=empty_list), 'onmousemove': SVGAttribute('onmousemove', anim=False, types=frozenset(['anything']), const=empty_list), 'onmouseout': SVGAttribute('onmouseout', anim=False, types=frozenset(['anything']), const=empty_list), 'onmouseover': SVGAttribute('onmouseover', anim=False, types=frozenset(['anything']), const=empty_list), 'onmouseup': SVGAttribute('onmouseup', anim=False, types=frozenset(['anything']), const=empty_list), 'onrepeat': SVGAttribute('onrepeat', anim=False, types=frozenset(['anything']), const=empty_list), 'onresize': SVGAttribute('onresize', anim=False, types=frozenset(['anything']), const=empty_list), 'onscroll': SVGAttribute('onscroll', anim=False, types=frozenset(['anything']), const=empty_list), 'onunload': SVGAttribute('onunload', anim=False, types=frozenset(['anything']), const=empty_list), 'onzoom': SVGAttribute('onzoom', anim=False, types=frozenset(['anything']), const=empty_list), 'opacity': SVGAttribute('opacity', anim=True, types=frozenset(['number']), const=frozenset(['inherit'])), 'operator': SVGMultiAttribute({ '* feComposite': SVGAttribute( 'operator', anim=True, types=empty_list, const=frozenset(['xor', 'in', 'over', 'atop', 'arithmetic', 'out'])), 'feMorphology': SVGAttribute( 'operator', anim=True, types=empty_list, const=frozenset(['erode', 'dilate'])), }), 'order': SVGAttribute('order', anim=True, types=frozenset(['number-optional-number']), const=empty_list), 'orient': SVGAttribute('orient', anim=True, types=frozenset(['angle']), const=frozenset(['auto'])), 'orientation': SVGAttribute('orientation', anim=False, types=empty_list, const=frozenset(['h', 'v'])), 'origin': SVGAttribute('origin', anim=False, types=empty_list, const=frozenset(['default'])), 'overflow': SVGAttribute('overflow', anim=True, types=empty_list, const=frozenset(['visible', 'hidden', 'scroll', 'inherit', 'auto'])), 'overline-position': SVGAttribute('overline-position', anim=False, types=frozenset(['number']), const=empty_list), 'overline-thickness': SVGAttribute('overline-thickness', anim=False, types=frozenset(['number']), const=empty_list), 'panose-1': SVGAttribute('panose-1', anim=False, types=frozenset(['list-of-integer']), const=empty_list), 'path': SVGAttribute('path', anim=False, types=frozenset(['path-data']), const=empty_list), 'pathLength': SVGAttribute('pathLength', anim=True, types=frozenset(['number']), const=empty_list), 'patternContentUnits': SVGAttribute('patternContentUnits', anim=True, types=empty_list, const=frozenset(['userSpaceOnUse', 'objectBoundingBox'])), 'patternTransform': SVGAttribute('patternTransform', anim=True, types=frozenset(['transform-list']), const=empty_list), 'patternUnits': SVGAttribute('patternUnits', anim=True, types=empty_list, const=frozenset(['userSpaceOnUse', 'objectBoundingBox'])), 'pointer-events': SVGAttribute('pointer-events', anim=True, types=empty_list, const=frozenset(['all', 'visibleStroke', 'painted', 'none', 'visibleFill', 'visible', 'stroke', 'inherit', 'visiblePainted', 'fill'])), 'points': SVGAttribute('points', anim=True, types=frozenset(['list-of-number']), const=empty_list), 'pointsAtX': SVGAttribute('pointsAtX', anim=True, types=frozenset(['number']), const=empty_list), 'pointsAtY': SVGAttribute('pointsAtY', anim=True, types=frozenset(['number']), const=empty_list), 'pointsAtZ': SVGAttribute('pointsAtZ', anim=True, types=frozenset(['number']), const=empty_list), 'preserveAlpha': SVGAttribute('preserveAlpha', anim=True, types=empty_list, const=frozenset(['true', 'false'])), 'preserveAspectRatio': SVGAttribute('preserveAspectRatio', anim=True, types=frozenset('string'), const=empty_list), 'primitiveUnits': SVGAttribute('primitiveUnits', anim=True, types=empty_list, const=frozenset(['userSpaceOnUse', 'objectBoundingBox'])), 'r': SVGAttribute('r', anim=True, types=frozenset(['length']), const=empty_list), 'radius': SVGAttribute('radius', anim=True, types=frozenset(['number-optional-number']), const=empty_list), 'refX': SVGAttribute('refX', anim=True, types=frozenset(['coordinate']), const=empty_list), 'refY': SVGAttribute('refY', anim=True, types=frozenset(['coordinate']), const=empty_list), 'rendering-intent': SVGAttribute('rendering-intent', anim=False, types=empty_list, const=frozenset(['auto', 'saturation', 'perceptual', 'relative-colorimetric', 'absolute-colorimetric'])), 'repeatCount': SVGAttribute('repeatCount', anim=False, types=frozenset(['number']), const=frozenset(['indefinite'])), 'repeatDur': SVGAttribute('repeatDur', anim=False, types=frozenset(['time']), const=frozenset(['indefinite'])), 'requiredExtensions': SVGAttribute('requiredExtensions', anim=False, types=frozenset(['string']), const=empty_list), 'requiredFeatures': SVGAttribute('requiredFeatures', anim=False, types=frozenset(['string']), const=empty_list), 'restart': SVGAttribute('restart', anim=False, types=empty_list, const=frozenset(['always', 'never', 'whenNotActive'])), 'result': SVGAttribute('result', anim=True, types=frozenset(['list-of-name']), const=empty_list), 'rotate': SVGMultiAttribute({ '* altGlyph text tref tspan': SVGAttribute( 'rotate', anim=True, types=frozenset(['list-of-number']), const=empty_list), 'animateMotion': SVGAttribute( 'rotate', anim=False, types=frozenset(['number']), const=frozenset(['auto', 'auto-reverse'])), }), 'rx': SVGAttribute('rx', anim=True, types=frozenset(['length']), const=empty_list), 'ry': SVGAttribute('ry', anim=True, types=frozenset(['length']), const=empty_list), 'scale': SVGAttribute('scale', anim=True, types=frozenset(['number']), const=empty_list), 'seed': SVGAttribute('seed', anim=True, types=frozenset(['number']), const=empty_list), 'shape-rendering': SVGAttribute('shape-rendering', anim=True, types=empty_list, const=frozenset(['auto', 'optimizeSpeed', 'inherit', 'geometricPrecision', 'crispEdges'])), 'slope': SVGMultiAttribute({ '*': SVGAttribute( 'slope', anim=True, types=frozenset(['number']), const=empty_list), 'font-face': SVGAttribute( 'slope', anim=False, types=frozenset(['number']), const=empty_list), }), 'spacing': SVGAttribute('spacing', anim=True, types=empty_list, const=frozenset(['auto', 'exact'])), 'specularConstant': SVGAttribute('specularConstant', anim=True, types=frozenset(['number']), const=empty_list), 'specularExponent': SVGAttribute('specularExponent', anim=True, types=frozenset(['number']), const=empty_list), 'spreadMethod': SVGAttribute('spreadMethod', anim=True, types=empty_list, const=frozenset(['reflect', 'repeat', 'pad'])), 'startOffset': SVGAttribute('startOffset', anim=True, types=frozenset(['length']), const=empty_list), 'stdDeviation': SVGAttribute('stdDeviation', anim=True, types=frozenset(['number-optional-number']), const=empty_list), 'stemh': SVGAttribute('stemh', anim=False, types=frozenset(['number']), const=empty_list), 'stemv': SVGAttribute('stemv', anim=False, types=frozenset(['number']), const=empty_list), 'stitchTiles': SVGAttribute('stitchTiles', anim=True, types=empty_list, const=frozenset(['noStitch', 'stitch'])), 'stop-color': SVGAttribute('stop-color', anim=True, types=frozenset(['color', 'icccolor']), const=frozenset(['currentColor', 'inherit'])), 'stop-opacity': SVGAttribute('stop-opacity', anim=True, types=frozenset(['number']), const=frozenset(['inherit'])), 'strikethrough-position': SVGAttribute('strikethrough-position', anim=False, types=frozenset(['number']), const=empty_list), 'strikethrough-thickness': SVGAttribute('strikethrough-thickness', anim=False, types=frozenset(['number']), const=empty_list), 'string': SVGAttribute('string', anim=False, types=frozenset('anything'), const=empty_list), 'stroke': SVGAttribute('stroke', anim=True, types=frozenset(['paint']), const=empty_list), 'stroke-dasharray': SVGAttribute('stroke-dasharray', anim=True, types=frozenset(['list-of-length']), const=frozenset(['none', 'inherit'])), 'stroke-dashoffset': SVGAttribute('stroke-dashoffset', anim=True, types=frozenset(['length']), const=frozenset(['inherit'])), 'stroke-linecap': SVGAttribute('stroke-linecap', anim=True, types=empty_list, const=frozenset(['square', 'round', 'inherit', 'butt'])), 'stroke-linejoin': SVGAttribute('stroke-linejoin', anim=True, types=empty_list, const=frozenset(['bevel', 'miter', 'round', 'inherit'])), 'stroke-miterlimit': SVGAttribute('stroke-miterlimit', anim=True, types=frozenset(['number']), const=frozenset(['inherit'])), 'stroke-opacity': SVGAttribute('stroke-opacity', anim=True, types=frozenset(['number']), const=frozenset(['inherit'])), 'stroke-width': SVGAttribute('stroke-width', anim=True, types=frozenset(['length']), const=frozenset(['inherit'])), 'style': SVGAttribute('style', anim=False, types=frozenset('anything'), const=empty_list), 'surfaceScale': SVGAttribute('surfaceScale', anim=True, types=frozenset(['number']), const=empty_list), 'systemLanguage': SVGAttribute('systemLanguage', anim=False, types=frozenset(['string']), const=empty_list), 'tableValues': SVGAttribute('tableValues', anim=True, types=frozenset(['list-of-number']), const=empty_list), 'target': SVGAttribute('target', anim=True, types=frozenset(['XML-Name']), const=frozenset(['_replace', '_self', '_parent', '_top', '_blank'])), 'targetX': SVGAttribute('targetX', anim=True, types=frozenset(['integer']), const=empty_list), 'targetY': SVGAttribute('targetY', anim=True, types=frozenset(['integer']), const=empty_list), 'text-anchor': SVGAttribute('text-anchor', anim=True, types=empty_list, const=frozenset(['start', 'end', 'inherit', 'middle'])), 'text-decoration': SVGAttribute('text-decoration', anim=True, types=empty_list, const=frozenset(['', 'overline', 'none', 'underline', 'line-through', 'inherit', 'blink'])), 'text-rendering': SVGAttribute('text-rendering', anim=True, types=empty_list, const=frozenset(['auto', 'optimizeSpeed', 'optimizeLegibility', 'geometricPrecision', 'inherit'])), 'textLength': SVGAttribute('textLength', anim=True, types=frozenset(['length']), const=empty_list), 'title': SVGAttribute('title', anim=False, types=frozenset(['string']), const=empty_list), 'to': SVGAttribute('to', anim=False, types=frozenset(['string']), const=empty_list), 'transform': SVGAttribute('transform', anim=True, types=frozenset(['transform-list']), const=empty_list), 'type': SVGMultiAttribute({ '* feColorMatrix': SVGAttribute( 'type', anim=True, types=empty_list, const=frozenset(['matrix', 'saturate', 'hueRotate', 'luminanceToAlpha'])), 'feTurbulence': SVGAttribute( 'type', anim=True, types=empty_list, const=frozenset(['fractalNoise', 'turbulence'])), 'feFuncR feFuncG feFuncB feFuncA': SVGAttribute( 'type', anim=True, types=empty_list, const=frozenset(['identity', 'table', 'discrete', 'linear', 'gamma'])), 'script style': SVGAttribute( 'type', anim=False, types=frozenset(['content-type']), const=empty_list), 'animateTransform': SVGAttribute( 'type', anim=False, types=empty_list, const=frozenset(['translate', 'scale', 'rotate', 'skewX', 'skewY'])), }), 'u1': SVGAttribute('u1', anim=False, types=frozenset(['string']), const=empty_list), 'u2': SVGAttribute('u2', anim=False, types=frozenset(['string']), const=empty_list), 'underline-position': SVGAttribute('underline-position', anim=False, types=frozenset(['number']), const=empty_list), 'underline-thickness': SVGAttribute('underline-thickness', anim=False, types=frozenset(['number']), const=empty_list), 'unicode': SVGAttribute('unicode', anim=False, types=frozenset(['string']), const=empty_list), 'unicode-bidi': SVGAttribute('unicode-bidi', anim=False, types=empty_list, const=frozenset(['embed', 'inherit', 'bidi-override', 'normal'])), 'unicode-range': SVGAttribute('unicode-range', anim=False, types=frozenset(['string']), const=empty_list), 'units-per-em': SVGAttribute('units-per-em', anim=False, types=frozenset(['number']), const=empty_list), 'v-alphabetic': SVGAttribute('v-alphabetic', anim=False, types=frozenset(['number']), const=empty_list), 'v-hanging': SVGAttribute('v-hanging', anim=False, types=frozenset(['number']), const=empty_list), 'v-ideographic': SVGAttribute('v-ideographic', anim=False, types=frozenset(['number']), const=empty_list), 'v-mathematical': SVGAttribute('v-mathematical', anim=False, types=frozenset(['number']), const=empty_list), 'values': SVGMultiAttribute({ '*': SVGAttribute( 'values', anim=False, types=frozenset(['semicolon-list']), const=empty_list), 'feColorMatrix': SVGAttribute( 'values', anim=True, types=frozenset(['list-of-number']), const=empty_list), }), 'version': SVGAttribute('version', anim=False, types=empty_list, const=frozenset(['1.1', '1.2'])), 'vert-adv-y': SVGAttribute('vert-adv-y', anim=False, types=frozenset(['number']), const=empty_list), 'vert-origin-x': SVGAttribute('vert-origin-x', anim=False, types=frozenset(['number']), const=empty_list), 'vert-origin-y': SVGAttribute('vert-origin-y', anim=False, types=frozenset(['number']), const=empty_list), 'viewBox': SVGAttribute('viewBox', anim=True, types=frozenset(['four-numbers']), const=empty_list), 'viewTarget': SVGAttribute('viewTarget', anim=False, types=frozenset(['list-of-XML-Name']), const=empty_list), 'visibility': SVGAttribute('visibility', anim=True, types=empty_list, const=frozenset(['visible', 'hidden', 'collapse', 'inherit'])), 'width': SVGAttribute('width', anim=True, types=frozenset(['length']), const=empty_list), 'widths': SVGAttribute('widths', anim=False, types=frozenset(['string']), const=empty_list), 'word-spacing': SVGAttribute('word-spacing', anim=True, types=frozenset(['length']), const=frozenset(['inherit', 'normal'])), 'writing-mode': SVGAttribute('writing-mode', anim=False, types=empty_list, const=frozenset(['rl-tb', 'lr', 'rl', 'tb-rl', 'lr-tb', 'inherit', 'tb'])), 'x': SVGMultiAttribute({ '*': SVGAttribute( 'x', anim=True, types=frozenset(['coordinate']), const=empty_list), 'altGlyph text tref tspan': SVGAttribute( 'x', anim=True, types=frozenset(['list-of-coordinate']), const=empty_list), 'fePointLight feSpotLight glyphRef': SVGAttribute( 'x', anim=True, types=frozenset(['number']), const=empty_list), }), 'x-height': SVGAttribute('x-height', anim=False, types=frozenset(['number']), const=empty_list), 'x1': SVGAttribute('x1', anim=True, types=frozenset(['list-of-coordinate']), const=empty_list), 'x2': SVGAttribute('x2', anim=True, types=frozenset(['list-of-coordinate']), const=empty_list), 'xChannelSelector': SVGAttribute('xChannelSelector', anim=True, types=empty_list, const=frozenset(['A', 'B', 'R', 'G'])), 'xlink:actuate': SVGMultiAttribute({ '*': SVGAttribute( 'xlink:actuate', anim=False, types=empty_list, const=frozenset(['onLoad'])), 'a': SVGAttribute( 'xlink:actuate', anim=False, types=empty_list, const=frozenset(['onRequest'])), }), 'xlink:arcrole': SVGAttribute('xlink:arcrole', anim=False, types=frozenset(['IRI']), const=empty_list), 'xlink:href': SVGAttribute('xlink:href', anim=False, types=frozenset(['IRI']), const=empty_list), 'xlink:role': SVGAttribute('xlink:role', anim=False, types=frozenset(['IRI']), const=empty_list), 'xlink:show': SVGMultiAttribute({ '*': SVGAttribute( 'xlink:show', anim=False, types=empty_list, const=frozenset(['other', 'new', 'replace', 'none', 'embed'])), 'a': SVGAttribute( 'xlink:show', anim=False, types=empty_list, const=frozenset(['new', 'replace'])), }), 'xlink:title': SVGAttribute('xlink:title', anim=False, types=frozenset(['string']), const=empty_list), 'xlink:type': SVGAttribute('xlink:type', anim=False, types=empty_list, const=frozenset(['simple'])), 'xmlns': SVGAttribute('xmlns', anim=False, types=frozenset(['IRI']), const=empty_list), 'xmlns:xlink': SVGAttribute('xmlns:xlink', anim=False, types=frozenset(['IRI']), const=empty_list), 'xmlns:ev': SVGAttribute('xmlns:ev', anim=False, types=frozenset(['IRI']), const=empty_list), 'xml:base': SVGAttribute('xml:base', anim=False, types=frozenset(['IRI']), const=empty_list), 'xml:lang': SVGAttribute('xml:lang', anim=False, types=frozenset(['name']), const=empty_list), 'xml:space': SVGAttribute('xml:space', anim=False, types=empty_list, const=frozenset(['default', 'preserve'])), 'y': SVGMultiAttribute({ '*': SVGAttribute( 'y', anim=True, types=frozenset(['coordinate']), const=empty_list), 'altGlyph text tref tspan': SVGAttribute( 'y', anim=True, types=frozenset(['list-of-coordinate']), const=empty_list), 'fePointLight feSpotLight glyphRef': SVGAttribute( 'y', anim=True, types=frozenset(['number']), const=empty_list), }), 'y1': SVGAttribute('y1', anim=True, types=frozenset(['list-of-coordinate']), const=empty_list), 'y2': SVGAttribute('y2', anim=True, types=frozenset(['list-of-coordinate']), const=empty_list), 'yChannelSelector': SVGAttribute('yChannelSelector', anim=True, types=empty_list, const=frozenset(['A', 'B', 'R', 'G'])), 'z': SVGAttribute('z', anim=True, types=frozenset(['number']), const=empty_list), 'zoomAndPan': SVGAttribute('zoomAndPan', anim=False, types=empty_list, const=frozenset(['disable', 'magnify'])), } presentation_attributes = frozenset([ "alignment-baseline", "baseline-shift", "clip", "clip-path", "clip-rule", "color", "color-interpolation", "color-interpolation-filters", "color-profile", "color-rendering", "cursor", "direction", "display", "dominant-baseline", "enable-background", "fill", "fill-opacity", "fill-rule", "filter", "flood-color", "flood-opacity", "font-family", "font-size", "font-size-adjust", "font-stretch", "font-style", "font-variant", "font-weight", "glyph-orientation-horizontal", "glyph-orientation-vertical", "image-rendering", "kerning", "letter-spacing", "lighting-color", "marker", "marker-end", "marker-mid", "marker-start", "mask", "opacity", "overflow", "pointer-events", "shape-rendering", "stop-color", "stop-opacity", "stroke", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "text-anchor", "text-decoration", "text-rendering", "unicode-bidi", "visibility", "word-spacing", "writing-mode"]) elements = { 'a': SVGElement('a', attributes=frozenset(['xlink:title', 'xml:base', 'onmouseup', 'onmouseout', 'requiredExtensions', 'onfocusout', 'xml:space', 'xlink:href', 'systemLanguage', 'onmouseover', 'xlink:type', 'externalResourcesRequired', 'id', 'xlink:actuate', 'onload', 'style', 'xlink:show', 'target', 'onactivate', 'onmousedown', 'transform', 'class', 'xlink:role', 'requiredFeatures', 'xml:lang', 'onmousemove', 'xmlns:xlink', 'onclick', 'xlink:arcrole', 'onfocusin']), properties=presentation_attributes, children=frozenset(['set', 'text', 'image', 'font-face', 'polyline', 'marker', 'animate', 'font', 'color-profile', 'ellipse', 'cursor', 'style', 'polygon', 'title', 'pattern', 'circle', 'radialGradient', 'metadata', 'defs', 'symbol', 'use', 'animateMotion', 'animateColor', 'path', 'line', 'rect', 'desc', 'a', 'g', 'svg', 'script', 'mask', 'altGlyphDef', 'filter', 'switch', 'animateTransform', 'linearGradient', 'clipPath', 'foreignObject', 'view'])), 'altGlyph': SVGElement('altGlyph', attributes=frozenset(['requiredExtensions', 'onfocusout', 'xml:space', 'xlink:href', 'id', 'onload', 'style', 'onmousedown', 'onmousemove', 'onclick', 'xlink:arcrole', 'onfocusin', 'xml:base', 'onmouseup', 'onmouseout', 'format', 'xlink:title', 'systemLanguage', 'onmouseover', 'dx', 'dy', 'xlink:type', 'externalResourcesRequired', 'class', 'xlink:actuate', 'xlink:show', 'onactivate', 'glyphRef', 'xlink:role', 'requiredFeatures', 'xml:lang', 'y', 'x', 'rotate']), properties=presentation_attributes, children=empty_list), 'altGlyphDef': SVGElement('altGlyphDef', attributes=frozenset(['xml:space', 'xml:lang', 'xml:base', 'id']), properties=empty_list, children=frozenset(['*'])), 'altGlyphItem': SVGElement('altGlyphItem', attributes=frozenset(['xml:space', 'xml:lang', 'xml:base', 'id']), properties=empty_list, children=frozenset(['*'])), 'animate': SVGElement('animate', attributes=frozenset(['requiredExtensions', 'from', 'repeatCount', 'xml:space', 'xlink:href', 'xlink:type', 'attributeType', 'repeatDur', 'id', 'fill', 'onload', 'additive', 'calcMode', 'min', 'keySplines', 'to', 'dur', 'xlink:arcrole', 'onend', 'begin', 'xml:base', 'max', 'xlink:title', 'attributeName', 'onbegin', 'systemLanguage', 'accumulate', 'end', 'externalResourcesRequired', 'by', 'restart', 'xlink:actuate', 'xlink:show', 'xlink:role', 'requiredFeatures', 'xml:lang', 'values', 'keyTimes', 'onrepeat']), properties=empty_list, children=frozenset(['desc', 'metadata', 'title'])), 'animateColor': SVGElement('animateColor', attributes=frozenset(['requiredExtensions', 'from', 'repeatCount', 'xml:space', 'xlink:href', 'xlink:type', 'attributeType', 'repeatDur', 'id', 'fill', 'onload', 'additive', 'calcMode', 'min', 'keySplines', 'to', 'dur', 'xlink:arcrole', 'onend', 'begin', 'xml:base', 'max', 'xlink:title', 'attributeName', 'onbegin', 'systemLanguage', 'accumulate', 'end', 'externalResourcesRequired', 'by', 'restart', 'xlink:actuate', 'xlink:show', 'xlink:role', 'requiredFeatures', 'xml:lang', 'values', 'keyTimes', 'onrepeat']), properties=empty_list, children=frozenset(['desc', 'metadata', 'title'])), 'animateMotion': SVGElement('animateMotion', attributes=frozenset(['origin', 'requiredExtensions', 'from', 'repeatCount', 'xml:space', 'xlink:href', 'xlink:type', 'repeatDur', 'id', 'fill', 'onload', 'additive', 'calcMode', 'min', 'keySplines', 'to', 'dur', 'xlink:arcrole', 'onend', 'begin', 'xlink:title', 'xml:base', 'max', 'end', 'keyPoints', 'onbegin', 'systemLanguage', 'accumulate', 'path', 'externalResourcesRequired', 'by', 'restart', 'xlink:actuate', 'xlink:show', 'xlink:role', 'requiredFeatures', 'xml:lang', 'values', 'keyTimes', 'onrepeat', 'rotate']), properties=empty_list, children=frozenset(['desc', 'metadata', 'mpath', 'title'])), 'animateTransform': SVGElement('animateTransform', attributes=frozenset(['requiredExtensions', 'from', 'repeatCount', 'xml:space', 'xlink:href', 'xlink:type', 'attributeType', 'repeatDur', 'id', 'fill', 'onload', 'additive', 'calcMode', 'min', 'keySplines', 'to', 'dur', 'xlink:arcrole', 'type', 'onend', 'begin', 'xml:base', 'max', 'xlink:title', 'attributeName', 'onbegin', 'systemLanguage', 'accumulate', 'end', 'externalResourcesRequired', 'by', 'restart', 'xlink:actuate', 'xlink:show', 'xlink:role', 'requiredFeatures', 'xml:lang', 'values', 'keyTimes', 'onrepeat']), properties=empty_list, children=frozenset(['desc', 'metadata', 'title'])), 'circle': SVGElement('circle', attributes=frozenset(['xml:base', 'onmouseup', 'onmouseout', 'requiredExtensions', 'onfocusout', 'xml:space', 'cy', 'cx', 'onmouseover', 'externalResourcesRequired', 'id', 'onload', 'style', 'onactivate', 'onmousedown', 'transform', 'class', 'requiredFeatures', 'r', 'onmousemove', 'onclick', 'xml:lang', 'onfocusin', 'systemLanguage']), properties=presentation_attributes, children=frozenset(['animateMotion', 'set', 'title', 'animateColor', 'animateTransform', 'animate', 'metadata', 'desc'])), 'clipPath': SVGElement('clipPath', attributes=frozenset(['clipPathUnits', 'style', 'xml:base', 'requiredExtensions', 'xml:space', 'transform', 'id', 'requiredFeatures', 'xml:lang', 'externalResourcesRequired', 'class', 'systemLanguage']), properties=presentation_attributes, children=frozenset(['set', 'animate', 'text', 'use', 'animateColor', 'polyline', 'path', 'line', 'ellipse', 'rect', 'desc', 'animateMotion', 'polygon', 'title', 'animateTransform', 'circle', 'metadata'])), 'color-profile': SVGElement('color-profile', attributes=frozenset(['xlink:actuate', 'xlink:show', 'xml:base', 'name', 'rendering-intent', 'xml:space', 'xlink:href', 'xlink:role', 'xml:lang', 'xlink:type', 'xlink:title', 'xlink:arcrole', 'local', 'id']), properties=empty_list, children=frozenset(['desc', 'metadata', 'title'])), 'cursor': SVGElement('cursor', attributes=frozenset(['xlink:title', 'xml:base', 'requiredExtensions', 'xml:space', 'xlink:href', 'systemLanguage', 'xlink:type', 'externalResourcesRequired', 'id', 'xlink:actuate', 'xlink:show', 'xlink:role', 'requiredFeatures', 'xml:lang', 'y', 'x', 'xlink:arcrole']), properties=empty_list, children=frozenset(['desc', 'metadata', 'title'])), 'defs': SVGElement('defs', attributes=frozenset(['xml:base', 'onmouseup', 'onmouseout', 'requiredExtensions', 'onfocusout', 'xml:space', 'systemLanguage', 'onmouseover', 'externalResourcesRequired', 'class', 'onload', 'style', 'onactivate', 'onmousedown', 'transform', 'id', 'requiredFeatures', 'xml:lang', 'onmousemove', 'onclick', 'onfocusin']), properties=presentation_attributes, children=frozenset(['set', 'text', 'image', 'font-face', 'polyline', 'marker', 'animate', 'font', 'color-profile', 'ellipse', 'cursor', 'style', 'polygon', 'title', 'pattern', 'circle', 'radialGradient', 'metadata', 'defs', 'symbol', 'use', 'animateMotion', 'animateColor', 'path', 'line', 'rect', 'desc', 'a', 'g', 'svg', 'script', 'mask', 'altGlyphDef', 'filter', 'switch', 'animateTransform', 'linearGradient', 'clipPath', 'foreignObject', 'view'])), 'desc': SVGElement('desc', attributes=frozenset(['style', 'xml:lang', 'xml:base', 'xml:space', 'class', 'id']), properties=empty_list, children=frozenset(['*'])), 'ellipse': SVGElement('ellipse', attributes=frozenset(['xml:base', 'onmouseup', 'onmouseout', 'requiredExtensions', 'onfocusout', 'xml:space', 'ry', 'cy', 'cx', 'onmouseover', 'externalResourcesRequired', 'id', 'onload', 'style', 'onactivate', 'onmousedown', 'rx', 'transform', 'class', 'requiredFeatures', 'systemLanguage', 'onmousemove', 'onclick', 'xml:lang', 'onfocusin']), properties=presentation_attributes, children=frozenset(['animateMotion', 'set', 'title', 'animateColor', 'animateTransform', 'animate', 'desc', 'metadata'])), 'feBlend': SVGElement('feBlend', attributes=frozenset(['style', 'xml:base', 'xml:space', 'in2', 'height', 'width', 'xml:lang', 'id', 'result', 'in', 'y', 'x', 'class', 'mode']), properties=presentation_attributes, children=frozenset(['animate', 'set'])), 'feColorMatrix': SVGElement('feColorMatrix', attributes=frozenset(['style', 'xml:base', 'xml:space', 'id', 'height', 'width', 'xml:lang', 'values', 'result', 'in', 'y', 'x', 'type', 'class']), properties=presentation_attributes, children=frozenset(['animate', 'set'])), 'feComponentTransfer': SVGElement('feComponentTransfer', attributes=frozenset(['style', 'xml:base', 'xml:space', 'height', 'width', 'xml:lang', 'id', 'result', 'in', 'y', 'x', 'class']), properties=presentation_attributes, children=frozenset(['feFuncA', 'feFuncR', 'feFuncB', 'feFuncG'])), 'feComposite': SVGElement('feComposite', attributes=frozenset(['xml:base', 'xml:space', 'in2', 'height', 'result', 'in', 'operator', 'class', 'style', 'width', 'id', 'k3', 'k2', 'k1', 'xml:lang', 'k4', 'y', 'x']), properties=presentation_attributes, children=frozenset(['animate', 'set'])), 'feConvolveMatrix': SVGElement('feConvolveMatrix', attributes=frozenset(['xml:base', 'xml:space', 'kernelUnitLength', 'edgeMode', 'height', 'bias', 'result', 'in', 'preserveAlpha', 'id', 'style', 'divisor', 'kernelMatrix', 'width', 'xml:lang', 'targetX', 'targetY', 'y', 'x', 'class2', 'order']), properties=presentation_attributes, children=frozenset(['animate', 'set'])), 'feDiffuseLighting': SVGElement('feDiffuseLighting', attributes=frozenset(['style', 'xml:base', 'xml:space', 'diffuseConstant', 'height', 'kernelUnitLength', 'width', 'xml:lang', 'id', 'result', 'in', 'y', 'x', 'class', 'surfaceScale']), properties=presentation_attributes, children=frozenset(['fePointLight', 'feSpotLight', 'title', 'metadata', 'feDistantLight', 'desc'])), 'feDisplacementMap': SVGElement('feDisplacementMap', attributes=frozenset(['xml:base', 'xml:space', 'yChannelSelector', 'in2', 'height', 'result', 'in', 'class', 'style', 'scale', 'id', 'width', 'xml:lang', 'xChannelSelector', 'y', 'x']), properties=presentation_attributes, children=frozenset(['animate', 'set'])), 'feDistantLight': SVGElement('feDistantLight', attributes=frozenset(['xml:lang', 'elevation', 'azimuth', 'xml:base', 'xml:space', 'id']), properties=empty_list, children=frozenset(['animate', 'set'])), 'feFlood': SVGElement('feFlood', attributes=frozenset(['style', 'xml:base', 'xml:space', 'height', 'width', 'xml:lang', 'id', 'result', 'y', 'x', 'class']), properties=presentation_attributes, children=frozenset(['animate', 'set', 'animateColor'])), 'feFuncA': SVGElement('feFuncA', attributes=frozenset(['slope', 'xml:base', 'tableValues', 'xml:space', 'xml:lang', 'intercept', 'amplitude', 'offset', 'type', 'id', 'exponent']), properties=empty_list, children=frozenset(['animate', 'set'])), 'feFuncB': SVGElement('feFuncB', attributes=frozenset(['slope', 'xml:base', 'tableValues', 'xml:space', 'xml:lang', 'intercept', 'amplitude', 'offset', 'type', 'id', 'exponent']), properties=empty_list, children=frozenset(['animate', 'set'])), 'feFuncG': SVGElement('feFuncG', attributes=frozenset(['slope', 'xml:base', 'tableValues', 'xml:space', 'xml:lang', 'intercept', 'amplitude', 'offset', 'type', 'id', 'exponent']), properties=empty_list, children=frozenset(['animate', 'set'])), 'feFuncR': SVGElement('feFuncR', attributes=frozenset(['slope', 'xml:base', 'tableValues', 'xml:space', 'xml:lang', 'intercept', 'amplitude', 'offset', 'type', 'id', 'exponent']), properties=empty_list, children=frozenset(['animate', 'set'])), 'feGaussianBlur': SVGElement('feGaussianBlur', attributes=frozenset(['style', 'xml:base', 'xml:space', 'height', 'width', 'xml:lang', 'id', 'result', 'in', 'y', 'x', 'stdDeviation', 'class']), properties=presentation_attributes, children=frozenset(['animate', 'set'])), 'feImage': SVGElement('feImage', attributes=frozenset(['xlink:title', 'xml:base', 'xml:space', 'xlink:href', 'height', 'result', 'xlink:type', 'externalResourcesRequired', 'preserveAsectRatio', 'class', 'xlink:actuate', 'style', 'xlink:show', 'id', 'xlink:role', 'width', 'xml:lang', 'y', 'x', 'xlink:arcrole']), properties=presentation_attributes, children=frozenset(['animate', 'set', 'animateColor'])), 'feMerge': SVGElement('feMerge', attributes=frozenset(['style', 'xml:base', 'xml:space', 'height', 'width', 'xml:lang', 'id', 'result', 'y', 'x', 'class']), properties=presentation_attributes, children=frozenset(['animate', 'set', 'feMergeNode'])), 'feMergeNode': SVGElement('feMergeNode', attributes=frozenset(['xml:space', 'xml:lang', 'xml:base', 'id', 'in']), properties=empty_list, children=frozenset(['animate', 'set'])), 'feMorphology': SVGElement('feMorphology', attributes=frozenset(['style', 'xml:base', 'y', 'xml:space', 'id', 'height', 'width', 'xml:lang', 'radius', 'result', 'in', 'operator', 'x', 'class']), properties=presentation_attributes, children=frozenset(['animate', 'set'])), 'feOffset': SVGElement('feOffset', attributes=frozenset(['style', 'xml:base', 'xml:space', 'in', 'height', 'width', 'xml:lang', 'id', 'result', 'dx', 'dy', 'y', 'x', 'class']), properties=presentation_attributes, children=frozenset(['animate', 'set'])), 'fePointLight': SVGElement('fePointLight', attributes=frozenset(['xml:lang', 'xml:base', 'y', 'x', 'xml:space', 'z', 'id']), properties=empty_list, children=frozenset(['animate', 'set'])), 'feSpecularLighting': SVGElement('feSpecularLighting', attributes=frozenset(['specularConstant', 'xml:base', 'xml:space', 'kernelUnitLength', 'height', 'result', 'in', 'class', 'style', 'id', 'width', 'xml:lang', 'specularExponent', 'y', 'x', 'surfaceScale']), properties=presentation_attributes, children=frozenset(['fePointLight', 'feSpotLight', 'title', 'metadata', 'feDistantLight', 'desc'])), 'feSpotLight': SVGElement('feSpotLight', attributes=frozenset(['pointsAtX', 'xml:base', 'xml:space', 'limitingConeAngle', 'xml:lang', 'specularExponent', 'pointsAtZ', 'y', 'x', 'pointsAtY', 'z', 'id']), properties=empty_list, children=frozenset(['animate', 'set'])), 'feTile': SVGElement('feTile', attributes=frozenset(['style', 'xml:base', 'xml:space', 'height', 'width', 'xml:lang', 'id', 'result', 'in', 'y', 'x', 'class']), properties=presentation_attributes, children=frozenset(['animate', 'set'])), 'feTurbulence': SVGElement('feTurbulence', attributes=frozenset(['xml:base', 'baseFrequency', 'xml:space', 'stitchTiles', 'height', 'width', 'xml:lang', 'id', 'result', 'x', 'y', 'numOctaves', 'type', 'seed']), properties=presentation_attributes, children=empty_list), 'filter': SVGElement('filter', attributes=frozenset(['xlink:title', 'xml:base', 'xml:space', 'xlink:href', 'height', 'xlink:type', 'externalResourcesRequired', 'class', 'xlink:actuate', 'style', 'xlink:show', 'filterRes', 'primitiveUnits', 'id', 'xlink:role', 'width', 'xml:lang', 'y', 'x', 'xlink:arcrole', 'filterUnits']), properties=presentation_attributes, children=frozenset(['set', 'animate', 'metadata', 'desc', 'feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feFlood', 'feGaussianBlur', 'feImage', 'feMerge', 'feMorphology', 'feOffset', 'feSpecularLighting', 'feTile', 'feTurbulence'])), 'font': SVGElement('font', attributes=frozenset(['xml:space', 'id', 'xml:lang', 'xml:base', 'class', 'style', 'externalResourcesRequired', 'horiz-origin-x', 'horiz-origin-y', 'horiz-adv-x', 'vert-origin-x', 'vert-origin-y', 'vert-adv-y']), properties=presentation_attributes, children=frozenset(['title', 'metadata', 'missing-glyph', 'font-face', 'vkern', 'hkern', 'glyph', 'desc'])), 'font-face': SVGElement('font-face', attributes=frozenset(['mathematical', 'slope', 'font-size', 'xml:space', 'v-hanging', 'hanging', 'overline-thickness', 'ascent', 'id', 'strikethrough-position', 'underline-position', 'descent', 'cap-height', 'units-per-em', 'font-style', 'unicode-range', 'font-stretch', 'font-variant', 'x-height', 'font-weight', 'xml:base', 'panose-1', 'strikethrough-thickness', 'stemh', 'v-alphabetic', 'stemv', 'bbox', 'underline-thickness', 'font-family', 'v-mathematical', 'v-ideographic', 'ideographic', 'overline-position', 'widths', 'xml:lang', 'accent-height', 'alphabetic']), properties=empty_list, children=frozenset(['desc', 'metadata', 'font-face-src', 'title'])), 'font-face-format': SVGElement('font-face-format', attributes=frozenset(['xml:space', 'xml:lang', 'xml:base', 'id']), properties=empty_list, children=empty_list), 'font-face-name': SVGElement('font-face-name', attributes=frozenset(['xml:space', 'xml:lang', 'xml:base', 'id', 'name']), properties=empty_list, children=empty_list), 'font-face-uri': SVGElement('font-face-uri', attributes=frozenset(['xlink:actuate', 'xlink:show', 'xml:base', 'xml:space', 'xlink:href', 'xlink:role', 'xml:lang', 'xlink:type', 'xlink:title', 'xlink:arcrole', 'id']), properties=empty_list, children=frozenset(['font-face-format'])), 'foreignObject': SVGElement('foreignObject', attributes=frozenset(['xml:base', 'onmouseup', 'onmouseout', 'requiredExtensions', 'onfocusout', 'xml:space', 'height', 'systemLanguage', 'onmouseover', 'externalResourcesRequired', 'id', 'onload', 'style', 'onactivate', 'onmousedown', 'transform', 'class', 'width', 'requiredFeatures', 'xml:lang', 'onmousemove', 'onclick', 'y', 'x', 'onfocusin']), properties=presentation_attributes, children=frozenset(['*'])), 'g': SVGElement('g', attributes=frozenset(['xml:base', 'onmouseup', 'onmouseout', 'requiredExtensions', 'onfocusout', 'xml:space', 'systemLanguage', 'onmouseover', 'externalResourcesRequired', 'class', 'onload', 'style', 'onactivate', 'onmousedown', 'transform', 'id', 'requiredFeatures', 'xml:lang', 'onmousemove', 'onclick', 'onfocusin']), properties=presentation_attributes, children=frozenset(['set', 'text', 'image', 'font-face', 'polyline', 'marker', 'animate', 'font', 'color-profile', 'ellipse', 'cursor', 'style', 'polygon', 'title', 'pattern', 'circle', 'radialGradient', 'metadata', 'defs', 'symbol', 'use', 'animateMotion', 'animateColor', 'path', 'line', 'rect', 'desc', 'a', 'g', 'svg', 'script', 'mask', 'altGlyphDef', 'filter', 'switch', 'animateTransform', 'linearGradient', 'clipPath', 'foreignObject', 'view'])), 'glyph': SVGElement('glyph', attributes=frozenset(['xml:base', 'xml:space', 'id', 'xml:lang', 'class', 'style','d','horiz-adv-x', 'vert-origin-x', 'vert-origin-y', 'vert-adv-y', 'unicode', 'glyph-name', 'orientation', 'arabic-form', 'lang']), properties=presentation_attributes, children=frozenset(['set', 'text', 'image', 'font-face', 'polyline', 'marker', 'animate', 'font', 'color-profile', 'ellipse', 'cursor', 'style', 'polygon', 'title', 'pattern', 'circle', 'radialGradient', 'metadata', 'defs', 'symbol', 'use', 'animateMotion', 'animateColor', 'path', 'line', 'rect', 'desc', 'a', 'g', 'svg', 'script', 'mask', 'altGlyphDef', 'filter', 'switch', 'animateTransform', 'linearGradient', 'clipPath', 'foreignObject', 'view'])), 'glyphRef': SVGElement('glyphRef', attributes=frozenset(['xlink:title', 'xml:base', 'format', 'xml:space', 'xlink:href', 'dx', 'dy', 'xlink:type', 'class', 'xlink:actuate', 'style', 'xlink:show', 'id', 'xlink:role', 'xml:lang', 'y', 'x', 'xlink:arcrole', 'glyphRef']), properties=presentation_attributes, children=empty_list), 'hkern': SVGElement('hkern', attributes=frozenset(['xml:base', 'g2', 'g1', 'xml:space', 'u1', 'u2', 'xml:lang', 'id', 'k']), properties=empty_list, children=empty_list), 'image': SVGElement('image', attributes=frozenset(['requiredExtensions', 'onfocusout', 'xml:space', 'xlink:href', 'height', 'id', 'onload', 'style', 'onmousedown', 'transform', 'width', 'onmousemove', 'onclick', 'xlink:arcrole', 'onfocusin', 'xml:base', 'onmouseup', 'onmouseout', 'xlink:title', 'systemLanguage', 'onmouseover', 'xlink:type', 'externalResourcesRequired', 'class', 'xlink:actuate', 'xlink:show', 'onactivate', 'xlink:role', 'requiredFeatures', 'xml:lang', 'y', 'x', 'preserveAspectRatio']), properties=presentation_attributes, children=frozenset(['animateMotion', 'set', 'title', 'animateColor', 'animateTransform', 'animate', 'desc', 'metadata'])), 'line': SVGElement('line', attributes=frozenset(['xml:base', 'onmouseup', 'onmouseout', 'requiredExtensions', 'onfocusout', 'xml:space', 'x2', 'systemLanguage', 'onmouseover', 'y1', 'externalResourcesRequired', 'y2', 'id', 'onload', 'style', 'x1', 'onactivate', 'onmousedown', 'transform', 'class', 'requiredFeatures', 'xml:lang', 'onmousemove', 'onclick', 'onfocusin']), properties=presentation_attributes, children=frozenset(['animateMotion', 'set', 'title', 'animateColor', 'animateTransform', 'animate', 'desc', 'metadata'])), 'linearGradient': SVGElement('linearGradient', attributes=frozenset(['xlink:title', 'xml:base', 'xml:space', 'xlink:href', 'x2', 'y1', 'externalResourcesRequired', 'y2', 'class', 'xlink:actuate', 'xlink:role', 'style', 'xlink:show', 'spreadMethod', 'id', 'gradientUnits', 'xml:lang', 'gradientTransform', 'xlink:type', 'xlink:arcrole', 'x1']), properties=presentation_attributes, children=frozenset(['set', 'title', 'animate', 'animateTransform', 'stop', 'metadata', 'desc'])), 'marker': SVGElement('marker', attributes=frozenset(['xml:space', 'id', 'xml:lang', 'xml:base', 'class', 'style', 'externalResourcesRequired', 'viewBox', 'preserveAspectRatio', 'refX', 'refY', 'markerUnits', 'markerWidth', 'markerHeight', 'orient']), properties=presentation_attributes, children=frozenset(['set', 'text', 'image', 'font-face', 'polyline', 'marker', 'animate', 'font', 'color-profile', 'ellipse', 'cursor', 'style', 'polygon', 'title', 'pattern', 'circle', 'radialGradient', 'metadata', 'defs', 'symbol', 'use', 'animateMotion', 'animateColor', 'path', 'line', 'rect', 'desc', 'a', 'g', 'svg', 'script', 'mask', 'altGlyphDef', 'filter', 'switch', 'animateTransform', 'linearGradient', 'clipPath', 'foreignObject', 'view'])), 'mask': SVGElement('mask', attributes=frozenset(['xml:base', 'requiredExtensions', 'xml:space', 'height', 'systemLanguage', 'externalResourcesRequired', 'maskContentUnits', 'class', 'style', 'id', 'width', 'requiredFeatures', 'xml:lang', 'y', 'x', 'maskUnits']), properties=presentation_attributes, children=frozenset(['set', 'text', 'image', 'font-face', 'polyline', 'marker', 'animate', 'font', 'color-profile', 'ellipse', 'cursor', 'style', 'polygon', 'title', 'pattern', 'circle', 'radialGradient', 'metadata', 'defs', 'symbol', 'use', 'animateMotion', 'animateColor', 'path', 'line', 'rect', 'desc', 'a', 'g', 'svg', 'script', 'mask', 'altGlyphDef', 'filter', 'switch', 'animateTransform', 'linearGradient', 'clipPath', 'foreignObject', 'view'])), 'metadata': SVGElement('metadata', attributes=frozenset(['xml:space', 'xml:lang', 'xml:base', 'id']), properties=empty_list, children=frozenset(['*'])), 'missing-glyph': SVGElement('missing-glyph', attributes=frozenset(['xml:base', 'xml:space', 'id', 'xml:lang', 'class', 'style', 'd', 'horiz-adv-x', 'vert-origin-x', 'vert-origin-y', 'vert-adv-y']), properties=presentation_attributes, children=frozenset(['set', 'text', 'image', 'font-face', 'polyline', 'marker', 'animate', 'font', 'color-profile', 'ellipse', 'cursor', 'style', 'polygon', 'title', 'pattern', 'circle', 'radialGradient', 'metadata', 'defs', 'symbol', 'use', 'animateMotion', 'animateColor', 'path', 'line', 'rect', 'desc', 'a', 'g', 'svg', 'script', 'mask', 'altGlyphDef', 'filter', 'switch', 'animateTransform', 'linearGradient', 'clipPath', 'foreignObject', 'view'])), 'mpath': SVGElement('mpath', attributes=frozenset(['xlink:actuate', 'xlink:show', 'xml:base', 'xml:space', 'xlink:href', 'id', 'xlink:role', 'xml:lang', 'xlink:type', 'xlink:title', 'xlink:arcrole', 'externalResourcesRequired']), properties=empty_list, children=frozenset(['desc', 'metadata', 'title'])), 'path': SVGElement('path', attributes=frozenset(['xml:base', 'onmouseup', 'onmouseout', 'requiredExtensions', 'onfocusout', 'xml:space', 'systemLanguage', 'onmouseover', 'pathLength', 'externalResourcesRequired', 'id', 'onload', 'style', 'd', 'onactivate', 'onmousedown', 'transform', 'class', 'requiredFeatures', 'xml:lang', 'onmousemove', 'onclick', 'onfocusin']), properties=presentation_attributes, children=frozenset(['animateMotion', 'set', 'title', 'animateColor', 'animateTransform', 'animate', 'desc', 'metadata'])), 'pattern': SVGElement('pattern', attributes=frozenset(['xlink:title', 'xml:base', 'requiredExtensions', 'xml:space', 'xlink:href', 'height', 'class', 'systemLanguage', 'patternContentUnits', 'xlink:type', 'externalResourcesRequired', 'id', 'xlink:actuate', 'style', 'xlink:show', 'viewBox', 'xlink:role', 'width', 'requiredFeatures', 'patternUnits', 'patternTransform', 'y', 'x', 'preserveAspectRatio', 'xlink:arcrole', 'xml:lang']), properties=presentation_attributes, children=frozenset(['set', 'text', 'image', 'font-face', 'polyline', 'marker', 'animate', 'font', 'color-profile', 'ellipse', 'cursor', 'style', 'polygon', 'title', 'pattern', 'circle', 'radialGradient', 'metadata', 'defs', 'symbol', 'use', 'animateMotion', 'animateColor', 'path', 'line', 'rect', 'desc', 'a', 'g', 'svg', 'script', 'mask', 'altGlyphDef', 'filter', 'switch', 'animateTransform', 'linearGradient', 'clipPath', 'foreignObject', 'view'])), 'polygon': SVGElement('polygon', attributes=frozenset(['xml:base', 'onmouseup', 'onmouseout', 'requiredExtensions', 'onfocusout', 'xml:space', 'systemLanguage', 'onmouseover', 'externalResourcesRequired', 'id', 'onload', 'style', 'onactivate', 'onmousedown', 'transform', 'class', 'requiredFeatures', 'points', 'onmousemove', 'onclick', 'xml:lang', 'onfocusin']), properties=presentation_attributes, children=frozenset(['animateMotion', 'set', 'title', 'animateColor', 'animateTransform', 'animate', 'desc', 'metadata'])), 'polyline': SVGElement('polyline', attributes=frozenset(['xml:base', 'onmouseup', 'onmouseout', 'requiredExtensions', 'onfocusout', 'xml:space', 'systemLanguage', 'onmouseover', 'externalResourcesRequired', 'id', 'onload', 'style', 'onactivate', 'onmousedown', 'transform', 'class', 'requiredFeatures', 'points', 'onmousemove', 'onclick', 'xml:lang', 'onfocusin']), properties=presentation_attributes, children=frozenset(['animateMotion', 'set', 'title', 'animateColor', 'animateTransform', 'animate', 'desc', 'metadata'])), 'radialGradient': SVGElement('radialGradient', attributes=frozenset(['xlink:title', 'xml:base', 'fx', 'fy', 'xml:space', 'xlink:href', 'cy', 'cx', 'xlink:type', 'externalResourcesRequired', 'r', 'id', 'xlink:actuate', 'gradientUnits', 'style', 'xlink:show', 'spreadMethod', 'class', 'xlink:role', 'xml:lang', 'gradientTransform', 'xlink:arcrole']), properties=presentation_attributes, children=frozenset(['set', 'title', 'animate', 'animateTransform', 'stop', 'metadata', 'desc'])), 'rect': SVGElement('rect', attributes=frozenset(['xml:base', 'onmouseup', 'onmouseout', 'requiredExtensions', 'onfocusout', 'xml:space', 'height', 'systemLanguage', 'onmouseover', 'externalResourcesRequired', 'id', 'onload', 'style', 'ry', 'onactivate', 'onmousedown', 'rx', 'transform', 'class', 'width', 'requiredFeatures', 'xml:lang', 'onmousemove', 'onclick', 'y', 'x', 'onfocusin']), properties=presentation_attributes, children=frozenset(['animateMotion', 'set', 'title', 'animateColor', 'animateTransform', 'animate', 'metadata', 'desc'])), 'script': SVGElement('script', attributes=frozenset(['xlink:actuate', 'xlink:show', 'xml:base', 'xml:space', 'xlink:href', 'id', 'xlink:role', 'xml:lang', 'xlink:type', 'xlink:title', 'xlink:arcrole', 'type', 'externalResourcesRequired']), properties=empty_list, children=empty_list), 'set': SVGElement('set', attributes=frozenset(['begin', 'xlink:title', 'xml:base', 'requiredExtensions', 'repeatCount', 'xml:space', 'xlink:href', 'attributeName', 'onbegin', 'systemLanguage', 'attributeType', 'xlink:type', 'externalResourcesRequired', 'id', 'restart', 'fill', 'xlink:actuate', 'onload', 'xlink:show', 'end', 'min', 'repeatDur', 'xlink:role', 'to', 'requiredFeatures', 'xml:lang', 'max', 'dur', 'xlink:arcrole', 'onrepeat', 'onend']), properties=empty_list, children=frozenset(['desc', 'metadata', 'title'])), 'stop': SVGElement('stop', attributes=frozenset(['xml:base', 'xml:space', 'xml:lang', 'offset', 'style', 'class']), properties=presentation_attributes, children=frozenset(['animate', 'set', 'animateColor'])), 'style': SVGElement('style', attributes=frozenset(['xml:lang', 'xml:base', 'title', 'media', 'xml:space', 'type', 'id']), properties=empty_list, children=frozenset(['*'])), 'svg': SVGElement('svg', attributes=frozenset(['requiredExtensions', 'onerror', 'onfocusout', 'xml:space', 'height', 'onscroll', 'baseProfile', 'contentStyleType', 'id', 'onabort', 'onload', 'style', 'onmousedown', 'onzoom', 'onresize', 'width', 'version', 'onmousemove', 'onmouseup', 'xmlns:xlink', 'xmlns:ev', 'onfocusin', 'xml:base', 'onclick', 'onmouseout', 'systemLanguage', 'onmouseover', 'externalResourcesRequired', 'zoomAndPan', 'class', 'onunload', 'xmlns', 'onactivate', 'viewBox', 'requiredFeatures', 'xml:lang', 'y', 'x', 'preserveAspectRatio', 'contentScriptType']), properties=presentation_attributes, children=frozenset(['set', 'text', 'image', 'font-face', 'polyline', 'marker', 'animate', 'font', 'color-profile', 'ellipse', 'cursor', 'style', 'polygon', 'title', 'pattern', 'circle', 'radialGradient', 'metadata', 'defs', 'symbol', 'use', 'animateMotion', 'animateColor', 'path', 'line', 'rect', 'desc', 'a', 'g', 'svg', 'script', 'mask', 'altGlyphDef', 'filter', 'switch', 'animateTransform', 'linearGradient', 'clipPath', 'foreignObject', 'view'])), 'switch': SVGElement('switch', attributes=frozenset(['xml:base', 'onmouseup', 'onmouseout', 'requiredExtensions', 'onfocusout', 'xml:space', 'systemLanguage', 'onmouseover', 'externalResourcesRequired', 'class', 'onload', 'style', 'onactivate', 'onmousedown', 'transform', 'id', 'requiredFeatures', 'xml:lang', 'onmousemove', 'onclick', 'onfocusin']), properties=presentation_attributes, children=frozenset(['set', 'text', 'image', 'line', 'use', 'animateColor', 'polyline', 'path', 'animate', 'ellipse', 'rect', 'desc', 'a', 'animateMotion', 'polygon', 'g', 'title', 'svg', 'switch', 'animateTransform', 'foreignObject', 'circle', 'metadata'])), 'symbol': SVGElement('symbol', attributes=frozenset(['xml:base', 'onmouseup', 'onmouseout', 'onfocusout', 'xml:space', 'onmouseover', 'id', 'externalResourcesRequired', 'viewBox', 'onload', 'style', 'onactivate', 'onmousedown', 'class', 'xml:lang', 'onmousemove', 'onclick', 'preserveAspectRatio', 'onfocusin']), properties=presentation_attributes, children=frozenset(['set', 'text', 'image', 'font-face', 'polyline', 'marker', 'animate', 'font', 'color-profile', 'ellipse', 'cursor', 'style', 'polygon', 'title', 'pattern', 'circle', 'radialGradient', 'metadata', 'defs', 'symbol', 'use', 'animateMotion', 'animateColor', 'path', 'line', 'rect', 'desc', 'a', 'g', 'svg', 'script', 'mask', 'altGlyphDef', 'filter', 'switch', 'animateTransform', 'linearGradient', 'clipPath', 'foreignObject', 'view'])), 'text': SVGElement('text', attributes=frozenset(['xml:base', 'onmouseup', 'onmouseout', 'requiredExtensions', 'onfocusout', 'xml:space', 'class', 'systemLanguage', 'onmouseover', 'dx', 'dy', 'externalResourcesRequired', 'lengthAdjust', 'onload', 'style', 'rotate', 'onactivate', 'onmousedown', 'textLength', 'transform', 'id', 'requiredFeatures', 'xml:lang', 'onmousemove', 'onclick', 'y', 'x', 'onfocusin']), properties=presentation_attributes, children=frozenset(['a', 'animateMotion', 'set', 'title', 'textPath', 'tspan', 'animateColor', 'tref', 'animateTransform', 'altGlyph', 'animate', 'desc', 'metadata'])), 'textPath': SVGElement('textPath', attributes=frozenset(['requiredExtensions', 'onfocusout', 'xml:space', 'xlink:href', 'startOffset', 'id', 'onload', 'style', 'onmousedown', 'lengthAdjust', 'onmousemove', 'onclick', 'xlink:arcrole', 'onfocusin', 'xml:base', 'onmouseup', 'onmouseout', 'xlink:title', 'spacing', 'systemLanguage', 'onmouseover', 'xlink:type', 'externalResourcesRequired', 'class', 'xlink:actuate', 'xlink:show', 'onactivate', 'textLength', 'method', 'xlink:role', 'requiredFeatures', 'xml:lang']), properties=presentation_attributes, children=frozenset(['a', 'set', 'title', 'tspan', 'animateColor', 'tref', 'altGlyph', 'animate', 'metadata', 'desc'])), 'title': SVGElement('title', attributes=frozenset(['style', 'xml:lang', 'xml:base', 'xml:space', 'class', 'id']), properties=empty_list, children=frozenset(['*'])), 'tref': SVGElement('tref', attributes=frozenset(['requiredExtensions', 'onfocusout', 'xml:space', 'xlink:href', 'id', 'onload', 'style', 'onmousedown', 'lengthAdjust', 'onmousemove', 'onclick', 'xlink:arcrole', 'onfocusin', 'xml:base', 'onmouseup', 'onmouseout', 'xlink:title', 'systemLanguage', 'onmouseover', 'dx', 'dy', 'xlink:type', 'externalResourcesRequired', 'class', 'xlink:actuate', 'xlink:show', 'onactivate', 'textLength', 'xlink:role', 'requiredFeatures', 'xml:lang', 'y', 'x', 'rotate']), properties=presentation_attributes, children=frozenset(['set', 'title', 'animate', 'metadata', 'animateColor', 'desc'])), 'tspan': SVGElement('tspan', attributes=frozenset(['xml:base', 'onmouseup', 'onmouseout', 'requiredExtensions', 'onfocusout', 'xml:space', 'class', 'systemLanguage', 'onmouseover', 'dx', 'dy', 'externalResourcesRequired', 'lengthAdjust', 'onload', 'style', 'rotate', 'onactivate', 'onmousedown', 'textLength', 'id', 'requiredFeatures', 'xml:lang', 'onmousemove', 'onclick', 'y', 'x', 'onfocusin']), properties=presentation_attributes, children=frozenset(['a', 'set', 'title', 'tspan', 'animateColor', 'tref', 'altGlyph', 'animate', 'metadata', 'desc'])), 'use': SVGElement('use', attributes=frozenset(['requiredExtensions', 'onfocusout', 'xml:space', 'xlink:href', 'height', 'id', 'onload', 'style', 'onmousedown', 'transform', 'width', 'onmousemove', 'onclick', 'xlink:arcrole', 'onfocusin', 'xml:base', 'onmouseup', 'onmouseout', 'xlink:title', 'systemLanguage', 'onmouseover', 'xlink:type', 'externalResourcesRequired', 'class', 'xlink:actuate', 'xlink:show', 'onactivate', 'xlink:role', 'requiredFeatures', 'xml:lang', 'y', 'x']), properties=presentation_attributes, children=frozenset(['animateMotion', 'set', 'title', 'animateColor', 'animateTransform', 'animate', 'desc', 'metadata'])), 'view': SVGElement('view', attributes=frozenset(['xml:base', 'viewTarget', 'xml:space', 'viewBox', 'xml:lang', 'preserveAspectRatio', 'externalResourcesRequired', 'zoomAndPan', 'id']), properties=empty_list, children=frozenset(['desc', 'metadata', 'title'])), 'vkern': SVGElement('vkern', attributes=frozenset(['xml:base', 'g2', 'g1', 'xml:space', 'u1', 'u2', 'xml:lang', 'id', 'k']), properties=empty_list, children=empty_list), } svgwrite-1.1.8/svgwrite/data/pattern.py0000666000000000000000000000205012012650554016334 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: pattern module # Created: 27.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import re #coordinate ::= number ("em" | "ex" | "px" | "in" | "cm" | "mm" | "pt" | "pc" | "%")? coordinate = re.compile(r"(^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)(cm|em|ex|in|mm|pc|pt|px|%)?$") #length ::= number ("em" | "ex" | "px" | "in" | "cm" | "mm" | "pt" | "pc" | "%")? length = coordinate #angle ::= number (~"deg" | ~"grad" | ~"rad")? angle = re.compile(r"(^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)(deg|rad|grad)?$") # numbers without units number = re.compile(r"(^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)$") # number as percentage value '###%' percentage = re.compile(r"(^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)%$") #frequency ::= number (~"Hz" | ~"kHz") frequency = re.compile(r"(^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)(Hz|kHz)?$") #time ::= number (~"s" | ~"ms") time = re.compile(r"(^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)(s|ms)?$") svgwrite-1.1.8/svgwrite/data/svgparser.py0000666000000000000000000001550112342010462016672 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: svgparser using pyparser # Created: 16.10.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License # depends on: pyparsing.py by Paul T. McGuire - http://pyparsing.wikispaces.com/ __all__ = ["is_valid_transferlist", "is_valid_pathdata", "is_valid_animation_timing"] import sys from pyparsing import * from functools import partial event_names = [ "focusin", "focusout", "activate", "click", "mousedown", "mouseup", "mouseover", "mousemove", "mouseout", "DOMSubtreeModified", "DOMNodeInserted", "DOMNodeRemoved", "DOMNodeRemovedFromDocument", "DOMNodeInsertedtoDocument", "DOMAttrModified", "DOMCharacterDataModified", "SVGLoad", "SVGUnload", "SVGAbort", "SVGError", "SVGResize", "SVGScroll", "SVGZoom", "beginEvent", "endEvent", "repeatEvent", ] sign = oneOf('+ -') comma = Literal(',') * (0, 1) # zero or one ',' semicolon = Literal(';') * (0, 1) # zero or one ';' integer_constant = Word(nums) exponent = CaselessLiteral('E') + Optional(sign) + integer_constant fractional_constant = Combine(Optional(integer_constant) + '.' + integer_constant) \ ^ Combine(integer_constant + '.') scientific_constant = Combine(fractional_constant + Optional(exponent)) \ ^ Combine(integer_constant + exponent) number = Combine(Optional(sign) + integer_constant) \ ^ Combine(Optional(sign) + scientific_constant) def has_valid_syntax(term, parser): try: parser.parseString(term, parseAll=True) return True except ParseException: return False def build_transferlist_parser(): matrix = Literal("matrix") + '(' + number + (Suppress(comma) + number) * 5 + ')' translate = Literal("translate") + '(' + number + Optional(comma + number) + ')' scale = Literal("scale") + '(' + number + Optional(comma + number) + ')' rotate = Literal("rotate") + '(' + number + Optional(comma + number + comma + number) + ')' skewX = Literal("skewX") + '(' + number + ')' skewY = Literal("skewY") + '(' + number + ')' transform = matrix | translate | scale | rotate | skewX | skewY return transform + ZeroOrMore(comma + transform) transferlist_parser = build_transferlist_parser() is_valid_transferlist = partial(has_valid_syntax, parser=transferlist_parser) def build_pathdata_parser(): coordinate = number coordinate_pair = coordinate + comma + coordinate nonnegative_number = integer_constant ^ scientific_constant flag = oneOf('0 1') comma_delimited_coordinates = coordinate + ZeroOrMore(comma + coordinate) comma_delimited_coordinate_pairs = coordinate_pair + ZeroOrMore(comma + coordinate_pair) closepath = oneOf('Z z') moveto = oneOf('M m') + comma_delimited_coordinate_pairs lineto = oneOf('L l') + comma_delimited_coordinate_pairs horizontal_lineto = oneOf('H h') + comma_delimited_coordinates vertical_lineto = oneOf('V v') + comma_delimited_coordinates curveto_argument_sequence = coordinate_pair + comma + coordinate_pair + comma + coordinate_pair curveto = oneOf('C c') + curveto_argument_sequence + ZeroOrMore(comma + curveto_argument_sequence) smooth_curveto_argument_sequence = coordinate_pair + comma + coordinate_pair smooth_curveto = oneOf('S s') + smooth_curveto_argument_sequence \ + ZeroOrMore(comma + smooth_curveto_argument_sequence) quadratic_bezier_curveto_argument_sequence = coordinate_pair + comma + coordinate_pair quadratic_bezier_curveto = oneOf('Q q') + quadratic_bezier_curveto_argument_sequence \ + ZeroOrMore(comma + quadratic_bezier_curveto_argument_sequence) smooth_quadratic_bezier_curveto = oneOf('T t') + coordinate_pair \ + ZeroOrMore(comma + coordinate_pair) elliptical_arc_argument = nonnegative_number + comma + nonnegative_number \ + comma + number + comma + flag + comma + flag + comma + coordinate_pair elliptical_arc = oneOf('A a') + elliptical_arc_argument \ + ZeroOrMore(comma + elliptical_arc_argument) drawto_command = closepath \ | lineto \ | horizontal_lineto \ | vertical_lineto \ | curveto \ | smooth_curveto \ | quadratic_bezier_curveto \ | smooth_quadratic_bezier_curveto \ | elliptical_arc return OneOrMore(moveto + ZeroOrMore(drawto_command)) pathdata_parser = build_pathdata_parser() is_valid_pathdata = partial(has_valid_syntax, parser=pathdata_parser) def build_clock_val_parser(): digit2 = Word(nums, exact=2) timecount = integer_constant fraction = integer_constant seconds = digit2 minutes = digit2 hours = integer_constant metric = oneOf("h min s ms") timecount_val = timecount + Optional("." + fraction) + Optional(metric) partial_clock_val = minutes + ":" + seconds + Optional("." + fraction) full_clock_val = hours + ":" + minutes + ":" + seconds + Optional("." + fraction) return full_clock_val | partial_clock_val | timecount_val def build_wall_clock_val_parser(): # http://www.w3.org/TR/2005/REC-SMIL2-20050107/smil-timing.html#Timing-WallclockSyncValueSyntax digit2 = Word(nums, exact=2) fraction = integer_constant seconds = digit2 minutes = digit2 hours24 = digit2 day = digit2 month = digit2 year = Word(nums, exact=4) tzd = Literal("Z") | (sign + hours24 + ":" + minutes) hhmmss = hours24 + ":" + minutes + Optional(":" + seconds + Optional("." + fraction)) walltime = hhmmss + Optional(tzd) date = year + "-" + month + "-" + day datetime = date + "T" + walltime return datetime | walltime | date def build_animation_timing_parser(): clock_val = build_clock_val_parser() wallclock_value = build_wall_clock_val_parser() event_ref = oneOf(event_names) # TODO: check id-value definition: is a leading '#' really valid? id_value = Optional("#") + Word(alphanums + "-_") opt_clock_val = Optional(sign + clock_val) wallclock_sync_value = Literal("wallclock(") + wallclock_value + ")" accesskey_value = Literal("accessKey(") + Word(alphas, exact=1) + ")" + opt_clock_val repeat_value = Optional(id_value + ".") + Literal("repeat(") + integer_constant + ")" + opt_clock_val event_value = Optional(id_value + ".") + event_ref + opt_clock_val syncbase_value = id_value + "." + oneOf("begin end") + opt_clock_val offset_value = Optional(sign) + clock_val begin_value = offset_value | syncbase_value | event_value | repeat_value \ | accesskey_value | wallclock_sync_value | Literal("indefinite") return begin_value + ZeroOrMore(semicolon + begin_value) animation_timing_parser = build_animation_timing_parser() is_valid_animation_timing = partial(has_valid_syntax, parser=animation_timing_parser) svgwrite-1.1.8/svgwrite/data/tiny12.py0000666000000000000000000016272312012650556016025 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: tiny12 data # Created: 15.10.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License from svgwrite.data.types import SVGAttribute, SVGMultiAttribute from svgwrite.data.types import SVGElement from svgwrite.data.typechecker import Tiny12TypeChecker as TypeChecker empty_list = [] attributes = { 'about': SVGAttribute('about', anim=True, types=frozenset(['string']), const=empty_list), 'accent-height': SVGAttribute('accent-height', anim=False, types=frozenset(['number']), const=empty_list), 'accumulate': SVGAttribute('accumulate', anim=False, types=empty_list, const=frozenset(['none', 'sum'])), 'additive': SVGAttribute('additive', anim=False, types=empty_list, const=frozenset(['replace', 'sum'])), 'alphabetic': SVGAttribute('alphabetic', anim=False, types=frozenset(['number']), const=empty_list), 'arabic-form': SVGAttribute('arabic-form', anim=False, types=empty_list, const=frozenset(['terminal', 'initial', 'isolated', 'medial'])), 'ascent': SVGAttribute('ascent', anim=False, types=frozenset(['number']), const=empty_list), 'attributeName': SVGAttribute('attributeName', anim=False, types=frozenset(['name']), const=empty_list), 'attributeType': SVGAttribute('attributeType', anim=False, types=empty_list, const=frozenset(['XML', 'CSS', 'auto'])), 'audio-level': SVGAttribute('audio-level', anim=True, types=frozenset(['number']), const=frozenset(['inherit'])), 'bandwidth': SVGAttribute('bandwidth', anim=False, types=frozenset(['number']), const=frozenset(['auto'])), 'baseProfile': SVGAttribute('baseProfile', anim=False, types=empty_list, const=frozenset(['none', 'tiny', 'basic', 'full'])), 'bbox': SVGAttribute('bbox', anim=False, types=frozenset(['string']), const=empty_list), 'begin': SVGAttribute('begin', anim=False, types=frozenset(['timing-value-list']), const=frozenset(['indefinite'])), 'buffered-rendering': SVGAttribute('buffered-rendering', anim=True, types=empty_list, const=frozenset(['auto', 'dynamic', 'static', 'inherit'])), 'by': SVGAttribute('by', anim=False, types=frozenset(['string']), const=empty_list), 'calcMode': SVGAttribute('calcMode', anim=False, types=empty_list, const=frozenset(['discrete', 'linear', 'paced', 'spline'])), 'cap-height': SVGAttribute('cap-height', anim=False, types=frozenset(['number']), const=empty_list), 'class': SVGAttribute('class', anim=True, types=frozenset(['XML-Name']), const=empty_list), 'color': SVGAttribute('color', anim=True, types=frozenset(['color']), const=frozenset(['inherit'])), 'color-rendering': SVGAttribute('color-rendering', anim=True, types=empty_list, const=frozenset(['auto', 'optimizeSpeed', 'optimizeQuality', 'inherit'])), 'content': SVGAttribute('content', anim=True, types=frozenset(['string']), const=empty_list), 'contentScriptType': SVGAttribute('contentScriptType', anim=False, types=frozenset(['content-type']), const=empty_list), 'cx': SVGAttribute('cx', anim=True, types=frozenset(['coordinate']), const=empty_list), 'cy': SVGAttribute('cy', anim=True, types=frozenset(['coordinate']), const=empty_list), 'd': SVGAttribute('d', anim=True, types=frozenset(['path-data']), const=empty_list), 'datatype': SVGAttribute('datatype', anim=True, types=frozenset(['string']), const=empty_list), 'defaultAction': SVGAttribute('defaultAction', anim=False, types=empty_list, const=frozenset(['perform', 'cancel'])), 'descent': SVGAttribute('descent', anim=False, types=frozenset(['number']), const=empty_list), 'direction': SVGAttribute('direction', anim=False, types=empty_list, const=frozenset(['ltr', 'rtl', 'inherit'])), 'display': SVGAttribute('display', anim=True, types=empty_list, const=frozenset(['inline', 'block', 'list-item', 'run-in', 'compact', 'marker', 'table', 'inline-table', 'table-row-group', 'table-header-group', 'table-footer-group', 'table-row', 'table-column-group', 'table-column', 'table-cell', 'table-caption', 'none', 'inherit'])), 'display-align': SVGAttribute('display-align', anim=True, types=empty_list, const=frozenset(['auto', 'before', 'center', 'after', 'inherit'])), 'dur': SVGAttribute('dur', anim=False, types=frozenset(['time']), const=frozenset(['media', 'indefinite'])), 'editable': SVGAttribute('editable', anim=True, types=empty_list, const=frozenset(['none', 'simple'])), 'end': SVGAttribute('end', anim=False, types=frozenset(['timing-value-list']), const=frozenset(['indefinite'])), 'ev:event': SVGAttribute('ev:event', anim=False, types=frozenset(['XML-Name']), const=empty_list), 'event': SVGAttribute('event', anim=False, types=frozenset(['XML-Name']), const=empty_list), 'externalResourcesRequired': SVGAttribute('externalResourcesRequired', anim=False, types=frozenset(['boolean']), const=empty_list), 'fill': SVGMultiAttribute({ '*': SVGAttribute( 'fill', anim=True, types=frozenset(['paint']), const=frozenset(['inherit'])), 'set animateMotion animate animateColor animateTransform': SVGAttribute( 'fill', anim=False, types=empty_list, const=frozenset(['freeze', 'remove'])) }), 'fill-opacity': SVGAttribute('fill-opacity', anim=True, types=frozenset(['number']), const=frozenset(['inherit'])), 'fill-rule': SVGAttribute('fill-rule', anim=True, types=empty_list, const=frozenset(['nonzero', 'evenodd', 'inherit'])), 'focusHighlight': SVGAttribute('focusHighlight', anim=True, types=empty_list, const=frozenset(['auto', 'none'])), 'focusable': SVGAttribute('focusable', anim=True, types=frozenset(['boolean']), const=frozenset(['auto'])), 'font-family': SVGAttribute('font-family', anim=True, types=frozenset(['string']), const=frozenset(['inherit'])), 'font-size': SVGAttribute('font-size', anim=True, types=frozenset(['length']), const=frozenset(['inherit'])), 'font-stretch': SVGAttribute('font-stretch', anim=False, types=empty_list, const=frozenset(['condensed', 'normal', 'ultra-condensed', 'expanded', 'narrower', 'inherit', 'semi-condensed', 'extra-condensed', 'ultra-expanded', 'wider', 'semi-expanded', 'extra-expanded'])), 'font-style': SVGAttribute('font-style', anim=True, types=empty_list, const=frozenset(['normal', 'italic', 'oblique', 'inherit'])), 'font-variant': SVGAttribute('font-variant', anim=True, types=empty_list, const=frozenset(['normal', 'small-caps', 'inherit'])), 'font-weight': SVGAttribute('font-weight', anim=True, types=empty_list, const=frozenset(['normal', 'bold', 'bolder', 'lighter', '100', '200', '300', '400', '500', '600', '700', '800', '900', 'inherit'])), 'from': SVGAttribute('from', anim=False, types=frozenset(['string']), const=empty_list), 'g1': SVGAttribute('g1', anim=False, types=frozenset(['list-of-name']), const=empty_list), 'g2': SVGAttribute('g2', anim=False, types=frozenset(['list-of-name']), const=empty_list), 'glyph-name': SVGAttribute('glyph-name', anim=False, types=frozenset(['list-of-name']), const=empty_list), 'gradientUnits': SVGAttribute('gradientUnits', anim=True, types=empty_list, const=frozenset(['userSpaceOnUse', 'objectBoundingBox'])), 'handler': SVGAttribute('handler', anim=False, types=frozenset(['IRI']), const=empty_list), 'hanging': SVGAttribute('hanging', anim=False, types=frozenset(['number']), const=empty_list), 'height': SVGMultiAttribute({ '*': SVGAttribute( 'height', anim=True, types=frozenset(['length']), const=empty_list), 'textArea': SVGAttribute( 'height', anim=True, types=frozenset(['length']), const=frozenset(['auto'])), }), 'horiz-adv-x': SVGAttribute('horiz-adv-x', anim=False, types=frozenset(['number']), const=empty_list), 'horiz-origin-x': SVGAttribute('horiz-origin-x', anim=False, types=frozenset(['number']), const=empty_list), 'id': SVGAttribute('id', anim=False, types=frozenset(['name']), const=empty_list), 'ideographic': SVGAttribute('ideographic', anim=False, types=frozenset(['number']), const=empty_list), 'image-rendering': SVGAttribute('image-rendering', anim=True, types=empty_list, const=frozenset(['auto', 'optimizeSpeed', 'optimizeQuality', 'inherit'])), 'initialVisibility': SVGAttribute('initialVisibility', anim=False, types=empty_list, const=frozenset(['whenStarted', 'always'])), 'k': SVGAttribute('k', anim=False, types=frozenset(['number']), const=empty_list), 'keyPoints': SVGAttribute('keyPoints', anim=False, types=frozenset(['semicolon-list']), const=empty_list), 'keySplines': SVGAttribute('keySplines', anim=False, types=frozenset(['semicolon-list']), const=empty_list), 'keyTimes': SVGAttribute('keyTimes', anim=False, types=frozenset(['semicolon-list']), const=empty_list), 'lang': SVGAttribute('lang', anim=False, types=frozenset(['list-of-name']), const=empty_list), 'line-increment': SVGAttribute('line-increment', anim=True, types=frozenset(['number']), const=frozenset(['auto', 'inherit'])), 'mathematical': SVGAttribute('mathematical', anim=False, types=frozenset(['number']), const=empty_list), 'max': SVGAttribute('max', anim=False, types=frozenset(['time']), const=frozenset(['media'])), 'mediaCharacterEncoding': SVGAttribute('mediaCharacterEncoding', anim=False, types=frozenset(['string']), const=empty_list), 'mediaContentEncodings': SVGAttribute('mediaContentEncodings', anim=False, types=frozenset(['string']), const=empty_list), 'mediaSize': SVGAttribute('mediaSize', anim=False, types=frozenset(['number']), const=empty_list), 'mediaTime': SVGAttribute('mediaTime', anim=False, types=frozenset(['time']), const=empty_list), 'min': SVGAttribute('min', anim=False, types=frozenset(['time']), const=frozenset(['media'])), 'nav-down': SVGAttribute('nav-down', anim=True, types=frozenset(['focus']), const=empty_list), 'nav-down-left': SVGAttribute('nav-down-left', anim=True, types=frozenset(['focus']), const=empty_list), 'nav-down-right': SVGAttribute('nav-down-right', anim=True, types=frozenset(['focus']), const=empty_list), 'nav-left': SVGAttribute('nav-left', anim=True, types=frozenset(['focus']), const=empty_list), 'nav-next': SVGAttribute('nav-next', anim=True, types=frozenset(['focus']), const=empty_list), 'nav-prev': SVGAttribute('nav-prev', anim=True, types=frozenset(['focus']), const=empty_list), 'nav-right': SVGAttribute('nav-right', anim=True, types=frozenset(['focus']), const=empty_list), 'nav-up': SVGAttribute('nav-up', anim=True, types=frozenset(['focus']), const=empty_list), 'nav-up-left': SVGAttribute('nav-up-left', anim=True, types=frozenset(['focus']), const=empty_list), 'nav-up-right': SVGAttribute('nav-up-right', anim=True, types=frozenset(['focus']), const=empty_list), 'observer': SVGAttribute('observer', anim=False, types=frozenset(['IDREF']), const=empty_list), 'offset': SVGAttribute('offset', anim=True, types=frozenset(['number']), const=empty_list), 'opacity': SVGAttribute('opacity', anim=True, types=frozenset(['number']), const=frozenset(['inherit'])), 'origin': SVGAttribute('origin', anim=False, types=empty_list, const=frozenset(['default'])), 'overlay': SVGAttribute('overlay', anim=False, types=empty_list, const=frozenset(['none', 'top'])), 'overline-position': SVGAttribute('overline-position', anim=False, types=frozenset(['number']), const=empty_list), 'overline-thickness': SVGAttribute('overline-thickness', anim=False, types=frozenset(['number']), const=empty_list), 'panose-1': SVGAttribute('panose-1', anim=False, types=frozenset(['list-of-integer']), const=empty_list), 'path': SVGAttribute('path', anim=False, types=frozenset(['path-data']), const=empty_list), 'pathLength': SVGAttribute('pathLength', anim=True, types=frozenset(['number']), const=empty_list), 'phase': SVGAttribute('phase', anim=False, types=empty_list, const=frozenset(['default', 'capture'])), 'playbackOrder': SVGAttribute('playbackOrder', anim=False, types=empty_list, const=frozenset(['all', 'forwardOnly'])), 'pointer-events': SVGAttribute('pointer-events', anim=True, types=empty_list, const=frozenset(['visiblePainted', 'visibleFill', 'visibleStroke', 'visible', 'painted', 'fill', 'stroke', 'all', 'none', 'inherit'])), 'points': SVGAttribute('points', anim=True, types=frozenset(['list-of-number']), const=empty_list), 'preserveAspectRatio': SVGAttribute('preserveAspectRatio', anim=True, types=frozenset(['string']), const=empty_list), 'propagate': SVGAttribute('propagate', anim=False, types=empty_list, const=frozenset(['continue', 'stop'])), 'property': SVGAttribute('property', anim=True, types=frozenset(['string']), const=empty_list), 'r': SVGAttribute('r', anim=True, types=frozenset(['length']), const=empty_list), 'rel': SVGAttribute('rel', anim=True, types=frozenset(['string']), const=empty_list), 'repeatCount': SVGAttribute('repeatCount', anim=False, types=frozenset(['number']), const=frozenset(['indefinite'])), 'repeatDur': SVGAttribute('repeatDur', anim=False, types=frozenset(['time']), const=frozenset(['indefinite'])), 'requiredExtensions': SVGAttribute('requiredExtensions', anim=False, types=frozenset(['list-of-IRI']), const=empty_list), 'requiredFeatures': SVGAttribute('requiredFeatures', anim=False, types=frozenset(['list-of-IRI']), const=empty_list), 'requiredFonts': SVGAttribute('requiredFonts', anim=False, types=frozenset(['string']), const=empty_list), 'requiredFormats': SVGAttribute('requiredFormats', anim=False, types=frozenset(['anything']), const=empty_list), 'resource': SVGAttribute('resource', anim=True, types=frozenset(['string']), const=empty_list), 'restart': SVGAttribute('restart', anim=False, types=empty_list, const=frozenset(['always', 'never', 'whenNotActive'])), 'rev': SVGAttribute('rev', anim=True, types=frozenset(['string']), const=empty_list), 'role': SVGAttribute('role', anim=True, types=frozenset(['string']), const=empty_list), 'rotate': SVGAttribute('rotate', anim=True, types=frozenset(['list-of-number']), const=empty_list), 'rx': SVGAttribute('rx', anim=True, types=frozenset(['length']), const=empty_list), 'ry': SVGAttribute('ry', anim=True, types=frozenset(['length']), const=empty_list), 'shape-rendering': SVGAttribute('shape-rendering', anim=True, types=empty_list, const=frozenset(['auto', 'optimizeSpeed', 'crispEdges', 'geometricPrecision', 'inherit'])), 'slope': SVGAttribute('slope', anim=False, types=frozenset(['number']), const=empty_list), 'snapshotTime': SVGAttribute('snapshotTime', anim=False, types=frozenset(['time']), const=frozenset(['none'])), 'solid-color': SVGAttribute('solid-color', anim=True, types=frozenset(['color']), const=frozenset(['inherit'])), 'solid-opacity': SVGAttribute('solid-opacity', anim=True, types=frozenset(['number']), const=frozenset(['inherit'])), 'stemh': SVGAttribute('stemh', anim=False, types=frozenset(['number']), const=empty_list), 'stemv': SVGAttribute('stemv', anim=False, types=frozenset(['number']), const=empty_list), 'stop-color': SVGAttribute('stop-color', anim=True, types=frozenset(['color']), const=frozenset(['inherit'])), 'stop-opacity': SVGAttribute('stop-opacity', anim=True, types=frozenset(['number']), const=frozenset(['inherit'])), 'strikethrough-position': SVGAttribute('strikethrough-position', anim=False, types=frozenset(['number']), const=empty_list), 'strikethrough-thickness': SVGAttribute('strikethrough-thickness', anim=False, types=frozenset(['number']), const=empty_list), 'stroke': SVGAttribute('stroke', anim=True, types=frozenset(['paint']), const=frozenset(['inherit'])), 'stroke-dasharray': SVGAttribute('stroke-dasharray', anim=True, types=frozenset(['list-of-length']), const=frozenset(['none', 'inherit'])), 'stroke-dashoffset': SVGAttribute('stroke-dashoffset', anim=True, types=frozenset(['length']), const=frozenset(['inherit'])), 'stroke-linecap': SVGAttribute('stroke-linecap', anim=True, types=empty_list, const=frozenset(['butt', 'round', 'square', 'inherit'])), 'stroke-linejoin': SVGAttribute('stroke-linejoin', anim=True, types=empty_list, const=frozenset(['miter', 'round', 'bevel', 'inherit'])), 'stroke-miterlimit': SVGAttribute('stroke-miterlimit', anim=True, types=frozenset(['number']), const=frozenset(['inherit'])), 'stroke-opacity': SVGAttribute('stroke-opacity', anim=True, types=frozenset(['number']), const=frozenset(['inherit'])), 'stroke-width': SVGAttribute('stroke-width', anim=True, types=frozenset(['length']), const=frozenset(['inherit'])), 'syncBehavior': SVGAttribute('syncBehavior', anim=False, types=empty_list, const=frozenset(['canSlip', 'locked', 'independent', 'default'])), 'syncBehaviorDefault': SVGAttribute('syncBehaviorDefault', anim=False, types=empty_list, const=frozenset(['canSlip', 'locked', 'independent', 'inherit'])), 'syncMaster': SVGAttribute('syncMaster', anim=False, types=frozenset(['boolean']), const=empty_list), 'syncTolerance': SVGAttribute('syncTolerance', anim=False, types=frozenset(['time']), const=frozenset(['default'])), 'syncToleranceDefault': SVGAttribute('syncToleranceDefault', anim=False, types=frozenset(['time']), const=frozenset(['inherit'])), 'systemLanguage': SVGAttribute('systemLanguage', anim=False, types=frozenset(['string']), const=empty_list), 'target': SVGMultiAttribute({ '* a': SVGAttribute( 'target', anim=True, types=frozenset(['XML-Name']), const=frozenset(['_replace', '_self', '_parent', '_top', '_blank'])), 'listener': SVGAttribute( 'target', anim=False, types=frozenset(['XML-Name']), const=empty_list), }), 'text-align': SVGAttribute('text-align', anim=True, types=empty_list, const=frozenset(['start', 'center', 'end', 'inherit'])), 'text-anchor': SVGAttribute('text-anchor', anim=True, types=empty_list, const=frozenset(['start', 'middle', 'end', 'inherit'])), 'text-rendering': SVGAttribute('text-rendering', anim=True, types=empty_list, const=frozenset(['auto', 'optimizeSpeed', 'optimizeLegibility', 'geometricPrecision', 'inherit'])), 'timelineBegin': SVGAttribute('timelineBegin', anim=False, types=empty_list, const=frozenset(['onLoad', 'onStart'])), 'to': SVGAttribute('to', anim=False, types=frozenset(['string']), const=empty_list), 'transform': SVGAttribute('transform', anim=True, types=frozenset(['transform-list']), const=frozenset(['none'])), 'transformBehavior': SVGAttribute('transformBehavior', anim=False, types=empty_list, const=frozenset(['geometric', 'pinned', 'pinned90', 'pinned180', 'pinned270'])), 'type': SVGMultiAttribute({ '* audio image video': SVGAttribute( 'type', anim=True, types=frozenset(['content-type']), const=empty_list), 'handler script': SVGAttribute( 'type', anim=False, types=frozenset(['content-type']), const=empty_list), 'animateTransform': SVGAttribute( 'type', anim=False, types=empty_list, const=frozenset(['translate', 'scale', 'rotate', 'skewX', 'skewY'])), }), 'typeof': SVGAttribute('typeof', anim=True, types=frozenset(['string']), const=empty_list), 'u1': SVGAttribute('u1', anim=False, types=frozenset(['string']), const=empty_list), 'u2': SVGAttribute('u2', anim=False, types=frozenset(['string']), const=empty_list), 'underline-position': SVGAttribute('underline-position', anim=False, types=frozenset(['number']), const=empty_list), 'underline-thickness': SVGAttribute('underline-thickness', anim=False, types=frozenset(['number']), const=empty_list), 'unicode': SVGAttribute('unicode', anim=False, types=frozenset(['string']), const=empty_list), 'unicode-bidi': SVGAttribute('unicode-bidi', anim=False, types=empty_list, const=frozenset(['normal', 'embed', 'bidi-override', 'inherit'])), 'unicode-range': SVGAttribute('unicode-range', anim=False, types=frozenset(['string']), const=empty_list), 'units-per-em': SVGAttribute('units-per-em', anim=False, types=frozenset(['number']), const=empty_list), 'values': SVGAttribute('values', anim=False, types=frozenset(['list-of-number']), const=empty_list), 'vector-effect': SVGAttribute('vector-effect', anim=True, types=empty_list, const=frozenset(['none', 'non-scaling-stroke', 'inherit'])), 'version': SVGAttribute('version', anim=False, types=empty_list, const=frozenset(['1.1', '1.2'])), 'viewBox': SVGAttribute('viewBox', anim=True, types=frozenset(['four-numbers']), const=empty_list), 'viewport-fill': SVGAttribute('viewport-fill', anim=True, types=frozenset(['color']), const=frozenset(['none', 'inherit'])), 'viewport-fill-opacity': SVGAttribute('viewport-fill-opacity', anim=True, types=frozenset(['number']), const=frozenset(['inherit'])), 'visibility': SVGAttribute('visibility', anim=True, types=empty_list, const=frozenset(['visible', 'hidden', 'inherit'])), 'width': SVGMultiAttribute({ '*': SVGAttribute( 'width', anim=True, types=frozenset(['length']), const=empty_list), 'textArea': SVGAttribute( 'width', anim=True, types=frozenset(['length']), const=frozenset(['auto'])), }), 'widths': SVGAttribute('widths', anim=False, types=frozenset(['string']), const=empty_list), 'x': SVGMultiAttribute({ '*': SVGAttribute( 'x', anim=True, types=frozenset(['coordinate']), const=empty_list), 'text': SVGAttribute( 'x', anim=True, types=frozenset(['list-of-coordinate']), const=empty_list), }), 'x-height': SVGAttribute('x-height', anim=False, types=frozenset(['number']), const=empty_list), 'x1': SVGAttribute('x1', anim=True, types=frozenset(['coordinate']), const=empty_list), 'x2': SVGAttribute('x2', anim=True, types=frozenset(['coordinate']), const=empty_list), 'xlink:actuate': SVGMultiAttribute({ '*': SVGAttribute( 'xlink:actuate', anim=False, types=empty_list, const=frozenset(['onLoad'])), 'a': SVGAttribute( 'xlink:actuate', anim=False, types=empty_list, const=frozenset(['onRequest'])), }), 'xlink:arcrole': SVGAttribute('xlink:arcrole', anim=False, types=frozenset(['IRI']), const=empty_list), 'xlink:href': SVGAttribute('xlink:href', anim=True, types=frozenset(['IRI']), const=empty_list), 'xlink:role': SVGAttribute('xlink:role', anim=False, types=frozenset(['IRI']), const=empty_list), 'xlink:show': SVGMultiAttribute({ '*': SVGAttribute( 'xlink:show', anim=False, types=empty_list, const=frozenset(['other'])), 'animation audio foreignObject image use video': SVGAttribute( 'xlink:show', anim=False, types=empty_list, const=frozenset(['embed'])), 'a': SVGAttribute( 'xlink:show', anim=False, types=empty_list, const=frozenset(['new', 'replace'])), }), 'xlink:title': SVGAttribute('xlink:title', anim=False, types=frozenset(['string']), const=empty_list), 'xlink:type': SVGAttribute('xlink:type', anim=True, types=empty_list, const=frozenset(['simple'])), 'xmlns': SVGAttribute('xmlns', anim=False, types=frozenset(['IRI']), const=empty_list), 'xmlns:xlink': SVGAttribute('xmlns:xlink', anim=False, types=frozenset(['IRI']), const=empty_list), 'xmlns:ev': SVGAttribute('xmlns:ev', anim=False, types=frozenset(['IRI']), const=empty_list), 'xml:base': SVGAttribute('xml:base', anim=False, types=frozenset(['IRI']), const=empty_list), 'xml:id': SVGAttribute('xml:id', anim=False, types=frozenset(['name']), const=empty_list), 'xml:lang': SVGAttribute('xml:lang', anim=False, types=frozenset(['name']), const=empty_list), 'xml:space': SVGMultiAttribute({ '*': SVGAttribute( 'xml:space', anim=False, types=empty_list, const=frozenset(['preserve', 'default'])), 'handler script': SVGAttribute( 'xml:space', anim=False, types=empty_list, const=frozenset(['preserve'])), }), 'y': SVGMultiAttribute({ '*': SVGAttribute( 'y', anim=True, types=frozenset(['coordinate']), const=empty_list), 'text': SVGAttribute( 'y', anim=True, types=frozenset(['list-of-coordinate']), const=empty_list), }), 'y1': SVGAttribute('y1', anim=True, types=frozenset(['coordinate']), const=empty_list), 'y2': SVGAttribute('y2', anim=True, types=frozenset(['coordinate']), const=empty_list), 'zoomAndPan': SVGAttribute('zoomAndPan', anim=False, types=empty_list, const=frozenset(['disable', 'magnify'])), } attribute_names = ['slope', 'keySplines', 'rx', 'accumulate', 'bandwidth', 'attributeType', 'unicode', 'nav-right', 'arabic-form', 'y2', 'horiz-origin-x', 'underline-position', 'zoomAndPan', 'cap-height', 'defaultAction', 'to', 'syncBehavior', 'alphabetic', 'g2', 'g1', 'panose-1', 'strikethrough-thickness', 'attributeName', 'bbox', 'nav-up-left', 'nav-left', 'restart', 'target', 'xlink:actuate', 'rotate', 'resource', 'd', 'syncToleranceDefault', 'initialVisibility', 'transformBehavior', 'nav-up-right', 'keyTimes', 'x', 'requiredFormats', 'nav-next', 'glyph-name', 'xml:lang', 'mathematical', 'observer', 'repeatDur', 'hanging', 'y1', 'xml:base', 'ascent', 'event', 'strikethrough-position', 'overlay', 'rev', 'ry', 'overline-thickness', 'content', 'version', 'rel', 'focusable', 'requiredFonts', 'nav-down-right', 'xml:id', 'offset', 'additive', 'underline-thickness', 'font-family', 'by', 'mediaTime', 'timelineBegin', 'about', 'horiz-adv-x', 'widths', 'k', 'requiredFeatures', 'preserveAspectRatio', 'contentScriptType', 'origin', 'xml:space', 'xlink:href', 'height', 'baseProfile', 'cy', 'cx', 'path', 'xlink:role', 'from', 'u1', 'transform', 'units-per-em', 'u2', 'width', 'handler', 'font-variant', 'x-height', 'dur', 'xlink:arcrole', 'type', 'focusHighlight', 'mediaCharacterEncoding', 'xlink:title', 'editable', 'stemv', 'systemLanguage', 'x2', 'x1', 'ideographic', 'xlink:show', 'overline-position', 'syncTolerance', 'gradientUnits', 'r', 'values', 'typeof', 'mediaContentEncodings', 'property', 'requiredExtensions', 'repeatCount', 'ev:event', 'nav-down', 'mediaSize', 'pathLength', 'syncMaster', 'font-style', 'fill', 'end', 'descent', 'calcMode', 'min', 'stemh', 'id', 'unicode-range', 'nav-up', 'font-stretch', 'role', 'font-weight', 'begin', 'xlink:type', 'syncBehaviorDefault', 'max', 'snapshotTime', 'playbackOrder', 'keyPoints', 'nav-prev', 'propagate', 'phase', 'externalResourcesRequired', 'nav-down-left', 'class', 'lang', 'datatype', 'viewBox', 'points', 'accent-height', 'y'] property_names = ['stroke-linejoin', 'font-size', 'text-rendering', 'color-rendering', 'fill-opacity', 'color', 'shape-rendering', 'solid-color', 'stroke', 'stroke-linecap', 'vector-effect', 'stroke-width', 'font-style', 'fill', 'solid-opacity', 'fill-rule', 'viewport-fill-opacity', 'display-align', 'buffered-rendering', 'stroke-miterlimit', 'font-variant', 'stop-opacity', 'font-weight', 'opacity', 'direction', 'audio-level', 'visibility', 'unicode-bidi', 'line-increment', 'image-rendering', 'font-family', 'viewport-fill', 'text-align', 'stroke-opacity', 'stroke-dashoffset', 'text-anchor', 'stop-color', 'pointer-events', 'stroke-dasharray', 'display'] media_group_names = ['audio-level', 'buffered-rendering', 'display', 'image-rendering', 'pointer-events', 'shape-rendering', 'text-rendering', 'viewport-fill', 'viewport-fill-opacity', 'visibility'] elements = { 'a': SVGElement('a', attributes=['about', 'class', 'content', 'datatype', 'externalResourcesRequired', 'focusHighlight', 'focusable', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'target', 'transform', 'typeof', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=property_names, children=['likeparent', 'defs', 'text', 'g', 'textArea', 'svg']), 'animate': SVGElement('animate', attributes=['about', 'accumulate', 'additive', 'attributeName', 'attributeType', 'begin', 'by', 'calcMode', 'class', 'content', 'datatype', 'dur', 'end', 'fill', 'from', 'id', 'keySplines', 'keyTimes', 'max', 'min', 'property', 'rel', 'repeatCount', 'repeatDur', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'restart', 'rev', 'role', 'systemLanguage', 'to', 'typeof', 'values', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=empty_list, children=['desc', 'handler', 'metadata', 'switch', 'title']), 'animateColor': SVGElement('animateColor', attributes=['about', 'accumulate', 'additive', 'attributeName', 'attributeType', 'begin', 'by', 'calcMode', 'class', 'content', 'datatype', 'dur', 'end', 'fill', 'from', 'id', 'keySplines', 'keyTimes', 'max', 'min', 'property', 'rel', 'repeatCount', 'repeatDur', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'restart', 'rev', 'role', 'systemLanguage', 'to', 'typeof', 'values', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=empty_list, children=['desc', 'handler', 'metadata', 'switch', 'title']), 'animateMotion': SVGElement('animateMotion', attributes=['about', 'accumulate', 'additive', 'begin', 'by', 'calcMode', 'class', 'content', 'datatype', 'dur', 'end', 'fill', 'from', 'id', 'keyPoints', 'keySplines', 'keyTimes', 'max', 'min', 'origin', 'path', 'property', 'rel', 'repeatCount', 'repeatDur', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'restart', 'rev', 'role', 'rotate', 'systemLanguage', 'to', 'typeof', 'values', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=empty_list, children=['desc', 'handler', 'metadata', 'mpath', 'switch', 'title']), 'animateTransform': SVGElement('animateTransform', attributes=['about', 'accumulate', 'additive', 'attributeName', 'attributeType', 'begin', 'by', 'calcMode', 'class', 'content', 'datatype', 'dur', 'end', 'fill', 'from', 'id', 'keySplines', 'keyTimes', 'max', 'min', 'property', 'rel', 'repeatCount', 'repeatDur', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'restart', 'rev', 'role', 'systemLanguage', 'to', 'type', 'typeof', 'values', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=empty_list, children=['desc', 'handler', 'metadata', 'switch', 'title']), 'animation': SVGElement('animation', attributes=['about', 'begin', 'class', 'content', 'datatype', 'dur', 'end', 'externalResourcesRequired', 'fill', 'focusHighlight', 'focusable', 'height', 'id', 'initialVisibility', 'max', 'min', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'preserveAspectRatio', 'property', 'rel', 'repeatCount', 'repeatDur', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'restart', 'rev', 'role', 'syncBehavior', 'syncMaster', 'syncTolerance', 'systemLanguage', 'transform', 'typeof', 'width', 'x', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space', 'y'], properties=media_group_names, children=['animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'handler', 'metadata', 'set', 'switch', 'title']), 'audio': SVGElement('audio', attributes=['about', 'begin', 'class', 'content', 'datatype', 'dur', 'end', 'externalResourcesRequired', 'fill', 'id', 'max', 'min', 'property', 'rel', 'repeatCount', 'repeatDur', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'restart', 'rev', 'role', 'syncBehavior', 'syncMaster', 'syncTolerance', 'systemLanguage', 'type', 'typeof', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=media_group_names, children=['animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'handler', 'metadata', 'set', 'switch', 'title']), 'circle': SVGElement('circle', attributes=['about', 'class', 'content', 'cx', 'cy', 'datatype', 'focusHighlight', 'focusable', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'property', 'r', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'transform', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=property_names, children=['animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'handler', 'metadata', 'set', 'switch', 'title']), 'defs': SVGElement('defs', attributes=['about', 'class', 'content', 'datatype', 'id', 'property', 'rel', 'resource', 'rev', 'role', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=property_names, children=['a', 'animate', 'animateColor', 'animateMotion', 'animateTransform', 'animation', 'audio', 'circle', 'defs', 'desc', 'discard', 'ellipse', 'font', 'font-face', 'foreignObject', 'g', 'handler', 'image', 'line', 'linearGradient', 'listener', 'metadata', 'path', 'polygon', 'polyline', 'prefetch', 'radialGradient', 'rect', 'script', 'set', 'solidColor', 'switch', 'text', 'textArea', 'title', 'use', 'video']), 'desc': SVGElement('desc', attributes=['about', 'class', 'content', 'datatype', 'id', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=media_group_names, children=empty_list), 'discard': SVGElement('discard', attributes=['about', 'begin', 'class', 'content', 'datatype', 'id', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'typeof', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=empty_list, children=['desc', 'handler', 'metadata', 'switch', 'title']), 'ellipse': SVGElement('ellipse', attributes=['about', 'class', 'content', 'cx', 'cy', 'datatype', 'focusHighlight', 'focusable', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'rx', 'ry', 'systemLanguage', 'transform', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=property_names, children=['animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'handler', 'metadata', 'set', 'switch', 'title']), 'font': SVGElement('font', attributes=['about', 'class', 'content', 'datatype', 'externalResourcesRequired', 'horiz-adv-x', 'horiz-origin-x', 'id', 'property', 'rel', 'resource', 'rev', 'role', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=empty_list, children=['desc', 'font-face', 'glyph', 'hkern', 'metadata', 'missing-glyph', 'switch', 'title']), 'font-face': SVGElement('font-face', attributes=['about', 'accent-height', 'alphabetic', 'ascent', 'bbox', 'cap-height', 'class', 'content', 'datatype', 'descent', 'externalResourcesRequired', 'font-family', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'hanging', 'id', 'ideographic', 'mathematical', 'overline-position', 'overline-thickness', 'panose-1', 'property', 'rel', 'resource', 'rev', 'role', 'slope', 'stemh', 'stemv', 'strikethrough-position', 'strikethrough-thickness', 'typeof', 'underline-position', 'underline-thickness', 'unicode-range', 'units-per-em', 'widths', 'x-height', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=empty_list, children=['desc', 'font-face-src', 'metadata', 'switch', 'title']), 'font-face-src': SVGElement('font-face-src', attributes=['about', 'class', 'content', 'datatype', 'id', 'property', 'rel', 'resource', 'rev', 'role', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=empty_list, children=['desc', 'font-face-uri', 'metadata', 'switch', 'title']), 'font-face-uri': SVGElement('font-face-uri', attributes=['about', 'class', 'content', 'datatype', 'externalResourcesRequired', 'id', 'property', 'rel', 'resource', 'rev', 'role', 'typeof', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=empty_list, children=['desc', 'metadata', 'switch', 'title']), 'foreignObject': SVGElement('foreignObject', attributes=['about', 'class', 'content', 'datatype', 'externalResourcesRequired', 'focusHighlight', 'focusable', 'height', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'transform', 'typeof', 'width', 'x', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space', 'y'], properties=property_names, children=['desc', 'metadata', 'svg', 'switch', 'title']), 'g': SVGElement('g', attributes=['about', 'class', 'content', 'datatype', 'externalResourcesRequired', 'focusHighlight', 'focusable', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'transform', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=property_names, children=['a', 'animate', 'animateColor', 'animateMotion', 'animateTransform', 'animation', 'audio', 'circle', 'defs', 'desc', 'discard', 'ellipse', 'font', 'font-face', 'foreignObject', 'g', 'handler', 'image', 'line', 'linearGradient', 'listener', 'metadata', 'path', 'polygon', 'polyline', 'prefetch', 'radialGradient', 'rect', 'script', 'set', 'solidColor', 'switch', 'text', 'textArea', 'title', 'use', 'video']), 'glyph': SVGElement('glyph', attributes=['about', 'arabic-form', 'class', 'content', 'd', 'datatype', 'glyph-name', 'horiz-adv-x', 'id', 'lang', 'property', 'rel', 'resource', 'rev', 'role', 'typeof', 'unicode', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=empty_list, children=['desc', 'metadata', 'switch', 'title']), 'handler': SVGElement('handler', attributes=['about', 'class', 'content', 'datatype', 'ev:event', 'externalResourcesRequired', 'id', 'property', 'rel', 'resource', 'rev', 'role', 'type', 'typeof', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=empty_list, children=['desc', 'metadata', 'switch', 'title']), 'hkern': SVGElement('hkern', attributes=['about', 'class', 'content', 'datatype', 'g1', 'g2', 'id', 'k', 'property', 'rel', 'resource', 'rev', 'role', 'typeof', 'u1', 'u2', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=empty_list, children=['desc', 'metadata', 'switch', 'title']), 'image': SVGElement('image', attributes=['about', 'class', 'content', 'datatype', 'externalResourcesRequired', 'focusHighlight', 'focusable', 'height', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'opacity', 'preserveAspectRatio', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'transform', 'type', 'typeof', 'width', 'x', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space', 'y'], properties=media_group_names, children=['animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'handler', 'metadata', 'set', 'switch', 'title']), 'line': SVGElement('line', attributes=['about', 'class', 'content', 'datatype', 'focusHighlight', 'focusable', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'transform', 'typeof', 'x1', 'x2', 'xml:base', 'xml:id', 'xml:lang', 'xml:space', 'y1', 'y2'], properties=property_names, children=['animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'handler', 'metadata', 'set', 'switch', 'title']), 'linearGradient': SVGElement('linearGradient', attributes=['about', 'class', 'content', 'datatype', 'gradientUnits', 'id', 'property', 'rel', 'resource', 'rev', 'role', 'typeof', 'x1', 'x2', 'xml:base', 'xml:id', 'xml:lang', 'xml:space', 'y1', 'y2'], properties=property_names, children=['animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'metadata', 'set', 'stop', 'switch', 'title']), 'listener': SVGElement('listener', attributes=['about', 'class', 'content', 'datatype', 'defaultAction', 'event', 'handler', 'id', 'observer', 'phase', 'propagate', 'property', 'rel', 'resource', 'rev', 'role', 'target', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=empty_list, children=empty_list), 'metadata': SVGElement('metadata', attributes=['about', 'class', 'content', 'datatype', 'id', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=media_group_names, children=empty_list), 'missing-glyph': SVGElement('missing-glyph', attributes=['about', 'class', 'content', 'd', 'datatype', 'horiz-adv-x', 'id', 'property', 'rel', 'resource', 'rev', 'role', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=empty_list, children=['desc', 'metadata', 'switch', 'title']), 'mpath': SVGElement('mpath', attributes=['about', 'class', 'content', 'datatype', 'id', 'property', 'rel', 'resource', 'rev', 'role', 'typeof', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=empty_list, children=['desc', 'metadata', 'switch', 'title']), 'path': SVGElement('path', attributes=['about', 'class', 'content', 'd', 'datatype', 'focusHighlight', 'focusable', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'pathLength', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'transform', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=property_names, children=['animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'handler', 'metadata', 'set', 'switch', 'title']), 'polygon': SVGElement('polygon', attributes=['about', 'class', 'content', 'datatype', 'focusHighlight', 'focusable', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'points', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'transform', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=property_names, children=['animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'handler', 'metadata', 'set', 'switch', 'title']), 'polyline': SVGElement('polyline', attributes=['about', 'class', 'content', 'datatype', 'focusHighlight', 'focusable', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'points', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'transform', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=property_names, children=['animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'handler', 'metadata', 'set', 'switch', 'title']), 'prefetch': SVGElement('prefetch', attributes=['about', 'bandwidth', 'class', 'content', 'datatype', 'id', 'mediaCharacterEncoding', 'mediaContentEncodings', 'mediaSize', 'mediaTime', 'property', 'rel', 'resource', 'rev', 'role', 'typeof', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=empty_list, children=['desc', 'metadata', 'switch', 'title']), 'radialGradient': SVGElement('radialGradient', attributes=['about', 'class', 'content', 'cx', 'cy', 'datatype', 'gradientUnits', 'id', 'property', 'r', 'rel', 'resource', 'rev', 'role', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=property_names, children=['animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'metadata', 'set', 'stop', 'switch', 'title']), 'rect': SVGElement('rect', attributes=['about', 'class', 'content', 'datatype', 'focusHighlight', 'focusable', 'height', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'rx', 'ry', 'systemLanguage', 'transform', 'typeof', 'width', 'x', 'xml:base', 'xml:id', 'xml:lang', 'xml:space', 'y'], properties=property_names, children=['animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'handler', 'metadata', 'set', 'switch', 'title']), 'script': SVGElement('script', attributes=['about', 'class', 'content', 'datatype', 'externalResourcesRequired', 'id', 'property', 'rel', 'resource', 'rev', 'role', 'type', 'typeof', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=empty_list, children=['desc', 'metadata', 'switch', 'title']), 'set': SVGElement('set', attributes=['about', 'attributeName', 'attributeType', 'begin', 'class', 'content', 'datatype', 'dur', 'end', 'fill', 'id', 'max', 'min', 'property', 'rel', 'repeatCount', 'repeatDur', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'restart', 'rev', 'role', 'systemLanguage', 'to', 'typeof', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=empty_list, children=['desc', 'handler', 'metadata', 'switch', 'title']), 'solidColor': SVGElement('solidColor', attributes=['about', 'class', 'content', 'datatype', 'id', 'property', 'rel', 'resource', 'rev', 'role', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=property_names, children=['animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'handler', 'metadata', 'set', 'switch', 'title']), 'stop': SVGElement('stop', attributes=['about', 'class', 'content', 'datatype', 'id', 'offset', 'property', 'rel', 'resource', 'rev', 'role', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=property_names, children=['animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'metadata', 'set', 'switch', 'title']), 'svg': SVGElement('svg', attributes=['about', 'baseProfile', 'class', 'content', 'contentScriptType', 'datatype', 'externalResourcesRequired', 'focusHighlight', 'focusable', 'height', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'playbackOrder', 'preserveAspectRatio', 'property', 'rel', 'resource', 'rev', 'role', 'snapshotTime', 'syncBehaviorDefault', 'syncToleranceDefault', 'timelineBegin', 'typeof', 'version', 'viewBox', 'width', 'xml:base', 'xml:id', 'xml:lang', 'xml:space', 'xmlns', 'xmlns:xlink', 'xmlns:ev', 'zoomAndPan'], properties=property_names, children=['a', 'animate', 'animateColor', 'animateMotion', 'animateTransform', 'animation', 'audio', 'circle', 'defs', 'desc', 'discard', 'ellipse', 'font', 'font-face', 'foreignObject', 'g', 'handler', 'image', 'line', 'linearGradient', 'listener', 'metadata', 'path', 'polygon', 'polyline', 'prefetch', 'radialGradient', 'rect', 'script', 'set', 'solidColor', 'switch', 'text', 'textArea', 'title', 'use', 'video']), 'switch': SVGElement('switch', attributes=['about', 'class', 'content', 'datatype', 'externalResourcesRequired', 'focusHighlight', 'focusable', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'transform', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=property_names, children=['likeparent', 'set', 'textArea', 'text', 'image', 'missing-glyph', 'font-face', 'video', 'path', 'animate', 'font', 'ellipse', 'glyph', 'use', 'font-face-src', 'polygon', 'script', 'handler', 'circle', 'radialGradient', 'prefetch', 'defs', 'mpath', 'stop', 'animateMotion', 'animateColor', 'discard', 'solidColor', 'hkern', 'line', 'animation', 'rect', 'g', 'svg', 'animateTransform', 'linearGradient', 'font-face-uri', 'foreignObject', 'polyline', 'audio']), 'tbreak': SVGElement('tbreak', attributes=['about', 'class', 'content', 'datatype', 'id', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=empty_list, children=empty_list), 'text': SVGElement('text', attributes=['about', 'class', 'content', 'datatype', 'editable', 'focusHighlight', 'focusable', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'rotate', 'systemLanguage', 'transform', 'typeof', 'x', 'xml:base', 'xml:id', 'xml:lang', 'xml:space', 'y'], properties=property_names, children=['a', 'animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'handler', 'metadata', 'set', 'switch', 'title', 'tspan']), 'textArea': SVGElement('textArea', attributes=['about', 'class', 'content', 'datatype', 'editable', 'focusHighlight', 'focusable', 'height', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'transform', 'typeof', 'width', 'x', 'xml:base', 'xml:id', 'xml:lang', 'xml:space', 'y'], properties=property_names, children=['a', 'animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'handler', 'metadata', 'set', 'switch', 'tbreak', 'title', 'tspan']), 'title': SVGElement('title', attributes=['about', 'class', 'content', 'datatype', 'id', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=media_group_names, children=empty_list), 'tspan': SVGElement('tspan', attributes=['about', 'class', 'content', 'datatype', 'focusHighlight', 'focusable', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'], properties=property_names, children=['likeparent', 'text', 'textArea']), 'use': SVGElement('use', attributes=['about', 'class', 'content', 'datatype', 'externalResourcesRequired', 'focusHighlight', 'focusable', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'transform', 'typeof', 'x', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space', 'y'], properties=property_names, children=['animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'handler', 'metadata', 'set', 'switch', 'title']), 'video': SVGElement('video', attributes=['about', 'begin', 'class', 'content', 'datatype', 'dur', 'end', 'externalResourcesRequired', 'fill', 'focusHighlight', 'focusable', 'height', 'id', 'initialVisibility', 'max', 'min', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'overlay', 'preserveAspectRatio', 'property', 'rel', 'repeatCount', 'repeatDur', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'restart', 'rev', 'role', 'syncBehavior', 'syncMaster', 'syncTolerance', 'systemLanguage', 'transform', 'transformBehavior', 'type', 'typeof', 'width', 'x', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space', 'y'], properties=media_group_names, children=['animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'handler', 'metadata', 'set', 'switch', 'title']), } svgwrite-1.1.8/svgwrite/data/typechecker.py0000666000000000000000000002666312720244411017202 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: typechecker # Created: 15.10.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import re from svgwrite.data import pattern from svgwrite.data.colors import colornames from svgwrite.data.svgparser import is_valid_transferlist, is_valid_pathdata, is_valid_animation_timing from svgwrite.utils import is_string, to_unicode def iterflatlist(values): """ Flatten nested *values*, returns an *iterator*. """ for element in values: if hasattr(element, "__iter__") and not is_string(element): for item in iterflatlist(element): yield item else: yield element INVALID_NAME_CHARS = frozenset([' ', '\t', '\r', '\n', ',', '(', ')']) WHITESPACE = frozenset([' ', '\t', '\r', '\n']) SHAPE_PATTERN = re.compile(r"^rect\((.*),(.*),(.*),(.*)\)$") FUNCIRI_PATTERN = re.compile(r"^url\((.*)\)$") ICCCOLOR_PATTERN = re.compile(r"^icc-color\((.*)\)$") COLOR_HEXDIGIT_PATTERN = re.compile(r"^#[a-fA-F0-9]{3}([a-fA-F0-9]{3})?$") COLOR_RGB_INTEGER_PATTERN = re.compile(r"^rgb\( *\d+ *, *\d+ *, *\d+ *\)$") COLOR_RGB_PERCENTAGE_PATTERN = re.compile(r"^rgb\( *\d+(\.\d*)?% *, *\d+(\.\d*)?% *, *\d+(\.\d*)?% *\)$") NMTOKEN_PATTERN = re.compile(r"^[a-zA-Z_:][\w\-\.:]*$") class Full11TypeChecker(object): def get_version(self): return '1.1', 'full' def is_angle(self, value): #angle ::= number (~"deg" | ~"grad" | ~"rad")? if self.is_number(value): return True elif is_string(value): return pattern.angle.match(value.strip()) is not None return False def is_anything(self, value): #anything ::= Char* return bool(str(value).strip()) is_string = is_anything is_content_type = is_anything def is_color(self, value): #color ::= "#" hexdigit hexdigit hexdigit (hexdigit hexdigit hexdigit)? # | "rgb(" wsp* integer comma integer comma integer wsp* ")" # | "rgb(" wsp* number "%" comma number "%" comma number "%" wsp* ")" # | color-keyword #hexdigit ::= [0-9A-Fa-f] #comma ::= wsp* "," wsp* value = str(value).strip() if value.startswith('#'): if COLOR_HEXDIGIT_PATTERN.match(value): return True else: return False elif value.startswith('rgb('): if COLOR_RGB_INTEGER_PATTERN.match(value): return True elif COLOR_RGB_PERCENTAGE_PATTERN.match(value): return True return False return self.is_color_keyword(value) def is_color_keyword(self, value): return value.strip() in colornames def is_frequency(self, value): #frequency ::= number (~"Hz" | ~"kHz") if self.is_number(value): return True elif is_string(value): return pattern.frequency.match(value.strip()) is not None return False def is_FuncIRI(self, value): #FuncIRI ::= "url(" ")" res = FUNCIRI_PATTERN.match(str(value).strip()) if res: return self.is_IRI(res.group(1)) return False def is_icccolor(self, value): #icccolor ::= "icc-color(" name (comma-wsp number)+ ")" res = ICCCOLOR_PATTERN.match(str(value).strip()) if res: return self.is_list_of_T(res.group(1), 'name') return False def is_integer(self, value): if isinstance(value, float): return False try: number = int(value) return True except: return False def is_IRI(self, value): # Internationalized Resource Identifiers # a more generalized complement to Uniform Resource Identifiers (URIs) # nearly everything can be a valid # only a none-empty string ist a valid input if is_string(value): return bool(value.strip()) else: return False def is_length(self, value): #length ::= number ("em" | "ex" | "px" | "in" | "cm" | "mm" | "pt" | "pc" | "%")? if value is None: return False if isinstance(value, (int, float)): return self.is_number(value) elif is_string(value): result = pattern.length.match(value.strip()) if result: number, tmp, unit = result.groups() return self.is_number(number) # for tiny check! return False is_coordinate = is_length def is_list_of_T(self, value, t='string'): def split(value): #TODO: improve split function!!!! if isinstance(value, (int, float)): return (value, ) if is_string(value): return iterflatlist(v.split(',') for v in value.split(' ')) return value #list-of-Ts ::= T # | T comma-wsp list-of-Ts #comma-wsp ::= (wsp+ ","? wsp*) | ("," wsp*) #wsp ::= (#x20 | #x9 | #xD | #xA) checker = self.get_func_by_name(t) for v in split(value): if not checker(v): return False return True def is_four_numbers(self, value): def split(value): if is_string(value): values = iterflatlist( (v.strip().split(' ') for v in value.split(',')) ) return (v for v in values if v) else: return iterflatlist(value) values = list(split(value)) if len(values) != 4: return False checker = self.get_func_by_name('number') for v in values: if not checker(v): return False return True def is_semicolon_list(self, value): #a semicolon-separated list of values # | value comma-wsp list-of-values #comma-wsp ::= (wsp+ ";" wsp*) | ("," wsp*) #wsp ::= (#x20 | #x9 | #xD | #xA) return self.is_list_of_T(value.replace(';', ' '), 'number') def is_name(self, value): #name ::= [^,()#x20#x9#xD#xA] /* any char except ",", "(", ")" or wsp */ chars = frozenset(str(value).strip()) if not chars or INVALID_NAME_CHARS.intersection(chars): return False else: return True def is_number(self, value): try: number = float(value) return True except: return False def is_number_optional_number(self, value): #number-optional-number ::= number # | number comma-wsp number if is_string(value): values = re.split(' *,? *', value.strip()) if 0 < len(values) < 3: # 1 or 2 numbers for v in values: if not self.is_number(v): return False return True else: try: # is it a 2-tuple n1, n2 = value if self.is_number(n1) and \ self.is_number(n2): return True except TypeError: # just one value return self.is_number(value) except ValueError: # more than 2 values pass return False def is_paint(self, value): #paint ::= "none" | # "currentColor" | # [] | # [ "none" | "currentColor" | [] | # "inherit" def split_values(value): try: funcIRI, value = value.split(")", 1) values = [funcIRI+")"] values.extend(split_values(value)) return values except ValueError: return value.split() values = split_values(str(value).strip()) for value in [v.strip() for v in values]: if value in ('none', 'currentColor', 'inherit'): continue elif self.is_color(value): continue elif self.is_icccolor(value): continue elif self.is_FuncIRI(value): continue return False return True def is_percentage(self, value): #percentage ::= number "%" if self.is_number(value): return True elif is_string(value): return pattern.percentage.match(value.strip()) is not None return False def is_time(self, value): #time ::= (~"ms" | ~"s")? if self.is_number(value): return True elif is_string(value): return pattern.time.match(value.strip()) is not None return False def is_transform_list(self, value): if is_string(value): return is_valid_transferlist(value) else: return False def is_path_data(self, value): if is_string(value): return is_valid_pathdata(value) else: return False def is_XML_Name(self, value): # http://www.w3.org/TR/2006/REC-xml-20060816/#NT-Name # Nmtoken return bool(NMTOKEN_PATTERN.match(str(value).strip())) def is_shape(self, value): #shape ::= ( ) # where , , and specify offsets from the # respective sides of the box. # , , , and are values # i.e. 'rect(5px, 10px, 10px, 5px)' res = SHAPE_PATTERN.match(value.strip()) if res: for arg in res.groups(): if arg.strip() == 'auto': continue if not self.is_length(arg): return False else: return False return True def is_timing_value_list(self, value): if is_string(value): return is_valid_animation_timing(value) else: return False def get_func_by_name(self, funcname): return getattr(self, 'is_'+funcname.replace('-', '_'), self.is_anything) def check(self, typename, value): if typename.startswith('list-of-'): t = typename[8:] return self.is_list_of_T(value, t) return self.get_func_by_name(typename)(value) FOCUS_CONST = frozenset(['nav-next', 'nav-prev', 'nav-up', 'nav-down', 'nav-left', 'nav-right', 'nav-up-left', 'nav-up-right', 'nav-down-left', 'nav-down-right']) class Tiny12TypeChecker(Full11TypeChecker): def get_version(self): return '1.2', 'tiny' def is_boolean(self, value): if isinstance(value, bool): return True if is_string(value): return value.strip().lower() in ('true', 'false') return False def is_number(self, value): try: number = float(value) if -32767.9999 <= number <= 32767.9999: return True else: return False except: return False def is_focus(self, value): return str(value).strip() in FOCUS_CONST svgwrite-1.1.8/svgwrite/data/types.py0000666000000000000000000000536312114021457016032 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: svg types # Created: 30.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License class SVGAttribute(object): def __init__(self, name, anim, types, const): self.name = name self._anim = anim self._types = types self._const = const # 'elementname' is ignored, but necessary because of the signatures of # the SVGMultiAttribute class methods get_...() def get_anim(self, elementname='*'): return self._anim def get_types(self, elementname='*'): return self._types def get_const(self, elementname='*'): return self._const class SVGMultiAttribute(object): # example: SVGMultiAttribute({'*':SVGAttribute(...), 'text tref':SVGAttribute(...)} ) # parametr is a dict-like object # '*' is the default attribute definition # 'text' and 'tref' share the same attribute definition def __init__(self, attributes): self.name = None self._attributes = {} for names, attribute in attributes.items(): for name in names.split(): name = name.strip() self._attributes[name] = attribute if not self.name: self.name = attribute.name elif self.name != attribute.name: raise ValueError("Different attribute-names for SVGMultiAttribute "\ "(%s != %s)." % (self.name, attribute.name)) if '*' not in self._attributes and len(self._attributes): # if no default attribute definition were given # set the first attribute definition as the default attribute definition firstkey = sorted(self._attributes.keys())[0] self._attributes['*'] = self._attributes[firstkey] def get_attribute(self, elementname): if elementname in self._attributes: return self._attributes[elementname] else: return self._attributes['*'] def get_anim(self, elementname='*'): attribute = self.get_attribute(elementname) return attribute.get_anim() def get_types(self, elementname='*'): attribute = self.get_attribute(elementname) return attribute.get_types() def get_const(self, elementname='*'): attribute = self.get_attribute(elementname) return attribute.get_const() class SVGElement(object): def __init__(self, name, attributes, properties, children): self.name = name s = set(attributes) s.update(properties) self.valid_attributes = frozenset(s) self.valid_children = frozenset(children) svgwrite-1.1.8/svgwrite/data/__init__.py0000666000000000000000000000000011452031523016403 0ustar 00000000000000svgwrite-1.1.8/svgwrite/drawing.py0000666000000000000000000001041712233634043015407 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman # Purpose: drawing # Created: 10.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License """ The *Drawing* object is the overall container for all SVG elements. It provides the methods to store the drawing into a file or a file-like object. If you want to use stylesheets, the reference links to this stylesheets were also stored (`add_stylesheet`) in the *Drawing* object. set/get SVG attributes:: element['attribute'] = value value = element['attribute'] The Drawing object also includes a defs section, add elements to the defs section by:: drawing.defs.add(element) """ from __future__ import unicode_literals import io from svgwrite.container import SVG, Defs from svgwrite.elementfactory import ElementFactory class Drawing(SVG, ElementFactory): """ This is the SVG drawing represented by the top level *svg* element. A drawing consists of any number of SVG elements contained within the drawing element, stored in the *elements* attribute. A drawing can range from an empty drawing (i.e., no content inside of the drawing), to a very simple drawing containing a single SVG element such as a *rect*, to a complex, deeply nested collection of container elements and graphics elements. """ def __init__(self, filename="noname.svg", size=('100%', '100%'), **extra): """ :param string filename: filesystem filename valid for :func:`open` :param 2-tuple size: width, height :param keywords extra: additional svg-attributes for the *SVG* object Important (and not SVG Attributes) **extra** parameters: :param string profile: ``'tiny | full'`` - define the SVG baseProfile :param bool debug: switch validation on/off """ super(Drawing, self).__init__(size=size, **extra) self.filename = filename self._stylesheets = [] # list of stylesheets appended def get_xml(self): """ Get the XML representation as `ElementTree` object. :return: XML `ElementTree` of this object and all its subelements """ profile = self.profile version = self.version self.attribs['xmlns'] = "http://www.w3.org/2000/svg" self.attribs['xmlns:xlink'] = "http://www.w3.org/1999/xlink" self.attribs['xmlns:ev'] = "http://www.w3.org/2001/xml-events" self.attribs['baseProfile'] = profile self.attribs['version'] = version return super(Drawing, self).get_xml() def add_stylesheet(self, href, title, alternate="no", media="screen"): """ Add a stylesheet reference. :param string href: link to stylesheet :param string title: name of stylesheet :param string alternate: ``'yes'|'no'`` :param string media: ``'all | aureal | braille | embossed | handheld | print | projection | screen | tty | tv'`` """ self._stylesheets.append( (href, title, alternate, media) ) def write(self, fileobj): """ Write XML string to **fileobj**. :param fileobj: a *file-like* object Python 3.x - set encoding at the open command:: open('filename', 'w', encoding='utf-8') """ # write xml header fileobj.write('\n') # don't use DOCTYPE. It's useless. see also: # http://tech.groups.yahoo.com/group/svg-developers/message/48562 # write stylesheets stylesheet_template = '\n' # removed map(), does not work with Python 3 for stylesheet in self._stylesheets: fileobj.write(stylesheet_template % stylesheet) fileobj.write(self.tostring()) def save(self): """ Write the XML string to **filename**. """ fileobj = io.open(self.filename, mode='w', encoding='utf-8') self.write(fileobj) fileobj.close() def saveas(self, filename): """ Write the XML string to **filename**. :param string filename: filesystem filename valid for :func:`open` """ self.filename = filename self.save() svgwrite-1.1.8/svgwrite/elementfactory.py0000666000000000000000000000425612233364212016777 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: element factory # Created: 15.10.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License from svgwrite import container from svgwrite import shapes from svgwrite import path from svgwrite import image from svgwrite import text from svgwrite import gradients from svgwrite import pattern from svgwrite import masking from svgwrite import animate from svgwrite import filters factoryelements = { 'g': container.Group, 'svg': container.SVG, 'defs': container.Defs, 'symbol': container.Symbol, 'marker': container.Marker, 'use': container.Use, 'a': container.Hyperlink, 'script': container.Script, 'style': container.Style, 'line': shapes.Line, 'rect': shapes.Rect, 'circle': shapes.Circle, 'ellipse': shapes.Ellipse, 'polyline': shapes.Polyline, 'polygon': shapes.Polygon, 'path': path.Path, 'image': image.Image, 'text': text.Text, 'tspan': text.TSpan, 'tref': text.TRef, 'textPath': text.TextPath, 'textArea': text.TextArea, 'linearGradient': gradients.LinearGradient, 'radialGradient': gradients.RadialGradient, 'pattern': pattern.Pattern, 'clipPath': masking.ClipPath, 'mask': masking.Mask, 'animate': animate.Animate, 'set': animate.Set, 'animateColor': animate.AnimateColor, 'animateMotion': animate.AnimateMotion, 'animateTransform': animate.AnimateTransform, 'filter': filters.Filter, } class ElementBuilder(object): def __init__(self, cls, factory): self.cls = cls self.factory = factory def __call__(self, *args, **kwargs): # inject creator object - inherit _parameter from factory kwargs['factory'] = self.factory # create an object of type 'cls' return self.cls(*args, **kwargs) class ElementFactory(object): def __getattr__(self, name): if name in factoryelements: return ElementBuilder(factoryelements[name], self) else: raise AttributeError("'%s' has no attribute '%s'" % (self.__class__.__name__, name)) svgwrite-1.1.8/svgwrite/etree.py0000666000000000000000000000252112314612177015061 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman # Purpose: a hack to generate XML containing CDATA by ElementTree # Created: 26.05.2012 # Copyright (C) 2012, Manfred Moitzi # License: MIT License # usage: # # from svgwrite.etree import etree, CDATA # # element = etree.Element('myTag') # element.append(CDATA("< and >")) # # assert etree.tostring(element) == "]]>" import sys PY3 = sys.version_info[0] > 2 import xml.etree.ElementTree as etree CDATA_TPL = "" CDATA_TAG = CDATA_TPL def CDATA(text): element = etree.Element(CDATA_TAG) element.text = text return element original_serialize_xml = etree._serialize_xml if PY3: def _serialize_xml_with_CDATA_support(write, elem, qnames, namespaces, **kwargs): if elem.tag == CDATA_TAG: write(CDATA_TPL % elem.text) else: original_serialize_xml(write, elem, qnames, namespaces, **kwargs) else: def _serialize_xml_with_CDATA_support(write, elem, encoding, qnames, namespaces): if elem.tag == CDATA_TAG: write(CDATA_TPL % elem.text.encode(encoding)) else: original_serialize_xml(write, elem, encoding, qnames, namespaces) # ugly, ugly, ugly patching etree._serialize_xml = _serialize_xml_with_CDATA_support svgwrite-1.1.8/svgwrite/filters.py0000666000000000000000000001750212321664113015425 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: filters module # Created: 03.11.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License from svgwrite.base import BaseElement from svgwrite.mixins import XLink, Presentation from svgwrite.utils import strlist, is_string __all__ = ['Filter'] class _feDistantLight(BaseElement): elementname = 'feDistantLight' def __init__(self, azimuth=0, elevation=0, **extra): super(_feDistantLight, self).__init__(**extra) if azimuth != 0: self['azimuth'] = azimuth if elevation != 0: self['elevation'] = elevation class _fePointLight(BaseElement): elementname = 'fePointLight' def __init__(self, source=(0, 0, 0), **extra): super(_fePointLight, self).__init__(**extra) x, y, z = source if x != 0: self['x'] = x if y != 0: self['y'] = y if z != 0: self['z'] = z class _feSpotLight(_fePointLight): elementname = 'feSpotLight' def __init__(self, source=(0, 0, 0), target=(0, 0, 0), **extra): super(_feSpotLight, self).__init__(source, **extra) x, y, z = target if x != 0: self['pointsAtX'] = x if y != 0: self['pointsAtY'] = y if z != 0: self['pointsAtZ'] = z class _FilterPrimitive(BaseElement, Presentation): pass class _FilterNoInput(_FilterPrimitive): def __init__(self, start=None, size=None, **extra): super(_FilterNoInput, self).__init__(**extra) if start is not None: self['x'] = start[0] self['y'] = start[1] if size is not None: self['width'] = size[0] self['height'] = size[1] class _FilterRequireInput(_FilterNoInput): def __init__(self, in_='SourceGraphic', **extra): super(_FilterRequireInput, self).__init__(**extra) self['in'] = in_ class _feBlend(_FilterRequireInput): elementname = 'feBlend' class _feColorMatrix(_FilterRequireInput): elementname = 'feColorMatrix' class _feComponentTransfer(_FilterRequireInput): elementname = 'feComponentTransfer' def feFuncR(self, type_, **extra): return self.add(_feFuncR(type_, factory=self, **extra)) def feFuncG(self, type_, **extra): return self.add(_feFuncG(type_, factory=self, **extra)) def feFuncB(self, type_, **extra): return self.add(_feFuncB(type_, factory=self, **extra)) def feFuncA(self, type_, **extra): return self.add(_feFuncA(type_, factory=self, **extra)) class _feFuncR(_FilterPrimitive): elementname = 'feFuncR' def __init__(self, type_, **extra): super(_feFuncR, self).__init__(**extra) self['type'] = type_ class _feFuncG(_feFuncR): elementname = 'feFuncG' class _feFuncB(_feFuncR): elementname = 'feFuncB' class _feFuncA(_feFuncR): elementname = 'feFuncA' class _feComposite(_FilterRequireInput): elementname = 'feComposite' class _feConvolveMatrix(_FilterRequireInput): elementname = 'feConvolveMatrix' class _feDiffuseLighting(_FilterRequireInput): elementname = 'feDiffuseLighting' def feDistantLight(self, azimuth=0, elevation=0, **extra): return self.add(_feDistantLight(azimuth, elevation, **extra)) def fePointLight(self, source=(0, 0, 0), **extra): return self.add(_fePointLight(source, **extra)) def feSpotLight(self, source=(0, 0, 0), target=(0, 0, 0), **extra): return self.add(_feSpotLight(source, target, **extra)) class _feDisplacementMap(_FilterRequireInput): elementname = 'feDisplacementMap' class _feFlood(_FilterNoInput): elementname = 'feFlood' class _feGaussianBlur(_FilterRequireInput): elementname = 'feGaussianBlur' class _feImage(_FilterNoInput, XLink): elementname = 'feImage' def __init__(self, href, start=None, size=None, **extra): super(_feImage, self).__init__(start, size, **extra) self.set_href(href) class _feMergeNode(_FilterPrimitive): elementname = 'feMergeNode' class _feMerge(_FilterNoInput): elementname = 'feMerge' def __init__(self, layernames, **extra): super(_feMerge, self).__init__(**extra) self.feMergeNode(layernames) def feMergeNode(self, layernames): for layername in layernames: self.add(_feMergeNode(in_=layername, factory=self)) class _feMorphology(_FilterRequireInput): elementname = 'feMorphology' class _feOffset(_FilterRequireInput): elementname = 'feOffset' class _feSpecularLighting(_feDiffuseLighting): elementname = 'feSpecularLighting' class _feTile(_FilterRequireInput): elementname = 'feTile' class _feTurbulence(_FilterNoInput): elementname = 'feTurbulence' filter_factory = { 'feBlend': _feBlend, 'feColorMatrix': _feColorMatrix, 'feComponentTransfer': _feComponentTransfer, 'feComposite': _feComposite, 'feConvolveMatrix': _feConvolveMatrix, 'feDiffuseLighting': _feDiffuseLighting, 'feDisplacementMap': _feDisplacementMap, 'feFlood': _feFlood, 'feGaussianBlur': _feGaussianBlur, 'feImage': _feImage, 'feMerge': _feMerge, 'feMorphology': _feMorphology, 'feOffset': _feOffset, 'feSpecularLighting': _feSpecularLighting, 'feTile': _feTile, 'feTurbulence': _feTurbulence, } class _FilterBuilder(object): def __init__(self, cls, parent): self.cls = cls # primitive filter class to build self.parent = parent # the parent Filter() object def __call__(self, *args, **kwargs): kwargs['factory'] = self.parent # to get the _paramters object obj = self.cls(*args, **kwargs) # create an object of type 'cls' self.parent.add(obj) # add primitive filter to parent Filter() return obj class Filter(BaseElement, XLink, Presentation): """ The filter element is a container element for filter primitives, and also a **factory** for filter primitives. """ elementname = 'filter' def __init__(self, start=None, size=None, resolution=None, inherit=None, **extra): """ :param 2-tuple start: defines the start point of the filter effects region (**x**, **y**) :param 2-tuple size: defines the size of the filter effects region (**width**, **height**) :param resolution: takes the form ``'x-pixels [y-pixels]'``, and indicates the width and height of the intermediate images in pixels. :param inherit: inherits properties from Filter `inherit` see: **xlink:href** """ super(Filter, self).__init__(**extra) if start is not None: self['x'] = start[0] self['y'] = start[1] if size is not None: self['width'] = size[0] self['height'] = size[1] if resolution is not None: if is_string(resolution): self['filterRes'] = resolution elif hasattr(resolution, '__iter__'): self['filterRes'] = strlist(resolution, ' ') else: self['filterRes'] = str(resolution) if inherit is not None: self.href = inherit self.update_id() def get_xml(self): self.update_id() return super(Filter, self).get_xml() def __getattr__(self, name): # create primitive filters by Filter.(...) # and auto-add the new filter as subelement of Filter() if name in filter_factory: return _FilterBuilder(filter_factory[name], self) else: raise AttributeError("'%s' has no attribute '%s'" % (self.__class__.__name__, name)) svgwrite-1.1.8/svgwrite/gradients.py0000666000000000000000000001122612723216227015737 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: gradients module # Created: 26.10.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License """ Gradients consist of continuously smooth color transitions along a vector from one color to another, possibly followed by additional transitions along the same vector to other colors. SVG provides for two types of gradients: linear gradients and radial gradients. """ from svgwrite.base import BaseElement from svgwrite.mixins import Transform, XLink from svgwrite.utils import is_string class _GradientStop(BaseElement): elementname = 'stop' def __init__(self, offset=None, color=None, opacity=None, **extra): super(_GradientStop, self).__init__(**extra) if offset is not None: self['offset'] = offset if color is not None: self['stop-color'] = color if opacity is not None: self['stop-opacity'] = opacity class _AbstractGradient(BaseElement, Transform, XLink): transformname = 'gradientTransform' def __init__(self, inherit=None, **extra): super(_AbstractGradient, self).__init__(**extra) if inherit is not None: if is_string(inherit): self.set_href(inherit) else: self.set_href(inherit.get_iri()) def get_paint_server(self, default='none'): """ Returns the of the gradient. """ return "%s %s" % (self.get_funciri(), default) def add_stop_color(self, offset=None, color=None, opacity=None): """ Adds a stop-color to the gradient. :param offset: is either a (usually ranging from 0 to 1) or a `` (usually ranging from 0% to 100%) which indicates where the gradient stop is placed. Represents a location along the gradient vector. For radial gradients, it represents a percentage distance from (fx,fy) to the edge of the outermost/largest circle. :param color: indicates what color to use at that gradient stop :param opacity: defines the opacity of a given gradient stop """ self.add(_GradientStop(offset, color, opacity, factory=self)) return self def add_colors(self, colors, sweep=(0., 1.), opacity=None): """ Add stop-colors from colors with linear offset distributuion from sweep[0] to sweep[1]. i.e. colors=['white', 'red', 'blue'] 'white': offset = 0.0 'red': offset = 0.5 'blue': offset = 1.0 """ start = float(sweep[0]) end = float(sweep[1]) delta = (end-start) / float(len(colors) - 1) offset = start for color in colors: self.add_stop_color(round(offset, 3), color, opacity) offset += delta return self def get_xml(self): if hasattr(self, 'href'): self.update_id() return super(_AbstractGradient, self).get_xml() class LinearGradient(_AbstractGradient): """ Linear gradients are defined by a SVG element. """ elementname = 'linearGradient' def __init__(self, start=None, end=None, inherit=None, **extra): """ :param 2-tuple start: start point of the gradient (**x1**, **y1**) :param 2-tuple end: end point of the gradient (**x2**, **y2**) :param inherit: gradient inherits properties from `inherit` see: **xlink:href** """ super(LinearGradient, self).__init__(inherit=inherit, **extra) if start is not None: self['x1'] = start[0] self['y1'] = start[1] if end is not None: self['x2'] = end[0] self['y2'] = end[1] class RadialGradient(_AbstractGradient): """ Radial gradients are defined by a SVG element. """ elementname = 'radialGradient' def __init__(self, center=None, r=None, focal=None, inherit=None, **extra): """ :param 2-tuple center: center point for the gradient (**cx**, **cy**) :param r: radius for the gradient :param 2-tuple focal: focal point for the radial gradient (**fx**, **fy**) :param inherit: gradient inherits properties from `inherit` see: **xlink:href** """ super(RadialGradient, self).__init__(inherit=inherit, **extra) if center is not None: self['cx'] = center[0] self['cy'] = center[1] if r is not None: self['r'] = r if focal is not None: self['fx'] = focal[0] self['fy'] = focal[1] svgwrite-1.1.8/svgwrite/image.py0000666000000000000000000000467412723216227015052 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: svg image element # Created: 09.10.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License from svgwrite.base import BaseElement from svgwrite.mixins import Transform, _vert, _horiz, Clipping class Image(BaseElement, Transform, Clipping): """ The **image** element indicates that the contents of a complete file are to be rendered into a given rectangle within the current user coordinate system. The **image** element can refer to raster image files such as PNG or JPEG or to files with MIME type of "image/svg+xml". """ elementname = 'image' def __init__(self, href, insert=None, size=None, **extra): """ :param string href: hyperlink to the image resource :param 2-tuple insert: insert point (**x**, **y**) :param 2-tuple size: (**width**, **height**) :param dict attribs: additional SVG attributes :param extra: additional SVG attributs as keyword-arguments """ super(Image, self).__init__(**extra) self['xlink:href'] = href if insert is not None: self['x'] = insert[0] self['y'] = insert[1] if size is not None: self['width'] = size[0] self['height'] = size[1] def stretch(self): """ Stretch viewBox in x and y direction to fill viewport, does not preserve aspect ratio. """ self['preserveAspectRatio'] = 'none' def fit(self, horiz="center", vert="middle", scale="meet"): """ Set the preserveAspectRatio attribute. :param string horiz: horizontal alignment ``'left'|'center'|'right'`` :param string vert: vertical alignment ``'top'|'middle'|'bottom'`` :param string scale: scale method ``'meet'|'slice'`` ============= =========== Scale methods Description ============= =========== ``meet`` preserve aspect ration and zoom to limits of viewBox ``slice`` preserve aspect ration and viewBox touch viewport on all bounds, viewBox will extend beyond the bounds of the viewport ============= =========== """ if self.debug and scale not in ('meet', 'slice'): raise ValueError("Invalid scale parameter '%s'" % scale) self.attribs['preserveAspectRatio'] = "%s%s %s" % (_horiz[horiz],_vert[vert], scale) svgwrite-1.1.8/svgwrite/masking.py0000666000000000000000000000350012723216341015401 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: masking module # Created: 30.10.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License from svgwrite.base import BaseElement from svgwrite.mixins import Transform class ClipPath(BaseElement, Transform): """ The clipping path restricts the region to which paint can be applied. Conceptually, any parts of the drawing that lie outside of the region bounded by the currently active clipping path are not drawn. A clipping path can be thought of as a mask wherein those pixels outside the clipping path are black with an alpha value of zero and those pixels inside the clipping path are white with an alpha value of one (with the possible exception of anti-aliasing along the edge of the silhouette). A **clipPath** element can contain **path** elements, **text** elements, basic shapes (such as **circle**) or a **use** element. If a **use** element is a child of a **clipPath** element, it must directly reference **path**, **text** or basic shape elements. Indirect references are an error. """ elementname = 'clipPath' class Mask(BaseElement): """ In SVG, you can specify that any other graphics object or **g** element can be used as an alpha mask for compositing the current object into the background. A **mask** can contain any graphical elements or container elements such as a **g**. """ elementname = 'mask' def __init__(self, start=None, size=None, **extra): super(Mask, self).__init__(**extra) if start is not None: self['x'] = start[0] self['y'] = start[1] if size is not None: self['width'] = size[0] self['height'] = size[1] svgwrite-1.1.8/svgwrite/mixins.py0000666000000000000000000002461112723215556015274 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: mixins # Created: 19.10.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License from svgwrite.utils import strlist from svgwrite.utils import is_string _horiz = {'center': 'xMid', 'left': 'xMin', 'right': 'xMax'} _vert = {'middle': 'YMid', 'top': 'YMin', 'bottom':'YMax'} class ViewBox(object): """ The **ViewBox** mixin provides the ability to specify that a given set of graphics stretch to fit a particular container element. The value of the **viewBox** attribute is a list of four numbers **min-x**, **min-y**, **width** and **height**, separated by whitespace and/or a comma, which specify a rectangle in **user space** which should be mapped to the bounds of the viewport established by the given element, taking into account attribute **preserveAspectRatio**. """ def viewbox(self, minx=0, miny=0, width=0, height=0): """ Specify a rectangle in **user space** (no units allowed) which should be mapped to the bounds of the viewport established by the given element. :param number minx: left border of the viewBox :param number miny: top border of the viewBox :param number width: width of the viewBox :param number height: height of the viewBox """ self['viewBox'] = strlist( [minx, miny, width, height] ) def stretch(self): """ Stretch viewBox in x and y direction to fill viewport, does not preserve aspect ratio. """ self['preserveAspectRatio'] = 'none' def fit(self, horiz="center", vert="middle", scale="meet"): """ Set the **preserveAspectRatio** attribute. :param string horiz: horizontal alignment ``'left | center | right'`` :param string vert: vertical alignment ``'top | middle | bottom'`` :param string scale: scale method ``'meet | slice'`` ============= ======================================================= Scale methods Description ============= ======================================================= ``'meet'`` preserve aspect ration and zoom to limits of viewBox ``'slice'`` preserve aspect ration and viewBox touch viewport on all bounds, viewBox will extend beyond the bounds of the viewport ============= ======================================================= """ if self.debug and scale not in ('meet', 'slice'): raise ValueError("Invalid scale parameter '%s'" % scale) self['preserveAspectRatio'] = "%s%s %s" % (_horiz[horiz],_vert[vert], scale) class Transform(object): """ The **Transform** mixin operates on the **transform** attribute. The value of the **transform** attribute is a ``, which is defined as a list of transform definitions, which are applied in the order provided. The individual transform definitions are separated by whitespace and/or a comma. All coordinates are **user space coordinates**. """ transformname = 'transform' def translate(self, tx, ty=None): """ Specifies a translation by **tx** and **ty**. If **ty** is not provided, it is assumed to be zero. :param number tx: user coordinate - no units allowed :param number ty: user coordinate - no units allowed """ self._add_transformation("translate(%s)" % strlist( [tx, ty] )) def rotate(self, angle, center=None): """ Specifies a rotation by **angle** degrees about a given point. If optional parameter **center** are not supplied, the rotate is about the origin of the current user coordinate system. :param number angle: rotate-angle in degrees :param 2-tuple center: rotate-center as user coordinate - no units allowed """ self._add_transformation("rotate(%s)" % strlist( [angle, center] )) def scale(self, sx, sy=None): """ Specifies a scale operation by **sx** and **sy**. If **sy** is not provided, it is assumed to be equal to **sx**. :param number sx: scalar factor x-axis, no units allowed :param number sy: scalar factor y-axis, no units allowed """ self._add_transformation("scale(%s)" % strlist([sx, sy])) def skewX(self, angle): """ Specifies a skew transformation along the x-axis. :param number angle: skew-angle in degrees, no units allowed """ self._add_transformation("skewX(%s)" % angle) def skewY(self, angle): """ Specifies a skew transformation along the y-axis. :param number angle: skew-angle in degrees, no units allowed """ self._add_transformation("skewY(%s)" % angle) def matrix(self, a, b, c, d, e, f): self._add_transformation("matrix(%s)" % strlist( [a, b, c, d, e, f] )) def _add_transformation(self, new_transform): old_transform = self.attribs.get(self.transformname, '') self[self.transformname] = ("%s %s" % (old_transform, new_transform)).strip() class XLink(object): """ XLink mixin """ def set_href(self, element): """ Create a reference to **element**. :param element: if element is a `string` its the **id** name of the referenced element, if element is a **BaseElement** class the **id** SVG Attribute is used to create the reference. """ self.href = element self.update_id() def set_xlink(self, title=None, show=None, role=None, arcrole=None): """ Set XLink attributes (for `href` use :meth:`set_href`). """ if role is not None: self['xlink:role'] = role if arcrole is not None: self['xlink:arcrole'] = arcrole if title is not None: self['xlink:title'] = title if show is not None: self['xlink:show'] = show def update_id(self): if not hasattr(self, 'href'): return if is_string(self.href): idstr = self.href else: idstr = self.href.get_iri() self.attribs['xlink:href'] = idstr class Presentation(object): """ Helper methods to set presentation attributes. """ def fill(self, color=None, rule=None, opacity=None): """ Set SVG Properties **fill**, **fill-rule** and **fill-opacity**. """ if color is not None: if is_string(color): self['fill'] = color else: self['fill'] = color.get_paint_server() if rule is not None: self['fill-rule'] = rule if opacity is not None: self['fill-opacity'] = opacity return self def stroke(self, color=None, width=None, opacity=None, linecap=None, linejoin=None, miterlimit=None): """ Set SVG Properties **stroke**, **stroke-width**, **stroke-opacity**, **stroke-linecap** and **stroke-miterlimit**. """ if color is not None: if is_string(color): self['stroke'] = color else: self['stroke'] = color.get_paint_server() if width is not None: self['stroke-width'] = width if opacity is not None: self['stroke-opacity'] = opacity if linecap is not None: self['stroke-linecap'] = linecap if linejoin is not None: self['stroke-linejoin'] = linejoin if miterlimit is not None: self['stroke-miterlimit'] = miterlimit return self def dasharray(self, dasharray=None, offset=None): """ Set SVG Properties **stroke-dashoffset** and **stroke-dasharray**. Where *dasharray* specify the lengths of alternating dashes and gaps as of or values or a of comma and/or white space separated or . (e.g. as dasharray=[1, 0.5] or as dasharray='1 0.5') """ if dasharray is not None: self['stroke-dasharray'] = strlist(dasharray, ' ') if offset is not None: self['stroke-dashoffset'] = offset return self class MediaGroup(object): """ Helper methods to set media group attributes. """ def viewport_fill(self, color=None, opacity=None): """ Set SVG Properties **viewport-fill** and **viewport-fill-opacity**. """ if color is not None: self['viewport-fill'] = color if opacity is not None: self['viewport-fill-opacity'] = opacity return self class Markers(object): """ Helper methods to set marker attributes. """ def set_markers(self, markers): """ Set markers for line elements (line, polygon, polyline, path) to values specified by `markers`. * if `markers` is a 3-tuple: * attribute 'marker-start' = markers[0] * attribute 'marker-mid' = markers[1] * attribute 'marker-end' = markers[2] * `markers` is a `string` or a `Marker` class: * attribute 'marker' = `FuncIRI` of markers """ def get_funciri(value): if is_string(value): # strings has to be a valid reference including the '#' return 'url(%s)' % value else: # else create a reference to the object '#id' return 'url(#%s)' % value['id'] if is_string(markers): self['marker'] = get_funciri(markers) else: try: markerstart, markermid, markerend = markers self['marker-start'] = get_funciri(markerstart) self['marker-mid'] = get_funciri(markermid) self['marker-end'] = get_funciri(markerend) except (TypeError, KeyError): self['marker'] = get_funciri(markers) class Clipping(object): def clip_rect(self, top='auto', right='auto', bottom='auto', left='auto'): """ Set SVG Property **clip**. """ self['clip'] = "rect(%s,%s,%s,%s)" % (top, right, bottom, left) svgwrite-1.1.8/svgwrite/params.py0000666000000000000000000000355712233640344015247 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman # Purpose: svgwrite package parameter # Created: 10.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License from svgwrite.validator2 import get_validator class Parameter(object): """ .. attribute:: Parameter.debug *read/write* property * *True* : debug mode is on, all SVG attributes are checked if valid in the element context. Also the included SVG subelements will be checked if they are valid for the parent SVG element. * *False*: no validation checks will be done, but program execution is faster. .. attribute:: Parameter.profile *read/write* property name of the SVG profile, valid profiles are: ``'full|basic|tiny'`` """ __slots__ = ['_debug', 'validator', '_profile'] def __init__(self, debug=True, profile='full'): self._debug = debug self.profile = profile def _init_validator(self): self.validator = get_validator(self.profile, self.debug) @property def debug(self): return self._debug @debug.setter def debug(self, debug): self._debug = debug self._init_validator() def get_version(self): if self._profile == 'tiny': return '1.2' else: return '1.1' @property def profile(self): return self._profile @profile.setter def profile(self, profile): """ :param string profile: name of the SVG profile, valid profiles are: ``'full|basic|tiny'`` """ profile = profile.lower() if profile in ('tiny', 'basic', 'full'): self._profile = profile self._init_validator() else: raise ValueError("'%s' is not a valid profile." % profile) svgwrite-1.1.8/svgwrite/path.py0000666000000000000000000000700712723216341014712 0ustar 00000000000000#coding:utf-8 # Author: mozman # Purpose: svg path element # Created: 08.09.2010 # # Copyright (C) 2010 Manfred Moitzi # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from svgwrite.base import BaseElement from svgwrite.utils import strlist from svgwrite.mixins import Presentation, Markers, Transform from svgwrite.utils import to_unicode class Path(BaseElement, Transform, Presentation, Markers): """ The element represent the outline of a shape which can be filled, stroked, used as a clipping path, or any combination of the three. """ elementname = 'path' def __init__(self, d=None, **extra): """ :param `iterable` d: *coordinates*, *length* and *commands* :param dict attribs: additional SVG attributes :param extra: additional SVG attributs as keyword-arguments """ super(Path, self).__init__(**extra) self.commands = [] self.push(d) if self.debug: self.validator.check_all_svg_attribute_values(self.elementname, self.attribs) def push(self, *elements): """ Push commands and coordinats onto the command stack. :param `iterable` elements: *coordinates*, *length* and *commands* """ self.commands.extend(elements) @staticmethod def arc_flags(large_arc=True, angle_dir='+'): large_arc_flag = int(large_arc) sweep_flag = {'+': 1, '-': 0}[angle_dir] return "%d,%d" % (large_arc_flag, sweep_flag) def push_arc(self, target, rotation, r, large_arc=True, angle_dir='+', absolute=False): """ Helper function for the elliptical-arc command. see SVG-Reference: http://www.w3.org/TR/SVG11/paths.html#PathData :param 2-tuple target: *coordinate* of the arc end point :param number rotation: x-axis-rotation of the ellipse in degrees :param number|2-tuple r: radii rx, ry when r is a *2-tuple* or rx=ry=r if r is a *number* :param bool large_arc: draw the arc sweep of greater than or equal to 180 degrees (**large-arc-flag**) :param angle_dir: ``'+|-'`` ``'+'`` means the arc will be drawn in a "positive-angle" direction (**sweep-flag**) :param bool absolute: indicates that target *coordinates* are absolute else they are relative to the current point """ self.push({True: 'A', False: 'a'}[absolute]) if isinstance(r, (float, int)): self.push(r, r) else: self.push(r) self.push(rotation) self.push(Path.arc_flags(large_arc, angle_dir)) self.push(target) def get_xml(self): """ Get the XML representation as `ElementTree` object. :return: XML `ElementTree` of this object and all its subelements """ self.attribs['d'] = to_unicode(strlist(self.commands, ' ')) return super(Path, self).get_xml() svgwrite-1.1.8/svgwrite/pattern.py0000666000000000000000000000366512012650556015442 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: pattern module # Created: 29.10.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License from svgwrite.base import BaseElement from svgwrite.mixins import XLink, ViewBox, Transform, Presentation from svgwrite.utils import is_string class Pattern(BaseElement, XLink, ViewBox, Transform, Presentation): """ A pattern is used to fill or stroke an object using a pre-defined graphic object which can be replicated ("tiled") at fixed intervals in x and y to cover the areas to be painted. Patterns are defined using a `pattern` element and then referenced by properties `fill` and `stroke` on a given graphics element to indicate that the given element shall be filled or stroked with the referenced pattern. """ elementname = 'pattern' transformname = 'patternTransform' def __init__(self, insert=None, size=None, inherit=None, **extra): """ :param 2-tuple insert: base point of the pattern (**x**, **y**) :param 2-tuple size: size of the pattern (**width**, **height**) :param inherit: pattern inherits properties from `inherit` see: **xlink:href** """ super(Pattern, self).__init__(**extra) if insert is not None: self['x'] = insert[0] self['y'] = insert[1] if size is not None: self['width'] = size[0] self['height'] = size[1] if inherit is not None: if is_string(inherit): self.set_href(inherit) else: self.set_href(inherit.get_iri()) if self.debug: self.validator.check_all_svg_attribute_values(self.elementname, self.attribs) def get_paint_server(self, default='none'): """ Returns the of the gradient. """ return "%s %s" % (self.get_funciri(), default) svgwrite-1.1.8/svgwrite/shapes.py0000666000000000000000000001346712723216510015246 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman # Purpose: svg shapes # Created: 08.09.2010 # # Copyright (C) 2010 Manfred Moitzi # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from svgwrite.base import BaseElement from svgwrite.mixins import Presentation, Markers, Transform class Line(BaseElement, Transform, Presentation, Markers): """ The **line** element defines a line segment that starts at one point and ends at another. """ elementname = 'line' def __init__(self, start=(0, 0), end=(0, 0), **extra): """ :param 2-tuple start: start point (**x1**, **y1**) :param 2-tuple end: end point (**x2**, **y2**) :param extra: additional SVG attributs as keyword-arguments """ super(Line, self).__init__(**extra) x1, y1 = start x2, y2 = end self['x1'] = x1 self['y1'] = y1 self['x2'] = x2 self['y2'] = y2 class Rect(BaseElement, Transform, Presentation): """ The **rect** element defines a rectangle which is axis-aligned with the current user coordinate system. Rounded rectangles can be achieved by setting appropriate values for attributes **rx** and **ry**. """ elementname = 'rect' def __init__(self, insert=(0, 0), size=(1, 1), rx=None, ry=None, **extra): """ :param 2-tuple insert: insert point (**x**, **y**), left-upper point :param 2-tuple size: (**width**, **height**) :param rx: corner x-radius :param ry: corner y-radius :param extra: additional SVG attributs as keyword-arguments """ super(Rect, self).__init__(**extra) x, y = insert width, height = size self['x'] = x self['y'] = y self['width'] = width self['height'] = height if rx is not None: self['rx'] = rx if ry is not None: self['ry'] = ry class Circle(BaseElement, Transform, Presentation): """ The **circle** element defines a circle based on a center point and a radius. """ elementname = 'circle' def __init__(self, center=(0, 0), r=1, **extra): """ :param 2-tuple center: circle center point (**cx**, **cy**) :param length r: circle-radius **r** :param extra: additional SVG attributs as keyword-arguments """ super(Circle, self).__init__(**extra) cx, cy = center self['cx'] = cx self['cy'] = cy self['r'] = r class Ellipse(BaseElement, Transform, Presentation): """ The **ellipse** element defines an ellipse which is axis-aligned with the current user coordinate system based on a center point and two radii. """ elementname = 'ellipse' def __init__(self, center=(0, 0), r=(1, 1), **extra): """ :param 2-tuple center: ellipse center point (**cx**, **cy**) :param 2-tuple r: ellipse radii (**rx**, **ry**) :param extra: additional SVG attributs as keyword-arguments """ super(Ellipse, self).__init__(**extra) cx, cy = center rx, ry = r self['cx'] = cx self['cy'] = cy self['rx'] = rx self['ry'] = ry class Polyline(BaseElement, Transform, Presentation, Markers): """ The **polyline** element defines a set of connected straight line segments. Typically, **polyline** elements define open shapes. """ elementname = 'polyline' def __init__(self, points=[], **extra): """ :param `iterable` points: `iterable` of points (points are `2-tuples`) :param extra: additional SVG attributs as keyword-arguments """ super(Polyline, self).__init__(**extra) self.points = list(points) if self.debug: for point in self.points: x, y = point self.validator.check_svg_type(x, 'number') self.validator.check_svg_type(y, 'number') def get_xml(self): self.attribs['points'] = self.points_to_string(self.points) return super(Polyline, self).get_xml() def points_to_string(self, points): """ Convert a `list` of points `2-tuples` to a `string` ``'p1x,p1y p2x,p2y ...'``. """ strings = [] for point in points: if len(point) != 2: raise TypeError('got %s values, but expected 2 values.' % len(point)) x, y = point if self.debug: self.validator.check_svg_type(x, 'coordinate') self.validator.check_svg_type(y, 'coordinate') if self.profile == 'tiny': if isinstance(x, float): x = round(x, 4) if isinstance(y, float): y = round(y, 4) point = "%s,%s" % (x, y) strings.append(point) return ' '.join(strings) class Polygon(Polyline): """ The **polygon** element defines a closed shape consisting of a set of connected straight line segments. Same as :class:`~svgwrite.shapes.Polyline` but closed. """ elementname = 'polygon' svgwrite-1.1.8/svgwrite/text.py0000666000000000000000000001774412723216510014751 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: text objects # Created: 20.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License """ Text that is to be rendered as part of an SVG document fragment is specified using the **text** element. The characters to be drawn are expressed as XML character data inside the **text** element. """ from svgwrite.base import BaseElement from svgwrite.mixins import Presentation, Transform, XLink from svgwrite.utils import iterflatlist, strlist, is_string, to_unicode class TSpan(BaseElement, Presentation): """ Within a **Text** element, text and font properties and the current text position can be adjusted with absolute or relative coordinate values by using the **TSpan** element. The characters to be drawn are expressed as XML character data inside the **TSpan** element. """ elementname = 'tspan' def __init__(self, text, insert=None, x=None, y=None, dx=None, dy=None, rotate=None, **extra): """ :param string text: **tspan** content :param 2-tuple insert: The **insert** parameter is the absolute insert point of the text, don't use this parameter in combination with the **x** or the **y** parameter. :param list x: list of absolute x-axis values for characters :param list y: list of absolute y-axis values for characters :param list dx: list of relative x-axis values for characters :param list dy: list of relative y-axis values for characters :param list rotate: list of rotation-values for characters (in degrees) """ super(TSpan, self).__init__(**extra) self.text = text if insert is not None: if is_string(insert): raise TypeError("'insert' should be a or a with" " at least two elements.") if x or y: raise ValueError("Use 'insert' and 'x' or 'y' parameter not" " at the same time!") x = [insert[0]] y = [insert[1]] if x is not None: self['x'] = strlist(list(iterflatlist(x)), ' ') if y is not None: self['y'] = strlist(list(iterflatlist(y)), ' ') if dx is not None: self['dx'] = strlist(list(iterflatlist(dx)), ' ') if dy is not None: self['dy'] = strlist(list(iterflatlist(dy)), ' ') if rotate is not None: self['rotate'] = strlist(list(iterflatlist(rotate)), ' ') def get_xml(self): xml = super(TSpan, self).get_xml() xml.text = to_unicode(self.text) return xml class Text(TSpan, Transform): """ The **Text** element defines a graphics element consisting of text. The characters to be drawn are expressed as XML character data inside the **Text** element. """ elementname = 'text' class TRef(BaseElement, XLink, Presentation): """ The textual content for a **Text** can be either character data directly embedded within the element or the character data content of a referenced element, where the referencing is specified with a **TRef** element. """ elementname = 'tref' def __init__(self, element, **extra): """ :param element: create a reference this element, if element is a \ `string` its the **id** name of the referenced element, \ if element is a :class:`~svgwrite.base.BaseElement` \ the **id** SVG Attribute is used to create the reference. """ super(TRef, self).__init__(**extra) self.set_href(element) def get_xml(self): self.update_id() # if href is an object - 'id' - attribute may be changed! return super(TRef, self).get_xml() class TextPath(BaseElement, XLink, Presentation): """ In addition to text drawn in a straight line, SVG also includes the ability to place text along the shape of a **path** element. To specify that a block of text is to be rendered along the shape of a **path**, include the given text within a **textPath** element which includes an **xlink:href** attribute with a IRI reference to a **path** element. """ elementname = 'textPath' def __init__(self, path, text, startOffset=None, method='align', spacing='exact', **extra): """ :param path: link to **path**, **id** string or **Path** object :param string text: **textPath** content :param number startOffset: text starts with offset from begin of path. :param string method: ``align|stretch`` :param string spacing: ``exact|auto`` """ super(TextPath, self).__init__(**extra) self.text = text if method == 'stretch': self['method'] = method if spacing == 'auto': self['spacing'] = spacing if startOffset is not None: self['startOffset'] = startOffset self.set_href(path) def get_xml(self): self.update_id() # if href is an object - 'id' - attribute may be changed! xml = super(TextPath, self).get_xml() xml.text = to_unicode(self.text) return xml class TBreak(BaseElement): elementname = 'tbreak' def __init__(self, **extra): super(TBreak, self).__init__(**extra) def __getitem__(self, key): raise NotImplementedError("__getitem__() not supported by TBreak class.") def __setitem__(self, key, value): raise NotImplementedError("__setitem__() not supported by TBreak class.") def add(self, element): raise NotImplementedError("add() not supported by TBreak class.") class TextArea(BaseElement, Transform, Presentation): """ At this time **textArea** is only available for SVG 1.2 Tiny profile. The **textArea** element allows simplistic wrapping of text content within a given region. The `tiny` profile of SVG specifies a single rectangular region. Other profiles may allow a sequence of arbitrary shapes. Text wrapping via the **textArea** element is available as a lightweight and convenient facility for simple text wrapping where a complete box model layout engine is not required. The layout of wrapped text is user agent dependent; thus, content developers need to be aware that there might be different results, particularly with regard to where line breaks occur. The TextArea class wraps every text added by write() or writeline() as **tspan** element. """ elementname = 'textArea' def __init__(self, text=None, insert=None, size=None, **extra): super(TextArea, self).__init__(**extra) if text is not None: self.write(text) if insert is not None: self['x'] = insert[0] self['y'] = insert[1] if size is not None: self['width'] = size[0] self['height'] = size[1] def line_increment(self, value): """ Set the line-spacing to *value*. """ self['line-increment'] = value def write(self, text, **extra): """ Add text as **tspan** elements, with extra-params for the **tspan** element. Use the '\\\\n' character for line breaks. """ if '\n' not in text: self.add(TSpan(text, **extra)) else: lines = text.split('\n') for line in lines[:-1]: if line: # no text between '\n'+ self.add(TSpan(line, **extra)) self.add(TBreak()) # case "text\n" : last element is '' # case "texta\ntextb : last element is 'textb' if lines[-1]: self.add(TSpan(lines[-1], **extra)) svgwrite-1.1.8/svgwrite/utils.py0000666000000000000000000001416012720243722015114 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman # Purpose: svg util functions and classes # Created: 08.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License """ .. autofunction:: rgb .. autofunction:: iterflatlist .. autofunction:: strlist .. autofunction:: get_unit .. autofunction:: split_coordinate .. autofunction:: split_angle .. autofunction:: rect_top_left_corner """ import sys PYTHON3 = sys.version_info[0] > 2 from functools import partial # Python 3 adaption if PYTHON3: to_unicode = str basestring = str else: def to_unicode(value): return unicode(value, encoding='utf8') if isinstance(value, str) else unicode(value) # Python 3 adaption def is_string(value): return isinstance(value, basestring) from svgwrite.data import pattern def rgb(r=0, g=0, b=0, mode='RGB'): """ Convert **r**, **g**, **b** values to a `string`. :param r: red part :param g: green part :param b: blue part :param string mode: ``'RGB | %'`` :rtype: string ========= ============================================================= mode Description ========= ============================================================= ``'RGB'`` returns a rgb-string format: ``'rgb(r, g, b)'`` ``'%'`` returns percent-values as rgb-string format: ``'rgb(r%, g%, b%)'`` ========= ============================================================= """ def percent(value): value = float(value) if value < 0: value = 0 if value > 100: value = 100 return value if mode.upper() == 'RGB': return "rgb(%d,%d,%d)" % (int(r) & 255, int(g) & 255, int(b) & 255) elif mode == "%": # see http://www.w3.org/TR/SVG11/types.html#DataTypeColor # percentage is an 'number' value return "rgb(%d%%,%d%%,%d%%)" % (percent(r), percent(g), percent(b)) else: raise ValueError("Invalid mode '%s'" % mode) def iterflatlist(values): """ Flatten nested *values*, returns an `iterator`. """ for element in values: if hasattr(element, "__iter__") and not is_string(element): for item in iterflatlist(element): yield item else: yield element def strlist(values, seperator=","): """ Concatenate **values** with **sepertator**, `None` values will be excluded. :param values: `iterable` object :returns: `string` """ if is_string(values): return values else: return seperator.join([str(value) for value in iterflatlist(values) if value is not None]) def get_unit(coordinate): """ Get the `unit` identifier of **coordinate**, if **coordinate** has a valid `unit` identifier appended, else returns `None`. """ if isinstance(coordinate, (int, float)): return None result = pattern.coordinate.match(coordinate) if result: return result.group(3) else: raise ValueError("Invalid format: '%s'" % coordinate) def split_coordinate(coordinate): """ Split coordinate into `` and 'unit` identifier. :returns: <2-tuple> (number, unit-identifier) or (number, None) if no unit-identifier is present or coordinate is an int or float. """ if isinstance(coordinate, (int, float)): return (float(coordinate), None) result = pattern.coordinate.match(coordinate) if result: return (float(result.group(1)), result.group(3)) else: raise ValueError("Invalid format: '%s'" % coordinate) def split_angle(angle): """ Split angle into `` and `` identifier. :returns: <2-tuple> (number, angle-identifier) or (number, None) if no angle-identifier is present or angle is an int or float. """ if isinstance(angle, (int, float)): return (float(angle), None) result = pattern.angle.match(angle) if result: return (float(result.group(1)), result.group(3)) else: raise ValueError("Invalid format: '%s'" % angle) def rect_top_left_corner(insert, size, pos='top-left'): """ Calculate top-left corner of a rectangle. **insert** and **size** must have the same units. :param 2-tuple insert: insert point :param 2-tuple size: (width, height) :param string pos: insert position ``'vert-horiz'`` :return: ``'top-left'`` corner of the rect :rtype: 2-tuple ========== ============================== pos valid values ========== ============================== **vert** ``'top | middle | bottom'`` **horiz** ``'left'|'center'|'right'`` ========== ============================== """ vert, horiz = pos.lower().split('-') x, xunit = split_coordinate(insert[0]) y, yunit = split_coordinate(insert[1]) width, wunit = split_coordinate(size[0]) height, hunit = split_coordinate(size[1]) if xunit != wunit: raise ValueError("x-coordinate and width has to have the same unit") if yunit != hunit: raise ValueError("y-coordinate and height has to have the same unit") if horiz == 'center': x = x - width / 2. elif horiz == 'right': x = x - width elif horiz != 'left': raise ValueError("Invalid horizontal position: '%s'" % horiz) if vert == 'middle': y = y - height / 2. elif vert == 'bottom': y = y - height elif vert != 'top': raise ValueError("Invalid vertical position: '%s'" % vert) if xunit: x = "%s%s" %(x, xunit) if yunit: y = "%s%s" %(y, yunit) return (x, y) class AutoID(object): _nextid = 1 def __init__(self, value=None): self._set_value(value) @classmethod def _set_value(cls, value=None): if value is not None: cls._nextid = value @classmethod def next_id(cls, value=None): cls._set_value(value) retval = "id%d" % cls._nextid cls._nextid += 1 return retval svgwrite-1.1.8/svgwrite/validator2.py0000666000000000000000000001372012270370170016022 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: validator2 module - new validator module # Created: 01.10.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License from svgwrite.data import full11 from svgwrite.data import tiny12 from svgwrite.data import pattern validator_cache = {} def cache_key(profile, debug): return str(profile) + str(debug) def get_validator(profile, debug=True): """ Validator factory """ try: return validator_cache[cache_key(profile, debug)] except KeyError: if profile == 'tiny': validator = Tiny12Validator(debug) elif profile in ('full', 'basic', 'none'): validator = Full11Validator(debug) else: raise ValueError("Unsupported profile: '%s'" % profile) validator_cache[cache_key(profile, debug)] = validator return validator class Tiny12Validator(object): profilename = "Tiny 1.2" def __init__(self, debug=True): self.debug = debug self.attributes = tiny12.attributes self.elements = tiny12.elements self.typechecker = tiny12.TypeChecker() def check_all_svg_attribute_values(self, elementname, attributes): """ Check if attributes are valid for object 'elementname' and all svg attributes have valid types and values. Raises ValueError. """ for attributename, value in attributes.items(): self.check_svg_attribute_value(elementname, attributename, value) def check_svg_attribute_value(self, elementname, attributename, value): """ Check if 'attributename' is valid for object 'elementname' and 'value' is a valid svg type and value. Raises ValueError. """ self._check_valid_svg_attribute_name(elementname, attributename) self._check_svg_value(elementname, attributename, value) def _check_svg_value(self, elementname, attributename, value): """ Checks if 'value' is a valid svg-type for svg-attribute 'attributename' at svg-element 'elementname'. Raises TypeError. """ attribute = self.attributes[attributename] # check if 'value' match a valid datatype for typename in attribute.get_types(elementname): if self.typechecker.check(typename, value): return # check if 'value' is a valid constant valuestr = str(value) if not valuestr in attribute.get_const(elementname): raise TypeError("'%s' is not a valid value for attribute '%s' at svg-element <%s>." % (value, attributename, elementname)) def _check_valid_svg_attribute_name(self, elementname, attributename): """ Check if 'attributename' is a valid svg-attribute for svg-element 'elementname'. Raises ValueError. """ if not self.is_valid_svg_attribute(elementname, attributename): raise ValueError("Invalid attribute '%s' for svg-element <%s>." % (attributename, elementname)) def _get_element(self, elementname): try: return self.elements[elementname] except KeyError: raise KeyError("<%s> is not valid for selected profile: '%s'." % (elementname, self.profilename)) def check_svg_type(self, value, typename='string'): """ Check if 'value' matches svg type 'typename'. Raises TypeError. """ if self.typechecker.check(typename, value): return value else: raise TypeError("%s is not of type '%s'." % (value, typename)) def is_valid_elementname(self, elementname): """ True if 'elementname' is a valid svg-element name. """ return elementname in self.elements def is_valid_svg_attribute(self, elementname, attributename): """ True if 'attributename' is a valid svg-attribute for svg-element 'elementname'. """ element = self._get_element(elementname) return attributename in element.valid_attributes def is_valid_children(self, elementname, childrenname): """ True if svg-element 'childrenname' is a valid children of svg-element 'elementname'. """ element = self._get_element(elementname) return childrenname in element.valid_children def check_valid_children(self, elementname, childrenname): """ Checks if svg-element 'childrenname' is a valid children of svg-element 'elementname'. Raises ValueError. """ if not self.is_valid_children(elementname, childrenname): raise ValueError("Invalid children '%s' for svg-element <%s>." % (childrenname, elementname)) def get_coordinate(self, value): """ Split value in (number, unit) if value has an unit or (number, None). Raises ValueError. """ if value is None: raise TypeError("Invalid type 'None'.") if isinstance(value, (int, float)): result = (value, None) else: result = pattern.coordinate.match(value.strip()) if result: number, tmp, unit = result.groups() number = float(number) else: raise ValueError("'%s' is not a valid svg-coordinate." % value) result = (number, unit) if self.typechecker.is_number(result[0]): return result else: version = "SVG %s %s" % self.typechecker.get_version() raise ValueError("%s is not a valid number for: %s." % (value, version)) get_length = get_coordinate class Full11Validator(Tiny12Validator): profilename = "Full 1.1" def __init__(self, debug=True): self.debug = debug self.attributes = full11.attributes self.elements = full11.elements self.typechecker = full11.TypeChecker() svgwrite-1.1.8/svgwrite/__init__.py0000666000000000000000000000465112723215672015525 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman # Purpose: package definition file # Created: 08.09.2010 # License: MIT License # Copyright (C) 2010-2014 Manfred Moitzi """ A Python library to create SVG drawings. SVG is a language for describing two-dimensional graphics in XML. SVG allows for three types of graphic objects: vector graphic shapes (e.g., paths consisting of straight lines and curves), images and text. Graphical objects can be grouped, styled, transformed and composited into previously rendered objects. The feature set includes nested transformations, clipping paths, alpha masks, filter effects and template objects. SVG drawings can be interactive and dynamic. Animations can be defined and triggered either declarative (i.e., by embedding SVG animation elements in SVG content) or via scripting. .. seealso:: http://www.w3.org/TR/SVG11/intro.html#AboutSVG a simple example:: import svgwrite dwg = svgwrite.Drawing('test.svg', profile='tiny') dwg.add(dwg.line((0, 0), (10, 0), stroke=svgwrite.rgb(10, 10, 16, '%'))) dwg.add(dwg.text('Test', insert=(0, 0.2))) dwg.save() SVG Version ----------- You can only create two types of SVG drawings: * *SVG 1.2 Tiny Profile*, use Drawing(profile= ``'tiny'``) * *SVG 1.1 Full Profile*, use Drawing(profile= ``'full'``) """ version = (1, 1, 8) # also update setup.py VERSION = '%d.%d.%d' % version AUTHOR_NAME = 'Manfred Moitzi' AUTHOR_EMAIL = 'mozman@gmx.at' CYEAR = '2014' from svgwrite.drawing import Drawing from svgwrite.utils import rgb class Unit(object): """ Add units to values. """ def __init__(self, unit='cm'): """ Unit constructor :param str unit: specify the unit string """ self._unit = unit def __rmul__(self, other): """ add unit-string to 'other'. (e.g. 5*cm => '5cm') """ return "%s%s" % (other, self._unit) def __call__(self, *args): """ Add unit-strings to all arguments. :param args: list of values e.g.: cm(1,2,3) => '1cm,2cm,3cm' """ return ','.join(["%s%s" % (arg, self._unit) for arg in args]) cm = Unit('cm') mm = Unit('mm') em = Unit('em') ex = Unit('ex') px = Unit('px') inch = Unit('in') pc = Unit('pc') pt = Unit('pt') percent = Unit('%') deg = Unit('deg') grad = Unit('grad') rad = Unit('rad') Hz = Unit('Hz') kHz = Unit('kHz') svgwrite-1.1.8/svgwrite.egg-info/0000777000000000000000000000000012723217123015071 5ustar 00000000000000svgwrite-1.1.8/svgwrite.egg-info/dependency_links.txt0000666000000000000000000000000112723217122021136 0ustar 00000000000000 svgwrite-1.1.8/svgwrite.egg-info/PKG-INFO0000666000000000000000000001600412723217122016166 0ustar 00000000000000Metadata-Version: 1.1 Name: svgwrite Version: 1.1.8 Summary: A Python library to create SVG drawings. Home-page: http://bitbucket.org/mozman/svgwrite Author: Manfred Moitzi Author-email: mozman@gmx.at License: MIT License Download-URL: http://bitbucket.org/mozman/svgwrite/downloads Description: svgwrite ======== .. image:: https://readthedocs.org/projects/pip/badge/ :target: https://svgwrite.readthedocs.io :alt: Read The Docs .. image:: https://img.shields.io/pypi/l/svgwrite.svg :target: https://pypi.python.org/pypi/svgwrite/ :alt: License .. image:: https://img.shields.io/pypi/pyversions/svgwrite.svg :target: https://pypi.python.org/pypi/svgwrite/ :alt: Python Versions .. image:: https://img.shields.io/pypi/wheel/svgwrite.svg :target: https://pypi.python.org/pypi/svgwrite/ :alt: Wheel Status .. image:: https://img.shields.io/pypi/status/svgwrite.svg :target: https://pypi.python.org/pypi/svgwrite/ :alt: Status Abstract ======== A Python library to create SVG drawings. a simple example:: import svgwrite dwg = svgwrite.Drawing('test.svg', profile='tiny') dwg.add(dwg.line((0, 0), (10, 0), stroke=svgwrite.rgb(10, 10, 16, '%'))) dwg.add(dwg.text('Test', insert=(0, 0.2), fill='red')) dwg.save() for more examples see: examples.py Installation ============ with pip:: pip install svgwrite or from source:: python setup.py install Documentation ============= * http://packages.python.org/svgwrite * http://readthedocs.org/docs/svgwrite/ send feedback to mozman@gmx.at svgwrite can be found on bitbucket.org at: http://bitbucket.org/mozman/svgwrite NEWS ==== Version 1.1.8 - 2016-05-31 * BUGFIX: None checks: 'if value:' -> 'if value is not None:' Version 1.1.7 - 2016-05-22 * BUGFIX: color accepts percentage values as floats like "rgb(10.2%, 3.78%, 20%)" Version 1.1.6 - 2014-05-30 * BUGFIX: sign for offset-value wasn't optional Version 1.1.5 - 2014-03-26 * BUGFIX: xml serialization for CPython 3.4.0 Version 1.1.4 - 2014-03-16 * simplified path parser * pyparsing as external dependency (by jenselme) Version 1.1.3 - 2013-10-01 * updated pyparsing for Python 3 to version 2.0.1 (prior version caused memory leaks) * BUGFIX: utf8 to unicode encoding error for Python 2.7 * Tests for Python 3 require CPython3.3 or newer, using the 'u' prefix. Version 1.1.2 - 2013-01-08 * prevent setup.py from compiling all modules - error with 'pyparsing_py2.py' and Python3 * BUGFIX: all tests run with CPython3.3 Version 1.1.1 - 2012-08-15 * License changed to MIT License * tested with CPython2.7, CPython3.2, CPython3.3 and pypy-1.9 on Win7 Pro 32-bit * BUGFIX: dwg.animateTranform() -> dwg.animateTransform() * BUGFIX: in examples, replaced width and height params by size parameter * added examples * edit docs Version 1.0.1 - 2012-06-08 * added inline stylesheets * added examples created by Lawrence Tattrie Version 1.0.0 - 2012-05-27 * stable * tested with CPython 2.7, CPython 3.2, pypy-1.8 * added script tag - thx to jmahmood * docs also available at: http://readthedocs.org/docs/svgwrite Version 0.2.4 - 2011-12-30 * beta version * Python 2.7: all strings will be converted by the unicode() function, for strings containing none-ascii-characters use prefix ``u""`` or better use ``from __future__ import unicode_literals``, because this is Python 3 compatible. * tested with CPython 2.7, CPython 3.2, and PyPy 1.7 * BUGFIX: color parsing accepts white spaces in ``rgb()`` like ``rgb(0, 0, 0)`` Version 0.2.3 - 2010-11-13 * beta version * Python 3.1 support * splitted examples.py into several files and moved them to the subdir 'examples' Version 0.2.2 - 2010-11-05 * alpha version * removed 'attribs' parameter from all constructors * new elements: Set, Animate, AnimateMotion, AnimateColor, AnimateTransform, all filter elements * added set_desc(title, desc), set_metadata(xmldata) to BaseElement class * moved content of interfaces.py to mixins.py, (ITransform -> Transform and so on) Version 0.2.1 - 2010-10-31 * alpha version * new elements: Marker, ClipPath, Mask * paint service: LinearGradient, RadialGradient, Pattern Version 0.2.0 - 2010-10-24 * alpha version * validator rewritten as validator2.py * debug and profile options separated for each drawing object * important change: create objects with factory functions of the *Drawing* class: drawing.(...) * added mixins for setting stroke and fill properties * new elements: Hyperlink, Image, TextArea, Version 0.1.0 - 2010-09-26 * alpha version * new elements: * basic shapes: Line, Rect, Circle, Ellipse, Polyline, Polygon, Path * text elements: Text, TSpan, TRef, TextPath * container elements: Group, Symbol, SVG, Use, Defs * for examples see: examples.py Platform: OS Independent Classifier: Development Status :: 5 - Production/Stable Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Intended Audience :: Developers Classifier: Topic :: Multimedia :: Graphics Classifier: Topic :: Software Development :: Libraries :: Python Modules Provides: svgwrite svgwrite-1.1.8/svgwrite.egg-info/requires.txt0000666000000000000000000000002112723217122017461 0ustar 00000000000000pyparsing>=2.0.1 svgwrite-1.1.8/svgwrite.egg-info/SOURCES.txt0000666000000000000000000000621312723217123016757 0ustar 00000000000000LICENSE.TXT MANIFEST.in NEWS.rst README.rst requirements.txt setup.py examples/LSystem.py examples/basic_shapes.py examples/checkerboard.py examples/defs_test.py examples/fePointLight.py examples/koch_snowflake.py examples/linearGradient.py examples/mandelbrot.py examples/marker.py examples/pattern.py examples/radialGradient.py examples/runall.bat examples/runall.sh examples/runall3.bat examples/runallpypy.bat examples/simple_text.py examples/use.py examples/ltattrie/bezier.py examples/ltattrie/circle_blur.py examples/ltattrie/color_names.py examples/ltattrie/color_triangles_function.py examples/ltattrie/length_units.py examples/ltattrie/line_cap_join.py examples/ltattrie/rgb.txt examples/ltattrie/runall.bat examples/ltattrie/runall.sh examples/ltattrie/runall3.bat examples/ltattrie/tenticles.py examples/ltattrie/text_font_generic_family.py examples/ltattrie/text_font_size.py examples/ltattrie/text_justify.py examples/ltattrie/tiling_part_1.py examples/ltattrie/tiling_part_2.py examples/ltattrie/tiling_part_3.py examples/ltattrie/tiling_part_4.py examples/ltattrie/tiling_part_5.py examples/ltattrie/xkcd_colour_data_svgwrite_3.py svgwrite/__init__.py svgwrite/animate.py svgwrite/base.py svgwrite/container.py svgwrite/drawing.py svgwrite/elementfactory.py svgwrite/etree.py svgwrite/filters.py svgwrite/gradients.py svgwrite/image.py svgwrite/masking.py svgwrite/mixins.py svgwrite/params.py svgwrite/path.py svgwrite/pattern.py svgwrite/shapes.py svgwrite/text.py svgwrite/utils.py svgwrite/validator2.py svgwrite.egg-info/PKG-INFO svgwrite.egg-info/SOURCES.txt svgwrite.egg-info/dependency_links.txt svgwrite.egg-info/requires.txt svgwrite.egg-info/top_level.txt svgwrite/data/__init__.py svgwrite/data/colors.py svgwrite/data/full11.py svgwrite/data/pattern.py svgwrite/data/svgparser.py svgwrite/data/tiny12.py svgwrite/data/typechecker.py svgwrite/data/types.py svgwrite/data/__init__.py svgwrite/data/colors.py svgwrite/data/full11.py svgwrite/data/pattern.py svgwrite/data/svgparser.py svgwrite/data/tiny12.py svgwrite/data/typechecker.py svgwrite/data/types.py tests/__init__.py tests/test_animate.py tests/test_animation_timing_parser.py tests/test_base_element.py tests/test_circle.py tests/test_clippath.py tests/test_clipping.py tests/test_clock_val_parser.py tests/test_defs.py tests/test_description.py tests/test_drawing.py tests/test_elementfactory.py tests/test_ellipse.py tests/test_filters.py tests/test_full11_typechecker.py tests/test_gradients.py tests/test_group.py tests/test_hyperlink.py tests/test_image.py tests/test_line.py tests/test_marker_class.py tests/test_markers_mixin.py tests/test_mask.py tests/test_mediagroup.py tests/test_parameter.py tests/test_parsing_basic_types.py tests/test_path.py tests/test_pathdataparser.py tests/test_pattern.py tests/test_polyline.py tests/test_presentation.py tests/test_rect.py tests/test_script.py tests/test_style.py tests/test_svg.py tests/test_svgattributes.py tests/test_symbol.py tests/test_text.py tests/test_textarea.py tests/test_tiny12_typechecker.py tests/test_transform.py tests/test_transformlistparser.py tests/test_use.py tests/test_utils.py tests/test_validator2.py tests/test_viewbox.py tests/test_xlink.pysvgwrite-1.1.8/svgwrite.egg-info/top_level.txt0000666000000000000000000000002712723217122017621 0ustar 00000000000000svgwrite svgwrite/data svgwrite-1.1.8/tests/0000777000000000000000000000000012723217123012667 5ustar 00000000000000svgwrite-1.1.8/tests/test_animate.py0000666000000000000000000001007612342010517015715 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test animate # Created: 31.10.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import unittest from svgwrite.animate import Set, Animate, AnimateColor, AnimateMotion, AnimateTransform class TestSet(unittest.TestCase): def test_constructor(self): s = Set(debug=True) self.assertEqual(s.tostring(), '') def test_set_href(self): s = Set(href='#test', debug=True) self.assertEqual(s.tostring(), '') def test_set_target(self): s = Set(debug=True) s.set_target('x', 'XML') self.assertEqual(s.tostring(), '') def test_set_event(self): s = Set(debug=True) s.set_event('test1', 'test2', 'test3', 'test4') self.assertEqual(s.tostring(), '') def test_set_timing(self): s = Set(debug=True) s.set_timing('indefinite', 'indefinite', 'indefinite', 'media', 'media', 'always', 'indefinite', 'indefinite') self.assertEqual(s.tostring(), '') def test_set_timing_1s(self): s = Set(debug=True) s.set_timing('1s') result = s.tostring() self.assertEqual(result, '') def test_freeze(self): s = Set(debug=True) s.freeze() self.assertEqual(s.tostring(), '') class TestAnimate(unittest.TestCase): def test_constructor(self): a = Animate('x', debug=True) self.assertEqual(a.tostring(), '') def test_freeze(self): a = Animate(debug=True) a.freeze() self.assertEqual(a.tostring(), '') def test_set_value(self): a = Animate(debug=True) a.set_value('0;1;2', 'linear', '0', '0 0 0 0', 0, 0, 0) self.assertEqual(a.tostring(), '') def test_values_string(self): s = Animate(values="1;2;3", debug=True) self.assertEqual(s.tostring(), '') def test_values_list(self): s = Animate(values=[1, 2, 3], debug=True) self.assertEqual(s.tostring(), '') def test_values_int(self): s = Animate(values=(3,), debug=True) self.assertEqual(s.tostring(), '') class TestAnimateColor(unittest.TestCase): def test_freeze(self): s = AnimateColor(debug=True) s.freeze() self.assertEqual(s.tostring(), '') class TestAnimateMotion(unittest.TestCase): def test_freeze(self): s = AnimateMotion(debug=True) s.freeze() self.assertEqual(s.tostring(), '') def test_init_with_path(self): s = AnimateMotion('m 0 0', debug=True) self.assertEqual(s.tostring(), '') def test_set_value(self): a = AnimateMotion(debug=True) a.set_value('m 0 0', 'linear', '0', 'auto') self.assertEqual(a.tostring(), '') class TestAnimateTransform(unittest.TestCase): def test_freeze(self): s = AnimateTransform('translate', debug=True) s.freeze() self.assertEqual(s.tostring(), '') if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_animation_timing_parser.py0000666000000000000000000000617412342011224021201 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test animation_timing_parser # Created: 03.11.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import unittest from svgwrite.data.svgparser import is_valid_animation_timing class TestAnimationTimingParser(unittest.TestCase): def test_offset_value(self): self.assertTrue(is_valid_animation_timing("+5min")) self.assertTrue(is_valid_animation_timing("-5s")) self.assertTrue(is_valid_animation_timing("1s")) self.assertTrue(is_valid_animation_timing("0.1s")) def test_syncbase_value(self): self.assertTrue(is_valid_animation_timing("#001.begin+5min")) self.assertTrue(is_valid_animation_timing("#001.end-5min")) self.assertTrue(is_valid_animation_timing("#0A1.begin")) self.assertTrue(is_valid_animation_timing("#0A1.end")) def test_event_value(self): # Id-Value does not start with '#' self.assertTrue(is_valid_animation_timing("shape.click+5min")) # Id-Value starts with '#' self.assertTrue(is_valid_animation_timing("#001.click+5min")) self.assertTrue(is_valid_animation_timing("#001.mouseover-5min")) self.assertTrue(is_valid_animation_timing("mouseup-5min")) self.assertTrue(is_valid_animation_timing("mousedown+5min")) self.assertTrue(is_valid_animation_timing("mouseout")) self.assertTrue(is_valid_animation_timing("focusout")) self.assertTrue(is_valid_animation_timing("focusin")) def test_repeat_value(self): self.assertTrue(is_valid_animation_timing("#001.repeat(1)+5min")) self.assertTrue(is_valid_animation_timing("repeat(1)-5min")) def test_accessKey_value(self): self.assertTrue(is_valid_animation_timing("accessKey(a)+5min")) self.assertTrue(is_valid_animation_timing("accessKey(Z)-5min")) self.assertTrue(is_valid_animation_timing("accessKey(a)")) self.assertTrue(is_valid_animation_timing("accessKey(Z)")) def test_wallclock(self): self.assertTrue(is_valid_animation_timing("wallclock(1997-07-16T19:20:30.45+01:00)")) self.assertTrue(is_valid_animation_timing("wallclock(1997-07-16T19:20:30+01:00)")) self.assertTrue(is_valid_animation_timing("wallclock(1997-07-16T19:20:30)")) self.assertTrue(is_valid_animation_timing("wallclock(1997-07-16T19:20)")) def test_invalid_value(self): self.assertFalse(is_valid_animation_timing("xyz")) self.assertFalse(is_valid_animation_timing("repeat(0")) self.assertFalse(is_valid_animation_timing("repeat0)")) self.assertFalse(is_valid_animation_timing("accessKeya)")) self.assertFalse(is_valid_animation_timing("accessKey(Z")) self.assertFalse(is_valid_animation_timing("001sec")) self.assertFalse(is_valid_animation_timing("wallclock(1997-07-16T19:2)")) self.assertFalse(is_valid_animation_timing("wallclock(1997-07-16T19:)")) self.assertFalse(is_valid_animation_timing("wallclock(1997-07-16T19)")) if __name__ == '__main__': unittest.main() svgwrite-1.1.8/tests/test_base_element.py0000666000000000000000000000533112314612177016731 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test BaseElement # Created: 18.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import sys import unittest from svgwrite.base import BaseElement from svgwrite.params import Parameter from svgwrite.utils import is_string class MockBase(BaseElement): elementname = 'svg' # necessary for validator _parameter = Parameter(True, 'full') class TestBaseElement(unittest.TestCase): def test_constructor_valid(self): # valid attributes m = MockBase(width=100, height=200) self.assertEqual(m['width'], 100) self.assertEqual(m['height'], 200) def test_trailing_underscore(self): m = MockBase(class_='test') self.assertEqual(m['class'], 'test') def test_inner_underscore(self): m = MockBase(stroke_width='1.0') self.assertEqual(m['stroke-width'], '1.0') def test_constructor_invalid(self): self.assertRaises(ValueError, MockBase, mozman=100) self.assertRaises(ValueError, MockBase, attribs={'mozman':100}) def test_tostring(self): # valid attributes m = MockBase(width=100, height=200) self.assertEqual(m.tostring(), '') def test_attribute_access(self): m = MockBase() m['id'] = 'test' self.assertEqual(m['id'], 'test') def test_get_funciri(self): m = MockBase() m['id'] = 'test' self.assertEqual(m.get_funciri(), "url(#test)") def test_copy(self): # valid attributes m = MockBase(width=100, height=200) m.add(MockBase(width=100, height=200)) copy = m.copy() m['width'] = 999 self.assertEqual(copy.tostring(), '') class TestValueToString(unittest.TestCase): def test_full_profile(self): element = MockBase() self.assertEqual(u'test', element.value_to_string('test')) self.assertEqual(u'süß', element.value_to_string('süß')) self.assertEqual(u'10', element.value_to_string(10)) def test_tiny_profile(self): element = MockBase() element.set_parameter(Parameter(True, 'tiny')) # value out of range self.assertRaises(TypeError, element.value_to_string, 100000) self.assertEqual('3.1416', element.value_to_string(3.141592)) def test_is_unicode(self): element = MockBase() self.assertTrue(is_string(element.value_to_string(10))) self.assertTrue(is_string(element.value_to_string('test'))) if __name__ == '__main__': unittest.main() svgwrite-1.1.8/tests/test_circle.py0000666000000000000000000000165712012650557015555 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test circle object # Created: 25.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import sys import unittest from svgwrite.shapes import Circle class TestCircle(unittest.TestCase): def test_numbers(self): circle = Circle(center=(0,0), r=2) self.assertEqual(circle.tostring(), '') def test_coordinates(self): circle = Circle(center=('1cm','1cm'), r='2mm') self.assertEqual(circle.tostring(), '') def test_errors(self): self.assertRaises(TypeError, Circle, center=1) self.assertRaises(TypeError, Circle, r=None) self.assertRaises(TypeError, Circle, center=None) self.assertRaises(TypeError, Circle, center=(None, None)) if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_clippath.py0000666000000000000000000000174312012650555016112 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test ClipPath # Created: 31.10.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import unittest from svgwrite.masking import ClipPath from svgwrite.shapes import Circle class TestClipPath(unittest.TestCase): def test_constructor(self): clip_path = ClipPath(debug=True, profile='full') self.assertEqual(clip_path.tostring(), '') def test_transform(self): clip_path = ClipPath(debug=True, profile='full') clip_path.translate(10, 20) self.assertEqual(clip_path.tostring(), '') def test_add_subelement(self): clip_path = ClipPath(debug=True, profile='full') clip_path.add(Circle((50,60), 70)) self.assertEqual(clip_path.tostring(), '') if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_clipping.py0000666000000000000000000000145012012650557016110 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test mixin Clipping # Created: 31.10.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import unittest from svgwrite.mixins import Clipping from svgwrite.base import BaseElement class SVGMock(BaseElement, Clipping): elementname = 'svg' class TestClipping(unittest.TestCase): def test_clip_rect_numbers(self): obj = SVGMock(debug=True) obj.clip_rect(1, 2, 3, 4) self.assertEqual(obj['clip'], 'rect(1,2,3,4)') def test_clip_rect_auto(self): obj = SVGMock(debug=True) obj.clip_rect('auto', 'auto', 'auto', 'auto') self.assertEqual(obj['clip'], 'rect(auto,auto,auto,auto)') if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_clock_val_parser.py0000666000000000000000000000452612311240260017607 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test clock_val_parser # Created: 03.11.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import sys import unittest import pyparsing as pp from svgwrite.data.svgparser import build_clock_val_parser from svgwrite.data.svgparser import build_wall_clock_val_parser class TestClockValParser(unittest.TestCase): clock_val_parser = build_clock_val_parser() def is_valid(self, value): try: self.clock_val_parser.parseString(value, parseAll=True) return True except pp.ParseException: return False def test_full_clock_values(self): self.assertTrue(self.is_valid("02:30:03")) self.assertTrue(self.is_valid("01:00:00")) self.assertTrue(self.is_valid("50:00:10.25")) def test_partial_clock_values(self): self.assertTrue(self.is_valid("02:33")) self.assertTrue(self.is_valid("00:10.5")) def test_time_count_values(self): self.assertTrue(self.is_valid("3.2h")) self.assertTrue(self.is_valid("45min")) self.assertTrue(self.is_valid("30s")) self.assertTrue(self.is_valid("5ms")) self.assertTrue(self.is_valid("12.467")) class TestWallClockValParser(unittest.TestCase): wallclock_parser = build_wall_clock_val_parser() def is_valid(self, value): try: self.wallclock_parser.parseString(value, parseAll=True) return True except pp.ParseException: return False def test_date_plus_hhmm(self): # Complete date plus hours and minutes: # YYYY-MM-DDThh:mmTZD (e.g. 1997-07-16T19:20+01:00) self.assertTrue(self.is_valid("1997-07-16T19:20+01:00")) def test_date_plus_hhmmss(self): # Complete date plus hours, minutes and seconds: # YYYY-MM-DDThh:mm:ssTZD (e.g. 1997-07-16T19:20:30+01:00) self.assertTrue(self.is_valid("1997-07-16T19:20:30+01:00")) def test_date_plus_hhmmss_frac(self): # Complete date plus hours, minutes, seconds and a decimal fraction of a second # YYYY-MM-DDThh:mm:ss.sTZD (e.g. 1997-07-16T19:20:30.45+01:00) self.assertTrue(self.is_valid("1997-07-16T19:20:30.45+01:00")) if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_defs.py0000666000000000000000000000160412012650555015223 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test defs element # Created: 25.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import sys import unittest from svgwrite.container import Group, Defs class TestDefs(unittest.TestCase): def test_constructor(self): defs = Defs() self.assertEqual(defs.tostring(), "") def test_add_subelement(self): defs = Defs(id='defs') group = Group(id='group') defs.add(group) self.assertEqual(defs.tostring(), '') def test_add_group(self): defs = Defs(id='defs') group = defs.add(Group(id='group')) # implicit call of add self.assertEqual(defs.tostring(), '') if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_description.py0000666000000000000000000000526312012650555016632 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test Description mixin # Created: 04.11.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import unittest import xml.etree.ElementTree as etree from svgwrite.base import BaseElement class Mock(BaseElement): elementname = 'g' class TestDescription(unittest.TestCase): def test_title(self): m = Mock() m.set_desc(title="TEST") self.assertEqual(m.tostring(), 'TEST') def test_desc(self): m = Mock() m.set_desc(desc="TEST") self.assertEqual(m.tostring(), 'TEST') def test_insert(self): # insert 'desc# and 'title' always as first subelement m = Mock() m.add(Mock()) # inner 'g' m.set_desc(desc="TEST") self.assertEqual(m.tostring(), 'TEST') m.set_desc("TITLE") self.assertEqual(m.tostring(), 'TITLETEST') def get_test_data(): rdf = etree.Element('rdf:RDF', attrib={'xmlns:rdf': 'http://test/rdf'}) rdf.append(etree.Element('rdf:Description')) return rdf class TestMetaData(unittest.TestCase): def test_metadata_only(self): m = Mock() m.set_metadata(get_test_data()) self.assertEqual(m.tostring(), '' \ '') def test_metadata_insert_after_title(self): m = Mock() m.set_desc('TITLE') m.set_metadata(get_test_data()) self.assertEqual(m.tostring(), 'TITLE'\ ''\ '') def test_metadata_insert_before_others(self): m = Mock() m.add(Mock()) m.add(Mock()) m.set_metadata(get_test_data()) self.assertEqual(m.tostring(), ''\ '') def test_metadata_insert_between_title_and_g(self): m = Mock() m.add(Mock()) m.add(Mock()) m.set_desc('TITLE', 'DESC') m.set_metadata(get_test_data()) self.assertEqual(m.tostring(), 'TITLEDESC' \ ''\ '') if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_drawing.py0000666000000000000000000001113512157476524015751 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test drawing module # Created: 11.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License from __future__ import unicode_literals import os import unittest from io import StringIO from svgwrite.drawing import Drawing from svgwrite.container import Group class TestDrawingFullProfile(unittest.TestCase): def test_empty_drawing(self): dwg = Drawing() result = dwg.tostring() self.assertEqual(result, '') def test_stylesheet(self): dwg = Drawing() dwg.add_stylesheet('test.css', 'Test') f = StringIO() dwg.write(f) result = f.getvalue() f.close() self.assertEqual(result, '\n' '\n' '') def test_save(self): fn = 'test_drawing.svg' if os.path.exists(fn): os.remove(fn) dwg = Drawing(fn) dwg.save() self.assertTrue(os.path.exists(fn)) os.remove(fn) def test_save_as(self): fn = 'test_drawing.svg' if os.path.exists(fn): os.remove(fn) dwg = Drawing() dwg.saveas(fn) self.assertTrue(os.path.exists(fn)) os.remove(fn) def test_non_us_ascii_chars(self): dwg = Drawing() dwg.set_desc('öäü') f = StringIO() dwg.write(f) result = f.getvalue() f.close() self.assertEqual(result, '\n' '' 'öäü') class TestDrawingTinyProfile(unittest.TestCase): def test_empty_drawing(self): dwg = Drawing(profile="tiny") result = dwg.tostring() self.assertEqual(result, '') def test_stylesheet(self): dwg = Drawing(profile="tiny") dwg.add_stylesheet('test.css', 'Test') f = StringIO() dwg.write(f) result = f.getvalue() f.close() self.assertEqual(result, '\n' '\n' '') class TestDefs(unittest.TestCase): def test_simple_defs(self): dwg = Drawing() g = dwg.defs.add(Group(id='test')) inner_g = g.add(Group(id='innerTest')) result = dwg.tostring() self.assertEqual(result, '' '') if __name__ == '__main__': unittest.main() svgwrite-1.1.8/tests/test_elementfactory.py0000666000000000000000000000456512012650554017333 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test elementfactory # Created: 15.10.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import sys import unittest from svgwrite.elementfactory import ElementFactory from svgwrite.params import Parameter class MockFactory(ElementFactory): _parameter = Parameter(debug=True, profile='full') debug = True profile = 'full' class TestElementFactory(unittest.TestCase): def setUp(self): self.factory = MockFactory() def test_g(self): group = self.factory.g(id='test') self.assertEqual(group.elementname, 'g') self.assertEqual(group['id'], 'test') def test_svg(self): svg = self.factory.svg() self.assertEqual(svg.elementname, 'svg') def test_defs(self): defs = self.factory.defs() self.assertEqual(defs.elementname, 'defs') def test_symbol(self): element = self.factory.symbol() self.assertEqual(element.elementname, 'symbol') def test_use(self): element = self.factory.use('link') self.assertEqual(element.elementname, 'use') def test_a(self): element = self.factory.a('link') self.assertEqual(element.elementname, 'a') def test_line(self): element = self.factory.line((0,0), (1,1)) self.assertEqual(element.elementname, 'line') def test_rect(self): element = self.factory.rect((0,0), (1,1)) self.assertEqual(element.elementname, 'rect') def test_circle(self): element = self.factory.circle((0,0), 5) self.assertEqual(element.elementname, 'circle') def test_ellipse(self): element = self.factory.ellipse((0,0), (5, 5)) self.assertEqual(element.elementname, 'ellipse') def test_polygon(self): element = self.factory.polygon([(0, 0), (5, 5)]) self.assertEqual(element.elementname, 'polygon') def test_polyline(self): element = self.factory.polyline([(0, 0), (5, 5)]) self.assertEqual(element.elementname, 'polyline') def test_AttributeError(self): try: self.factory.test() self.fail('AttributeError not raised.') except AttributeError: self.assertTrue(True) if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_ellipse.py0000666000000000000000000000212012012650555015731 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test ellipse object # Created: 25.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import sys import unittest from svgwrite.shapes import Ellipse class TestEllipse(unittest.TestCase): def test_numbers(self): ellipse = Ellipse(center=(0,0), r=(2,1)) self.assertEqual(ellipse.tostring(), '') def test_coordinates(self): ellipse = Ellipse(center=('1cm','1cm'), r=('2mm', '1mm')) self.assertEqual(ellipse.tostring(), '') def test_errors(self): self.assertRaises(TypeError, Ellipse, center=1) self.assertRaises(TypeError, Ellipse, center=None) self.assertRaises(TypeError, Ellipse, center=(None, None)) self.assertRaises(TypeError, Ellipse, r=1) self.assertRaises(TypeError, Ellipse, r=None) self.assertRaises(TypeError, Ellipse, r=(None, None)) if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_filters.py0000666000000000000000000004321712321664113015756 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test filters module # Created: 04.11.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import unittest from svgwrite import filters class TestFilter(unittest.TestCase): def test_constructor(self): f = filters.Filter(profile='full', debug=True) self.assertEqual(f.tostring(), '') def test_constructor_params(self): f = filters.Filter(start=(10,20), size=(30,40), inherit='#test', profile='full', debug=True) self.assertEqual(f.tostring(), '') def test_filterRes(self): f = filters.Filter(resolution=300, profile='full', debug=True) self.assertEqual(f.tostring(), '') f = filters.Filter(resolution=(300, 400), profile='full', debug=True) self.assertEqual(f.tostring(), '') f = filters.Filter(resolution="300 400", profile='full', debug=True) self.assertEqual(f.tostring(), '') class MockFRI(filters._FilterRequireInput): elementname = 'feBlend' class TestFilterRequireInput(unittest.TestCase): def test_constructor(self): f = MockFRI('input') self.assertEqual(f.tostring(), '') def test_constructor_with_all_params(self): f = MockFRI('input', start=(10, 20), size=(30, 40), result='output') self.assertEqual(f.tostring(), '') class Test_feBlend(unittest.TestCase): def test_constructor(self): f = filters.Filter() f.feBlend('input1', in2='input2', mode='normal') self.assertEqual(f.tostring(), '') class Test_feColorMatrix(unittest.TestCase): def test_constructor(self): f = filters.Filter() f.feColorMatrix('input1', type_='matrix', values='0 0 0') self.assertEqual(f.tostring(), '') class Test_feComponentTransfer(unittest.TestCase): def test_constructor(self): f = filters.Filter() f.feComponentTransfer('input1') self.assertEqual(f.tostring(), '') def test_add_FuncR(self): f = filters.Filter() fct = f.feComponentTransfer('input1') func = fct.feFuncR('identity') self.assertEqual(fct.tostring(), '') self.assertEqual(func.tostring(), '') def test_add_FuncG(self): f = filters.Filter() fct = f.feComponentTransfer('input1') func = fct.feFuncG('table') self.assertEqual(func.tostring(), '') def test_add_FuncB(self): f = filters.Filter() fct = f.feComponentTransfer('input1') func = fct.feFuncB('discrete') self.assertEqual(func.tostring(), '') def test_add_FuncA(self): f = filters.Filter() fct = f.feComponentTransfer('input1') func = fct.feFuncA('gamma') self.assertEqual(func.tostring(), '') def test_FuncR_all_params(self): f = filters.Filter() fct = f.feComponentTransfer('input1') func = fct.feFuncR('identity', tableValues="1,2", slope=1, intercept=0, amplitude=0, exponent=1, offset=0) self.assertEqual(func.tostring(), '') class Test_feComposite(unittest.TestCase): def test_constructor(self): f = filters.Filter() pf = f.feComposite('input1', in2='input2') self.assertEqual(pf.tostring(), '') def test_operator(self): f = filters.Filter() self.assertEqual(f.feComposite('input1', operator='over').tostring(), '') self.assertEqual(f.feComposite('input1', operator='in').tostring(), '') self.assertEqual(f.feComposite('input1', operator='out').tostring(), '') self.assertEqual(f.feComposite('input1', operator='xor').tostring(), '') self.assertEqual(f.feComposite('input1', operator='arithmetic').tostring(), '') def test_k1k2k3k4(self): f = filters.Filter() pf = f.feComposite('input1', k1=1, k2=2, k3=3, k4=4) self.assertEqual(pf.tostring(), '') class Test_feConvolveMatrix(unittest.TestCase): def test_constructor(self): f = filters.Filter() pf = f.feConvolveMatrix('input1') self.assertEqual(pf.tostring(), '') def test_order(self): f = filters.Filter() pf = f.feConvolveMatrix('input1', order='1 2') self.assertEqual(pf.tostring(), '') def test_kernelMatrix(self): f = filters.Filter() pf = f.feConvolveMatrix('input1', kernelMatrix='1 2 3 4') self.assertEqual(pf.tostring(), '') def test_divisor_and_bias(self): f = filters.Filter() pf = f.feConvolveMatrix('input1', divisor=2.5, bias=0.5) self.assertEqual(pf.tostring(), '') def test_targetX_and_targetY(self): f = filters.Filter() pf = f.feConvolveMatrix('input1', targetX=1, targetY=2) self.assertEqual(pf.tostring(), '') def test_edgeMode(self): f = filters.Filter() self.assertEqual(f.feConvolveMatrix('input1', edgeMode='duplicate').tostring(), '') self.assertEqual(f.feConvolveMatrix('input1', edgeMode='wrap').tostring(), '') self.assertEqual(f.feConvolveMatrix('input1', edgeMode='none').tostring(), '') def test_preserveAlpha(self): f = filters.Filter() self.assertEqual(f.feConvolveMatrix('input1', preserveAlpha='true').tostring(), '') self.assertEqual(f.feConvolveMatrix('input1', preserveAlpha='false').tostring(), '') def test_kernelUnitLength(self): f = filters.Filter() self.assertEqual(f.feConvolveMatrix('input1', kernelUnitLength=2).tostring(), '') class Test_feDiffuseLighting(unittest.TestCase): def test_constructor(self): f = filters.Filter() self.assertEqual(f.feDiffuseLighting('input1').tostring(), '') def test_surfaceScale(self): f = filters.Filter() self.assertEqual(f.feDiffuseLighting('input1', surfaceScale=1).tostring(), '') def test_diffuseConstant(self): f = filters.Filter() self.assertEqual(f.feDiffuseLighting('input1', diffuseConstant=1).tostring(), '') def test_kernelUnitLength(self): f = filters.Filter() self.assertEqual(f.feDiffuseLighting('input1', kernelUnitLength=2).tostring(), '') def test_lighting_color(self): f = filters.Filter() self.assertEqual(f.feDiffuseLighting('input1', lighting_color='yellow').tostring(), '') class Test_feDisplacementMap(unittest.TestCase): def test_constructor(self): f = filters.Filter() self.assertEqual(f.feDisplacementMap('input1', in2="input2").tostring(), '') def test_scale(self): f = filters.Filter() self.assertEqual(f.feDisplacementMap('input1', scale=2).tostring(), '') def test_xChannelSelector_yChannelSelector(self): f = filters.Filter() self.assertEqual(f.feDisplacementMap('input1', xChannelSelector="R", yChannelSelector="G").tostring(), '') class Test_feFlood(unittest.TestCase): def test_constructor(self): f = filters.Filter() self.assertEqual(f.feFlood().tostring(), '') def test_flood_color(self): f = filters.Filter() self.assertEqual(f.feFlood(flood_color="red").tostring(), '') def test_flood_opacity(self): f = filters.Filter() self.assertEqual(f.feFlood(flood_opacity=0.5).tostring(), '') class Test_feGaussianBlur(unittest.TestCase): def test_constructor(self): f = filters.Filter() self.assertEqual(f.feGaussianBlur("input1").tostring(), '') def test_stdDeviation(self): f = filters.Filter() self.assertEqual(f.feGaussianBlur("input1", stdDeviation="1 2").tostring(), '') class Test_feImage(unittest.TestCase): def test_constructor(self): f = filters.Filter() self.assertEqual(f.feImage("./image.png").tostring(), '') class Test_feMerge(unittest.TestCase): def test_constructor(self): f = filters.Filter() self.assertEqual(f.feMerge(['Layer1', 'Layer2']).tostring(), '') def test_layers(self): f = filters.Filter() merge = f.feMerge(['Layer1', 'Layer2']) merge.feMergeNode(('Layer3', )) self.assertEqual(merge.tostring(), '' '') class Test_feMorphology(unittest.TestCase): def test_constructor(self): f = filters.Filter() self.assertEqual(f.feMorphology("input1").tostring(), '') def test_operator(self): f = filters.Filter() self.assertEqual(f.feMorphology("input1", operator="erode").tostring(), '') self.assertEqual(f.feMorphology("input1", operator="dilate").tostring(), '') def test_radius(self): f = filters.Filter() self.assertEqual(f.feMorphology("input1", radius="1,2").tostring(), '') class Test_feOffset(unittest.TestCase): def test_constructor(self): f = filters.Filter() self.assertEqual(f.feOffset("input1").tostring(), '') def test_dx_dy(self): f = filters.Filter() self.assertEqual(f.feOffset("input1", dx=10, dy=20).tostring(), '') class Test_feSpecularLighting(unittest.TestCase): def test_constructor(self): f = filters.Filter() self.assertEqual(f.feSpecularLighting("input1").tostring(), '') def test_surfaceScale(self): f = filters.Filter() self.assertEqual(f.feSpecularLighting("input1", surfaceScale=7).tostring(), '') def test_specularExponent(self): f = filters.Filter() self.assertEqual(f.feSpecularLighting("input1", specularExponent=7).tostring(), '') def test_kernelUnitLength(self): f = filters.Filter() self.assertEqual(f.feSpecularLighting("input1", kernelUnitLength="1,2").tostring(), '') def test_lighting_color(self): f = filters.Filter() self.assertEqual(f.feSpecularLighting('input1', lighting_color='yellow').tostring(), '') class Test_feTile(unittest.TestCase): def test_constructor(self): f = filters.Filter() self.assertEqual(f.feTile("input1").tostring(), '') class Test_feTurbulence(unittest.TestCase): def test_constructor(self): f = filters.Filter() self.assertEqual(f.feTurbulence().tostring(), '') def test_baseFrequency(self): f = filters.Filter() self.assertEqual(f.feTurbulence(baseFrequency="1,2").tostring(), '') def test_numOctaves(self): f = filters.Filter() self.assertEqual(f.feTurbulence(numOctaves="1").tostring(), '') def test_seed(self): f = filters.Filter() self.assertEqual(f.feTurbulence(seed="1").tostring(), '') def test_stitchTiles(self): f = filters.Filter() self.assertEqual(f.feTurbulence(stitchTiles="stitch").tostring(), '') def test_type(self): f = filters.Filter() self.assertEqual(f.feTurbulence(type_="fractalNoise").tostring(), '') self.assertEqual(f.feTurbulence(type_="turbulence").tostring(), '') class TestDistantLight(unittest.TestCase): def test_constructor(self): f = filters.Filter() fp = f.feDiffuseLighting('input1') ls = fp.feDistantLight() self.assertEqual(ls.tostring(), '') self.assertEqual(fp.tostring(), '') self.assertEqual(f.tostring(), '') def test_all_parmeters(self): f = filters.Filter() ls = f.feDiffuseLighting('input1').feDistantLight(1, 2) self.assertEqual(ls.tostring(), '') class TestPointLight(unittest.TestCase): def test_constructor(self): f = filters.Filter() fp = f.feDiffuseLighting('input1') ls = fp.fePointLight() self.assertEqual(ls.tostring(), '') self.assertEqual(fp.tostring(), '') self.assertEqual(f.tostring(), '') def test_all_parmeters(self): f = filters.Filter() ls = f.feDiffuseLighting('input1').fePointLight(source=(1,2,3)) self.assertEqual(ls.tostring(), '') class TestSpotLight(unittest.TestCase): def test_constructor(self): f = filters.Filter() fp = f.feDiffuseLighting('input1') ls = fp.feSpotLight() self.assertEqual(ls.tostring(), '') self.assertEqual(fp.tostring(), '') self.assertEqual(f.tostring(), '') def test_all_parmeters(self): f = filters.Filter() ls = f.feDiffuseLighting('input1').feSpotLight(source=(1, 2, 3), target=(4, 5, 6), specularExponent=2, limitingConeAngle=15) self.assertEqual(ls.tostring(), '') if __name__ == '__main__': unittest.main() svgwrite-1.1.8/tests/test_full11_typechecker.py0000666000000000000000000004374512720244343020010 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test full11typechecker # Created: 04.10.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import unittest from svgwrite.data.typechecker import Full11TypeChecker class TestFull11TypeChecker(unittest.TestCase): def setUp(self): self.checker = Full11TypeChecker() def test_version(self): self.assertEqual(('1.1', 'full'), self.checker.get_version()) def test_is_anything(self): """ Everything is valid. """ self.assertTrue(self.checker.is_anything('abcdef :::\n \r \t all is valid äüß')) self.assertTrue(self.checker.is_anything(100.0)) self.assertTrue(self.checker.is_anything((100.0, 11))) self.assertTrue(self.checker.is_anything(dict(a=100, b=200))) def test_is_string(self): """ Everything is valid. """ self.assertTrue(self.checker.is_anything('abcdef :::\n \r \t all is valid äüß')) self.assertTrue(self.checker.is_anything(100.0)) self.assertTrue(self.checker.is_anything((100.0, 11))) self.assertTrue(self.checker.is_anything(dict(a=100, b=200))) self.assertTrue(self.checker.is_anything(u'äüß'.encode('utf-8'))) def test_is_number(self): """ Integer and Float, also as String '100' or '3.1415'. """ # big numbers only valid for full profile self.assertTrue(self.checker.is_number(100000)) self.assertTrue(self.checker.is_number(-100000)) self.assertTrue(self.checker.is_number(3.141592)) self.assertTrue(self.checker.is_number('100000')) self.assertTrue(self.checker.is_number('-100000')) self.assertTrue(self.checker.is_number('3.141592')) def test_is_not_number(self): self.assertFalse(self.checker.is_number( (1,2) )) self.assertFalse(self.checker.is_number('manfred')) self.assertFalse(self.checker.is_number( dict(a=1, b=2) )) def test_is_name(self): self.assertTrue(self.checker.is_name('mozman-öäüß')) self.assertTrue(self.checker.is_name('mozman:mozman')) self.assertTrue(self.checker.is_name('mozman:mozman[2]')) # not only strings allowed self.assertTrue(self.checker.is_name(100)) self.assertTrue(self.checker.is_name(100.123)) def test_is_not_name(self): self.assertFalse(self.checker.is_name('')) self.assertFalse(self.checker.is_name('mozman,mozman[2]')) self.assertFalse(self.checker.is_name('mozman mozman[2]')) self.assertFalse(self.checker.is_name('mozman(mozman)[2]')) # tuple and dict contains ',', '(', ')' or ' ' self.assertFalse(self.checker.is_name((100, 200))) self.assertFalse(self.checker.is_name(dict(a=100, b=200))) def test_is_length(self): for value in [' 100px ', ' -100ex ', ' 100em ', ' -100pt ', ' 100pc ', ' 100mm', ' 100cm', ' 100in', ' 5%', 100, 3.1415, 700000, -500000, '100000', '-4000000.45']: self.assertTrue(self.checker.is_length(value)) def test_is_not_length(self): for value in [' 100xpx ', ' -100km ', ' 100mi ', (1, 1), dict(a=1, b=2), [1, 2], ' mozman ']: self.assertFalse(self.checker.is_length(value)) def test_is_integer(self): """ Integer also as String '100'. """ # big numbers only valid for full profile self.assertTrue(self.checker.is_integer(100000)) self.assertTrue(self.checker.is_integer(-100000)) self.assertTrue(self.checker.is_integer('100000')) self.assertTrue(self.checker.is_integer('-100000')) def test_is_not_integer(self): self.assertFalse(self.checker.is_integer( (1,2) )) self.assertFalse(self.checker.is_integer('manfred')) self.assertFalse(self.checker.is_integer( dict(a=1, b=2) )) self.assertFalse(self.checker.is_integer(3.141592)) self.assertFalse(self.checker.is_integer('3.141592')) def test_is_percentage(self): self.assertTrue(self.checker.is_percentage(100)) self.assertTrue(self.checker.is_percentage(50.123)) self.assertTrue(self.checker.is_percentage(1000)) self.assertTrue(self.checker.is_percentage('100')) self.assertTrue(self.checker.is_percentage('50.123')) self.assertTrue(self.checker.is_percentage('1000')) self.assertTrue(self.checker.is_percentage(' 100% ')) self.assertTrue(self.checker.is_percentage(' 50.123% ')) self.assertTrue(self.checker.is_percentage(' 1000% ')) def test_is_not_percentage(self): self.assertFalse(self.checker.is_percentage('100px')) self.assertFalse(self.checker.is_percentage('100cm')) self.assertFalse(self.checker.is_percentage(' mozman ')) self.assertFalse(self.checker.is_percentage( (1, 2) )) self.assertFalse(self.checker.is_percentage( dict(a=1, b=2) )) def test_is_time(self): self.assertTrue(self.checker.is_time(100)) self.assertTrue(self.checker.is_time(50.123)) self.assertTrue(self.checker.is_time(1000)) self.assertTrue(self.checker.is_time(' 100 ')) self.assertTrue(self.checker.is_time(' 50.123 ')) self.assertTrue(self.checker.is_time(' 1000 ')) self.assertTrue(self.checker.is_time(' 100ms')) self.assertTrue(self.checker.is_time(' 50.123s')) self.assertTrue(self.checker.is_time(' 1000ms')) def test_is_not_time(self): self.assertFalse(self.checker.is_time('100px')) self.assertFalse(self.checker.is_time('100cm')) self.assertFalse(self.checker.is_time(' mozman ')) self.assertFalse(self.checker.is_time( (1, 2) )) self.assertFalse(self.checker.is_time( dict(a=1, b=2) )) def test_is_angle(self): self.assertTrue(self.checker.is_angle(100)) self.assertTrue(self.checker.is_angle(50.123)) self.assertTrue(self.checker.is_angle(1000)) self.assertTrue(self.checker.is_angle(' 100 ')) self.assertTrue(self.checker.is_angle(' 50.123 ')) self.assertTrue(self.checker.is_angle(' 1000 ')) self.assertTrue(self.checker.is_angle(' 100rad')) self.assertTrue(self.checker.is_angle(' 50.123grad')) self.assertTrue(self.checker.is_angle(' 1000deg')) def test_is_not_angle(self): self.assertFalse(self.checker.is_angle('100px')) self.assertFalse(self.checker.is_angle('100cm')) self.assertFalse(self.checker.is_angle(' mozman ')) self.assertFalse(self.checker.is_angle( (1, 2) )) self.assertFalse(self.checker.is_angle( dict(a=1, b=2) )) def test_is_frequency(self): self.assertTrue(self.checker.is_frequency(100)) self.assertTrue(self.checker.is_frequency(50.123)) self.assertTrue(self.checker.is_frequency(1000)) self.assertTrue(self.checker.is_frequency(' 100 ')) self.assertTrue(self.checker.is_frequency(' 50.123 ')) self.assertTrue(self.checker.is_frequency(' 1000 ')) self.assertTrue(self.checker.is_frequency(' 100Hz')) self.assertTrue(self.checker.is_frequency(' 50.123kHz')) self.assertTrue(self.checker.is_frequency(' 1000Hz')) def test_is_not_frequency(self): self.assertFalse(self.checker.is_frequency('100px')) self.assertFalse(self.checker.is_frequency('100cm')) self.assertFalse(self.checker.is_frequency(' mozman ')) self.assertFalse(self.checker.is_frequency( (1, 2) )) self.assertFalse(self.checker.is_frequency( dict(a=1, b=2) )) def test_is_shape(self): self.assertTrue(self.checker.is_shape(' rect(1, 2, 3, 4)')) self.assertTrue(self.checker.is_shape(' rect(1cm, 2mm, -3px, 4%)')) def test_is_not_shape(self): self.assertFalse(self.checker.is_shape('rect(1, 2, 3)')) self.assertFalse(self.checker.is_shape('rect(1, 2, 3, 4, 5)')) self.assertFalse(self.checker.is_shape('rect(1, 2, 3, m)')) def test_is_number_optional_number(self): self.assertTrue(self.checker.is_number_optional_number(' 1, 2')) self.assertTrue(self.checker.is_number_optional_number('1 2. ')) self.assertTrue(self.checker.is_number_optional_number('1 ')) self.assertTrue(self.checker.is_number_optional_number(' 1.5 ')) self.assertTrue(self.checker.is_number_optional_number( 1 )) self.assertTrue(self.checker.is_number_optional_number( [1, 2] )) def test_is_not_number_optional_number(self): self.assertFalse(self.checker.is_number_optional_number(' 1px, 2')) self.assertFalse(self.checker.is_number_optional_number('')) self.assertFalse(self.checker.is_number_optional_number(' , 2')) self.assertFalse(self.checker.is_number_optional_number(' 1 , 2 , 3')) self.assertFalse(self.checker.is_number_optional_number(' 1. 2. 3.')) self.assertFalse(self.checker.is_number_optional_number(' 1 2 3')) self.assertFalse(self.checker.is_number_optional_number([])) self.assertFalse(self.checker.is_number_optional_number([1,2,3])) self.assertFalse(self.checker.is_number_optional_number([1, '1px'])) def test_is_IRI(self): # every none empty string is valid - no real url validation is done self.assertTrue(self.checker.is_IRI("http://localhost:8080?a=12")) self.assertTrue(self.checker.is_IRI("%&/(/&%$")) def test_is_not_IRI(self): self.assertFalse(self.checker.is_IRI("")) self.assertFalse(self.checker.is_IRI(1)) self.assertFalse(self.checker.is_IRI(3.1415)) self.assertFalse(self.checker.is_IRI( (1, 0))) self.assertFalse(self.checker.is_IRI(dict(a=1))) def test_is_FuncIRI(self): self.assertTrue(self.checker.is_FuncIRI("url(http://localhost:8080?a=12)")) self.assertTrue(self.checker.is_FuncIRI("url(ftp://something/234)")) def test_is_not_FuncIRI(self): self.assertFalse(self.checker.is_FuncIRI("url()")) self.assertFalse(self.checker.is_FuncIRI("url")) self.assertFalse(self.checker.is_FuncIRI("url(")) self.assertFalse(self.checker.is_FuncIRI("url(http://localhost:8080")) self.assertFalse(self.checker.is_FuncIRI("http://localhost:8080")) def test_is_semicolon_list(self): self.assertTrue(self.checker.is_semicolon_list("1;2;3;4;5")) self.assertTrue(self.checker.is_semicolon_list("1;2,3;4,5")) self.assertTrue(self.checker.is_semicolon_list("1.;2.,3.;4.,5.")) self.assertTrue(self.checker.is_semicolon_list("1")) self.assertTrue(self.checker.is_semicolon_list("1 2;3;4;5")) def test_is_not_semicolon_list(self): # only numbers! self.assertFalse(self.checker.is_semicolon_list("1 A;3 4;5,Z")) self.assertFalse(self.checker.is_semicolon_list("")) def test_is_icc_color(self): self.assertTrue(self.checker.is_icccolor("icc-color(red)")) self.assertTrue(self.checker.is_icccolor("icc-color(red mozman)")) self.assertTrue(self.checker.is_icccolor("icc-color(red,mozman)")) self.assertTrue(self.checker.is_icccolor("icc-color(red,mozman 123)")) def test_is_not_icc_color(self): self.assertFalse(self.checker.is_icccolor("icc-color()")) self.assertFalse(self.checker.is_icccolor("icc-color((a))")) def test_is_hex_color(self): self.assertTrue(self.checker.is_color("#101010")) self.assertTrue(self.checker.is_color("#111")) self.assertTrue(self.checker.is_color("#FFFFFF")) self.assertTrue(self.checker.is_color("#FFF")) self.assertTrue(self.checker.is_color("#aaaaaa")) self.assertTrue(self.checker.is_color("#aaa")) def test_is_not_hex_color(self): self.assertFalse(self.checker.is_color("#1")) self.assertFalse(self.checker.is_color("#22")) self.assertFalse(self.checker.is_color("#4444")) self.assertFalse(self.checker.is_color("#55555")) self.assertFalse(self.checker.is_color("#7777777")) self.assertFalse(self.checker.is_color("#gghhii")) def test_is_rgb_int_color(self): self.assertTrue(self.checker.is_color("rgb(1,2,3)")) self.assertTrue(self.checker.is_color("rgb( 1, 2, 3 )")) self.assertTrue(self.checker.is_color("rgb( 11, 21, 31 )")) self.assertTrue(self.checker.is_color("rgb( 0, 0, 0 )")) self.assertTrue(self.checker.is_color("rgb( 255 , 255 , 255 )")) def test_is_not_rgb_int_color(self): self.assertFalse(self.checker.is_color("rgb(,2,3)")) self.assertFalse(self.checker.is_color("rgb(1,,3)")) self.assertFalse(self.checker.is_color("rgb(1,2)")) self.assertFalse(self.checker.is_color("rgb(1)")) self.assertFalse(self.checker.is_color("rgb(a,2,3)")) self.assertFalse(self.checker.is_color("rgb()")) def test_is_rgb_percentage_color(self): self.assertTrue(self.checker.is_color("rgb(1%,2%,3%)")) self.assertTrue(self.checker.is_color("rgb( 1%, 2%, 3% )")) self.assertTrue(self.checker.is_color("rgb( 11%, 21%, 31% )")) self.assertTrue(self.checker.is_color("rgb( 0%, 0%, 0% )")) # this is not really valid self.assertTrue(self.checker.is_color("rgb( 255% , 255% , 255% )")) def test_is_not_rgb_percentage_color(self): self.assertFalse(self.checker.is_color("rgb()")) self.assertFalse(self.checker.is_color("rgb(1,2%,3%)")) self.assertFalse(self.checker.is_color("rgb(,2%,3%)")) self.assertFalse(self.checker.is_color("rgb(,,)")) self.assertFalse(self.checker.is_color("rgb(a%,b%,c%)")) # decimals allowed self.assertTrue(self.checker.is_color("rgb(1.0%, 2.0%, 3.0%)")) def test_is_color_name(self): self.assertTrue(self.checker.is_color("blue")) def test_is_not_color_name(self): self.assertFalse(self.checker.is_color("blau")) def test_is_paint_with_funcIRI(self): self.assertTrue(self.checker.is_paint("rgb(10, 20, 30)")) def test_is_paint_with_funcIRI_2(self): self.assertTrue(self.checker.is_paint("rgb(10, 20, 30) none")) def test_is_paint_with_funcIRI_3(self): self.assertTrue(self.checker.is_paint("url(localhost) rgb(10, 20, 30)")) def test_is_paint(self): self.assertTrue(self.checker.is_paint("inherit")) self.assertTrue(self.checker.is_paint("none")) self.assertTrue(self.checker.is_paint("currentColor")) self.assertTrue(self.checker.is_paint("rgb(10,20,30)")) self.assertTrue(self.checker.is_paint("rgb(10%,20%,30%)")) self.assertTrue(self.checker.is_paint("url(localhost)")) self.assertTrue(self.checker.is_paint("red")) def test_is_not_paint(self): self.assertFalse(self.checker.is_paint("(123)")) self.assertFalse(self.checker.is_paint("123")) self.assertFalse(self.checker.is_paint("schwarz")) def test_is_XML_name(self): self.assertTrue(self.checker.is_XML_Name("Name:xml123")) self.assertTrue(self.checker.is_XML_Name("Name-xml123")) self.assertTrue(self.checker.is_XML_Name("Name.xml123")) def test_is_not_XML_name(self): self.assertFalse(self.checker.is_XML_Name("Name xml123")) self.assertFalse(self.checker.is_XML_Name("0Name:xml123")) self.assertFalse(self.checker.is_XML_Name(".Name:xml123")) def test_is_transform_list(self): self.assertTrue(self.checker.is_transform_list("translate(10,10)")) self.assertTrue(self.checker.is_transform_list("scale(2 2)")) self.assertTrue(self.checker.is_transform_list("rotate( 30 )")) self.assertTrue(self.checker.is_transform_list("skewX(15)")) self.assertTrue(self.checker.is_transform_list("skewY(-15)")) self.assertTrue(self.checker.is_transform_list("matrix(.1 .2 .3 .4 .5 .6)")) self.assertTrue(self.checker.is_transform_list("translate(10,10), rotate( 30 )")) self.assertTrue(self.checker.is_transform_list("translate(10,10) , rotate( 30 )")) self.assertTrue(self.checker.is_transform_list("translate(10,10) , rotate( 30 )")) self.assertTrue(self.checker.is_transform_list("translate(10,10) rotate( 30 )")) def test_is_not_transform_list(self): self.assertFalse(self.checker.is_transform_list("mozman(10,10)")) self.assertFalse(self.checker.is_transform_list("translate(10,10")) self.assertFalse(self.checker.is_transform_list("translate 10, 10")) self.assertFalse(self.checker.is_transform_list("translate(10, 10))")) self.assertFalse(self.checker.is_transform_list("translate((10, 10))")) def test_is_not_transform_list_invalid_separator(self): self.assertFalse(self.checker.is_transform_list("translate(10,10) ,, rotate( 30 )")) self.assertFalse(self.checker.is_transform_list("translate(10,10) x rotate( 30 )")) def test_is_four_numbers(self): self.assertTrue(self.checker.is_four_numbers(' 1, 2, 3, 4 ')) self.assertTrue(self.checker.is_four_numbers(' 1 2 3 4 ')) self.assertTrue(self.checker.is_four_numbers((1,2,3,4))) def test_is_not_four_numbers(self): self.assertFalse(self.checker.is_four_numbers(' 1, 2, 3, ')) self.assertFalse(self.checker.is_four_numbers(' 1, 2 ')) self.assertFalse(self.checker.is_four_numbers(' 1 ')) self.assertFalse(self.checker.is_four_numbers((1,2,3))) def test_is_shape(self): self.assertTrue(self.checker.is_shape("rect(1,2,3,4)")) self.assertTrue(self.checker.is_shape("rect(1px,2px,-3px,-4px)")) self.assertTrue(self.checker.is_shape("rect( 1px , 2px , -3px , -4px )")) self.assertTrue(self.checker.is_shape("rect(auto,auto,auto,auto)")) self.assertTrue(self.checker.is_shape("rect( auto , auto , auto , auto )")) if __name__=='__main__' : unittest.main() svgwrite-1.1.8/tests/test_gradients.py0000666000000000000000000000666312012650556016275 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test gradients module # Created: 26.10.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import unittest import re from svgwrite.gradients import _GradientStop, LinearGradient, RadialGradient class TestGradientStop(unittest.TestCase): def test_constructor1(self): stop = _GradientStop(offset=0.5, color='red', opacity=1.0, debug=True, profile='full') self.assertEqual(stop.tostring(), '') def test_constructor2(self): stop = _GradientStop(offset='50%', color='red', opacity=0.63, debug=True, profile='full') self.assertEqual(stop.tostring(), '') def test_constructor3(self): stop = _GradientStop(debug=True, profile='full') self.assertEqual(stop.tostring(), '') class TestLinearGradient(unittest.TestCase): def test_constructor(self): lg = LinearGradient(start=(1, 2), end=(10, 20), inherit='#test', debug=True, profile='full') self.assertEqual( '', lg.tostring()) def test_get_paint_server(self): lg = LinearGradient() self.assertTrue(re.match("^url\(#id\d+\) none$", lg.get_paint_server())) self.assertTrue(re.match("^url\(#id\d+\) red$", lg.get_paint_server(default='red'))) def test_add_stop_color(self): lg = LinearGradient() lg.add_stop_color(offset=0.5, color='red', opacity=1.0) self.assertEqual(lg.tostring(), '') def test_add_colors(self): lg = LinearGradient() lg.add_colors(['white', 'red', 'blue', 'green'], opacity=0.5) result = '' \ '' \ '' \ '' \ '' \ '' self.assertEqual(lg.tostring(), result) def test_inherit(self): inherit_from = LinearGradient(id='test') lg = LinearGradient(inherit=inherit_from) self.assertTrue('', lg.tostring()) class TestRadialGradient(unittest.TestCase): def test_constructor(self): rg = RadialGradient(center=(10, 20), r=10, focal=(15, 25), inherit='#test', debug=True, profile='full') self.assertEqual(rg.tostring(), '') def test_get_paint_server(self): rg = RadialGradient() self.assertTrue(re.match("^url\(#id\d+\) none$", rg.get_paint_server())) self.assertTrue(re.match("^url\(#id\d+\) red$", rg.get_paint_server(default='red'))) def test_add_stop_color(self): rg = RadialGradient() rg.add_stop_color(offset=0.5, color='red', opacity=1.0) self.assertEqual(rg.tostring(), '') if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_group.py0000666000000000000000000000157012012650555015440 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test group element # Created: 25.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import sys import unittest from svgwrite.container import Group class TestGroup(unittest.TestCase): def test_constructor(self): g = Group() self.assertEqual(g.tostring(), "") def test_add_subelement(self): group = Group(id='group') subgroup = Group(id='subgroup') group.add(subgroup) self.assertEqual(group.tostring(), '') def test_add_group(self): group = Group(id='group') subgroup = group.add(Group(id='subgroup')) self.assertEqual(group.tostring(), '') if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_hyperlink.py0000666000000000000000000000144512012650555016312 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test hyperlink object # Created: 09.10.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import sys import unittest from svgwrite.container import Hyperlink class TestHyperlink(unittest.TestCase): def test_constructor(self): link = Hyperlink("http://localhost:8080") self.assertEqual(link.tostring(), '') def test_errors(self): self.assertRaises(TypeError, Hyperlink, 1) self.assertRaises(TypeError, Hyperlink, 3.1415) self.assertRaises(TypeError, Hyperlink, (1,2)) self.assertRaises(TypeError, Hyperlink, dict(a=1)) if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_image.py0000666000000000000000000000415312012650557015370 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test image object # Created: 09.10.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import sys import unittest from svgwrite.image import Image class TestImage(unittest.TestCase): def test_constructor(self): image = Image("http://localhost/test.jpg") self.assertEqual(image.tostring(), '') def test_constructor2(self): image = Image("test.jpg", insert=(10,20), size=(30,40)) self.assertEqual(image.tostring(), '') def test_errors(self): self.assertRaises(TypeError, Image, 1) self.assertRaises(TypeError, Image, 3.1415) self.assertRaises(TypeError, Image, (1,2)) self.assertRaises(TypeError, Image, dict(a=1)) def test_strech(self): image = Image("http://test.jpg") image.stretch() self.assertEqual(image.tostring(), '') def test_fit_horiz(self): image = Image("http://test.jpg") for align, expected in [('left', 'xMin'), ('center', 'xMid'), ('right', 'xMax')]: image.fit(align, 'top', 'meet') self.assertEqual(image.tostring(), '' % expected) def test_fit_vert(self): image = Image("http://test.jpg") for align, expected in [('top', 'YMin'), ('middle', 'YMid'), ('bottom', 'YMax')]: image.fit('left', align, 'slice') self.assertEqual(image.tostring(), '' % expected) def test_fit_err(self): image = Image("http://test.jpg") self.assertRaises(ValueError, image.fit, scale='invalid') self.assertRaises(KeyError, image.fit, horiz='invalid') self.assertRaises(KeyError, image.fit, vert='invalid') if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_line.py0000666000000000000000000000233212574313317015235 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test line object # Created: 25.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import sys import unittest from svgwrite.shapes import Line class TestLine(unittest.TestCase): def test_numbers(self): line = Line(start=(0,0), end=(10,20)) self.assertEqual(line.tostring(), '') def test_coordinates(self): line = Line(start=('10cm','11cm'), end=('20cm', '30cm')) self.assertEqual(line.tostring(), '') def test_errors(self): self.assertRaises(TypeError, Line, start=1) self.assertRaises(TypeError, Line, end=1) self.assertRaises(TypeError, Line, start=None) self.assertRaises(TypeError, Line, end=None) self.assertRaises(TypeError, Line, end=(None, None)) self.assertRaises(TypeError, Line, start=(None, None)) def test_issue_01(self): line = Line((0, 0), (10, 10), stroke='red', stroke_width='3', style="x:y") self.assertEqual("x:y", line.attribs['style']) if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_markers_mixin.py0000666000000000000000000000411412012650557017153 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test markers mixin # Created: 24.10.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import unittest from svgwrite.base import BaseElement from svgwrite.mixins import Markers class MarkerMock(BaseElement, Markers): elementname = 'line' # has valid marker properties class TestMarkers(unittest.TestCase): def test_with_one_string(self): e = MarkerMock(debug=True, profile='full') e.set_markers('#mozman') self.assertEqual(e.tostring(), '') def test_with_three_strings(self): e = MarkerMock(debug=True, profile='full') e.set_markers(('#mozman1', '#mozman2', '#mozman3')) self.assertEqual(e.tostring(), '') def test_with_one_obj(self): marker = MarkerMock(id='mozman', debug=True, profile='full') e = MarkerMock(debug=True, profile='full') e.set_markers(marker) self.assertEqual(e.tostring(), '') def test_with_three_obj(self): m1 = MarkerMock(id='mozman1', debug=True, profile='full') m2 = MarkerMock(id='mozman2', debug=True, profile='full') m3 = MarkerMock(id='mozman3', debug=True, profile='full') e = MarkerMock(debug=True, profile='full') e.set_markers((m1, m2, m3)) self.assertEqual(e.tostring(), '') def test_unpack_error(self): e = MarkerMock(debug=True, profile='full') # one or three values not two self.assertRaises(ValueError, e.set_markers, (1, 2)) def test_id_error(self): e = MarkerMock(debug=True, profile='full') # intergers not valid self.assertRaises(TypeError, e.set_markers, (1, 2, 3)) if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_marker_class.py0000666000000000000000000000353712012650557016761 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test marker element # Created: 24.10.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import sys import unittest import re from svgwrite.container import Marker, Group class TestMarker(unittest.TestCase): def test_constructor(self): marker = Marker(id='test', orient='auto', debug=True, profile='full') self.assertEqual(marker.tostring(), '') def test_add_subelement(self): marker = Marker(id='test', debug=True, profile='full') marker.add(Group()) self.assertEqual(marker.tostring(), '') def test_add_subelement_with_autoid(self): marker = Marker(debug=True, profile='full') marker.add(Group()) self.assertTrue( re.match('^$', marker.tostring()), "getting an autoid for class Marker failed.") def test_insert(self): marker = Marker(id='test', insert=(1, 2), debug=True, profile='full') self.assertEqual(marker.tostring(), '') def test_size(self): marker = Marker(id='test', size=(1, 2), debug=True, profile='full') self.assertEqual(marker.tostring(), '') def test_orient_rad(self): marker = Marker(id='test', orient='3.1415rad', debug=True, profile='full') self.assertEqual(marker.tostring(), '') def test_orient_number(self): marker = Marker(id='test', orient=30, debug=True, profile='full') self.assertEqual(marker.tostring(), '') if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_mask.py0000666000000000000000000000145112012650557015237 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test Mask # Created: 31.10.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import unittest from svgwrite.masking import Mask from svgwrite.shapes import Circle class TestMask(unittest.TestCase): def test_constructor(self): mask = Mask(start=('-10%', '-20%'), size=('120%', '140%'), debug=True, profile='full') self.assertEqual(mask.tostring(), '') def test_add_subelement(self): mask = Mask(debug=True, profile='full') mask.add(Circle((50,60), 70)) self.assertEqual(mask.tostring(), '') if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_mediagroup.py0000666000000000000000000000142612012650556016441 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test MediaGroup mixin # Created: 24.10.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import unittest from svgwrite.base import BaseElement from svgwrite.mixins import MediaGroup class MediaGroupClass(BaseElement, MediaGroup): elementname = "image" # element with valid media group attributes class TestMediaGroupMixin(unittest.TestCase): def test_viewport_fill(self): obj = MediaGroupClass(debug=True, profile='tiny') obj.viewport_fill(color='red', opacity=1.0) self.assertEqual(obj.tostring(), '') if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_parameter.py0000666000000000000000000000123312233636766016275 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test parameter module # Created: 10.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import sys import unittest from svgwrite.params import Parameter class TestParameterClass(unittest.TestCase): def test_init(self): p = Parameter(debug=True, profile='TINY') self.assertEqual(p.profile, 'tiny') self.assertTrue(p.debug) def test_default_values(self): p = Parameter() self.assertEqual(p.profile, 'full') self.assertTrue(p.debug) if __name__ == '__main__': unittest.main() svgwrite-1.1.8/tests/test_parsing_basic_types.py0000666000000000000000000001413012311240260020316 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test parsing basic types # Created: 17.10.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import sys import unittest import pyparsing as pp from svgwrite.data.svgparser import exponent, fractional_constant, \ scientific_constant, number class TestBasicTypes(unittest.TestCase): def is_valid(self, parser, value): try: parser.parseString(value, parseAll=True) return True except pp.ParseException: return False def test_exponent(self): self.assertTrue(self.is_valid(exponent, "e1")) self.assertTrue(self.is_valid(exponent, "E1")) self.assertTrue(self.is_valid(exponent, "e10")) self.assertTrue(self.is_valid(exponent, "E10")) self.assertTrue(self.is_valid(exponent, "e-1")) self.assertTrue(self.is_valid(exponent, "E-1")) self.assertTrue(self.is_valid(exponent, "e-10")) self.assertTrue(self.is_valid(exponent, "E-10")) self.assertTrue(self.is_valid(exponent, "e+1")) self.assertTrue(self.is_valid(exponent, "E+1")) self.assertTrue(self.is_valid(exponent, "e+10")) self.assertTrue(self.is_valid(exponent, "E+10")) def test_exponent_error(self): self.assertFalse(self.is_valid(exponent, "e")) self.assertFalse(self.is_valid(exponent, "e1.")) self.assertFalse(self.is_valid(exponent, "e1.0")) def test_fractional_constant(self): self.assertTrue(self.is_valid(fractional_constant, "1.")) self.assertTrue(self.is_valid(fractional_constant, "1.0")) self.assertTrue(self.is_valid(fractional_constant, ".1")) def test_fractional_constant_error(self): self.assertFalse(self.is_valid(fractional_constant, "1"), "missing '.' is not valid") self.assertFalse(self.is_valid(fractional_constant, "-1.0"), "a sign is not valid") self.assertFalse(self.is_valid(fractional_constant, "+1.0"), "a sign is not valid") self.assertFalse(self.is_valid(fractional_constant, "1.0.0"), "two or more '.' are not valid") self.assertFalse(self.is_valid(fractional_constant, "1..0"), "two or more '.' are not valid") self.assertFalse(self.is_valid(fractional_constant, "."), "only a '.' are not valid") self.assertFalse(self.is_valid(fractional_constant, "-."), "only a '.' are not valid") self.assertFalse(self.is_valid(fractional_constant, "+."), "only a '.' are not valid") self.assertFalse(self.is_valid(fractional_constant, "1,0"), "',' is not valid comma") def test_scientific_constant(self): self.assertTrue(self.is_valid(scientific_constant, "3.1415")) self.assertTrue(self.is_valid(scientific_constant, "3.1415e10")) self.assertTrue(self.is_valid(scientific_constant, "3.1415e-10")) self.assertTrue(self.is_valid(scientific_constant, "3.1415e+10")) def test_scientific_constant_error(self): self.assertFalse(self.is_valid(scientific_constant, "-3.1415"), "leading sign is not valid") self.assertFalse(self.is_valid(scientific_constant, "+3.1415"), "leading sign is not valid") self.assertFalse(self.is_valid(scientific_constant, "1.0.0e10"), "two or more '.' are not valid") self.assertFalse(self.is_valid(scientific_constant, "1..0e10"), "two or more '.' are not valid") self.assertFalse(self.is_valid(scientific_constant, "."), "only a '.' are not valid") self.assertFalse(self.is_valid(scientific_constant, "-."), "only a '.' are not valid") self.assertFalse(self.is_valid(scientific_constant, "+."), "only a '.' are not valid") def test_number(self): self.assertTrue(self.is_valid(number, "3.1415")) self.assertTrue(self.is_valid(number, "3.")) self.assertTrue(self.is_valid(number, "3.e10")) self.assertTrue(self.is_valid(number, ".1415")) self.assertTrue(self.is_valid(number, "-.1415")) self.assertTrue(self.is_valid(number, ".1415e10")) self.assertTrue(self.is_valid(number, "-.1415e10")) self.assertTrue(self.is_valid(number, "-3.1415")) self.assertTrue(self.is_valid(number, "+3.1415")) self.assertTrue(self.is_valid(number, "3.1415e10")) self.assertTrue(self.is_valid(number, "-3.1415e10")) self.assertTrue(self.is_valid(number, "-3.e10")) self.assertTrue(self.is_valid(number, "-.1415e10")) self.assertTrue(self.is_valid(number, "+3.1415e10")) self.assertTrue(self.is_valid(number, "+.1415e10")) self.assertTrue(self.is_valid(number, "3.1415e-10")) self.assertTrue(self.is_valid(number, "-3.1415e-10")) self.assertTrue(self.is_valid(number, "+3.1415e-10")) self.assertTrue(self.is_valid(number, "3.1415e+10")) self.assertTrue(self.is_valid(number, "-3.1415e+10")) self.assertTrue(self.is_valid(number, "+3.1415e+10")) self.assertTrue(self.is_valid(number, "31415e+10")) self.assertTrue(self.is_valid(number, "-31415e+10")) self.assertTrue(self.is_valid(number, "+31415e+10")) def test_number_error(self): self.assertFalse(self.is_valid(number, "1.0.0e10"), "two or more '.' are not valid") self.assertFalse(self.is_valid(number, "1..0e10"), "two or more '.' are not valid") self.assertFalse(self.is_valid(number, "."), "only a '.' are not valid") self.assertFalse(self.is_valid(number, "-."), "only a '.' are not valid") self.assertFalse(self.is_valid(number, "+."), "only a '.' are not valid") self.assertFalse(self.is_valid(number, "1.0e1-0"), "exponent 'e1-0' is not valid") self.assertFalse(self.is_valid(number, "1.0e1+0"), "exponent 'e1+0' is not valid") self.assertFalse(self.is_valid(number, "1.0e1.0"), "exponent 'e1.0' is not valid") self.assertFalse(self.is_valid(number, "1.0e"), "only 'e' is not valid") self.assertFalse(self.is_valid(number, "e10"), "only an exponent is not valid") if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_path.py0000666000000000000000000000404112012650555015234 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test path class # Created: 18.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import sys import unittest from svgwrite.path import Path class TestPath(unittest.TestCase): def test_constructor(self): p = Path(d="M 0 0", pathLength=100) self.assertEqual(p['pathLength'], 100) self.assertEqual(p.tostring(), '') # init path with command-string p = Path(d='M 10,7') self.assertEqual(p.tostring(), '') # init path with a tuple of values p = Path(d=('M', 9, 9)) self.assertEqual(p.tostring(), '') def test_flat_commands(self): p = Path(d="M 0 0") self.assertEqual(p.tostring(), '') # push separated commands and values p.push(100, 100, 100, 200) self.assertEqual(p.tostring(), '') # push commands strings p = Path() p.push('M 100 100 100 200') self.assertEqual(p.tostring(), '') p = Path(d=('M 10', 7)) p.push('l', 100., 100.) p.push('v 100.7 200.1') self.assertEqual(p.tostring(), '') def test_nested_commands(self): p = Path(d=('M 1,2', ['L', (7, 7, 'H 1 2 3 4 5')])) self.assertEqual(p.tostring(), '') def test_push_arc_1(self): p = Path('m0,0') p.push_arc(target=(7,7), rotation=30, r=5) self.assertEqual(p.tostring(), '') def test_push_arc_2(self): p = Path('m0,0') p.push_arc(target=(7,7), rotation=30, r=(2,4), large_arc=False, angle_dir='-', absolute=True) self.assertEqual(p.tostring(), '') if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_pathdataparser.py0000666000000000000000000001451712114553105017310 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: transform list parser # Created: 10.10.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import unittest from svgwrite.data.svgparser import is_valid_pathdata class TestPathDataParser(unittest.TestCase): def test_moveto(self): self.assertTrue(is_valid_pathdata("m 0, 0")) self.assertTrue(is_valid_pathdata("m 0,0")) self.assertTrue(is_valid_pathdata("m 0, 0")) self.assertTrue(is_valid_pathdata("m 0 ,0")) self.assertTrue(is_valid_pathdata("m 0 , 0")) self.assertTrue(is_valid_pathdata("m0,0")) self.assertTrue(is_valid_pathdata("M0,0,1,1")) self.assertTrue(is_valid_pathdata("M 0,0 1,1")) self.assertTrue(is_valid_pathdata("M 0 0 1 1")) self.assertTrue(is_valid_pathdata("M 0 0 , 1 1")) def test_moveto_errors(self): self.assertFalse(is_valid_pathdata("m m")) self.assertFalse(is_valid_pathdata("m 1 2 3")) def test_lineto(self): self.assertTrue(is_valid_pathdata("m0,0L0,0")) self.assertTrue(is_valid_pathdata("m0,0 L0,0")) self.assertTrue(is_valid_pathdata("m0,0 L 0.5 0.5")) self.assertTrue(is_valid_pathdata("m0,0 L 0.5 0.5 99,88")) self.assertTrue(is_valid_pathdata("m0,0l0,0")) self.assertTrue(is_valid_pathdata("m0,0 l0,0")) self.assertTrue(is_valid_pathdata("m0,0 l 0.5 0.5")) self.assertTrue(is_valid_pathdata("m0,0 l 0.5 0.5 99,88")) def test_lineto_errors(self): # error: 0 lineto args self.assertFalse(is_valid_pathdata("m0,0 l")) # error: 1 lineto args self.assertFalse(is_valid_pathdata("m0,0 l0")) # error: 3 lineto args self.assertFalse(is_valid_pathdata("m0,0 l0,0,0")) def test_horizontal_lineto(self): self.assertTrue(is_valid_pathdata("m0,0h1")) self.assertTrue(is_valid_pathdata("m0,0H1,2")) self.assertTrue(is_valid_pathdata("m0,0h1,2,3")) self.assertTrue(is_valid_pathdata("m0,0H1,2 3,4 5 6 7")) self.assertTrue(is_valid_pathdata("m0,0h1.")) self.assertTrue(is_valid_pathdata("m0,0H1.,2.")) self.assertTrue(is_valid_pathdata("m0,0h.1,.2,.3")) self.assertTrue(is_valid_pathdata("m0,0H1.,.2 3.,.4 .5 .6 7.")) def test_horizontal_lineto_errors(self): # error: 0 horizontal-lineto args self.assertFalse(is_valid_pathdata("m0,0 h")) def test_vertical_lineto(self): self.assertTrue(is_valid_pathdata("m0,0v1")) self.assertTrue(is_valid_pathdata("m0,0V1,2")) self.assertTrue(is_valid_pathdata("m0,0v1,2,3")) self.assertTrue(is_valid_pathdata("m0,0V1,2 3,4 5 6 7")) self.assertTrue(is_valid_pathdata("m0,0v1.")) self.assertTrue(is_valid_pathdata("m0,0V1.,2.")) self.assertTrue(is_valid_pathdata("m0,0v.1,.2,.3")) self.assertTrue(is_valid_pathdata("m0,0V1.,.2 3.,.4 .5 .6 7.")) def test_vertical_lineto_errors(self): # error: 0 vertical-lineto args self.assertFalse(is_valid_pathdata("m0,0 v")) def test_closepath(self): self.assertTrue(is_valid_pathdata("m0,0h1z")) self.assertTrue(is_valid_pathdata("m0,0h1Z")) self.assertTrue(is_valid_pathdata("m0,0v1 z")) self.assertTrue(is_valid_pathdata("m0,0v1 Z")) def test_closepath_errors(self): # error: 1 closepath arg self.assertFalse(is_valid_pathdata("m0,0 z 1")) def test_curveto(self): self.assertTrue(is_valid_pathdata("m0,0 c 1 2 3 4 5 6")) self.assertTrue(is_valid_pathdata("m0,0 C 1 2 3 4 5 6, 7 8 9 10 11 12")) def test_curveto_errors(self): self.assertFalse(is_valid_pathdata("m0,0 c 1 2 3 4 5")) self.assertFalse(is_valid_pathdata("m0,0 C 1 2 3 4 5 6, 7 8 9 10 11")) self.assertFalse(is_valid_pathdata("m0,0 C 1 2 3 4 5 6, 7 8 9 10")) self.assertFalse(is_valid_pathdata("m0,0 C 1 2 3 4 5 6, 7 8 9")) self.assertFalse(is_valid_pathdata("m0,0 C 1 2 3 4 5 6, 7 8")) self.assertFalse(is_valid_pathdata("m0,0 C 1 2 3 4 5 6, 7")) def test_smooth_curveto(self): self.assertTrue(is_valid_pathdata("m0,0 s 3 4 5 6")) self.assertTrue(is_valid_pathdata("m0,0 S 3 4 5 6, 9 10 11 12")) def test_smooth_curveto_errors(self): self.assertFalse(is_valid_pathdata("m0,0 s 3 4 5")) self.assertFalse(is_valid_pathdata("m0,0 S 1 2 3 4, 7 8 9")) self.assertFalse(is_valid_pathdata("m0,0 S 1 2 3 4, 7 8")) self.assertFalse(is_valid_pathdata("m0,0 S 1 2 3 4, 7")) def test_quadratic_bezier_curveto(self): self.assertTrue(is_valid_pathdata("m0,0 q 1 2 3 4")) self.assertTrue(is_valid_pathdata("m0,0 Q 1 2 3 4, 5 6 7 8")) def test_quadratic_bezier_curveto_errors(self): self.assertFalse(is_valid_pathdata("m0,0 q 1 2 3")) self.assertFalse(is_valid_pathdata("m0,0 q 1 2 3 4, 5 6 7")) self.assertFalse(is_valid_pathdata("m0,0 q 1 2 3 4, 5 6")) self.assertFalse(is_valid_pathdata("m0,0 q 1 2 3 4, 5")) def test_smooth_quadratic_bezier_curveto(self): self.assertTrue(is_valid_pathdata("m0,0 t 1 2")) self.assertTrue(is_valid_pathdata("m0,0 T 1 2 3 4 5 6")) def test_smooth_quadratic_bezier_curveto_errors(self): self.assertFalse(is_valid_pathdata("m0,0 t 1")) self.assertFalse(is_valid_pathdata("m0,0 t 1 2 3")) def test_elliptical_arc(self): self.assertTrue(is_valid_pathdata("m0,0 a 1 1 0 0 0 10 10")) self.assertTrue(is_valid_pathdata("m0,0 a 1 1 0 1 1 10 10")) self.assertTrue(is_valid_pathdata("m0,0 A 1 1 0 0 0 10 10, 1 1 0 0 0 10 10")) def test_elliptical_arc_errors(self): self.assertFalse(is_valid_pathdata("m0,0 a 1 1 45 0 0 10")) self.assertFalse(is_valid_pathdata("m0,0 a 1 1 45 0 0")) self.assertFalse(is_valid_pathdata("m0,0 a 1 1 45 0")) self.assertFalse(is_valid_pathdata("m0,0 a 1 1 45")) self.assertFalse(is_valid_pathdata("m0,0 a 1 1")) self.assertFalse(is_valid_pathdata("m0,0 a 1")) self.assertFalse(is_valid_pathdata("m0,0 a")) # flag errors flags != [01] self.assertFalse(is_valid_pathdata("m0,0 a 1 1 45 2 2 10 10")) if __name__ == '__main__': unittest.main() svgwrite-1.1.8/tests/test_pattern.py0000666000000000000000000000226112012650555015757 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test pattern module # Created: 29.10.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import unittest from svgwrite.pattern import Pattern class TestPattern(unittest.TestCase): def test_constructor(self): pattern = Pattern(insert=(10, 20), size=(30, 40), inherit='#test', debug=True, profile='full') self.assertEqual( pattern.tostring(), '') def test_get_paint_server(self): pattern = Pattern(id="testpattern", debug=True, profile='full') self.assertEqual(pattern.get_paint_server(), "url(#testpattern) none") def test_inherit_from_pattern(self): parent = Pattern(id='test') pattern = Pattern(insert=(10, 20), size=(30, 40), inherit=parent, debug=True, profile='full') self.assertEqual( pattern.tostring(), '') if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_polyline.py0000666000000000000000000000626112012650557016143 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test polyline object # Created: 25.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import sys import unittest from svgwrite.shapes import Polyline class TestPolyline(unittest.TestCase): def test_numbers(self): polyline = Polyline(points=[(0,0), (1,1)]) self.assertEqual(polyline.tostring(), '') def test_coordinates(self): # list of points is a list of numbers not coordinates -> no units allowed!! self.assertRaises(TypeError, Polyline, [('1cm','1cm'), ('2mm', '1mm')]) def test_errors(self): self.assertRaises(TypeError, Polyline, 0) self.assertRaises(TypeError, Polyline, None) self.assertRaises(TypeError, Polyline, [(None, None)]) class TestPointsToStringFullProfile(unittest.TestCase): def setUp(self): self.polyline = Polyline(debug=True, profile='full') def test_valid_points(self): # valid units: cm|em|ex|in|mm|pc|pt|px|% # dont't know if '%' is valid for points? result = self.polyline.points_to_string([(10,10), ('20cm', '20em'), ('30ex', '30in'), ('40mm', '40pc'), ('50pt', '50px'), ('60%', '60%')]) # it's an unicode string self.assertEqual(result, "10,10 20cm,20em 30ex,30in 40mm,40pc 50pt,50px 60%,60%") # e-notation is valid result = self.polyline.points_to_string([('1e10pt','1e-10in')]) self.assertEqual(result, "1e10pt,1e-10in") def test_invalid_points(self): # invalid unit #'p' self.assertRaises(TypeError, self.polyline.points_to_string, [(10,10), ('20p', '20px')]) def test_invalid_tuple_count(self): # 3-tuple not allowed self.assertRaises(TypeError, self.polyline.points_to_string, [(10,10), ('20px', '20px', '20px')]) # 1-tuple not allowed self.assertRaises(TypeError, self.polyline.points_to_string, [(10,10), ('20px', )]) class TestPointsToStringTinyProfile(unittest.TestCase): def setUp(self): self.polyline = Polyline(debug=True, profile='tiny') def test_valid_points(self): # valid units: cm|em|ex|in|mm|pc|pt|px|% # dont't know if '%' is valid for points? result = self.polyline.points_to_string([(10,10), ('20cm', '20em'), ('30ex', '30in'), ('40mm', '40pc'), ('50pt', '50px'), ('60%', '60%')]) # it's an unicode string self.assertEqual(result, "10,10 20cm,20em 30ex,30in 40mm,40pc 50pt,50px 60%,60%") def test_float_points(self): result = self.polyline.points_to_string([(10.12345,10.12345),(3.14151, 3.14151)]) self.assertEqual(result, "10.1235,10.1235 3.1415,3.1415") def test_value_range(self): # invalid unit #'p' self.assertRaises(TypeError, self.polyline.points_to_string, [(100000,10)]) self.assertRaises(TypeError, self.polyline.points_to_string, [(-100000,10)]) self.assertRaises(TypeError, self.polyline.points_to_string, [(10,100000)]) self.assertRaises(TypeError, self.polyline.points_to_string, [(-10,-100000)]) if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_presentation.py0000666000000000000000000000641012012650557017017 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test presentation mixin # Created: 24.10.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import unittest from svgwrite.base import BaseElement from svgwrite.mixins import Presentation from svgwrite import rgb class PresentationClass(BaseElement, Presentation): elementname = "line" # element with valid presentation attributes class MockPaintServer: def get_paint_server(self): return "url(#mockpaintserver)" class TestPresentationMixin(unittest.TestCase): def test_fill(self): obj = PresentationClass(debug=True, profile='full') obj.fill(color='red', rule="evenodd", opacity=1.0) self.assertEqual(obj.tostring(), '') def test_fill_rgb_values(self): obj = PresentationClass(debug=True, profile='full') obj.fill(color=rgb(10, 20, 30), rule="evenodd", opacity=1.0) self.assertEqual(obj.tostring(), '') def test_fill_rgb_percentage(self): obj = PresentationClass(debug=True, profile='full') obj.fill(color=rgb(10, 20, 30, '%'), rule="evenodd", opacity=1.0) self.assertEqual(obj.tostring(), '') def test_fill_paintserver(self): obj = PresentationClass(debug=True, profile='full') obj.fill(color=MockPaintServer()) self.assertEqual(obj.tostring(), '') def test_stroke(self): obj = PresentationClass(debug=True, profile='full') obj.stroke(color='red', width=2, opacity=0.5, linecap='round', linejoin='round', miterlimit='1.5') self.assertEqual(obj.tostring(), '') def test_stroke_paintserver(self): obj = PresentationClass(debug=True, profile='full') obj.stroke(color=MockPaintServer()) self.assertEqual(obj.tostring(), '') def test_dasharray(self): obj = PresentationClass(debug=True, profile='full') obj.dasharray([1., 0.5], offset=0.5) self.assertEqual(obj.tostring(), '') obj.dasharray('1.0 0.5', offset=0.5) self.assertEqual(obj.tostring(), '') def test_combi_call(self): obj = PresentationClass(debug=True, profile='full') obj.fill('red').stroke('blue') self.assertEqual(obj.tostring(), '') if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_rect.py0000666000000000000000000000265112012650555015242 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test rect object # Created: 25.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import sys import unittest from svgwrite.shapes import Rect class TestRect(unittest.TestCase): def test_numbers(self): rect = Rect(insert=(0,0), size=(10,20)) self.assertEqual(rect.tostring(), '') def test_coordinates(self): rect = Rect(insert=('10cm','11cm'), size=('20cm', '30cm')) self.assertEqual(rect.tostring(), '') def test_corners_numbers(self): rect = Rect(rx=1, ry=1) self.assertEqual(rect.tostring(), '') def test_corners_length(self): rect = Rect(rx='1mm', ry='1mm') self.assertEqual(rect.tostring(), '') def test_errors(self): self.assertRaises(TypeError, Rect, insert=1) self.assertRaises(TypeError, Rect, size=1) self.assertRaises(TypeError, Rect, insert=None) self.assertRaises(TypeError, Rect, size=None) self.assertRaises(TypeError, Rect, size=(None, None)) self.assertRaises(TypeError, Rect, insert=(None, None)) if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_script.py0000666000000000000000000000161512012650554015607 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test script element # Created: 25.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import unittest from svgwrite.container import Script class TestScript(unittest.TestCase): def test_link(self): script = Script('test.js') self.assertEqual(script.tostring(), '') if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_style.py0000666000000000000000000000105112012650556015437 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test style element # Created: 27.05.2012 # Copyright (C) 2012, Manfred Moitzi # License: MIT License import unittest from svgwrite.container import Style class TestScript(unittest.TestCase): def test_content(self): style = Style(content='.red {fill: red};') result = style.tostring() self.assertEqual(result, '') if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_svg.py0000666000000000000000000000147512012650557015111 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test svg element # Created: 25.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import sys import unittest from svgwrite.container import SVG, Symbol class TestSVG(unittest.TestCase): def test_constructor(self): svg = SVG(insert=(10,20), size=(100,200)) self.assertTrue(isinstance(svg, Symbol)) self.assertEqual(svg.tostring(), '') def test_add_svg_as_subelement(self): svg = SVG(id='svg') subsvg = SVG(id='subsvg') svg.add(subsvg) self.assertEqual(svg.tostring(), '') if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_svgattributes.py0000666000000000000000000000577212012650555017222 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test SVGAttribute # Created: 12.10.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import sys import unittest from svgwrite.data.types import SVGAttribute, SVGMultiAttribute class TestSVGMultiAttribute(unittest.TestCase): def setUp(self): self.ma = SVGMultiAttribute({ '*': SVGAttribute('x', anim=True, types=frozenset(['coordinate']), const=frozenset(['star'])), 'text tref tspan': SVGAttribute('x', anim=False, types=frozenset(['list-of-coordinate']), const=frozenset(['text'])) } ) def test_no_default(self): ma = SVGMultiAttribute({ 'a': SVGAttribute('x', anim=True, types=frozenset(['coordinate']), const=frozenset(['star'])), 'b': SVGAttribute('x', anim=False, types=frozenset(['list-of-coordinate']), const=frozenset(['text'])) } ) self.assertTrue('coordinate' in ma.get_types('c')) def test_get_types(self): coordinate = frozenset(['coordinate']) list_of_coordinates = frozenset(['list-of-coordinate']) self.assertEqual(coordinate, self.ma.get_types('line')) # default attribute self.assertEqual(coordinate, self.ma.get_types()) # default attribute self.assertEqual(list_of_coordinates, self.ma.get_types('text')) self.assertEqual(list_of_coordinates, self.ma.get_types('tref')) self.assertEqual(list_of_coordinates, self.ma.get_types('tspan')) def test_get_anim(self): self.assertTrue(self.ma.get_anim('line')) # default attribute self.assertTrue(self.ma.get_anim()) # default attribute self.assertFalse(self.ma.get_anim('text')) self.assertFalse(self.ma.get_anim('tref')) self.assertFalse(self.ma.get_anim('tspan')) def test_get_const(self): star = frozenset(['star']) text = frozenset(['text']) self.assertEqual(star, self.ma.get_const('line')) # default attribute self.assertEqual(star, self.ma.get_const()) # default attribute self.assertEqual(text, self.ma.get_const('text')) self.assertEqual(text, self.ma.get_const('tref')) self.assertEqual(text, self.ma.get_const('tspan')) def test_init_error(self): # different attribute names ma = { '*' : SVGAttribute('x', True, [], []), 'text' : SVGAttribute('y', False, [], []) } self.assertRaises(ValueError, SVGMultiAttribute, ma) if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_symbol.py0000666000000000000000000000166212012650556015614 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test symbol element # Created: 25.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import sys import unittest from svgwrite.container import Symbol, Group class TestSymbol(unittest.TestCase): def test_constructor(self): symbol = Symbol() self.assertEqual(symbol.tostring(), "") def test_add_subelement(self): symbol = Symbol(id='symbol') group = Group(id='group') symbol.add(group) self.assertEqual(symbol.tostring(), '') def test_add_group(self): symbol = Symbol(id='symbol') group = symbol.add(Group(id='group')) # implicit call of add self.assertEqual(symbol.tostring(), '') if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_text.py0000666000000000000000000000705112012650557015272 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test text module # Created: 25.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License from __future__ import unicode_literals import sys import unittest from svgwrite.utils import PYTHON3, to_unicode from svgwrite.text import TSpan, TRef, TextPath class TestTSpan(unittest.TestCase): def test_constructor(self): txt = TSpan('testtext') self.assertEqual(txt.tostring(), 'testtext') def test_insert(self): txt = TSpan('testtext', insert=(1,1)) self.assertEqual(txt.tostring(), 'testtext') def test_subelement(self): txt = TSpan('testtext') txt.add(TSpan('subtext1')) txt.add(TSpan('subtext2')) self.assertEqual(txt.tostring(), 'testtextsubtext1subtext2') def test_x_values(self): txt = TSpan('text', x=[1,2,3,4]) self.assertEqual(txt.tostring(), 'text') def test_y_values(self): txt = TSpan('text', y=[1,2,3,4]) self.assertEqual(txt.tostring(), 'text') def test_dx_values(self): txt = TSpan('text', dx=[1,2,3,4]) self.assertEqual(txt.tostring(), 'text') def test_dy_values(self): txt = TSpan('text', dy=[1,2,3,4]) self.assertEqual(txt.tostring(), 'text') def test_rotate_values(self): txt = TSpan('text', rotate=[1,2,3,4]) self.assertEqual(txt.tostring(), 'text') def test_subelement_tspan(self): txt = TSpan('text') txt.add(TSpan('subtext')) self.assertEqual(txt.tostring(), 'textsubtext') def test_non_us_ascii_chars(self): txt = TSpan('öäü') self.assertEqual(txt.tostring(), to_unicode('öäü')) def test_errors(self): # None for x, y, dx, dy, rotate is valid - willl be ignored self.assertRaises(TypeError, TSpan,"txt", x=1) self.assertRaises(TypeError, TSpan,"txt", y=1) self.assertRaises(TypeError, TSpan,"txt", dx=1) self.assertRaises(TypeError, TSpan,"txt", dy=1) self.assertRaises(TypeError, TSpan,"txt", rotate=1) def test_insert_errors(self): self.assertRaises(TypeError, TSpan, "txt", insert=1) self.assertRaises(TypeError, TSpan, "txt", insert='1') # do not use 'insert' and 'x' or 'y' at the same time self.assertRaises(ValueError, TSpan, "txt", insert=(1,1), x=[1]) self.assertRaises(ValueError, TSpan, "txt", insert=(1,1), y=[1]) class TestTRef(unittest.TestCase): def test_constructor(self): tref = TRef('#test') self.assertEqual(tref.tostring(), '') class TestTextPath(unittest.TestCase): def test_constructor(self): tref = TextPath('#test', 'The Text', startOffset=10, spacing='auto', method='stretch') self.assertEqual(tref.tostring(), 'The Text') def test_subelement_tspan(self): txt = TextPath('#test', 'text') txt.add(TSpan('subtext')) self.assertEqual(txt.tostring(), 'textsubtext') if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_textarea.py0000666000000000000000000000742112270370146016123 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test TextArea class # Created: 14.10.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import sys import unittest from svgwrite.text import TextArea from svgwrite.text import TBreak class TestTBreak(unittest.TestCase): def test_tostring(self): br = TBreak(profile='tiny') self.assertEqual(br.tostring(), "") def test_errors(self): br = TBreak() self.assertRaises(NotImplementedError, br.add, None) self.assertRaises(NotImplementedError, br.__getitem__, 'key') self.assertRaises(NotImplementedError, br.__setitem__, 'key', 'value') class TestTextAreaFullProfile(unittest.TestCase): def test_constructor(self): self.assertRaises(KeyError, TextArea, (0, 0)) class TestTextAreaTinyProfile(unittest.TestCase): def test_constructor(self): textarea = TextArea(insert=(1, 2), size=(10,20), profile='tiny') self.assertEqual(textarea.tostring(), '') def test_write_linebreaks(self): textarea = TextArea('\n', profile='tiny') self.assertEqual(textarea.tostring(), '') textarea = TextArea('\n\n', profile='tiny') self.assertEqual(textarea.tostring(), '') def test_write_lines(self): textarea = TextArea('line1\n', profile='tiny') self.assertEqual(textarea.tostring(), '') textarea = TextArea('line1\nline2', profile='tiny') self.assertEqual(textarea.tostring(), '') textarea = TextArea('line1\nline2\n', profile='tiny') self.assertEqual(textarea.tostring(), '') textarea = TextArea('line1\n \nline2\n', profile='tiny') self.assertEqual(textarea.tostring(), '') def test_line_increment(self): textarea = TextArea('line1\n', profile='tiny') textarea.line_increment('14') self.assertEqual(textarea.tostring(), '') def test_write_lines_prepending_linebreak(self): textarea = TextArea('\nline1\n', profile='tiny') self.assertEqual(textarea.tostring(), '') textarea = TextArea('\nline1\nline2', profile='tiny') self.assertEqual(textarea.tostring(), '') textarea = TextArea('\nline1\nline2\n', profile='tiny') self.assertEqual(textarea.tostring(), '') textarea = TextArea('\nline1\n\nline2\n', profile='tiny') self.assertEqual(textarea.tostring(), '') if __name__ == '__main__': unittest.main() svgwrite-1.1.8/tests/test_tiny12_typechecker.py0000666000000000000000000000503012012650555020013 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test tiny12 typechecker # Created: 08.10.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import sys import unittest from svgwrite.data.typechecker import Tiny12TypeChecker class TestTiny12TypeChecker(unittest.TestCase): def setUp(self): self.checker = Tiny12TypeChecker() def test_is_bool(self): self.assertTrue(self.checker.is_boolean(True)) self.assertTrue(self.checker.is_boolean(False)) self.assertTrue(self.checker.is_boolean(' true ')) self.assertTrue(self.checker.is_boolean(' false ')) self.assertTrue(self.checker.is_boolean('True')) self.assertTrue(self.checker.is_boolean('False')) def test_is_not_bool(self): self.assertFalse(self.checker.is_boolean(1)) self.assertFalse(self.checker.is_boolean(0)) self.assertFalse(self.checker.is_boolean((1, 1))) self.assertFalse(self.checker.is_boolean(dict(a=1, b=1))) def test_is_number(self): """ Integer and Float, also as String '100' or '3.1415'. """ # big numbers only valid for full profile self.assertTrue(self.checker.is_number(10000)) self.assertTrue(self.checker.is_number(-10000)) self.assertTrue(self.checker.is_number(3.141592)) self.assertTrue(self.checker.is_number('10000')) self.assertTrue(self.checker.is_number('-10000')) self.assertTrue(self.checker.is_number('3.141592')) def test_is_not_number(self): self.assertFalse(self.checker.is_number( (1,2) )) self.assertFalse(self.checker.is_number('manfred')) self.assertFalse(self.checker.is_number( dict(a=1, b=2) )) self.assertFalse(self.checker.is_number(100000)) self.assertFalse(self.checker.is_number(-100000)) self.assertFalse(self.checker.is_number('100000')) self.assertFalse(self.checker.is_number('-100000')) def test_is_focus(self): for focus in [' nav-next ', ' nav-prev ', ' nav-up ', ' nav-down ', ' nav-left ', ' nav-right ', ' nav-up-left ', ' nav-up-right ', 'nav-down-left', 'nav-down-right']: self.assertTrue(self.checker.is_focus(focus)) def test_is_not_focus(self): self.assertFalse(self.checker.is_focus('mozman')) self.assertFalse(self.checker.is_focus(1)) self.assertFalse(self.checker.is_focus((1,1))) if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_transform.py0000666000000000000000000000726012217740721016323 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test ITransform interface # Created: 25.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import sys import unittest from svgwrite.params import Parameter from svgwrite.base import BaseElement from svgwrite.mixins import Transform class Mock(BaseElement, Transform): elementname = 'g' _parameter = Parameter(True, 'full') class TestITransfer(unittest.TestCase): def test_mock_class(self): m = Mock() self.assertEqual(m.tostring(), '') def test_translate_tx(self): m = Mock() m.translate(tx=10) self.assertEqual(m.tostring(), '') def test_translate_tx_ty(self): m = Mock() # strings allowed m.translate(tx='10', ty=20) self.assertEqual(m.tostring(), '') def test_translate_err(self): m = Mock() # no units allowed self.assertRaises(TypeError, m.translate, '10cm') def test_rotate(self): m = Mock() m.rotate(angle=30) self.assertEqual(m.tostring(), '') def test_rotate_center(self): m = Mock() # strings allowed m.rotate(angle='30', center=(1,2)) self.assertEqual(m.tostring(), '') def test_rotate_err(self): m = Mock() # no units allowed self.assertRaises(TypeError, m.rotate, '30deg') self.assertRaises(TypeError, m.rotate, '30', center=('1cm', '1cm')) def test_scale_sx(self): m = Mock() m.scale(sx=3) self.assertEqual(m.tostring(), '') def test_scale_sx_sy(self): m = Mock() m.scale(sx='3', sy=2) self.assertEqual(m.tostring(), '') def test_scale_err(self): m = Mock() # no units allowed self.assertRaises(TypeError, m.scale, '3cm') self.assertRaises(TypeError, m.scale, '3', '2cm') def test_skewX(self): m = Mock() m.skewX(angle=30) self.assertEqual(m.tostring(), '') def test_skewX_str(self): m = Mock() m.skewX(angle='30') self.assertEqual(m.tostring(), '') def test_skewX_err(self): m = Mock() # no units allowed self.assertRaises(TypeError, m.skewX, '3deg') def test_skewY(self): m = Mock() m.skewY(angle=30) self.assertEqual(m.tostring(), '') def test_skewY_str(self): m = Mock() m.skewY(angle='30') self.assertEqual(m.tostring(), '') def test_skewY_err(self): m = Mock() # no units allowed self.assertRaises(TypeError, m.skewY, '3deg') def test_matrix(self): m = Mock() m.matrix(1,2,3,4,5,6) self.assertEqual(m.tostring(), '') def test_matrix_too_few_params(self): m = Mock() self.assertRaises(TypeError, m.matrix, 1, 2, 3, 4, 5) def test_combine_tranformation(self): m = Mock() m.translate(10,20) m.scale(2,2) self.assertEqual(m.tostring(), '') def test_delete_transformation(self): m = Mock() m.translate(10,20) del m.attribs['transform'] self.assertEqual(m.tostring(), '') if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_transformlistparser.py0000666000000000000000000000510412114552113020417 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: transform list parser # Created: 10.10.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import unittest from svgwrite.data.svgparser import is_valid_transferlist class TestTransformListParser(unittest.TestCase): def test_matrix_1(self): self.assertTrue(is_valid_transferlist("matrix(1 2 3 4 5 6)")) def test_matrix_2(self): self.assertTrue(is_valid_transferlist("matrix(1, 2, 3, 4, 5, 6)")) def test_translate_1(self): self.assertTrue(is_valid_transferlist("translate(1)")) def test_translate_2(self): self.assertTrue(is_valid_transferlist("translate(1 2)")) def test_translate_3(self): self.assertTrue(is_valid_transferlist("translate(1,2)")) def test_rotate_1(self): self.assertTrue(is_valid_transferlist("rotate(1)")) def test_rotate_3(self): self.assertTrue(is_valid_transferlist("rotate(1 2 3)")) def test_scale_1(self): self.assertTrue(is_valid_transferlist("scale(1)")) def test_scale_2(self): self.assertTrue(is_valid_transferlist("scale(2)")) def test_skewX(self): self.assertTrue(is_valid_transferlist("skewX(30)")) def test_skewY(self): self.assertTrue(is_valid_transferlist("skewY(30)")) def test_parse_skewX_errors(self): self.assertFalse(is_valid_transferlist("skewX()")) self.assertFalse(is_valid_transferlist("skewX(30 30)")) self.assertFalse(is_valid_transferlist("skewX(30,30)")) def test_parse_skewY_errors(self): self.assertFalse(is_valid_transferlist("skewY()")) self.assertFalse(is_valid_transferlist("skewY(30 30)")) self.assertFalse(is_valid_transferlist("skewY(30,30)")) def test_parse_matrix_errors(self): self.assertFalse(is_valid_transferlist("matrix()")) self.assertFalse(is_valid_transferlist("matrix(1, 2, 3, 4, 5, 6,)")) self.assertFalse(is_valid_transferlist("matrix(1, 2, 3, 4, 5, )")) self.assertFalse(is_valid_transferlist("matrix(1, 2, 3, 4)")) def test_multi_command(self): self.assertTrue(is_valid_transferlist("matrix(1 2 3 4 5 6) skewX(30)")) self.assertTrue(is_valid_transferlist("skewY(15), matrix(1 2 3 4 5 6) skewX(30)")) def test_multi_command_errors(self): self.assertFalse(is_valid_transferlist("skewX(15),, skewY(15)")) self.assertFalse(is_valid_transferlist("skewX(15), skewY(15) ,")) if __name__ == '__main__': unittest.main() svgwrite-1.1.8/tests/test_use.py0000666000000000000000000000265712012650557015111 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test svg element # Created: 25.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import sys import unittest from svgwrite.container import Use, Group from svgwrite.utils import AutoID class TestUse(unittest.TestCase): def test_constructor(self): use = Use('#an_id', x=10, y=20, width=100, height=200) self.assertEqual(use.tostring(), '') def test_constructor2(self): use = Use('#an_id', insert=(10, 20), size=(100, 200)) self.assertEqual(use.tostring(), '') def test_object_link(self): g = Group(id='test') use = Use(g) self.assertEqual(use.tostring(), '') def test_object_link_auto_id(self): AutoID(999) # set next id to 999 g = Group() use = Use(g) self.assertEqual(use.tostring(), '') def test_object_link_change_id(self): g = Group(id=999) self.assertEqual(g['id'], 999) use = Use(g) # change 'id' after assigning to object g['id'] = 'newid' self.assertEqual(use.tostring(), '') if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_utils.py0000666000000000000000000001554312233657266015464 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test utils module # Created: 10.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import sys import unittest from svgwrite.utils import rgb, AutoID, get_unit from svgwrite.utils import strlist, rect_top_left_corner from svgwrite.utils import split_angle, split_coordinate from svgwrite.utils import to_unicode from svgwrite import cm class TestRgb(unittest.TestCase): def test_rgb_8bit(self): self.assertEqual(rgb(128, 128, 128), "rgb(128,128,128)") self.assertEqual(rgb(), "rgb(0,0,0)") # value overflow self.assertEqual(rgb(256, 256, 256), "rgb(0,0,0)") self.assertEqual(rgb(257, 257, 257), "rgb(1,1,1)") def test_rgb_percent(self): self.assertEqual(rgb(50, 50, 50, '%'), "rgb(50%,50%,50%)") self.assertEqual(rgb(mode='%'), "rgb(0%,0%,0%)") # value overflow self.assertEqual(rgb(101, -1, 101, '%'), "rgb(100%,0%,100%)") def test_rgb_invalid_mode(self): self.assertRaises(ValueError, rgb, mode='$') class TestStrList(unittest.TestCase): def test_basic_types(self): self.assertEqual(strlist([1,2,3]), "1,2,3" ) self.assertEqual(strlist([1,None,3]), "1,3") self.assertEqual(strlist([1,2,None]), "1,2") def test_seperator(self): self.assertEqual(strlist([1,2,3], ' '), "1 2 3" ) self.assertEqual(strlist([1,None,3], ';'), "1;3") self.assertEqual(strlist([1,2,None], ':'), "1:2") def test_list(self): self.assertEqual(strlist( [(5, 'abc', None), (1, 2, None)] ), "5,abc,1,2") self.assertEqual(strlist( [(1,None,3), 4]), "1,3,4") def test_string(self): self.assertEqual(strlist("5,abc,1,2") , "5,abc,1,2") class TestRectTopLeftCorner(unittest.TestCase): def test_top_left(self): res = rect_top_left_corner(insert=(10,10), size=(10,10)) self.assertEqual(res, (10,10)) def test_top_center(self): res = rect_top_left_corner(insert=(10,10), size=(10,10), pos='top-center') self.assertEqual(res, (5,10)) def test_top_right(self): res = rect_top_left_corner(insert=(10,10), size=(10,10), pos='top-right') self.assertEqual(res, (0,10)) def test_middle_center(self): res = rect_top_left_corner(insert=(10,10), size=(10,10), pos='middle-center') self.assertEqual(res, (5,5)) def test_bottom_center(self): res = rect_top_left_corner(insert=(10,10), size=(10,10), pos='bottom-center') self.assertEqual(res, (5,0)) def test_valid_units(self): res = rect_top_left_corner(insert=('10mm','10mm'), size=('10mm','10mm'), pos='middle-center') # numbers converted to floats self.assertEqual(res, ('5.0mm','5.0mm')) res = rect_top_left_corner(insert=('10in','10in'), size=('10in','10in'), pos='bottom-center') self.assertEqual(res, ('5.0in','0.0in')) def test_invalid_units(self): # insert and size has to have the same units self.assertRaises(ValueError, rect_top_left_corner, insert=('10cm','10cm'), size=(10,10), pos='middle-center') self.assertRaises(ValueError, rect_top_left_corner, insert=('10mm','10mm'), size=('10cm','10cm'), pos='middle-center') self.assertRaises(ValueError, rect_top_left_corner, insert=('10mm','10mm'), size=('10mm','10cm'), pos='middle-center') def test_invalid_pos(self): # insert and size has to have the same units self.assertRaises(ValueError, rect_top_left_corner, insert=(1, 1), size=(1, 1), pos='middle-mitte') self.assertRaises(ValueError, rect_top_left_corner, insert=(1, 1), size=(1, 1), pos='mitte-center') class TestSplitCoordinate(unittest.TestCase): def test_int_coordinates(self): res = split_coordinate(10) self.assertEqual(res, (10, None)) def test_float_coordinates(self): res = split_coordinate(7.9) self.assertEqual(res, (7.9, None)) def test_valid_str_coordinates(self): res = split_coordinate('10cm') self.assertEqual(res, (10, 'cm')) res = split_coordinate('10.7in') self.assertEqual(res, (10.7, 'in')) def test_invalid_str_coordinates(self): self.assertRaises(ValueError, split_coordinate, '100km') self.assertRaises(ValueError, split_coordinate, '100ccm') self.assertRaises(ValueError, split_coordinate, '10,0cm') self.assertRaises(ValueError, split_coordinate, '1.0.0cm') class TestSplitAngle(unittest.TestCase): def test_int_angle(self): res = split_angle(10) self.assertEqual(res, (10, None)) def test_float_angle(self): res = split_angle(7.9) self.assertEqual(res, (7.9, None)) def test_valid_str_angle(self): res = split_angle('10deg') self.assertEqual(res, (10, 'deg')) res = split_angle('10.7rad') self.assertEqual(res, (10.7, 'rad')) res = split_angle('10.7grad') self.assertEqual(res, (10.7, 'grad')) def test_invalid_str_angle(self): self.assertRaises(ValueError, split_angle, '100km') self.assertRaises(ValueError, split_angle, '100ccm') self.assertRaises(ValueError, split_angle, '10,0deg') self.assertRaises(ValueError, split_angle, '1.0.0deg') class TestAutoID(unittest.TestCase): def test_next_id(self): getter = AutoID(1) self.assertEqual('id1', getter.next_id()) getter = AutoID() self.assertEqual('id2', getter.next_id()) self.assertEqual('id3', AutoID.next_id()) def test_set_next_id(self): #getter = AutoID() self.assertEqual('id7', AutoID.next_id(7)) self.assertEqual('id8', AutoID.next_id()) class TestGetUnit(unittest.TestCase): def test_number(self): self.assertEqual(None, get_unit(1)) self.assertEqual(None, get_unit(1.0)) def test_valid_units(self): self.assertEqual('cm', get_unit('1cm')) self.assertEqual('mm', get_unit('3.1415mm')) self.assertEqual('%', get_unit('300%')) def test_invalid_units(self): self.assertRaises(ValueError, get_unit, '1m') class TestUnit(unittest.TestCase): def test_cm(self): self.assertEqual('5cm', 5*cm) def test_call_cm(self): self.assertEqual('5cm,7cm', cm(5, 7)) class TestToUnicode(unittest.TestCase): def test_utf8_to_unicode(self): self.assertEqual(u'süß', to_unicode('süß')) def test_unicode_to_unicode(self): self.assertEqual(u'süß', to_unicode(u'süß')) def test_int_to_unicode(self): self.assertEqual(u'10', to_unicode(10)) def test_float_to_unicode(self): self.assertEqual(u'10.1', to_unicode(10.1)) if __name__ == '__main__': unittest.main() svgwrite-1.1.8/tests/test_validator2.py0000666000000000000000000001452412720242072016353 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test utils module # Created: 10.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import unittest from svgwrite.validator2 import get_validator class TestGetCoordinate(unittest.TestCase): def test_invalid_profile(self): self.assertRaises(ValueError, get_validator, profile='invalid') def test_get_none_coordinate(self): validator = get_validator('tiny', debug=True) self.assertRaises(TypeError, validator.get_coordinate, None) def test_valid_units(self): validator = get_validator('tiny', debug=True) for value, number, unit in [(' 100px ', 100, 'px'), (' -100ex ', -100, 'ex'), (' 100em ', 100, 'em'), (' -100pt ', -100, 'pt'), (' 100pc ', 100, 'pc'), (' 100mm', 100, 'mm'), (' 100cm', 100, 'cm'), (' 100in', 100, 'in'), (' 5%', 5, '%')]: number2, unit2 = validator.get_coordinate(value) self.assertEqual(number2, number) self.assertEqual(unit2, unit) def test_not_valid_numbers(self): validator = get_validator('tiny', debug=True) for value in (' 1s00in ', ' 1s00mm ', ' 1s00% '): self.assertRaises(ValueError, validator.get_coordinate, value) self.assertRaises(ValueError, validator.get_length, value) def test_not_valid_units(self): validator = get_validator('tiny', debug=True) for value in (' 100km ', ' 100mi ', ' 100$ '): self.assertRaises(ValueError, validator.get_coordinate, value) def test_not_valid_tiny_values(self): validator = get_validator('tiny', debug=True) for value in (100000, '100000', -100000, '-100000'): self.assertRaises(ValueError, validator.get_coordinate, value) # but valid for full profile - do not raise an error validator = get_validator('full', debug=True) for value in (100000, '100000', -100000, '-100000'): validator.get_coordinate(value) def test_valid_elementname(self): validator = get_validator('full', debug=True) self.assertTrue(validator.is_valid_elementname('text')) def test_invalid_elementname(self): validator = get_validator('full', debug=True) self.assertFalse(validator.is_valid_elementname('textArea')) def test_valid_children(self): validator = get_validator('full', debug=True) self.assertTrue(validator.is_valid_children('text', 'tspan')) def test_invalid_children(self): validator = get_validator('full', debug=True) self.assertFalse(validator.is_valid_children('text', 'line')) def test_check_invalid_children(self): validator = get_validator('full', debug=True) self.assertRaises(ValueError, validator.check_valid_children, 'text', 'line') def test_color(self): validator = get_validator('full', debug=True) self.assertTrue(validator.check_svg_type("red", 'color')) self.assertTrue(validator.check_svg_type("#000000", 'color')) self.assertTrue(validator.check_svg_type("rgb(10%, 20%, 30%)", 'color')) self.assertTrue(validator.check_svg_type("rgb(10.1%, 20.2%, 30.3%)", 'color')) class TestCheckCoordinate(unittest.TestCase): def test_valid_units(self): validator = get_validator('tiny', debug=True) for value, number, unit in [(' 100px ', 100, 'px'), (' -100ex ', -100, 'ex'), (' 100em ', 100, 'em'), (' -100pt ', -100, 'pt'), (' 100pc ', 100, 'pc'), (' 100mm', 100, 'mm'), (' 100cm', 100, 'cm'), (' 100in', 100, 'in'), (' 5%', 5, '%')]: value2 = validator.check_svg_type(value, 'coordinate') # checks also value pass through self.assertEqual(value, value2) def test_not_valid_numbers(self): validator = get_validator('tiny', debug=True) for value in (' 1s00in ', ' 1s00mm ', ' 1s00% '): self.assertRaises(TypeError, validator.check_svg_type, value, 'coordinate') def test_not_valid_units(self): validator = get_validator('tiny', debug=True) for value in (' 100km ', ' 100mi ', ' 100$ '): self.assertRaises(TypeError, validator.check_svg_type, value, 'coordinate') def test_not_valid_tiny_values(self): validator = get_validator('tiny', debug=True) for value in (100000, '100000', -100000, '-100000'): self.assertRaises(TypeError, validator.check_svg_type, value, 'coordinate') # but valid for full profile - do not raise an error validator = get_validator('full', debug=True) for value in (100000, '100000', -100000, '-100000'): validator.check_svg_type(value, 'coordinate') class TestCheckTiny(unittest.TestCase): def test_valid_tiny(self): validator = get_validator('tiny', debug=True) for value in (10000, 0, -10000., -32767.9999, +32767.9999): validator.check_svg_type(value, 'number') # no exception should raised def test_invalid_tiny(self): validator = get_validator('tiny', debug=True) for value in (100000, -100000., -32768, 32768): self.assertRaises(TypeError, validator.check_svg_type, value, 'number') class TestCheckAngle(unittest.TestCase): def test_valid_angle(self): validator = get_validator('tiny', debug=True) for value in ('100deg', '0.5grad', '-1.5rad'): validator.check_svg_type(value, 'angle') # no exception should raised def test_invalid_angle(self): validator = get_validator('tiny', debug=True) for value in ('10cm', '-10px', '10in', '1gon', '3°'): self.assertRaises(TypeError, validator.check_svg_type, value, 'angle') if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_viewbox.py0000666000000000000000000000357512012650556015777 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test ITransform interface # Created: 25.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import sys import unittest from svgwrite.params import Parameter from svgwrite.base import BaseElement from svgwrite.mixins import ViewBox class Mock(BaseElement, ViewBox): elementname = 'svg' _parameter = Parameter(True, 'full') class TestViewBox(unittest.TestCase): def test_mock_class(self): m = Mock() self.assertEqual(m.tostring(), '') def test_viewbox(self): m = Mock() m.viewbox(minx=1, miny=2, width=10, height=20) self.assertEqual(m.tostring(), '') def test_viewbox_err(self): m = Mock() # no units allowed self.assertRaises(TypeError, m.viewbox, '10cm') def test_strech(self): m = Mock() m.stretch() self.assertEqual(m.tostring(), '') def test_fit_horiz(self): m = Mock() for align, expected in [('left', 'xMin'), ('center', 'xMid'), ('right', 'xMax')]: m.fit(align, 'top', 'meet') self.assertEqual(m.tostring(), '' % expected) def test_fit_vert(self): m = Mock() for align, expected in [('top', 'YMin'), ('middle', 'YMid'), ('bottom', 'YMax')]: m.fit('left', align, 'slice') self.assertEqual(m.tostring(), '' % expected) def test_fit_err(self): m = Mock() self.assertRaises(ValueError, m.fit, scale='invalid') self.assertRaises(KeyError, m.fit, horiz='invalid') self.assertRaises(KeyError, m.fit, vert='invalid') if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/test_xlink.py0000666000000000000000000000402612012650555015430 0ustar 00000000000000#!/usr/bin/env python #coding:utf-8 # Author: mozman -- # Purpose: test ITransform interface # Created: 25.09.2010 # Copyright (C) 2010, Manfred Moitzi # License: MIT License import sys import unittest import re from svgwrite.container import Group from svgwrite.params import Parameter from svgwrite.base import BaseElement from svgwrite.mixins import XLink class Mock(BaseElement, XLink): elementname = 'use' _parameter = Parameter(True, 'full') def next_id(self): return "id999" class TestIXLink(unittest.TestCase): def test_mock_class(self): m = Mock() self.assertEqual(m.tostring(), '') def test_href(self): m = Mock() m.set_href('#an_id') self.assertEqual(m.tostring(), '') def test_object_link(self): g = Group(id='test') m = Mock() m.set_href(g) self.assertEqual(m.tostring(), '') def test_object_link_auto_id(self): g = Group() m = Mock() m.set_href(g) self.assertTrue(re.match('^$', m.tostring())) def test_set_xlink_show(self): m = Mock() m.set_xlink(show='new') self.assertEqual(m.tostring(), '') m.set_xlink(show='replace') self.assertEqual(m.tostring(), '') def test_set_xlink_role(self): m = Mock() m.set_xlink(role='http://test/role') self.assertEqual(m.tostring(), '') def test_set_xlink_arcrole(self): m = Mock() m.set_xlink(arcrole='http://test/arcrole') self.assertEqual(m.tostring(), '') def test_set_xlink_title(self): m = Mock() m.set_xlink(title='test') self.assertEqual(m.tostring(), '') if __name__=='__main__': unittest.main() svgwrite-1.1.8/tests/__init__.py0000666000000000000000000000000012114556556015000 0ustar 00000000000000