...
1 package text
2
3 import (
4 "fmt"
5 "strconv"
6 "strings"
7 "unicode/utf8"
8 )
9
10
11 type Align int
12
13
14 const (
15 AlignDefault Align = iota
16 AlignLeft
17 AlignCenter
18 AlignJustify
19 AlignRight
20 )
21
22
23
24
25
26
27
28 func (a Align) Apply(text string, maxLength int) string {
29 text = a.trimString(text)
30 sLen := utf8.RuneCountInString(text)
31 sLenWoE := RuneWidthWithoutEscSequences(text)
32 numEscChars := sLen - sLenWoE
33
34
35 switch a {
36 case AlignDefault, AlignLeft:
37 return fmt.Sprintf("%-"+strconv.Itoa(maxLength+numEscChars)+"s", text)
38 case AlignCenter:
39 if sLenWoE < maxLength {
40
41 return fmt.Sprintf("%"+strconv.Itoa(maxLength+numEscChars)+"s",
42 text+strings.Repeat(" ", int((maxLength-sLenWoE)/2)))
43 }
44 case AlignJustify:
45 return a.justifyText(text, sLenWoE, maxLength)
46 }
47 return fmt.Sprintf("%"+strconv.Itoa(maxLength+numEscChars)+"s", text)
48 }
49
50
51 func (a Align) HTMLProperty() string {
52 switch a {
53 case AlignLeft:
54 return "align=\"left\""
55 case AlignCenter:
56 return "align=\"center\""
57 case AlignJustify:
58 return "align=\"justify\""
59 case AlignRight:
60 return "align=\"right\""
61 default:
62 return ""
63 }
64 }
65
66
67 func (a Align) MarkdownProperty() string {
68 switch a {
69 case AlignLeft:
70 return ":--- "
71 case AlignCenter:
72 return ":---:"
73 case AlignRight:
74 return " ---:"
75 default:
76 return " --- "
77 }
78 }
79
80 func (a Align) justifyText(text string, textLength int, maxLength int) string {
81
82 wordsUnfiltered := strings.Split(text, " ")
83 words := Filter(wordsUnfiltered, func(item string) bool {
84 return item != ""
85 })
86
87 if len(words) == 0 {
88 return strings.Repeat(" ", maxLength)
89 }
90
91 numSpacesNeeded := maxLength - textLength + strings.Count(text, " ")
92 numSpacesNeededBetweenWords := 0
93 if len(words) > 1 {
94 numSpacesNeededBetweenWords = numSpacesNeeded / (len(words) - 1)
95 }
96
97 var outText strings.Builder
98 outText.Grow(maxLength)
99 for idx, word := range words {
100 if idx > 0 {
101
102 if idx == len(words)-1 {
103
104 outText.WriteString(strings.Repeat(" ", numSpacesNeeded))
105 numSpacesNeeded = 0
106 } else {
107
108 outText.WriteString(strings.Repeat(" ", numSpacesNeededBetweenWords))
109
110 numSpacesNeeded -= numSpacesNeededBetweenWords
111 }
112 }
113 outText.WriteString(word)
114 if idx == len(words)-1 && numSpacesNeeded > 0 {
115 outText.WriteString(strings.Repeat(" ", numSpacesNeeded))
116 }
117 }
118 return outText.String()
119 }
120
121 func (a Align) trimString(text string) string {
122 switch a {
123 case AlignDefault, AlignLeft:
124 if strings.HasSuffix(text, " ") {
125 return strings.TrimRight(text, " ")
126 }
127 case AlignRight:
128 if strings.HasPrefix(text, " ") {
129 return strings.TrimLeft(text, " ")
130 }
131 default:
132 if strings.HasPrefix(text, " ") || strings.HasSuffix(text, " ") {
133 return strings.Trim(text, " ")
134 }
135 }
136 return text
137 }
138
View as plain text