teddecor.TED.tokens

  1from __future__ import annotations
  2from functools import cached_property
  3from lib2to3.pytree import Base
  4from typing import Union, Callable, Dict
  5
  6from .formatting import build_color, ColorType, LINK, RESET, FUNC
  7
  8
  9class Token:
 10    """Generic base class that has a default repr."""
 11
 12    def __repr__(self) -> str:
 13        return f"<{type(self).__name__}: {self._markup}, {self.value}>"
 14
 15
 16class Reset(Token):
 17    @property
 18    def value(self) -> str:
 19        return RESET
 20
 21    def __str__(self) -> str:
 22        return self.value
 23
 24
 25class Func(Token):
 26    def __init__(self, markup: str, funcs: Dict[str, Callable]) -> None:
 27        self._markup: str = markup
 28        self._func: str = markup[1:].strip().lower()
 29        self._caller = lambda string: string
 30        self.parse_func(funcs)
 31
 32    def parse_func(self, funcs: Dict[str, Callable]) -> None:
 33        if self._func in funcs:
 34            self._caller = funcs[self._func]
 35        else:
 36            raise ValueError(f"Invalid Function \x1b[1;31m{self._markup}\x1b[0m")
 37
 38    def exec(self, string: str) -> str:
 39        return self._caller(string)
 40
 41    @property
 42    def value(self) -> str:
 43        return self._func
 44
 45    def __str__(self) -> str:
 46        return self._markup
 47
 48    def __repr__(self) -> str:
 49        return f"<Func: {self._func}"
 50
 51
 52class HLink(Token):
 53    def __init__(self, markup: str) -> None:
 54        self._markup = markup.strip()
 55        self._closing = False
 56        self._value = self.parse_link()
 57
 58    def parse_link(self) -> str:
 59        """Determine if the token is a closing link token and assign _closing accordingly.
 60
 61        Returns:
 62            str: The value of the token based on if the token is closing
 63        """
 64        if len(self._markup) == 1:
 65            self._closing = True
 66            return LINK.CLOSE
 67        elif len(self._markup) > 1:
 68            return LINK.OPEN(self._markup[1:])
 69
 70    @property
 71    def value(self) -> str:
 72        """Value of the token."""
 73        return self._value
 74
 75    @value.setter
 76    def value(self, value: str) -> str:
 77        self._value = value
 78
 79    @property
 80    def closing(self) -> bool:
 81        """True if this link token is a closing link token."""
 82        return self._closing
 83
 84    def __str__(self) -> str:
 85        return self.value
 86
 87
 88class Text(Token):
 89    """Plain text token."""
 90
 91    def __init__(self, markup: str) -> None:
 92        self._markup: str = markup
 93        self._value: str = markup
 94
 95    @property
 96    def value(self) -> str:
 97        """Fomatted value of the tokens markup."""
 98        return self._value
 99
