Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

base underline style and color extension support #56

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions sty/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,11 @@ def __init__(self):
from sty.register import EfRegister as EfRegister
from sty.register import FgRegister as FgRegister
from sty.register import RsRegister as RsRegister
from sty.register import UnderlineRegister as UnderlineRegister
from sty.register import bg as bg
from sty.register import ef as ef
from sty.register import fg as fg
from sty.register import rs as rs
from sty.register import ul as ul

from sty.rendertype import *
117 changes: 92 additions & 25 deletions sty/register.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"""
from sty import renderfunc
from sty.primitive import Register, Style
from sty.rendertype import EightbitBg, EightbitFg, RgbBg, RgbFg, Sgr
from sty.rendertype import Eightbit, Rgb, Sgr, SgrArgs


class EfRegister(Register):
Expand Down Expand Up @@ -56,11 +56,11 @@ def __init__(self):
super().__init__()

self.renderfuncs[Sgr] = renderfunc.sgr
self.renderfuncs[EightbitFg] = renderfunc.eightbit_fg
self.renderfuncs[RgbFg] = renderfunc.rgb_fg
self.renderfuncs[Eightbit] = renderfunc.eightbit_fg
self.renderfuncs[Rgb] = renderfunc.rgb_fg

self.set_eightbit_call(EightbitFg)
self.set_rgb_call(RgbFg)
self.set_eightbit_call(Eightbit)
self.set_rgb_call(Rgb)

# Classic terminal foreground color preset.
# These are well supported.
Expand All @@ -86,14 +86,14 @@ def __init__(self):
self.white = Style(Sgr(97))

# These are least supported.
self.da_black = Style(EightbitFg(0))
self.da_red = Style(EightbitFg(88))
self.da_green = Style(EightbitFg(22))
self.da_yellow = Style(EightbitFg(58))
self.da_blue = Style(EightbitFg(18))
self.da_magenta = Style(EightbitFg(89))
self.da_cyan = Style(EightbitFg(23))
self.grey = Style(EightbitFg(249))
self.da_black = Style(Eightbit(0))
self.da_red = Style(Eightbit(88))
self.da_green = Style(Eightbit(22))
self.da_yellow = Style(Eightbit(58))
self.da_blue = Style(Eightbit(18))
self.da_magenta = Style(Eightbit(89))
self.da_cyan = Style(Eightbit(23))
self.grey = Style(Eightbit(249))


class BgRegister(Register):
Expand All @@ -112,11 +112,11 @@ def __init__(self):
super().__init__()

self.renderfuncs[Sgr] = renderfunc.sgr
self.renderfuncs[EightbitBg] = renderfunc.eightbit_bg
self.renderfuncs[RgbBg] = renderfunc.rgb_bg
self.renderfuncs[Eightbit] = renderfunc.eightbit_bg
self.renderfuncs[Rgb] = renderfunc.rgb_bg

self.set_eightbit_call(EightbitBg)
self.set_rgb_call(RgbBg)
self.set_eightbit_call(Eightbit)
self.set_rgb_call(Rgb)

# Classic terminal background color preset.
# These are well supported.
Expand All @@ -142,14 +142,80 @@ def __init__(self):
self.white = Style(Sgr(107))

# These are least supported.
self.da_black = Style(EightbitBg(0))
self.da_red = Style(EightbitBg(88))
self.da_green = Style(EightbitBg(22))
self.da_yellow = Style(EightbitBg(58))
self.da_blue = Style(EightbitBg(18))
self.da_magenta = Style(EightbitBg(89))
self.da_cyan = Style(EightbitBg(23))
self.grey = Style(EightbitBg(249))
self.da_black = Style(Eightbit(0))
self.da_red = Style(Eightbit(88))
self.da_green = Style(Eightbit(22))
self.da_yellow = Style(Eightbit(58))
self.da_blue = Style(Eightbit(18))
self.da_magenta = Style(Eightbit(89))
self.da_cyan = Style(Eightbit(23))
self.grey = Style(Eightbit(249))


class UnderlineRegister(Register):
"""
The default 'underline register'.

Instances from this class can be used to create text with colored underlines.

For example:

