add ability to preserve svg-attributes

Added svg_attributes attribute to wsvg and disvg.
Added return_svg_attributes option to svg2paths.
Added convenience function svg2paths2().
pull/4/head
Andy 2016-07-15 22:10:59 -07:00
parent 0c682bf4d8
commit 15d186ff33
7 changed files with 89 additions and 34 deletions

View File

@ -86,7 +86,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 16, "execution_count": 5,
"metadata": { "metadata": {
"collapsed": true "collapsed": true
}, },
@ -97,7 +97,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 17, "execution_count": 6,
"metadata": { "metadata": {
"collapsed": false "collapsed": false
}, },
@ -147,7 +147,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 18, "execution_count": 7,
"metadata": { "metadata": {
"collapsed": false "collapsed": false
}, },
@ -224,7 +224,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 19, "execution_count": 8,
"metadata": { "metadata": {
"collapsed": false "collapsed": false
}, },
@ -244,6 +244,11 @@
"from svgpathtools import svg2paths, wsvg\n", "from svgpathtools import svg2paths, wsvg\n",
"paths, attributes = svg2paths('test.svg')\n", "paths, attributes = svg2paths('test.svg')\n",
"\n", "\n",
"# Update: You can now also extract the svg-attributes by setting\n",
"# return_svg_attributes=True, or with the convenience function svg2paths2\n",
"from svgpathtools import svg2paths2\n",
"paths, attributes, svg_attributes = svg2paths2('test.svg')\n",
"\n",
"# Let's print out the first path object and the color it was in the SVG\n", "# Let's print out the first path object and the color it was in the SVG\n",
"# We'll see it is composed of two CubicBezier objects and, in the SVG file it \n", "# We'll see it is composed of two CubicBezier objects and, in the SVG file it \n",
"# came from, it was red\n", "# came from, it was red\n",
@ -265,14 +270,14 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 20, "execution_count": 9,
"metadata": { "metadata": {
"collapsed": false "collapsed": false
}, },
"outputs": [], "outputs": [],
"source": [ "source": [
"# Let's make a new SVG that's identical to the first\n", "# Let's make a new SVG that's identical to the first\n",
"wsvg(paths, attributes=attributes, filename='output1.svg')" "wsvg(paths, attributes=attributes, svg_attributes=svg_attributes, filename='output1.svg')"
] ]
}, },
{ {
@ -300,7 +305,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 21, "execution_count": 10,
"metadata": { "metadata": {
"collapsed": false "collapsed": false
}, },
@ -363,7 +368,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 22, "execution_count": 11,
"metadata": { "metadata": {
"collapsed": false "collapsed": false
}, },
@ -411,7 +416,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 23, "execution_count": 12,
"metadata": { "metadata": {
"collapsed": false "collapsed": false
}, },
@ -466,7 +471,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 24, "execution_count": 13,
"metadata": { "metadata": {
"collapsed": false "collapsed": false
}, },
@ -509,7 +514,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 25, "execution_count": 14,
"metadata": { "metadata": {
"collapsed": false "collapsed": false
}, },
@ -551,7 +556,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 26, "execution_count": 15,
"metadata": { "metadata": {
"collapsed": false "collapsed": false
}, },
@ -606,7 +611,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 27, "execution_count": 16,
"metadata": { "metadata": {
"collapsed": false "collapsed": false
}, },
@ -641,7 +646,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 28, "execution_count": 17,
"metadata": { "metadata": {
"collapsed": false "collapsed": false
}, },
@ -734,7 +739,7 @@
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython2", "pygments_lexer": "ipython2",
"version": "2.7.11" "version": "2.7.12"
} }
}, },
"nbformat": 4, "nbformat": 4,

View File

@ -225,6 +225,11 @@ Reading SVGSs
from svgpathtools import svg2paths, wsvg from svgpathtools import svg2paths, wsvg
paths, attributes = svg2paths('test.svg') paths, attributes = svg2paths('test.svg')
# Update: You can now also extract the svg-attributes by setting
# return_svg_attributes=True, or with the convenience function svg2paths2
from svgpathtools import svg2paths2
paths, attributes, svg_attributes = svg2paths2('test.svg')
# Let's print out the first path object and the color it was in the SVG # Let's print out the first path object and the color it was in the SVG
# We'll see it is composed of two CubicBezier objects and, in the SVG file it # We'll see it is composed of two CubicBezier objects and, in the SVG file it
# came from, it was red # came from, it was red
@ -254,7 +259,7 @@ viewer.
.. code:: python .. code:: python
# Let's make a new SVG that's identical to the first # Let's make a new SVG that's identical to the first
wsvg(paths, attributes=attributes, filename='output1.svg') wsvg(paths, attributes=attributes, svg_attributes=svg_attributes, filename='output1.svg')
.. figure:: https://cdn.rawgit.com/mathandy/svgpathtools/master/output1.svg .. figure:: https://cdn.rawgit.com/mathandy/svgpathtools/master/output1.svg
:alt: output1.svg :alt: output1.svg

