blockstack.go

 1package ansi
 2
 3import (
 4	"bytes"
 5)
 6
 7// BlockStack is a stack of block elements, used to calculate the current
 8// indentation & margin level during the rendering process.
 9type BlockStack []BlockElement
10
11// Len returns the length of the stack.
12func (s *BlockStack) Len() int {
13	return len(*s)
14}
15
16// Push appends an item to the stack.
17func (s *BlockStack) Push(e BlockElement) {
18	*s = append(*s, e)
19}
20
21// Pop removes the last item on the stack.
22func (s *BlockStack) Pop() {
23	stack := *s
24	if len(stack) == 0 {
25		return
26	}
27
28	stack = stack[0 : len(stack)-1]
29	*s = stack
30}
31
32// Indent returns the current indentation level of all elements in the stack.
33func (s BlockStack) Indent() uint {
34	var i uint
35
36	for _, v := range s {
37		if v.Style.Indent == nil {
38			continue
39		}
40		i += *v.Style.Indent
41	}
42
43	return i
44}
45
46// Margin returns the current margin level of all elements in the stack.
47func (s BlockStack) Margin() uint {
48	var i uint
49
50	for _, v := range s {
51		if v.Style.Margin == nil {
52			continue
53		}
54		i += *v.Style.Margin
55	}
56
57	return i
58}
59
60// Width returns the available rendering width.
61func (s BlockStack) Width(ctx RenderContext) uint {
62	if s.Indent()+s.Margin()*2 > uint(ctx.options.WordWrap) { //nolint: gosec
63		return 0
64	}
65	return uint(ctx.options.WordWrap) - s.Indent() - s.Margin()*2 //nolint: gosec
66}
67
68// Parent returns the current BlockElement's parent.
69func (s BlockStack) Parent() BlockElement {
70	if len(s) == 1 {
71		return BlockElement{
72			Block: &bytes.Buffer{},
73		}
74	}
75
76	return s[len(s)-2]
77}
78
79// Current returns the current BlockElement.
80func (s BlockStack) Current() BlockElement {
81	if len(s) == 0 {
82		return BlockElement{
83			Block: &bytes.Buffer{},
84		}
85	}
86
87	return s[len(s)-1]
88}
89
90// With returns a StylePrimitive that inherits the current BlockElement's style.
91func (s BlockStack) With(child StylePrimitive) StylePrimitive {
92	sb := StyleBlock{}
93	sb.StylePrimitive = child
94	return cascadeStyle(s.Current().Style, sb, false).StylePrimitive
95}