2019-01-24 09:43:22 +00:00
|
|
|
# encoding: utf-8
|
2019-01-22 10:15:47 +00:00
|
|
|
from typing import Optional, Union
|
|
|
|
|
|
|
|
|
|
|
|
class Indent:
|
|
|
|
class IdentStart:
|
|
|
|
def __init__(self, text):
|
|
|
|
self.text = text
|
|
|
|
|
|
|
|
class IdentEnd:
|
|
|
|
def __init__(self, text):
|
|
|
|
self.text = text
|
|
|
|
|
|
|
|
class IdentEndLater:
|
|
|
|
def __init__(self, text):
|
|
|
|
self.text = text
|
|
|
|
|
2019-01-24 09:43:22 +00:00
|
|
|
def __init__(self, text: Optional[Union[str, "TextHolder"]] = None):
|
2019-01-22 10:15:47 +00:00
|
|
|
self.text = text
|
|
|
|
|
|
|
|
def __add__(self, other: str):
|
|
|
|
assert self.text is None
|
|
|
|
return Indent(other)
|
|
|
|
|
|
|
|
def __radd__(self, other: str):
|
|
|
|
assert self.text is None
|
|
|
|
return Indent.IdentStart(other)
|
|
|
|
|
|
|
|
def __rsub__(self, other: str):
|
|
|
|
assert self.text is None
|
|
|
|
return Indent.IdentEnd(other)
|
|
|
|
|
|
|
|
|
|
|
|
class IndentLater:
|
|
|
|
def __rsub__(self, other: str):
|
|
|
|
return Indent.IdentEndLater(other)
|
|
|
|
|
|
|
|
|
|
|
|
class TextHolder:
|
|
|
|
def __init__(self, text: Optional[str] = None):
|
|
|
|
super().__init__()
|
|
|
|
if text is None:
|
2019-01-24 09:43:22 +00:00
|
|
|
text = ""
|
2019-01-22 10:15:47 +00:00
|
|
|
self.text = text
|
|
|
|
self.ident_text = " "
|
|
|
|
self._ident = 0
|
|
|
|
|
|
|
|
def __add__(self, other: Union[str, int]):
|
|
|
|
if isinstance(other, Indent.IdentStart):
|
|
|
|
self.append(other.text)
|
|
|
|
self.ident(1)
|
|
|
|
elif isinstance(other, Indent.IdentEnd):
|
|
|
|
self.ident(-1)
|
|
|
|
self.append(other.text)
|
|
|
|
elif isinstance(other, Indent.IdentEndLater):
|
|
|
|
self.append(other.text)
|
|
|
|
self.ident(-1)
|
|
|
|
elif isinstance(other, Indent):
|
|
|
|
self.append(
|
2019-01-24 09:43:22 +00:00
|
|
|
TextHolder(str(other.text)).ident_all(
|
|
|
|
n=self._ident + 1, ident_text=self.ident_text
|
|
|
|
),
|
|
|
|
add_ident=False,
|
|
|
|
)
|
2019-01-22 10:15:47 +00:00
|
|
|
elif isinstance(other, str):
|
|
|
|
self.append(other)
|
|
|
|
elif isinstance(other, TextHolder):
|
|
|
|
self.append(
|
2019-01-24 09:43:22 +00:00
|
|
|
TextHolder(str(other.text)).ident_all(
|
|
|
|
n=self._ident, ident_text=self.ident_text
|
|
|
|
),
|
|
|
|
add_ident=False,
|
|
|
|
)
|
2019-01-22 10:15:47 +00:00
|
|
|
elif isinstance(other, int):
|
|
|
|
self.ident(other)
|
|
|
|
else:
|
|
|
|
raise TypeError(f"can only add str or int, but {type(other)} got")
|
|
|
|
return self
|
|
|
|
|
|
|
|
def __sub__(self, other):
|
|
|
|
if isinstance(other, int):
|
|
|
|
self.ident(-other)
|
|
|
|
else:
|
|
|
|
raise TypeError(f"can only add str or int, but {type(other)} got")
|
|
|
|
return self
|
|
|
|
|
|
|
|
def __bool__(self):
|
|
|
|
return bool(self.text)
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return self.text
|
|
|
|
|
2019-01-24 09:43:22 +00:00
|
|
|
def append(
|
|
|
|
self,
|
|
|
|
text: Union[str, "TextHolder"],
|
|
|
|
ensure_new_line=True,
|
|
|
|
ignore_empty=True,
|
|
|
|
add_ident=True,
|
|
|
|
):
|
2019-01-22 10:15:47 +00:00
|
|
|
strtext = str(text)
|
|
|
|
if ignore_empty and not strtext:
|
|
|
|
return self
|
2019-01-24 09:43:22 +00:00
|
|
|
if not strtext.endswith("\n") and ensure_new_line:
|
|
|
|
strtext += "\n"
|
2019-01-22 10:15:47 +00:00
|
|
|
if add_ident:
|
|
|
|
self.text += self._ident * self.ident_text + strtext
|
|
|
|
else:
|
|
|
|
self.text += strtext
|
|
|
|
return self
|
|
|
|
|
|
|
|
def ident_all(self, n: int = 1, ident_text: str = None):
|
|
|
|
if ident_text is None:
|
|
|
|
ident_text = self.ident_text
|
|
|
|
text = self.text
|
2019-01-24 09:43:22 +00:00
|
|
|
if text.endswith("\n"):
|
2019-01-22 10:15:47 +00:00
|
|
|
text = text[:-1]
|
2019-01-24 09:43:22 +00:00
|
|
|
return "\n".join([ident_text * n + i for i in text.split("\n")])
|
2019-01-22 10:15:47 +00:00
|
|
|
|
|
|
|
def ident(self, n: int = 1):
|
|
|
|
self._ident += n
|
|
|
|
return self
|