Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

text.go 2.2KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. // Copyright (c) 2017 Daniel Oaks <daniel@danieloaks.net>
  2. // released under the MIT license
  3. package utils
  4. import "bytes"
  5. import "time"
  6. // WordWrap wraps the given text into a series of lines that don't exceed lineWidth characters.
  7. func WordWrap(text string, lineWidth int) []string {
  8. var lines []string
  9. var cacheLine, cacheWord bytes.Buffer
  10. for _, char := range text {
  11. if char == '\r' {
  12. continue
  13. } else if char == '\n' {
  14. cacheLine.Write(cacheWord.Bytes())
  15. lines = append(lines, cacheLine.String())
  16. cacheWord.Reset()
  17. cacheLine.Reset()
  18. } else if (char == ' ' || char == '-') && cacheLine.Len()+cacheWord.Len()+1 < lineWidth {
  19. // natural word boundary
  20. cacheLine.Write(cacheWord.Bytes())
  21. cacheLine.WriteRune(char)
  22. cacheWord.Reset()
  23. } else if lineWidth <= cacheLine.Len()+cacheWord.Len()+1 {
  24. // time to wrap to next line
  25. if cacheLine.Len() < (lineWidth / 2) {
  26. // this word takes up more than half a line... just split in the middle of the word
  27. cacheLine.Write(cacheWord.Bytes())
  28. cacheLine.WriteRune(char)
  29. cacheWord.Reset()
  30. } else {
  31. cacheWord.WriteRune(char)
  32. }
  33. lines = append(lines, cacheLine.String())
  34. cacheLine.Reset()
  35. } else {
  36. // normal character
  37. cacheWord.WriteRune(char)
  38. }
  39. }
  40. if 0 < cacheWord.Len() {
  41. cacheLine.Write(cacheWord.Bytes())
  42. }
  43. if 0 < cacheLine.Len() {
  44. lines = append(lines, cacheLine.String())
  45. }
  46. return lines
  47. }
  48. type MessagePair struct {
  49. Message string
  50. Msgid string
  51. }
  52. // SplitMessage represents a message that's been split for sending.
  53. type SplitMessage struct {
  54. MessagePair
  55. Wrapped []MessagePair // if this is nil, `Message` didn't need wrapping and can be sent to anyone
  56. Time time.Time
  57. }
  58. const defaultLineWidth = 400
  59. func MakeSplitMessage(original string, origIs512 bool) (result SplitMessage) {
  60. result.Message = original
  61. result.Msgid = GenerateSecretToken()
  62. result.Time = time.Now().UTC()
  63. if !origIs512 && defaultLineWidth < len(original) {
  64. wrapped := WordWrap(original, defaultLineWidth)
  65. result.Wrapped = make([]MessagePair, len(wrapped))
  66. for i, wrappedMessage := range wrapped {
  67. result.Wrapped[i] = MessagePair{
  68. Message: wrappedMessage,
  69. Msgid: GenerateSecretToken(),
  70. }
  71. }
  72. }
  73. return
  74. }