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.core.nodes import NODE, Element, Root 9 10__all__ = ["path", "path_names", "walk", "visit_children", "visit_all_after"] 11 12 13def path(node: NODE) -> list[NODE]: 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: 29 ancestors = [node.parent, *ancestors] 30 node = node.parent 31 32 return ancestors 33 34def path_names(node: NODE) -> list[str]: 35 """Get a list of nodes where each one is a child of 36 the other leading to the node passed in. This gives a 37 path to the node. 38 39 Does not include given node. 40 41 Args: 42 node (NODE): Node to find ancestors of. 43 44 Returns: 45 list[str]: List of nodes leading to the given node 46 starting from the root. 47 """ 48 ancestors = [] 49 while node.parent is not None and node.parent.type != "root": 50 ancestors = [node.parent.tag, *ancestors] 51 node = node.parent 52 53 return ancestors 54 55 56def walk(node: Root | Element) -> Iterator: 57 """Recursively traverse the node and it's chidlren as an iterator. 58 Left to right depth first. 59 """ 60 61 def get_children(parent) -> Iterator: 62 yield parent 63 if parent.type in ["root", "element"]: 64 for child in parent.children: 65 yield from get_children(child) 66 67 yield node 68 if node.type in ["root", "element"]: 69 for child in visit_children(node): 70 yield from get_children(child) 71 72 73def visit_children(parent: Root | Element) -> Iterator: 74 """Traverse the children of a Root or Element as an iterator.""" 75 for child in parent.children: 76 yield child 77 78 79def visit_all_after(start: NODE) -> Iterator: 80 """Recursively traverse the tree starting at given node.""" 81 82 def get_children(parent) -> Iterator: 83 yield parent 84 if parent.type in ["root", "element"]: 85 for child in parent.children: 86 yield from get_children(child) 87 88 parent = start.parent 89 idx = parent.children.index(start) 90 if idx < len(parent.children) - 1: 91 for child in parent.children[idx + 1 :]: 92 yield from get_children(child)
def
path( node: 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) -> 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]:
14def path(node: NODE) -> list[NODE]: 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: 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.
Arguments:
- node (NODE): Node to find ancestors of.
Returns:
list[NODE]: List of nodes leading to the given node starting from the root.
def
path_names( node: 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) -> list[str]:
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 node.parent.type != "root": 51 ancestors = [node.parent.tag, *ancestors] 52 node = node.parent 53 54 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.
Arguments:
- node (NODE): Node to find ancestors of.
Returns:
list[str]: List of nodes leading to the given node starting from the root.
57def walk(node: Root | Element) -> 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(parent) -> Iterator: 63 yield parent 64 if parent.type in ["root", "element"]: 65 for child in parent.children: 66 yield from get_children(child) 67 68 yield node 69 if node.type in ["root", "element"]: 70 for child in visit_children(node): 71 yield from get_children(child)
Recursively traverse the node and it's chidlren as an iterator. Left to right depth first.
def
visit_children( parent: phml.core.nodes.nodes.Root | phml.core.nodes.nodes.Element) -> Iterator:
74def visit_children(parent: Root | Element) -> Iterator: 75 """Traverse the children of a Root or Element as an iterator.""" 76 for child in parent.children: 77 yield child
Traverse the children of a Root or Element as an iterator.
def
visit_all_after( start: 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) -> Iterator:
80def visit_all_after(start: NODE) -> Iterator: 81 """Recursively traverse the tree starting at given node.""" 82 83 def get_children(parent) -> Iterator: 84 yield parent 85 if parent.type in ["root", "element"]: 86 for child in parent.children: 87 yield from get_children(child) 88 89 parent = start.parent 90 idx = parent.children.index(start) 91 if idx < len(parent.children) - 1: 92 for child in parent.children[idx + 1 :]: 93 yield from get_children(child)
Recursively traverse the tree starting at given node.