annotate vendor/github.com/Depado/bfchroma/v2/renderer.go @ 66:787b5ee0289d draft

Use vendored modules Signed-off-by: Izuru Yakumo <yakumo.izuru@chaotic.ninja>
author yakumo.izuru
date Sun, 23 Jul 2023 13:18:53 +0000
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
66
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1 // Package bfchroma provides an easy and extensible blackfriday renderer that
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
2 // uses the chroma syntax highlighter to render code blocks.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
3 package bfchroma
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
4
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
5 import (
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
6 "io"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
7
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
8 "github.com/alecthomas/chroma/v2"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
9 "github.com/alecthomas/chroma/v2/formatters/html"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
10 "github.com/alecthomas/chroma/v2/lexers"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
11 "github.com/alecthomas/chroma/v2/styles"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
12 bf "github.com/russross/blackfriday/v2"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
13 )
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
14
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
15 // Option defines the functional option type
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
16 type Option func(r *Renderer)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
17
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
18 // Style is a function option allowing to set the style used by chroma
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
19 // Default : "monokai"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
20 func Style(s string) Option {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
21 return func(r *Renderer) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
22 r.Style = styles.Get(s)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
23 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
24 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
25
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
26 // ChromaStyle is an option to directly set the style of the renderer using a
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
27 // chroma style instead of a string
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
28 func ChromaStyle(s *chroma.Style) Option {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
29 return func(r *Renderer) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
30 r.Style = s
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
31 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
32 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
33
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
34 // WithoutAutodetect disables chroma's language detection when no codeblock
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
35 // extra information is given. It will fallback to a sane default instead of
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
36 // trying to detect the language.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
37 func WithoutAutodetect() Option {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
38 return func(r *Renderer) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
39 r.Autodetect = false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
40 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
41 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
42
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
43 // EmbedCSS will embed CSS needed for html.WithClasses() in beginning of the document
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
44 func EmbedCSS() Option {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
45 return func(r *Renderer) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
46 r.embedCSS = true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
47 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
48 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
49
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
50 // ChromaOptions allows to pass Chroma html.Option such as Standalone()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
51 // WithClasses(), ClassPrefix(prefix)...
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
52 func ChromaOptions(options ...html.Option) Option {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
53 return func(r *Renderer) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
54 r.ChromaOptions = options
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
55 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
56 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
57
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
58 // Extend allows to specify the blackfriday renderer which is extended
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
59 func Extend(br bf.Renderer) Option {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
60 return func(r *Renderer) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
61 r.Base = br
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
62 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
63 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
64
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
65 // NewRenderer will return a new bfchroma renderer with sane defaults
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
66 func NewRenderer(options ...Option) *Renderer {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
67 r := &Renderer{
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
68 Base: bf.NewHTMLRenderer(bf.HTMLRendererParameters{
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
69 Flags: bf.CommonHTMLFlags,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
70 }),
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
71 Style: styles.Monokai,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
72 Autodetect: true,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
73 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
74 for _, option := range options {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
75 option(r)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
76 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
77 r.Formatter = html.New(r.ChromaOptions...)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
78 return r
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
79 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
80
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
81 // RenderWithChroma will render the given text to the w io.Writer
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
82 func (r *Renderer) RenderWithChroma(w io.Writer, text []byte, data bf.CodeBlockData) error {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
83 var lexer chroma.Lexer
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
84
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
85 // Determining the lexer to use
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
86 if len(data.Info) > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
87 lexer = lexers.Get(string(data.Info))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
88 } else if r.Autodetect {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
89 lexer = lexers.Analyse(string(text))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
90 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
91 if lexer == nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
92 lexer = lexers.Fallback
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
93 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
94
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
95 // Tokenize the code
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
96 iterator, err := lexer.Tokenise(nil, string(text))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
97 if err != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
98 return err
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
99 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
100 return r.Formatter.Format(w, r.Style, iterator)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
101 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
102
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
103 // Renderer is a custom Blackfriday renderer that uses the capabilities of
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
104 // chroma to highlight code with triple backtick notation
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
105 type Renderer struct {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
106 Base bf.Renderer
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
107 Autodetect bool
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
108 ChromaOptions []html.Option
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
109 Style *chroma.Style
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
110 Formatter *html.Formatter
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
111 embedCSS bool
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
112 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
113
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
114 // RenderNode satisfies the Renderer interface
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
115 func (r *Renderer) RenderNode(w io.Writer, node *bf.Node, entering bool) bf.WalkStatus {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
116 switch node.Type {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
117 case bf.Document:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
118 if entering && r.embedCSS {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
119 w.Write([]byte("<style>")) // nolint: errcheck
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
120 r.Formatter.WriteCSS(w, r.Style) // nolint: errcheck
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
121 w.Write([]byte("</style>")) // nolint: errcheck
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
122 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
123 return r.Base.RenderNode(w, node, entering)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
124 case bf.CodeBlock:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
125 if err := r.RenderWithChroma(w, node.Literal, node.CodeBlockData); err != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
126 return r.Base.RenderNode(w, node, entering)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
127 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
128 return bf.SkipChildren
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
129 default:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
130 return r.Base.RenderNode(w, node, entering)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
131 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
132 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
133
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
134 // RenderHeader satisfies the Renderer interface
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
135 func (r *Renderer) RenderHeader(w io.Writer, ast *bf.Node) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
136 r.Base.RenderHeader(w, ast)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
137 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
138
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
139 // RenderFooter satisfies the Renderer interface
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
140 func (r *Renderer) RenderFooter(w io.Writer, ast *bf.Node) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
141 r.Base.RenderFooter(w, ast)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
142 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
143
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
144 // ChromaCSS returns CSS used with chroma's html.WithClasses() option
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
145 func (r *Renderer) ChromaCSS(w io.Writer) error {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
146 return r.Formatter.WriteCSS(w, r.Style)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
147 }