phml.core.formats.html_format

  1from copy import deepcopy
  2from typing import Optional
  3
  4from phml.core.nodes import AST, NODE
  5from phml.core.virtual_python import VirtualPython
  6from phml.utilities import find_all, remove_nodes
  7
  8from .compile import ASTRenderer, apply_conditions, apply_python
  9from .format import Format
 10from .parse import parse_hypertest_markup
 11
 12
 13def parse_markup(data: str, class_name: str, auto_close: bool = True) -> AST:
 14    """Parse a string as a markup document."""
 15    return parse_hypertest_markup(data, class_name, auto_close)
 16
 17
 18class HTMLFormat(Format):
 19    """Logic for parsing and compiling html files."""
 20
 21    extension: list[str] = ["html", "htm"]
 22
 23    @classmethod
 24    def parse(cls, data: str, auto_close: bool = True) -> str:
 25        return parse_markup(data, cls.__name__, auto_close)
 26
 27    @classmethod
 28    def compile(
 29        cls,
 30        ast: AST,
 31        components: Optional[dict[str, dict[str, list | NODE]]] = None,
 32        **kwargs,
 33    ) -> AST:
 34        """Compile and process the given ast and return the resulting ast."""
 35
 36        components = components or {}
 37        src = deepcopy(ast)
 38
 39        # 1. Search for all python elements and get source info.
 40        #    - Remove when done
 41        virtual_python = VirtualPython()
 42
 43        for python_block in find_all(src, {"tag": "python"}):
 44            if len(python_block.children) == 1:
 45                if python_block.children[0].type == "text":
 46                    virtual_python += VirtualPython(python_block.children[0].normalized())
 47
 48        remove_nodes(src, ["element", {"tag": "python"}])
 49
 50        # 2. Replace specific element node with given replacement components
 51        # replace_components(src, components, virtual_python, **kwargs)
 52
 53        # 3. Search each element and find @if, @elif, and @else
 54        #    - Execute those statements
 55
 56        apply_conditions(src, virtual_python, components, **kwargs)
 57
 58        for python_block in find_all(src, {"tag": "python"}):
 59            if len(python_block.children) == 1:
 60                if python_block.children[0].type == "text":
 61                    virtual_python += VirtualPython(python_block.children[0].normalized())
 62
 63        remove_nodes(src, ["element", {"tag": "python"}])
 64
 65
 66        # 4. Search for python blocks and process them.
 67
 68        apply_python(src, virtual_python, **kwargs)
 69        remove_nodes(src, {"tag": "slot"})
 70
 71        return src
 72
 73    @classmethod
 74    def render(
 75        cls,
 76        ast: AST,
 77        components: Optional[dict[str, dict[str, list | NODE]]] = None,
 78        indent: int = 4,
 79        **kwargs,
 80    ) -> str:
 81        indent = indent or 4
 82        components = components or {}
 83        src = ast
 84
 85        # 1. Search for all python elements and get source info.
 86        #    - Remove when done
 87        virtual_python = VirtualPython()
 88
 89        for python_block in find_all(src, {"tag": "python"}):
 90            if len(python_block.children) == 1:
 91                if python_block.children[0].type == "text":
 92                    virtual_python += VirtualPython(python_block.children[0].normalized())
 93
 94        remove_nodes(src, ["element", {"tag": "python"}])
 95
 96        # 2. Replace specific element node with given replacement components
 97        # replace_components(src, components, virtual_python, **kwargs)
 98
 99        # 3. Search each element and find @if, @elif, and @else
100        #    - Execute those statements
101
102        apply_conditions(src, virtual_python, components, **kwargs)
103
104        for python_block in find_all(src, {"tag": "python"}):
105            if len(python_block.children) == 1:
106                if python_block.children[0].type == "text":
107                    virtual_python += VirtualPython(python_block.children[0].normalized())
108
109        remove_nodes(src, ["element", {"tag": "python"}])
110
111
112        # 4. Search for python blocks and process them.
113
114        apply_python(src, virtual_python, **kwargs)
115        remove_nodes(src, {"tag": "slot"})
116
117        return ASTRenderer(src, indent).compile()
def parse_markup( data: str, class_name: str, auto_close: bool = True) -> phml.core.nodes.AST.AST:
14def parse_markup(data: str, class_name: str, auto_close: bool = True) -> AST:
15    """Parse a string as a markup document."""
16    return parse_hypertest_markup(data, class_name, auto_close)