View File

@ -1,5 +1,5 @@
<?xml version="1.0" ?> <?xml version="1.0" ?>
<svg baseProfile="full" height="600px" version="1.1" viewBox="-20.6525 -20.6525 366.305 366.305" width="600px" xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink"> <svg baseProfile="full" height="100%" version="1.1" viewBox="-20.6525 -20.6525 366.305 366.305" width="100%" xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs/> <defs/>
<path d="M 10.5,80.0 C 40.0,10.0 65.0,10.0 95.0,80.0 C 125.0,150.0 150.0,150.0 180.0,80.0" fill="none" stroke="red"/> <path d="M 10.5,80.0 C 40.0,10.0 65.0,10.0 95.0,80.0 C 125.0,150.0 150.0,150.0 180.0,80.0" fill="none" stroke="red"/>
<path d="M 84.0,92.0 C 94.0,102.0 114.0,102.0 124.0,92.0" fill="none" stroke="purple"/> <path d="M 84.0,92.0 C 94.0,102.0 114.0,102.0 124.0,92.0" fill="none" stroke="purple"/>

Before

Width:  |  Height:  |  Size: 776 B

After

Width:  |  Height:  |  Size: 774 B

View File

@ -1,6 +1,6 @@
from distutils.core import setup from distutils.core import setup
VERSION = '1.0.1' VERSION = '1.1'
AUTHOR_NAME = 'Andy Port' AUTHOR_NAME = 'Andy Port'
AUTHOR_EMAIL = 'AndyAPort@gmail.com' AUTHOR_EMAIL = 'AndyAPort@gmail.com'

View File

@ -14,6 +14,6 @@ from .misctools import hex2rgb, rgb2hex
from .smoothing import smoothed_path, smoothed_joint, is_differentiable, kinks from .smoothing import smoothed_path, smoothed_joint, is_differentiable, kinks
try: try:
from .svg2paths import svg2paths from .svg2paths import svg2paths, svg2paths2
except ImportError: except ImportError:
pass pass

View File

