standard_tags = [
	"a",
	"abbr",
	"acronym",
	"address",
	"applet",
	"area",
	"article",
	"aside",
	"audio",
	"b",
	"base",
	"basefont",
	"bdi",
	"bdo",
	"bgsound",
	"big",
	"blink",
	"blockquote",
	"body",
	"br",
	"button",
	"canvas",
	"caption",
	"center",
	"cite",
	"code",
	"col",
	"colgroup",
	"content",
	"data",
	"datalist",
	"dd",
	"decorator",
	"del",
	"details",
	"dfn",
	"dir",
	"div",
	"dl",
	"dt",
	"element",
	"em",
	"embed",
	"fieldset",
	"figcaption",
	"figure",
	"font",
	"footer",
	"form",
	"frame",
	"frameset",
	"h1",
	"h2",
	"h3",
	"h4",
	"h5",
	"h6",
	"head",
	"header",
	"hgroup",
	"hr",
	"html",
	"i",
	"iframe",
	"img",
	"input",
	"ins",
	"isindex",
	"kbd",
	"keygen",
	"label",
	"legend",
	"li",
	"link",
	"listing",
	"main",
	"map",
	"mark",
	"marquee",
	"menu",
	"menuitem",
	"meta",
	"meter",
	"nav",
	"nobr",
	"noframes",
	"noscript",
	"object",
	"ol",
	"optgroup",
	"option",
	"output",
	"p",
	"param",
	"plaintext",
	"pre",
	"progress",
	"q",
	"rp",
	"rt",
	"ruby",
	"s",
	"samp",
	"script",
	"section",
	"select",
	"shadow",
	"small",
	"source",
	"spacer",
	"span",
	"strike",
	"strong",
	"style",
	"sub",
	"summary",
	"sup",
	"table",
	"tbody",
	"td",
	"template",
	"textarea",
	"tfoot",
	"th",
	"thead",
	"time",
	"title",
	"tr",
	"track",
	"tt",
	"u",
	"ul",
	"var",
	"video",
	"wbr",
	"xmp"
]

class Element:
	def __init__(self, tag: str, data: str="", children: list=None, **attrs: str):
		self.tag = tag
		self.data = data
		self.children: list[Element] = children if children else []
		self.attrs = attrs
		self.parent: Element = None

	@property
	def html(self) -> str:
		return str(self)

	def __str__(self):
		attrs = ""
		children = '\n'.join(str(child) for child in self.children)

		for attrname, value in self.attrs.items():
			attrs+=f'{attrname}="{value}" '

		return f"<{self.tag} {attrs}>{self.data}{children}</{self.tag}>"

for tag in standard_tags:
	globals()[tag] = type(
		tag, 
		(Element,),
		{
			"__init__": 
			lambda self, data="", children=None, **attrs:
			super(self.__class__, self).__init__(self.__class__.__name__, data, children, **attrs)
		}
	)