# Prevod testovacích SVG cenoviek z Illustratora na pozadia šablón: # - ceny, zľava % a „zľava“ sa odstránia (budú z nich vrstvy editora), # - statické nápisy (SUPER / CENA / VÝHODNÉ, písmo Gilroy-Heavy) sa prevedú na krivky, # - triedy a id dostanú jedinečnú predponu (inak by sa viaceré cenovky na stránke prebíjali), # - obsah sa posunie tak, aby telo cenovky bolo vo všetkých šablónach na rovnakom mieste. # # Použitie: pip install fonttools; python convert-illustrator-svg.py # (Gilroy-Heavy musí byť nainštalovaný; priradenie súborov k typu/farbe/pôvodu je v ASSETS nižšie.) # Výstup obsahuje vyčistené SVG a namerané polohy textov – z nich sa vyrobili šablóny v tabuľke badges. import json import re import sys from fontTools.pens.svgPathPen import SVGPathPen from fontTools.pens.transformPen import TransformPen from fontTools.ttLib import TTFont SRC = sys.argv[1] OUT = sys.argv[2] GILROY = r'C:\Users\jakub\AppData\Local\Microsoft\Windows\Fonts\Gilroy-Heavy.ttf' font = TTFont(GILROY) glyphs = font.getGlyphSet() cmap = font.getBestCmap() upem = font['head'].unitsPerEm # referenčná poloha tela cenovky (zhora ľavý roh rámika s cenou) REF_X = 27.98 ASSETS = { 'Asset 2.svg': ('SUPER CENA', 'cervena', 'SK'), 'Asset 3.svg': ('SUPER VÝHODNÉ', 'cervena', 'SK'), 'Asset 4.svg': ('SUPER CENA', 'oranzova', 'SK'), 'Asset 5.svg': ('SUPER CENA', 'zelena', 'SK'), 'Asset 6.svg': ('SUPER CENA', 'cervena', ''), 'Asset 7.svg': ('SUPER VÝHODNÉ', 'cervena', ''), 'Asset 8.svg': ('SUPER CENA', 'oranzova', ''), 'Asset 9.svg': ('SUPER VÝHODNÉ', 'zelena', ''), 'Asset 10.svg': ('SUPER VÝHODNÉ', 'oranzova', 'SK'), 'Asset 11.svg': ('SUPER VÝHODNÉ', 'oranzova', ''), } def parse_css(svg): style = re.search(r'', svg, re.S).group(1) props = {} for sel, body in re.findall(r'([^{}]+)\{([^}]*)\}', style): decl = dict( (k.strip(), v.strip()) for k, v in (d.split(':', 1) for d in body.split(';') if ':' in d) ) for cls in sel.split(','): props.setdefault(cls.strip().lstrip('.'), {}).update(decl) return props def text_to_path(transform, runs, size, fill): """runs: [(x, text, letter_spacing_em)] → s tou istou transformáciou ako pôvodný .""" s = size / upem pen = SVGPathPen(glyphs) for x, txt, ls in runs: cursor = x for ch in txt: name = cmap.get(ord(ch)) if not name: continue glyphs[name].draw(TransformPen(pen, (s, 0, 0, -s, cursor, 0))) cursor += glyphs[name].width * s + ls * size d = pen.getCommands() return f'' if d else '' result = [] for fname, (btype, color, origin) in ASSETS.items(): svg = open(f'{SRC}/{fname}', encoding='utf-8').read() key = 'b' + re.sub(r'\D', '', fname) css = parse_css(svg) texts = {} # rola → údaje def replace_text(m): classes = m.group(1).split() transform = m.group(2) body = m.group(3) p = {} for c in classes: p.update(css.get(c, {})) size = float(p.get('font-size', '0').replace('px', '')) family = p.get('font-family', '') fill = p.get('fill', '#000') runs = [] for tcls, x, txt in re.findall(r'([^<]*)', body): ls = css.get(tcls, {}).get('letter-spacing', '0em').replace('em', '') if tcls else '0' runs.append((float(x), txt, float(ls or 0))) content = ''.join(r[1] for r in runs) tr = re.match(r'translate\(([\d.\-]+) ([\d.\-]+)\)', transform) tx, ty = float(tr.group(1)), float(tr.group(2)) if not content.strip(): return '' if 'Gilroy' in family: return text_to_path(transform, runs, size, fill) # Aptly: ceny, zľava % a „zľava“ → vrstvy editora if '%' in content: role = 'discount' elif content.isdigit() and size >= 25: role = 'main' elif content.isdigit(): role = 'cents' else: role = 'label' texts[role] = {'text': content, 'x': tx, 'y': ty, 'size': size, 'fill': fill, 'runs': runs} return '' svg = re.sub(r'(.*?)', replace_text, svg, flags=re.S) # posun obsahu: rámik s cenou vždy na REF_X a jeho horná hrana na rovnakej výške v rámci druhu cenovky rects = re.findall(r'', svg) box_x, box_y = float(rects[0][1]), float(rects[0][2]) dx = REF_X - box_x dy = (92.67 if btype == 'SUPER CENA' else 44.98) - box_y # jedinečné triedy a id svg = re.sub(r'\bcls-(\d+)\b', rf'{key}-c\1', svg) for ident in set(re.findall(r'id="([^"]+)"', svg)): svg = re.sub(rf'(id="|url\(#|xlink:href="#){re.escape(ident)}(["\)])', rf'\1{key}-{ident}\2', svg) inner = re.sub(r'^.*?]*>', '', svg, flags=re.S) inner = re.sub(r'\s*$', '', inner) defs = re.search(r'.*?', inner, re.S).group(0) body = inner.replace(defs, '') vb = [float(v) for v in re.search(r'viewBox="([^"]+)"', svg).group(1).split()] result.append({ 'file': fname, 'key': key, 'type': btype, 'color': color, 'origin': origin, 'dx': dx, 'dy': dy, 'boxY': box_y, 'vb': vb, 'texts': texts, 'svg': f'{defs}{body.strip()}', }) json.dump(result, open(OUT, 'w', encoding='utf-8'), ensure_ascii=False, indent=1) for r in result: print(r['file'], r['type'], r['color'], r['origin'], 'dx', round(r['dx'], 2), 'dy', round(r['dy'], 2), 'boxY', r['boxY'], 'texts', {k: v['text'] for k, v in r['texts'].items()}, len(r['svg']))