private static StringCollection GenerateLinesWithoutWordWrap(DisplayCells displayCells, string val, int firstLineLen, int followingLinesLen) { StringCollection retVal = new StringCollection(); if (string.IsNullOrEmpty(val)) { // if null or empty, just add and we are done retVal.Add(val); return(retVal); } // break string on newlines and process each line separately string[] lines = SplitLines(val); for (int k = 0; k < lines.Length; k++) { string currentLine = lines[k]; if (currentLine == null || displayCells.Length(currentLine) <= firstLineLen) { // we do not need to split further, just add retVal.Add(currentLine); continue; } // the string does not fit, so we have to wrap around on multiple lines // for each of these lines in the string, the first line will have // a (potentially) different length (indentation or hanging) // for each line, start a new state SplitLinesAccumulator accumulator = new SplitLinesAccumulator(retVal, firstLineLen, followingLinesLen); int offset = 0; // offset into the line we are splitting while (offset < currentLine.Length) { // acquire the current active display line length (it can very from call to call) int currentDisplayLen = accumulator.ActiveLen; // determine if the current tail would fit or not // for the remaining part of the string, determine its display cell count int currentCellsToFit = displayCells.Length(currentLine, offset); // determine if we fit into the line int excessCells = currentCellsToFit - currentDisplayLen; if (excessCells > 0) { // we are not at the end of the string, select a sub string // that would fit in the remaining display length int charactersToAdd = displayCells.TruncateTail(currentLine, offset, currentDisplayLen); if (charactersToAdd <= 0) { // corner case: we have a two cell character and the current // display length is one. // add a single cell arbitrary character instead of the original // one and keep going charactersToAdd = 1; accumulator.AddLine("?"); } else { // of the given length, add it to the accumulator accumulator.AddLine(currentLine.VtSubstring(offset, charactersToAdd)); } // increase the offset by the # of characters added offset += charactersToAdd; } else { // we reached the last (partial) line, we add it all accumulator.AddLine(currentLine.VtSubstring(offset)); break; } } } return(retVal); }
private static string GenerateRowField(string val, int width, int alignment, DisplayCells dc, bool addPadding) { // make sure the string does not have any embedded <CR> in it string s = StringManipulationHelper.TruncateAtNewLine(val); int currentValueDisplayLength = dc.Length(s); if (currentValueDisplayLength < width) { // the string is shorter than the width of the column // need to pad with with blanks to reach the desired width int padCount = width - currentValueDisplayLength; switch (alignment) { case TextAlignment.Right: { s = StringUtil.Padding(padCount) + s; } break; case TextAlignment.Center: { // add a bit at both ends of the string int padLeft = padCount / 2; int padRight = padCount - padLeft; s = StringUtil.Padding(padLeft) + s; if (addPadding) { s += StringUtil.Padding(padRight); } } break; default: { if (addPadding) { // left align is the default s += StringUtil.Padding(padCount); } } break; } } else if (currentValueDisplayLength > width) { // the string is longer than the width of the column // truncate and add ellipsis if it's too long int truncationDisplayLength = width - EllipsisSize; if (truncationDisplayLength > 0) { // we have space for the ellipsis, add it switch (alignment) { case TextAlignment.Right: { // get from "abcdef" to "...f" s = s.VtSubstring( startOffset: dc.TruncateHead(s, truncationDisplayLength), prependStr: PSObjectHelper.EllipsisStr, appendStr: null); } break; default: { // left align is the default // get from "abcdef" to "a..." s = s.VtSubstring( startOffset: 0, length: dc.TruncateTail(s, truncationDisplayLength), prependStr: null, appendStr: PSObjectHelper.EllipsisStr); } break; } } else { // not enough space for the ellipsis, just truncate at the width switch (alignment) { case TextAlignment.Right: { // get from "abcdef" to "f" s = s.VtSubstring(startOffset: dc.TruncateHead(s, width)); } break; default: { // left align is the default // get from "abcdef" to "a" s = s.VtSubstring(startOffset: 0, length: dc.TruncateTail(s, width)); } break; } } } // we need to take into consideration that truncation left the string one // display cell short if a double cell character got truncated // in this case, we need to pad with a blank int finalValueDisplayLength = dc.Length(s); if (finalValueDisplayLength == width) { return(s); } switch (alignment) { case TextAlignment.Right: { s = " " + s; } break; case TextAlignment.Center: { if (addPadding) { s += " "; } } break; default: { // left align is the default if (addPadding) { s += " "; } } break; } return(s); }