package main // example for https://blog.kowalczyk.info/article/cxn3/advanced-markdown-processing-in-go.html import ( "fmt" "io" "github.com/gomarkdown/markdown" "github.com/gomarkdown/markdown/ast" mdhtml "github.com/gomarkdown/markdown/html" "github.com/alecthomas/chroma" "github.com/alecthomas/chroma/formatters/html" "github.com/alecthomas/chroma/lexers" "github.com/alecthomas/chroma/styles" ) var ( htmlFormatter *html.Formatter highlightStyle *chroma.Style ) func init() { htmlFormatter = html.New(html.WithClasses(true), html.TabWidth(2)) if htmlFormatter == nil { panic("couldn't create html formatter") } styleName := "monokailight" highlightStyle = styles.Get(styleName) if highlightStyle == nil { panic(fmt.Sprintf("didn't find style '%s'", styleName)) } } // based on https://github.com/alecthomas/chroma/blob/master/quick/quick.go func htmlHighlight(w io.Writer, source, lang, defaultLang string) error { if lang == "" { lang = defaultLang } l := lexers.Get(lang) if l == nil { l = lexers.Analyse(source) } if l == nil { l = lexers.Fallback } l = chroma.Coalesce(l) it, err := l.Tokenise(nil, source) if err != nil { return err } return htmlFormatter.Format(w, highlightStyle, it) } // an actual rendering of Paragraph is more complicated func renderCode(w io.Writer, codeBlock *ast.CodeBlock, entering bool) { defaultLang := "" lang := string(codeBlock.Info) htmlHighlight(w, string(codeBlock.Literal), lang, defaultLang) } func myRenderHook(w io.Writer, node ast.Node, entering bool) (ast.WalkStatus, bool) { if code, ok := node.(*ast.CodeBlock); ok { renderCode(w, code, entering) return ast.GoToNext, true } return ast.GoToNext, false } func newCustomizedRender() *mdhtml.Renderer { opts := mdhtml.RendererOptions{ Flags: mdhtml.CommonFlags, RenderNodeHook: myRenderHook, } return mdhtml.NewRenderer(opts) } var mds = "code block:\n```go\nvar n = 384\n```" func codeHighlight() { md := []byte(mds) renderer := newCustomizedRender() html := markdown.ToHTML(md, nil, renderer) fmt.Printf("--- Markdown:\n%s\n\n--- HTML:\n%s\n", md, html) } func main() { codeHighlight() }