Skip to content

Commit

Permalink
Update Parser.cs
Browse files Browse the repository at this point in the history
  • Loading branch information
Peled-Zohar authored Nov 5, 2019
1 parent 7dde9fc commit 1771bd3
Showing 1 changed file with 55 additions and 26 deletions.
81 changes: 55 additions & 26 deletions ExtendedConsole/Parser.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
using System;
using System;
using System.Xml.Linq;
using System.Linq;

namespace ExtendedConsole
{
internal static class Parser
{
/// <summary>
/// Parse markup and returns an instance of the TextBuilder class,
/// containing actions to write the text to the Console.
/// </summary>
/// <param name="markup">A string containing the markup to write to Console.</param>
/// <returns>An instance of the TextBuilder class ready to write the text to the Console.</returns>
internal static TextBuilder ParseMarkeup(string markup)
{
var textBuilder = new TextBuilder();
Expand All @@ -18,8 +25,18 @@ internal static TextBuilder ParseMarkeup(string markup)
return textBuilder;
}

/// <summary>
/// Recursively parses XML nodes in the markup.
/// </summary>
/// <param name="textBuilder">The instance of TextBuilder to hold the parsed information.</param>
/// <param name="node">The current XML node to parse.</param>
private static void ParseNode(TextBuilder textBuilder, XNode node)
{
if (node is null)
{
return;
}

var element = node as XElement;
if (element is null)
{
Expand All @@ -30,35 +47,26 @@ private static void ParseNode(TextBuilder textBuilder, XNode node)
ParseElement(textBuilder, element);
}

if (node.NextNode != null)
{
ParseNode(textBuilder, node.NextNode);
}
ParseNode(textBuilder, node.NextNode);

}

/// <summary>
/// Parse an XML element into the text builder.
/// If the element has children, Pass them to the ParseNode method.
/// </summary>
/// <param name="textBuilder">The instance of TextBuilder to hold the parsed information.</param>
/// <param name="element">The current XML element to parse.</param>
private static void ParseElement(TextBuilder textBuilder, XElement element)
{
ConsoleColor? foregroundColor = null, backgroundColor = null;
var isColorElement = element.Name.LocalName == "c";
var isColorElement = element.Name.LocalName == "c" &&
element.Attributes().Any(a => a.Name == "f" || a.Name == "b");

if (isColorElement)
{
var foreground = element.Attribute("f");
if (foreground != null)
{
if (Enum.TryParse(foreground.Value, true, out ConsoleColor color))
{
foregroundColor = textBuilder.SetForegroundColor(color);
}
}

var background = element.Attribute("b");
if (background != null)
{
if (Enum.TryParse(background.Value, true, out ConsoleColor color))
{
backgroundColor = textBuilder.SetBackgroundColor(color);
}
}
SetColor(ref foregroundColor, "f", textBuilder.SetForegroundColor);
SetColor(ref backgroundColor, "b", textBuilder.SetBackgroundColor);
}
else
{
Expand All @@ -79,11 +87,26 @@ private static void ParseElement(TextBuilder textBuilder, XElement element)
{
textBuilder.AddText($"</{element.Name}>");
}

void SetColor(ref ConsoleColor? color, string attributeName, Func<ConsoleColor, ConsoleColor?> setColor)
{
var attribute = element.Attribute(attributeName);
if (attribute != null &&
Enum.TryParse(attribute.Value, true, out ConsoleColor newColor))
{
color = setColor(newColor);
}
}
}

/// <summary>
/// Adds the XML element to the TextBuilder.
/// </summary>
/// <param name="textBuilder">The instance of TextBuilder to hold the parsed information.</param>
/// <param name="element">The current XML element to add to the TextBuilder.</param>
private static void WriteElement(TextBuilder textBuilder, XElement element)
{

textBuilder.AddText($"<{element.Name}");
if (element.HasAttributes)
{
Expand All @@ -96,12 +119,18 @@ private static void WriteElement(TextBuilder textBuilder, XElement element)
textBuilder.AddText(">");
}

/// <summary>
/// Adds the attributes of an XML element to the TextBuilder.
/// </summary>
/// <param name="textBuilder">The instance of TextBuilder to hold the parsed information.</param>
/// <param name="attribute">The current attribute to add to the TextBuilder.</param>
private static void WriteAttributes(TextBuilder textBuilder, XAttribute attribute)
{
textBuilder.AddText($" {attribute}");
if (attribute.NextAttribute != null)
var nextAttribute = attribute.NextAttribute;
if (nextAttribute != null)
{
WriteAttributes(textBuilder, attribute.NextAttribute);
WriteAttributes(textBuilder, nextAttribute);
}
}
}
Expand Down

0 comments on commit 1771bd3

Please sign in to comment.