aboutsummaryrefslogtreecommitdiff
path: root/mammoth/styles/parser/html_path_parser.py
blob: 9e155b600c9c5b4627ec4cc265db326df5dd4bba (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
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