private string GenerateRow(string[] values, int[] alignment, DisplayCells dc) { StringBuilder sb = new StringBuilder(); for (int k = 0; k < _si.columnInfo.Length; k++) { if (_si.columnInfo[k].width <= 0) { // skip columns that are not at least a single character wide continue; } int newRowIndex = sb.Length; // NOTE: the following padding operations assume that we // pad with a blank (or any character that ALWAYS maps to a single screen cell if (k > 0) { sb.Append(new string(' ', ScreenInfo.separatorCharacterCount)); } else { // add indentation padding if needed if (_startColumn > 0) { sb.Append(new string(' ', _startColumn)); } } sb.Append(GenerateRowField(values[k], _si.columnInfo[k].width, alignment[k], dc)); } return(sb.ToString()); }
internal static StringCollection GenerateLines(DisplayCells displayCells, string val, int firstLineLen, int followingLinesLen) { if (CultureCollection.Contains(Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName)) { return GenerateLinesWithWordWrap(displayCells, val, firstLineLen, followingLinesLen); } return GenerateLinesWithoutWordWrap(displayCells, val, firstLineLen, followingLinesLen); }
internal static StringCollection GenerateLines(DisplayCells displayCells, string val, int firstLineLen, int followingLinesLen) { if (CultureCollection.Contains(Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName)) { return(GenerateLinesWithWordWrap(displayCells, val, firstLineLen, followingLinesLen)); } return(GenerateLinesWithoutWordWrap(displayCells, val, firstLineLen, followingLinesLen)); }
internal void Initialize(string[] propertyNames, int screenColumnWidth, DisplayCells dc) { this.columnWidth = screenColumnWidth; if ((propertyNames == null) || (propertyNames.Length == 0)) { this.disabled = true; } else { this.disabled = false; if ((((screenColumnWidth - " : ".Length) - 1) - 1) < 0) { this.disabled = true; } else { int num = (screenColumnWidth - " : ".Length) - 1; this.propertyLabelsDisplayLength = 0; int[] numArray = new int[propertyNames.Length]; for (int i = 0; i < propertyNames.Length; i++) { numArray[i] = dc.Length(propertyNames[i]); if (numArray[i] > this.propertyLabelsDisplayLength) { this.propertyLabelsDisplayLength = numArray[i]; } } if (this.propertyLabelsDisplayLength > num) { this.propertyLabelsDisplayLength = num; } this.propertyLabels = new string[propertyNames.Length]; for (int j = 0; j < propertyNames.Length; j++) { string[] strArray = null; IntPtr ptr; if (numArray[j] < this.propertyLabelsDisplayLength) { this.propertyLabels[j] = propertyNames[j] + new string(' ', this.propertyLabelsDisplayLength - numArray[j]); } else if (numArray[j] > this.propertyLabelsDisplayLength) { this.propertyLabels[j] = propertyNames[j].Substring(0, dc.GetHeadSplitLength(propertyNames[j], this.propertyLabelsDisplayLength)); } else { this.propertyLabels[j] = propertyNames[j]; } strArray = this.propertyLabels; ptr = (IntPtr) j; strArray[(int) (ptr)] = strArray[(int) ptr] + " : "; } this.propertyLabelsDisplayLength += " : ".Length; } } }
internal void Initialize(string[] propertyNames, int screenColumnWidth, DisplayCells dc) { this.columnWidth = screenColumnWidth; if ((propertyNames == null) || (propertyNames.Length == 0)) { this.disabled = true; } else { this.disabled = false; if ((((screenColumnWidth - " : ".Length) - 1) - 1) < 0) { this.disabled = true; } else { int num = (screenColumnWidth - " : ".Length) - 1; this.propertyLabelsDisplayLength = 0; int[] numArray = new int[propertyNames.Length]; for (int i = 0; i < propertyNames.Length; i++) { numArray[i] = dc.Length(propertyNames[i]); if (numArray[i] > this.propertyLabelsDisplayLength) { this.propertyLabelsDisplayLength = numArray[i]; } } if (this.propertyLabelsDisplayLength > num) { this.propertyLabelsDisplayLength = num; } this.propertyLabels = new string[propertyNames.Length]; for (int j = 0; j < propertyNames.Length; j++) { string[] strArray = null; IntPtr ptr; if (numArray[j] < this.propertyLabelsDisplayLength) { this.propertyLabels[j] = propertyNames[j] + new string(' ', this.propertyLabelsDisplayLength - numArray[j]); } else if (numArray[j] > this.propertyLabelsDisplayLength) { this.propertyLabels[j] = propertyNames[j].Substring(0, dc.GetHeadSplitLength(propertyNames[j], this.propertyLabelsDisplayLength)); } else { this.propertyLabels[j] = propertyNames[j]; } strArray = this.propertyLabels; ptr = (IntPtr)j; strArray[(int)(ptr)] = strArray[(int)ptr] + " : "; } this.propertyLabelsDisplayLength += " : ".Length; } } }
private StringCollection GenerateMultiLineRowField(string val, int k, int aligment, DisplayCells dc) { StringCollection strings = StringManipulationHelper.GenerateLines(dc, val, this.si.columnInfo[k].width, this.si.columnInfo[k].width); for (int i = 0; i < strings.Count; i++) { if (dc.Length(strings[i]) < this.si.columnInfo[k].width) { strings[i] = GenerateRowField(strings[i], this.si.columnInfo[k].width, aligment, dc); } } return strings; }
private string GenerateRow(string[] values, ReadOnlySpan <int> alignment, DisplayCells dc) { StringBuilder sb = new StringBuilder(); bool addPadding = true; for (int k = 0; k < _si.columnInfo.Length; k++) { // don't pad the last column if (k == _si.columnInfo.Length - 1) { addPadding = false; } if (_si.columnInfo[k].width <= 0) { // skip columns that are not at least a single character wide continue; } // NOTE: the following padding operations assume that we // pad with a blank (or any character that ALWAYS maps to a single screen cell if (k > 0) { sb.Append(StringUtil.Padding(ScreenInfo.separatorCharacterCount)); } else { // add indentation padding if needed if (_startColumn > 0) { sb.Append(StringUtil.Padding(_startColumn)); } } sb.Append(GenerateRowField(values[k], _si.columnInfo[k].width, alignment[k], dc, addPadding)); if (values[k].Contains(ESC)) { // Reset the console output if the content of this column contains ESC if (ExperimentalFeature.IsEnabled("PSAnsiRendering")) { // Remove definition of `ResetConsoleVt10Code` when PSAnsiRendering is not experimental sb.Append(PSStyle.Instance.Reset); } else { sb.Append(ResetConsoleVt100Code); } } } return(sb.ToString()); }
internal WriteLineHelper(bool lineWrap, WriteCallback wlc, WriteCallback wc, DisplayCells displayCells) { if (wlc == null) { throw PSTraceSource.NewArgumentNullException("wlc"); } if (displayCells == null) { throw PSTraceSource.NewArgumentNullException("displayCells"); } this._displayCells = displayCells; this.writeLineCall = wlc; this.writeCall = (wc != null) ? wc : wlc; this.lineWrap = lineWrap; }
/// <summary> /// Construct an instance, given the two callbacks /// NOTE: if the underlying device treats the two cases as the /// same, the same delegate can be passed twice. /// </summary> /// <param name="lineWrap">True if we require line wrapping.</param> /// <param name="wlc">Delegate for WriteLine(), must ben non null.</param> /// <param name="wc">Delegate for Write(), if null, use the first parameter.</param> /// <param name="displayCells">Helper object for manipulating strings.</param> internal WriteLineHelper(bool lineWrap, WriteCallback wlc, WriteCallback wc, DisplayCells displayCells) { if (wlc == null) { throw PSTraceSource.NewArgumentNullException(nameof(wlc)); } if (displayCells == null) { throw PSTraceSource.NewArgumentNullException(nameof(displayCells)); } _displayCells = displayCells; _writeLineCall = wlc; _writeCall = wc ?? wlc; _lineWrap = lineWrap; }
private static StringCollection GenerateLinesWithoutWordWrap(DisplayCells displayCells, string val, int firstLineLen, int followingLinesLen) { StringCollection retVal = new StringCollection(); if (string.IsNullOrEmpty(val)) { retVal.Add(val); return(retVal); } string[] strArray = SplitLines(val); for (int i = 0; i < strArray.Length; i++) { if ((strArray[i] == null) || (displayCells.Length(strArray[i]) <= firstLineLen)) { retVal.Add(strArray[i]); continue; } SplitLinesAccumulator accumulator = new SplitLinesAccumulator(retVal, firstLineLen, followingLinesLen); int offset = 0; while (true) { int activeLen = accumulator.ActiveLen; int num5 = displayCells.Length(strArray[i], offset) - activeLen; if (num5 <= 0) { break; } int length = displayCells.GetHeadSplitLength(strArray[i], offset, activeLen); if (length <= 0) { length = 1; accumulator.AddLine("?"); } else { accumulator.AddLine(strArray[i].Substring(offset, length)); } offset += length; } accumulator.AddLine(strArray[i].Substring(offset)); } return(retVal); }
private static StringCollection GenerateLinesWithoutWordWrap(DisplayCells displayCells, string val, int firstLineLen, int followingLinesLen) { StringCollection retVal = new StringCollection(); if (string.IsNullOrEmpty(val)) { retVal.Add(val); return retVal; } string[] strArray = SplitLines(val); for (int i = 0; i < strArray.Length; i++) { if ((strArray[i] == null) || (displayCells.Length(strArray[i]) <= firstLineLen)) { retVal.Add(strArray[i]); continue; } SplitLinesAccumulator accumulator = new SplitLinesAccumulator(retVal, firstLineLen, followingLinesLen); int offset = 0; while (true) { int activeLen = accumulator.ActiveLen; int num5 = displayCells.Length(strArray[i], offset) - activeLen; if (num5 <= 0) { break; } int length = displayCells.GetHeadSplitLength(strArray[i], offset, activeLen); if (length <= 0) { length = 1; accumulator.AddLine("?"); } else { accumulator.AddLine(strArray[i].Substring(offset, length)); } offset += length; } accumulator.AddLine(strArray[i].Substring(offset)); } return retVal; }
private string GenerateRow(string[] values, int[] alignment, DisplayCells dc) { StringBuilder builder = new StringBuilder(); for (int i = 0; i < this.si.columnInfo.Length; i++) { if (this.si.columnInfo[i].width > 0) { int length = builder.Length; if (i > 0) { builder.Append(new string(' ', 1)); } else if (this.startColumn > 0) { builder.Append(new string(' ', this.startColumn)); } builder.Append(GenerateRowField(values[i], this.si.columnInfo[i].width, alignment[i], dc)); } } return builder.ToString(); }
private string GenerateRow(string[] values, int[] alignment, DisplayCells dc) { StringBuilder builder = new StringBuilder(); for (int i = 0; i < this.si.columnInfo.Length; i++) { if (this.si.columnInfo[i].width > 0) { int length = builder.Length; if (i > 0) { builder.Append(new string(' ', 1)); } else if (this.startColumn > 0) { builder.Append(new string(' ', this.startColumn)); } builder.Append(GenerateRowField(values[i], this.si.columnInfo[i].width, alignment[i], dc)); } } return(builder.ToString()); }
private StringCollection GenerateMultiLineRowField(string val, int k, int alignment, DisplayCells dc) { StringCollection sc = StringManipulationHelper.GenerateLines(dc, val, _si.columnInfo[k].width, _si.columnInfo[k].width); // if length is shorter, do some padding for (int col = 0; col < sc.Count; col++) { if (dc.Length(sc[col]) < _si.columnInfo[k].width) sc[col] = GenerateRowField(sc[col], _si.columnInfo[k].width, alignment, dc); } return sc; }
private string[] GenerateTableRow(string[] values, int[] alignment, DisplayCells ds) { // select the active columns (skip hidden ones) int[] validColumnArray = new int[_si.columnInfo.Length]; int validColumnCount = 0; for (int k = 0; k < _si.columnInfo.Length; k++) { if (_si.columnInfo[k].width > 0) { validColumnArray[validColumnCount++] = k; } } if (validColumnCount == 0) return null; StringCollection[] scArray = new StringCollection[validColumnCount]; for (int k = 0; k < scArray.Length; k++) { // obtain a set of tokens for each field scArray[k] = GenerateMultiLineRowField(values[validColumnArray[k]], validColumnArray[k], alignment[validColumnArray[k]], ds); // NOTE: the following padding operations assume that we // pad with a blank (or any character that ALWAYS maps to a single screen cell if (k > 0) { // skipping the first ones, add a separator for catenation for (int j = 0; j < scArray[k].Count; j++) { scArray[k][j] = new string(' ', ScreenInfo.separatorCharacterCount) + scArray[k][j]; } } else { // add indentation padding if needed if (_startColumn > 0) { for (int j = 0; j < scArray[k].Count; j++) { scArray[k][j] = new string(' ', _startColumn) + scArray[k][j]; } } } } // now we processed all the rows columns and we need to find the cell that occupies the most // rows int screenRows = 0; for (int k = 0; k < scArray.Length; k++) { if (scArray[k].Count > screenRows) screenRows = scArray[k].Count; } // add padding for the columns that are shorter for (int col = 0; col < scArray.Length; col++) { int paddingBlanks = _si.columnInfo[validColumnArray[col]].width; if (col > 0) paddingBlanks += ScreenInfo.separatorCharacterCount; else { paddingBlanks += _startColumn; } int paddingEntries = screenRows - scArray[col].Count; if (paddingEntries > 0) { for (int j = 0; j < paddingEntries; j++) { scArray[col].Add(new string(' ', paddingBlanks)); } } } // finally, build an array of strings string[] rows = new string[screenRows]; for (int row = 0; row < rows.Length; row++) { StringBuilder sb = new StringBuilder(); // for a give row, walk the columns for (int col = 0; col < scArray.Length; col++) { sb.Append(scArray[col][row]); } rows[row] = sb.ToString(); } return rows; }
private static StringCollection GenerateLinesWithWordWrap(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++) { if (lines[k] == null || displayCells.Length(lines[k]) <= firstLineLen) { // we do not need to split further, just add retVal.Add(lines[k]); continue; } int spacesLeft = firstLineLen; int lineWidth = firstLineLen; bool firstLine = true; StringBuilder singleLine = new StringBuilder(); foreach (GetWordsResult word in GetWords(lines[k])) { string wordToAdd = word.Word; // Handle soft hyphen if (word.Delim == s_softHyphen.ToString()) { int wordWidthWithHyphen = displayCells.Length(wordToAdd) + displayCells.Length(s_softHyphen.ToString()); // Add hyphen only if necessary if (wordWidthWithHyphen == spacesLeft) { wordToAdd += "-"; } } else { if (!String.IsNullOrEmpty(word.Delim)) { wordToAdd += word.Delim; } } int wordWidth = displayCells.Length(wordToAdd); // Handle zero width if (lineWidth == 0) { if (firstLine) { firstLine = false; lineWidth = followingLinesLen; } if (lineWidth == 0) { break; } spacesLeft = lineWidth; } // Word is wider than a single line if (wordWidth > lineWidth) { foreach (char c in wordToAdd) { char charToAdd = c; int charWidth = displayCells.Length(c); // 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 if (charWidth > lineWidth) { charToAdd = '?'; charWidth = 1; } if (charWidth > spacesLeft) { retVal.Add(singleLine.ToString()); singleLine.Clear(); singleLine.Append(charToAdd); if (firstLine) { firstLine = false; lineWidth = followingLinesLen; } spacesLeft = lineWidth - charWidth; } else { singleLine.Append(charToAdd); spacesLeft -= charWidth; } } } else { if (wordWidth > spacesLeft) { retVal.Add(singleLine.ToString()); singleLine.Clear(); singleLine.Append(wordToAdd); if (firstLine) { firstLine = false; lineWidth = followingLinesLen; } spacesLeft = lineWidth - wordWidth; } else { singleLine.Append(wordToAdd); spacesLeft -= wordWidth; } } } retVal.Add(singleLine.ToString()); } return retVal; }
internal void GenerateRow(string[] values, LineOutput lo, bool multiLine, int[] alignment, DisplayCells dc) { if (!this.disabled) { int length = this.si.columnInfo.Length; int[] numArray = new int[length]; if (alignment == null) { for (int i = 0; i < length; i++) { numArray[i] = this.si.columnInfo[i].alignment; } } else { for (int j = 0; j < length; j++) { if (alignment[j] == 0) { numArray[j] = this.si.columnInfo[j].alignment; } else { numArray[j] = alignment[j]; } } } if (multiLine) { string[] strArray = this.GenerateTableRow(values, numArray, lo.DisplayCells); for (int k = 0; k < strArray.Length; k++) { lo.WriteLine(strArray[k]); } } else { lo.WriteLine(this.GenerateRow(values, numArray, dc)); } } }
private static string GenerateRowField(string val, int width, int alignment, DisplayCells dc) { string str = StringManipulationHelper.TruncateAtNewLine(val); if (str == null) { str = ""; } string str2 = str; int num = dc.Length(str2); if (num < width) { int count = width - num; switch (alignment) { case 2: { int num3 = count / 2; int num4 = count - num3; str = new string(' ', num3) + str + new string(' ', num4); goto Label_0182; } case 3: str = new string(' ', count) + str; goto Label_0182; } str = str + new string(' ', count); } else if (num > width) { int displayCells = width - "...".Length; if (displayCells > 0) { switch (alignment) { case 2: str = str.Substring(0, dc.GetHeadSplitLength(str, displayCells)) + "..."; goto Label_0182; case 3: { int tailSplitLength = dc.GetTailSplitLength(str, displayCells); str = str.Substring(str.Length - tailSplitLength); str = "..." + str; goto Label_0182; } } str = str.Substring(0, dc.GetHeadSplitLength(str, displayCells)) + "..."; } else { int num7 = width; switch (alignment) { case 2: str = str.Substring(0, dc.GetHeadSplitLength(str, num7)); goto Label_0182; case 3: { int length = dc.GetTailSplitLength(str, num7); str = str.Substring(str.Length - length, length); goto Label_0182; } } str = str.Substring(0, dc.GetHeadSplitLength(str, num7)); } } Label_0182: if (dc.Length(str) == width) { return str; } switch (alignment) { case 2: return (str + " "); case 3: return (" " + str); } return (str + " "); }
private static string GenerateRowField(string val, int width, int alignment, DisplayCells dc) { string str = StringManipulationHelper.TruncateAtNewLine(val); if (str == null) { str = ""; } string str2 = str; int num = dc.Length(str2); if (num < width) { int count = width - num; switch (alignment) { case 2: { int num3 = count / 2; int num4 = count - num3; str = new string(' ', num3) + str + new string(' ', num4); goto Label_0182; } case 3: str = new string(' ', count) + str; goto Label_0182; } str = str + new string(' ', count); } else if (num > width) { int displayCells = width - "...".Length; if (displayCells > 0) { switch (alignment) { case 2: str = str.Substring(0, dc.GetHeadSplitLength(str, displayCells)) + "..."; goto Label_0182; case 3: { int tailSplitLength = dc.GetTailSplitLength(str, displayCells); str = str.Substring(str.Length - tailSplitLength); str = "..." + str; goto Label_0182; } } str = str.Substring(0, dc.GetHeadSplitLength(str, displayCells)) + "..."; } else { int num7 = width; switch (alignment) { case 2: str = str.Substring(0, dc.GetHeadSplitLength(str, num7)); goto Label_0182; case 3: { int length = dc.GetTailSplitLength(str, num7); str = str.Substring(str.Length - length, length); goto Label_0182; } } str = str.Substring(0, dc.GetHeadSplitLength(str, num7)); } } Label_0182: if (dc.Length(str) == width) { return(str); } switch (alignment) { case 2: return(str + " "); case 3: return(" " + str); } return(str + " "); }
internal int ComputePromptLines(DisplayCells displayCells, int cols) { this.actualPrompt = StringManipulationHelper.GenerateLines(displayCells, this.promptString, cols, cols); return(this.actualPrompt.Count); }
/// <summary> /// construct an instance, given the two callbacks /// NOTE: if the underlying device treats the two cases as the /// same, the same delegate can be passed twice /// </summary> /// <param name="lineWrap">true if we require line wrapping</param> /// <param name="wlc">delegate for WriteLine(), must ben non null</param> /// <param name="wc">delegate for Write(), if null, use the first parameter</param> /// <param name="displayCells">helper object for manipulating strings</param> internal WriteLineHelper(bool lineWrap, WriteCallback wlc, WriteCallback wc, DisplayCells displayCells) { if (wlc == null) throw PSTraceSource.NewArgumentNullException("wlc"); if (displayCells == null) throw PSTraceSource.NewArgumentNullException("displayCells"); _displayCells = displayCells; _writeLineCall = wlc; _writeCall = wc ?? wlc; _lineWrap = lineWrap; }
/// <summary> /// /// </summary> /// <param name="propertyNames">names of the properties to display</param> /// <param name="screenColumnWidth">column width of the screen</param> /// <param name="dc">instance of the DisplayCells helper object</param> internal void Initialize(string[] propertyNames, int screenColumnWidth, DisplayCells dc) { _columnWidth = screenColumnWidth; if (propertyNames == null || propertyNames.Length == 0) { // there is nothing to show _disabled = true; return; } _disabled = false; Debug.Assert(propertyNames != null, "propertyNames is null"); Debug.Assert(propertyNames.Length > 0, "propertyNames has zero length"); // assess the useful widths if ((screenColumnWidth - Separator.Length - MinFieldWidth - MinLabelWidth) < 0) { // we do not have enough space for any meaningful display _disabled = true; return; } // check if we have to truncate the labels int maxAllowableLabelLength = screenColumnWidth - Separator.Length - MinFieldWidth; // find out the max display length (cell count) of the property names _propertyLabelsDisplayLength = 0; // reset max // cache the cell lengths for each property int[] propertyNameCellCounts = new int[propertyNames.Length]; for (int k = 0; k < propertyNames.Length; k++) { Debug.Assert(propertyNames[k] != null, "propertyNames[k] is null"); propertyNameCellCounts[k] = dc.Length(propertyNames[k]); if (propertyNameCellCounts[k] > _propertyLabelsDisplayLength) _propertyLabelsDisplayLength = propertyNameCellCounts[k]; } if (_propertyLabelsDisplayLength > maxAllowableLabelLength) { // need to truncate _propertyLabelsDisplayLength = maxAllowableLabelLength; } _propertyLabels = new string[propertyNames.Length]; for (int k = 0; k < propertyNames.Length; k++) { if (propertyNameCellCounts[k] < _propertyLabelsDisplayLength) { // shorter than the max, add padding _propertyLabels[k] = propertyNames[k] + new string(' ', _propertyLabelsDisplayLength - propertyNameCellCounts[k]); } else if (propertyNameCellCounts[k] > _propertyLabelsDisplayLength) { // longer than the max, clip _propertyLabels[k] = propertyNames[k].Substring(0, dc.GetHeadSplitLength(propertyNames[k], _propertyLabelsDisplayLength)); } else { _propertyLabels[k] = propertyNames[k]; } _propertyLabels[k] += Separator; } _propertyLabelsDisplayLength += Separator.Length; }
private static StringCollection GenerateLinesWithWordWrap(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 List <string> lines = SplitLines(val); for (int k = 0; k < lines.Count; k++) { if (lines[k] == null || displayCells.Length(lines[k]) <= firstLineLen) { // we do not need to split further, just add retVal.Add(lines[k]); continue; } int spacesLeft = firstLineLen; int lineWidth = firstLineLen; bool firstLine = true; StringBuilder singleLine = new StringBuilder(); string resetStr = PSStyle.Instance.Reset; foreach (GetWordsResult word in GetWords(lines[k])) { string wordToAdd = word.Word; string suffix = null; // Handle soft hyphen if (word.Delim.Length == 1 && word.Delim[0] == s_softHyphen) { int wordWidthWithHyphen = displayCells.Length(wordToAdd) + displayCells.Length(s_softHyphen); // Add hyphen only if necessary if (wordWidthWithHyphen == spacesLeft) { suffix = "-"; } } else if (!string.IsNullOrEmpty(word.Delim)) { suffix = word.Delim; } if (suffix is not null) { wordToAdd = wordToAdd.EndsWith(resetStr) ? wordToAdd.Insert(wordToAdd.Length - resetStr.Length, suffix) : wordToAdd + suffix; } int wordWidth = displayCells.Length(wordToAdd); // Handle zero width if (lineWidth == 0) { if (firstLine) { firstLine = false; lineWidth = followingLinesLen; } if (lineWidth == 0) { break; } spacesLeft = lineWidth; } // Word is wider than a single line if (wordWidth > lineWidth) { Dictionary <int, int> vtRanges = null; StringBuilder vtSeqs = null; var valueStrDec = new ValueStringDecorated(wordToAdd); if (valueStrDec.IsDecorated) { vtSeqs = new StringBuilder(); vtRanges = valueStrDec.EscapeSequenceRanges; } bool hasEscSeqs = false; for (int i = 0; i < wordToAdd.Length; i++) { if (vtRanges?.TryGetValue(i, out int len) == true) { var vtSpan = wordToAdd.AsSpan(i, len); singleLine.Append(vtSpan); vtSeqs.Append(vtSpan); hasEscSeqs = true; i += len - 1; continue; } char charToAdd = wordToAdd[i]; int charWidth = displayCells.Length(charToAdd); // 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. if (charWidth > lineWidth) { charToAdd = '?'; charWidth = 1; } if (charWidth > spacesLeft) { if (hasEscSeqs && !singleLine.EndsWith(resetStr)) { singleLine.Append(resetStr); } retVal.Add(singleLine.ToString()); singleLine.Clear().Append(vtSeqs).Append(charToAdd); if (firstLine) { firstLine = false; lineWidth = followingLinesLen; } spacesLeft = lineWidth - charWidth; } else { singleLine.Append(charToAdd); spacesLeft -= charWidth; } } } else { if (wordWidth > spacesLeft) { retVal.Add(singleLine.ToString()); singleLine.Clear().Append(wordToAdd); if (firstLine) { firstLine = false; lineWidth = followingLinesLen; } spacesLeft = lineWidth - wordWidth; } else { singleLine.Append(wordToAdd); spacesLeft -= wordWidth; } } } retVal.Add(singleLine.ToString()); } return(retVal); }
private StringCollection GenerateMultiLineRowField(string val, int k, int aligment, DisplayCells dc) { StringCollection strings = StringManipulationHelper.GenerateLines(dc, val, this.si.columnInfo[k].width, this.si.columnInfo[k].width); for (int i = 0; i < strings.Count; i++) { if (dc.Length(strings[i]) < this.si.columnInfo[k].width) { strings[i] = GenerateRowField(strings[i], this.si.columnInfo[k].width, aligment, dc); } } return(strings); }
private string[] GenerateTableRow(string[] values, int[] alignment, DisplayCells ds) { int[] numArray = new int[this.si.columnInfo.Length]; int num = 0; for (int i = 0; i < this.si.columnInfo.Length; i++) { if (this.si.columnInfo[i].width > 0) { numArray[num++] = i; } } if (num == 0) { return(null); } StringCollection[] stringsArray = new StringCollection[num]; for (int j = 0; j < stringsArray.Length; j++) { stringsArray[j] = this.GenerateMultiLineRowField(values[numArray[j]], numArray[j], alignment[numArray[j]], ds); if (j > 0) { for (int num4 = 0; num4 < stringsArray[j].Count; num4++) { stringsArray[j][num4] = new string(' ', 1) + stringsArray[j][num4]; } } else if (this.startColumn > 0) { for (int num5 = 0; num5 < stringsArray[j].Count; num5++) { stringsArray[j][num5] = new string(' ', this.startColumn) + stringsArray[j][num5]; } } } int count = 0; for (int k = 0; k < stringsArray.Length; k++) { if (stringsArray[k].Count > count) { count = stringsArray[k].Count; } } for (int m = 0; m < stringsArray.Length; m++) { int width = this.si.columnInfo[numArray[m]].width; if (m > 0) { width++; } else { width += this.startColumn; } int num10 = count - stringsArray[m].Count; if (num10 > 0) { for (int num11 = 0; num11 < num10; num11++) { stringsArray[m].Add(new string(' ', width)); } } } string[] strArray = new string[count]; for (int n = 0; n < strArray.Length; n++) { StringBuilder builder = new StringBuilder(); for (int num13 = 0; num13 < stringsArray.Length; num13++) { builder.Append(stringsArray[num13][n]); } strArray[n] = builder.ToString(); } return(strArray); }
private string GenerateRow(string[] values, int[] alignment, DisplayCells dc) { StringBuilder sb = new StringBuilder(); for (int k = 0; k < _si.columnInfo.Length; k++) { if (_si.columnInfo[k].width <= 0) { // skip columns that are not at least a single character wide continue; } int newRowIndex = sb.Length; // NOTE: the following padding operations assume that we // pad with a blank (or any character that ALWAYS maps to a single screen cell if (k > 0) { sb.Append(new string(' ', ScreenInfo.separatorCharacterCount)); } else { // add indentation padding if needed if (_startColumn > 0) { sb.Append(new string(' ', _startColumn)); } } sb.Append(GenerateRowField(values[k], _si.columnInfo[k].width, alignment[k], dc)); } return sb.ToString(); }
internal int ComputePromptLines(DisplayCells displayCells, int cols) { this.actualPrompt = StringManipulationHelper.GenerateLines(displayCells, this.promptString, cols, cols); return this.actualPrompt.Count; }
private static string GenerateRowField(string val, int width, int alignment, DisplayCells dc) { // make sure the string does not have any embedded <CR> in it string s = StringManipulationHelper.TruncateAtNewLine(val) ?? ""; string currentValue = s; int currentValueDisplayLength = dc.Length(currentValue); 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 = new string(' ', padCount) + s; } break; case TextAlignment.Center: { // add a bit at both ends of the string int padLeft = padCount / 2; int padRight = padCount - padLeft; s = new string(' ', padLeft) + s + new string(' ', padRight); } break; default: { // left align is the default s += new string(' ', 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 - ellipsis.Length; if (truncationDisplayLength > 0) { // we have space for the ellipsis, add it switch (alignment) { case TextAlignment.Right: { // get from "abcdef" to "...f" int tailCount = dc.GetTailSplitLength(s, truncationDisplayLength); s = s.Substring(s.Length - tailCount); s = ellipsis + s; } break; case TextAlignment.Center: { // get from "abcdef" to "a..." s = s.Substring(0, dc.GetHeadSplitLength(s, truncationDisplayLength)); s += ellipsis; } break; default: { // left align is the default // get from "abcdef" to "a..." s = s.Substring(0, dc.GetHeadSplitLength(s, truncationDisplayLength)); s += ellipsis; } break; } } else { // not enough space for the ellipsis, just truncate at the width int len = width; switch (alignment) { case TextAlignment.Right: { // get from "abcdef" to "f" int tailCount = dc.GetTailSplitLength(s, len); s = s.Substring(s.Length - tailCount, tailCount); } break; case TextAlignment.Center: { // get from "abcdef" to "a" s = s.Substring(0, dc.GetHeadSplitLength(s, len)); } break; default: { // left align is the default // get from "abcdef" to "a" s = s.Substring(0, dc.GetHeadSplitLength(s, len)); } 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; } // we have to pad System.Diagnostics.Debug.Assert(finalValueDisplayLength == width - 1, "padding is not correct"); switch (alignment) { case TextAlignment.Right: { s = " " + s; } break; case TextAlignment.Center: { s += " "; } break; default: { // left align is the default s += " "; } break; } return s; }
internal void GenerateRow(string[] values, LineOutput lo, bool multiLine, int[] alignment, DisplayCells dc) { if (_disabled) { return; } // build the current row alignment settings int cols = _si.columnInfo.Length; int[] currentAlignment = new int[cols]; if (alignment == null) { for (int i = 0; i < cols; i++) { currentAlignment[i] = _si.columnInfo[i].alignment; } } else { for (int i = 0; i < cols; i++) { if (alignment[i] == TextAlignment.Undefined) { currentAlignment[i] = _si.columnInfo[i].alignment; } else { currentAlignment[i] = alignment[i]; } } } if (multiLine) { string[] lines = GenerateTableRow(values, currentAlignment, lo.DisplayCells); for (int k = 0; k < lines.Length; k++) { lo.WriteLine(lines[k]); } } else { lo.WriteLine(GenerateRow(values, currentAlignment, dc)); } }
private static StringCollection GenerateLinesWithWordWrap(DisplayCells displayCells, string val, int firstLineLen, int followingLinesLen) { StringCollection strings = new StringCollection(); if (string.IsNullOrEmpty(val)) { strings.Add(val); return(strings); } string[] strArray = SplitLines(val); for (int i = 0; i < strArray.Length; i++) { if ((strArray[i] == null) || (displayCells.Length(strArray[i]) <= firstLineLen)) { strings.Add(strArray[i]); continue; } int num2 = firstLineLen; int num3 = firstLineLen; bool flag = true; StringBuilder builder = new StringBuilder(); foreach (GetWordsResult result in GetWords(strArray[i])) { string word = result.Word; if (result.Delim == SoftHyphen.ToString()) { int num4 = displayCells.Length(word) + displayCells.Length(SoftHyphen.ToString()); if (num4 == num2) { word = word + "-"; } } else if (!string.IsNullOrEmpty(result.Delim)) { word = word + result.Delim; } int num5 = displayCells.Length(word); if (num3 == 0) { if (flag) { flag = false; num3 = followingLinesLen; } if (num3 == 0) { break; } num2 = num3; } if (num5 > num3) { foreach (char ch in word) { char ch2 = ch; int num6 = displayCells.Length(ch); if (num6 > num3) { ch2 = '?'; num6 = 1; } if (num6 > num2) { strings.Add(builder.ToString()); builder.Clear(); builder.Append(ch2); if (flag) { flag = false; num3 = followingLinesLen; } num2 = num3 - num6; } else { builder.Append(ch2); num2 -= num6; } } } else if (num5 > num2) { strings.Add(builder.ToString()); builder.Clear(); builder.Append(word); if (flag) { flag = false; num3 = followingLinesLen; } num2 = num3 - num5; } else { builder.Append(word); num2 -= num5; } } strings.Add(builder.ToString()); } return(strings); }
private string[] GenerateTableRow(string[] values, int[] alignment, DisplayCells ds) { int[] numArray = new int[this.si.columnInfo.Length]; int num = 0; for (int i = 0; i < this.si.columnInfo.Length; i++) { if (this.si.columnInfo[i].width > 0) { numArray[num++] = i; } } if (num == 0) { return null; } StringCollection[] stringsArray = new StringCollection[num]; for (int j = 0; j < stringsArray.Length; j++) { stringsArray[j] = this.GenerateMultiLineRowField(values[numArray[j]], numArray[j], alignment[numArray[j]], ds); if (j > 0) { for (int num4 = 0; num4 < stringsArray[j].Count; num4++) { stringsArray[j][num4] = new string(' ', 1) + stringsArray[j][num4]; } } else if (this.startColumn > 0) { for (int num5 = 0; num5 < stringsArray[j].Count; num5++) { stringsArray[j][num5] = new string(' ', this.startColumn) + stringsArray[j][num5]; } } } int count = 0; for (int k = 0; k < stringsArray.Length; k++) { if (stringsArray[k].Count > count) { count = stringsArray[k].Count; } } for (int m = 0; m < stringsArray.Length; m++) { int width = this.si.columnInfo[numArray[m]].width; if (m > 0) { width++; } else { width += this.startColumn; } int num10 = count - stringsArray[m].Count; if (num10 > 0) { for (int num11 = 0; num11 < num10; num11++) { stringsArray[m].Add(new string(' ', width)); } } } string[] strArray = new string[count]; for (int n = 0; n < strArray.Length; n++) { StringBuilder builder = new StringBuilder(); for (int num13 = 0; num13 < stringsArray.Length; num13++) { builder.Append(stringsArray[num13][n]); } strArray[n] = builder.ToString(); } return strArray; }
/// <summary> /// determine how many rows the prompt should take. /// </summary> /// <param name="cols">current number of columns on the screen</param> /// <param name="displayCells">string manipulation helper</param> /// <returns></returns> internal int ComputePromptLines(DisplayCells displayCells, int cols) { // split the prompt string into lines _actualPrompt = StringManipulationHelper.GenerateLines(displayCells, _promptString, cols, cols); return _actualPrompt.Count; }
private string[] GenerateTableRow(string[] values, int[] alignment, DisplayCells ds) { // select the active columns (skip hidden ones) int[] validColumnArray = new int[_si.columnInfo.Length]; int validColumnCount = 0; for (int k = 0; k < _si.columnInfo.Length; k++) { if (_si.columnInfo[k].width > 0) { validColumnArray[validColumnCount++] = k; } } if (validColumnCount == 0) { return(null); } StringCollection[] scArray = new StringCollection[validColumnCount]; for (int k = 0; k < scArray.Length; k++) { // obtain a set of tokens for each field scArray[k] = GenerateMultiLineRowField(values[validColumnArray[k]], validColumnArray[k], alignment[validColumnArray[k]], ds); // NOTE: the following padding operations assume that we // pad with a blank (or any character that ALWAYS maps to a single screen cell if (k > 0) { // skipping the first ones, add a separator for catenation for (int j = 0; j < scArray[k].Count; j++) { scArray[k][j] = new string(' ', ScreenInfo.separatorCharacterCount) + scArray[k][j]; } } else { // add indentation padding if needed if (_startColumn > 0) { for (int j = 0; j < scArray[k].Count; j++) { scArray[k][j] = new string(' ', _startColumn) + scArray[k][j]; } } } } // now we processed all the rows columns and we need to find the cell that occupies the most // rows int screenRows = 0; for (int k = 0; k < scArray.Length; k++) { if (scArray[k].Count > screenRows) { screenRows = scArray[k].Count; } } // add padding for the columns that are shorter for (int col = 0; col < scArray.Length; col++) { int paddingBlanks = _si.columnInfo[validColumnArray[col]].width; if (col > 0) { paddingBlanks += ScreenInfo.separatorCharacterCount; } else { paddingBlanks += _startColumn; } int paddingEntries = screenRows - scArray[col].Count; if (paddingEntries > 0) { for (int j = 0; j < paddingEntries; j++) { scArray[col].Add(new string(' ', paddingBlanks)); } } } // finally, build an array of strings string[] rows = new string[screenRows]; for (int row = 0; row < rows.Length; row++) { StringBuilder sb = new StringBuilder(); // for a give row, walk the columns for (int col = 0; col < scArray.Length; col++) { sb.Append(scArray[col][row]); } rows[row] = sb.ToString(); } return(rows); }
private static StringCollection GenerateLinesWithWordWrap(DisplayCells displayCells, string val, int firstLineLen, int followingLinesLen) { StringCollection strings = new StringCollection(); if (string.IsNullOrEmpty(val)) { strings.Add(val); return strings; } string[] strArray = SplitLines(val); for (int i = 0; i < strArray.Length; i++) { if ((strArray[i] == null) || (displayCells.Length(strArray[i]) <= firstLineLen)) { strings.Add(strArray[i]); continue; } int num2 = firstLineLen; int num3 = firstLineLen; bool flag = true; StringBuilder builder = new StringBuilder(); foreach (GetWordsResult result in GetWords(strArray[i])) { string word = result.Word; if (result.Delim == SoftHyphen.ToString()) { int num4 = displayCells.Length(word) + displayCells.Length(SoftHyphen.ToString()); if (num4 == num2) { word = word + "-"; } } else if (!string.IsNullOrEmpty(result.Delim)) { word = word + result.Delim; } int num5 = displayCells.Length(word); if (num3 == 0) { if (flag) { flag = false; num3 = followingLinesLen; } if (num3 == 0) { break; } num2 = num3; } if (num5 > num3) { foreach (char ch in word) { char ch2 = ch; int num6 = displayCells.Length(ch); if (num6 > num3) { ch2 = '?'; num6 = 1; } if (num6 > num2) { strings.Add(builder.ToString()); builder.Clear(); builder.Append(ch2); if (flag) { flag = false; num3 = followingLinesLen; } num2 = num3 - num6; } else { builder.Append(ch2); num2 -= num6; } } } else if (num5 > num2) { strings.Add(builder.ToString()); builder.Clear(); builder.Append(word); if (flag) { flag = false; num3 = followingLinesLen; } num2 = num3 - num5; } else { builder.Append(word); num2 -= num5; } } strings.Add(builder.ToString()); } return strings; }
private static string GenerateRowField(string val, int width, int alignment, DisplayCells dc) { // make sure the string does not have any embedded <CR> in it string s = StringManipulationHelper.TruncateAtNewLine(val) ?? ""; string currentValue = s; int currentValueDisplayLength = dc.Length(currentValue); 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 = new string(' ', padCount) + s; } break; case TextAlignment.Center: { // add a bit at both ends of the string int padLeft = padCount / 2; int padRight = padCount - padLeft; s = new string(' ', padLeft) + s + new string(' ', padRight); } break; default: { // left align is the default s += new string(' ', 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 - ellipsis.Length; if (truncationDisplayLength > 0) { // we have space for the ellipsis, add it switch (alignment) { case TextAlignment.Right: { // get from "abcdef" to "...f" int tailCount = dc.GetTailSplitLength(s, truncationDisplayLength); s = s.Substring(s.Length - tailCount); s = ellipsis + s; } break; case TextAlignment.Center: { // get from "abcdef" to "a..." s = s.Substring(0, dc.GetHeadSplitLength(s, truncationDisplayLength)); s += ellipsis; } break; default: { // left align is the default // get from "abcdef" to "a..." s = s.Substring(0, dc.GetHeadSplitLength(s, truncationDisplayLength)); s += ellipsis; } break; } } else { // not enough space for the ellipsis, just truncate at the width int len = width; switch (alignment) { case TextAlignment.Right: { // get from "abcdef" to "f" int tailCount = dc.GetTailSplitLength(s, len); s = s.Substring(s.Length - tailCount, tailCount); } break; case TextAlignment.Center: { // get from "abcdef" to "a" s = s.Substring(0, dc.GetHeadSplitLength(s, len)); } break; default: { // left align is the default // get from "abcdef" to "a" s = s.Substring(0, dc.GetHeadSplitLength(s, len)); } 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); } // we have to pad System.Diagnostics.Debug.Assert(finalValueDisplayLength == width - 1, "padding is not correct"); switch (alignment) { case TextAlignment.Right: { s = " " + s; } break; case TextAlignment.Center: { s += " "; } break; default: { // left align is the default s += " "; } break; } return(s); }
internal void GenerateRow(string[] values, LineOutput lo, bool multiLine, int[] alignment, DisplayCells dc) { if (_disabled) return; // build the current row alignment settings int cols = _si.columnInfo.Length; int[] currentAlignment = new int[cols]; if (alignment == null) { for (int i = 0; i < cols; i++) { currentAlignment[i] = _si.columnInfo[i].alignment; } } else { for (int i = 0; i < cols; i++) { if (alignment[i] == TextAlignment.Undefined) currentAlignment[i] = _si.columnInfo[i].alignment; else currentAlignment[i] = alignment[i]; } } if (multiLine) { string[] lines = GenerateTableRow(values, currentAlignment, lo.DisplayCells); for (int k = 0; k < lines.Length; k++) { lo.WriteLine(lines[k]); } } else { lo.WriteLine(GenerateRow(values, currentAlignment, dc)); } }
internal void GenerateRow(string[] values, LineOutput lo, bool multiLine, ReadOnlySpan <int> alignment, DisplayCells dc) { if (_disabled) { return; } // build the current row alignment settings int cols = _si.columnInfo.Length; Span <int> currentAlignment = cols <= OutCommandInner.StackAllocThreshold ? stackalloc int[cols] : new int[cols]; if (alignment == null) { for (int i = 0; i < currentAlignment.Length; i++) { currentAlignment[i] = _si.columnInfo[i].alignment; } } else { for (int i = 0; i < currentAlignment.Length; i++) { if (alignment[i] == TextAlignment.Undefined) { currentAlignment[i] = _si.columnInfo[i].alignment; } else { currentAlignment[i] = alignment[i]; } } } if (multiLine) { string[] lines = GenerateTableRow(values, currentAlignment, lo.DisplayCells); for (int k = 0; k < lines.Length; k++) { lo.WriteLine(lines[k]); } } else { lo.WriteLine(GenerateRow(values, currentAlignment, dc)); } }
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++) { if (lines[k] == null || displayCells.Length(lines[k]) <= firstLineLen) { // we do not need to split further, just add retVal.Add(lines[k]); 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 (true) { // 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(lines[k], 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.GetHeadSplitLength(lines[k], 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(lines[k].Substring(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(lines[k].Substring(offset)); break; } } } return retVal; }