132 lines
3.7 KiB
Python
132 lines
3.7 KiB
Python
import re
|
|
from enum import Enum
|
|
from typing import List, Union
|
|
|
|
from .constants import *
|
|
|
|
|
|
class MacroReplacementAtomIF:
|
|
pass
|
|
|
|
|
|
class FormatterProperty(MacroReplacementAtomIF, Enum):
|
|
author = 'author'
|
|
shortauthor = 'shortauthor'
|
|
date = 'date'
|
|
year = 'year'
|
|
version = 'version',
|
|
file_name = 'file_name'
|
|
name = 'name' # class or package name
|
|
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:
|
|
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):
|
|
raise NotImplementedError
|
|
|
|
def matches(self, line: str) -> bool:
|
|
raise NotImplementedError
|
|
|
|
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}(?<!@)\)'.format(
|
|
keyword=FORMATTER_PREFIX + self.macroname,
|
|
arguments=','.join(['(.*?)'] * self.num_args)
|
|
))
|
|
|
|
def matches(self, line: str) -> 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
|
|
)
|