diff options
Diffstat (limited to 'modules/util/truncate.go')
-rw-r--r-- | modules/util/truncate.go | 43 |
1 files changed, 34 insertions, 9 deletions
diff --git a/modules/util/truncate.go b/modules/util/truncate.go index 8d0f630973..38c2c0d1d6 100644 --- a/modules/util/truncate.go +++ b/modules/util/truncate.go @@ -6,20 +6,23 @@ package util import "unicode/utf8" +// in UTF8 "…" is 3 bytes so doesn't really gain us anything... +const utf8Ellipsis = "…" +const asciiEllipsis = "..." + // SplitStringAtByteN splits a string at byte n accounting for rune boundaries. (Combining characters are not accounted for.) func SplitStringAtByteN(input string, n int) (left, right string) { if len(input) <= n { - left = input - return + return input, "" } if !utf8.ValidString(input) { - left = input[:n-3] + "..." - right = "..." + input[n-3:] - return + if n-3 < 0 { + return input, "" + } + return input[:n-3] + asciiEllipsis, asciiEllipsis + input[n-3:] } - // in UTF8 "…" is 3 bytes so doesn't really gain us anything... end := 0 for end <= n-3 { _, size := utf8.DecodeRuneInString(input[end:]) @@ -29,7 +32,29 @@ func SplitStringAtByteN(input string, n int) (left, right string) { end += size } - left = input[:end] + "…" - right = "…" + input[end:] - return + return input[:end] + utf8Ellipsis, utf8Ellipsis + input[end:] +} + +// SplitStringAtRuneN splits a string at rune n accounting for rune boundaries. (Combining characters are not accounted for.) +func SplitStringAtRuneN(input string, n int) (left, right string) { + if !utf8.ValidString(input) { + if len(input) <= n || n-3 < 0 { + return input, "" + } + return input[:n-3] + asciiEllipsis, asciiEllipsis + input[n-3:] + } + + if utf8.RuneCountInString(input) <= n { + return input, "" + } + + count := 0 + end := 0 + for count < n-1 { + _, size := utf8.DecodeRuneInString(input[end:]) + end += size + count++ + } + + return input[:end] + utf8Ellipsis, utf8Ellipsis + input[end:] } |