Source code for mil_misc_tools.text_effects

from typing import Callable, Optional


class Colors:
    red = "\033[31m"
    green = "\033[32m"
    yellow = "\033[33m"
    blue = "\033[34m"
    purple = "\033[35m"
    cyan = "\033[36m"
    white = "\033[37m"

    underline = "\033[2m"
    bold = "\033[1m"
    negative = "\033[3m"

    reset = "\033[0m"

    def __getattr__(self, arg):
        # If we get a non existent color, return the reset color
        return self.reset


class Printer:
    def __init__(self, string: Optional[str] = "", autospace: bool = False):
        self._autospace = autospace
        self._string = string

        # Default adding text
        self.text = lambda text: self + text

        # Colors
        self.red = lambda text: self + (Colors.red + str(text) + Colors.reset)
        self.green = lambda text: self + (Colors.green + str(text) + Colors.reset)
        self.yellow = lambda text: self + (Colors.yellow + str(text) + Colors.reset)
        self.blue = lambda text: self + (Colors.blue + str(text) + Colors.reset)
        self.purple = lambda text: self + (Colors.purple + str(text) + Colors.reset)
        self.cyan = lambda text: self + (Colors.cyan + str(text) + Colors.reset)
        self.white = lambda text: self + (Colors.white + str(text) + Colors.reset)

        # Text effects
        self.underline = lambda text: Printer(
            self._string + Colors.underline + str(text) + Colors.reset,
        )
        self.bold = lambda text: Printer(
            self._string + Colors.bold + str(text) + Colors.reset,
        )
        self.negative = lambda text: Printer(
            self._string + Colors.negative + str(text) + Colors.reset,
        )

        # For passing in custom formatting
        self.custom = lambda text, effect: self + (effect + str(text) + Colors.reset)

    def __repr__(self):
        return self._string + Colors.reset

    __str__ = __repr__

    def __add__(self, other):
        extra_space = " " if self._autospace and self._string != "" else ""
        return Printer(self._string + extra_space + str(other), self._autospace)

    @property
    def set_red(self):
        return Printer(self._string + Colors.red)

    @property
    def set_green(self):
        return Printer(self._string + Colors.green)

    @property
    def set_yellow(self):
        return Printer(self._string + Colors.yellow)

    @property
    def set_blue(self):
        return Printer(self._string + Colors.blue)

    @property
    def set_purple(self):
        return Printer(self._string + Colors.purple)

    @property
    def set_cyan(self):
        return Printer(self._string + Colors.cyan)

    @property
    def set_white(self):
        return Printer(self._string + Colors.white)

    @property
    def reset(self):
        return Printer(self._string + Colors.reset)

    def space(self, count=1):
        return Printer(self._string + " " * count)

    def newline(self, count=1):
        return Printer(self._string + "\n" * count)

    def enable_autospaces(self):
        self._autospace = False

    def disable_autospaces(self):
        self._autospace = True


[docs]class FprintFactory: """ Factory method for producing a printer with the specified characteristics. Args: title (Optional[str]): The title to produce with each printed message. time (Optional[Callable]): A method for getting the time to produce with each method. If ``None``, then no time is sent with a message. msg_color (Optional[str]): The color of each message. If ``None``, defaults to white. auto_bold (bool): Automatically bolds each method. Defaults to ``True``. newline (int): The number of newlines to print after each method. """ def __init__( self, title: Optional[str] = None, time: Optional[Callable] = None, msg_color: Optional[str] = None, auto_bold: bool = True, newline: int = 1, ): assert time is None or callable( time, ), "`time` should be `None` for no printing or a function that generates a timestamp." assert msg_color is None or isinstance( msg_color, str, ), "`msg_color` should be `None` for default printing or a string color." assert isinstance( auto_bold, bool, ), "`auto_bold` should be true or false if messages should be printed\ as bold by default or not" assert newline is None or isinstance( newline, int, ), "`newline` should be the number of newlines after the text (default 1)" # All these can be overwritten if not specified here self.title = title # Title to print with each message # Either `None` for no printing or a function that generates a # timestamp self.time = time self.msg_color = ( msg_color # Either `None` for default printing or a string color ) self.auto_bold = auto_bold # Should each message be bolded by default self.newline = newline # The number of newlines characters to add to the end self.printer = Printer()
[docs] def fprint(self, text: str, **kwargs): """ Prints some text with the specified characteristics. Characteristics can be passed through the kwargs argument or through the class' constructor. Args: text (str): The text to format and then print kwargs: Any characteristics to print with the text. All keyword arguments are the same as the arguments specified in the constructor. """ title = kwargs.get("title", self.title) time = kwargs.get("time", self.time) msg_color = kwargs.get("msg_color", self.msg_color) auto_bold = kwargs.get("auto_bold", self.auto_bold) newline = kwargs.get("newline", self.newline) message = self.printer if title is not None: message = message.set_blue.bold(title).reset.space() if time is not None: t = time() message = message.bold(t).space() message += ": " if auto_bold: text = str(self.printer.bold(text)) if msg_color is not None: message = message.custom(text, getattr(Colors, msg_color)) else: message = message.text(text) if newline == 1: print(message) else: print(message.newline(newline - 1))
# Standard instantiation fprint = FprintFactory().fprint