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)))
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')
aW1wb3J0IHN2Z3dyaXRlCmZyb20gc3Znd3JpdGUgaW1wb3J0IGNtLCBtbSAgIAoKCmRlZiBiYXNpY19zaGFwZXMobmFtZSk6CiAgICBkd2cgPSBzdmd3cml0ZS5EcmF3aW5nKGZpbGVuYW1lPW5hbWUsIGRlYnVnPVRydWUpCiAgICBobGluZXMgPSBkd2cuYWRkKGR3Zy5nKGlkPSdobGluZXMnLCBzdHJva2U9J2dyZWVuJykpCiAgICBmb3IgeSBpbiByYW5nZSgyMCk6CiAgICAgICAgaGxpbmVzLmFkZChkd2cubGluZShzdGFydD0oMipjbSwgKDIreSkqY20pLCBlbmQ9KDE4KmNtLCAoMit5KSpjbSkpKQogICAgdmxpbmVzID0gZHdnLmFkZChkd2cuZyhpZD0ndmxpbmUnLCBzdHJva2U9J2JsdWUnKSkKICAgIGZvciB4IGluIHJhbmdlKDE3KToKICAgICAgICB2bGluZXMuYWRkKGR3Zy5saW5lKHN0YXJ0PSgoMit4KSpjbSwgMipjbSksIGVuZD0oKDIreCkqY20sIDIxKmNtKSkpCiAgICBzaGFwZXMgPSBkd2cuYWRkKGR3Zy5nKGlkPSdzaGFwZXMnLCBmaWxsPSdyZWQnKSkKCiAgICAjIHNldCBwcmVzZW50YXRpb24gYXR0cmlidXRlcyBhdCBvYmplY3QgY3JlYXRpb24gYXMgU1ZHLUF0dHJpYnV0ZXMKICAgIHNoYXBlcy5hZGQoZHdnLmNpcmNsZShjZW50ZXI9KDE1KmNtLCA4KmNtKSwgcj0nMi41Y20nLCBzdHJva2U9J2JsdWUnLAogICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZV93aWR0aD0zKSkKCiAgICAjIG92ZXJyaWRlIHRoZSAnZmlsbCcgYXR0cmlidXRlIG9mIHRoZSBwYXJlbnQgZ3JvdXAgJ3NoYXBlcycKICAgIHNoYXBlcy5hZGQoZHdnLnJlY3QoaW5zZXJ0PSg1KmNtLCA1KmNtKSwgc2l6ZT0oNDUqbW0sIDQ1Km1tKSwKICAgICAgICAgICAgICAgICAgICAgICAgZmlsbD0nYmx1ZScsIHN0cm9rZT0ncmVkJywgc3Ryb2tlX3dpZHRoPTMpKQoKICAgICMgb3Igc2V0IHByZXNlbnRhdGlvbiBhdHRyaWJ1dGVzIGJ5IGhlbHBlciBmdW5jdGlvbnMgb2YgdGhlIFByZXNlbnRhdGlvbi1NaXhpbgogICAgZWxsaXBzZSA9IHNoYXBlcy5hZGQoZHdnLmVsbGlwc2UoY2VudGVyPSgxMCpjbSwgMTUqY20pLCByPSgnNWNtJywgJzEwbW0nKSkpCiAgICBlbGxpcHNlLmZpbGwoJ2dyZWVuJywgb3BhY2l0eT0wLjUpLnN0cm9rZSgnYmxhY2snLCB3aWR0aD01KS5kYXNoYXJyYXkoWzIwLCAyMF0pCiAgICBkd2cuc2F2ZSgpCgppZiBfX25hbWVfXyA9PSAnX19tYWluX18nOgogICAgYmFzaWNfc2hhcGVzKCdiYXNpY19zaGFwZXMuc3ZnJykK