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",
"execution_count": 16,
"execution_count": 5,
"metadata": {
"collapsed": true
},
@ -97,7 +97,7 @@
},
{
"cell_type": "code",
"execution_count": 17,
"execution_count": 6,
"metadata": {
"collapsed": false
},
@ -147,7 +147,7 @@
},
{
"cell_type": "code",
"execution_count": 18,
"execution_count": 7,
"metadata": {
"collapsed": false
},
@ -224,7 +224,7 @@
},
{
"cell_type": "code",
"execution_count": 19,
"execution_count": 8,
"metadata": {
"collapsed": false
},
@ -244,6 +244,11 @@
"from svgpathtools import svg2paths, wsvg\n",
"paths, attributes = svg2paths('test.svg')\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",
"# We'll see it is composed of two CubicBezier objects and, in the SVG file it \n",
"# came from, it was red\n",
@ -265,14 +270,14 @@
},
{
"cell_type": "code",
"execution_count": 20,
"execution_count": 9,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# 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",
"execution_count": 21,
"execution_count": 10,
"metadata": {
"collapsed": false
},
@ -363,7 +368,7 @@
},
{
"cell_type": "code",
"execution_count": 22,
"execution_count": 11,
"metadata": {
"collapsed": false
},
@ -411,7 +416,7 @@
},
{
"cell_type": "code",
"execution_count": 23,
"execution_count": 12,
"metadata": {
"collapsed": false
},
@ -466,7 +471,7 @@
},
{
"cell_type": "code",
"execution_count": 24,
"execution_count": 13,
"metadata": {
"collapsed": false
},
@ -509,7 +514,7 @@
},
{
"cell_type": "code",
"execution_count": 25,
"execution_count": 14,
"metadata": {
"collapsed": false
},
@ -551,7 +556,7 @@
},
{
"cell_type": "code",
"execution_count": 26,
"execution_count": 15,
"metadata": {
"collapsed": false
},
@ -606,7 +611,7 @@
},
{
"cell_type": "code",
"execution_count": 27,
"execution_count": 16,
"metadata": {
"collapsed": false
},
@ -641,7 +646,7 @@
},
{
"cell_type": "code",
"execution_count": 28,
"execution_count": 17,
"metadata": {
"collapsed": false
},
@ -734,7 +739,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.11"
"version": "2.7.12"
}
},
"nbformat": 4,

View File

@ -225,6 +225,11 @@ Reading SVGSs
from svgpathtools import svg2paths, wsvg
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
# We'll see it is composed of two CubicBezier objects and, in the SVG file it
# came from, it was red
@ -254,7 +259,7 @@ viewer.
.. code:: python
# 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
:alt: output1.svg

View File

@ -1,5 +1,5 @@
<?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/>
<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"/>

Before

Width:  |  Height:  |  Size: 776 B

After

Width:  |  Height:  |  Size: 774 B

View File

@ -1,6 +1,6 @@
from distutils.core import setup
VERSION = '1.0.1'
VERSION = '1.1'
AUTHOR_NAME = 'Andy Port'
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
try:
from .svg2paths import svg2paths
from .svg2paths import svg2paths, svg2paths2
except ImportError:
pass

View File

@ -88,7 +88,7 @@ def disvg(paths=None, colors=None,
openinbrowser=True, timestamp=False,
margin_size=0.1, mindim=600, dimensions=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.
REQUIRED INPUTS:
: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
dimension of the svg, which can be set through mindim or dimensions.
:param attributes - a dictionary of attributes for the input paths.
This will override any other conflicting settings.
:param attributes - a list of dictionaries of attributes for the input
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:
-The unit of length here is assumed to be pixels in all variables.
@ -272,7 +275,10 @@ def disvg(paths=None, colors=None,
szy = str(mindim) + 'px'
# Create an SVG file
dwg = Drawing(filename=filename, size=(szx, szy), viewBox=viewbox)
if svg_attributes:
dwg = Drawing(filename=filename, **svg_attributes)
else:
dwg = Drawing(filename=filename, size=(szx, szy), viewBox=viewbox)
# add paths
if paths:
@ -367,7 +373,7 @@ def wsvg(paths=None, colors=None,
openinbrowser=False, timestamp=False,
margin_size=0.1, mindim=600, dimensions=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
openinbrowser=False by default. See disvg() docstring for more info."""
disvg(paths, colors=colors, filename=filename,
@ -375,5 +381,5 @@ def wsvg(paths=None, colors=None,
node_colors=node_colors, node_radii=node_radii,
openinbrowser=openinbrowser, timestamp=timestamp,
margin_size=margin_size, mindim=mindim, dimensions=dimensions,
viewbox=viewbox, text=text, text_path=text_path,
font_size=font_size, attributes=attributes)
viewbox=viewbox, text=text, text_path=text_path, font_size=font_size,
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 xml.dom.minidom import parse
from os import path as os_path, getcwd
from shutil import copyfile
# Internal dependencies
from .parser import parse_path
@ -31,9 +32,10 @@ def polyline2pathd(polyline_d):
def svg2paths(svg_file_location,
convert_lines_to_paths=True,
convert_polylines_to_paths=True,
convert_polygons_to_paths=True):
convert_lines_to_paths=True,
convert_polylines_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
dictionaries containing their attributes. This currently supports
@ -45,12 +47,20 @@ def svg2paths(svg_file_location,
objects (converted to Paths)
:param convert_polygons_to_paths: Set to False to disclude SVG-Polygon
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) == '':
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):
"""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')]
d_strings = [el['d'] for el in 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
# path strings, add to list
@ -82,6 +95,32 @@ def svg2paths(svg_file_location,
d_strings += [('M' + l['x1'] + ' ' + l['y1'] +
'L' + l['x2'] + ' ' + l['y2']) for l in lines]
attribute_dictionary_list += lines
doc.unlink()
path_list = [parse_path(d) for d in d_strings]
return path_list, attribute_dictionary_list
# 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()
path_list = [parse_path(d) for d in d_strings]
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)