import std.conv;
import std.stdio;
public struct Color
{
private enum Mode: bool
{
BASIC,
EXTENDED
}
private ubyte Data;
private Mode DataMode;
public this(const double Red, const double Green, const double Blue)
{
// Pack RGB values into 8 bits for xterm-256color.
Data += cast(ubyte)(Red * 5) * 36;
Data += cast(ubyte)(Green * 5) * 6;
Data += cast(ubyte)(Blue * 5);
Data += 16; // The first 16 values are for system colors.
DataMode = Mode.EXTENDED;
}
// Module-protected. Allows for special basic color support.
this(const ubyte Index)
{
Data = Index;
DataMode = Mode.BASIC;
}
/**
* Returns an ANSI escape code to make any following text
* the color represented by this object.
**/
@property string TextColorCode() const
{
// "ESC" would be replaced with the actual escape character.
// "ESC" is used here to more easily see what's going on.
if (DataMode == Mode.BASIC)
{
return "ESC[" ~ to!string(30 + Data) ~ "m";
}
else
{
return "ESC[38;5;" ~ to!string(Data) ~ "m";
}
}
}
public
{
immutable Color BLACK = Color(cast(ubyte)0);
immutable Color RED = Color(cast(ubyte)1);
immutable Color GREEN = Color(cast(ubyte)2);
immutable Color YELLOW = Color(cast(ubyte)3);
immutable Color BLUE = Color(cast(ubyte)4);
immutable Color MAGENTA = Color(cast(ubyte)5);
immutable Color CYAN = Color(cast(ubyte)6);
immutable Color WHITE = Color(cast(ubyte)7);
immutable Color DEFAULT = Color(cast(ubyte)9);
}
public void Output(const string Text, const Color TextColor = DEFAULT)
{
write(TextColor.TextColorCode);
write(Text);
write("ESC[0m");
}
void main()
{
Output("Hello, ");
Output("world!\n", BLUE);
Output("XTerm 256-color is supported.\n", Color(1.0, 1.0, 0.0));
}