SGR (Select Graphic Rendition) colour and text-style attributes, both ways.
SGR is the m-terminated CSI sequence that carries colour and text-style
information (ESC [ 1 ; 31 m = bold red, for example). parse/1 turns the raw
parameter binary into a list of structured attributes; encode/1 turns a list
of attributes back into a sequence ready to write — including 256-colour and
truecolor, which IO.ANSI does not cover.
parse/1 is used internally by Vtex.Input; both functions are useful
standalone.
Attribute types
:reset
:bold | :faint | :italic | :underline | :blink | :inverse
{:fg, color()}
{:bg, color()}
{:unknown, integer()} # a recognised-as-numeric but unmapped codewhere color() is one of:
:black | :red | :green | :yellow | :blue | :magenta | :cyan | :white
{:bright, basic_color()} # codes 90-97 / 100-107
{:index, 0..255} # 256-colour palette (38;5;n / 48;5;n)
{:rgb, 0..255, 0..255, 0..255} # truecolor (38;2;r;g;b / 48;2;r;g;b)
Summary
Functions
Encode a list of attributes into an SGR control sequence (ESC [ … m).
Parse an SGR parameter binary into a list of attributes.
Types
@type basic_color() ::
:black | :red | :green | :yellow | :blue | :magenta | :cyan | :white
@type color() :: basic_color() | {:bright, basic_color()} | {:index, 0..255} | {:rgb, 0..255, 0..255, 0..255}
Functions
Encode a list of attributes into an SGR control sequence (ESC [ … m).
The inverse of parse/1: it accepts the same attribute terms — including
256-colour ({:index, n}) and truecolor ({:rgb, r, g, b}) selectors that
IO.ANSI does not cover. Write the result to the terminal.
Examples
iex> Vtex.SGR.encode([:bold, {:fg, :red}])
"\e[1;31m"
iex> Vtex.SGR.encode([{:fg, {:rgb, 10, 20, 30}}, {:bg, {:index, 200}}])
"\e[38;2;10;20;30;48;5;200m"
iex> Vtex.SGR.encode([:reset])
"\e[0m"
Parse an SGR parameter binary into a list of attributes.
An empty parameter string is treated as :reset (a bare ESC [ m), matching
terminal behaviour. Non-numeric parameters are ignored.
Examples
iex> Vtex.SGR.parse("0")
[:reset]
iex> Vtex.SGR.parse("")
[:reset]
iex> Vtex.SGR.parse("1;31")
[:bold, {:fg, :red}]
iex> Vtex.SGR.parse("38;5;200")
[{:fg, {:index, 200}}]
iex> Vtex.SGR.parse("48;2;10;20;30")
[{:bg, {:rgb, 10, 20, 30}}]