To be able to apply various colors to the console I created a ConosoleColorizer
. It's really simple. It just takes an XML and renders it to the console with the colors specified.
The element names are actually optional and can be any names. They are only required to parse the XML. What matters are the attribute and color names. I didn't know how to solve it with less effort without inventing a new markup.
internal class ConsoleColorizer
{
public static void Render(string xml)
{
Render(XElement.Parse(xml).Nodes());
}
public static void Render(IEnumerable<XNode> xNodes)
{
Render(xNodes, null, null);
}
private static void Render(IEnumerable<XNode> xNodes, ConsoleColor? lastForegroundColor, ConsoleColor? lastBackgroundColor)
{
foreach (var xChildNode in xNodes)
{
var xElement = xChildNode as XElement;
if (xElement != null)
{
Render(
xElement.Nodes(),
SetForegroundColor(xElement),
SetBackgroundColor(xElement)
);
}
else
{
RestoreForegroundColor(lastForegroundColor);
RestoreBackgroundColor(lastBackgroundColor);
Console.Write(((XText)xChildNode).Value);
}
}
Console.ResetColor();
}
private static ConsoleColor? SetForegroundColor(XElement xElement)
{
var foregroundColor = (ConsoleColor)0;
if (Enum.TryParse<ConsoleColor>(xElement.Attribute("fg")?.Value, true, out foregroundColor))
{
return Console.ForegroundColor = foregroundColor;
}
return null;
}
private static ConsoleColor? SetBackgroundColor(XElement xElement)
{
var backgroundColor = (ConsoleColor)0;
if (Enum.TryParse<ConsoleColor>(xElement.Attribute("bg")?.Value, true, out backgroundColor))
{
return Console.BackgroundColor = backgroundColor;
}
return null;
}
private static void RestoreForegroundColor(ConsoleColor? consoleColor)
{
if (consoleColor.HasValue)
{
Console.ForegroundColor = consoleColor.Value;
}
}
private static void RestoreBackgroundColor(ConsoleColor? consoleColor)
{
if (consoleColor.HasValue)
{
Console.BackgroundColor = consoleColor.Value;
}
}
}
Example:
var xml = @"<line>Hallo <color fg=""yellow"">colored</color> console! <color fg=""darkred"" bg=""darkgray"">These are <color fg=""white"" bg=""blue"">nested</color> colors</color>.</line>";
ConsoleColorizer.Render(xml);