From d4703adfcbbfcd24499ee4aa7ee47703f00a1ff7 Mon Sep 17 00:00:00 2001 From: Henrik Johansson Date: Thu, 26 Sep 2013 08:23:23 +0200 Subject: [PATCH] added functionality to transform.fromstring which add a prefix to all ids in order to avoid id name clashes --- src/svgutils/transform.py | 18 ++++++++++++++++-- src/svgutils/util.py | 25 +++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 src/svgutils/util.py diff --git a/src/svgutils/transform.py b/src/svgutils/transform.py index c1e981e..3fef4a1 100644 --- a/src/svgutils/transform.py +++ b/src/svgutils/transform.py @@ -6,6 +6,8 @@ except ImportError: from io import StringIO +import util + SVG_NAMESPACE = "http://www.w3.org/2000/svg" SVG = "{%s}" % SVG_NAMESPACE NSMAP = {None : SVG_NAMESPACE} @@ -54,6 +56,12 @@ def __init__(self, element_list): class SVGFigure(object): def __init__(self, width=None, height=None): + # create a unique id + if not hasattr(SVGFigure, 'maxid'): + SVGFigure.maxid = 0 + self.id = SVGFigure.maxid + 1 + SVGFigure.maxid = self.id + self.root = etree.Element(SVG+"svg",nsmap=NSMAP) self.root.set("version", "1.1") if width or height: @@ -96,13 +104,19 @@ def set_size(self, size): self.root.set('width', w) self.root.set('height', h) -def fromfile(fname): +def fromfile(fname, idprefix=None): fig = SVGFigure() fid = open(fname) svg_file = etree.parse(fid) fid.close() + + # make id's unique in order to avoid clashes + if idprefix is None: + idprefix = 'inst%d_' % fig.id + fig_root = util.svg_id_prepend(svg_file.getroot(), prefix=idprefix) + + fig.root = fig_root - fig.root = svg_file.getroot() return fig def fromstring(text): diff --git a/src/svgutils/util.py b/src/svgutils/util.py new file mode 100644 index 0000000..1440670 --- /dev/null +++ b/src/svgutils/util.py @@ -0,0 +1,25 @@ +import copy +import re + +def svg_id_prepend(root, prefix): + """Append prefix to id attributes and url(#id) references""" + + root = copy.deepcopy(root) + + id_attributes = {} + ## Replace id attributes + for e in root.findall("*//*[@id]"): + idvalue = e.attrib['id'] + newidvalue = prefix + idvalue + e.attrib['id'] = newidvalue + + id_attributes[idvalue] = newidvalue + + ## Update references + for e in root.xpath("//*[contains(@*, 'url(#')]"): + for attr, value in e.attrib.items(): + matchobj = re.match('url\(#(.*)\)', value) + if matchobj and matchobj.groups()[0] in id_attributes: + e.attrib[attr] = 'url(#%s)' % id_attributes[matchobj.groups()[0]] + + return root