paragraph.go

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