/// <summary> /// Adds folds to the text editor around each start-end element pair. /// </summary> /// <remarks> /// <para>If the xml is not well formed then no folds are created.</para> /// <para>Note that the xml text reader lines and positions start /// from 1 and the SharpDevelop text editor line information starts /// from 0.</para> /// </remarks> public List <FoldMarker> GenerateFoldMarkers(IDocument document, string fileName, object parseInformation) { showAttributesWhenFolded = true; List <FoldMarker> foldMarkers = new List <FoldMarker>(); Stack stack = new Stack(); try { string xml = document.TextContent; XmlTextReader reader = new XmlTextReader(new StringReader(xml)); while (reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: if (!reader.IsEmptyElement) { XmlFoldStart newFoldStart = CreateElementFoldStart(reader); stack.Push(newFoldStart); } break; case XmlNodeType.EndElement: XmlFoldStart foldStart = (XmlFoldStart)stack.Pop(); CreateElementFold(document, foldMarkers, reader, foldStart); break; case XmlNodeType.Comment: CreateCommentFold(document, foldMarkers, reader); break; } } } catch (Exception) { // If the xml is not well formed keep the foldings // that already exist in the document. List <FoldMarker> markers = new List <FoldMarker>(); foreach (FoldMarker foldmarker in document.FoldingManager.FoldMarker) { markers.Add(foldmarker); } return(markers); } return(foldMarkers); }
/// <summary> /// Creates an XmlFoldStart for the start tag of an element. /// </summary> XmlFoldStart CreateElementFoldStart(XmlTextReader reader) { // Take off 2 from the line position returned // from the xml since it points to the start // of the element name and not the beginning // tag. XmlFoldStart newFoldStart = new XmlFoldStart(reader.Prefix, reader.LocalName, reader.LineNumber - 1, reader.LinePosition - 2); if (showAttributesWhenFolded && reader.HasAttributes) { newFoldStart.FoldText = String.Concat("<", newFoldStart.Name, " ", GetAttributeFoldText(reader), ">"); } else { newFoldStart.FoldText = String.Concat("<", newFoldStart.Name, ">"); } return(newFoldStart); }
/// <summary> /// Create an element fold if the start and end tag are on /// different lines. /// </summary> void CreateElementFold(IDocument document, List <FoldMarker> foldMarkers, XmlTextReader reader, XmlFoldStart foldStart) { int endLine = reader.LineNumber - 1; if (endLine > foldStart.Line) { int endCol = reader.LinePosition + foldStart.Name.Length; FoldMarker foldMarker = new FoldMarker(document, foldStart.Line, foldStart.Column, endLine, endCol, FoldType.TypeBody, foldStart.FoldText); foldMarkers.Add(foldMarker); } }