get.go

  1package lipgloss
  2
  3import (
  4	"image/color"
  5	"strings"
  6
  7	"github.com/charmbracelet/x/ansi"
  8)
  9
 10// GetBold returns the style's bold value. If no value is set false is returned.
 11func (s Style) GetBold() bool {
 12	return s.getAsBool(boldKey, false)
 13}
 14
 15// GetItalic returns the style's italic value. If no value is set false is
 16// returned.
 17func (s Style) GetItalic() bool {
 18	return s.getAsBool(italicKey, false)
 19}
 20
 21// GetUnderline returns the style's underline value. If no value is set false is
 22// returned.
 23func (s Style) GetUnderline() bool {
 24	return s.getAsBool(underlineKey, false)
 25}
 26
 27// GetStrikethrough returns the style's strikethrough value. If no value is set false
 28// is returned.
 29func (s Style) GetStrikethrough() bool {
 30	return s.getAsBool(strikethroughKey, false)
 31}
 32
 33// GetReverse returns the style's reverse value. If no value is set false is
 34// returned.
 35func (s Style) GetReverse() bool {
 36	return s.getAsBool(reverseKey, false)
 37}
 38
 39// GetBlink returns the style's blink value. If no value is set false is
 40// returned.
 41func (s Style) GetBlink() bool {
 42	return s.getAsBool(blinkKey, false)
 43}
 44
 45// GetFaint returns the style's faint value. If no value is set false is
 46// returned.
 47func (s Style) GetFaint() bool {
 48	return s.getAsBool(faintKey, false)
 49}
 50
 51// GetForeground returns the style's foreground color. If no value is set
 52// NoColor{} is returned.
 53func (s Style) GetForeground() color.Color {
 54	return s.getAsColor(foregroundKey)
 55}
 56
 57// GetBackground returns the style's background color. If no value is set
 58// NoColor{} is returned.
 59func (s Style) GetBackground() color.Color {
 60	return s.getAsColor(backgroundKey)
 61}
 62
 63// GetWidth returns the style's width setting. If no width is set 0 is
 64// returned.
 65func (s Style) GetWidth() int {
 66	return s.getAsInt(widthKey)
 67}
 68
 69// GetHeight returns the style's height setting. If no height is set 0 is
 70// returned.
 71func (s Style) GetHeight() int {
 72	return s.getAsInt(heightKey)
 73}
 74
 75// GetAlign returns the style's implicit horizontal alignment setting.
 76// If no alignment is set Position.Left is returned.
 77func (s Style) GetAlign() Position {
 78	v := s.getAsPosition(alignHorizontalKey)
 79	if v == Position(0) {
 80		return Left
 81	}
 82	return v
 83}
 84
 85// GetAlignHorizontal returns the style's implicit horizontal alignment setting.
 86// If no alignment is set Position.Left is returned.
 87func (s Style) GetAlignHorizontal() Position {
 88	v := s.getAsPosition(alignHorizontalKey)
 89	if v == Position(0) {
 90		return Left
 91	}
 92	return v
 93}
 94
 95// GetAlignVertical returns the style's implicit vertical alignment setting.
 96// If no alignment is set Position.Top is returned.
 97func (s Style) GetAlignVertical() Position {
 98	v := s.getAsPosition(alignVerticalKey)
 99	if v == Position(0) {
100		return Top
101	}
102	return v
103}
104
105// GetPadding returns the style's top, right, bottom, and left padding values,
106// in that order. 0 is returned for unset values.
107func (s Style) GetPadding() (top, right, bottom, left int) {
108	return s.getAsInt(paddingTopKey),
109		s.getAsInt(paddingRightKey),
110		s.getAsInt(paddingBottomKey),
111		s.getAsInt(paddingLeftKey)
112}
113
114// GetPaddingTop returns the style's top padding. If no value is set 0 is
115// returned.
116func (s Style) GetPaddingTop() int {
117	return s.getAsInt(paddingTopKey)
118}
119
120// GetPaddingRight returns the style's right padding. If no value is set 0 is
121// returned.
122func (s Style) GetPaddingRight() int {
123	return s.getAsInt(paddingRightKey)
124}
125
126// GetPaddingBottom returns the style's bottom padding. If no value is set 0 is
127// returned.
128func (s Style) GetPaddingBottom() int {
129	return s.getAsInt(paddingBottomKey)
130}
131
132// GetPaddingLeft returns the style's left padding. If no value is set 0 is
133// returned.
134func (s Style) GetPaddingLeft() int {
135	return s.getAsInt(paddingLeftKey)
136}
137
138// GetHorizontalPadding returns the style's left and right padding. Unset
139// values are measured as 0.
140func (s Style) GetHorizontalPadding() int {
141	return s.getAsInt(paddingLeftKey) + s.getAsInt(paddingRightKey)
142}
143
144// GetVerticalPadding returns the style's top and bottom padding. Unset values
145// are measured as 0.
146func (s Style) GetVerticalPadding() int {
147	return s.getAsInt(paddingTopKey) + s.getAsInt(paddingBottomKey)
148}
149
150// GetColorWhitespace returns the style's whitespace coloring setting. If no
151// value is set false is returned.
152func (s Style) GetColorWhitespace() bool {
153	return s.getAsBool(colorWhitespaceKey, false)
154}
155
156// GetMargin returns the style's top, right, bottom, and left margins, in that
157// order. 0 is returned for unset values.
158func (s Style) GetMargin() (top, right, bottom, left int) {
159	return s.getAsInt(marginTopKey),
160		s.getAsInt(marginRightKey),
161		s.getAsInt(marginBottomKey),
162		s.getAsInt(marginLeftKey)
163}
164
165// GetMarginTop returns the style's top margin. If no value is set 0 is
166// returned.
167func (s Style) GetMarginTop() int {
168	return s.getAsInt(marginTopKey)
169}
170
171// GetMarginRight returns the style's right margin. If no value is set 0 is
172// returned.
173func (s Style) GetMarginRight() int {
174	return s.getAsInt(marginRightKey)
175}
176
177// GetMarginBottom returns the style's bottom margin. If no value is set 0 is
178// returned.
179func (s Style) GetMarginBottom() int {
180	return s.getAsInt(marginBottomKey)
181}
182
183// GetMarginLeft returns the style's left margin. If no value is set 0 is
184// returned.
185func (s Style) GetMarginLeft() int {
186	return s.getAsInt(marginLeftKey)
187}
188
189// GetHorizontalMargins returns the style's left and right margins. Unset
190// values are measured as 0.
191func (s Style) GetHorizontalMargins() int {
192	return s.getAsInt(marginLeftKey) + s.getAsInt(marginRightKey)
193}
194
195// GetVerticalMargins returns the style's top and bottom margins. Unset values
196// are measured as 0.
197func (s Style) GetVerticalMargins() int {
198	return s.getAsInt(marginTopKey) + s.getAsInt(marginBottomKey)
199}
200
201// GetBorder returns the style's border style (type Border) and value for the
202// top, right, bottom, and left in that order. If no value is set for the
203// border style, Border{} is returned. For all other unset values false is
204// returned.
205func (s Style) GetBorder() (b Border, top, right, bottom, left bool) {
206	return s.getBorderStyle(),
207		s.getAsBool(borderTopKey, false),
208		s.getAsBool(borderRightKey, false),
209		s.getAsBool(borderBottomKey, false),
210		s.getAsBool(borderLeftKey, false)
211}
212
213// GetBorderStyle returns the style's border style (type Border). If no value
214// is set Border{} is returned.
215func (s Style) GetBorderStyle() Border {
216	return s.getBorderStyle()
217}
218
219// GetBorderTop returns the style's top border setting. If no value is set
220// false is returned.
221func (s Style) GetBorderTop() bool {
222	return s.getAsBool(borderTopKey, false)
223}
224
225// GetBorderRight returns the style's right border setting. If no value is set
226// false is returned.
227func (s Style) GetBorderRight() bool {
228	return s.getAsBool(borderRightKey, false)
229}
230
231// GetBorderBottom returns the style's bottom border setting. If no value is
232// set false is returned.
233func (s Style) GetBorderBottom() bool {
234	return s.getAsBool(borderBottomKey, false)
235}
236
237// GetBorderLeft returns the style's left border setting. If no value is
238// set false is returned.
239func (s Style) GetBorderLeft() bool {
240	return s.getAsBool(borderLeftKey, false)
241}
242
243// GetBorderTopForeground returns the style's border top foreground color. If
244// no value is set NoColor{} is returned.
245func (s Style) GetBorderTopForeground() color.Color {
246	return s.getAsColor(borderTopForegroundKey)
247}
248
249// GetBorderRightForeground returns the style's border right foreground color.
250// If no value is set NoColor{} is returned.
251func (s Style) GetBorderRightForeground() color.Color {
252	return s.getAsColor(borderRightForegroundKey)
253}
254
255// GetBorderBottomForeground returns the style's border bottom foreground
256// color.  If no value is set NoColor{} is returned.
257func (s Style) GetBorderBottomForeground() color.Color {
258	return s.getAsColor(borderBottomForegroundKey)
259}
260
261// GetBorderLeftForeground returns the style's border left foreground
262// color.  If no value is set NoColor{} is returned.
263func (s Style) GetBorderLeftForeground() color.Color {
264	return s.getAsColor(borderLeftForegroundKey)
265}
266
267// GetBorderTopBackground returns the style's border top background color. If
268// no value is set NoColor{} is returned.
269func (s Style) GetBorderTopBackground() color.Color {
270	return s.getAsColor(borderTopBackgroundKey)
271}
272
273// GetBorderRightBackground returns the style's border right background color.
274// If no value is set NoColor{} is returned.
275func (s Style) GetBorderRightBackground() color.Color {
276	return s.getAsColor(borderRightBackgroundKey)
277}
278
279// GetBorderBottomBackground returns the style's border bottom background
280// color.  If no value is set NoColor{} is returned.
281func (s Style) GetBorderBottomBackground() color.Color {
282	return s.getAsColor(borderBottomBackgroundKey)
283}
284
285// GetBorderLeftBackground returns the style's border left background
286// color.  If no value is set NoColor{} is returned.
287func (s Style) GetBorderLeftBackground() color.Color {
288	return s.getAsColor(borderLeftBackgroundKey)
289}
290
291// GetBorderTopWidth returns the width of the top border. If borders contain
292// runes of varying widths, the widest rune is returned. If no border exists on
293// the top edge, 0 is returned.
294//
295// Deprecated: This function simply calls Style.GetBorderTopSize.
296func (s Style) GetBorderTopWidth() int {
297	return s.GetBorderTopSize()
298}
299
300// GetBorderTopSize returns the width of the top border. If borders contain
301// runes of varying widths, the widest rune is returned. If no border exists on
302// the top edge, 0 is returned.
303func (s Style) GetBorderTopSize() int {
304	if s.isBorderStyleSetWithoutSides() {
305		return 1
306	}
307	if !s.getAsBool(borderTopKey, false) {
308		return 0
309	}
310	return s.getBorderStyle().GetTopSize()
311}
312
313// GetBorderLeftSize returns the width of the left border. If borders contain
314// runes of varying widths, the widest rune is returned. If no border exists on
315// the left edge, 0 is returned.
316func (s Style) GetBorderLeftSize() int {
317	if s.isBorderStyleSetWithoutSides() {
318		return 1
319	}
320	if !s.getAsBool(borderLeftKey, false) {
321		return 0
322	}
323	return s.getBorderStyle().GetLeftSize()
324}
325
326// GetBorderBottomSize returns the width of the bottom border. If borders
327// contain runes of varying widths, the widest rune is returned. If no border
328// exists on the left edge, 0 is returned.
329func (s Style) GetBorderBottomSize() int {
330	if s.isBorderStyleSetWithoutSides() {
331		return 1
332	}
333	if !s.getAsBool(borderBottomKey, false) {
334		return 0
335	}
336	return s.getBorderStyle().GetBottomSize()
337}
338
339// GetBorderRightSize returns the width of the right border. If borders
340// contain runes of varying widths, the widest rune is returned. If no border
341// exists on the right edge, 0 is returned.
342func (s Style) GetBorderRightSize() int {
343	if s.isBorderStyleSetWithoutSides() {
344		return 1
345	}
346	if !s.getAsBool(borderRightKey, false) {
347		return 0
348	}
349	return s.getBorderStyle().GetRightSize()
350}
351
352// GetHorizontalBorderSize returns the width of the horizontal borders. If
353// borders contain runes of varying widths, the widest rune is returned. If no
354// border exists on the horizontal edges, 0 is returned.
355func (s Style) GetHorizontalBorderSize() int {
356	return s.GetBorderLeftSize() + s.GetBorderRightSize()
357}
358
359// GetVerticalBorderSize returns the width of the vertical borders. If
360// borders contain runes of varying widths, the widest rune is returned. If no
361// border exists on the vertical edges, 0 is returned.
362func (s Style) GetVerticalBorderSize() int {
363	return s.GetBorderTopSize() + s.GetBorderBottomSize()
364}
365
366// GetInline returns the style's inline setting. If no value is set false is
367// returned.
368func (s Style) GetInline() bool {
369	return s.getAsBool(inlineKey, false)
370}
371
372// GetMaxWidth returns the style's max width setting. If no value is set 0 is
373// returned.
374func (s Style) GetMaxWidth() int {
375	return s.getAsInt(maxWidthKey)
376}
377
378// GetMaxHeight returns the style's max height setting. If no value is set 0 is
379// returned.
380func (s Style) GetMaxHeight() int {
381	return s.getAsInt(maxHeightKey)
382}
383
384// GetTabWidth returns the style's tab width setting. If no value is set 4 is
385// returned which is the implicit default.
386func (s Style) GetTabWidth() int {
387	return s.getAsInt(tabWidthKey)
388}
389
390// GetUnderlineSpaces returns whether or not the style is set to underline
391// spaces. If not value is set false is returned.
392func (s Style) GetUnderlineSpaces() bool {
393	return s.getAsBool(underlineSpacesKey, false)
394}
395
396// GetStrikethroughSpaces returns whether or not the style is set to strikethrough
397// spaces. If not value is set false is returned.
398func (s Style) GetStrikethroughSpaces() bool {
399	return s.getAsBool(strikethroughSpacesKey, false)
400}
401
402// GetHorizontalFrameSize returns the sum of the style's horizontal margins, padding
403// and border widths.
404//
405// Provisional: this method may be renamed.
406func (s Style) GetHorizontalFrameSize() int {
407	return s.GetHorizontalMargins() + s.GetHorizontalPadding() + s.GetHorizontalBorderSize()
408}
409
410// GetVerticalFrameSize returns the sum of the style's vertical margins, padding
411// and border widths.
412//
413// Provisional: this method may be renamed.
414func (s Style) GetVerticalFrameSize() int {
415	return s.GetVerticalMargins() + s.GetVerticalPadding() + s.GetVerticalBorderSize()
416}
417
418// GetFrameSize returns the sum of the margins, padding and border width for
419// both the horizontal and vertical margins.
420func (s Style) GetFrameSize() (x, y int) {
421	return s.GetHorizontalFrameSize(), s.GetVerticalFrameSize()
422}
423
424// GetTransform returns the transform set on the style. If no transform is set
425// nil is returned.
426func (s Style) GetTransform() func(string) string {
427	return s.getAsTransform(transformKey)
428}
429
430// Returns whether or not the given property is set.
431func (s Style) isSet(k propKey) bool {
432	return s.props.has(k)
433}
434
435func (s Style) getAsBool(k propKey, defaultVal bool) bool {
436	if !s.isSet(k) {
437		return defaultVal
438	}
439	return s.attrs&int(k) != 0
440}
441
442func (s Style) getAsColor(k propKey) color.Color {
443	if !s.isSet(k) {
444		return noColor
445	}
446
447	var c color.Color
448	switch k { //nolint:exhaustive
449	case foregroundKey:
450		c = s.fgColor
451	case backgroundKey:
452		c = s.bgColor
453	case marginBackgroundKey:
454		c = s.marginBgColor
455	case borderTopForegroundKey:
456		c = s.borderTopFgColor
457	case borderRightForegroundKey:
458		c = s.borderRightFgColor
459	case borderBottomForegroundKey:
460		c = s.borderBottomFgColor
461	case borderLeftForegroundKey:
462		c = s.borderLeftFgColor
463	case borderTopBackgroundKey:
464		c = s.borderTopBgColor
465	case borderRightBackgroundKey:
466		c = s.borderRightBgColor
467	case borderBottomBackgroundKey:
468		c = s.borderBottomBgColor
469	case borderLeftBackgroundKey:
470		c = s.borderLeftBgColor
471	}
472
473	if c != nil {
474		return c
475	}
476
477	return noColor
478}
479
480func (s Style) getAsInt(k propKey) int {
481	if !s.isSet(k) {
482		return 0
483	}
484	switch k { //nolint:exhaustive
485	case widthKey:
486		return s.width
487	case heightKey:
488		return s.height
489	case paddingTopKey:
490		return s.paddingTop
491	case paddingRightKey:
492		return s.paddingRight
493	case paddingBottomKey:
494		return s.paddingBottom
495	case paddingLeftKey:
496		return s.paddingLeft
497	case marginTopKey:
498		return s.marginTop
499	case marginRightKey:
500		return s.marginRight
501	case marginBottomKey:
502		return s.marginBottom
503	case marginLeftKey:
504		return s.marginLeft
505	case maxWidthKey:
506		return s.maxWidth
507	case maxHeightKey:
508		return s.maxHeight
509	case tabWidthKey:
510		return s.tabWidth
511	}
512	return 0
513}
514
515func (s Style) getAsPosition(k propKey) Position {
516	if !s.isSet(k) {
517		return Position(0)
518	}
519	switch k { //nolint:exhaustive
520	case alignHorizontalKey:
521		return s.alignHorizontal
522	case alignVerticalKey:
523		return s.alignVertical
524	}
525	return Position(0)
526}
527
528func (s Style) getBorderStyle() Border {
529	if !s.isSet(borderStyleKey) {
530		return noBorder
531	}
532	return s.borderStyle
533}
534
535func (s Style) getAsTransform(propKey) func(string) string {
536	if !s.isSet(transformKey) {
537		return nil
538	}
539	return s.transform
540}
541
542// Split a string into lines, additionally returning the size of the widest
543// line.
544func getLines(s string) (lines []string, widest int) {
545	s = strings.ReplaceAll(s, "\t", "    ")
546	s = strings.ReplaceAll(s, "\r\n", "\n")
547	lines = strings.Split(s, "\n")
548
549	for _, l := range lines {
550		w := ansi.StringWidth(l)
551		if widest < w {
552			widest = w
553		}
554	}
555
556	return lines, widest
557}
558
559// isBorderStyleSetWithoutSides returns true if the border style is set but no
560// sides are set. This is used to determine if the border should be rendered by
561// default.
562func (s Style) isBorderStyleSetWithoutSides() bool {
563	var (
564		border    = s.getBorderStyle()
565		topSet    = s.isSet(borderTopKey)
566		rightSet  = s.isSet(borderRightKey)
567		bottomSet = s.isSet(borderBottomKey)
568		leftSet   = s.isSet(borderLeftKey)
569	)
570	return border != noBorder && !(topSet || rightSet || bottomSet || leftSet) //nolint:staticcheck
571}