phml.utilities.travel.travel
utilities.travel
Collection of utilities that hep with traversing an ast or node tree.
1"""utilities.travel 2 3Collection of utilities that hep with traversing an ast or node tree. 4""" 5 6from typing import Iterator 7 8from phml.nodes import Element, Node, Parent, AST 9 10__all__ = ["path", "path_names", "walk", "visit_all_after"] 11 12 13def path(node: Node) -> list[Element]: 14 """Get a list of nodes where each one is a child of 15 the other leading to the node passed in. This gives a 16 path to the node. 17 18 Does not include given node. 19 20 Args: 21 node (Node): Node to find ancestors of. 22 23 Returns: 24 list[Node]: List of nodes leading to the given node 25 starting from the root. 26 """ 27 ancestors = [] 28 while node.parent is not None and isinstance(node.parent, Element): 29 ancestors = [node.parent, *ancestors] 30 node = node.parent 31 32 return ancestors 33 34 35def path_names(node: Node) -> list[str]: 36 """Get a list of nodes where each one is a child of 37 the other leading to the node passed in. This gives a 38 path to the node. 39 40 Does not include given node. 41 42 Args: 43 node (Node): Node to find ancestors of. 44 45 Returns: 46 list[str]: List of nodes leading to the given node 47 starting from the root. 48 """ 49 ancestors = [] 50 while node.parent is not None and isinstance(node.parent, Element): 51 ancestors = [node.parent.tag, *ancestors] 52 node = node.parent 53 54 return ancestors 55 56 57def walk(node: Parent) -> Iterator: 58 """Recursively traverse the node and it's chidlren as an iterator. 59 Left to right depth first. 60 """ 61 62 def get_children(n: Node) -> Iterator: 63 yield n 64 if isinstance(n, Parent): 65 for child in n: 66 yield from get_children(child) 67 68 yield node 69 if isinstance(node, Parent): 70 for child in node: 71 yield from get_children(child) 72 73 74def visit_all_after(start: Node) -> Iterator: 75 """Recursively traverse the tree starting at given node.""" 76 77 def get_children(parent) -> Iterator: 78 yield parent 79 if parent.type in ["root", "element"]: 80 for child in parent: 81 yield from get_children(child) 82 83 parent = start.parent 84 if parent is not None: 85 idx = parent.index(start) 86 if idx < len(parent) - 1: 87 for child in parent[idx + 1 :]: 88 yield from get_children(child)
14def path(node: Node) -> list[Element]: 15 """Get a list of nodes where each one is a child of 16 the other leading to the node passed in. This gives a 17 path to the node. 18 19 Does not include given node. 20 21 Args: 22 node (Node): Node to find ancestors of. 23 24 Returns: 25 list[Node]: List of nodes leading to the given node 26 starting from the root. 27 """ 28 ancestors = [] 29 while node.parent is not None and isinstance(node.parent, Element): 30 ancestors = [node.parent, *ancestors] 31 node = node.parent 32 33 return ancestors
Get a list of nodes where each one is a child of the other leading to the node passed in. This gives a path to the node.
Does not include given node.
Args
- node (Node): Node to find ancestors of.
Returns
list[Node]: List of nodes leading to the given node starting from the root.
36def path_names(node: Node) -> list[str]: 37 """Get a list of nodes where each one is a child of 38 the other leading to the node passed in. This gives a 39 path to the node. 40 41 Does not include given node. 42 43 Args: 44 node (Node): Node to find ancestors of. 45 46 Returns: 47 list[str]: List of nodes leading to the given node 48 starting from the root. 49 """ 50 ancestors = [] 51 while node.parent is not None and isinstance(node.parent, Element): 52 ancestors = [node.parent.tag, *ancestors] 53 node = node.parent 54 55 return ancestors
Get a list of nodes where each one is a child of the other leading to the node passed in. This gives a path to the node.
Does not include given node.
Args
- node (Node): Node to find ancestors of.
Returns
list[str]: List of nodes leading to the given node starting from the root.
58def walk(node: Parent) -> Iterator: 59 """Recursively traverse the node and it's chidlren as an iterator. 60 Left to right depth first. 61 """ 62 63 def get_children(n: Node) -> Iterator: 64 yield n 65 if isinstance(n, Parent): 66 for child in n: 67 yield from get_children(child) 68 69 yield node 70 if isinstance(node, Parent): 71 for child in node: 72 yield from get_children(child)
Recursively traverse the node and it's chidlren as an iterator. Left to right depth first.
75def visit_all_after(start: Node) -> Iterator: 76 """Recursively traverse the tree starting at given node.""" 77 78 def get_children(parent) -> Iterator: 79 yield parent 80 if parent.type in ["root", "element"]: 81 for child in parent: 82 yield from get_children(child) 83 84 parent = start.parent 85 if parent is not None: 86 idx = parent.index(start) 87 if idx < len(parent) - 1: 88 for child in parent[idx + 1 :]: 89 yield from get_children(child)
Recursively traverse the tree starting at given node.