diff options
Diffstat (limited to 'html')
| -rw-r--r-- | html/highlight.go | 75 | ||||
| -rw-r--r-- | html/html.go | 13 |
2 files changed, 82 insertions, 6 deletions
diff --git a/html/highlight.go b/html/highlight.go new file mode 100644 index 0000000..72b8d79 --- /dev/null +++ b/html/highlight.go @@ -0,0 +1,75 @@ +package html + +import ( + "fmt" + "io" + + "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" +) + +type Highlighter struct { + htmlFormatter *html.Formatter + highlightStyle *chroma.Style +} + +func (h Highlighter) 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 h.htmlFormatter.Format(w, h.highlightStyle, it) +} + +func (h Highlighter) renderCode(w io.Writer, codeBlock *ast.CodeBlock, entering bool) { + defaultLang := "" + lang := string(codeBlock.Info) + h.htmlHighlight(w, string(codeBlock.Literal), lang, defaultLang) +} + +func (h Highlighter) myRenderHook(w io.Writer, node ast.Node, entering bool) (ast.WalkStatus, bool) { + if code, ok := node.(*ast.CodeBlock); ok { + h.renderCode(w, code, entering) + return ast.GoToNext, true + } + return ast.GoToNext, false +} + +func newRenderer() *mdhtml.Renderer { + 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)) + } + h := Highlighter{ + htmlFormatter: htmlFormatter, + highlightStyle: highlightStyle, + } + opts := mdhtml.RendererOptions{ + Flags: mdhtml.CommonFlags, + RenderNodeHook: h.myRenderHook, + } + return mdhtml.NewRenderer(opts) +} diff --git a/html/html.go b/html/html.go index fe1bbee..8b088a7 100644 --- a/html/html.go +++ b/html/html.go @@ -2,18 +2,19 @@ package html import ( "github.com/gomarkdown/markdown" - "github.com/gomarkdown/markdown/html" "github.com/gomarkdown/markdown/parser" ) func MDToHTML(md []byte) []byte { extensions := parser.CommonExtensions | parser.AutoHeadingIDs | parser.NoEmptyLineBeforeBlock p := parser.NewWithExtensions(extensions) - doc := p.Parse(md) + // doc := p.Parse(md) - htmlFlags := html.CommonFlags - opts := html.RendererOptions{Flags: htmlFlags} - renderer := html.NewRenderer(opts) + // htmlFlags := html.CommonFlags + // opts := html.RendererOptions{Flags: htmlFlags} + // renderer := html.NewRenderer(opts) - return markdown.Render(doc, renderer) + // return markdown.Render(doc, renderer) + renderer := newRenderer() + return markdown.ToHTML(md, p, renderer) } |
