...
1 package wordwrap
2
3 import (
4 "bytes"
5 "unicode"
6 )
7
8 const nbsp = 0xA0
9
10
11
12
13
14
15
16 func WrapString(s string, lim uint) string {
17
18 init := make([]byte, 0, len(s))
19 buf := bytes.NewBuffer(init)
20
21 var current uint
22 var wordBuf, spaceBuf bytes.Buffer
23 var wordBufLen, spaceBufLen uint
24
25 for _, char := range s {
26 if char == '\n' {
27 if wordBuf.Len() == 0 {
28 if current+spaceBufLen > lim {
29 current = 0
30 } else {
31 current += spaceBufLen
32 spaceBuf.WriteTo(buf)
33 }
34 spaceBuf.Reset()
35 spaceBufLen = 0
36 } else {
37 current += spaceBufLen + wordBufLen
38 spaceBuf.WriteTo(buf)
39 spaceBuf.Reset()
40 spaceBufLen = 0
41 wordBuf.WriteTo(buf)
42 wordBuf.Reset()
43 wordBufLen = 0
44 }
45 buf.WriteRune(char)
46 current = 0
47 } else if unicode.IsSpace(char) && char != nbsp {
48 if spaceBuf.Len() == 0 || wordBuf.Len() > 0 {
49 current += spaceBufLen + wordBufLen
50 spaceBuf.WriteTo(buf)
51 spaceBuf.Reset()
52 spaceBufLen = 0
53 wordBuf.WriteTo(buf)
54 wordBuf.Reset()
55 wordBufLen = 0
56 }
57
58 spaceBuf.WriteRune(char)
59 spaceBufLen++
60 } else {
61 wordBuf.WriteRune(char)
62 wordBufLen++
63
64 if current+wordBufLen+spaceBufLen > lim && wordBufLen < lim {
65 buf.WriteRune('\n')
66 current = 0
67 spaceBuf.Reset()
68 spaceBufLen = 0
69 }
70 }
71 }
72
73 if wordBuf.Len() == 0 {
74 if current+spaceBufLen <= lim {
75 spaceBuf.WriteTo(buf)
76 }
77 } else {
78 spaceBuf.WriteTo(buf)
79 wordBuf.WriteTo(buf)
80 }
81
82 return buf.String()
83 }
84
View as plain text