diff --git a/CompatBot/Commands/Invites.cs b/CompatBot/Commands/Invites.cs index 42d63229..5f55c94c 100644 --- a/CompatBot/Commands/Invites.cs +++ b/CompatBot/Commands/Invites.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.Linq; using System.Text; using System.Threading.Tasks; using CompatApiClient.Utils; diff --git a/CompatBot/Utils/AsciiTable.cs b/CompatBot/Utils/AsciiTable.cs index 0205ceed..4c2f6e6b 100644 --- a/CompatBot/Utils/AsciiTable.cs +++ b/CompatBot/Utils/AsciiTable.cs @@ -133,10 +133,10 @@ namespace CompatBot.Utils throw new InvalidOperationException("Can't format table as every column is disabled"); // header - result.Append(columns[firstIdx].Trim(width[firstIdx]).PadRightVisible(width[firstIdx])); + result.Append(columns[firstIdx].TrimVisible(maxWidth[firstIdx]).PadRightVisible(width[firstIdx])); for (var i = firstIdx+1; i < columns.Length; i++) if (!disabled[i]) - result.Append(" │ ").Append(columns[i].Trim(width[i]).PadRightVisible(width[i])); // header is always aligned to the left + result.Append(" │ ").Append(columns[i].TrimVisible(maxWidth[i]).PadRightVisible(width[i])); // header is always aligned to the left result.AppendLine(); //header separator result.Append("".PadRight(width[firstIdx], '─')); @@ -147,12 +147,12 @@ namespace CompatBot.Utils //rows foreach (var row in rows) { - var cell = row[firstIdx].Trim(width[firstIdx]); + var cell = row[firstIdx].TrimVisible(maxWidth[firstIdx]); result.Append(alignToRight[firstIdx] ? cell.PadLeftVisible(width[firstIdx]) : cell.PadRightVisible(width[firstIdx])); for (var i = firstIdx+1; i < row.Length; i++) if (!disabled[i]) { - cell = row[i].Trim(width[i]); + cell = row[i].TrimVisible(maxWidth[i]); result.Append(" │ ").Append(alignToRight[i] ?cell.PadLeftVisible(width[i]) : cell.PadRightVisible(width[i])); } result.AppendLine(); diff --git a/CompatBot/Utils/StringUtils.cs b/CompatBot/Utils/StringUtils.cs index 8f93ddf6..59216702 100644 --- a/CompatBot/Utils/StringUtils.cs +++ b/CompatBot/Utils/StringUtils.cs @@ -118,6 +118,32 @@ namespace CompatBot.Utils return c; } + public static string TrimVisible(this string s, int maxLength) + { + if (string.IsNullOrEmpty(s)) + return s; + + if (maxLength < 1) + throw new ArgumentException("Max length can't be less than 1", nameof(maxLength)); + + if (s.Length <= maxLength) + return s; + + var c = 0; + var e = StringInfo.GetTextElementEnumerator(s.Normalize()); + var result = new StringBuilder(); + while (e.MoveNext() && c < maxLength-1) + { + var strEl = e.GetTextElement(); + result.Append(strEl); + if (char.IsControl(strEl[0]) || char.GetUnicodeCategory(strEl[0]) == UnicodeCategory.Format) + continue; + + c++; + } + return result.Append("…").ToString(); + } + public static string PadLeftVisible(this string s, int totalWidth, char padding = ' ') { s = s ?? ""; diff --git a/Tests/StringUtilTests.cs b/Tests/StringUtilTests.cs index ab07f323..3feb7ab5 100644 --- a/Tests/StringUtilTests.cs +++ b/Tests/StringUtilTests.cs @@ -7,7 +7,7 @@ namespace Tests public class StringUtilTests { [Test] - public void StringLengthTest() + public void VisibleLengthTest() { Assert.That("🇭🇷".GetVisibleLength(), Is.EqualTo(2)); Assert.That("\u200d".GetVisibleLength(), Is.EqualTo(0)); @@ -15,5 +15,13 @@ namespace Tests Assert.That("a\u0304\u0308bc\u0327".GetVisibleLength(), Is.EqualTo(3)); Assert.That("Megamouse".GetVisibleLength(), Is.EqualTo(9)); } + + [Test] + public void VisibleTrimTest() + { + Assert.That("abc".TrimVisible(100), Is.EqualTo("abc")); + Assert.That("abc".TrimVisible(3), Is.EqualTo("abc")); + Assert.That("abc".TrimVisible(2), Is.EqualTo("a…")); + } } }