main
Raw Download raw file
 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}