Skip to content

Commit

Permalink
SVG styling with classes didn't work out, so a quick 0.8.2 release.
Browse files Browse the repository at this point in the history
  • Loading branch information
cwant committed Jul 4, 2023
1 parent e5b9e87 commit d262351
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 90 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Tessellate your favorite 3D surfaces (technically, 2D manifolds) with triangles,
**You can find a Blender (3.6) pull request to add support for Tessagon in the "XYZ function" addon here:
<https://projects.blender.org/blender/blender-addons/pulls/104726>**

**Check out my presentation on the creation of Tessagon as an open source Python project here: <https://cwant.github.io/python-os-presentation>**
**Check out my presentation on the creation of Tessagon as an open source Python project here: <https://cwant.github.io/python-os-presentation> (or watch on [YouTube](https://www.youtube.com/watch?v=R0hG9hHs9Fw))**

**A demo of using Tessagon with Inkscape Simple Scripting can be found [here](https://gist.github.com/cwant/697f0c6ce07d9e14e710f5b80ca5eece).**

Expand Down
84 changes: 48 additions & 36 deletions tessagon/adaptors/svg_adaptor.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,54 +21,66 @@ def get_mesh(self):
buffer = ""
if self.svg_root_tag:
if self.svg_root_tag is True:
buffer += '<svg xmlns="http://www.w3.org/2000/svg">'
buffer += '<svg xmlns="http://www.w3.org/2000/svg">\n'
else:
buffer += self.svg_root_tag
buffer += "<g>"

style = self.make_style()
if style:
buffer += "<style>{}</style>".format(style)
buffer += "<g{}>\n".format(self.group_style())

for i in range(len(self.face_list)):
face = self.face_list[i]
class_string = ""
if len(self.color_list) > 0:
color = self.color_list[i]
class_string = ' class="color-{}"'.format(color)
verts = [self.vert_list[v] for v in face]
points_string = \
' '.join(["{},{}".format(vert[0],
vert[1]) for vert in verts])
buffer += '<polygon points="{}"{} />'.format(points_string,
class_string)
buffer += "</g>"
if self.svg_root_tag:
buffer += "</svg>"
return buffer

def make_style(self):
if self.style:
return self.style
buffer += "<style>{}</style>".format(self.style)

style = ""
polygon_style = ""
if self.svg_fill_colors:
color_indices = self.make_color_indices()
for i in range(len(self.svg_fill_colors)):
style += '.color-{} {{\n fill:{};\n}}\n'.\
format(i, self.svg_fill_colors[i])
if i not in color_indices:
continue
fill_color = self.svg_fill_colors[i]
faces = [self.face_list[j] for j in color_indices[i]]
buffer += self.make_color_group(faces, fill_color)
else:
for face in self.face_list:
buffer += self.make_face(face)

buffer += "</g>\n"
if self.svg_root_tag:
buffer += "</svg>\n"
return buffer

def group_style(self):
style = ""
if self.svg_stroke_color:
polygon_style += ' stroke:{};\n'.format(self.svg_stroke_color)
style += 'stroke:{};'.format(self.svg_stroke_color)
if self.svg_stroke_width:
polygon_style += " stroke-width:{};\n".\
style += "stroke-width:{};".\
format(self.svg_stroke_width)
if self.svg_fill_color:
polygon_style += ' fill:{};\n'.format(self.svg_fill_color)
style += 'fill:{};'.format(self.svg_fill_color)
if len(style) > 0:
style = ' style="{}"'.format(style)
return style

if len(polygon_style) > 0:
style += "polygon {{\n{}}}\n".format(polygon_style)
def make_color_indices(self):
color_indices = {}
for i in range(len(self.color_list)):
color = self.color_list[i]
if color not in color_indices:
color_indices[color] = []
color_indices[color].append(i)

if len(style) > 0:
return style
return color_indices

def make_color_group(self, faces, fill_color):
buffer = '<g style="fill:{};">\n'.format(fill_color)
for face in faces:
buffer += self.make_face(face)
buffer += '</g>\n'

return buffer

return None
def make_face(self, face):
verts = [self.vert_list[v] for v in face]
points_string = \
' '.join(["{},{}".format(vert[0],
vert[1]) for vert in verts])
return '<polygon points="{}" />'.format(points_string)
2 changes: 1 addition & 1 deletion tessagon/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.8.1'
__version__ = '0.8.2'
78 changes: 26 additions & 52 deletions tests/adaptors/test_svg_adaptor.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,22 @@ class SvgToList(HTMLParser):
def __init__(self):
HTMLParser.__init__(self)
self.parts = []
self.getting_style = False
self.style = ""
self.getting_data = False

def handle_starttag(self, tag, attrs):
self.parts.append(tag)
for attr in attrs:
self.parts.append(attr[0])
self.parts.append(attr[1])
if tag == "style":
self.getting_style = True
self.getting_data = True
else:
self.getting_style = False
self.getting_data = False

def handle_data(self, data):
if self.getting_style:
self.style = data
# Just through the style info on the list
if self.getting_data:
self.parts.append(data)


class TestSvgAdaptor:
Expand Down Expand Up @@ -62,17 +62,13 @@ def test_get_mesh(self):
parser.feed(mesh)
parser.close()

print(parser.parts)
assert parser.parts == ['g',

'polygon', 'points', '0.0,1.0 3.0,2.0 5.0,4.0',
'class', 'color-2',

'polygon', 'points', '3.0,2.0 5.0,4.0 3.0,1.0',
'class', 'color-0',

'polygon', 'points', '0.0,1.0 5.0,4.0 3.0,1.0',
'class', 'color-1']
'polygon', 'points', '0.0,1.0 5.0,4.0 3.0,1.0']

