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 }