Coverage for phml\compiler\steps\embedded.py: 100%

14 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2023-04-12 14:26 -0500

1from typing import Any 

2 

3from phml.embedded import exec_embedded, exec_embedded_blocks 

4from phml.helpers import build_recursive_context 

5from phml.nodes import Element, Literal, Parent 

6 

7from .base import scoped_step 

8 

9 

10def _process_attributes(node: Element, context: dict[str, Any]): 

11 context = build_recursive_context(node, context) 

12 for attribute in list(node.attributes.keys()): 

13 if attribute.startswith(":"): 

14 result = exec_embedded( 

15 str(node[attribute]).strip(), 

16 f"<{node.tag} {attribute}='{node[attribute]}'>", 

17 **context, 

18 ) 

19 if result is not None: 

20 node.pop(attribute, None) 

21 node[attribute.lstrip(":")] = result 

22 else: 

23 if isinstance(node[attribute], str): 

24 value = exec_embedded_blocks( 

25 str(node.attributes[attribute]).strip(), 

26 f"<{node.tag} {attribute}='{node.attributes[attribute]}'>", 

27 **context, 

28 ) 

29 if value is not None: 

30 node[attribute] = value 

31 

32 

33@scoped_step 

34def step_execute_embedded_python(node: Parent, _, context: dict[str, Any]): 

35 """Step to process embedded python inside of attributes and text nodes.""" 

36 for child in node: 

37 if isinstance(child, Element): 

38 _process_attributes( 

39 child, 

40 build_recursive_context(child, context), 

41 ) 

42 elif ( 

43 Literal.is_text(child) 

44 and "{{" in child.content 

45 and child.parent.tag not in ["script", "style", "python"] 

46 ): 

47 child.content = exec_embedded_blocks( 

48 child.content.strip(), 

49 f"Text in <{node.tag}> at {node.position!r}", 

50 **build_recursive_context(child, context), 

51 )