Skip to content

Instantly share code, notes, and snippets.

@ef2k
Forked from depado/main.go
Created January 4, 2018 01:36
Show Gist options
  • Save ef2k/14eeef9698ea013d0e583e8d24a99c80 to your computer and use it in GitHub Desktop.
Save ef2k/14eeef9698ea013d0e583e8d24a99c80 to your computer and use it in GitHub Desktop.
Integrating Chroma in Blackfriday
package main
import (
"fmt"
"io"
"github.com/alecthomas/chroma"
"github.com/alecthomas/chroma/formatters/html"
"github.com/alecthomas/chroma/lexers"
"github.com/alecthomas/chroma/styles"
bf "gopkg.in/russross/blackfriday.v2"
)
var md = "This is some sample code.\n\n```go\n" +
`func main() {
fmt.Println("Hi")
}
` + "```"
func renderWithChroma(w io.Writer, text []byte, data bf.CodeBlockData) error {
var lexer chroma.Lexer
if len(data.Info) > 0 {
lexer = lexers.Get(string(data.Info))
} else {
lexer = lexers.Analyse(string(text))
}
if lexer == nil {
lexer = lexers.Fallback
}
style := styles.Get("monokai")
if style == nil {
style = styles.Fallback
}
formatter := html.New()
iterator, err := lexer.Tokenise(nil, string(text))
if err != nil {
return err
}
return formatter.Format(w, style, iterator)
}
type chromaRenderer struct {
defR *bf.HTMLRenderer
}
func (r *chromaRenderer) RenderNode(w io.Writer, node *bf.Node, entering bool) bf.WalkStatus {
switch node.Type {
case bf.CodeBlock:
if err := renderWithChroma(w, node.Literal, node.CodeBlockData); err != nil {
return r.defR.RenderNode(w, node, entering)
}
return bf.SkipChildren
default:
return r.defR.RenderNode(w, node, entering)
}
}
func (r *chromaRenderer) RenderHeader(w io.Writer, ast *bf.Node) {
r.defR.RenderHeader(w, ast)
}
func (r *chromaRenderer) RenderFooter(w io.Writer, ast *bf.Node) {
r.defR.RenderFooter(w, ast)
}
func main() {
r := chromaRenderer{
defR: bf.NewHTMLRenderer(bf.HTMLRendererParameters{
Flags: bf.CommonHTMLFlags,
}),
}
html := bf.Run([]byte(md), bf.WithRenderer(&r))
fmt.Println(string(html))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment