github.com/gitbundle/modules@v0.0.0-20231025071548-85b91c5c3b01/util/truncate.go (about) 1 // Copyright 2023 The GitBundle Inc. All rights reserved. 2 // Copyright 2017 The Gitea Authors. All rights reserved. 3 // Use of this source code is governed by a MIT-style 4 // license that can be found in the LICENSE file. 5 6 package util 7 8 import "unicode/utf8" 9 10 // in UTF8 "…" is 3 bytes so doesn't really gain us anything... 11 const ( 12 utf8Ellipsis = "…" 13 asciiEllipsis = "..." 14 ) 15 16 // SplitStringAtByteN splits a string at byte n accounting for rune boundaries. (Combining characters are not accounted for.) 17 func SplitStringAtByteN(input string, n int) (left, right string) { 18 if len(input) <= n { 19 return input, "" 20 } 21 22 if !utf8.ValidString(input) { 23 if n-3 < 0 { 24 return input, "" 25 } 26 return input[:n-3] + asciiEllipsis, asciiEllipsis + input[n-3:] 27 } 28 29 end := 0 30 for end <= n-3 { 31 _, size := utf8.DecodeRuneInString(input[end:]) 32 if end+size > n-3 { 33 break 34 } 35 end += size 36 } 37 38 return input[:end] + utf8Ellipsis, utf8Ellipsis + input[end:] 39 } 40 41 // SplitStringAtRuneN splits a string at rune n accounting for rune boundaries. (Combining characters are not accounted for.) 42 func SplitStringAtRuneN(input string, n int) (left, right string) { 43 if !utf8.ValidString(input) { 44 if len(input) <= n || n-3 < 0 { 45 return input, "" 46 } 47 return input[:n-3] + asciiEllipsis, asciiEllipsis + input[n-3:] 48 } 49 50 if utf8.RuneCountInString(input) <= n { 51 return input, "" 52 } 53 54 count := 0 55 end := 0 56 for count < n-1 { 57 _, size := utf8.DecodeRuneInString(input[end:]) 58 end += size 59 count++ 60 } 61 62 return input[:end] + utf8Ellipsis, utf8Ellipsis + input[end:] 63 }