github.com/charmbracelet/glamour@v0.7.0/ansi/blockstack.go (about) 1 package ansi 2 3 import ( 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. 9 type BlockStack []BlockElement 10 11 // Len returns the length of the stack. 12 func (s *BlockStack) Len() int { 13 return len(*s) 14 } 15 16 // Push appends an item to the stack. 17 func (s *BlockStack) Push(e BlockElement) { 18 *s = append(*s, e) 19 } 20 21 // Pop removes the last item on the stack. 22 func (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. 33 func (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. 47 func (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. 61 func (s BlockStack) Width(ctx RenderContext) uint { 62 if s.Indent()+s.Margin()*2 > uint(ctx.options.WordWrap) { 63 return 0 64 } 65 return uint(ctx.options.WordWrap) - s.Indent() - s.Margin()*2 66 } 67 68 // Parent returns the current BlockElement's parent. 69 func (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. 80 func (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. 91 func (s BlockStack) With(child StylePrimitive) StylePrimitive { 92 sb := StyleBlock{} 93 sb.StylePrimitive = child 94 return cascadeStyle(s.Current().Style, sb, false).StylePrimitive 95 }