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

charmbracelet / glamour / 15113664933

19 May 2025 01:00PM UTC coverage: 83.216% (+3.5%) from 79.737%
15113664933

push

github

caarlos0
chore(deps): chroma update

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

1413 of 1698 relevant lines covered (83.22%)

516.42 hits per line

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

86.67
/ansi/codeblock.go
1
package ansi
2

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

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

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

19
        // The chroma formatter name used for rendering.
20
        chromaFormatter = "terminal256"
21
)
22

23
// mutex for synchronizing access to the chroma style registry.
24
// Related https://github.com/alecthomas/chroma/pull/650
25
var mutex = sync.Mutex{}
26

27
// A CodeBlockElement is used to render code blocks.
28
type CodeBlockElement struct {
29
        Code     string
30
        Language string
31
}
32

33
func chromaStyle(style StylePrimitive) string {
31✔
34
        var s string
31✔
35

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

64
        return s
31✔
65
}
66

67
// Render renders a CodeBlockElement.
68
func (e *CodeBlockElement) Render(w io.Writer, ctx RenderContext) error {
5✔
69
        bs := ctx.blockStack
5✔
70

5✔
71
        var indentation uint
5✔
72
        var margin uint
5✔
73
        formatter := chromaFormatter
5✔
74
        rules := ctx.options.Styles.CodeBlock
5✔
75
        if rules.Indent != nil {
5✔
76
                indentation = *rules.Indent
×
77
        }
×
78
        if rules.Margin != nil {
9✔
79
                margin = *rules.Margin
4✔
80
        }
4✔
81
        if len(ctx.options.ChromaFormatter) > 0 {
5✔
82
                formatter = ctx.options.ChromaFormatter
×
83
        }
×
84
        theme := rules.Theme
5✔
85

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

130
        iw := indent.NewWriterPipe(w, indentation+margin, func(_ io.Writer) {
15✔
131
                renderText(w, ctx.options.ColorProfile, bs.Current().Style.StylePrimitive, " ")
10✔
132
        })
10✔
133

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

5✔
137
                err := quick.Highlight(iw, e.Code, e.Language, formatter, theme)
5✔
138
                if err != nil {
5✔
139
                        return fmt.Errorf("glamour: error highlighting code: %w", err)
×
140
                }
×
141
                renderText(iw, ctx.options.ColorProfile, bs.Current().Style.StylePrimitive, rules.BlockSuffix)
5✔
142
                return nil
5✔
143
        }
144

145
        // fallback rendering
146
        el := &BaseElement{
×
147
                Token: e.Code,
×
148
                Style: rules.StylePrimitive,
×
149
        }
×
150

×
151
        return el.Render(iw, ctx)
×
152
}
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