Parse a string as a markup document.

class HTMLFormat(phml.core.formats.format.Format):
 19class HTMLFormat(Format):
 20    """Logic for parsing and compiling html files."""
 21
 22    extension: list[str] = ["html", "htm"]
 23
 24    @classmethod
 25    def parse(cls, data: str, auto_close: bool = True) -> str:
 26        return parse_markup(data, cls.__name__, auto_close)
 27
 28    @classmethod
 29    def compile(
 30        cls,
 31        ast: AST,
 32        components: Optional[dict[str, dict[str, list | NODE]]] = None,
 33        **kwargs,
 34    ) -> AST:
 35        """Compile and process the given ast and return the resulting ast."""
 36
 37        components = components or {}
 38        src = deepcopy(ast)
 39
 40        # 1. Search for all python elements and get source info.
 41        #    - Remove when done
 42        virtual_python = VirtualPython()
 43
 44        for python_block in find_all(src, {"tag": "python"}):
 45            if len(python_block.children) == 1:
 46                if python_block.children[0].type == "text":
 47                    virtual_python += VirtualPython(python_block.children[0].normalized())
 48
 49        remove_nodes(src, ["element", {"tag": "python"}])
 50
 51        # 2. Replace specific element node with given replacement components
 52        # replace_components(src, components, virtual_python, **kwargs)
 53
 54        # 3. Search each element and find @if, @elif, and @else
 55        #    - Execute those statements
 56
 57        apply_conditions(src, virtual_python, components, **kwargs)
 58
 59        for python_block in find_all(src, {"tag": "python"}):
 60            if len(python_block.children) == 1:
 61                if python_block.children[0].type == "text":
 62                    virtual_python += VirtualPython(python_block.children[0].normalized())
 63
 64        remove_nodes(src, ["element", {"tag": "python"}])
 65
 66
 67        # 4. Search for python blocks and process them.
 68
 69        apply_python(src, virtual_python, **kwargs)
 70        remove_nodes(src, {"tag": "slot"})
 71
 72        return src
 73
 74    @classmethod
 75    def render(
 76        cls,
 77        ast: AST,
 78        components: Optional[dict[str, dict[str, list | NODE]]] = None,
 79        indent: int = 4,
 80        **kwargs,
 81    ) -> str:
 82        indent = indent or 4
 83        components = components or {}
 84        src = ast
 85
 86        # 1. Search for all python elements and get source info.
 87        #    - Remove when done
 88        virtual_python = VirtualPython()
 89
 90        for python_block in find_all(src, {"tag": "python"}):
 91            if len(python_block.children) == 1:
 92                if python_block.children[0].type == "text":
 93                    virtual_python += VirtualPython(python_block.children[0].normalized())
 94
 95        remove_nodes(src, ["element", {"tag": "python"}])
 96
 97        # 2. Replace specific element node with given replacement components
 98        # replace_components(src, components, virtual_python, **kwargs)
 99
100        # 3. Search each element and find @if, @elif, and @else
101        #    - Execute those statements
102
103        apply_conditions(src, virtual_python, components, **kwargs)
104
105        for python_block in find_all(src, {"tag": "python"}):
106            if len(python_block.children) == 1:
107                if python_block.children[0].type == "text":
108                    virtual_python += VirtualPython(python_block.children[0].normalized())
109
110        remove_nodes(src, ["element", {"tag": "python"}])
111
112
113        # 4. Search for python blocks and process them.
114
115        apply_python(src, virtual_python, **kwargs)
116        remove_nodes(src, {"tag": "slot"})
117
118        return ASTRenderer(src, indent).compile()

Logic for parsing and compiling html files.

HTMLFormat()
extension: list[str] = ['html', 'htm']