100    @value.setter
101    def value(self, text: str) -> str:
102        """Fomatted value of the tokens markup."""
103        self._value = text
104
105    def __repr__(self) -> str:
106        return f"<{type(self).__name__}: '{self._markup}'>"
107
108    def __str__(self) -> str:
109        return self._value
110
111
112class Color(Token):
113    """A color tokens that is either hex, xterm, rgb, or predefined."""
114
115    def __init__(
116        self, markup: str, colors: list[int] = None, ctype: ColorType = None
117    ) -> None:
118        self._markup: str = markup
119        self._type, self._colors = build_color(markup)
120        if colors is not None:
121            self._colors = colors
122        if ctype is not None:
123            self._type = ctype
124
125    @cached_property
126    def value(self) -> str:
127        """Fomatted value of the tokens markup."""
128        return f"{';'.join(self._colors)}"
129
130    @cached_property
131    def type_str(self) -> str:
132        """Redable type of the color."""
133        if len(self._type) == 1 and self._type[0] == ColorType.FG:
134            return "FG"
135        elif len(self._type) == 1 and self._type[0] == ColorType.BG:
136            return "BG"
137        else:
138            return "FG + BG"
139
140    @property
141    def colors(self) -> list[int]:
142        """List of color codes."""
143        return self._colors
144
145    @colors.setter
146    def colors(self, colors: list[int]) -> None:
147        self._colors = colors
148
149    @property
150    def type(self) -> ColorType:
151        """The colors type; fg, bg, or both."""
152        return self._type
153
154    def __repr__(self) -> str:
155        """String representation of the class when printing class."""
156        return f"<Color: {self.type}, {repr(self.value)}>"
157
158    def __str__(self) -> str:
159        """Full ansi representation of the token."""
160        return f"\x1b[{';'.join(self._colors)}m"
161
162
163class Bold(Token):
164    def __init__(self, value: str) -> None:
165        self._markup: str = "*"
166        self._value: str = value
167
168    @property
169    def value(self) -> int:
170        """The ansi code for the markup."""
171        return self._value
172
173    def __str__(self) -> str:
174        """Full ansi representation of the token."""
175        return f"\x1b[{self.value}m"
176
177
178class Underline(Token):
179    def __init__(self, value: str) -> None:
180        self._markup: str = "_"
181        self._value: str = value
182
183    @property
184    def value(self) -> int:
185        """The ansi code for the markup."""
186        return self._value
187
188    def __str__(self) -> str:
189        """Full ansi representation of the token."""
190        return f"\x1b[{self.value}m"
191
192
193class Formatter(Token):
194    """A class used to combine format tokens that are next to eachother."""
195
196    def __init__(self):
197        self._fg = None
198        self._bg = None
199        self._underline = None
200        self._bold = None
201
202    @property
203    def color(self) -> str:
204        """The colors current in the format"""
205        return f"{self._fg};{self._bg}"
206
207    @color.setter
208    def color(self, color: Color) -> None:
209        if color.type == [ColorType.FG]:
210            self._fg = color
211        elif color.type == [ColorType.BG]:
212            self._bg = color
213        elif color.type == ColorType.BOTH:
214            self._fg = Color("", [color.colors[0]], [ColorType.FG])
215            self._bg = Color("", [color.colors[1]], [ColorType.BG])
216
217    @property
218    def bold(self) -> Union[Bold, None]:
219        """The bold toggle currently in the format."""
220        return self._bold
221
222    @bold.setter
223    def bold(self, bold: Bold) -> None:
224        self._bold = bold if self._bold is None else None
225
226    @property
227    def underline(self) -> Union[Underline, None]:
228        """The underline toggle currently in the format."""
229        return self._underline
230
231    @bold.setter
232    def underline(self, underline: Underline) -> None:
233        self._underline = underline if self._underline is None else None
234
235    def is_empty(self) -> bool:
236        """True if all of fg, bg, underline, and bold are None."""
237        return (
238            self._fg is None
239            and self._bg is None
240            and self._underline is None
241            and self._bold is None
242        )
243
244    def __str__(self) -> str:
245        values = []
246        if self._bold is not None:
247            values.append(self._bold.value)
248        if self._underline is not None:
249            values.append(self._underline.value)
250        if self._fg is not None:
251            values.append(self._fg.value)
252        if self._bg is not None:
253            values.append(self._bg.value)
254
255        if len(values) > 0:
256            return f"\x1b[{';'.join(str(value) for value in values)}m"
257        else:
258            return ""
259
260    def __repr__(self) -> str:
261        return f"<Format: {repr(str(self))}>"
class Token:
10class Token:
11    """Generic base class that has a default repr."""
12
13    def __repr__(self) -> str:
14        return f"<{type(self).__name__}: {self._markup}, {self.value}>"

Generic base class that has a default repr.

Token()
class Reset(Token):
17class Reset(Token):
18    @property
19    def value(self) -> str:
20        return RESET
21
22    def __str__(self) -> str:
23        return self.value

Generic base class that has a default repr.

