diff --git a/README.md b/README.md
index 297aa3d..b989200 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@ Replit-py is a python library designed to be run from a repl on [repl.it](https:
- Fully featured database client for Repl DB
- Audio library which can play tones and files
-- Clear the terminal
+- Terminal Utillity library which can create and clear colors better than most libaries
### Documentation
diff --git a/src/replit/__init__.py b/src/replit/__init__.py
index 9d74f1f..6b49b8e 100644
--- a/src/replit/__init__.py
+++ b/src/replit/__init__.py
@@ -1,12 +1,11 @@
"""The replit python module."""
from . import maqpy
+from . import termutils
from .audio import Audio
from .database import db
-
def clear() -> None:
"""Clear the terminal."""
print("\033[H\033[2J", end="", flush=True)
-
-
+
audio = Audio()
diff --git a/src/replit/maqpy/html.py b/src/replit/maqpy/html.py
index 0014bb9..eb877d0 100644
--- a/src/replit/maqpy/html.py
+++ b/src/replit/maqpy/html.py
@@ -58,29 +58,29 @@ class Link(HTMLElement):
class Page(flask.Response):
- """Represents an HTML page."""
+ """Represents an HTML page."""
- def __init__(self, title: str = None, head: str = "", body: str = "") -> None:
- """Initialize the class.
+ def __init__(self, title: str = None, head: str = "", body: str = "") -> None:
+ """Initialize the class.
- Args:
- title (str): The title of the page. If not provided no title tag will be sent.
- head (str): The HTML to put in the head of the page. Defaults to nothing.
- body (str): The HTML to put in the body of the page. Defaults to nothing.
- """
- self.title = title
- self.head = head
- self.body = body
+ Args:
+ title (str): The title of the page. If not provided no title tag will be sent.
+ head (str): The HTML to put in the head of the page. Defaults to nothing.
+ body (str): The HTML to put in the body of the page. Defaults to nothing.
+ """
+ self.title = title
+ self.head = head
+ self.body = body
- title_html = f"
{self.title}\n " if self.title else ""
- super().__init__(
+ title_html = f"{self.title}\n " if self.title else ""
+ super().__init__(
f"""
-
-
- {title_html}{self.head}
-
-
- {self.body}
-
-"""
- )
+
+
+ {title_html}{self.head}
+
+
+ {self.body}
+
+ """
+ )
diff --git a/src/replit/termutils.py b/src/replit/termutils.py
new file mode 100644
index 0000000..d51d781
--- /dev/null
+++ b/src/replit/termutils.py
@@ -0,0 +1,178 @@
+"""Pure Python ANSI Color Escape Code generator."""
+import colorsys
+
+def clear() -> None:
+ """Clear the terminal."""
+ print("\033[H\033[2J", end="", flush=True)
+
+
+class Color:
+ """Dynamic Color: Accepts RGB Color."""
+
+ def __init__(self, r: int, g: int, b: int) -> None:
+
+ """
+ Generate an ANSI escape code for color
+
+ Args:
+ r (int): Amount of red in color
+ g (int): Amount of green in color
+ b (int): Amount of blue in color
+
+ Raises:
+ ValueError
+ """
+
+ if r < 0 or g < 0 or b < 0:
+ raise ValueError("No Color Support for colors under 0")
+ if r > 255 or g > 255 or b > 255:
+ raise ValueError("No Color Support for colors over 255")
+
+ self.rgb = (r, g, b)
+ self.fg = f"\033[38;2;{r};{g};{b}m"
+ self.bg = f"\033[48;2;{r};{g};{b}m"
+
+ @classmethod
+ def hexdec(cls, hexvalue: str) -> None:
+ """
+ Convert Hex Value to RGB
+ then generate an ANSI escape code
+
+ Args:
+ hexvalue (str): The color's hex value
+
+ Raises:
+ ValueError
+
+ Returns:
+ color : RGB colors from Hex Value
+ """
+
+ try:
+ hexvalue = hexvalue.lstrip("#")
+ r, g, b = tuple(int(hexvalue[i : i + 2], 16) for i in (0, 2, 4))
+ except Exception as e:
+ raise ValueError(f"Error while converting Hex to RGB - {e}")
+
+ return cls(r, g, b)
+
+ @classmethod
+ def hsv(cls, h, s, v) -> None:
+ """
+ Convert Hex Value to RGB
+ then generate an ANSI escape code
+
+ Args:
+ hexvalue (str): The color's hex value
+
+ Raises:
+ ValueError
+
+ Returns:
+ color : RGB colors from Hex Value
+ """
+ try:
+ r, g, b = colorsys.hsv_to_rgb(h, s, v)
+ except:
+ raise ValueError('Converting HSV to RGB ran into an error')
+
+ return cls(r, g, b)
+
+ @classmethod
+ def hls(cls, h, l, s)
+ """
+ Convert Hex Value to RGB
+ then generate an ANSI escape code
+
+ Args:
+ hexvalue (str): The color's hex value
+
+ Raises:
+ ValueError
+
+ Returns:
+ color : RGB colors from Hex Value
+ """
+ try:
+ r, g, b = colorsys.hls_to_rgb(h, s, v)
+ except:
+ raise ValueError('Converting HLS to RGB ran into an error')
+
+ return cls(r, g, b)
+
+class Bit:
+ def __init__(self, value: int) -> None:
+ """
+ Use a 8bit colorpallete
+ colors from 0-255 (256 total)
+
+ Args:
+ value (int): A color value from 0 to 255
+
+ Raises:
+ ValueError
+ """
+
+ if value > 255:
+ raise ValueError("8 Bit Pallete - No Color Support for Colors over 255")
+ if value < 0:
+ raise ValueError("8 Bit Pallete - No Color Support for colors under 0")
+
+ self.fg = f"\033[38;5;{value}m"
+ self.bg = f"\033[48;5;{value}m"
+
+
+attributes = { # use only repl.it supported ansi codes. Codes such as blink do not work.
+ "reset": 0,
+ "bold": 1,
+ "faint": 2,
+ "italic": 3,
+ "underline": 4,
+ "highlight": 7,
+}
+
+
+class Attr:
+ def __init__(self, attrib: str) -> None:
+ """
+ Custom Attributes such as bold and italic
+ Returns ANSI Escape
+
+ Args:
+ attrib (str): Special Styles for characters
+
+ Raises:
+ ValueError
+ """
+
+ if attrib in attributes:
+ self.attr = f"\033[{attributes[attrib]}m"
+ else:
+ raise ValueError(f"Attributes - {attrib} is not supported.")
+
+
+reset = attr("reset").attr
+bold = attr("bold").attr
+italic = attr("italic").attr
+red = color(255, 0, 0)
+orange = color(255, 165, 0)
+yellow = color(255, 255, 0)
+green = color(0, 255, 0)
+blue = color(0, 0, 255)
+indigo = color(75, 0, 130)
+violet = color(238, 130, 238)
+purple = color(128, 0, 128)
+pink = color(255, 105, 180)
+brown = color(165, 42, 42)
+brightred = color(250, 128, 114)
+brightorange = color(255, 215, 0)
+brightyellow = color(255, 255, 102)
+brightgreen = color(102, 255, 102)
+brightblue = color(102, 178, 255)
+brightpurple = color(178, 102, 255)
+darkred = color(139, 0, 0)
+darkorange = color(255, 140, 0)
+darkyellow = color(204, 204, 0)
+darkgreen = color(0, 153, 0)
+darkblue = color(0, 0, 204)
+darkpurple = color(102, 0, 204)