wordwrap.go 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. package wordwrap
  2. import (
  3. "bytes"
  4. "unicode"
  5. )
  6. // WrapString wraps the given string within lim width in characters.
  7. //
  8. // Wrapping is currently naive and only happens at white-space. A future
  9. // version of the library will implement smarter wrapping. This means that
  10. // pathological cases can dramatically reach past the limit, such as a very
  11. // long word.
  12. func WrapString(s string, lim uint) string {
  13. // Initialize a buffer with a slightly larger size to account for breaks
  14. init := make([]byte, 0, len(s))
  15. buf := bytes.NewBuffer(init)
  16. var current uint
  17. var wordBuf, spaceBuf bytes.Buffer
  18. for _, char := range s {
  19. if char == '\n' {
  20. if wordBuf.Len() == 0 {
  21. if current+uint(spaceBuf.Len()) > lim {
  22. current = 0
  23. } else {
  24. current += uint(spaceBuf.Len())
  25. spaceBuf.WriteTo(buf)
  26. }
  27. spaceBuf.Reset()
  28. } else {
  29. current += uint(spaceBuf.Len() + wordBuf.Len())
  30. spaceBuf.WriteTo(buf)
  31. spaceBuf.Reset()
  32. wordBuf.WriteTo(buf)
  33. wordBuf.Reset()
  34. }
  35. buf.WriteRune(char)
  36. current = 0
  37. } else if unicode.IsSpace(char) {
  38. if spaceBuf.Len() == 0 || wordBuf.Len() > 0 {
  39. current += uint(spaceBuf.Len() + wordBuf.Len())
  40. spaceBuf.WriteTo(buf)
  41. spaceBuf.Reset()
  42. wordBuf.WriteTo(buf)
  43. wordBuf.Reset()
  44. }
  45. spaceBuf.WriteRune(char)
  46. } else {
  47. wordBuf.WriteRune(char)
  48. if current+uint(spaceBuf.Len()+wordBuf.Len()) > lim && uint(wordBuf.Len()) < lim {
  49. buf.WriteRune('\n')
  50. current = 0
  51. spaceBuf.Reset()
  52. }
  53. }
  54. }
  55. if wordBuf.Len() == 0 {
  56. if current+uint(spaceBuf.Len()) <= lim {
  57. spaceBuf.WriteTo(buf)
  58. }
  59. } else {
  60. spaceBuf.WriteTo(buf)
  61. wordBuf.WriteTo(buf)
  62. }
  63. return buf.String()
  64. }