Document now stores element and transform in path and Document.display() is fixed

pull/114/head
Andy Port 2020-06-23 20:50:43 -07:00
parent b503b9b3a5
commit d673176347
2 changed files with 31 additions and 28 deletions

View File

@ -15,15 +15,14 @@ Example:
>> from svgpathtools import * >> from svgpathtools import *
>> doc = Document('my_file.html') >> doc = Document('my_file.html')
>> results = doc.flatten_all_paths() >> for path in doc.flatten_all_paths():
>> for result in results:
>> path = result.path
>> # Do something with the transformed Path object. >> # Do something with the transformed Path object.
>> element = result.element >> foo(path)
>> # Inspect the raw SVG element. This gives access to the >> # Inspect the raw SVG element, e.g. change its attributes
>> # path's attributes >> foo(path.element)
>> transform = result.transform >> transform = result.transform
>> # Use the transform that was applied to the path. >> # Use the transform that was applied to the path.
>> foo(path.transform)
>> foo(doc.tree) # do stuff using ElementTree's functionality >> foo(doc.tree) # do stuff using ElementTree's functionality
>> doc.display() # display doc in OS's default application >> doc.display() # display doc in OS's default application
>> doc.save('my_new_file.html') >> doc.save('my_new_file.html')
@ -41,6 +40,8 @@ import collections
import xml.etree.ElementTree as etree import xml.etree.ElementTree as etree
from xml.etree.ElementTree import Element, SubElement, register_namespace from xml.etree.ElementTree import Element, SubElement, register_namespace
import warnings import warnings
from tempfile import gettempdir
from time import time
# Internal dependencies # Internal dependencies
from .parser import parse_path from .parser import parse_path
@ -126,10 +127,7 @@ def flatten_all_paths(group, group_filter=lambda x: True,
stack = [new_stack_element(group, np.identity(3))] stack = [new_stack_element(group, np.identity(3))]
FlattenedPath = collections.namedtuple('FlattenedPath',
['path', 'element', 'transform'])
paths = [] paths = []
while stack: while stack:
top = stack.pop() top = stack.pop()
@ -142,7 +140,9 @@ def flatten_all_paths(group, group_filter=lambda x: True,
path_tf = top.transform.dot( path_tf = top.transform.dot(
parse_transform(path_elem.get('transform'))) parse_transform(path_elem.get('transform')))
path = transform(parse_path(converter(path_elem)), path_tf) path = transform(parse_path(converter(path_elem)), path_tf)
paths.append(FlattenedPath(path, path_elem, path_tf)) path.element = path_elem
path.transform = path_tf
paths.append(path)
stack.extend(get_relevant_children(top.group, top.transform)) stack.extend(get_relevant_children(top.group, top.transform))
@ -222,7 +222,7 @@ def flatten_group(group_to_flatten, root, recursive=True,
class Document: class Document:
def __init__(self, filename): def __init__(self, filepath):
"""A container for a DOM-style SVG document. """A container for a DOM-style SVG document.
The `Document` class provides a simple interface to modify and analyze The `Document` class provides a simple interface to modify and analyze
@ -230,21 +230,20 @@ class Document:
parsed into an ElementTree object (stored in the `tree` attribute). parsed into an ElementTree object (stored in the `tree` attribute).
This class provides functions for extracting SVG data into Path objects. This class provides functions for extracting SVG data into Path objects.
The Path output objects will be transformed based on their parent groups. The output Path objects will be transformed based on their parent groups.
Args: Args:
filename (str): The filename of the DOM-style object. filepath (str): The filepath of the DOM-style object.
""" """
# remember location of original svg file # remember location of original svg file
if filename is not None and os.path.dirname(filename) == '': self.original_filepath = filepath
self.original_filename = os.path.join(os.getcwd(), filename) if filepath is not None and os.path.dirname(filepath) == '':
else: self.original_filepath = os.path.join(os.getcwd(), filepath)
self.original_filename = filename
if filename is not None: if filepath is not None:
# parse svg to ElementTree object # parse svg to ElementTree object
self.tree = etree.parse(filename) self.tree = etree.parse(filepath)
else: else:
self.tree = etree.ElementTree(Element('svg')) self.tree = etree.ElementTree(Element('svg'))
@ -412,18 +411,21 @@ class Document:
return SubElement(parent, '{{{0}}}g'.format( return SubElement(parent, '{{{0}}}g'.format(
SVG_NAMESPACE['svg']), group_attribs) SVG_NAMESPACE['svg']), group_attribs)
def save(self, filename): def save(self, filepath):
with open(filename, 'w') as output_svg: with open(filepath, 'w') as output_svg:
output_svg.write(etree.tostring(self.tree.getroot())) output_svg.write(etree.tostring(self.tree.getroot()))
def display(self, filename=None): def display(self, filepath=None):
"""Displays/opens the doc using the OS's default application.""" """Displays/opens the doc using the OS's default application."""
if filename is None: if filepath is None:
filename = self.original_filename orig_name, ext = \
os.path.splitext(os.path.basename(self.original_filepath))
filepath = os.path.join(gettempdir(),
orig_name + '_' + str(time()).replace('.', '-') + ext)
# write to a (by default temporary) file # write to a (by default temporary) file
with open(filename, 'w') as output_svg: with open(filepath, 'w') as output_svg:
output_svg.write(etree.tostring(self.tree.getroot())) output_svg.write(etree.tostring(self.tree.getroot()).decode())
open_in_browser(filename) open_in_browser(filepath)

View File

@ -2199,7 +2199,8 @@ class Path(MutableSequence):
_closed = False _closed = False
_start = None _start = None
_end = None _end = None
attributes = None element = None
transform = None
meta = None # meant as container for storage of arbitrary meta data meta = None # meant as container for storage of arbitrary meta data
def __init__(self, *segments, **kw): def __init__(self, *segments, **kw):