"""Dynamically compile classes for all HTML elements and output them to the elements directory. This script generates the element classes in the pynecone.el.elements module. Run as follows: python -m pynecone.el.precompile Make sure to delete the __init__.py file in the elements directory before running this script. """ import os from pynecone.compiler.templates import join from .constants import ELEMENT_TO_PROPS, ELEMENTS FILE_DIR = os.path.dirname(os.path.realpath(__file__)) ELEMENTS_DIR = os.path.join(FILE_DIR, "elements") INIT_PY_PATH = os.path.join(ELEMENTS_DIR, "__init__.py") def element_path(element: str) -> str: """Get the name of the Python file for the given element. Args: element: The name of the element. For example, `a` or `div`. Returns: The name of the Python file for the given element. """ return os.path.join(ELEMENTS_DIR, f"{element}.py") PROP = " {prop}: PCVar[Union[str, int, bool]]".format def compile_pyclass_props(element: str) -> str: """Compile props for an element. Args: element: The name of the element. For example, `a` or `div`. Returns: A string containing compiled props for the element. """ return join(PROP(prop=prop) for prop in ELEMENT_TO_PROPS[element]) PYCLASS = join( [ "", "class {name}(Element): # noqa: E742", ' """Display the {element} element."""', "", ' tag = "{element}"', "", "{props}", "", "", "{call_name} = {name}.create", "", ] ).format def compile_pyclass(element: str) -> str: """Compile a Python class for an element. Args: element: The name of the element. For example, `a` or `div`. Returns: A string containing a Python class for the element. """ name = element.capitalize() props = compile_pyclass_props(element) # Handle the `del` element, which is a Python keyword. Note that the class # name is still `Del`. call_name = "del_" if element == "del" else element return PYCLASS( name=name, element=element, props=props, call_name=call_name, ) INIT_PY = [ '"""Element classes. This is an auto-generated file. Do not edit. See ../generate.py."""', "from typing import Union", "", "from pynecone.el.element import Element", "from pynecone.var import Var as PCVar", "", ] for element in sorted(ELEMENTS): INIT_PY.append(compile_pyclass(element)) os.makedirs(ELEMENTS_DIR, exist_ok=True) with open(INIT_PY_PATH, "w+") as f: f.write(join(INIT_PY))