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)
+}