ANSITerm is available on Nuget as Tamar.ANSITerm
.
This package doesn't require any additional dependencies.
ANSITerm.Console
re-implements the System.Console
class so properties like Console.ForegroundColor
would rather take values from the Color
struct with 24-bit RGB colors than the basic 16 ConsoleColor
s, and adapt these colors to the limitations of the given terminal emulator using ANSI escape codes.
- Automatic detection and use of:
- XTerm sequences for italic, bold, underlined, blink, rapid-blink,reverse color, and faint text formatting styles[inconsistent support].
- Automatic conversion to the nearest 4-bit or 8-bit colors when the terminal does not support 24-bit true color. The algorithm is quite fast and it calculates via the RGB values and keeps a cache dictionary.
- Turn on/off features or ignore their terminal support through imperative commands within your code.
Write
/WriteLine
/ReadLine
method overloads with foreground and background color parameters to appease the usual code bloat with imperative console formatting.
If support for ANSI escape codes is uncertain, then ANSITerm will virtually take no effect and skip all escape-code-depended formatting, except for colors which will be converted to the nearest 4-bit color and passed as .NET's default System.ConsoleColor
.
Escape codes support is determined by the TERM
environment variable. ANSITerm tries to search for known terminal types such as xterm
, linux
and vt100
to ensure escape code support.
8-bit color support is determined by the TERM
environment variable for values that include 256color
in them, such as xterm-256color
.
24-bit color support is determined by COLORTERM
environment variable, which is usually set to truecolor
by the terminal emulator in question.
XTerm formatting support (including style formatting) is determined by escape code support alone.
If you are certain that you managed to identify your terminal within your code however ANSITerm has failed to detect your terminal, then you may instruct ANSITerm to ignore its own terminal support and enable escape codes anyway by setting the Feature.IgnoreSupport
property to true
in Console.Config
.
Use this with caution. If you haven't identified the terminal properly then the user may see escape characters printed all over the buffer and this will render your application unusable on certain terminals that do not support ANSI escape codes to their full extent as you may have expected.
Turn IgnoreSupport
only if you're 100% certain that you've managed to detect a terminal that supports the features you need but ANSITerm fails to detect them automatically. It's also a good idea to allow the user to turn on or off this behavior via external configuration.
If the current terminal supports 24-bit colors, then ANSITerm will use SGR sequences[what is SGR?] for RGB colors[alpha emitted] without performing any conversions to the nearest 8-bit/4-bit color.
If ANSITerm can't determine support for 24-bit colors in the current terminal, then it will resort to ANSI's standard 8-bit 256 colors palette with nearest-color conversions.
If ANSITerm can't determine support for 8-bit colors, but escape codes are supported, then it will resort to XTerm's base 4-bit 16 colors with bright and dark variants with nearest-color conversions.
If escape codes are not supported at all, then it will resort to .NET's basic system colors by utilizing the well known ConsoleColor
enum and nearest-color conversions.
I've tested CMD's escape code support on both Visual Studio and Rider and experienced different results, thus ANSITerm won't support escape codes on the Windows CMD by default. Windows Terminal is in ANSITerm's todo list.
ANSITerm.Console
's use is fairly similar to .NET's standard System.Console
use. A using
alias directive should be declared at each source file that makes use of ANSITerm.Console
in order to prevent confusion between the standard base class and ANSITerm
's class.
using Console = Tamar.ANSITerm.Console;
Multiple formatting ANSI sequences can be applied simultaneously over the current state, and ANSITerm will run an SGR sequence[what is SGR?] update every time the formatting is being changed by color or by style (as long as the terminal is able to support escape codes).
Consider using the method overloads for Write
, WriteLine
, and ReadLine
that include foreground and background parameters as shown below. They don't interfere with ForegroundColor
or BackgroundColor
and will revert back once they done printing.
Console.WriteLine("Red text over white background.", Color.Red, Color.White);
Console.WriteLine("Normal text");
Console.ReadLine(Color.DarkTeal); // The user's input is shown in dark teal as they type, and reverts back to the previous colors when they're done.
Toggle XTerm formatting styles (such as italic/bold/underline) the same way you would set colors.
Console.Italic = true;
Console.WriteLine("Italic text");
Console.Bold = true;
Console.WriteLine("Italic & bold text");
Console.Italic = false;
Console.WriteLine("Bold text");
Console.ResetStyle();
Console.WriteLine("Normal text");
Console.ForegroundColor = Color.MediumPurple;
Console.BackgroundColor = Color.MidnightBlue;
Console.WriteLine("Light purple text over dark blue background.")
Console.ResetColor();
You may enable or disable certain formatting features at runtime as shown in the following example.
Console.Config.EscapeCodes.Enable();
Console.Config.Colors8Bit.Enable();
Console.Config.Colors24Bit.Enable();
Console.WriteLine("Printed with 24-bit colors");
PrintColors();
Console.Config.Colors24Bit.Disable();
Console.WriteLine("Printed with 8-bit colors");
PrintColors();
Console.Config.Colors8Bit.Disable();
Console.WriteLine("Printed with 4-bit (16 colors) XTerm palette (using escape codes)");
PrintColors();
Console.Config.EscapeCodes.Disable();
Console.WriteLine("Printed with 4-bit (16 colors) System.ConsoleColor (no escape codes)");
PrintColors();
Console.Config.EscapeCodes.Enable();
Console.Config.Colors8Bit.Enable();
Console.Config.Colors24Bit.Enable();
ANSITerm is fully backwards-compatible. Since version 0.1.4 a number of changes were done to the public API, however the obsolete API is still there and re-routes everything to the new API to make sure that old properties and functions are still working as they worked before.
You can read more details about why, where they moved, or what happened to each deprecated member within the XML documentation in ANSITerm.Console
attached to each deprecated member.
Inconsistent support for XTerm styles: Not all terminals support XTerm's text formatting to full extent. ANSITerm doesn't have any mechanism to detect proper support of text formatting beyond basic support for ANSI escape codes in general.
What is SGR?: The term “SGR” stands for “Select Graphic Rendition” as specified by ECMA. This sequence is responsible for all graphical changes on the buffer, including color and text formatting. You can find more details about SGR in the ECMA-48 specification paper.
Alpha is emitted from RGB colors:
The transparency component of A-RGB colors is ignored for SGR sequences, however fully transparent colors (i.e. Color.Transparent
indicates the default (no color) for both: foreground and background settings. Console.ResetColor
will set both of them to Color.Transparent
. Every time the SGR sequence will be updated, transparent colors will be ignored and skipped thus resulting in the default colors as set by the terminal emulator.
ANSI's palette:
ANSI's palette includes 256 colors in total. The first 16 colors correspond to the well known bright/dark shades of the 4-bit system colors as presented by System.ConsoleColor
. The last 24 colors are gray-scale only, and the 216 colors in between (6*6*6) are non-gray-scale. Some colors have duplicates. When performing nearest-color conversion, ANSITerm will consider the entire spectrum, including the gray-scale for non-gray-scale colors and vice-versa.
XTerm's palette:
This palette includes 16 colors in total and is equivalent to System.ConsoleColor
's palette. There are 8 pigments with 2 shades each - bright and dark. The SGR byte values for XTerm's palette are separated in different ranges for foreground and background colors by bright and dark shades. In some terminals the bold sequence turns on the bright shade for the current foreground color, however this behavior doesn't follow the specification as required.
ANSITerm is under MIT License, © 2019-2020 David von Tamar.
See LICENSE for details.