Reset()
value: str
class Func(Token):
26class Func(Token):
27    def __init__(self, markup: str, funcs: Dict[str, Callable]) -> None:
28        self._markup: str = markup
29        self._func: str = markup[1:].strip().lower()
30        self._caller = lambda string: string
31        self.parse_func(funcs)
32
33    def parse_func(self, funcs: Dict[str, Callable]) -> None:
34        if self._func in funcs:
35            self._caller = funcs[self._func]
36        else:
37            raise ValueError(f"Invalid Function \x1b[1;31m{self._markup}\x1b[0m")
38
39    def exec(self, string: str) -> str:
40        return self._caller(string)
41
42    @property
43    def value(self) -> str:
44        return self._func
45
46    def __str__(self) -> str:
47        return self._markup
48
49    def __repr__(self) -> str:
50        return f"<Func: {self._func}"

Generic base class that has a default repr.

Func(markup: str, funcs: Dict[str, Callable])
27    def __init__(self, markup: str, funcs: Dict[str, Callable]) -> None:
28        self._markup: str = markup
29        self._func: str = markup[1:].strip().lower()
30        self._caller = lambda string: string
31        self.parse_func(funcs)
def parse_func(self, funcs: Dict[str, Callable]) -> None:
33    def parse_func(self, funcs: Dict[str, Callable]) -> None:
34        if self._func in funcs:
35            self._caller = funcs[self._func]
36        else:
37            raise ValueError(f"Invalid Function \x1b[1;31m{self._markup}\x1b[0m")
def exec(self, string: str) -> str:
39    def exec(self, string: str) -> str:
40        return self._caller(string)
value: str
class Text(Token):
 89class Text(Token):
 90    """Plain text token."""
 91
 92    def __init__(self, markup: str) -> None:
 93        self._markup: str = markup
 94        self._value: str = markup
 95
 96    @property
 97    def value(self) -> str:
 98        """Fomatted value of the tokens markup."""
 99        return self._value
100
101    @value.setter
102    def value(self, text: str) -> str:
103        """Fomatted value of the tokens markup."""
104        self._value = text
105
106    def __repr__(self) -> str:
107        return f"<{type(self).__name__}: '{self._markup}'>"
108
109    def __str__(self) -> str:
110        return self._value

Plain text token.

Text(markup: str)
92    def __init__(self, markup: str) -> None:
93        self._markup: str = markup
94        self._value: str = markup
value: str

Fomatted value of the tokens markup.

class Color(Token):
113class Color(Token):
114    """A color tokens that is either hex, xterm, rgb, or predefined."""
115
116    def __init__(
117        self, markup: str, colors: list[int] = None, ctype: ColorType = None
118    ) -> None:
119        self._markup: str = markup
120        self._type, self._colors = build_color(markup)
121        if colors is not None:
122            self._colors = colors
123        if ctype is not None:
124            self._type = ctype
125
126    @cached_property
127    def value(self) -> str:
128        """Fomatted value of the tokens markup."""
129        return f"{';'.join(self._colors)}"
130
131    @cached_property
132    def type_str(self) -> str:
133        """Redable type of the color."""
134        if len(self._type) == 1 and self._type[0] == ColorType.FG:
135            return "FG"
136        elif len(self._type) == 1 and self._type[0] == ColorType.BG:
137            return "BG"
138        else:
139            return "FG + BG"
140
141    @property
142    def colors(self) -> list[int]:
143        """List of color codes."""
144        return self._colors
145
146    @colors.setter
147    def colors(self, colors: list[int]) -> None:
148        self._colors = colors
149
150    @property
151    def type(self) -> ColorType:
152        """The colors type; fg, bg, or both."""
153        return self._type
154
155    def __repr__(self) -> str:
156        """String representation of the class when printing class."""
157        return f"<Color: {self.type}, {repr(self.value)}>"
158
159    def __str__(self) -> str:
160        """Full ansi representation of the token."""
161        return f"\x1b[{';'.join(self._colors)}m"

A color tokens that is either hex, xterm, rgb, or predefined.

Color( markup: str, colors: list[int] = None, ctype: teddecor.TED.formatting.ColorType = None)
116    def __init__(
117        self, markup: str, colors: list[int] = None, ctype: ColorType = None
118    ) -> None:
119        self._markup: str = markup
120        self._type, self._colors = build_color(markup)
121        if colors is not None:
122            self._colors = colors
123        if ctype is not None:
124            self._type = ctype
value: str

