Skip to content

Commit 11ff934

Browse files
authored
Add CutLongWords option to Wrapper (#13)
1 parent e0dddf3 commit 11ff934

2 files changed

Lines changed: 61 additions & 7 deletions

File tree

wrapper.go

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,12 @@ type Wrapper struct {
4646
TrimInputSuffix string
4747

4848
// StripTrailingNewline can be set to true if you want the trailing
49-
// newline to be removed from the return vailue.
49+
// newline to be removed from the return value.
5050
// Default: false
5151
StripTrailingNewline bool
52+
53+
// CutLongWords will cause a hard-wrap in the middle of a word if the word's length exceeds the given limit.
54+
CutLongWords bool
5255
}
5356

5457
// NewWrapper returns a new instance of a Wrapper initialised with defaults.
@@ -98,15 +101,24 @@ func (w Wrapper) line(s string, limit int) string {
98101
// Find the index of the last breakpoint within the limit.
99102
i := strings.LastIndexAny(s[:limit+1], w.Breakpoints)
100103

101-
// Can't wrap within the limit, wrap at the next breakpoint instead.
104+
breakpointWidth := 1
105+
106+
// Can't wrap within the limit
102107
if i < 0 {
103-
i = strings.IndexAny(s, w.Breakpoints)
104-
// Nothing left to do!
105-
if i < 0 {
106-
return w.OutputLinePrefix + s + w.OutputLineSuffix
108+
if w.CutLongWords {
109+
// wrap at the limit
110+
i = limit
111+
breakpointWidth = 0
112+
} else {
113+
// wrap at the next breakpoint instead
114+
i = strings.IndexAny(s, w.Breakpoints)
115+
// Nothing left to do!
116+
if i < 0 {
117+
return w.OutputLinePrefix + s + w.OutputLineSuffix
118+
}
107119
}
108120
}
109121

110122
// Recurse until we have nothing left to do.
111-
return w.OutputLinePrefix + s[:i] + w.OutputLineSuffix + w.Newline + w.line(s[i+1:], limit)
123+
return w.OutputLinePrefix + s[:i] + w.OutputLineSuffix + w.Newline + w.line(s[i+breakpointWidth:], limit)
112124
}

wrapper_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package wrap_test
22

33
import (
4+
"strconv"
45
"strings"
56
"testing"
67
"unicode/utf8"
@@ -63,3 +64,44 @@ func TestWrapper_Wrap(t *testing.T) {
6364

6465
}
6566
}
67+
68+
func TestWrapper_Wrap_CutLongWords(t *testing.T) {
69+
const limit = 8
70+
71+
tests := []struct {
72+
input string
73+
expected string
74+
}{
75+
{
76+
input: "A short woooord",
77+
expected: `A short
78+
woooord`,
79+
},
80+
{
81+
input: "A perfect wooooord",
82+
expected: `A
83+
perfect
84+
wooooord`,
85+
},
86+
{
87+
input: "A long wooooooooooooord",
88+
expected: `A long
89+
wooooooo
90+
oooooord`,
91+
},
92+
}
93+
94+
for i, test := range tests {
95+
t.Run(strconv.FormatInt(int64(i), 10), func(t *testing.T) {
96+
w := wrap.NewWrapper()
97+
w.CutLongWords = true
98+
w.StripTrailingNewline = true
99+
100+
actual := w.Wrap(test.input, limit)
101+
102+
if actual != test.expected {
103+
t.Errorf("expected %q but got %q", test.expected, actual)
104+
}
105+
})
106+
}
107+
}

0 commit comments

Comments
 (0)