141 lines
3.4 KiB
Python
141 lines
3.4 KiB
Python
from dataclasses import dataclass
|
|
from typing import Optional, Tuple, Union, Dict, List
|
|
|
|
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():
|
|
|
|
map:Dict[str, str] = {}
|
|
|
|
def __init__(self):
|
|
pass
|
|
def __repr__(self)->str:
|
|
print("repr called on cluster")
|
|
return self.render()
|
|
|
|
def render(self)->str:
|
|
output:List[str] = []
|
|
for key in self.map:
|
|
value = self.__getattribute__(self.map[key])
|
|
if value:
|
|
output.append(f'{key}:{value};')
|
|
return "".join(output)
|
|
|
|
@dataclass
|
|
class Font(Cluster):
|
|
family: Optional[str] = None
|
|
kerning: Optional[str] = None
|
|
size: Optional[Unit] = None
|
|
|
|
map = {
|
|
"font-family":"family",
|
|
"font-kerning":"kerning",
|
|
"font-size":"size"
|
|
}
|
|
|
|
@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
|
|
|
|
class Chainer():
|
|
|
|
def __init__(self) -> None:
|
|
self.size = 0
|
|
self.dump_id:int = -1
|
|
self.log:List[str] = []
|
|
pass
|
|
|
|
def __getitem__(self, args:Union[Cluster, Tuple[Cluster, ...]]):
|
|
print("bracket access", args)
|
|
|
|
styledata = "".join(c.render() for c in args) if isinstance(args, tuple) else args.render()
|
|
if self.size:
|
|
self.log.append(f'\n@media(min-width:{self.size}px){{ {styledata} }}')
|
|
else:
|
|
self.log.append(styledata)
|
|
return self
|
|
|
|
def __call__(self, key:int):
|
|
print("call access", key)
|
|
self.size = key
|
|
return self
|
|
|
|
def dump(self, log:List[str], fullName:str, dump_id:int):
|
|
if self.dump_id != dump_id:
|
|
log.append(f'.{fullName} {{\n {"".join(self.log)} \n}}')
|
|
self.dump_id = dump_id
|
|
self.log = []
|
|
self.size = 0
|
|
|
|
class Kickoff():
|
|
def __getitem__(self, args:Union[Cluster, Tuple[Cluster, ...]]):
|
|
return Chainer().__getitem__(args)
|
|
|
|
def __call__(self, key:int):
|
|
return Chainer().__call__(key)
|
|
|
|
CSS = Kickoff()
|
|
|
|
|
|
##########################
|
|
|
|
class Writer:
|
|
dump_id = 0
|
|
log:List[str] = []
|
|
|
|
@classmethod
|
|
def start(cls):
|
|
cls.dump_id += 1
|
|
cls.log.clear()
|
|
print("Writer reset, dump_id:", cls.dump_id)
|
|
|
|
@classmethod
|
|
def capture(cls, fullName:str, chainer:Chainer):
|
|
chainer.dump(cls.log, fullName, Writer.dump_id)
|
|
|
|
@classmethod
|
|
def dump(cls) -> str:
|
|
output = "\n".join(cls.log)
|
|
cls.start() # Reset after dumping
|
|
return output
|
|
|
|
class _SHEET(type):
|
|
|
|
def __getattribute__(cls, name:str):
|
|
if name != "__name__" and name != "__module__":
|
|
print("class name access", name)
|
|
value = super().__getattribute__(name)
|
|
if isinstance(value, Chainer):
|
|
fullName = f'{cls.__module__}_{cls.__name__}_{name}'
|
|
Writer.capture(fullName, value)
|
|
return fullName
|
|
|
|
return super().__getattribute__(name)
|
|
|
|
class SHEET(metaclass=_SHEET):
|
|
pass
|
|
|