destos / svgpy

SVG parser based on lxml.etree

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[WIP] svg.py

SVG parser based on lxml.etree.

This project aims to implement an SVG 2 DOM API.

Usage

  1. Parsing from files

    >>> from svgpy import SVGParser
    >>> parser = SVGParser(remove_comments=True)
    >>> doc = parser.create_document('http://www.w3.org/2000/svg')
    >>> doc.location.assign('https://raw.githubusercontent.com/miute/svgpy/master/tests/svg/svg.svg')
    >>> print(doc.tostring(pretty_print=True).decode())
    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100" height="100" viewBox="0 0 100 100">
     <g id="gtop" stroke-width="12" stroke="#000">
       <g id="svgstar" transform="translate(50,50)">
         <path id="svgbar" d="M-27-5a7,7,0,1,0,0,10h54a7,7,0,1,0,0-10z"/>
         <use id="use1" xlink:href="#svgbar" transform="rotate(45)"/>
         <use id="use2" xlink:href="#svgbar" transform="rotate(90)"/>
         <use id="use3" xlink:href="#svgbar" transform="rotate(135)"/>
       </g>
     </g>
     <use id="usetop" xlink:href="#svgstar" fill="#FB4"/>
    </svg>
    
    >>> for element in doc.document_element.iter():
    ...     print((element.node_type, element.node_name, element.id))
    ...
    (1, 'svg', '')
    (1, 'g', 'gtop')
    (1, 'g', 'svgstar')
    (1, 'path', 'svgbar')
    (1, 'use', 'use1')
    (1, 'use', 'use2')
    (1, 'use', 'use3')
    (1, 'use', 'usetop')
    >>> element = doc.get_element_by_id('usetop')
    >>> element.attributes
    {'id': 'usetop', '{http://www.w3.org/1999/xlink}href': '#svgstar', 'fill': '#FB4'}
    >>> bbox = element.get_bbox()
    >>> bbox.x, bbox.y, bbox.width, bbox.height
    (11.101020514433644, 11.101020514433644, 77.79795897113272, 77.79795897113272)
    >>> element = doc.get_element_by_id('svgbar')
    >>> element.attributes
    {'id': 'svgbar', 'd': 'M-27-5a7,7,0,1,0,0,10h54a7,7,0,1,0,0-10z'}
    >>> bbox = element.get_bbox()
    >>> bbox.x, bbox.y, bbox.width, bbox.height
    (-38.89897948556636, -7.0000009993777565, 77.79795897113272, 14.000001998755515)
    >>> element.get_total_length()
    173.68771160294722
  2. Serialization

    >>> from svgpy import SVGParser
    >>> parser = SVGParser()
    >>> doc = parser.create_svg_document()
    >>> root = doc.document_element
    >>> root.attributes.update({'width': '10cm', 'height': '3cm', 'viewBox': '0 0 1000 300'})
    >>> text = doc.create_element_ns('http://www.w3.org/2000/svg', 'text')
    >>> root.append(text)
    >>> text.style.update({'font-family': 'Verdana', 'font-size': '55', 'fill': 'blue'})
    >>> tspan = doc.create_element_ns('http://www.w3.org/2000/svg', 'tspan')
    >>> text.append(tspan)
    >>> tspan.attributes.update({'x': '250', 'y': '150', 'rotate': '-30,0,30'})
    >>> tspan.text = 'Hello, out there'
    >>> print(doc.tostring(pretty_print=True).decode())
    <svg xmlns="http://www.w3.org/2000/svg" width="10cm" height="3cm" viewBox="0 0 1000 300">
      <text style="fill: blue; font-family: Verdana; font-size: 55;">
        <tspan x="250" y="150" rotate="-30,0,30">Hello, out there</tspan>
      </text>
    </svg>
    
    >>> tree = root.getroottree()
    >>> tree.write('output.svg', encoding='utf-8', pretty_print=True)
    $ cat output.svg
    <svg xmlns="http://www.w3.org/2000/svg" width="10cm" height="3cm" viewBox="0 0 1000 300">
      <text style="fill: blue; font-family: Verdana; font-size: 55;">
        <tspan x="250" y="150" rotate="-30,0,30">Hello, out there</tspan>
      </text>
    </svg>
  3. Path processing

    >>> from svgpy import PathParser, SVGParser, SVGPathSegment, formatter
    >>> parser = SVGParser()
    >>> path = parser.create_element_ns('http://www.w3.org/2000/svg', 'path')
    >>> path_data = list()
    >>> path_data.append(SVGPathSegment('M', 150, 10))
    >>> path_data.append(SVGPathSegment('B', 36))
    >>> path_data.append(SVGPathSegment('h', 47))
    >>> path_data.append(SVGPathSegment('b', 72))
    >>> path_data.append(SVGPathSegment('h', 47))
    >>> path_data.append(SVGPathSegment('b', 72))
    >>> path_data.append(SVGPathSegment('h', 47))
    >>> path_data.append(SVGPathSegment('b', 72))
    >>> path_data.append(SVGPathSegment('h', 47))
    >>> path_data.append(SVGPathSegment('z'))
    >>> path.set_path_data(path_data)
    >>> path.get_attribute('d')
    'M150,10 B36 h47 b72 h47 b72 h47 b72 h47 z'
    >>> bbox = path.get_bbox()
    >>> bbox.x, bbox.y, bbox.width, bbox.height
    (111.97620126437747, 10.0, 76.04759747124507, 72.32556312361845)
    >>> path.get_total_length()
    235.0
    >>> normalized = PathParser.normalize(path_data)  # convert to 'M', 'L', 'C' and 'Z' path command
    >>> path.set_path_data(normalized)
    >>> path.get_attribute('d')
    'M150,10 L188.023799,37.625907 173.5,82.325563 126.5,82.325563 111.976201,37.625907 Z'
    >>> formatter.precision
    6  # default precision for a floating point value
    >>> formatter.precision = 3
    >>> path.set_path_data(normalized)
    >>> path.get_attribute('d')
    'M150,10 L188.024,37.626 173.5,82.326 126.5,82.326 111.976,37.626 Z'
    >>> bbox = path.get_bbox()
    >>> bbox.x, bbox.y, bbox.width, bbox.height
    (111.976, 10.0, 76.048, 72.326)
    >>> path.get_total_length()
    235.00121335747357

License

This software is licensed under the Apache License 2.0.

About

SVG parser based on lxml.etree


Languages

Language:Python 91.2%Language:HTML 8.7%Language:CSS 0.1%Language:Shell 0.0%