print(f"{ul.red}{ul.on}Red Underline{ul.rs}")
print(f"{ul.green}{ul.on}Green Underline{ul.rs}")
"""

def __init__(self):
super().__init__()

self.renderfuncs[Sgr] = renderfunc.sgr
self.renderfuncs[SgrArgs] = renderfunc.sgr_args
self.renderfuncs[Eightbit] = renderfunc.eightbit_underline
self.renderfuncs[Rgb] = renderfunc.rgb_underline

self.set_eightbit_call(Eightbit)
self.set_rgb_call(Rgb)

self.on = Style(Sgr(4))
self.off = Style(Sgr(24))
self.line = Style(Sgr(4))
self.double = Style(SgrArgs(4, 2))
self.curly = Style(SgrArgs(4, 3))
self.dotted = Style(SgrArgs(4, 4))
self.dashed = Style(SgrArgs(4, 5))

# Classic terminal background color preset.
# These are well supported.
self.black = Style(Eightbit(0))
self.red = Style(Eightbit(1))
self.green = Style(Eightbit(2))
self.yellow = Style(Eightbit(3))
self.blue = Style(Eightbit(4))
self.magenta = Style(Eightbit(5))
self.cyan = Style(Eightbit(6))
self.li_grey = Style(Eightbit(7))

self.rs = Style(Sgr(59), Sgr(24))
self.default = Style(Sgr(59))

# These are less supported.
self.da_grey = Style(Eightbit(8))
self.li_red = Style(Eightbit(9))
self.li_green = Style(Eightbit(10))
self.li_yellow = Style(Eightbit(11))
self.li_blue = Style(Eightbit(12))
self.li_magenta = Style(Eightbit(13))
self.li_cyan = Style(Eightbit(14))
self.white = Style(Eightbit(15))

# These are least supported.
self.da_black = Style(Eightbit(0))
self.da_red = Style(Eightbit(88))
self.da_green = Style(Eightbit(22))
self.da_yellow = Style(Eightbit(58))
self.da_blue = Style(Eightbit(18))
self.da_magenta = Style(Eightbit(89))
self.da_cyan = Style(Eightbit(23))
self.grey = Style(Eightbit(249))


class RsRegister(Register):
Expand Down Expand Up @@ -193,3 +259,4 @@ def __init__(self):
fg = FgRegister()
bg = BgRegister()
rs = RsRegister()
ul = UnderlineRegister()
23 changes: 23 additions & 0 deletions sty/renderfunc.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,29 @@ def sgr(num: int) -> str:
return "\033[" + str(num) + "m"


def sgr_args(*num: int) -> str:
"""
Create a extended SGR escape sequence.
"""
if not num:
raise TypeError("Need at least one argument")
return "\033[" + ":".join(map(str, num)) + "m"


def eightbit_fg(num: int) -> str:
"""
Create a 8bit (256-color) foreground escape sequence.
"""
return "\033[38;5;" + str(num) + "m"


def eightbit_underline(num: int) -> str:
"""
Create a 8bit (256-color) underline escape sequence.
"""
return "\033[58;5;" + str(num) + "m"


def eightbit_bg(num: int) -> str:
"""
Create a 8bit (256-color) background escape sequence.
Expand All @@ -39,3 +55,10 @@ def rgb_bg(r: int, g: int, b: int) -> str:
Create a 24bit (true color) background escape sequence.
"""
return "\x1b[48;2;" + str(r) + ";" + str(g) + ";" + str(b) + "m"


def rgb_underline(r: int, g: int, b: int) -> str:
"""
Create a 24bit (true color) underline escape sequence.
"""
return "\x1b[58;2;" + str(r) + ";" + str(g) + ";" + str(b) + "m"
39 changes: 16 additions & 23 deletions sty/rendertype.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,23 @@ def __init__(self, num: int):
self.args = [num]


class EightbitFg(RenderType):
class SgrArgs(RenderType):
"""
Define Eightbit Foreground.
Define SGR styling extended rule, rule with argument.

More info about 8-bit terminal colors: https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit
Example of underline extension: https://sw.kovidgoyal.net/kitty/underlines/

:param num: Eightbit number.
:param num: A SGR number.
:param args: A list of argument numbers.
"""

def __init__(self, num: int):
self.args = [num]
def __init__(self, num: int, *args: int):
self.args = [num, *args]


class EightbitBg(RenderType):
class Eightbit(RenderType):
"""
Define Eightbit Background.
Define Eightbit color (foreground, background, underline).

More info about 8-bit terminal colors: https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit

Expand All @@ -48,9 +49,9 @@ def __init__(self, num: int):
self.args = [num]


class RgbFg(RenderType):
class Rgb(RenderType):
"""
Define RGB Foreground.
Define RGB color (foreground, background, underline).

More info about 24-bit terminal colors: https://en.wikipedia.org/wiki/ANSI_escape_code#24-bit

Expand All @@ -63,16 +64,8 @@ def __init__(self, r: int, g: int, b: int):
self.args = [r, g, b]


class RgbBg(RenderType):
"""
Define RGB Background.

More info about 24-bit terminal colors: https://en.wikipedia.org/wiki/ANSI_escape_code#24-bit

:param r: Red.
:param g: Green.
:param b: Blue.
"""

def __init__(self, r: int, g: int, b: int):
self.args = [r, g, b]
# Backward compatibility.
EightbitFg = Eightbit
EightbitBg = Eightbit
RgbFg = Rgb
RgbBg = Rgb