github.com/charmbracelet/glamour@v0.7.0/ansi/blockelement.go (about)

     1  package ansi
     2  
     3  import (
     4  	"bytes"
     5  	"io"
     6  
     7  	"github.com/muesli/reflow/wordwrap"
     8  )
     9  
    10  // BlockElement provides a render buffer for children of a block element.
    11  // After all children have been rendered into it, it applies indentation and
    12  // margins around them and writes everything to the parent rendering buffer.
    13  type BlockElement struct {
    14  	Block   *bytes.Buffer
    15  	Style   StyleBlock
    16  	Margin  bool
    17  	Newline bool
    18  }
    19  
    20  func (e *BlockElement) Render(w io.Writer, ctx RenderContext) error {
    21  	bs := ctx.blockStack
    22  	bs.Push(*e)
    23  
    24  	renderText(w, ctx.options.ColorProfile, bs.Parent().Style.StylePrimitive, e.Style.BlockPrefix)
    25  	renderText(bs.Current().Block, ctx.options.ColorProfile, bs.Current().Style.StylePrimitive, e.Style.Prefix)
    26  	return nil
    27  }
    28  
    29  func (e *BlockElement) Finish(w io.Writer, ctx RenderContext) error {
    30  	bs := ctx.blockStack
    31  
    32  	if e.Margin {
    33  		mw := NewMarginWriter(ctx, w, bs.Current().Style)
    34  		_, err := mw.Write(
    35  			wordwrap.Bytes(bs.Current().Block.Bytes(), int(bs.Width(ctx))))
    36  		if err != nil {
    37  			return err
    38  		}
    39  
    40  		if e.Newline {
    41  			_, err = mw.Write([]byte("\n"))
    42  			if err != nil {
    43  				return err
    44  			}
    45  		}
    46  	} else {
    47  		_, err := bs.Parent().Block.Write(bs.Current().Block.Bytes())
    48  		if err != nil {
    49  			return err
    50  		}
    51  	}
    52  
    53  	renderText(w, ctx.options.ColorProfile, bs.Current().Style.StylePrimitive, e.Style.Suffix)
    54  	renderText(w, ctx.options.ColorProfile, bs.Parent().Style.StylePrimitive, e.Style.BlockSuffix)
    55  
    56  	bs.Current().Block.Reset()
    57  	bs.Pop()
    58  	return nil
    59  }