Merge pull request #3582 from 0xDEADFED5/ansi_fix

add true color parsing to ANSIString
This commit is contained in:
Griatch 2024-07-20 07:37:29 +02:00 committed by GitHub
commit 4e4b440a7d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 40 additions and 25 deletions

View file

@ -822,7 +822,7 @@ class ANSIString(str, metaclass=ANSIMeta):
if not decoded:
# Completely new ANSI String
clean_string = parser.parse_ansi(string, strip_ansi=True, mxp=MXP_ENABLED)
string = parser.parse_ansi(string, xterm256=True, mxp=MXP_ENABLED)
string = parser.parse_ansi(string, xterm256=True, mxp=MXP_ENABLED, truecolor=True)
elif clean_string is not None:
# We have an explicit clean string.
pass

View file

@ -121,27 +121,22 @@ class HexColors:
r, g, b = self._hex_to_rgb_24_bit(tag)
# Is it greyscale?
if r == g and g == b:
return f"{indicator}=" + self._GREYS[self._grey_int(r)]
if not truecolor:
# Fallback to xterm256 syntax
r, g, b = self._rgb_24_bit_to_256(r, g, b)
return f"{indicator}{r}{g}{b}"
else:
if not truecolor:
# Fallback to xterm256 syntax
r, g, b = self._rgb_24_bit_to_256(r, g, b)
return f"{indicator}{r}{g}{b}"
xtag = f"\033["
if "[" in indicator:
# Background Color
xtag += "4"
else:
xtag = f"\033["
if "[" in indicator:
# Background Color
xtag += "4"
xtag += "3"
else:
xtag += "3"
xtag += f"8;2;{r};{g};{b}m"
return xtag
xtag += f"8;2;{r};{g};{b}m"
return xtag
def xterm_truecolor_to_html_style(self, fg="", bg="") -> str:
"""

View file

@ -15,57 +15,77 @@ class TestANSIStringHex(TestCase):
def setUp(self):
self.str = "test "
self.output1 = "\x1b[38;5;16mtest \x1b[0m"
self.output1_truecolor = "\x1b[38;2;0;0;0mtest \x1b[0m"
self.output2 = "\x1b[48;5;16mtest \x1b[0m"
self.output2_truecolor = "\x1b[48;2;0;0;0mtest \x1b[0m"
self.output3 = "\x1b[38;5;46mtest \x1b[0m"
self.output3_truecolor = "\x1b[38;2;0;255;0mtest \x1b[0m"
self.output4 = "\x1b[48;5;46mtest \x1b[0m"
self.output4_truecolor = "\x1b[48;2;0;255;0mtest \x1b[0m"
def test_long_grayscale_fg(self):
raw = f"|#000000{self.str}|n"
ansi = AN(raw)
ansi_256 = parser(raw, xterm256=True)
self.assertEqual(ansi.clean(), self.str, "Cleaned")
self.assertEqual(ansi.raw(), self.output1, "Output")
self.assertEqual(ansi.raw(), self.output1_truecolor, "Output truecolor")
self.assertEqual(ansi_256, self.output1, "Output xterm256")
def test_long_grayscale_bg(self):
raw = f"|[#000000{self.str}|n"
ansi = AN(raw)
ansi_256 = parser(raw, xterm256=True)
self.assertEqual(ansi.clean(), self.str, "Cleaned")
self.assertEqual(ansi.raw(), self.output2, "Output")
self.assertEqual(ansi.raw(), self.output2_truecolor, "Output truecolor")
self.assertEqual(ansi_256, self.output2, "Output xterm256")
def test_short_grayscale_fg(self):
raw = f"|#000{self.str}|n"
ansi = AN(raw)
ansi_256 = parser(raw, xterm256=True)
self.assertEqual(ansi.clean(), self.str, "Cleaned")
self.assertEqual(ansi.raw(), self.output1, "Output")
self.assertEqual(ansi.raw(), self.output1_truecolor, "Output truecolor")
self.assertEqual(ansi_256, self.output1, "Output xterm256")
def test_short_grayscale_bg(self):
raw = f"|[#000{self.str}|n"
ansi = AN(raw)
ansi_256 = parser(raw, xterm256=True)
self.assertEqual(ansi.clean(), self.str, "Cleaned")
self.assertEqual(ansi.raw(), self.output2, "Output")
self.assertEqual(ansi.raw(), self.output2_truecolor, "Output truecolor")
self.assertEqual(ansi_256, self.output2, "Output xterm256")
def test_short_color_fg(self):
raw = f"|#0F0{self.str}|n"
ansi = AN(raw)
ansi_256 = parser(raw, xterm256=True)
self.assertEqual(ansi.clean(), self.str, "Cleaned")
self.assertEqual(ansi.raw(), self.output3, "Output")
self.assertEqual(ansi.raw(), self.output3_truecolor, "Output truecolor")
self.assertEqual(ansi_256, self.output3, "Output xterm256")
def test_short_color_bg(self):
raw = f"|[#0f0{self.str}|n"
ansi = AN(raw)
ansi_256 = parser(raw, xterm256=True)
self.assertEqual(ansi.clean(), self.str, "Cleaned")
self.assertEqual(ansi.raw(), self.output4, "Output")
self.assertEqual(ansi.raw(), self.output4_truecolor, "Output truecolor")
self.assertEqual(ansi_256, self.output4, "Output xterm256")
def test_long_color_fg(self):
raw = f"|#00ff00{self.str}|n"
ansi = AN(raw)
ansi_256 = parser(raw, xterm256=True)
self.assertEqual(ansi.clean(), self.str, "Cleaned")
self.assertEqual(ansi.raw(), self.output3, "Output")
self.assertEqual(ansi.raw(), self.output3_truecolor, "Output truecolor")
self.assertEqual(ansi_256, self.output3, "Output xterm256")
def test_long_color_bg(self):
raw = f"|[#00FF00{self.str}|n"
ansi = AN(raw)
ansi_256 = parser(raw, xterm256=True)
self.assertEqual(ansi.clean(), self.str, "Cleaned")
self.assertEqual(ansi.raw(), self.output4, "Output")
self.assertEqual(ansi.raw(), self.output4_truecolor, "Output truecolor")
self.assertEqual(ansi_256, self.output4, "Output xterm256")
class TestANSIParser(TestCase):