summaryrefslogtreecommitdiff
path: root/htmtl/parsers/iterate.py
diff options
context:
space:
mode:
authorAsko Nõmm <asko@nmm.ee>2025-01-06 01:16:33 +0200
committerAsko Nõmm <asko@nmm.ee>2025-01-06 01:16:33 +0200
commit4ea133608350e6e99008f46cb4c45dd18989b836 (patch)
tree2b285fce4be72873dee9c243361c258f77573ee7 /htmtl/parsers/iterate.py
parent51904366dd5c46c8d8d37e333b538b7574360ff5 (diff)
Implement `Iterate` parser.
Diffstat (limited to 'htmtl/parsers/iterate.py')
-rw-r--r--htmtl/parsers/iterate.py67
1 files changed, 67 insertions, 0 deletions
diff --git a/htmtl/parsers/iterate.py b/htmtl/parsers/iterate.py
new file mode 100644
index 0000000..a70d026
--- /dev/null
+++ b/htmtl/parsers/iterate.py
@@ -0,0 +1,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]
+ )