Fomatted value of the tokens markup.

type_str: str

Redable type of the color.

colors: list[int]

List of color codes.

type: teddecor.TED.formatting.ColorType

The colors type; fg, bg, or both.

class Bold(Token):
164class Bold(Token):
165    def __init__(self, value: str) -> None:
166        self._markup: str = "*"
167        self._value: str = value
168
169    @property
170    def value(self) -> int:
171        """The ansi code for the markup."""
172        return self._value
173
174    def __str__(self) -> str:
175        """Full ansi representation of the token."""
176        return f"\x1b[{self.value}m"

Generic base class that has a default repr.

Bold(value: str)
165    def __init__(self, value: str) -> None:
166        self._markup: str = "*"
167        self._value: str = value
value: int

The ansi code for the markup.

class Underline(Token):
179class Underline(Token):
180    def __init__(self, value: str) -> None:
181        self._markup: str = "_"
182        self._value: str = value
183
184    @property
185    def value(self) -> int:
186        """The ansi code for the markup."""
187        return self._value
188
189    def __str__(self) -> str:
190        """Full ansi representation of the token."""
191        return f"\x1b[{self.value}m"

Generic base class that has a default repr.

Underline(value: str)
180    def __init__(self, value: str) -> None:
181        self._markup: str = "_"
182        self._value: str = value
value: int

The ansi code for the markup.

class Formatter(Token):
194class Formatter(Token):
195    """A class used to combine format tokens that are next to eachother."""
196
197    def __init__(self):
198        self._fg = None
199        self._bg = None
200        self._underline = None
201        self._bold = None
202
203    @property
204    def color(self) -> str:
205        """The colors current in the format"""
206        return f"{self._fg};{self._bg}"
207
208    @color.setter
209    def color(self, color: Color) -> None:
210        if color.type == [ColorType.FG]:
211            self._fg = color
212        elif color.type == [ColorType.BG]:
213            self._bg = color
214        elif color.type == ColorType.BOTH:
215            self._fg = Color("", [color.colors[0]], [ColorType.FG])
216            self._bg = Color("", [color.colors[1]], [ColorType.BG])
217
218    @property
219    def bold(self) -> Union[Bold, None]:
220        """The bold toggle currently in the format."""
221        return self._bold
222
223    @bold.setter
224    def bold(self, bold: Bold) -> None:
225        self._bold = bold if self._bold is None else None
226
227    @property
228    def underline(self) -> Union[Underline, None]:
229        """The underline toggle currently in the format."""
230        return self._underline
231
232    @bold.setter
233    def underline(self, underline: Underline) -> None:
234        self._underline = underline if self._underline is None else None
235
236    def is_empty(self) -> bool:
237        """True if all of fg, bg, underline, and bold are None."""
238        return (
239            self._fg is None
240            and self._bg is None
241            and self._underline is None
242            and self._bold is None
243        )
244
245    def __str__(self) -> str:
246        values = []
247        if self._bold is not None:
248            values.append(self._bold.value)
249        if self._underline is not None:
250            values.append(self._underline.value)
251        if self._fg is not None:
252            values.append(self._fg.value)
253        if self._bg is not None:
254            values.append(self._bg.value)
255
256        if len(values) > 0:
257            return f"\x1b[{';'.join(str(value) for value in values)}m"
258        else:
259            return ""
260
261    def __repr__(self) -> str:
262        return f"<Format: {repr(str(self))}>"

A class used to combine format tokens that are next to eachother.

Formatter()
197    def __init__(self):
198        self._fg = None
199        self._bg = None
200        self._underline = None
201        self._bold = None
color: str

The colors current in the format

bold: Optional[teddecor.TED.tokens.Bold]

The bold toggle currently in the format.

underline: Optional[teddecor.TED.tokens.Bold]

The bold toggle currently in the format.

def is_empty(self) -> bool:
236    def is_empty(self) -> bool:
237        """True if all of fg, bg, underline, and bold are None."""
238        return (
239            self._fg is None
240            and self._bg is None
241            and self._underline is None
242            and self._bold is None
243        )

True if all of fg, bg, underline, and bold are None.