zakirullin--files.md
177 行
4.0 KiB
Go
177 行
4.0 KiB
Go
package txt
|
|
|
|
import (
|
|
"fmt"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
"unicode"
|
|
)
|
|
|
|
func I64(i int64) string {
|
|
return strconv.FormatInt(i, 10)
|
|
}
|
|
|
|
func Ucfirst(str string) string {
|
|
if len(str) == 0 {
|
|
return str
|
|
}
|
|
r := []rune(str)
|
|
|
|
return string(unicode.ToUpper(r[0])) + string(r[1:])
|
|
}
|
|
|
|
func Lcfirst(str string) string {
|
|
if len(str) == 0 {
|
|
return str
|
|
}
|
|
r := []rune(str)
|
|
|
|
return string(unicode.ToLower(r[0])) + string(r[1:])
|
|
}
|
|
|
|
// Substr respects unicode codepoints, but not multi-unicode-codepoint aware.
|
|
// Specifying skintone or gender of an emoji will count as 2 codepoints:
|
|
// https://unicode.org/emoji/charts/full-emoji-modifiers.html
|
|
func Substr(input string, start int, length int) string {
|
|
if start < 0 || length < 0 {
|
|
return ""
|
|
}
|
|
|
|
asRunes := []rune(input)
|
|
if start >= len(asRunes) {
|
|
return ""
|
|
}
|
|
|
|
if start+length > len(asRunes) {
|
|
length = len(asRunes) - start
|
|
}
|
|
|
|
return string(asRunes[start : start+length])
|
|
}
|
|
|
|
func Emoji(emoji, str string) string {
|
|
if emoji == "" {
|
|
return str
|
|
}
|
|
|
|
// Custom for George :)
|
|
str = strings.TrimPrefix(str, "WRK ")
|
|
str = strings.TrimPrefix(str, "UA ")
|
|
str = strings.TrimPrefix(str, "US ")
|
|
str = strings.TrimPrefix(str, "CY ")
|
|
str = strings.TrimPrefix(str, "HOB ")
|
|
str = strings.TrimPrefix(str, "SRB ")
|
|
str = strings.TrimPrefix(str, "PL ")
|
|
|
|
return fmt.Sprintf("%s %s", emoji, str)
|
|
}
|
|
|
|
func NormNewLines(text string) string {
|
|
text = strings.Replace(text, "\r\n", "\n", -1) // replace Windows line endings
|
|
return strings.Replace(text, "\r", "\n", -1) // replace remaining Mac line endings
|
|
}
|
|
|
|
func IsMultiline(text string) bool {
|
|
text = NormNewLines(text)
|
|
lines := strings.Split(text, "\n")
|
|
return len(lines) > 1
|
|
}
|
|
|
|
// SplitTextIntoChunks splits the text into chunks less than or equal to maxLen.
|
|
// The chunks are split at the last new line or space before maxLen (inclusive).
|
|
// Spaces-like characters are trimmed out from the beginning and the end of each chunk.
|
|
func SplitTextIntoChunks(text string, maxLen int) []string {
|
|
text = strings.TrimSpace(text)
|
|
|
|
if maxLen <= 0 {
|
|
return []string{text}
|
|
}
|
|
|
|
var chunks []string
|
|
runes := []rune(text) // Convert the string to runes
|
|
|
|
for len(runes) > maxLen {
|
|
// Find the split index
|
|
splitIndex := -1
|
|
subStr := runes[:maxLen]
|
|
// Find the last newline in the substring
|
|
for i := len(subStr) - 1; i >= 0; i-- {
|
|
if subStr[i] == '\n' {
|
|
splitIndex = i
|
|
break
|
|
}
|
|
}
|
|
if splitIndex == -1 {
|
|
// No newline found, find the last space
|
|
for i := len(subStr) - 1; i >= 0; i-- {
|
|
if subStr[i] == ' ' {
|
|
splitIndex = i
|
|
break
|
|
}
|
|
}
|
|
}
|
|
if splitIndex == -1 {
|
|
// No space found either, split at maxLen
|
|
splitIndex = maxLen
|
|
}
|
|
|
|
trimmedSubStr := strings.TrimSpace(string(runes[:splitIndex]))
|
|
if len(trimmedSubStr) > 0 {
|
|
chunks = append(chunks, trimmedSubStr)
|
|
}
|
|
runes = runes[splitIndex:]
|
|
runes = []rune(strings.TrimSpace(string(runes)))
|
|
}
|
|
|
|
// Add the remaining runes as the final chunk
|
|
chunks = append(chunks, strings.TrimSpace(string(runes)))
|
|
|
|
return chunks
|
|
}
|
|
|
|
func FirstWord(str string) string {
|
|
str = strings.TrimSpace(str)
|
|
re := regexp.MustCompile(`^[^\s\p{P}]+`)
|
|
return re.FindString(str)
|
|
}
|
|
|
|
func EscapeHTML(str string) string {
|
|
// HTML escaping
|
|
htmlEscaper := strings.NewReplacer(
|
|
"&", "&",
|
|
"<", "<",
|
|
">", ">",
|
|
)
|
|
|
|
return htmlEscaper.Replace(str)
|
|
}
|
|
|
|
func StripHTMLTags(str string) string {
|
|
re := regexp.MustCompile(`<[^>]*>`)
|
|
return re.ReplaceAllString(str, "")
|
|
}
|
|
|
|
func ReplaceWithPlaceholders(str, regex, placeholder string) (string, map[string]string) {
|
|
re := regexp.MustCompile(regex)
|
|
placeholders := make(map[string]string)
|
|
counter := 0
|
|
|
|
// Function to replace each match with a placeholder
|
|
res := re.ReplaceAllStringFunc(str, func(match string) string {
|
|
p := fmt.Sprintf("#%s%d#", placeholder, counter)
|
|
placeholders[p] = match
|
|
counter++
|
|
return p
|
|
})
|
|
|
|
return res, placeholders
|
|
}
|
|
|
|
func RestoreFromPlaceholders(str string, placeholders map[string]string) string {
|
|
for placeholder, original := range placeholders {
|
|
str = strings.ReplaceAll(str, placeholder, original)
|
|
}
|
|
return str
|
|
}
|