Skip to content

Commit c212c3e

Browse files
committed
Merge pull request UWPCE-PythonCert#89 from MikeSchincariol/master
Session7 - html_render
2 parents 04ae6a1 + be0dbab commit c212c3e

File tree

3 files changed

+449
-0
lines changed

3 files changed

+449
-0
lines changed
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
import io
2+
3+
class Element(object):
4+
5+
@classmethod
6+
def check_content_is_compat(cls, content):
7+
if isinstance(content, str) or isinstance(content, Element):
8+
return True
9+
else:
10+
return False
11+
12+
13+
def __init__(self, content=None, **kwargs):
14+
'''
15+
:param content: The string or element instance to initialize the element with.
16+
:param kwargs: Attributes that are associated with the content
17+
:return: Nothing
18+
'''
19+
self.tag = 'tag'
20+
self.data = []
21+
self.attr = kwargs
22+
23+
if content is not None:
24+
if Element.check_content_is_compat(content):
25+
self.data.append(content)
26+
else:
27+
raise ValueError("The 'content' argument must be a string or another Element")
28+
29+
30+
def append(self, content, **kwargs):
31+
'''
32+
:param content: The string or element instance to add to the items already in the element
33+
:param kwargs: Attributes that are associated with the content
34+
:return: Nothing
35+
'''
36+
37+
self.attr.update(kwargs)
38+
if content is not None:
39+
if Element.check_content_is_compat(content):
40+
self.data.append(content)
41+
else:
42+
raise ValueError("The 'content' argument must be a string or another Element")
43+
44+
45+
def _render_start_tag(self, file_out, ind, inline=True, self_closing=False):
46+
try:
47+
if not inline:
48+
file_out.write("\n{0}".format(ind))
49+
file_out.write("<{0}".format(self.tag))
50+
for k,v in self.attr.items():
51+
file_out.write(' {0}="{1}"'.format(k, v))
52+
if self_closing:
53+
file_out.write("/>")
54+
else:
55+
file_out.write(">")
56+
except AttributeError:
57+
raise ValueError("The 'file_out' argument must be a class or subclass of io.TextIOBase")
58+
59+
60+
def _render_data(self, file_out, ind, inline=True):
61+
sub_ind = " " * (len(ind) + 3)
62+
63+
for idx, item in enumerate(self.data):
64+
try:
65+
# Assume it is an Element
66+
item.render(file_out, sub_ind)
67+
except AttributeError:
68+
# Guess not...assume it is a string :)
69+
try:
70+
if not inline:
71+
file_out.write("\n{0}".format(sub_ind))
72+
file_out.write("{0}".format(item))
73+
except AttributeError:
74+
raise ValueError("The 'file_out' argument must be a class or subclass of io.TextIOBase")
75+
76+
77+
def _render_end_tag(self, file_out, ind, inline=True):
78+
try:
79+
if not inline:
80+
file_out.write("\n{0}".format(ind))
81+
file_out.write("</{0}>".format(self.tag))
82+
except AttributeError:
83+
raise ValueError("The 'file_out' argument must be a class or subclass of io.TextIOBase")
84+
85+
86+
def render(self, file_out, ind = ""):
87+
'''
88+
89+
:param file_out: A io.TextIOBase file object
90+
:param ind: A string, which supplies the amount of indentation whitespace to use
91+
:return: Nothing
92+
'''
93+
self._render_start_tag(file_out, ind, False, False)
94+
self._render_data(file_out, ind, False)
95+
self._render_end_tag(file_out, ind, False)
96+
97+
98+
99+
class Html(Element):
100+
def __init__(self, content=None, **kwargs):
101+
super().__init__(content, **kwargs)
102+
self.tag = "html"
103+
self.data.append("<!DOCTYPE html>")
104+
105+
106+
class Body(Element):
107+
def __init__(self, content=None, **kwargs):
108+
super().__init__(content, **kwargs)
109+
self.tag = "body"
110+
111+
112+
class P(Element):
113+
def __init__(self, content=None, **kwargs):
114+
super().__init__(content, **kwargs)
115+
self.tag = "p"
116+
117+
118+
class Head(Element):
119+
def __init__(self, content=None, **kwargs):
120+
super().__init__(content, **kwargs)
121+
self.tag = "head"
122+
123+
class Ul(Element):
124+
def __init__(self, content=None, **kwargs):
125+
super().__init__(content, **kwargs)
126+
self.tag = "ul"
127+
128+
class Li(Element):
129+
def __init__(self, content=None, **kwargs):
130+
super().__init__(content, **kwargs)
131+
self.tag = "li"
132+
133+
134+
class OneLineTag(Element):
135+
def __init__(self, content=None, **kwargs):
136+
super().__init__(content, **kwargs)
137+
self.tag = "head"
138+
139+
def render(self, file_out, ind=""):
140+
'''
141+
142+
:param file_out: A io.TextIOBase file object
143+
:param ind: A string, which supplies the amount of indentation whitespace to use
144+
:return: Nothing
145+
'''
146+
self._render_start_tag(file_out, ind, False, False)
147+
self._render_data(file_out, ind, True)
148+
self._render_end_tag(file_out, ind, True)
149+
150+
151+
152+
class Title(OneLineTag):
153+
def __init__(self, content=None, **kwargs):
154+
super().__init__(content, **kwargs)
155+
self.tag = "title"
156+
157+
class H(OneLineTag):
158+
def __init__(self, hdr_lvl, content=None, **kwargs):
159+
super().__init__(content, **kwargs)
160+
self.tag = "h{0}".format(hdr_lvl)
161+
162+
163+
class SelfClosingTag(Element):
164+
def __init__(self, content=None, **kwargs):
165+
super().__init__(content, **kwargs)
166+
self.tag = "selfclosing"
167+
168+
def render(self, file_out, ind = ""):
169+
'''
170+
171+
:param file_out: A io.TextIOBase file object
172+
:param ind: A string, which supplies the amount of indentation whitespace to use
173+
:return: Nothing
174+
'''
175+
self._render_start_tag(file_out, ind, True, True)
176+
self._render_data(file_out, ind, True)
177+
178+
179+
180+
class Hr(SelfClosingTag):
181+
def __init__(self, content=None, **kwargs):
182+
super().__init__(content, **kwargs)
183+
self.tag = "hr"
184+
185+
class Br(SelfClosingTag):
186+
def __init__(self, content=None, **kwargs):
187+
super().__init__(content, **kwargs)
188+
self.tag = "br"
189+
190+
class Meta(SelfClosingTag):
191+
def __init__(self, content=None, **kwargs):
192+
super().__init__(content, **kwargs)
193+
self.tag = "meta"
194+
self.attr['charset']="UTF-8"
195+
196+
197+
class A(Element):
198+
def __init__(self, link, content):
199+
super().__init__(content, href=link)
200+
self.tag = "a"

0 commit comments

Comments
 (0)