diff --git a/adafruit_templateengine.py b/adafruit_templateengine.py index 21234cf..bf34f44 100644 --- a/adafruit_templateengine.py +++ b/adafruit_templateengine.py @@ -42,19 +42,94 @@ del implementation -class Language: # pylint: disable=too-few-public-methods - """ - Enum-like class that contains languages supported for escaping. - """ +class Token: # pylint: disable=too-few-public-methods + """Stores a token with its position in a template.""" + + def __init__(self, template: str, start_position: int, end_position: int): + self.template = template + self.start_position = start_position + self.end_position = end_position + + self.content = template[start_position:end_position] + - HTML = "html" - """HTML language""" +class TemplateNotFoundError(OSError): + """Raised when a template file is not found.""" - XML = "xml" - """XML language""" + def __init__(self, path: str): + """Specified template file that was not found.""" + super().__init__(f"Template file not found: {path}") - MARKDOWN = "markdown" - """Markdown language""" + +class TemplateSyntaxError(SyntaxError): + """Raised when a syntax error is encountered in a template.""" + + def __init__(self, token: Token, reason: str): + """Provided token is not a valid template syntax at the specified position.""" + super().__init__(self._underline_token_in_template(token) + f"\n\n{reason}") + + @staticmethod + def _skipped_lines_message(nr_of_lines: int) -> str: + return f"[{nr_of_lines} line{'s' if nr_of_lines > 1 else ''} skipped]" + + @classmethod + def _underline_token_in_template( + cls, token: Token, *, lines_around: int = 4, symbol: str = "^" + ) -> str: + """ + Return ``number_of_lines`` lines before and after ``token``, with the token content + underlined with ``symbol`` e.g.: + + ```html + [8 lines skipped] + Shopping list: +