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

charmbracelet / glamour / 13420703237

19 Feb 2025 07:24PM UTC coverage: 77.072% (-0.7%) from 77.74%
13420703237

push

github

andreynering
fix(lint): add missing enum value to switch statement

1 of 1 new or added line in 1 file covered. (100.0%)

101 existing lines in 14 files now uncovered.

1153 of 1496 relevant lines covered (77.07%)

281.51 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
        "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

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

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

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

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

61
        return s
31✔
62
}
63

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

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

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

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

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

5✔
130
                err := quick.Highlight(iw, e.Code, e.Language, "terminal256", theme)
5✔
131
                if err != nil {
5✔
UNCOV
132
                        return fmt.Errorf("glamour: error highlighting code: %w", err)
×
UNCOV
133
                }
×
134
                renderText(iw, ctx.options.ColorProfile, bs.Current().Style.StylePrimitive, rules.BlockSuffix)
5✔
135
                return nil
5✔
136
        }
137

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

×
UNCOV
144
        return el.Render(iw, ctx)
×
145
}
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