/// <summary> /// Does the location represent whitespace? /// </summary> /// <param name="location"> /// The XML location. /// </param> /// <param name="whitespace"> /// Receives the <see cref="XSWhitespace"/> (if any) at the location. /// </param> /// <returns> /// <c>true</c>, if the location represents whitespace within element content; otherwise, <c>false</c>. /// </returns> public static bool IsWhitespace(this XmlLocation location, out XSWhitespace whitespace) { if (location == null) { throw new ArgumentNullException(nameof(location)); } if (location.IsWhitespace()) { whitespace = (XSWhitespace)location.Node; return(true); } whitespace = null; return(false); }
/// <summary> /// Find the spaces between elements and use that to infer whitespace. /// </summary> void ComputeWhitespace() { // TODO: Merge contiguous whitespace. var discoveredElements = DiscoveredNodes.OfType <XSElementWithContent>() .OrderBy(discoveredNode => discoveredNode.Range.Start) .ThenBy(discoveredNode => discoveredNode.Range.End); foreach (XSElementWithContent element in discoveredElements) { int startOfNextNode, endOfNode, whitespaceLength; XSWhitespace whitespace; endOfNode = element.ElementNode.StartTag.Span.End; for (int contentIndex = 0; contentIndex < element.Content.Count; contentIndex++) { if (element.Content[contentIndex] is XSElementText text) { startOfNextNode = _textPositions.GetAbsolutePosition(text.Range.Start); whitespaceLength = startOfNextNode - endOfNode; if (whitespaceLength > 0) { whitespace = new XSWhitespace( range: new Range( start: _textPositions.GetPosition(endOfNode), end: _textPositions.GetPosition(startOfNextNode) ), parent: element ); element.Content = element.Content.Insert(contentIndex, whitespace); DiscoveredNodes.Add(whitespace); } endOfNode = _textPositions.GetAbsolutePosition(text.Range.End); } if (element.Content[contentIndex] is XSElement childElement) { startOfNextNode = childElement.ElementNode.Span.Start; whitespaceLength = startOfNextNode - endOfNode; if (whitespaceLength > 0) { whitespace = new XSWhitespace( range: new Range( start: _textPositions.GetPosition(endOfNode), end: _textPositions.GetPosition(startOfNextNode) ), parent: element ); element.Content = element.Content.Insert(contentIndex, whitespace); DiscoveredNodes.Add(whitespace); } endOfNode = childElement.ElementNode.Span.End; } } // Any trailing whitespace before the closing tag? startOfNextNode = element.ElementNode.EndTag.Span.Start; whitespaceLength = startOfNextNode - endOfNode; if (whitespaceLength > 0) { whitespace = new XSWhitespace( range: new Range( start: _textPositions.GetPosition(endOfNode), end: _textPositions.GetPosition(startOfNextNode) ), parent: element ); element.Content = element.Content.Add(whitespace); DiscoveredNodes.Add(whitespace); } } }