-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathexcerpt.go
More file actions
56 lines (48 loc) · 1.16 KB
/
excerpt.go
File metadata and controls
56 lines (48 loc) · 1.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package str
import "strings"
// Excerpt returns a snippet around the first occurrence of needle with the given radius.
// If needle is not found, an empty string is returned. If radius <= 0, a default of 100 is used.
// Omission is used at the start/end when text is trimmed (default "...").
// @group Snippet
//
// Example: excerpt with radius
//
// v := str.Of("This is my name").Excerpt("my", 3, "...")
// println(v.String())
// // #string ...is my na...
func (s String) Excerpt(needle string, radius int, omission string) String {
if needle == "" {
return String{s: ""}
}
if radius <= 0 {
radius = 100
}
if omission == "" {
omission = "..."
}
idx := strings.Index(s.s, needle)
if idx == -1 {
return String{s: ""}
}
runes := []rune(s.s)
needleRunes := []rune(needle)
startRune := len([]rune(s.s[:idx]))
endRune := startRune + len(needleRunes)
lo := startRune - radius
if lo < 0 {
lo = 0
}
hi := endRune + radius
if hi > len(runes) {
hi = len(runes)
}
var out strings.Builder
if lo > 0 {
out.WriteString(omission)
}
out.WriteString(string(runes[lo:hi]))
if hi < len(runes) {
out.WriteString(omission)
}
return String{s: out.String()}
}