private void ReplaceContent(NodeCollection nodes, Node target, string content, string raw) { if (nodes == null || target == null) { throw new ArgumentNullException(); } Node[] nn = CreateContent(content, raw); foreach (Node n in nn) { nodes.InsertBefore(target, n); } nodes.Remove(target); }
/// <summary> /// Balances out the stream of nodes to form a valid tree. /// This process will always try to resolve conflicts by introducing extra inline elements over block elements. /// </summary> public void Balance(NodeCollection nodes) { if (nodes == null) { throw new ArgumentNullException(); } // Fill in missing elements List <string> nameStack = new List <string>(); nodes.Reset(); Node node = null; while ((node = nodes.Next()) != null) { switch (node.Type) { case NodeType.Open: OpenNode openNode = (OpenNode)node; if (openNode.Closed) { continue; } nameStack.Insert(0, openNode.Name); break; case NodeType.Close: CloseNode closeNode = (CloseNode)node; if (!nameStack.Contains(closeNode.Name)) { // Found CloseNode without OpenNode // Fix by insert an OpenNode before it nodes.InsertBefore( closeNode, new OpenNode(closeNode.Name, "", false)); } nameStack.Remove(closeNode.Name); break; } } while (nameStack.Count > 0) { // Found OpenNode without CloseNode // Fix by adding a CloseNode at the end of the stream string name = nameStack[0]; nameStack.RemoveAt(0); nodes.Add(new CloseNode(name, "")); } // Resolve tree structure List <OpenNode> nodeStack = new List <OpenNode>(); nodes.Reset(); while ((node = nodes.Next()) != null) { switch (node.Type) { case NodeType.Open: OpenNode on = (OpenNode)node; if (on.Closed) { continue; } nodeStack.Insert(0, on); break; case NodeType.Close: // A bit of setup CloseNode closeNode = (CloseNode)node; bool block = blockElements.Contains(closeNode.Name); // Find matching OpenNode OpenNode openNode = null; foreach (OpenNode o in nodeStack) { if (o.Name == closeNode.Name) { openNode = o; break; } } if (openNode == null) { throw new InvalidOperationException("Unable to find matching OpenNode to CloseNode"); } // Handle incorrect balance int offset = 0; while (nodeStack[offset].Name != closeNode.Name) { OpenNode n = nodeStack[offset]; if (block) { nodes.InsertBefore(node, new CloseNode(n.Name, "")); nodes.InsertAfter(node, n.Clone()); nodeStack.RemoveAt(offset); offset--; } else { nodes.InsertBefore(n, closeNode.Clone()); nodes.InsertAfter(n, openNode.Clone()); } offset++; } // All fixed nodeStack.RemoveAt(offset); break; } } // And we're done! nodes.Reset(); }