main
1package lipgloss
2
3import (
4 "strings"
5
6 "github.com/charmbracelet/x/ansi"
7 "github.com/muesli/termenv"
8)
9
10// Perform text alignment. If the string is multi-lined, we also make all lines
11// the same width by padding them with spaces. If a termenv style is passed,
12// use that to style the spaces added.
13func alignTextHorizontal(str string, pos Position, width int, style *termenv.Style) string {
14 lines, widestLine := getLines(str)
15 var b strings.Builder
16
17 for i, l := range lines {
18 lineWidth := ansi.StringWidth(l)
19
20 shortAmount := widestLine - lineWidth // difference from the widest line
21 shortAmount += max(0, width-(shortAmount+lineWidth)) // difference from the total width, if set
22
23 if shortAmount > 0 {
24 switch pos { //nolint:exhaustive
25 case Right:
26 s := strings.Repeat(" ", shortAmount)
27 if style != nil {
28 s = style.Styled(s)
29 }
30 l = s + l
31 case Center:
32 // Note: remainder goes on the right.
33 left := shortAmount / 2 //nolint:mnd
34 right := left + shortAmount%2 //nolint:mnd
35
36 leftSpaces := strings.Repeat(" ", left)
37 rightSpaces := strings.Repeat(" ", right)
38
39 if style != nil {
40 leftSpaces = style.Styled(leftSpaces)
41 rightSpaces = style.Styled(rightSpaces)
42 }
43 l = leftSpaces + l + rightSpaces
44 default: // Left
45 s := strings.Repeat(" ", shortAmount)
46 if style != nil {
47 s = style.Styled(s)
48 }
49 l += s
50 }
51 }
52
53 b.WriteString(l)
54 if i < len(lines)-1 {
55 b.WriteRune('\n')
56 }
57 }
58
59 return b.String()
60}
61
62func alignTextVertical(str string, pos Position, height int, _ *termenv.Style) string {
63 strHeight := strings.Count(str, "\n") + 1
64 if height < strHeight {
65 return str
66 }
67
68 switch pos {
69 case Top:
70 return str + strings.Repeat("\n", height-strHeight)
71 case Center:
72 topPadding, bottomPadding := (height-strHeight)/2, (height-strHeight)/2 //nolint:mnd
73 if strHeight+topPadding+bottomPadding > height {
74 topPadding--
75 } else if strHeight+topPadding+bottomPadding < height {
76 bottomPadding++
77 }
78 return strings.Repeat("\n", topPadding) + str + strings.Repeat("\n", bottomPadding)
79 case Bottom:
80 return strings.Repeat("\n", height-strHeight) + str
81 }
82 return str
83}