pytex/PyTeX/format/macros.py

132 lines
3.7 KiB
Python
Raw Normal View History

from typing import List, Union
from enum import Enum
2022-02-06 19:36:37 +01:00
import re
from .constants import *
2022-02-06 19:36:37 +01:00
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'
2022-02-06 19:40:41 +01:00
2022-02-06 19:36:37 +01:00
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:
2022-02-06 19:40:41 +01:00
new_args.append(call_args[arg.value - 1])
2022-02-06 19:36:37 +01:00
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:
2022-02-06 19:40:41 +01:00
new_kwargs[kw] = call_args[self.kwargs[kw].value - 1]
2022-02-06 19:36:37 +01:00
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
2022-02-06 19:36:37 +01:00
def apply(self, line: str, formatter) -> Union[str, List[str]]:
raise NotImplementedError
2022-02-06 19:36:37 +01:00
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
)