summaryrefslogtreecommitdiff
path: root/htmtl/parsers/iterate.py
blob: a70d0269e06f1facd8b0f05bf61ba0ba73107418 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
from collections.abc import Iterable
from typing import Optional

from dompa.nodes.actions import ToHtml
from dompa.nodes import Node, FragmentNode
from ..parser import Parser
import htmtl

class IterateOp:
    var: str
    iter_var_as: Optional[str]
    iter_index_as: Optional[str]

    def __init__(self, var: str, iter_var_as: Optional[str] = None, iter_index_as: Optional[str] = None):
        self.var = var
        self.iter_var_as = iter_var_as or None
        self.iter_index_as = iter_index_as or None


class Iterate(Parser):
    def traverse(self, node: Node) -> Optional[Node]:
        if "iterate" in node.attributes:
            replacement_nodes = []
            iterate_op = self.__parse_exp(node.attributes["iterate"])
            collection = self.expression(iterate_op.var)
            node.attributes.pop("iterate")

            if isinstance(collection, Iterable):
                data = self.data()

                for idx, item in enumerate(collection):
                    if iterate_op.iter_var_as:
                        data[iterate_op.iter_var_as] = item

                    if iterate_op.iter_index_as:
                        data[iterate_op.iter_index_as] = idx

                    template = htmtl.Htmtl(node.action(ToHtml), data)
                    template_nodes = template.nodes()

                    if len(template_nodes) > 0:
                        replacement_nodes.append(template_nodes[0])

            return FragmentNode(children=replacement_nodes)

        return node

    @staticmethod
    def __parse_exp(exp: str) -> IterateOp:
        parts = exp.split(" ")

        if len(parts) == 3:
            if parts[2].count(":") == 1:
                return IterateOp(
                    var=parts[0].strip(),
                    iter_index_as=parts[2].split(":")[0].strip(),
                    iter_var_as=parts[2].split(":")[1].strip()
                )

            return IterateOp(
                var=parts[0].strip(),
                iter_var_as=parts[2].strip()
            )

        return IterateOp(
            var=parts[0]
        )