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}