0

I would like to use rgb(a) hex codes to display colors on the terminal. I intend to make some kind of program that can render colors inside brackets, like: [#FFFFFF]this is white text

5
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking.
    – Community Bot
    Apr 1, 2022 at 3:58
  • shellhacks.com/bash-colors Apr 1, 2022 at 4:28
  • thanks, but the shellhacks thing doesnt support hexes Apr 1, 2022 at 5:36
  • i found a program called pastel that seems to work. Apr 1, 2022 at 6:07
  • yes, you will need an external program, because the bash does not support hex code text coloring by itself. Apr 2, 2022 at 2:39

1 Answer 1

0

You don't need a dedicated external program to display colors in your terminal. If the terminal supports colors then it will react to specific control sequences that are nothing more than sequences of bytes embedded in the very same stream that carries text to be printed. You can print such sequences with echo or (better) with printf or with anything that can print arbitrary data.

Many online resources cover a widely spread palette of 8 colors plus 8 bright counterparts (example). Modern terminal emulators additionally support 24-bit color; this is what you need. I assume your terminal emulator is modern enough.

The sequences are:

  • ESC[38;2;⟨r⟩;⟨g⟩;⟨b⟩m to set RGB foreground color
  • ESC[48;2;⟨r⟩;⟨g⟩;⟨b⟩m to set RGB background color

where ESC denotes the escape character (a byte with decimal value 27, octal 33, hexadecimal 1B), ⟨r⟩, ⟨g⟩ and ⟨b⟩ are respectively red, green and blue 8-bit components written in decimal using ASCII digits (so the range is 0..255). The standard sequence ESC[0m or ESC[m can be used to reset the colors (and more in general) to whatever your terminal considers the default.

The escape character (ESC above) can be denoted as \033 (octal), \0x1B or \x1b (hexadecimal), \e, ^[ or in yet another way. Various tools support various subsets of these.

An example of how to print a colored text with printf from a shell:

printf '\e[38;2;240;100;200m\e[48;2;200;255;50mHello World!\e[0m\n'
#          fg   RRR GGG BBB    bg   RRR GGG BB             reset

You want to provide foreground color as a string in a format like [#FFFFFF]. If the relevant escape sequence used hexadecimal numbers, it would be relatively easy to convert your desired format to a working escape sequence (e.g. with sed). Unfortunately the sequence must use decimal representation of RGB components.

What you can do easily is to use %d of printf to convert hexadecimal to decimal. It will look like this:

printf '\e[38;2;%d;%d;%dm%s\e[0m\n' 0x00 0xA0 0xFF 'Hello World!'

These 0x00 0xA0 0xFF need to be separate arguments. It takes some work to get to them from the form of [#00A0FF], but it is possible. If your goal is to parse strings in the form of [#FFFFFF]this is white text, where [#…] is always at the beginning, then it can be done just by manipulating strings in a POSIX shell (mainly with these). An example shell function:

colprint() (
   text="${1#'[#'??????']'}"
   r="${1%"$text"}"
   r="${r%']'}"
   r="${r#'[#'}"
   r="${r:-FFFFFF}"
   b="${r#????}"
   r="${r%??}"
   g="${r#??}"
   r="${r%??}"
   printf '\e[38;2;%d;%d;%dm%s\e[0m\n' "0x$r" "0x$g" "0x$b" "$text"
)

And then:

colprint '[#FFFFFF]this is white text'
colprint '[#FF0000]this is red text'
colprint '[#BFFF00]this is lime text'
colprint 'white again (default)'

If you want to detect [#…] anywhere in a line and substitute it with a proper escape sequence then a more powerful tool is advised. If not the conversion from hexadecimal to decimal, sed would do well. Because of the conversion I think you need something more like awk. Anyway in principle this seems possible with standard tools. As you "intend to make some kind of program", I won't take this joy away from you by publishing a working example. :) Now you know what to print to the terminal. Good luck!

Note a dedicated external program to display colors may go beyond generating escape sequences straightforwardly, like our colprint function does. First it may check $TERM and $COLORTERM to learn if the terminal really supports colors and how many of them; then it may pick sequences that actually work. E.g. if it discovers the terminal does not support 24-bit color, it may translate the color you want to the closest color of the supported palette.

2
  • I indeed do want to detect [#...] anywhere in a line, and, actually, I managed to do it! Thank you for the rgb escape code tip. Apr 6, 2022 at 22:41
  • All i had to do was go through the string, put all the [...] things into a array, and everything else in a different array, then iterate through the array, adding colors where appropriate. Apr 6, 2022 at 22:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .