From 5df28ae239b0796bf4b0ab3c9baab45942953a9c Mon Sep 17 00:00:00 2001 From: Mark Blakeney Date: Thu, 1 Aug 2024 14:54:33 +1000 Subject: [PATCH] Refactor element declarations. 1. The void_elements were identically defined in two different files. This PR moves them to 1 file. 2. Better to define the element names in a table and loop over that table to create the elements (exploiting globals()) rather than use explicit code per element. --- htpy/__init__.py | 126 +++------------------------------------------- htpy/elements.py | 124 +++++++++++++++++++++++++++++++++++++++++++++ htpy/html2htpy.py | 21 ++------ 3 files changed, 134 insertions(+), 137 deletions(-) create mode 100644 htpy/elements.py diff --git a/htpy/__init__.py b/htpy/__init__.py index b59fecf..2c470a3 100644 --- a/htpy/__init__.py +++ b/htpy/__init__.py @@ -10,6 +10,8 @@ from markupsafe import Markup as _Markup from markupsafe import escape as _escape +from . import elements + BaseElementSelf = TypeVar("BaseElementSelf", bound="BaseElement") ElementSelf = TypeVar("ElementSelf", bound="Element") @@ -234,122 +236,8 @@ def __html__(self) -> str: ... # https://developer.mozilla.org/en-US/docs/Glossary/Doctype html = HTMLElement("html", {}, None) -# https://developer.mozilla.org/en-US/docs/Glossary/Void_element -area = VoidElement("area", {}, None) -base = VoidElement("base", {}, None) -br = VoidElement("br", {}, None) -col = VoidElement("col", {}, None) -embed = VoidElement("embed", {}, None) -hr = VoidElement("hr", {}, None) -img = VoidElement("img", {}, None) -input = VoidElement("input", {}, None) -link = VoidElement("link", {}, None) -meta = VoidElement("meta", {}, None) -param = VoidElement("param", {}, None) -source = VoidElement("source", {}, None) -track = VoidElement("track", {}, None) -wbr = VoidElement("wbr", {}, None) - -# Non-deprecated HTML elements, extracted from -# https://developer.mozilla.org/en-US/docs/Web/HTML/Element -# Located via the inspector with: -# Array.from($0.querySelectorAll('li')).filter(x=>!x.querySelector('.icon-deprecated')).map(x => x.querySelector('code').textContent) # noqa: E501 -a = Element("a", {}, None) -abbr = Element("abbr", {}, None) -abc = Element("abc", {}, None) -address = Element("address", {}, None) -article = Element("article", {}, None) -aside = Element("aside", {}, None) -audio = Element("audio", {}, None) -b = Element("b", {}, None) -bdi = Element("bdi", {}, None) -bdo = Element("bdo", {}, None) -blockquote = Element("blockquote", {}, None) -body = Element("body", {}, None) -button = Element("button", {}, None) -canvas = Element("canvas", {}, None) -caption = Element("caption", {}, None) -cite = Element("cite", {}, None) -code = Element("code", {}, None) -colgroup = Element("colgroup", {}, None) -data = Element("data", {}, None) -datalist = Element("datalist", {}, None) -dd = Element("dd", {}, None) -del_ = Element("del_", {}, None) -details = Element("details", {}, None) -dfn = Element("dfn", {}, None) -dialog = Element("dialog", {}, None) -div = Element("div", {}, None) -dl = Element("dl", {}, None) -dt = Element("dt", {}, None) -em = Element("em", {}, None) -fieldset = Element("fieldset", {}, None) -figcaption = Element("figcaption", {}, None) -figure = Element("figure", {}, None) -footer = Element("footer", {}, None) -form = Element("form", {}, None) -h1 = Element("h1", {}, None) -h2 = Element("h2", {}, None) -h3 = Element("h3", {}, None) -h4 = Element("h4", {}, None) -h5 = Element("h5", {}, None) -h6 = Element("h6", {}, None) -head = Element("head", {}, None) -header = Element("header", {}, None) -hgroup = Element("hgroup", {}, None) -i = Element("i", {}, None) -iframe = Element("iframe", {}, None) -ins = Element("ins", {}, None) -kbd = Element("kbd", {}, None) -label = Element("label", {}, None) -legend = Element("legend", {}, None) -li = Element("li", {}, None) -main = Element("main", {}, None) -map = Element("map", {}, None) -mark = Element("mark", {}, None) -menu = Element("menu", {}, None) -meter = Element("meter", {}, None) -nav = Element("nav", {}, None) -noscript = Element("noscript", {}, None) -object = Element("object", {}, None) -ol = Element("ol", {}, None) -optgroup = Element("optgroup", {}, None) -option = Element("option", {}, None) -output = Element("output", {}, None) -p = Element("p", {}, None) -picture = Element("picture", {}, None) -portal = Element("portal", {}, None) -pre = Element("pre", {}, None) -progress = Element("progress", {}, None) -q = Element("q", {}, None) -rp = Element("rp", {}, None) -rt = Element("rt", {}, None) -ruby = Element("ruby", {}, None) -s = Element("s", {}, None) -samp = Element("samp", {}, None) -script = Element("script", {}, None) -search = Element("search", {}, None) -section = Element("section", {}, None) -select = Element("select", {}, None) -slot = Element("slot", {}, None) -small = Element("small", {}, None) -span = Element("span", {}, None) -strong = Element("strong", {}, None) -style = Element("style", {}, None) -sub = Element("sub", {}, None) -summary = Element("summary", {}, None) -sup = Element("sup", {}, None) -table = Element("table", {}, None) -tbody = Element("tbody", {}, None) -td = Element("td", {}, None) -template = Element("template", {}, None) -textarea = Element("textarea", {}, None) -tfoot = Element("tfoot", {}, None) -th = Element("th", {}, None) -thead = Element("thead", {}, None) -time = Element("time", {}, None) -title = Element("title", {}, None) -tr = Element("tr", {}, None) -u = Element("u", {}, None) -ul = Element("ul", {}, None) -var = Element("var", {}, None) +for name in elements.void_elements: + globals()[name] = VoidElement(name, {}, None) + +for name in elements.elements: + globals()[name] = Element(name, {}, None) diff --git a/htpy/elements.py b/htpy/elements.py new file mode 100644 index 0000000..2185ff7 --- /dev/null +++ b/htpy/elements.py @@ -0,0 +1,124 @@ +# https://developer.mozilla.org/en-US/docs/Glossary/Void_element +void_elements = ( + "area", + "base", + "br", + "col", + "embed", + "hr", + "img", + "input", + "link", + "meta", + "param", + "source", + "track", + "wbr", +) + +# Non-deprecated HTML elements, extracted from +# https://developer.mozilla.org/en-US/docs/Web/HTML/Element Located via +# the inspector with: +# Array.from($0.querySelectorAll('li')).filter(x=>!x.querySelector('.icon-deprecated')).map(x +# => x.querySelector('code').textContent) # noqa: E501 +elements = ( + "a", + "abbr", + "abc", + "address", + "article", + "aside", + "audio", + "b", + "bdi", + "bdo", + "blockquote", + "body", + "button", + "canvas", + "caption", + "cite", + "code", + "colgroup", + "data", + "datalist", + "dd", + "del_", + "details", + "dfn", + "dialog", + "div", + "dl", + "dt", + "em", + "fieldset", + "figcaption", + "figure", + "footer", + "form", + "h1", + "h2", + "h3", + "h4", + "h5", + "h6", + "head", + "header", + "hgroup", + "i", + "iframe", + "ins", + "kbd", + "label", + "legend", + "li", + "main", + "map", + "mark", + "menu", + "meter", + "nav", + "noscript", + "object", + "ol", + "optgroup", + "option", + "output", + "p", + "picture", + "portal", + "pre", + "progress", + "q", + "rp", + "rt", + "ruby", + "s", + "samp", + "script", + "search", + "section", + "select", + "slot", + "small", + "span", + "strong", + "style", + "sub", + "summary", + "sup", + "table", + "tbody", + "td", + "template", + "textarea", + "tfoot", + "th", + "thead", + "time", + "title", + "tr", + "u", + "ul", + "var", +) diff --git a/htpy/html2htpy.py b/htpy/html2htpy.py index eed5d7e..33330b7 100644 --- a/htpy/html2htpy.py +++ b/htpy/html2htpy.py @@ -10,24 +10,9 @@ from html.parser import HTMLParser from typing import Literal -__all__ = ["html2htpy"] +from .elements import void_elements -_void_elements = [ - "area", - "base", - "br", - "col", - "embed", - "hr", - "img", - "input", - "link", - "meta", - "param", - "source", - "track", - "wbr", -] +__all__ = ["html2htpy"] def _quote(x: str) -> str: @@ -207,7 +192,7 @@ def handle_starttag(self, tag: str, attrs: list[tuple[str, str | None]]) -> None else: self._current.children.append(t) - if tag not in _void_elements: + if tag not in void_elements: self._current = t def handle_startendtag(self, tag: str, attrs: list[tuple[str, str | None]]) -> None: