fix: Fixed a bug where table width calculations were not considering unprintable characters

This commit is contained in:
Chris Cameron
2020-03-15 15:51:05 -04:00
parent b496594cd6
commit 022e625143
4 changed files with 58 additions and 6 deletions

View File

@@ -27,6 +27,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Console uses unicode for table drawing on Net Standard
- Using UTC for tracking scheduled events, fixes issues with DST
- Using UTC for tracking durations
- Fixed a bug where table width calculations were not considering unprintable characters
## [10.3.0] - 2020-01-20
### Changed

View File

@@ -37,7 +37,7 @@ namespace ICD.Common.Utils
/// <summary>
/// Matches ANSI escape codes, e.g. \x1b[31m and \x1b[30;1m
/// </summary>
private const string ANSI_PATTERN = "(?'match'\x01b\\[(?'code'[\\d;]+)m)";
public const string ANSI_REGEX = "(?'match'\x01b\\[(?'code'[\\d;]+)m)";
/// <summary>
/// Matches ANSI escape codes to HTML styles.
@@ -105,7 +105,7 @@ namespace ICD.Common.Utils
if (string.IsNullOrEmpty(data))
yield break;
Regex regex = new Regex(ANSI_PATTERN);
Regex regex = new Regex(ANSI_REGEX);
Match match = regex.Match(data);
// No matches

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using ICD.Common.Properties;
namespace ICD.Common.Utils.Extensions
@@ -256,5 +257,55 @@ namespace ICD.Common.Utils.Extensions
return hash1 + (hash2 * 1566083941);
}
}
/// <summary>
/// Strips all of the non-printable characters and control codes from the string.
/// </summary>
/// <param name="extends"></param>
/// <returns></returns>
public static string ToPrintableCharacters([NotNull] this string extends)
{
if (extends == null)
throw new ArgumentNullException("extends");
// Strip ANSI escape sequences
extends = Regex.Replace(extends, AnsiUtils.ANSI_REGEX, string.Empty);
// Strip control characters
extends = Regex.Replace(extends, @"\p{C}+", string.Empty);
return extends;
}
/// <summary>
/// Gets the printable length of the string.
/// </summary>
/// <param name="extends"></param>
/// <returns></returns>
public static int GetPrintableLength([NotNull] this string extends)
{
if (extends == null)
throw new ArgumentNullException("extends");
return extends.ToPrintableCharacters().Length;
}
/// <summary>
/// Pads the string to the number of printable characters.
/// </summary>
/// <param name="extends"></param>
/// <param name="length"></param>
/// <returns></returns>
public static string PadRightPrintable([NotNull] this string extends, int length)
{
if (extends == null)
throw new ArgumentNullException("extends");
int printableLength = extends.GetPrintableLength();
int actualLength = extends.Length;
int delta = actualLength - printableLength;
return extends.PadRight(length + delta);
}
}
}

View File

@@ -169,14 +169,14 @@ namespace ICD.Common.Utils
private int GetColumnWidth(int index)
{
int titleLength = m_Columns[index].Length + 1;
int titleLength = m_Columns[index].GetPrintableLength() + 1;
if (m_Rows.Count == 0)
return titleLength;
int maxColumnWidth = m_Rows.Except((string[])null)
.Max(x => x[index] != null ? x[index].Length : 0) + 1;
.Max(x => x[index] != null ? x[index].GetPrintableLength() : 0) + 1;
return (titleLength > maxColumnWidth) ? titleLength : maxColumnWidth;
return titleLength > maxColumnWidth ? titleLength : maxColumnWidth;
}
private void AppendTopSeparator(StringBuilder builder, IList<int> columnWidths)
@@ -245,7 +245,7 @@ namespace ICD.Common.Utils
builder.Append(' ');
string value = row[index] ?? string.Empty;
builder.Append(value.PadRight(columnWidths[index]));
builder.Append(value.PadRightPrintable(columnWidths[index]));
if (index < row.Count - 1)
builder.Append(VERTICAL);