4

The rich project allows to specify console markup, including text color. However it seems that any color choices need to be hardcoded, e.g. using red for important messages:

from rich import print

print('[red bold]This is a very important notification[/]')

This looks good on a terminal with light background color (e.g. Solarized light):

red on light background

However when the user has a dark background color, it makes it difficult to read (e.g. Solarized dark):

red on dark background

As the developer of a command line application using rich, however, I cannot assume any background color for the users' terminals and hence hardcoding specific colors doesn't seem like a good idea (I don't want to modify the background color either, since the user probably chose it for a good reason). So I was wondering whether rich offers background-aware color choices (e.g. via themes, so I could just specify something like category='important')?

a_guest
  • 34,165
  • 12
  • 64
  • 118
  • Would it work to use a specified background colour just for that text span? How about detecting the terminal's background colour and implementing your own logic on top of that? – Karl Knechtel Sep 27 '21 at 20:10
  • @KarlKnechtel Both solutions would work, but I'd prefer to choose a different text color if the background color of the terminal has a low contrast w.r.t. red. Do you know if it's possible to detect the terminal's background color via `rich` (or some other reliable method)? – a_guest Sep 28 '21 at 10:07

2 Answers2

2

Detecting terminal color schemes

Depending on your terminal the color-settings are stored in config-files. Usually those have a plain/text format, e.g. rc-files on Linux systems.

For example in XFCE you can discover the current 16 base-colors, including background color and bold style by reading the terminalrc file:

cat ~/.config/xfce4/terminal/terminalrc | egrep 'ColorPalette|ColorBackground|ColorBold'
ColorBackground=#131926
ColorPalette=#000000;#aa0000;#44aa44;#aa5500;#0039aa;#aa22aa;#1a92aa;#aaaaaa;#777777;#ff8787;#4ce64c;#ded82c;#295fcc;#cc58cc;#4ccce6;#ffffff
ColorBold=#ffffff
ColorBoldUseDefault=FALSE

See themes - Change color scheme for xfce4 terminal manually - Ask Ubuntu.

Increasing contrast by applying foreground and background colors together

What about choosing a black or white background color along with your red text:

from rich import print

# bold font may also be rendered depending on terminal's predefined style and color
print('[bold]This is just bold, which can be rendered as different color depending on terminal\'s color-scheme[/]')
# only foreground may suffer readability, e.g. when transparent background
print('[red bold]This is a very important notification[/]')
# use foreground on background to achieve high contrast
print('[red bold on black] on black[/]')
print('[red bold on white] on white[/]')

Even within a transparent terminal window the background color can improve contrast and readability: better contrast with 'foreground on background'

Benefit:

This will make your TUI independent from terminal's color-schemes and ensures some kind of brand-identity to your application. Then the color-choice is consistently across all systems and terminals and the user can recognize your application by its unique colors.

See Set different background color using Rich.

Using configurable themes

Like answered by Will McGugan (the creator of Rich) you can leverage themes to let the user control colors. This follows the customization approach used in modern terminals and allows the user to align both color-themes (e.g. to have the same theme in terminal and app).

See the 16 base-colors and also bold-style color of the Solarized theme.

hc_dev
  • 8,389
  • 1
  • 26
  • 38
1

The first 16 colors in the terminal (which includes red) are defined by the terminal software, and are generally chosen to work well together. For instance here is red on black within iTerm on MacOS.

Example of red on black in the terminal

Red on black will be perfectly readable on virtually all terminals. A notable exception would be the classic Windows terminal (which I'm guessing you are using) which has some very poorly thought out color palettes.

Regarding hard coded colors, you can create themed aliases via themes so you can use "[important] message" rather than "[bold red] message"

Will McGugan
  • 2,005
  • 13
  • 10
  • I'm using Ubuntu 20.04 with GNOME 3.36. The screenshots I included show the standard terminal application with either [Solarized light or dark](https://ethanschoonover.com/solarized/) color profile (which is a popular choice, I assume). The terminal application provides other themes, such as "Tango dark" (gray background) where it's difficult to read too. I agree that red on black is fine though. Is there an option to detect the terminal's background color via `rich`, so I could choose another text color when the background is neither light nor black? – a_guest Sep 28 '21 at 09:59
  • I'm afraid there is no reliable way programmatically detect the terminal color scheme. You have to rely on the user picking a theme with good contrast. Bear in mind the gamma, contrast, brightness settings of your monitor will have a big impact on legibility. The screenshots in the link all look clear to me. – Will McGugan Sep 28 '21 at 11:00