static class Dumper {
static public string Dump(Node root) { /* ... */
Worker dumper = new Worker();
dumper.Dump(root, "");
return dumper.ToString();
}
/// <summary>
/// Does the actual work; I like Dumper being a static class since all public methods in it are static
/// </summary>
private class Worker {
private const string VerticalIndent = "│ ";
private const string EmptyVerticalIndent = " ";
private const string ChildIndent = "├─";
private const string LastChildIndent = "└─";
private StringBuilder output = new StringBuilder();
private List<string> indentStack = new List<string>();
/// <summary>
/// Dumps the given node. The beforeRoot is printed before the root node's text.
/// </summary>
public void Dump(Node node, string beforeRoot) {
Indent();
output.Append(beforeRoot);
output.AppendLine(node.Text);
if (node.Children.Count > 0)
DumpChildren(node);
}
/// <summary>
/// Dumps the children of the node. Assumes that there are children, i.e. node.Children.Count > 0
/// </summary>
private void DumpChildren(Node node) {
indentStack.Push(VerticalIndent);
for (int i = 0; i < node.Children.Count - 1; i++) {
Dump(node.Children[i], ChildIndent);
}
indentStack.Pop();
indentStack.Push(EmptyVerticalIndent);
Dump(node.Children[node.Children.Count - 1], LastChildIndent);
indentStack.Pop();
}
/// <summary>
/// Indents properly. Prints the indentStack, except the last item.
/// </summary>
private void Indent() {
for (int i = 0; i < indentStack.Count - 1; i++) {
output.Append(indentStack[i]);
}
}
/// <summary>
/// Returns the string representation of the dump
/// </summary>
/// <returns></returns>
public override string ToString() {
return output.ToString();
}
}
}
/// <summary>
/// Allows us to treat a list as a stack, ordered from the first to last item.
/// Provides Push to add a last item and Pop to remove it.
/// </summary>
static class ListStackExtensions {
public static void Push<T>(this List<T> list, T item) {
list.Add(item);
}
// I didn't bother returning the removed item because I don't need it in this case
public static void Pop<T>(this List<T> list) {
list.RemoveAt(list.Count - 1);
}
}