| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- import _io
- class template_exception(Exception):
- pass
- class template:
- def __init__(self, content: str | _io.TextIOWrapper, check: bool = True):
- self.__template = None
- self.__rendered = None
- self.__properties = dict()
- if type(content) is str:
- self.__template = content
- if type(content) is _io.TextIOWrapper:
- self.__template = content.read()
- if self.__template is None:
- raise Exception("Template content must be string or file.")
-
- if check is True:
- self.__prepare_template()
- @property
- def separators(self) -> [str, str]:
- return "<<!", "!>>"
- def __prepare_template(self) -> None:
- template = self.template
- start, end = self.separators
- count = 0
- current = 0
- while True:
- current_start = template.find(start, count)
-
- if current_start == -1:
- break
-
- current = current_start + len(start)
- current_end = template.find(end, count)
- current_after = current_end + len(end)
- if current > current_end:
- found = "Close char before start char on " + str(current)
- raise template_exception(found)
-
- key = template[current:current_end]
- key = key.strip()
- if len(key) == 0:
- raise template_exception("Empty key on " + str(current))
- before = template[:current_start]
- after = template[current_after:]
- template = before + start + key + end + after
- count = current + len(key) + len(end)
- self.__template = template
- @property
- def template(self) -> str:
- return self.__template
- def get(self, name: str) -> str:
- if not type(name) is str:
- raise Exception("Name of the key must be str.")
- if not name in self.__properties:
- raise Exception("Key " + name + " not exists in properties.")
- return self.__properties[name]
- def set(self, name: str, value: str | int | float) -> template:
- if not type(name) is str:
- raise Exception("Name of the attribute must be str.")
- if type(value) is str:
- self.__properties[name] = value
- return self
- if type(value) is int or type(value) is float:
- self.__properties[name] = str(value)
- return self
- raise Exception("Value to set must be str, int or float.")
- def clone(self) -> template:
- return template(self.template, False)
- def __key(self, target: str) -> str:
- start, end = self.separators
- return start + target + end
- def render(self) -> str:
- if not self.__rendered is None:
- return self.__rendered
- template = self.template
- for name, value in self.__properties.items():
- template = template.replace(self.__key(name), value)
- self.__rendered = template
-
- return self.render()
|