1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- package wordwrap
- import (
- "bytes"
- "unicode"
- )
- const nbsp = 0xA0
- // WrapString wraps the given string within lim width in characters.
- //
- // Wrapping is currently naive and only happens at white-space. A future
- // version of the library will implement smarter wrapping. This means that
- // pathological cases can dramatically reach past the limit, such as a very
- // long word.
- func WrapString(s string, lim uint) string {
- // Initialize a buffer with a slightly larger size to account for breaks
- init := make([]byte, 0, len(s))
- buf := bytes.NewBuffer(init)
- var current uint
- var wordBuf, spaceBuf bytes.Buffer
- var wordBufLen, spaceBufLen uint
- for _, char := range s {
- if char == '\n' {
- if wordBuf.Len() == 0 {
- if current+spaceBufLen > lim {
- current = 0
- } else {
- current += spaceBufLen
- spaceBuf.WriteTo(buf)
- }
- spaceBuf.Reset()
- spaceBufLen = 0
- } else {
- current += spaceBufLen + wordBufLen
- spaceBuf.WriteTo(buf)
- spaceBuf.Reset()
- spaceBufLen = 0
- wordBuf.WriteTo(buf)
- wordBuf.Reset()
- wordBufLen = 0
- }
- buf.WriteRune(char)
- current = 0
- } else if unicode.IsSpace(char) && char != nbsp {
- if spaceBuf.Len() == 0 || wordBuf.Len() > 0 {
- current += spaceBufLen + wordBufLen
- spaceBuf.WriteTo(buf)
- spaceBuf.Reset()
- spaceBufLen = 0
- wordBuf.WriteTo(buf)
- wordBuf.Reset()
- wordBufLen = 0
- }
- spaceBuf.WriteRune(char)
- spaceBufLen++
- } else {
- wordBuf.WriteRune(char)
- wordBufLen++
- if current+wordBufLen+spaceBufLen > lim && wordBufLen < lim {
- buf.WriteRune('\n')
- current = 0
- spaceBuf.Reset()
- spaceBufLen = 0
- }
- }
- }
- if wordBuf.Len() == 0 {
- if current+spaceBufLen <= lim {
- spaceBuf.WriteTo(buf)
- }
- } else {
- spaceBuf.WriteTo(buf)
- wordBuf.WriteTo(buf)
- }
- return buf.String()
- }
|