extract.go
TLDR
This file contains a Go package notifymentions
that provides functionality for extracting a subset of text based on mentions within the text.
Methods
extractText
This method takes in a string s
, a mention string, and a set of limits. It finds the position of the mention within the text and returns a subset of the text based on the number of lines preceding and following the mention, as well as the maximum number of characters before and after the mention.
safeConcat
This method takes in an array of strings lines
, a start index, and an end index. It concatenates a subset of the lines delimited by the start and end indices, handling empty lines properly.
safeSubstr
This method takes in a string s
, a start index, and an end index. It returns a substring of s
delimited by the start and end indices.
min
This method takes in two integers a
and b
and returns the minimum value between them.
max
This method takes in two integers a
and b
and returns the maximum value between them.
Functions
newLimits
This function returns a limits
struct with default values for the number of prefix lines, maximum prefix characters, suffix lines, and maximum suffix characters.
Constants
-
defPrefixLines
: The default number of lines preceding the mention to include in the extracted text. -
defPrefixMaxChars
: The default maximum number of characters before the mention to include in the extracted text. -
defSuffixLines
: The default number of lines following the mention to include in the extracted text. -
defSuffixMaxChars
: The default maximum number of characters after the mention to include in the extracted text.
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
package notifymentions
import "strings"
const (
defPrefixLines = 2
defPrefixMaxChars = 100
defSuffixLines = 2
defSuffixMaxChars = 100
)
type limits struct {
prefixLines int
prefixMaxChars int
suffixLines int
suffixMaxChars int
}
func newLimits() limits {
return limits{
prefixLines: defPrefixLines,
prefixMaxChars: defPrefixMaxChars,
suffixLines: defSuffixLines,
suffixMaxChars: defSuffixMaxChars,
}
}
// extractText returns all or a subset of the input string, such that
// no more than `prefixLines` lines preceding the mention and `suffixLines`
// lines after the mention are returned, and no more than approx
// prefixMaxChars+suffixMaxChars are returned.
func extractText(s string, mention string, limits limits) string {
if !strings.HasPrefix(mention, "@") {
mention = "@" + mention
}
lines := strings.Split(s, "\n")
// find first line with mention
found := -1
for i, l := range lines {
if strings.Contains(l, mention) {
found = i
break
}
}
if found == -1 {
return ""
}
prefix := safeConcat(lines, found-limits.prefixLines, found)
suffix := safeConcat(lines, found+1, found+limits.suffixLines+1)
combined := strings.TrimSpace(strings.Join([]string{prefix, lines[found], suffix}, "\n"))
// find mention position within
pos := strings.Index(combined, mention)
pos = max(pos, 0)
return safeSubstr(combined, pos-limits.prefixMaxChars, pos+limits.suffixMaxChars)
}
func safeConcat(lines []string, start int, end int) string {
count := len(lines)
start = min(max(start, 0), count)
end = min(max(end, start), count)
var sb strings.Builder
for i := start; i < end; i++ {
if lines[i] != "" {
sb.WriteString(lines[i])
sb.WriteByte('\n')
}
}
return strings.TrimSpace(sb.String())
}
func safeSubstr(s string, start int, end int) string {
count := len(s)
start = min(max(start, 0), count)
end = min(max(end, start), count)
return s[start:end]
}
func min(a int, b int) int {
if a < b {
return a
}
return b
}
func max(a int, b int) int {
if a > b {
return a
}
return b
}