Giter Club home page Giter Club logo

svgpy's Introduction

[WIP] svg.py

SVG parser based on lxml.

This project aims to implement an SVG 2 DOM API.

Usage

  1. Parsing from files

    >>> from svgpy import Node, SVGParser
    >>> parser = SVGParser(remove_comments=True)
    >>> tree = parser.parse('tests/svg/svg.svg')
    >>> tree
    <lxml.etree._ElementTree object at 0x7fd75cad6cc8>
    >>> for element in tree.iter():
    ...     print((element.node_type, element.node_name, element.id))
    ...
    (1, 'svg', None)
    (1, 'g', 'gtop')
    (1, 'g', 'svgstar')
    (1, 'path', 'svgbar')
    (1, 'use', 'use1')
    (1, 'use', 'use2')
    (1, 'use', 'use3')
    (1, 'use', 'usetop')
    >>> root = tree.getroot()
    >>> root
    <Element svg at 0x7fd73910ff98>
    >>> from lxml import etree
    >>> isinstance(root, etree.ElementBase)
    True
    >>> isinstance(root, Node)
    True
    >>> element = root.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 = root.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()
    >>> root = parser.create_element('svg')
    >>> root.attributes.update({'width': '10cm', 'height': '3cm', 'viewBox': '0 0 1000 300'})
    >>> text = root.create_sub_element('text')
    >>> text.attributes.update({'font-family': 'Verdana', 'font-size': '55', 'fill': 'blue'})
    >>> tspan = text.create_sub_element('tspan')
    >>> tspan.attributes.update({'x': '250', 'y': '150', 'rotate': '-30,0,30'})
    >>> tspan.text = 'Hello, out there'
    >>> print(root.tostring(pretty_print=True).decode())
    <svg xmlns="http://www.w3.org/2000/svg" width="10cm" height="3cm" viewBox="0 0 1000 300">
      <text font-family="Verdana" font-size="55" fill="blue">
        <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 font-family="Verdana" font-size="55" fill="blue">
        <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('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.tostring()
    b'<path 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.tostring()
    b'<path 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.tostring()
    b'<path 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
  4. DOM interface

    >>> from svgpy import window
    >>> window.location = 'https://raw.githubusercontent.com/miute/svgpy/master/tests/svg/svg.svg'
    >>> document = window.document
    >>> document.content_type
    'image/svg+xml'
    >>> document.location
    {'href': 'https://raw.githubusercontent.com/miute/svgpy/master/tests/svg/svg.svg', 'origin': 'https://raw.githubusercontent.com', 'protocol': 'https:', 'username': '', 'password': '', 'host': 'raw.githubusercontent.com', 'hostname': 'raw.githubusercontent.com', 'port': '', 'pathname': '/miute/svgpy/master/tests/svg/svg.svg', 'search': {}, 'hash': ''}
    >>> document.origin
    'https://raw.githubusercontent.com'
    >>> root = document.document_element
    >>> for element in root.iter():
    ...     print(element)
    ...
    <Element {http://www.w3.org/2000/svg}svg at 0x7fd7390b2958>
    <Element {http://www.w3.org/2000/svg}g at 0x7fd7390b2e58>
    <Element {http://www.w3.org/2000/svg}g at 0x7fd7390b2ea8>
    <Element {http://www.w3.org/2000/svg}path at 0x7fd7390b2e08>
    <Element {http://www.w3.org/2000/svg}use at 0x7fd7390b2db8>
    <Element {http://www.w3.org/2000/svg}use at 0x7fd7390b2a98>
    <Element {http://www.w3.org/2000/svg}use at 0x7fd7390b2b88>
    <Element {http://www.w3.org/2000/svg}use at 0x7fd7390c8048>
    >>> sheets = document.style_sheets
    >>> len(sheets)
    1
    >>> for rule in sheets[0].css_rules:
    ...     print(rule)
    ...
    ('CSSNamespaceRule', {'namespaceURI': 'http://www.w3.org/2000/svg', 'prefix': ''})
    ('CSSNamespaceRule', {'namespaceURI': 'http://www.w3.org/XML/1998/namespace', 'prefix': 'xml'})
    ('CSSStyleRule', 'svg:not(:root), hatch, image, marker, pattern, symbol', ('CSSStyleDeclaration', {'overflow': ('hidden', '')}))
    ('CSSStyleRule', '*:not(svg), *:not(foreignObject) > svg', ('CSSStyleDeclaration', {'transform-origin': ('0 0', '')}))
    ('CSSStyleRule', '*[xml|space=preserve]', ('CSSStyleDeclaration', {'text-space-collapse': ('preserve-spaces', '')}))
    ('CSSStyleRule', 'defs, clipPath, mask, marker, desc, title, metadata, pattern, hatch, linearGradient, radialGradient, meshGradient, script, style, symbol', ('CSSStyleDeclaration', {'display': ('none', 'important')}))
    ('CSSStyleRule', ':host(use) > symbol', ('CSSStyleDeclaration', {'display': ('inline', 'important')}))

License

This software is licensed under the Apache License 2.0.

svgpy's People

Contributors

miute avatar

Watchers

 avatar

Forkers

destos

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.