/// <summary> /// Collapses a whitespace /// </summary> /// <param name="value">String value</param> /// <returns>String value without extra spaces</returns> internal static string CollapseWhitespace(string value) { if (value == null) { throw new ArgumentNullException("value"); } if (value.Length == 0 || (value.IndexOfAny(_otherWhitespaceChars) == -1 && value.IndexOf(" ", StringComparison.Ordinal) == -1)) { return(value); } StringBuilder sb = null; bool previousWhitespace = false; int previousCharIndex = 0; int charCount = value.Length; for (int charIndex = 0; charIndex < charCount; charIndex++) { char charValue = value[charIndex]; bool currentWhitespace = charValue.IsWhitespace(); if (currentWhitespace) { if (previousWhitespace || charValue != ' ') { if (sb == null) { sb = StringBuilderPool.GetBuilder(); } if (previousCharIndex < charIndex) { sb.Append(value, previousCharIndex, charIndex - previousCharIndex); } if (!previousWhitespace) { sb.Append(' '); } previousCharIndex = charIndex + 1; } } previousWhitespace = currentWhitespace; } if (sb == null) { return(value); } if (previousCharIndex < charCount) { sb.Append(value, previousCharIndex, charCount - previousCharIndex); } string result = sb.ToString(); StringBuilderPool.ReleaseBuilder(sb); return(result); }
/// <summary> /// Gets a source fragment /// </summary> /// <param name="sourceCode">Source code</param> /// <param name="nodeCoordinates">Node coordinates</param> /// <param name="tabSize">Number of spaces in the tab</param> /// <param name="maxFragmentLength">Maximum length of the source fragment</param> /// <returns>Source fragment</returns> public static string GetSourceFragment(string sourceCode, SourceCodeNodeCoordinates nodeCoordinates, byte tabSize = DEFAULT_TAB_SIZE, int maxFragmentLength = DEFAULT_MAX_FRAGMENT_LENGTH) { string sourceFragment = string.Empty; int lineNumber = nodeCoordinates.LineNumber; int columnNumber = nodeCoordinates.ColumnNumber; if (!string.IsNullOrEmpty(sourceCode)) { int previousLineNumber = lineNumber - 1; int currentLineNumber = lineNumber; int nextLineNumber = lineNumber + 1; string previousLine = string.Empty; string currentLine = string.Empty; string nextLine = string.Empty; int lineCount = 0; int lineBreakPosition = int.MinValue; int lineBreakLength = 0; do { string line; int startLinePosition = lineBreakPosition == int.MinValue ? 0 : lineBreakPosition + lineBreakLength; FindNextLineBreak(sourceCode, startLinePosition, out lineBreakPosition, out lineBreakLength); if (lineBreakPosition != -1) { line = sourceCode.Substring(startLinePosition, lineBreakPosition - startLinePosition); } else { line = sourceCode.Substring(startLinePosition); } lineCount++; if (lineCount == previousLineNumber) { previousLine = line; } else if (lineCount == currentLineNumber) { currentLine = line; } else if (lineCount == nextLineNumber) { nextLine = line; } }while (lineBreakPosition != -1 && lineCount <= nextLineNumber); int lineNumberSize = nextLineNumber.ToString(CultureInfo.InvariantCulture).Length; if (currentLineNumber == lineCount) { lineNumberSize = currentLineNumber.ToString(CultureInfo.InvariantCulture).Length; } int fragmentStartPosition; int fragmentLength; CalculateCutPositions(currentLine, columnNumber, maxFragmentLength, out fragmentStartPosition, out fragmentLength); StringBuilder sourceFragmentBuilder = StringBuilderPool.GetBuilder(); if (currentLine.Length > 0) { if (previousLine.Length > 0) { sourceFragmentBuilder.AppendLine(FormatSourceCodeLine(previousLine, new SourceCodeNodeCoordinates(previousLineNumber, 0), lineNumberSize, fragmentStartPosition, fragmentLength, tabSize)); } sourceFragmentBuilder.AppendLine(FormatSourceCodeLine(currentLine, new SourceCodeNodeCoordinates(currentLineNumber, columnNumber), lineNumberSize, fragmentStartPosition, fragmentLength, tabSize)); if (nextLine.Length > 0) { sourceFragmentBuilder.AppendLine(FormatSourceCodeLine(nextLine, new SourceCodeNodeCoordinates(nextLineNumber, 0), lineNumberSize, fragmentStartPosition, fragmentLength, tabSize)); } } sourceFragment = sourceFragmentBuilder.ToString(); StringBuilderPool.ReleaseBuilder(sourceFragmentBuilder); } return(sourceFragment); }