Created
June 9, 2021 22:32
-
-
Save WizardOfArc/1381979a1a16ebfe283e814565d07c35 to your computer and use it in GitHub Desktop.
My Html Helper - to prevent me from messing up the html, let the program handle opening and closing tags
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| """ | |
| To Use: | |
| Build your dom structure out of these elements and then call render.() | |
| on the document object to get the dom rendered as a string - either print that out | |
| or write it to a file | |
| """ | |
| class Document: | |
| def __init__(self, dom_elements): | |
| self._dom_elements = dom_elements | |
| def render(self): | |
| lines = [] | |
| lines.append('<!DOCTYPE HTML>') | |
| lines.append('<html>') | |
| for de in self._dom_elements: | |
| lines.append(de.render(1)) | |
| lines.append('</html>') | |
| return '\n'.join(lines) | |
| def _paddit(level): | |
| return ''.join(' ' for _ in range(level) ) | |
| class TextNode: | |
| def __init__(self, text): | |
| self._text = text | |
| def render(self, depth): | |
| lines = [f'{_paddit(depth)}{l}' for l in self._text.split('\n')] | |
| return '\n'.join(lines) | |
| class Attributes: | |
| def __init__(self, attributes_dict): | |
| self._dict = attributes_dict | |
| def render(self): | |
| atts = [] | |
| if len(self._dict) == 0: | |
| return '' | |
| for k,v in self._dict.items(): | |
| if k == 'style': | |
| # style is a dict | |
| value = str(v).replace("'",'') | |
| elif k == 'class': | |
| # class is a list of classes | |
| value = ' '.join(v) | |
| else: | |
| value = v | |
| atts.append(f'{k}="{value}"') | |
| return f' {" ".join(atts)}' | |
| class DomElement: | |
| def __init__(self, type_name, attributes, self_closing, children): | |
| self._type_name = type_name | |
| self._attributes = attributes | |
| self._self_closing = self_closing | |
| self._children = children | |
| def render(self, depth): | |
| lines = [] | |
| phrases = [] | |
| padding = _paddit(depth) | |
| phrases.append(f'{padding}<{self._type_name}') | |
| phrases.append(self._attributes.render()) | |
| if self._self_closing: | |
| phrases.append('/>') | |
| lines.append(''.join(phrases)) | |
| else: | |
| phrases.append('>') | |
| lines.append(''.join(phrases)) | |
| for c in self._children: | |
| lines.append(c.render(depth+1)) | |
| lines.append(f'{padding}</{self._type_name}>') | |
| return '\n'.join(lines) | |
| class Body(DomElement): | |
| def __init__(self, attributes, children): | |
| super().__init__('body', attributes, False, children) | |
| class CSS: | |
| def __init__(self, content_string): | |
| self._content = content_string | |
| def render(self, depth): | |
| broken = content_string.split('\n') | |
| return '\n'.join( f'{paddit(depth)}{broken}') | |
| class Head(DomElement): | |
| def __init__(self, attributes, children): | |
| super().__init__( 'head', attributes, False, children) | |
| class Base(DomElement): | |
| def __init__(self, attributes, children): | |
| super().__init__( 'base', attributes, False, children) | |
| class Link(DomElement): | |
| def __init__(self, attributes, children): | |
| super().__init__( 'link', attributes, False, children) | |
| class Title(DomElement): | |
| def __init__(self, attributes, children): | |
| super().__init__( 'title', attributes, False, children) | |
| class Meta(DomElement): | |
| def __init__(self, attributes, children): | |
| super().__init__( 'meta', attributes, False, children) | |
| class Script(DomElement): | |
| def __init__(self, attributes, children): | |
| super().__init__( 'script', attributes, False, children) | |
| class Span(DomElement): | |
| def __init__(self, attributes, children): | |
| super().__init__( 'span', attributes, False, children) | |
| class Anchor(DomElement): | |
| def __init__(self, attributes, children): | |
| super().__init__( 'a', attributes, False, children) | |
| class Code(DomElement): | |
| def __init__(self, attributes, children): | |
| super().__init__( 'code', attributes, False, children) | |
| class Style(DomElement): | |
| def __init__(self, css): | |
| super().__init__( 'style', Attributes({}), False, [css]) | |
| class Br(DomElement): | |
| def __init__(self): | |
| super().__init__( 'br', Attributes({}), True, []) | |
| class Hr(DomElement): | |
| def __init__(self): | |
| super().__init__('hr', Attributes({}), True, []) | |
| class Div(DomElement): | |
| def __init__(self, attributes, children): | |
| super().__init__('div', attributes, False, children) | |
| class Table(DomElement): | |
| def __init__(self, attributes, children): | |
| super().__init__('table', attributes, False, children) | |
| class TR(DomElement): | |
| def __init__(self, attributes, children): | |
| super().__init__('tr', attributes, False, children) | |
| class TD(DomElement): | |
| def __init__(self, attributes, children): | |
| super().__init__('td', attributes, False, children) | |
| class TH(DomElement): | |
| def __init__(self, attributes, children): | |
| super().__init__('th', attributes, False, children) | |
| class ListElement(DomElement): | |
| def __init__(self, attributes, children): | |
| super().__init__('li', attributes, False, children) | |
| class OrderedList(DomElement): | |
| def __init__(self, attributes, children): | |
| super().__init__('ol', attributes, False, children) | |
| class UnorderedList(DomElement): | |
| def __init__(self, attributes, children): | |
| super().__init__('ul', attributes, False, children) | |
| class Paragraph(DomElement): | |
| def __init__(self, attributes, children): | |
| super().__init__('p', attributes, False, children) | |
| class Heading(DomElement): | |
| def __init__(self, level, attributes, children): | |
| if level > 6: | |
| lvl = 6 | |
| elif level < 1: | |
| lvl = 1 | |
| else: | |
| lvl = level | |
| super().__init__(f'h{lvl}', attributes, False, children) | |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
☝️ this is example code to use the above