The extension or extensions for the file format. When writing to a file and extensions is a list then the first extensions in the list is used for the file extension.

@classmethod
def parse(cls, data: str, auto_close: bool = True) -> str:
24    @classmethod
25    def parse(cls, data: str, auto_close: bool = True) -> str:
26        return parse_markup(data, cls.__name__, auto_close)

Parse the given data into a phml.core.nodes.AST.

28    @classmethod
29    def compile(
30        cls,
31        ast: AST,
32        components: Optional[dict[str, dict[str, list | NODE]]] = None,
33        **kwargs,
34    ) -> AST:
35        """Compile and process the given ast and return the resulting ast."""
36
37        components = components or {}
38        src = deepcopy(ast)
39
40        # 1. Search for all python elements and get source info.
41        #    - Remove when done
42        virtual_python = VirtualPython()
43
44        for python_block in find_all(src, {"tag": "python"}):
45            if len(python_block.children) == 1:
46                if python_block.children[0].type == "text":
47                    virtual_python += VirtualPython(python_block.children[0].normalized())
48
49        remove_nodes(src, ["element", {"tag": "python"}])
50
51        # 2. Replace specific element node with given replacement components
52        # replace_components(src, components, virtual_python, **kwargs)
53
54        # 3. Search each element and find @if, @elif, and @else
55        #    - Execute those statements
56
57        apply_conditions(src, virtual_python, components, **kwargs)
58
59        for python_block in find_all(src, {"tag": "python"}):
60            if len(python_block.children) == 1:
61                if python_block.children[0].type == "text":
62                    virtual_python += VirtualPython(python_block.children[0].normalized())
63
64        remove_nodes(src, ["element", {"tag": "python"}])
65
66
67        # 4. Search for python blocks and process them.
68
69        apply_python(src, virtual_python, **kwargs)
70        remove_nodes(src, {"tag": "slot"})
71
72        return src

Compile and process the given ast and return the resulting ast.

@classmethod
def render( cls, ast: phml.core.nodes.AST.AST, components: Optional[dict[str, dict[str, list | phml.core.nodes.nodes.Root | phml.core.nodes.nodes.Element | phml.core.nodes.nodes.Text | phml.core.nodes.nodes.Comment | phml.core.nodes.nodes.DocType | phml.core.nodes.nodes.Parent | phml.core.nodes.nodes.Node | phml.core.nodes.nodes.Literal]]] = None, indent: int = 4, **kwargs) -> str:
 74    @classmethod
 75    def render(
 76        cls,
 77        ast: AST,
 78        components: Optional[dict[str, dict[str, list | NODE]]] = None,
 79        indent: int = 4,
 80        **kwargs,
 81    ) -> str:
 82        indent = indent or 4
 83        components = components or {}
 84        src = ast
 85
 86        # 1. Search for all python elements and get source info.
 87        #    - Remove when done
 88        virtual_python = VirtualPython()
 89
 90        for python_block in find_all(src, {"tag": "python"}):
 91            if len(python_block.children) == 1:
 92                if python_block.children[0].type == "text":
 93                    virtual_python += VirtualPython(python_block.children[0].normalized())
 94
 95        remove_nodes(src, ["element", {"tag": "python"}])
 96
 97        # 2. Replace specific element node with given replacement components
 98        # replace_components(src, components, virtual_python, **kwargs)
 99
100        # 3. Search each element and find @if, @elif, and @else
101        #    - Execute those statements
102
103        apply_conditions(src, virtual_python, components, **kwargs)
104
105        for python_block in find_all(src, {"tag": "python"}):
106            if len(python_block.children) == 1:
107                if python_block.children[0].type == "text":
108                    virtual_python += VirtualPython(python_block.children[0].normalized())
109
110        remove_nodes(src, ["element", {"tag": "python"}])
111
112
113        # 4. Search for python blocks and process them.
114
115        apply_python(src, virtual_python, **kwargs)
116        remove_nodes(src, {"tag": "slot"})
117
118        return ASTRenderer(src, indent).compile()

Compile the given phml.core.nodes.AST into string of a given format.