From 5e7448912618b6199310f0974118633aadbc3ccb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Mur=C3=A9?= Date: Sat, 1 Dec 2018 15:15:57 +0100 Subject: [PATCH] text: fix broken truncate with unicode and use the ellipsis character in LeftPadMaxLine --- util/text/left_padded.go | 25 +++++++++------- util/text/left_padded_test.go | 56 +++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 10 deletions(-) create mode 100644 util/text/left_padded_test.go diff --git a/util/text/left_padded.go b/util/text/left_padded.go index 78d772d596da37dacf158e2f95181de20200f513..729834db848a6d25c3f54f97538b45173deed4d9 100644 --- a/util/text/left_padded.go +++ b/util/text/left_padded.go @@ -2,22 +2,27 @@ package text import ( "bytes" + "fmt" "strings" - "unicode/utf8" ) // LeftPadMaxLine pads a string on the left by a specified amount and pads the string on the right to fill the maxLength -func LeftPadMaxLine(value string, maxValueLength, leftPad int) string { - valueLength := utf8.RuneCountInString(value) - if maxValueLength-leftPad >= valueLength { - return strings.Repeat(" ", leftPad) + value + strings.Repeat(" ", maxValueLength-valueLength-leftPad) - } else if maxValueLength-leftPad < valueLength { - tmp := strings.Trim(value[0:maxValueLength-leftPad-3], " ") + "..." - tmpLength := utf8.RuneCountInString(tmp) - return strings.Repeat(" ", leftPad) + tmp + strings.Repeat(" ", maxValueLength-tmpLength-leftPad) +func LeftPadMaxLine(text string, length, leftPad int) string { + runes := []rune(text) + + // truncate and ellipse if needed + if len(runes)+leftPad > length { + runes = append(runes[:(length-leftPad-1)], '…') + } + + if len(runes)+leftPad < length { + runes = append(runes, []rune(strings.Repeat(" ", length-len(runes)-leftPad))...) } - return value + return fmt.Sprintf("%s%s", + strings.Repeat(" ", leftPad), + string(runes), + ) } // LeftPad left pad each line of the given text diff --git a/util/text/left_padded_test.go b/util/text/left_padded_test.go new file mode 100644 index 0000000000000000000000000000000000000000..0be79e32d64ea792a228d18d58bb08eb331cb31f --- /dev/null +++ b/util/text/left_padded_test.go @@ -0,0 +1,56 @@ +package text + +import "testing" + +func TestLeftPadMaxLine(t *testing.T) { + cases := []struct { + input, output string + maxValueLength int + leftPad int + }{ + { + "foo", + "foo ", + 4, + 0, + }, + { + "foofoofoo", + "foo…", + 4, + 0, + }, + { + "foo", + "foo ", + 10, + 0, + }, + { + "foo", + " f…", + 4, + 2, + }, + { + "foofoofoo", + " foo…", + 6, + 2, + }, + { + "foo", + " foo ", + 10, + 2, + }, + } + + for i, tc := range cases { + result := LeftPadMaxLine(tc.input, tc.maxValueLength, tc.leftPad) + if result != tc.output { + t.Fatalf("Case %d Input:\n\n`%s`\n\nExpected Output:\n\n`%s`\n\nActual Output:\n\n`%s`", + i, tc.input, tc.output, result) + } + } +}