def test_get_mesh_root_tag(self):
adaptor = SvgAdaptor(svg_root_tag=True)
Expand All @@ -83,43 +79,34 @@ def test_get_mesh_root_tag(self):
parser.feed(mesh)
parser.close()

print(parser.parts)
assert parser.parts == ['svg',
'xmlns', 'http://www.w3.org/2000/svg',
'g',

'polygon', 'points', '0.0,1.0 3.0,2.0 5.0,4.0',
'class', 'color-2',

'polygon', 'points', '3.0,2.0 5.0,4.0 3.0,1.0',
'class', 'color-0',

'polygon', 'points', '0.0,1.0 5.0,4.0 3.0,1.0',
'class', 'color-1']
'polygon', 'points', '0.0,1.0 5.0,4.0 3.0,1.0']

def test_get_mesh_style(self):
adaptor = SvgAdaptor(svg_style='whatever;')
adaptor = SvgAdaptor(svg_style='fill:#555555;')
self.setup_adaptor(adaptor)
mesh = adaptor.get_mesh()

parser = SvgToList()
parser.feed(mesh)
parser.close()

print(parser.parts)
assert parser.parts == ['g',
'style',
'fill:#555555;',

'polygon', 'points', '0.0,1.0 3.0,2.0 5.0,4.0',
'class', 'color-2',

'polygon', 'points', '3.0,2.0 5.0,4.0 3.0,1.0',
'class', 'color-0',

'polygon', 'points', '0.0,1.0 5.0,4.0 3.0,1.0',
'class', 'color-1']

assert parser.style == 'whatever;'
'polygon', 'points', '0.0,1.0 5.0,4.0 3.0,1.0']

def test_get_mesh_style_fill_color(self):
adaptor = SvgAdaptor(svg_fill_color='#ffffff')
Expand All @@ -130,47 +117,41 @@ def test_get_mesh_style_fill_color(self):
parser.feed(mesh)
parser.close()

print(parser.parts)
assert parser.parts == ['g',
'style',
'fill:#ffffff;',

'polygon', 'points', '0.0,1.0 3.0,2.0 5.0,4.0',
'class', 'color-2',

'polygon', 'points', '3.0,2.0 5.0,4.0 3.0,1.0',
'class', 'color-0',

'polygon', 'points', '0.0,1.0 5.0,4.0 3.0,1.0',
'class', 'color-1']

assert parser.style == \
'polygon {\n fill:#ffffff;\n}\n'
'polygon', 'points', '0.0,1.0 5.0,4.0 3.0,1.0']

def test_get_mesh_style_fill_colors(self):
adaptor = SvgAdaptor(svg_fill_colors=['#ffffff', '#000000'])
adaptor = SvgAdaptor(svg_fill_colors=['#ffffff', '#000000', '#888888'])
self.setup_adaptor(adaptor)
mesh = adaptor.get_mesh()

parser = SvgToList()
parser.feed(mesh)
parser.close()

print(parser.parts)
assert parser.parts == ['g',
'style',

'polygon', 'points', '0.0,1.0 3.0,2.0 5.0,4.0',
'class', 'color-2',

'g',
'style',
'fill:#ffffff;',
'polygon', 'points', '3.0,2.0 5.0,4.0 3.0,1.0',
'class', 'color-0',

'g',
'style',
'fill:#000000;',
'polygon', 'points', '0.0,1.0 5.0,4.0 3.0,1.0',
'class', 'color-1']

assert parser.style == \
'.color-0 {\n fill:#ffffff;\n}\n'\
'.color-1 {\n fill:#000000;\n}\n'
'g',
'style',
'fill:#888888;',
'polygon', 'points', '0.0,1.0 3.0,2.0 5.0,4.0']

def test_get_mesh_style_stroke(self):
adaptor = SvgAdaptor(svg_stroke_color='#ffffff',
Expand All @@ -182,19 +163,12 @@ def test_get_mesh_style_stroke(self):
parser.feed(mesh)
parser.close()

print(parser.parts)
assert parser.parts == ['g',
'style',
'stroke:#ffffff;stroke-width:1px;',

'polygon', 'points', '0.0,1.0 3.0,2.0 5.0,4.0',
'class', 'color-2',

'polygon', 'points', '3.0,2.0 5.0,4.0 3.0,1.0',
'class', 'color-0',

'polygon', 'points', '0.0,1.0 5.0,4.0 3.0,1.0',
'class', 'color-1']

assert parser.style == \
'polygon {\n stroke:#ffffff;\n'\
' stroke-width:1px;\n}\n'
'polygon', 'points', '0.0,1.0 5.0,4.0 3.0,1.0']

0 comments on commit d262351

Please sign in to comment.