1package util
2
3import (
4 "bytes"
5 "strings"
6)
7
8func WordWrap(text string, lineWidth int) (string, int) {
9 words := strings.Fields(strings.TrimSpace(text))
10 if len(words) == 0 {
11 return "", 1
12 }
13 lines := 1
14 wrapped := words[0]
15 spaceLeft := lineWidth - len(wrapped)
16 for _, word := range words[1:] {
17 if len(word)+1 > spaceLeft {
18 wrapped += "\n" + word
19 spaceLeft = lineWidth - len(word)
20 lines++
21 } else {
22 wrapped += " " + word
23 spaceLeft -= 1 + len(word)
24 }
25 }
26
27 return wrapped, lines
28}
29
30func TextWrap(text string, lineWidth int) (string, int) {
31 var textBuffer bytes.Buffer
32 var lineBuffer bytes.Buffer
33 nbLine := 1
34 firstLine := true
35
36 // tabs are formatted as 4 spaces
37 text = strings.Replace(text, "\t", " ", 4)
38
39 for _, line := range strings.Split(text, "\n") {
40 spaceLeft := lineWidth
41
42 if !firstLine {
43 textBuffer.WriteString("\n")
44 nbLine++
45 }
46
47 firstWord := true
48
49 for _, word := range strings.Split(line, " ") {
50 if spaceLeft > len(word) {
51 if !firstWord {
52 lineBuffer.WriteString(" ")
53 spaceLeft -= 1
54 }
55 lineBuffer.WriteString(word)
56 spaceLeft -= len(word)
57 firstWord = false
58 } else {
59 if len(word) > lineWidth {
60 for len(word) > 0 {
61 l := minInt(spaceLeft, len(word))
62 part := word[:l]
63 word = word[l:]
64
65 lineBuffer.WriteString(part)
66 textBuffer.Write(lineBuffer.Bytes())
67 lineBuffer.Reset()
68
69 if len(word) > 0 {
70 textBuffer.WriteString("\n")
71 nbLine++
72 }
73
74 spaceLeft = lineWidth
75 }
76 } else {
77 textBuffer.WriteString(strings.TrimRight(lineBuffer.String(), " "))
78 textBuffer.WriteString("\n")
79 lineBuffer.Reset()
80 lineBuffer.WriteString(word)
81 firstWord = false
82 spaceLeft = lineWidth - len(word)
83 nbLine++
84 }
85 }
86 }
87 textBuffer.WriteString(strings.TrimRight(lineBuffer.String(), " "))
88 lineBuffer.Reset()
89 firstLine = false
90 }
91
92 return textBuffer.String(), nbLine
93}
94
95func minInt(a, b int) int {
96 if a > b {
97 return b
98 }
99 return a
100}