-
Notifications
You must be signed in to change notification settings - Fork 0
/
tag_builder.py
121 lines (99 loc) · 3.05 KB
/
tag_builder.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
"""
This file is a mini library for building html based on a tag-based system.
"""
from __future__ import annotations
from typing import List
class TagBuilder():
"""
HTML Builder Class for generating HTML.
"""
def __init__(self, tag_name : str, data : str = "", *, parent : TagBuilder = None, collapse = False, style = "") -> None:
self.parent = parent
self.collapse = collapse
self.data = data
self.tag_name = tag_name
self.children : List[TagBuilder] = []
self.properties = {
"class": style
}
def decorate(self, property_name : str, property_value : str):
"""
Adds a property to this tag.
"""
base = self.properties.get(property_name, "")
self.properties[property_name] = f"{base} {property_value}"
return self
def insert_table(self, data : List[List[str]]) -> None:
"""
Inserts a table into this structure.
"""
table_builder = self.insert_tag("table")
for row in data:
row_builder = table_builder.insert_tag("tr")
for cell in row:
row_builder.insert_tag("td", str(cell))
return table_builder
def append(self, tag: TagBuilder) -> TagBuilder:
"""
Appends a new tag to this structure, returning the parent tag.
"""
tag.parent = self
self.children.append(tag)
return self
def insert(self, tag: TagBuilder) -> TagBuilder:
"""
Inserts a new tag into this structure, returning the child tag.
"""
tag.parent = self
self.children.append(tag)
return tag
def insert_tag(self, tag_name: str, data : str = "", *, collapse = False, style = "") -> TagBuilder:
"""
Inserts a new tag into this structure, returning the child tag.
"""
child = TagBuilder(tag_name, data, parent=self, collapse=collapse, style=style)
self.children.append(child)
return child
def image(self, src: str, alt: str = "") -> TagBuilder:
"""
Inserts an image into this structure.
"""
return self.insert_tag("img", f"", collapse=True).decorate("src", src).decorate("alt", alt)
def append_tag(self, tag_name: str, data : str = "", *, collapse = False, style = "") -> TagBuilder:
"""
Appends a new tag to this structure, returning the parent tag.
"""
child = TagBuilder(tag_name, data, parent=self, collapse=collapse, style=style)
self.children.append(child)
return self
def generate(self):
"""
Generates the HTML for this structure by walking up to the top parent
then rendering.
"""
if self.parent != None:
return self.parent.generate()
else:
return str(self)
def prettify_properties(self) -> str:
"""
Returns a string of all properties for this tag.
"""
html = ""
for key, value in self.properties.items():
html += f"{key}=\"{value.strip()}\" "
return html.strip()
def __str__(self) -> str:
"""
Returns the HTML string for this tag, and all child tags recursively.
"""
end_line = "/" if self.collapse else ""
html = f"<{self.tag_name} {self.prettify_properties()}{end_line}>\n"
html += self.data
for child in self.children:
html += str(child)
if not self.collapse:
html += "</{}>".format(self.tag_name)
return html
def __repr__(self) -> str:
return str(self)