• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

charmbracelet / glamour / 10182535319

31 Jul 2024 02:50PM UTC coverage: 80.0% (+0.08%) from 79.917%
10182535319

push

github

bashbunni
chore: go mod tidy

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

1156 of 1445 relevant lines covered (80.0%)

295.3 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.12
/ansi/codeblock.go
1
package ansi
2

3
import (
4
        "io"
5
        "sync"
6

7
        "github.com/alecthomas/chroma/v2"
8
        "github.com/alecthomas/chroma/v2/quick"
9
        "github.com/alecthomas/chroma/v2/styles"
10
        "github.com/muesli/reflow/indent"
11
        "github.com/muesli/termenv"
12
)
13

14
const (
15
        // The chroma style theme name used for rendering.
16
        chromaStyleTheme = "charm"
17
)
18

19
// mutex for synchronizing access to the chroma style registry.
20
// Related https://github.com/alecthomas/chroma/pull/650
21
var mutex = sync.Mutex{}
22

23
// A CodeBlockElement is used to render code blocks.
24
type CodeBlockElement struct {
25
        Code     string
26
        Language string
27
}
28

29
func chromaStyle(style StylePrimitive) string {
31✔
30
        var s string
31✔
31

31✔
32
        if style.Color != nil {
54✔
33
                s = *style.Color
23✔
34
        }
23✔
35
        if style.BackgroundColor != nil {
33✔
36
                if s != "" {
3✔
37
                        s += " "
1✔
38
                }
1✔
39
                s += "bg:" + *style.BackgroundColor
2✔
40
        }
41
        if style.Italic != nil && *style.Italic {
32✔
42
                if s != "" {
1✔
43
                        s += " "
×
44
                }
×
45
                s += "italic"
1✔
46
        }
47
        if style.Bold != nil && *style.Bold {
33✔
48
                if s != "" {
3✔
49
                        s += " "
1✔
50
                }
1✔
51
                s += "bold"
2✔
52
        }
53
        if style.Underline != nil && *style.Underline {
32✔
54
                if s != "" {
2✔
55
                        s += " "
1✔
56
                }
1✔
57
                s += "underline"
1✔
58
        }
59

60
        return s
31✔
61
}
62

63
func (e *CodeBlockElement) Render(w io.Writer, ctx RenderContext) error {
5✔
64
        bs := ctx.blockStack
5✔
65

5✔
66
        var indentation uint
5✔
67
        var margin uint
5✔
68
        rules := ctx.options.Styles.CodeBlock
5✔
69
        if rules.Indent != nil {
5✔
70
                indentation = *rules.Indent
×
71
        }
×
72
        if rules.Margin != nil {
9✔
73
                margin = *rules.Margin
4✔
74
        }
4✔
75
        theme := rules.Theme
5✔
76

5✔
77
        if rules.Chroma != nil && ctx.options.ColorProfile != termenv.Ascii {
9✔
78
                theme = chromaStyleTheme
4✔
79
                mutex.Lock()
4✔
80
                // Don't register the style if it's already registered.
4✔
81
                _, ok := styles.Registry[theme]
4✔
82
                if !ok {
5✔
83
                        styles.Register(chroma.MustNewStyle(theme,
1✔
84
                                chroma.StyleEntries{
1✔
85
                                        chroma.Text:                chromaStyle(rules.Chroma.Text),
1✔
86
                                        chroma.Error:               chromaStyle(rules.Chroma.Error),
1✔
87
                                        chroma.Comment:             chromaStyle(rules.Chroma.Comment),
1✔
88
                                        chroma.CommentPreproc:      chromaStyle(rules.Chroma.CommentPreproc),
1✔
89
                                        chroma.Keyword:             chromaStyle(rules.Chroma.Keyword),
1✔
90
                                        chroma.KeywordReserved:     chromaStyle(rules.Chroma.KeywordReserved),
1✔
91
                                        chroma.KeywordNamespace:    chromaStyle(rules.Chroma.KeywordNamespace),
1✔
92
                                        chroma.KeywordType:         chromaStyle(rules.Chroma.KeywordType),
1✔
93
                                        chroma.Operator:            chromaStyle(rules.Chroma.Operator),
1✔
94
                                        chroma.Punctuation:         chromaStyle(rules.Chroma.Punctuation),
1✔
95
                                        chroma.Name:                chromaStyle(rules.Chroma.Name),
1✔
96
                                        chroma.NameBuiltin:         chromaStyle(rules.Chroma.NameBuiltin),
1✔
97
                                        chroma.NameTag:             chromaStyle(rules.Chroma.NameTag),
1✔
98
                                        chroma.NameAttribute:       chromaStyle(rules.Chroma.NameAttribute),
1✔
99
                                        chroma.NameClass:           chromaStyle(rules.Chroma.NameClass),
1✔
100
                                        chroma.NameConstant:        chromaStyle(rules.Chroma.NameConstant),
1✔
101
                                        chroma.NameDecorator:       chromaStyle(rules.Chroma.NameDecorator),
1✔
102
                                        chroma.NameException:       chromaStyle(rules.Chroma.NameException),
1✔
103
                                        chroma.NameFunction:        chromaStyle(rules.Chroma.NameFunction),
1✔
104
                                        chroma.NameOther:           chromaStyle(rules.Chroma.NameOther),
1✔
105
                                        chroma.Literal:             chromaStyle(rules.Chroma.Literal),
1✔
106
                                        chroma.LiteralNumber:       chromaStyle(rules.Chroma.LiteralNumber),
1✔
107
                                        chroma.LiteralDate:         chromaStyle(rules.Chroma.LiteralDate),
1✔
108
                                        chroma.LiteralString:       chromaStyle(rules.Chroma.LiteralString),
1✔
109
                                        chroma.LiteralStringEscape: chromaStyle(rules.Chroma.LiteralStringEscape),
1✔
110
                                        chroma.GenericDeleted:      chromaStyle(rules.Chroma.GenericDeleted),
1✔
111
                                        chroma.GenericEmph:         chromaStyle(rules.Chroma.GenericEmph),
1✔
112
                                        chroma.GenericInserted:     chromaStyle(rules.Chroma.GenericInserted),
1✔
113
                                        chroma.GenericStrong:       chromaStyle(rules.Chroma.GenericStrong),
1✔
114
                                        chroma.GenericSubheading:   chromaStyle(rules.Chroma.GenericSubheading),
1✔
115
                                        chroma.Background:          chromaStyle(rules.Chroma.Background),
1✔
116
                                }))
1✔
117
                }
1✔
118
                mutex.Unlock()
4✔
119
        }
120

121
        iw := indent.NewWriterPipe(w, indentation+margin, func(wr io.Writer) {
15✔
122
                renderText(w, ctx.options.ColorProfile, bs.Current().Style.StylePrimitive, " ")
10✔
123
        })
10✔
124

125
        if len(theme) > 0 {
10✔
126
                renderText(iw, ctx.options.ColorProfile, bs.Current().Style.StylePrimitive, rules.BlockPrefix)
5✔
127

5✔
128
                err := quick.Highlight(iw, e.Code, e.Language, "terminal256", theme)
5✔
129
                if err != nil {
5✔
130
                        return err
×
131
                }
×
132
                renderText(iw, ctx.options.ColorProfile, bs.Current().Style.StylePrimitive, rules.BlockSuffix)
5✔
133
                return nil
5✔
134
        }
135

136
        // fallback rendering
137
        el := &BaseElement{
×
138
                Token: e.Code,
×
139
                Style: rules.StylePrimitive,
×
140
        }
×
141

×
142
        return el.Render(iw, ctx)
×
143
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc