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