text.go

  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}