@ -88,7 +88,7 @@ def disvg(paths=None, colors=None,
openinbrowser=True, timestamp=False, openinbrowser=True, timestamp=False,
margin_size=0.1, mindim=600, dimensions=None, margin_size=0.1, mindim=600, dimensions=None,
viewbox=None, text=None, text_path=None, font_size=None, viewbox=None, text=None, text_path=None, font_size=None,
attributes=None): attributes=None, svg_attributes=None):
"""Takes in a list of paths and creates an SVG file containing said paths. """Takes in a list of paths and creates an SVG file containing said paths.
REQUIRED INPUTS: REQUIRED INPUTS:
:param paths - a list of paths :param paths - a list of paths
@ -148,8 +148,11 @@ def disvg(paths=None, colors=None,
(min_x, min_y, width, height). This is different from the display (min_x, min_y, width, height). This is different from the display
dimension of the svg, which can be set through mindim or dimensions. dimension of the svg, which can be set through mindim or dimensions.
:param attributes - a dictionary of attributes for the input paths. :param attributes - a list of dictionaries of attributes for the input
This will override any other conflicting settings. paths. Note: This will override any other conflicting settings.
:param svg_attributes - a dictionary of attributes for output svg.
Note: This will override any other conflicting settings.
NOTES: NOTES:
-The unit of length here is assumed to be pixels in all variables. -The unit of length here is assumed to be pixels in all variables.
@ -272,6 +275,9 @@ def disvg(paths=None, colors=None,
szy = str(mindim) + 'px' szy = str(mindim) + 'px'
# Create an SVG file # Create an SVG file
if svg_attributes:
dwg = Drawing(filename=filename, **svg_attributes)
else:
dwg = Drawing(filename=filename, size=(szx, szy), viewBox=viewbox) dwg = Drawing(filename=filename, size=(szx, szy), viewBox=viewbox)
# add paths # add paths
@ -367,7 +373,7 @@ def wsvg(paths=None, colors=None,
openinbrowser=False, timestamp=False, openinbrowser=False, timestamp=False,
margin_size=0.1, mindim=600, dimensions=None, margin_size=0.1, mindim=600, dimensions=None,
viewbox=None, text=None, text_path=None, font_size=None, viewbox=None, text=None, text_path=None, font_size=None,
attributes=None): attributes=None, svg_attributes=None):
"""Convenience function; identical to disvg() except that """Convenience function; identical to disvg() except that
openinbrowser=False by default. See disvg() docstring for more info.""" openinbrowser=False by default. See disvg() docstring for more info."""
disvg(paths, colors=colors, filename=filename, disvg(paths, colors=colors, filename=filename,
@ -375,5 +381,5 @@ def wsvg(paths=None, colors=None,
node_colors=node_colors, node_radii=node_radii, node_colors=node_colors, node_radii=node_radii,
openinbrowser=openinbrowser, timestamp=timestamp, openinbrowser=openinbrowser, timestamp=timestamp,
margin_size=margin_size, mindim=mindim, dimensions=dimensions, margin_size=margin_size, mindim=mindim, dimensions=dimensions,
viewbox=viewbox, text=text, text_path=text_path, viewbox=viewbox, text=text, text_path=text_path, font_size=font_size,
font_size=font_size, attributes=attributes) attributes=attributes, svg_attributes=svg_attributes)

View File

@ -5,6 +5,7 @@ The main tool being the svg2paths() function."""
from __future__ import division, absolute_import, print_function from __future__ import division, absolute_import, print_function
from xml.dom.minidom import parse from xml.dom.minidom import parse
from os import path as os_path, getcwd from os import path as os_path, getcwd
from shutil import copyfile
# Internal dependencies # Internal dependencies
from .parser import parse_path from .parser import parse_path
@ -33,7 +34,8 @@ def polyline2pathd(polyline_d):
def svg2paths(svg_file_location, def svg2paths(svg_file_location,
convert_lines_to_paths=True, convert_lines_to_paths=True,
convert_polylines_to_paths=True, convert_polylines_to_paths=True,
convert_polygons_to_paths=True): convert_polygons_to_paths=True,
return_svg_attributes=False):
""" """
Converts an SVG file into a list of Path objects and a list of Converts an SVG file into a list of Path objects and a list of
dictionaries containing their attributes. This currently supports dictionaries containing their attributes. This currently supports
@ -45,12 +47,20 @@ def svg2paths(svg_file_location,
objects (converted to Paths) objects (converted to Paths)
:param convert_polygons_to_paths: Set to False to disclude SVG-Polygon :param convert_polygons_to_paths: Set to False to disclude SVG-Polygon
objects (converted to Paths) objects (converted to Paths)
:return: list of Path objects :param return_svg_attributes: Set to True and a dictionary of
svg-attributes will be extracted and returned
:return: list of Path objects, list of path attribute dictionaries, and
(optionally) a dictionary of svg-attributes
""" """
if os_path.dirname(svg_file_location) == '': if os_path.dirname(svg_file_location) == '':
svg_file_location = os_path.join(getcwd(), svg_file_location) svg_file_location = os_path.join(getcwd(), svg_file_location)
doc = parse(svg_file_location) # parseString also exists # if pathless_svg:
# copyfile(svg_file_location, pathless_svg)
# doc = parse(pathless_svg)
# else:
doc = parse(svg_file_location)
def dom2dict(element): def dom2dict(element):
"""Converts DOM elements to dictionaries of attributes.""" """Converts DOM elements to dictionaries of attributes."""
@ -62,6 +72,9 @@ def svg2paths(svg_file_location,
paths = [dom2dict(el) for el in doc.getElementsByTagName('path')] paths = [dom2dict(el) for el in doc.getElementsByTagName('path')]
d_strings = [el['d'] for el in paths] d_strings = [el['d'] for el in paths]
attribute_dictionary_list = paths attribute_dictionary_list = paths
# if pathless_svg:
# for el in doc.getElementsByTagName('path'):
# el.parentNode.removeChild(el)
# Use minidom to extract polyline strings from input SVG, convert to # Use minidom to extract polyline strings from input SVG, convert to
# path strings, add to list # path strings, add to list
@ -82,6 +95,32 @@ def svg2paths(svg_file_location,
d_strings += [('M' + l['x1'] + ' ' + l['y1'] + d_strings += [('M' + l['x1'] + ' ' + l['y1'] +
'L' + l['x2'] + ' ' + l['y2']) for l in lines] 'L' + l['x2'] + ' ' + l['y2']) for l in lines]
attribute_dictionary_list += lines attribute_dictionary_list += lines
# if pathless_svg:
# with open(pathless_svg, "wb") as f:
# doc.writexml(f)
if return_svg_attributes:
svg_attributes = dom2dict(doc.getElementsByTagName('svg')[0])
doc.unlink()
path_list = [parse_path(d) for d in d_strings]
return path_list, attribute_dictionary_list, svg_attributes
else:
doc.unlink() doc.unlink()
path_list = [parse_path(d) for d in d_strings] path_list = [parse_path(d) for d in d_strings]
return path_list, attribute_dictionary_list return path_list, attribute_dictionary_list
def svg2paths2(svg_file_location,
convert_lines_to_paths=True,
convert_polylines_to_paths=True,
convert_polygons_to_paths=True,
return_svg_attributes=True):
"""Convenience function; identical to svg2paths() except that
return_svg_attributes=True by default. See svg2paths() docstring for more
info."""
return svg2paths(svg_file_location=svg_file_location,
convert_lines_to_paths=convert_lines_to_paths,
convert_polylines_to_paths=convert_polylines_to_paths,
convert_polygons_to_paths=convert_polygons_to_paths,
return_svg_attributes=return_svg_attributes)