Mercurial > yakumo_izuru > aya
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/github.com/Depado/bfchroma/v2/renderer.go Sun Jul 23 13:18:53 2023 +0000 @@ -0,0 +1,147 @@ +// Package bfchroma provides an easy and extensible blackfriday renderer that +// uses the chroma syntax highlighter to render code blocks. +package bfchroma + +import ( + "io" + + "github.com/alecthomas/chroma/v2" + "github.com/alecthomas/chroma/v2/formatters/html" + "github.com/alecthomas/chroma/v2/lexers" + "github.com/alecthomas/chroma/v2/styles" + bf "github.com/russross/blackfriday/v2" +) + +// Option defines the functional option type +type Option func(r *Renderer) + +// Style is a function option allowing to set the style used by chroma +// Default : "monokai" +func Style(s string) Option { + return func(r *Renderer) { + r.Style = styles.Get(s) + } +} + +// ChromaStyle is an option to directly set the style of the renderer using a +// chroma style instead of a string +func ChromaStyle(s *chroma.Style) Option { + return func(r *Renderer) { + r.Style = s + } +} + +// WithoutAutodetect disables chroma's language detection when no codeblock +// extra information is given. It will fallback to a sane default instead of +// trying to detect the language. +func WithoutAutodetect() Option { + return func(r *Renderer) { + r.Autodetect = false + } +} + +// EmbedCSS will embed CSS needed for html.WithClasses() in beginning of the document +func EmbedCSS() Option { + return func(r *Renderer) { + r.embedCSS = true + } +} + +// ChromaOptions allows to pass Chroma html.Option such as Standalone() +// WithClasses(), ClassPrefix(prefix)... +func ChromaOptions(options ...html.Option) Option { + return func(r *Renderer) { + r.ChromaOptions = options + } +} + +// Extend allows to specify the blackfriday renderer which is extended +func Extend(br bf.Renderer) Option { + return func(r *Renderer) { + r.Base = br + } +} + +// NewRenderer will return a new bfchroma renderer with sane defaults +func NewRenderer(options ...Option) *Renderer { + r := &Renderer{ + Base: bf.NewHTMLRenderer(bf.HTMLRendererParameters{ + Flags: bf.CommonHTMLFlags, + }), + Style: styles.Monokai, + Autodetect: true, + } + for _, option := range options { + option(r) + } + r.Formatter = html.New(r.ChromaOptions...) + return r +} + +// RenderWithChroma will render the given text to the w io.Writer +func (r *Renderer) RenderWithChroma(w io.Writer, text []byte, data bf.CodeBlockData) error { + var lexer chroma.Lexer + + // Determining the lexer to use + if len(data.Info) > 0 { + lexer = lexers.Get(string(data.Info)) + } else if r.Autodetect { + lexer = lexers.Analyse(string(text)) + } + if lexer == nil { + lexer = lexers.Fallback + } + + // Tokenize the code + iterator, err := lexer.Tokenise(nil, string(text)) + if err != nil { + return err + } + return r.Formatter.Format(w, r.Style, iterator) +} + +// Renderer is a custom Blackfriday renderer that uses the capabilities of +// chroma to highlight code with triple backtick notation +type Renderer struct { + Base bf.Renderer + Autodetect bool + ChromaOptions []html.Option + Style *chroma.Style + Formatter *html.Formatter + embedCSS bool +} + +// RenderNode satisfies the Renderer interface +func (r *Renderer) RenderNode(w io.Writer, node *bf.Node, entering bool) bf.WalkStatus { + switch node.Type { + case bf.Document: + if entering && r.embedCSS { + w.Write([]byte("<style>")) // nolint: errcheck + r.Formatter.WriteCSS(w, r.Style) // nolint: errcheck + w.Write([]byte("</style>")) // nolint: errcheck + } + return r.Base.RenderNode(w, node, entering) + case bf.CodeBlock: + if err := r.RenderWithChroma(w, node.Literal, node.CodeBlockData); err != nil { + return r.Base.RenderNode(w, node, entering) + } + return bf.SkipChildren + default: + return r.Base.RenderNode(w, node, entering) + } +} + +// RenderHeader satisfies the Renderer interface +func (r *Renderer) RenderHeader(w io.Writer, ast *bf.Node) { + r.Base.RenderHeader(w, ast) +} + +// RenderFooter satisfies the Renderer interface +func (r *Renderer) RenderFooter(w io.Writer, ast *bf.Node) { + r.Base.RenderFooter(w, ast) +} + +// ChromaCSS returns CSS used with chroma's html.WithClasses() option +func (r *Renderer) ChromaCSS(w io.Writer) error { + return r.Formatter.WriteCSS(w, r.Style) +}