diff --git a/evennia/utils/ansi.py b/evennia/utils/ansi.py index 66daa67c8c..cfa7192477 100644 --- a/evennia/utils/ansi.py +++ b/evennia/utils/ansi.py @@ -332,7 +332,7 @@ class ANSIParser(object): colval = 134 + ord(letter) # ansi fallback logic expects r,g,b values in [0..5] range - gray = (ord(letter) - 97) / 5.0 + gray = round((ord(letter) - 97) / 5.0) red, green, blue = gray, gray, gray if use_xterm256: @@ -347,62 +347,57 @@ class ANSIParser(object): else: # xterm256 not supported, convert the rgb value to ansi instead - if red == green == blue and red < 3: - if background: - return ANSI_BACK_BLACK - elif red >= 1: - return ANSI_HILITE + ANSI_BLACK - else: - return ANSI_NORMAL + ANSI_BLACK - elif red == green == blue: - if background: - return ANSI_BACK_WHITE - elif red >= 4: - return ANSI_HILITE + ANSI_WHITE - else: - return ANSI_NORMAL + ANSI_WHITE - elif red > green and red > blue: - if background: - return ANSI_BACK_RED - elif red >= 3: - return ANSI_HILITE + ANSI_RED - else: - return ANSI_NORMAL + ANSI_RED - elif red == green and red > blue: - if background: - return ANSI_BACK_YELLOW - elif red >= 3: - return ANSI_HILITE + ANSI_YELLOW - else: - return ANSI_NORMAL + ANSI_YELLOW - elif red == blue and red > green: - if background: - return ANSI_BACK_MAGENTA - elif red >= 3: - return ANSI_HILITE + ANSI_MAGENTA - else: - return ANSI_NORMAL + ANSI_MAGENTA - elif green > blue: - if background: - return ANSI_BACK_GREEN - elif green >= 3: - return ANSI_HILITE + ANSI_GREEN - else: - return ANSI_NORMAL + ANSI_GREEN - elif green == blue: - if background: - return ANSI_BACK_CYAN - elif green >= 3: - return ANSI_HILITE + ANSI_CYAN - else: - return ANSI_NORMAL + ANSI_CYAN - else: # mostly blue - if background: - return ANSI_BACK_BLUE - elif blue >= 3: - return ANSI_HILITE + ANSI_BLUE - else: - return ANSI_NORMAL + ANSI_BLUE + rgb = (red, green, blue) + + def _convert_for_ansi(val): + return int((val+1)//2) + + # greys + if (max(rgb) - min(rgb)) <= 1: + match rgb: + case (0,0,0): + return ANSI_BACK_BLACK if background else ANSI_NORMAL + ANSI_BLACK + case ((1|2), (1|2), (1|2)): + return ANSI_BACK_BLACK if background else ANSI_HILITE + ANSI_BLACK + case ((2|3), (2|3), (2|3)): + return ANSI_BACK_WHITE if background else ANSI_NORMAL + ANSI_WHITE + case ((3|4), (3|4), (3|4)): + return ANSI_BACK_WHITE if background else ANSI_NORMAL + ANSI_WHITE + case ((4|5), (4|5), (4|5)): + return ANSI_BACK_WHITE if background else ANSI_HILITE + ANSI_WHITE + + match tuple(_convert_for_ansi(c) for c in rgb): + # red + case ((2|3), (0|1), (0|1)): + return ANSI_BACK_RED if background else ANSI_HILITE + ANSI_RED + case ((1|2), 0, 0): + return ANSI_BACK_RED if background else ANSI_NORMAL + ANSI_RED + # green + case ((0|1), (2|3), (0|1)): + return ANSI_BACK_GREEN if background else ANSI_HILITE + ANSI_GREEN + case ((0 | 1), 1, 0) if green > red: + return ANSI_BACK_GREEN if background else ANSI_NORMAL + ANSI_GREEN + # blue + case ((0|1), (0|1), (2|3)): + return ANSI_BACK_BLUE if background else ANSI_HILITE + ANSI_BLUE + case (0, 0, 1): + return ANSI_BACK_BLUE if background else ANSI_NORMAL + ANSI_BLUE + # cyan + case ((0|1|2), (2|3), (2|3)) if red == min(rgb): + return ANSI_BACK_CYAN if background else ANSI_HILITE + ANSI_CYAN + case (0, (1|2), (1|2)): + return ANSI_BACK_CYAN if background else ANSI_NORMAL + ANSI_CYAN + # yellow + case ((2|3), (2|3), (0|1|2)) if blue == min(rgb): + return ANSI_BACK_YELLOW if background else ANSI_HILITE + ANSI_YELLOW + case ((2|1), (2|1), (0|1)): + return ANSI_BACK_YELLOW if background else ANSI_NORMAL + ANSI_YELLOW + # magenta + case ((2|3), (0|1|2), (2|3)) if green == min(rgb): + return ANSI_BACK_MAGENTA if background else ANSI_HILITE + ANSI_MAGENTA + case ((1|2), 0, (1|2)): + return ANSI_BACK_MAGENTA if background else ANSI_NORMAL + ANSI_MAGENTA + def strip_raw_codes(self, string): """