blob: 4418dbb18b12eb28f5f17e8f5e1b8a5dffb05cfc (
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
68
69
70
71
|
from parsimonious.grammar import Grammar
from . import html_paths
def read_html_path(string):
path_node = _grammar.parse(string)
return _read_path_node(path_node)
def _read_path_node(path_node):
elements = [
_read_element_node(child)
for child in _repeated_children_with_separator(path_node, has_whitespace=True)
]
return html_paths.path(elements)
def _read_element_node(node):
tag_names = _read_tag_names_node(node.children[0])
class_names = _read_class_names_node(node.children[1])
return html_paths.element(tag_names, class_names=class_names)
def _read_tag_names_node(node):
return [
child.text
for child in _repeated_children_with_separator(node, has_whitespace=False)
]
def _read_class_names_node(class_names_node):
return [
_read_class_name_node(node)
for node in class_names_node.children
]
def _read_class_name_node(node):
return node.children[1].text
def _repeated_children_with_separator(node, has_whitespace):
yield node.children[0]
if has_whitespace:
sequence_node_index = 2
else:
sequence_node_index = 1
sequence_node = node.children[sequence_node_index]
for child in sequence_node.children:
yield child.children[sequence_node_index]
_grammar = Grammar(r"""
path = element whitespace* (">" whitespace* element)*
element = tag_names class_name*
class_name = "." identifier
tag_names = identifier ("|" identifier)*
identifier = ~"[A-Z0-9]*"i
whitespace = ~"\s"*
""")
|