my-multiplayer-app / compare_svg.py
Jaimodiji's picture
Upload folder using huggingface_hub
d9eba27 verified
#!/usr/bin/env python3
"""Compare original SVG with roundtrip SVG"""
import re
from xml.etree import ElementTree as ET
from collections import defaultdict
def parse_svg(path):
"""Parse SVG and extract element details"""
with open(path, 'r') as f:
content = f.read()
# Parse XML
try:
root = ET.fromstring(content)
except:
# Fallback to regex if XML parsing fails
return parse_svg_regex(content)
ns = {'svg': 'http://www.w3.org/2000/svg', 'xlink': 'http://www.w3.org/1999/xlink'}
elements = defaultdict(list)
def process_elem(elem, depth=0):
tag = elem.tag.split('}')[-1] # Remove namespace
attrs = dict(elem.attrib)
if tag in ['path', 'rect', 'circle', 'ellipse', 'polygon', 'polyline', 'line', 'image', 'text']:
info = {'tag': tag, 'depth': depth}
# Key attributes
for attr in ['fill', 'stroke', 'stroke-width', 'stroke-dasharray',
'fill-opacity', 'stroke-opacity', 'opacity', 'transform']:
if attr in attrs:
info[attr] = attrs[attr][:30] if len(attrs.get(attr, '')) > 30 else attrs.get(attr)
# Special handling
if 'd' in attrs:
info['d_len'] = len(attrs['d'])
info['d_cmds'] = len(re.findall(r'[MLHVCSQTAZ]', attrs['d'], re.I))
if 'points' in attrs:
info['points_count'] = len(attrs['points'].split())
if '{http://www.w3.org/1999/xlink}href' in attrs:
href = attrs['{http://www.w3.org/1999/xlink}href']
info['href'] = href[:40] + '...' if len(href) > 40 else href
if 'href' in attrs:
href = attrs['href']
info['href'] = href[:40] + '...' if len(href) > 40 else href
elements[tag].append(info)
for child in elem:
process_elem(child, depth + 1)
process_elem(root)
return elements
def parse_svg_regex(content):
"""Fallback regex parser"""
elements = defaultdict(list)
for tag in ['path', 'rect', 'circle', 'ellipse', 'polygon', 'polyline', 'line', 'image']:
pattern = rf'<{tag}\s+([^>]*)/?>'
for match in re.finditer(pattern, content, re.I):
attrs_str = match.group(1)
info = {'tag': tag}
for attr in ['fill', 'stroke', 'stroke-width', 'stroke-dasharray',
'fill-opacity', 'stroke-opacity', 'opacity']:
m = re.search(rf'{attr}="([^"]*)"', attrs_str)
if m:
val = m.group(1)
info[attr] = val[:30] if len(val) > 30 else val
if tag == 'path':
m = re.search(r'd="([^"]*)"', attrs_str)
if m:
info['d_len'] = len(m.group(1))
info['d_cmds'] = len(re.findall(r'[MLHVCSQTAZ]', m.group(1), re.I))
if tag == 'polygon':
m = re.search(r'points="([^"]*)"', attrs_str)
if m:
info['points_count'] = len(m.group(1).split())
elements[tag].append(info)
return elements
def compare(orig_path, roundtrip_path):
print(f"Original: {orig_path}")
print(f"Roundtrip: {roundtrip_path}")
print("=" * 60)
orig = parse_svg(orig_path)
rt = parse_svg(roundtrip_path)
all_tags = set(orig.keys()) | set(rt.keys())
print("\n### ELEMENT COUNTS ###")
print(f"{'Tag':<12} {'Original':>10} {'Roundtrip':>10} {'Diff':>10}")
print("-" * 44)
for tag in sorted(all_tags):
o_count = len(orig.get(tag, []))
r_count = len(rt.get(tag, []))
diff = r_count - o_count
diff_str = f"+{diff}" if diff > 0 else str(diff)
print(f"{tag:<12} {o_count:>10} {r_count:>10} {diff_str:>10}")
print("\n### ORIGINAL ELEMENTS ###")
for tag in sorted(orig.keys()):
print(f"\n[{tag.upper()}] ({len(orig[tag])} elements)")
for i, elem in enumerate(orig[tag][:5]): # Show first 5
attrs = {k: v for k, v in elem.items() if k != 'tag' and k != 'depth'}
print(f" {i}: {attrs}")
if len(orig[tag]) > 5:
print(f" ... and {len(orig[tag]) - 5} more")
print("\n### ROUNDTRIP ELEMENTS ###")
for tag in sorted(rt.keys()):
print(f"\n[{tag.upper()}] ({len(rt[tag])} elements)")
for i, elem in enumerate(rt[tag][:5]): # Show first 5
attrs = {k: v for k, v in elem.items() if k != 'tag' and k != 'depth'}
print(f" {i}: {attrs}")
if len(rt[tag]) > 5:
print(f" ... and {len(rt[tag]) - 5} more")
# Attribute comparison
print("\n### ATTRIBUTE ANALYSIS ###")
# Check fills
orig_fills = [e.get('fill') for t in orig.values() for e in t if e.get('fill')]
rt_fills = [e.get('fill') for t in rt.values() for e in t if e.get('fill')]
print(f"\nFills - Original: {len(orig_fills)}, Roundtrip: {len(rt_fills)}")
print(f" Orig unique: {set(orig_fills)}")
print(f" RT unique: {set(rt_fills)}")
# Check strokes
orig_strokes = [e.get('stroke') for t in orig.values() for e in t if e.get('stroke')]
rt_strokes = [e.get('stroke') for t in rt.values() for e in t if e.get('stroke')]
print(f"\nStrokes - Original: {len(orig_strokes)}, Roundtrip: {len(rt_strokes)}")
# Check dash arrays
orig_dash = [e.get('stroke-dasharray') for t in orig.values() for e in t if e.get('stroke-dasharray')]
rt_dash = [e.get('stroke-dasharray') for t in rt.values() for e in t if e.get('stroke-dasharray')]
print(f"\nDash arrays - Original: {len(orig_dash)}, Roundtrip: {len(rt_dash)}")
if orig_dash:
print(f" Orig: {orig_dash[:3]}...")
if rt_dash:
print(f" RT: {rt_dash[:3]}...")
if __name__ == '__main__':
compare('test_page_1.svg', 'test_page_1.roundtrip.svg')