Manfred Moitzi avatar Manfred Moitzi committed 1d1387a

improved Marker class, tests and doc

Comments (0)

Files changed (9)

doc/classes/base.rst

 
 .. automethod:: svgwrite.base.BaseElement.get_xml()
 
+.. automethod:: svgwrite.base.BaseElement.get_funciri()
+
 .. automethod:: svgwrite.base.BaseElement.__getitem__(key)
 
 .. automethod:: svgwrite.base.BaseElement.__setitem__(key, value)

doc/classes/marker.rst

 
 .. autoclass:: svgwrite.container.Marker
 
-.. automethod:: svgwrite.container.Marker.__init__(insert=None, size=None, orient='auto', attribs=None, \*\*extra)
+example::
+
+    dwg = svgwrite.Drawing()
+    # create a new marker object
+    marker = dwg.marker(insert=(5,5), size=(10,10))
+
+    # red point as marker
+    marker.add(dwg.circle((5, 5), r=5, fill='red'))
+
+    # add marker to defs section of the drawing
+    dwg.defs.add(marker)
+
+    # create a new line object
+    line = dwg.add(dwg.polyline(
+        [(10, 10), (50, 20), (70, 50), (100, 30)],
+        stroke='black', fill='none'))
+
+    # set marker (start, mid and end markers are the same)
+    line.set_markers(marker)
+
+    # 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()
+
+.. automethod:: svgwrite.container.Marker.__init__(insert=None, size=None, orient=None, attribs=None, \*\*extra)
 
 Inherited Attributes
 --------------------
 
 .. automethod:: svgwrite.container.Marker.get_xml()
 
+.. automethod:: svgwrite.container.Marker.get_funciri()
+
 Supported Interfaces
 --------------------
 
             dwg.add(u)
     dwg.save()
 
+def marker_drawing(name):
+    dwg = svgwrite.Drawing(name, profile='full', debug=True)
+
+    # create a new marker object
+    # markerUnits='userSpaceOnUse'
+    marker = dwg.marker(insert=(5,5), size=(10,10))
+
+    # red point as marker
+    marker.add(dwg.circle((5, 5), r=5, fill='red'))
+
+    # add marker to defs section of the drawing
+    dwg.defs.add(marker)
+
+    # create a new line object
+    line = dwg.add(dwg.polyline(
+        [(10, 10), (50, 20), (70, 50), (100, 30)],
+        stroke='black', fill='none'))
+
+    # set marker (start, mid and end markers are the same)
+    line.set_markers(marker)
+
+    # 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()
+    dwg.save()
+
 def koch_snowflake(name):
     # Koch Snowflake and Sierpinski Triangle combination fractal using recursion
     # ActiveState Recipe 577156
     dwg.save()
 
 def main():
-    longrun = True
+    longrun = False
     # short time running
     print("start short time running examples!\n")
 
     print("start: example_koch_snowflake.svg\n")
     koch_snowflake('example_koch_snowflake.svg')
 
+    print("start: example_markers.svg\n")
+    marker_drawing('example_markers.svg')
+
 
     if longrun:
         print("start long time running examples!\n")
     def nextid(self, value=None):
         return AutoID.nextid(value)
 
+    def get_funciri(self):
+        """
+        Get the `FuncIRI` reference string of the object. (e.g. ``'url(#id)'``).
+
+        :returns: `string`
+        """
+        if 'id' not in self.attribs:
+            self['id'] = self.nextid()
+        return "url(#%s)" % self['id']
+
     def __getitem__(self, key):
         """ Get SVG attribute by `key`.
 

svgwrite/container.py

     """ 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='auto', attribs=None, **extra):
+    def __init__(self, insert=None, size=None, orient=None, attribs=None, **extra):
         """
         :param 2-tuple insert: reference point
         :param 2-tuple size: width, height
+        :param orient: ``'auto'`` | `angle`
         :param dict attribs: additional SVG attributes
         :param extra: additional SVG attributs as keyword-arguments
         """
         if size:
             self['markerWidth'] = size[0]
             self['markerHeight'] = size[1]
-
-        self['orient'] = orient
+        if orient is not None:
+            self['orient'] = orient
         if 'id' not in self.attribs: # an 'id' is necessary
             self['id'] = self.nextid()
 

svgwrite/metadata.py

 # Copyright (C) 2010, Manfred Moitzi
 # License: GPLv3
 
-VERSION = '0.2'
+VERSION = '0.2.1'
 AUTHOR_NAME = 'Manfred Moitzi'
 AUTHOR_EMAIL = 'mozman@gmx.at'
 CYEAR = '2010'

svgwrite/mixins.py

           * attribute 'marker-mid' = markers[1]
           * attribute 'marker-end' = markers[2]
 
-        * `markers` is as `string` or a `Marker` class:
+        * `markers` is a `string` or a `Marker` class:
 
-          * attribute 'marker' = markers
+          * attribute 'marker' = `FuncIRI` of markers
 
         """
         def get_funciri(value):
             else:
                 # else create a reference to the object '#id'
                 return 'url(#%s)' % value['id']
+
         if isinstance(markers, basestring):
             self['marker'] = get_funciri(markers)
         else:

tests/test_base_element.py

         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)")
+
 class TestValueToString(unittest.TestCase):
     def test_full_profile(self):
         element = MockBase()

tests/test_marker_class.py

 
 class TestMarker(unittest.TestCase):
     def test_constructor(self):
-        marker = Marker(id='test', debug=True, profile='full')
+        marker = Marker(id='test', orient='auto', debug=True, profile='full')
         self.assertEqual(marker.tostring(), '<marker id="test" orient="auto" />')
 
     def test_add_subelement(self):
         marker = Marker(id='test', debug=True, profile='full')
         marker.add(Group())
-        self.assertEqual(marker.tostring(), '<marker id="test" orient="auto"><g /></marker>')
+        self.assertEqual(marker.tostring(), '<marker id="test"><g /></marker>')
 
     def test_add_subelement_with_autoid(self):
         marker = Marker(debug=True, profile='full')
         marker.add(Group())
         self.assertTrue(
-            re.match('^<marker id="id\d+" orient="auto"><g /></marker>$',
+            re.match('^<marker id="id\d+"><g /></marker>$',
                      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(), '<marker id="test" orient="auto" refX="1" refY="2" />')
+        self.assertEqual(marker.tostring(), '<marker id="test" refX="1" refY="2" />')
 
     def test_size(self):
         marker = Marker(id='test', size=(1, 2), debug=True, profile='full')
-        self.assertEqual(marker.tostring(), '<marker id="test" markerHeight="2" markerWidth="1" orient="auto" />')
+        self.assertEqual(marker.tostring(), '<marker id="test" markerHeight="2" markerWidth="1" />')
 
     def test_orient_rad(self):
         marker = Marker(id='test', orient='3.1415rad', debug=True, profile='full')
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.