-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcenter.go
113 lines (104 loc) · 2.18 KB
/
center.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package strutils
// https://github.com/NiclasOlofsson/MiNET/blob/master/src/MiNET/MiNET/Utils/TextUtils.cs
import (
"math"
"strings"
)
const (
lineLength = 30
charWidth = 6
spaceChar = ' '
)
var charWidths = map[string]int{
" ": 4,
"!": 2,
"\"": 5,
"'": 3,
"(": 5,
")": 5,
"*": 5,
",": 2,
".": 2,
":": 2,
";": 2,
"<": 5,
">": 5,
"@": 7,
"I": 4,
"[": 4,
"]": 4,
"f": 5,
"i": 2,
"k": 5,
"l": 3,
"t": 4,
"|": 2,
"~": 7,
"█": 9,
"░": 8,
"▒": 9,
"▓": 9,
"▌": 5,
"─": 9,
}
// CenterLine centers a string on a regular line in minecraft.
func CenterLine(input string) string {
return Center(input, lineLength*charWidth, false)
}
// Center centers a [multiline] string with a given maximum length. addRightPadding can be set to true
// to add padding to the right of the centered lines.
func Center(input string, maxLength int, addRightPadding bool) string {
lines := strings.Split(input, "\n")
for _, line := range lines {
l := getPixelLength(line)
if l > maxLength {
maxLength = l
}
}
result := strings.Builder{}
spaceWidth := 4
for _, line := range lines {
length := math.Max(float64(maxLength-getPixelLength(line)), 0)
padding := int(math.Round(float64(int(length) / (2 * spaceWidth))))
result.WriteString(strings.Repeat(string(spaceChar), padding) + line)
if addRightPadding {
paddingRight := int(math.Floor(float64(int(length) / (2 * spaceWidth))))
result.WriteString(strings.Repeat(string(spaceChar), paddingRight))
}
result.WriteString("\n")
}
return strings.TrimRight(result.String(), "\n")
}
// getCharWidth returns the width of a character.
func getCharWidth(s string) int {
c, ok := charWidths[s]
if !ok {
return charWidth
}
return c
}
// getPixelLength returns the total pixel length of a string.
func getPixelLength(line string) int {
length := 0
for _, c := range Clean(line) {
length += getCharWidth(string(c))
}
// +1 for each bold character
split := strings.Split(line, "§")
bold := false
for _, s := range split {
if len(s) == 0 {
continue
}
switch s[0] {
case 'l':
bold = true
case 'r':
bold = false
}
if bold {
length += len(s) - 1
}
}
return length
}