From a783270b09af3d873c08a01d13f802018b69fb02 Mon Sep 17 00:00:00 2001 From: a73x Date: Sun, 29 Dec 2024 19:13:27 +0000 Subject: new markdown renderer since TOC has a title now and it can compact toc headers, we can use header 2 for everything use the built in goldmark extension for syntax highlighting --- html/highlight.go | 79 ------------------------------------------------------- html/html.go | 61 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 55 insertions(+), 85 deletions(-) (limited to 'html') diff --git a/html/highlight.go b/html/highlight.go index d198ad0..621abdb 100644 --- a/html/highlight.go +++ b/html/highlight.go @@ -1,80 +1 @@ package html - -import ( - "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 -} - -type opts struct { -} - -func newRenderer(hasToc bool) *mdhtml.Renderer { - - htmlFormatter := html.New(html.WithClasses(true), html.TabWidth(2)) - - styleName := "monokailight" - highlightStyle := styles.Get(styleName) - - h := Highlighter{ - htmlFormatter: htmlFormatter, - highlightStyle: highlightStyle, - } - - flags := mdhtml.CommonFlags | mdhtml.FootnoteReturnLinks - if hasToc { - flags = flags | mdhtml.TOC - } - - opts := mdhtml.RendererOptions{ - Flags: flags, - RenderNodeHook: h.myRenderHook, - } - return mdhtml.NewRenderer(opts) -} diff --git a/html/html.go b/html/html.go index 40a6ad5..bd3139e 100644 --- a/html/html.go +++ b/html/html.go @@ -1,14 +1,63 @@ package html import ( - "github.com/gomarkdown/markdown" - "github.com/gomarkdown/markdown/parser" + "bytes" + + "github.com/yuin/goldmark" + "github.com/yuin/goldmark/extension" + "github.com/yuin/goldmark/parser" + "github.com/yuin/goldmark/renderer/html" + "go.abhg.dev/goldmark/toc" + + "github.com/alecthomas/chroma/v2" + chromahtml "github.com/alecthomas/chroma/v2/formatters/html" + chromastyles "github.com/alecthomas/chroma/v2/styles" + highlighting "github.com/yuin/goldmark-highlighting/v2" ) func MDToHTML(md []byte, hasToc bool) []byte { - extensions := parser.CommonExtensions | parser.AutoHeadingIDs | parser.NoEmptyLineBeforeBlock | parser.Footnotes - p := parser.NewWithExtensions(extensions) + style := chromastyles.Get("autumn") + style, err := style.Builder().Add(chroma.Background, "bg:#f0f0f0").Build() + if err != nil { + return nil + } + + extensions := []goldmark.Extender{ + extension.GFM, + extension.Footnote, + highlighting.NewHighlighting( + highlighting.WithCustomStyle(style), + highlighting.WithFormatOptions( + chromahtml.WrapLongLines(true), + chromahtml.InlineCode(true), + chromahtml.TabWidth(4), + chromahtml.PreventSurroundingPre(false), + ), + ), + } + + if hasToc { + extensions = append(extensions, &toc.Extender{ + Compact: true, + }) + } + + converter := goldmark.New( + goldmark.WithExtensions(extensions...), + goldmark.WithParserOptions( + parser.WithAutoHeadingID(), + ), + goldmark.WithRendererOptions( + html.WithHardWraps(), + html.WithXHTML(), + ), + ) + + var buf bytes.Buffer + err = converter.Convert(md, &buf) + if err != nil { + return nil + } - renderer := newRenderer(hasToc) - return markdown.ToHTML(md, p, renderer) + return buf.Bytes() } -- cgit v1.2.3