diff --git a/PyTeX/format/macros.py b/PyTeX/format/macros.py index 23f9bd9..012400c 100644 --- a/PyTeX/format/macros.py +++ b/PyTeX/format/macros.py @@ -1,8 +1,14 @@ from typing import List, Union from enum import Enum +import re +from .constants import * -class MacroReplacement(Enum): +class MacroReplacementAtomIF: + pass + + +class FormatterProperty(MacroReplacementAtomIF, Enum): author = 'author' shortauthor = 'shortauthor' date = 'date' @@ -13,6 +19,71 @@ class MacroReplacement(Enum): repo_version = 'repo_version' pytex_version = 'pytex_version' +class Argument(MacroReplacementAtomIF, Enum): + one = 1 + two = 2 + three = 3 + four = 4 + five = 5 + six = 6 + + + +class MacroReplacement(str): + def __init__( + self, + replacement: str, + format_type: str = '%', + *args, + **kwargs + ): + self.replacement: str = replacement + self.format_type = '%', + self.args = args + self.kwargs = kwargs + + def make_format_args(self, formatter, *call_args): + new_args = [] + for arg in self.args: + if type(arg) == FormatterProperty: + try: + new_args.append(getattr(formatter, arg.value)) + except: + raise NotImplementedError + elif type(arg) == Argument: + try: + new_args.append(call_args[arg.value -1]) + except: + raise NotImplementedError + elif type(arg) == str: + new_args.append(arg) + else: + raise NotImplementedError + new_kwargs = {} + for kw in self.kwargs.keys(): + if type(self.kwargs[kw]) == FormatterProperty: + new_kwargs[kw] = getattr(formatter, self.kwargs[kw].value) + elif type(self.kwargs[kw]) == Argument: + new_kwargs[kw] = call_args[self.kwargs[kw].value -1] + elif type(self.kwargs[kw]) == str: + new_kwargs[kw] = self.kwargs[kw] + else: + raise NotImplementedError + return new_args, new_kwargs + + def format(self, formatter, *call_args) -> str: + args, kwargs = self.make_format_args(formatter, *call_args) + if self.format_type == '%': + if self.args: + raise NotImplementedError # Currently, not supported + return self.replacement % kwargs + elif self.format_type == '{': + return self.replacement.format( + *args, **kwargs + ) + else: + raise NotImplementedError + class Macro: def __init__(self): @@ -21,5 +92,40 @@ class Macro: def matches(self, line: str) -> bool: raise NotImplementedError - def apply(self, line: str, *args, **kwargs) -> Union[str, List[str]]: + def apply(self, line: str, formatter) -> Union[str, List[str]]: raise NotImplementedError + + +class BasicMacro(Macro): + def __init__( + self, + macroname, + num_args: int, + macro_replacement: MacroReplacement + ): + self.macroname = macroname + self.num_args = num_args + self.macro_replacement: MacroReplacement = macro_replacement + self._search_regex = re.compile(r'{keyword}\({arguments}(? bool: + match = re.search(self._search_regex, line) + if match is None: + return False + else: + return True + + def apply(self, line: str, formatter) -> Union[str, List[str]]: + match = re.search(self._search_regex, line) + if match is None: + raise NotImplementedError + replacement = self.macro_replacement.format( + formatter, match.groups() + ) + return line.replace( + match.group(), + replacement + )