110 lines
1.8 KiB
Go
110 lines
1.8 KiB
Go
package text
|
|
|
|
import (
|
|
"strings"
|
|
"unicode/utf8"
|
|
)
|
|
|
|
func CleanMOTD(s string) string {
|
|
if s == "" {
|
|
return ""
|
|
}
|
|
|
|
s = strings.ReplaceAll(s, "\r\n", "\n")
|
|
s = strings.ReplaceAll(s, "\r", "\n")
|
|
s = stripColorCodes(s)
|
|
s = stripControl(s)
|
|
s = normalizeSpacesKeepNewlines(s)
|
|
return strings.TrimSpace(s)
|
|
}
|
|
|
|
func stripColorCodes(s string) string {
|
|
var b strings.Builder
|
|
b.Grow(len(s))
|
|
|
|
for i := 0; i < len(s); {
|
|
r, size := utf8.DecodeRuneInString(s[i:])
|
|
if r == utf8.RuneError && size == 1 {
|
|
i++
|
|
continue
|
|
}
|
|
|
|
if r == '§' || r == '&' {
|
|
if i+2 < len(s) && (s[i] == '§' || s[i] == '&') && (s[i+1] == 'x' || s[i+1] == 'X') {
|
|
j := i + 2
|
|
ok := true
|
|
for k := 0; k < 6; k++ {
|
|
if j+2 >= len(s) {
|
|
ok = false
|
|
break
|
|
}
|
|
if s[j] != s[i] {
|
|
ok = false
|
|
break
|
|
}
|
|
c := s[j+1]
|
|
if !isHex(c) {
|
|
ok = false
|
|
break
|
|
}
|
|
j += 2
|
|
}
|
|
if ok {
|
|
i = j
|
|
continue
|
|
}
|
|
}
|
|
|
|
i += size
|
|
if i < len(s) {
|
|
_, nextSize := utf8.DecodeRuneInString(s[i:])
|
|
i += nextSize
|
|
}
|
|
continue
|
|
}
|
|
|
|
b.WriteRune(r)
|
|
i += size
|
|
}
|
|
|
|
return b.String()
|
|
}
|
|
|
|
func isHex(c byte) bool {
|
|
return (c >= '0' && c <= '9') ||
|
|
(c >= 'a' && c <= 'f') ||
|
|
(c >= 'A' && c <= 'F')
|
|
}
|
|
|
|
func stripControl(s string) string {
|
|
var b strings.Builder
|
|
b.Grow(len(s))
|
|
|
|
for _, r := range s {
|
|
if r == '\n' || r == '\t' {
|
|
b.WriteRune(r)
|
|
continue
|
|
}
|
|
if r < 32 || r == 127 {
|
|
continue
|
|
}
|
|
b.WriteRune(r)
|
|
}
|
|
return b.String()
|
|
}
|
|
|
|
func normalizeSpacesKeepNewlines(s string) string {
|
|
lines := strings.Split(s, "\n")
|
|
for i := range lines {
|
|
lines[i] = strings.Join(strings.Fields(lines[i]), " ")
|
|
}
|
|
|
|
out := strings.Join(lines, "\n")
|
|
out = strings.Trim(out, "\n")
|
|
|
|
for strings.Contains(out, "\n\n\n") {
|
|
out = strings.ReplaceAll(out, "\n\n\n", "\n\n")
|
|
}
|
|
return out
|
|
}
|