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