aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/mitchellh/go-wordwrap/wordwrap.go
blob: ac67205bc2e5eb0f4ab0d57fd2477e003e5ed914 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package wordwrap

import (
    "bytes"
    "unicode"
)

// 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

    for _, char := range s {
        if char == '\n' {
            if wordBuf.Len() == 0 {
                if current+uint(spaceBuf.Len()) > lim {
                    current = 0
                } else {
                    current += uint(spaceBuf.Len())
                    spaceBuf.WriteTo(buf)
                }
                spaceBuf.Reset()
            } else {
                current += uint(spaceBuf.Len() + wordBuf.Len())
                spaceBuf.WriteTo(buf)
                spaceBuf.Reset()
                wordBuf.WriteTo(buf)
                wordBuf.Reset()
            }
            buf.WriteRune(char)
            current = 0
        } else if unicode.IsSpace(char) {
            if spaceBuf.Len() == 0 || wordBuf.Len() > 0 {
                current += uint(spaceBuf.Len() + wordBuf.Len())
                spaceBuf.WriteTo(buf)
                spaceBuf.Reset()
                wordBuf.WriteTo(buf)
                wordBuf.Reset()
            }

            spaceBuf.WriteRune(char)
        } else {

            wordBuf.WriteRune(char)

            if current+uint(spaceBuf.Len()+wordBuf.Len()) > lim && uint(wordBuf.Len()) < lim {
                buf.WriteRune('\n')
                current = 0
                spaceBuf.Reset()
            }
        }
    }

    if wordBuf.Len() == 0 {
        if current+uint(spaceBuf.Len()) <= lim {
            spaceBuf.WriteTo(buf)
        }
    } else {
        spaceBuf.WriteTo(buf)
        wordBuf.WriteTo(buf)
    }

    return buf.String()
}