public string ToHTML(int Depth = -1, bool renderingOnNewLine = true) { // Normally we won't have closing tags in the final hierarchy, but just in case... if (IsClosingTag) { return(GetCloseTag()); } // Determine different factors that will weigh in on rendering int childCount = (Children == null ? 0 : Children.Count); bool onlyHasOneContentChild = ((childCount == 1) && (Children[0] is HTMLContent)); bool hasGrandchildren = false; if (childCount > 0) { foreach (DOMElement child in Children) { if (child is HTMLTag) { HTMLTag childTag = (HTMLTag)child; if (childTag.Children != null) { hasGrandchildren = true; break; } } } } // Normal render StringBuilder sb = new StringBuilder(); string indent = (renderingOnNewLine ? "".PadLeft((Depth < 0 ? 0 : Depth), '\t') : ""); bool childrenAreOnNewLine = ((hasGrandchildren) || (childCount > 1)); // Don't render fake elements like our DOM container if (Depth >= 0) { if (childrenAreOnNewLine) { sb.AppendLine(indent + GetOpenTag()); } else { sb.Append(indent + GetOpenTag()); } } if ((Children != null) && (Children.Count > 0)) { for (int i = 0; i < Children.Count; i++) { DOMElement child = Children[i]; if (child is HTMLTag) { // Child Tag if (childrenAreOnNewLine) { sb.AppendLine(((HTMLTag)child).ToHTML(Depth + 1, childrenAreOnNewLine)); } else { sb.Append(((HTMLTag)child).ToHTML(Depth + 1, childrenAreOnNewLine)); } } else { // Raw content if (childrenAreOnNewLine) { sb.Append(((HTMLContent)child).Value); // Line } else { sb.Append(((HTMLContent)child).Value); } } } } if ((Depth >= 0) && Closes) { sb.Append((childrenAreOnNewLine ? indent : "") + GetCloseTag()); } return(sb.ToString()); }