diff --git a/convenience.go b/convenience.go index 2322c27..42e0a85 100644 --- a/convenience.go +++ b/convenience.go @@ -20,20 +20,35 @@ package bunt -import colorful "github.com/lucasb-eyer/go-colorful" +import ( + "regexp" + "strings" + "unicode/utf8" + + colorful "github.com/lucasb-eyer/go-colorful" +) // StyleOption defines style option for strings type StyleOption func(*String) // PlainTextLength returns the length of the input text without any escape -// sequences. The function will panic in the unlikely case of a parse issue. +// sequences. func PlainTextLength(text string) int { - result, err := ParseString(text) - if err != nil { - panic(err) + return utf8.RuneCountInString(RemoveAllEscapeSequences(text)) +} + +// RemoveAllEscapeSequences return the input string with all escape sequences +// removed. +func RemoveAllEscapeSequences(input string) string { + escapeSeqFinderRegExp := regexp.MustCompile(`\x1b\[([\d;]*)m`) + + for loc := escapeSeqFinderRegExp.FindStringIndex(input); loc != nil; loc = escapeSeqFinderRegExp.FindStringIndex(input) { + start := loc[0] + end := loc[1] + input = strings.Replace(input, input[start:end], "", -1) } - return len(*result) + return input } // Substring returns a substring of a text that may contains escape sequences. diff --git a/convenience_test.go b/convenience_test.go index eee1258..adee7b4 100644 --- a/convenience_test.go +++ b/convenience_test.go @@ -54,6 +54,10 @@ var _ = Describe("convenience functions", func() { It("should return the right size when used on strings created by the bunt package", func() { Expect(PlainTextLength(Sprintf("*This* text is too long"))).To(BeEquivalentTo(len(Sprintf("This text is too long")))) }) + + It("should return the correct length based on the rune count", func() { + Expect(PlainTextLength("fünf")).To(BeEquivalentTo(4)) + }) }) Context("style function", func() {