Skip to content

Commit

Permalink
add ability to preserve svg-attributes
Browse files Browse the repository at this point in the history
Added svg_attributes attribute to wsvg and disvg.
Added return_svg_attributes option to svg2paths.
Added convenience function svg2paths2().
  • Loading branch information
mathandy committed Jul 16, 2016
1 parent 0c682bf commit 15d186f
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 34 deletions.
35 changes: 20 additions & 15 deletions README.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
},
{
"cell_type": "code",
"execution_count": 16,
"execution_count": 5,
"metadata": {
"collapsed": true
},
Expand All @@ -97,7 +97,7 @@
},
{
"cell_type": "code",
"execution_count": 17,
"execution_count": 6,
"metadata": {
"collapsed": false
},
Expand Down Expand Up @@ -147,7 +147,7 @@
},
{
"cell_type": "code",
"execution_count": 18,
"execution_count": 7,
"metadata": {
"collapsed": false
},
Expand Down Expand Up @@ -224,7 +224,7 @@
},
{
"cell_type": "code",
"execution_count": 19,
"execution_count": 8,
"metadata": {
"collapsed": false
},
Expand All @@ -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",
Expand All @@ -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')"
]
},
{
Expand Down Expand Up @@ -300,7 +305,7 @@
},
{
"cell_type": "code",
"execution_count": 21,
"execution_count": 10,
"metadata": {
"collapsed": false
},
Expand Down Expand Up @@ -363,7 +368,7 @@
},
{
"cell_type": "code",
"execution_count": 22,
"execution_count": 11,
"metadata": {
"collapsed": false
},
Expand Down Expand Up @@ -411,7 +416,7 @@
},
{
"cell_type": "code",
"execution_count": 23,
"execution_count": 12,
"metadata": {
"collapsed": false
},
Expand Down Expand Up @@ -466,7 +471,7 @@
},
{
"cell_type": "code",
"execution_count": 24,
"execution_count": 13,
"metadata": {
"collapsed": false
},
Expand Down Expand Up @@ -509,7 +514,7 @@
},
{
"cell_type": "code",
"execution_count": 25,
"execution_count": 14,
"metadata": {
"collapsed": false
},
Expand Down Expand Up @@ -551,7 +556,7 @@
},
{
"cell_type": "code",
"execution_count": 26,
"execution_count": 15,
"metadata": {
"collapsed": false
},
Expand Down Expand Up @@ -606,7 +611,7 @@
},
{
"cell_type": "code",
"execution_count": 27,
"execution_count": 16,
"metadata": {
"collapsed": false
},
Expand Down Expand Up @@ -641,7 +646,7 @@
},
{
"cell_type": "code",
"execution_count": 28,
"execution_count": 17,
"metadata": {
"collapsed": false
},
Expand Down Expand Up @@ -734,7 +739,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.11"
"version": "2.7.12"
}
},
"nbformat": 4,
Expand Down
7 changes: 6 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion output1.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from distutils.core import setup

VERSION = '1.0.1'
VERSION = '1.1'
AUTHOR_NAME = 'Andy Port'
AUTHOR_EMAIL = '[email protected]'

Expand Down
2 changes: 1 addition & 1 deletion svgpathtools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@
from .smoothing import smoothed_path, smoothed_joint, is_differentiable, kinks

try:
from .svg2paths import svg2paths
from .svg2paths import svg2paths, svg2paths2
except ImportError:
pass
20 changes: 13 additions & 7 deletions svgpathtools/paths2svg.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -367,13 +373,13 @@ 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,
stroke_widths=stroke_widths, nodes=nodes,
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)
55 changes: 47 additions & 8 deletions svgpathtools/svg2paths.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
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
Expand All @@ -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
Expand All @@ -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."""
Expand All @@ -62,6 +72,9 @@ def dom2dict(element):
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
Expand All @@ -82,6 +95,32 @@ def dom2dict(element):
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)

0 comments on commit 15d186f

Please sign in to comment.