This commit is contained in:
Seth Trowbridge 2025-08-15 16:16:47 -04:00
parent b68b443071
commit c0df226188
6 changed files with 104 additions and 166 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
__pycache__/*

View File

@ -1,81 +0,0 @@
from typing import List, Tuple, Union
def MakeAttrs(css:str|Tuple[str, ...]|None, id:str|None, attributes: dict[str, str | None]|None) -> str:
if not attributes:
attributes = {}
if css:
attributes['class'] = " ".join(css) if isinstance(css, (list, tuple)) else css
if id:
attributes['id'] = id
attrList: List[str] = []
for key, value in attributes.items():
if value:
attrList.append(f'{key}="{value}"')
return " " + " ".join(attrList)
class ComplexProxyLeaf():
name:str = ""
def __init__(self, name:str|None = None):
if name:
self.name = name
self.attrs = None
def props(self, css:str|Tuple[str, ...]|None, id:str|None, attributes: dict[str, str | None]|None):
clone = self.__class__(self.name)
clone.attrs = MakeAttrs(css, id, attributes)
return clone
def __call__(self, css:str|None = None, id:str|None = None):
return self.props(css, id, {})
def __repr__(self) -> str:
return f'<{self.name}{self.attrs or ""}/>'
class ComplexProxyBranch(ComplexProxyLeaf):
name:str = ""
def __init__(self, name:str|None = None):
if name:
self.name = name
self.attrs = None
def __repr__(self) -> str:
return f'<{self.name}{self.attrs or ""}></{self.name}>'
def __getitem__(self, key:Union[str, 'ComplexProxyBranch', ComplexProxyLeaf, Tuple[Union[str, 'ComplexProxyBranch', ComplexProxyLeaf], ...]]) -> str:
if isinstance(key, tuple):
children = f'\n'.join(str(k) for k in key)
else:
children = str(key)
return f'<{self.name}{self.attrs or ""}>\n{children}\n</{self.name}>'
class IMGTag(ComplexProxyLeaf):
name = "img"
def __call__(self, css:str|None = None, id:str|None = None, src:str|None = None):
return self.props(css, id, {"src":src})
class ATag(ComplexProxyBranch):
name = "a"
def __call__(self, css:str|None = None, id:str|None = None, href:str|None = None, target:str|None = None):
return self.props(css, id, {"href":href, "target":target})
IMG = IMGTag()
A = ATag()
BR = ComplexProxyLeaf("br")
DIV = ComplexProxyBranch("div")
print(
DIV
[
"click here",
BR,
IMG(id="header.png"),
A(css="test"),
A["other?"],
A(css="www.site.com")
[
IMG(id="image.png")
]
]
)

View File

@ -1,64 +0,0 @@
from typing import List, Protocol, Tuple, Union
class StrArgsToStr(Protocol):
def __call__(self, *children: str) -> str:
...
ClassArg = str|List[str]|Tuple[str, ...]|None
class ComplexProxy(Protocol):
def __repr__(self) -> str:
...
def __getitem__(self, key:Tuple[Union['ComplexProxy',str], ...]) -> str:
...
def MakeAttrs(classes:ClassArg, id:str|None, attributes: dict[str, str | None]) -> str:
if classes:
attributes['class'] = " ".join(classes) if isinstance(classes, (list, tuple)) else classes
if id:
attributes['id'] = id
attrList: List[str] = []
for key, value in attributes.items():
if value:
attrList.append(f'{key}="{value}"')
return " ".join(attrList)
class NodeLeaf():
name:str = ""
attrs:str = ""
def __init__(self):
pass
def __repr__(self) -> str:
return f'<{self.name} {self.attrs}/>'
def __getitem__(self, key:ComplexProxy) -> str:
...
class NodeBranch(dict):
name:str = ""
attrs:str = ""
def __init__(self):
pass
def __repr__(self) -> str:
return f'<{self.name} {self.attrs}></{self.name}>'
def __getitem__(self, key:Tuple[Union['ComplexProxy',str], ...]) -> str:
return f'<{self.name} {self.attrs}>{"".join(key) if isinstance(key, tuple) else key}</{self.name}>'
class A(NodeBranch):
name = "a"
def __init__(self, classes:ClassArg = None, id:str|None = None, href:str|None = None, target:str|None = None):
self.attrs = MakeAttrs(classes, id, {"href":href, "target":target})
class IMG(NodeLeaf):
name = "img"
def __init__(self, classes:ClassArg = None, id:str|None = None, src:str|None = None):
self.attrs = MakeAttrs(classes, id, {"src":src})
a = A()
print(
A(href="outer")[
IMG(src="image.jpg"),
IMG(src="image.jpg"),
]
)

87
pyx.py
View File

@ -1,29 +1,74 @@
def html_args(dict):
return " "+(" ".join([f'{key}="{value}"' for key, value in dict.items()])) if dict else ""
from typing import List, Tuple, Union
def html_element(tagName, children, args):
return f"<{tagName}{html_args(args)}>{"".join(children)}</{tagName}>"
def MakeAttrs(css:str|Tuple[str, ...]|None, id:str|None, attributes: dict[str, str | None]|None) -> str:
if not attributes:
attributes = {}
if css:
attributes['class'] = " ".join(css) if isinstance(css, (list, tuple)) else css
if id:
attributes['id'] = id
attrList: List[str] = []
for key, value in attributes.items():
if value:
attrList.append(f'{key}="{value}"')
return " " + " ".join(attrList)
def html_element_self_closing(tagName, **args):
return f"<{tagName}{html_args(args)} />"
class Leaf():
name:str = ""
def __init__(self, name:str|None = None):
if name:
self.name = name
self.attrs = None
def _H(tagName, *children, **attrs):
childrenInvoker = lambda *childrenFinal: html_element(tagName, childrenFinal, attrs)
return childrenInvoker if attrs else childrenInvoker(*children)
def props(self, css:str|Tuple[str, ...]|None, id:str|None, attributes: dict[str, str | None]|None):
clone = self.__class__(self.name)
clone.attrs = MakeAttrs(css, id, attributes)
return clone
def H(stringName):
return lambda *children, **attrs: _H(stringName, *children, **attrs)
def __call__(self, css:str|None = None, id:str|None = None):
return self.props(css, id, {})
def __repr__(self) -> str:
return f'<{self.name}{self.attrs or ""}/>'
class Branch(Leaf):
name:str = ""
def __init__(self, name:str|None = None):
if name:
self.name = name
self.attrs = None
def __repr__(self) -> str:
return f'<{self.name}{self.attrs or ""}></{self.name}>'
def __getitem__(self, key:Union[str, 'Branch', Leaf, Tuple[Union[str, 'Branch', Leaf], ...]]) -> str:
if isinstance(key, tuple):
children = f'\n'.join(str(k) for k in key)
else:
children = str(key)
p = H("p")
a = H("a")
span = H("span")
return f'<{self.name}{self.attrs or ""}>\n{children}\n</{self.name}>'
class IMGTag(Leaf):
name = "img"
def __call__(self, css:str|None = None, id:str|None = None, src:str|None = None):
return self.props(css, id, {"src":src})
class ATag(Branch):
name = "a"
def __call__(self, css:str|None = None, id:str|None = None, href:str|None = None, target:str|None = None):
return self.props(css, id, {"href":href, "target":target})
def CustomComponent(message:str)->str:
return p(onClick="toggleMenu")(
message,
span(classes="")("anyone there?")
)
print(CustomComponent("Hello World!"))
IMG = IMGTag()
A = ATag()
BR = Leaf("br")
HR = Leaf("hr")
DIV = Branch("div")
P = Branch("p")
SPAN = Branch("span")
EM = Branch("EM")
H1 = Branch("h1")
H2 = Branch("h2")
H3 = Branch("h3")
H4 = Branch("h4")
SECTION = Branch("section")
MAIN = Branch("main")

21
scratch.py Normal file
View File

@ -0,0 +1,21 @@
from dataclasses import dataclass, field
from typing import Optional, Dict, Tuple, List
class Bracket():
def __init__(self, *args: str):
self.children = list(args)
@dataclass
class StyledTag(Bracket):
style: Optional[str] = None
other: Optional[str] = None
def Test(*children:str, css:Optional[str]=None, ):
print(css)
print(children)
Test("itme1", "item2", css="yo")

16
template.py Normal file
View File

@ -0,0 +1,16 @@
from PYX import DIV, H1, H2, P, SPAN, BR, IMG, A
print(
DIV
[
H1("Welcome!"),
P(),
IMG(id="header.png"),
A(css="test"),
A["other?"],
A(css="www.site.com")
[
IMG(id="image.png")
]
]
)