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
72
73
74
75
76
77
78
79
80
|
from ... import html_paths
from .tokeniser import TokenType
from .token_parser import parse_identifier, parse_string, try_parse_class_name
def parse_html_path(tokens):
if tokens.try_skip(TokenType.SYMBOL, "!"):
return html_paths.ignore
else:
return html_paths.path(_parse_html_path_elements(tokens))
def _parse_html_path_elements(tokens):
elements = []
if tokens.peek_token_type() == TokenType.IDENTIFIER:
elements.append(_parse_element(tokens))
while tokens.try_skip_many(((TokenType.WHITESPACE, None), (TokenType.SYMBOL, ">"))):
tokens.skip(TokenType.WHITESPACE)
elements.append(_parse_element(tokens))
return elements
def _parse_element(tokens):
tag_names = _parse_tag_names(tokens)
class_names = _parse_class_names(tokens)
is_fresh = _parse_is_fresh(tokens)
separator = _parse_separator(tokens)
return html_paths.element(
tag_names,
class_names=class_names,
fresh=is_fresh,
separator=separator,
)
def _parse_tag_names(tokens):
tag_names = [parse_identifier(tokens)]
while tokens.try_skip(TokenType.SYMBOL, "|"):
tag_names.append(parse_identifier(tokens))
return tag_names
def _parse_class_names(tokens):
class_names = []
while True:
class_name = try_parse_class_name(tokens)
if class_name is None:
break
else:
class_names.append(class_name)
return class_names
def _parse_is_fresh(tokens):
return tokens.try_skip_many((
(TokenType.SYMBOL, ":"),
(TokenType.IDENTIFIER, "fresh"),
))
def _parse_separator(tokens):
is_separator = tokens.try_skip_many((
(TokenType.SYMBOL, ":"),
(TokenType.IDENTIFIER, "separator"),
))
if is_separator:
tokens.skip(TokenType.SYMBOL, "(")
value = parse_string(tokens)
tokens.skip(TokenType.SYMBOL, ")")
return value
else:
return None
|