Files
replit-py/src/replit/maqpy/html.py
T
2020-07-28 12:52:52 -07:00

87 lines
2.3 KiB
Python

"""Python object representations of HTML."""
from abc import ABC
from dataclasses import dataclass
import flask
class HTMLElement(ABC):
"""Base class for an HTML element."""
def __init__(self, content: str, **attrs: str) -> None:
"""Initialize the class.
Args:
content (str): The content inside the HTML tag.
attrs (str): The attributes of tag.
"""
self.content = content
self.attrs = attrs
def stringify_attrs(self) -> str:
"""Generate a string version of the tags attributes.
Returns:
str: A string in the form of attr1="value1" attr2="value2"
"""
return " ".join(f'{name}="{value}"' for name, value in self.attrs.items())
def __str__(self) -> str:
"""Generates an HTML representation of the tag."""
attr_text = self.stringify_attrs()
return (
f"<{self.tagname}{' ' + attr_text if attr_text else ''}>{self.content}"
f"</{self.tagname}>"
)
class Paragraph(HTMLElement):
"""Represents a Paragraph (p) tag."""
tagname = "p"
class Link(HTMLElement):
"""Represents a Link (a) tag."""
tagname = "a"
def __init__(self, content: str, href: str, **attrs: str) -> None:
"""Initialize the class.
Args:
content (str): The content of the link tag.
href (str): The href attribute, where the link points to.
attrs (str): Any additional attributes of the tag.
"""
super().__init__(content, **{"href": href, **attrs})
class Page(flask.Response):
"""Represents an HTML page."""
def __init__(self, title: str = None, head: str = "", body: str = "") -> None:
"""Initialize the class.
Args:
title (str): The title of the page. If not provided no title tag will be sent.
head (str): The HTML to put in the head of the page. Defaults to nothing.
body (str): The HTML to put in the body of the page. Defaults to nothing.
"""
self.title = title
self.head = head
self.body = body
title_html = f"<title>{self.title}</title>\n " if self.title else ""
super().__init__(
f"""<!DOCTYPE html>
<html>
<head>
{title_html}{self.head}
</head>
<body>
{self.body}
</body>
</html>"""
)