pyx/css.py
2025-08-20 18:12:40 -04:00

132 lines
2.9 KiB
Python

from dataclasses import dataclass
from typing import Optional, Tuple, Union, Dict, List
import random
css_final:List[str] = []
css_lines:List[str] = []
def css_class(css_context:str):
global css_lines
output = f'{css_context}{{ {"".join(css_lines)} }}'
css_lines = []
css_final.append(output)
def css_write(str:str):
css_lines.append(str)
def css_dump():
global css_final
output = "".join(css_final)
css_final = []
return output
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):
self.key = random.randrange(1000, 5000)
pass
def __repr__(self)->str:
print("repr called on cluster")
#todo: flesh this out / provide overrides for each inheriting class
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 "\n".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.accessed = 0
pass
def __getitem__(self, args:Union[Cluster, Tuple[Cluster, ...]]):
if isinstance(args, tuple):
children = f'\n'.join(k.render() for k in args)
else:
children = args.render()
if self.accessed:
css_write(f'@media(max-width:{self.accessed}px){{ {children} }}')
else:
css_write(children)
self.accessed = 0
return self
def __call__(self, key:int):
self.accessed = key
return self
CSS = Chainer()
##########################
class _SHEET(type):
last_accessed:Optional[str] = None
def __getattribute__(cls, name:str):
if name != "__name__" and name != "__module__":
css_class(f'.{cls.__module__}.{cls.__name__}.{name}')
return super().__getattribute__(name)
class SHEET(metaclass=_SHEET):
pass
class UserMadeSheet(SHEET):
Paragraph=CSS[
Font( size=PX(10) ),
](512)[
Font( size=PX(18), family="sans" ),
](1024)[
Font( size=PX(120) ),
]
Anchor=CSS[
Font( size=PX(123) )
]