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

     1  package ansi
     2  
     3  import (
     4  	"bytes"
     5  	"io"
     6  	"strings"
     7  
     8  	"github.com/muesli/reflow/wordwrap"
     9  )
    10  
    11  // A ParagraphElement is used to render individual paragraphs.
    12  type ParagraphElement struct {
    13  	First bool
    14  }
    15  
    16  func (e *ParagraphElement) Render(w io.Writer, ctx RenderContext) error {
    17  	bs := ctx.blockStack
    18  	rules := ctx.options.Styles.Paragraph
    19  
    20  	if !e.First {
    21  		_, _ = w.Write([]byte("\n"))
    22  	}
    23  	be := BlockElement{
    24  		Block: &bytes.Buffer{},
    25  		Style: cascadeStyle(bs.Current().Style, rules, false),
    26  	}
    27  	bs.Push(be)
    28  
    29  	renderText(w, ctx.options.ColorProfile, bs.Parent().Style.StylePrimitive, rules.BlockPrefix)
    30  	renderText(bs.Current().Block, ctx.options.ColorProfile, bs.Current().Style.StylePrimitive, rules.Prefix)
    31  	return nil
    32  }
    33  
    34  func (e *ParagraphElement) Finish(w io.Writer, ctx RenderContext) error {
    35  	bs := ctx.blockStack
    36  	rules := bs.Current().Style
    37  
    38  	mw := NewMarginWriter(ctx, w, rules)
    39  	if len(strings.TrimSpace(bs.Current().Block.String())) > 0 {
    40  		flow := wordwrap.NewWriter(int(bs.Width(ctx)))
    41  		flow.KeepNewlines = ctx.options.PreserveNewLines
    42  		_, _ = flow.Write(bs.Current().Block.Bytes())
    43  		flow.Close()
    44  
    45  		_, err := mw.Write(flow.Bytes())
    46  		if err != nil {
    47  			return err
    48  		}
    49  		_, _ = mw.Write([]byte("\n"))
    50  	}
    51  
    52  	renderText(w, ctx.options.ColorProfile, bs.Current().Style.StylePrimitive, rules.Suffix)
    53  	renderText(w, ctx.options.ColorProfile, bs.Parent().Style.StylePrimitive, rules.BlockSuffix)
    54  
    55  	bs.Current().Block.Reset()
    56  	bs.Pop()
    57  	return nil
    58  }