/// <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 <Fold> GenerateFolds(IDocument document, string fileName, object parseInformation) { List <Fold> foldMarkers = new List <Fold>(); Stack stack = new Stack(); try { string xml = document.TextContent; XmlTextReader reader = new XmlTextReader(new StringReader(xml)); // Do not parse external references such as a DTD. reader.XmlResolver = null; 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. return(new List <Fold>(document.FoldingManager.Folds)); } 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> private static void CreateElementFold(IDocument document, List <Fold> foldMarkers, XmlTextReader reader, XmlFoldStart foldStart) { int endLine = reader.LineNumber - 1; if (endLine > foldStart.Line) { int endCol = reader.LinePosition + foldStart.Name.Length; Fold fold = new Fold(document, foldStart.Line, foldStart.Column, endLine, endCol, foldStart.FoldText); foldMarkers.Add(fold); } }
/// <summary> /// Create an element fold if the start and end tag are on /// different lines. /// </summary> private static void CreateElementFold(IDocument document, List<Fold> foldMarkers, XmlTextReader reader, XmlFoldStart foldStart) { int endLine = reader.LineNumber - 1; if (endLine > foldStart.Line) { int endCol = reader.LinePosition + foldStart.Name.Length; Fold fold = new Fold(document, foldStart.Line, foldStart.Column, endLine, endCol, foldStart.FoldText); foldMarkers.Add(fold); } }
/// <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; }