private static void ColorizeEscapeSequences(
TextWriter output,
string message,
ColorPair startingColor,
ColorPair defaultColor)
{
var colorStack = new Stack<ColorPair>();
colorStack.Push(startingColor);
int p0 = 0;
while (p0 < message.Length)
{
int p1 = p0;
while (p1 < message.Length && message[p1] >= 32)
{
p1++;
}
// text
if (p1 != p0)
{
output.Write(message.Substring(p0, p1 - p0));
}
if (p1 >= message.Length)
{
p0 = p1;
break;
}
// control characters
char c1 = message[p1];
char c2 = (char)0;
if (p1 + 1 < message.Length)
{
c2 = message[p1 + 1];
}
if (c1 == '\a' && c2 == '\a')
{
output.Write('\a');
p0 = p1 + 2;
continue;
}
if (c1 == '\r' || c1 == '\n')
{
Console.ForegroundColor = defaultColor.ForegroundColor;
Console.BackgroundColor = defaultColor.BackgroundColor;
output.Write(c1);
Console.ForegroundColor = colorStack.Peek().ForegroundColor;
Console.BackgroundColor = colorStack.Peek().BackgroundColor;
p0 = p1 + 1;
continue;
}
if (c1 == '\a')
{
if (c2 == 'X')
{
colorStack.Pop();
Console.ForegroundColor = colorStack.Peek().ForegroundColor;
Console.BackgroundColor = colorStack.Peek().BackgroundColor;
p0 = p1 + 2;
continue;
}
var foreground = (ConsoleOutputColor)(c2 - 'A');
var background = (ConsoleOutputColor)(message[p1 + 2] - 'A');
if (foreground != ConsoleOutputColor.NoChange)
{
Console.ForegroundColor = (ConsoleColor)foreground;
}
if (background != ConsoleOutputColor.NoChange)
{
Console.BackgroundColor = (ConsoleColor)background;
}
colorStack.Push(new ColorPair(Console.ForegroundColor, Console.BackgroundColor));
p0 = p1 + 3;
continue;
}
output.Write(c1);
p0 = p1 + 1;
}
if (p0 < message.Length)
{
output.Write(message.Substring(p0));
}
}