diff options
Diffstat (limited to 'mammoth')
| -rw-r--r-- | mammoth/styles/parser/html_path_parser.py | 64 | ||||
| -rw-r--r-- | mammoth/styles/parser/token_iterator.py | 22 |
2 files changed, 84 insertions, 2 deletions
diff --git a/mammoth/styles/parser/html_path_parser.py b/mammoth/styles/parser/html_path_parser.py new file mode 100644 index 0000000..e8f448e --- /dev/null +++ b/mammoth/styles/parser/html_path_parser.py @@ -0,0 +1,64 @@ +from ... import html_paths +from .tokeniser import TokenType +from .token_parser import parse_identifier, 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) + + return html_paths.element( + tag_names, + class_names=class_names, + fresh=is_fresh, + ) + + +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"), + )) diff --git a/mammoth/styles/parser/token_iterator.py b/mammoth/styles/parser/token_iterator.py index 810e50b..c6876e9 100644 --- a/mammoth/styles/parser/token_iterator.py +++ b/mammoth/styles/parser/token_iterator.py @@ -1,8 +1,13 @@ +# TODO: check indices + class TokenIterator(object): def __init__(self, tokens): self._tokens = tokens self._index = 0 + def peek_token_type(self): + return self._tokens[self._index].type + def next_value(self, token_type): return self._next(token_type).value @@ -14,9 +19,9 @@ class TokenIterator(object): else: raise self._unexpected_token_type(token_type, token) - def skip(self, token_type, token_value): + def skip(self, token_type, token_value=None): token = self._tokens[self._index] - if token.type == token_type and token.value == token_value: + if token.type == token_type and (token_value is None or token.value == token_value): self._index += 1 return True else: @@ -29,3 +34,16 @@ class TokenIterator(object): return True else: return False + + def try_skip_many(self, tokens): + start = self._index + for token_type, token_value in tokens: + token = self._tokens[self._index] + if not (token.type == token_type and (token_value is None or token.value == token_value)): + self._index = start + return False + else: + self._index += 1 + + return True + |
