from dataclasses import dataclass from typing import Optional, Tuple, List, Union import random class Unit(): unit = "px" def __init__(self, amount:float): self.amount = amount def __repr__(self) -> str: return f'{self.amount}{self.unit}' class PX(Unit): pass class EM(Unit): unit = "em" class REM(Unit): unit = "rem" class Cluster(): def __init__(self): pass def __repr__(self)->str: #todo: flesh this out / provide overrides for each inheriting class return "" @dataclass class Font(Cluster): family: Optional[str] = None kerning: Optional[str] = None size: Optional[Unit] = None @dataclass class Space(Cluster): top: Optional[Unit] = None right: Optional[Unit] = None bottom: Optional[Unit] = None left: Optional[Unit] = None @dataclass class XForm(Space): width: Optional[Unit] = None height: Optional[Unit] = None angle: Optional[float] = None @dataclass class Size(): def __init__(self, minWidth:int = 0): pass def __getitem__(self, keys:Union[Cluster, Tuple[Cluster, ...]]): self.keys = keys return self def __repr__(self) -> str: if isinstance(self.keys, tuple): return f'\n'.join(str(k) for k in self.keys) else: return str(self.keys) class Atomic(): def __init__(self, *parts:Cluster): self.output:List[str] = [] for part in parts: self.output.append(f'max-width({part[0]}px)'+"{"+part[1].render()+"}") def __getitem__(self, keys:Tuple[int, *tuple[Cluster, ...]]): self.keys = keys return self ### example use: print( Atomic ( Font( size=PX(18) ), XForm( left=PX(10) ) ) [ ( 512, Font( size=PX(22) ), XForm( left=PX(18) ) ) ] )