diff options
author | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2023-02-24 07:23:10 +0100 |
---|---|---|
committer | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2023-02-24 10:40:06 +0100 |
commit | 271318ad787ee2442c6d553edffaa29e1d9a4cf7 (patch) | |
tree | 4314daa1667ecb7badff421a5c19e51f5ea7bc4f /markup/goldmark/convert.go | |
parent | e442a63bb7659d95aec2d48bf954cd9d61163559 (diff) |
Split parse and render for Goldmark
This also speeds up situations where you only need the fragments/toc and not the rendered content, e.g. Related
with fragments type indexing:
```bash
name old time/op new time/op delta
RelatedSite-10 12.3ms ± 2% 10.7ms ± 1% -12.95% (p=0.029 n=4+4)
name old alloc/op new alloc/op delta
RelatedSite-10 38.6MB ± 0% 38.2MB ± 0% -1.08% (p=0.029 n=4+4)
name old allocs/op new allocs/op delta
RelatedSite-10 117k ± 0% 115k ± 0% -1.36% (p=0.029 n=4+4)
```
Fixes #10750
Diffstat (limited to 'markup/goldmark/convert.go')
-rw-r--r-- | markup/goldmark/convert.go | 72 |
1 files changed, 58 insertions, 14 deletions
diff --git a/markup/goldmark/convert.go b/markup/goldmark/convert.go index 6c1c7ad0a..3c8dbb299 100644 --- a/markup/goldmark/convert.go +++ b/markup/goldmark/convert.go @@ -18,6 +18,7 @@ import ( "bytes" "github.com/gohugoio/hugo/identity" + "github.com/gohugoio/hugo/markup/goldmark/codeblocks" "github.com/gohugoio/hugo/markup/goldmark/images" "github.com/gohugoio/hugo/markup/goldmark/internal/extensions/attributes" @@ -26,6 +27,7 @@ import ( "github.com/gohugoio/hugo/markup/converter" "github.com/gohugoio/hugo/markup/tableofcontents" "github.com/yuin/goldmark" + "github.com/yuin/goldmark/ast" "github.com/yuin/goldmark/extension" "github.com/yuin/goldmark/parser" "github.com/yuin/goldmark/renderer" @@ -158,26 +160,41 @@ func newMarkdown(pcfg converter.ProviderConfig) goldmark.Markdown { var _ identity.IdentitiesProvider = (*converterResult)(nil) -type converterResult struct { - converter.Result +type parserResult struct { + doc any toc *tableofcontents.Fragments +} + +func (p parserResult) Doc() any { + return p.doc +} + +func (p parserResult) TableOfContents() *tableofcontents.Fragments { + return p.toc +} + +type renderResult struct { + converter.ResultRender ids identity.Identities } -func (c converterResult) TableOfContents() *tableofcontents.Fragments { - return c.toc +func (r renderResult) GetIdentities() identity.Identities { + return r.ids } -func (c converterResult) GetIdentities() identity.Identities { - return c.ids +type converterResult struct { + converter.ResultRender + tableOfContentsProvider + identity.IdentitiesProvider } -var converterIdentity = identity.KeyValueIdentity{Key: "goldmark", Value: "converter"} +type tableOfContentsProvider interface { + TableOfContents() *tableofcontents.Fragments +} -func (c *goldmarkConverter) Convert(ctx converter.RenderContext) (result converter.Result, err error) { +var converterIdentity = identity.KeyValueIdentity{Key: "goldmark", Value: "converter"} - buf := &render.BufWriter{Buffer: &bytes.Buffer{}} - result = buf +func (c *goldmarkConverter) Parse(ctx converter.RenderContext) (converter.ResultParse, error) { pctx := c.newParserContext(ctx) reader := text.NewReader(ctx.Src) @@ -186,6 +203,16 @@ func (c *goldmarkConverter) Convert(ctx converter.RenderContext) (result convert parser.WithContext(pctx), ) + return parserResult{ + doc: doc, + toc: pctx.TableOfContents(), + }, nil + +} +func (c *goldmarkConverter) Render(ctx converter.RenderContext, doc any) (converter.ResultRender, error) { + n := doc.(ast.Node) + buf := &render.BufWriter{Buffer: &bytes.Buffer{}} + rcx := &render.RenderContextDataHolder{ Rctx: ctx, Dctx: c.ctx, @@ -197,15 +224,32 @@ func (c *goldmarkConverter) Convert(ctx converter.RenderContext) (result convert ContextData: rcx, } - if err := c.md.Renderer().Render(w, ctx.Src, doc); err != nil { + if err := c.md.Renderer().Render(w, ctx.Src, n); err != nil { return nil, err } + return renderResult{ + ResultRender: buf, + ids: rcx.IDs.GetIdentities(), + }, nil + +} + +func (c *goldmarkConverter) Convert(ctx converter.RenderContext) (converter.ResultRender, error) { + parseResult, err := c.Parse(ctx) + if err != nil { + return nil, err + } + renderResult, err := c.Render(ctx, parseResult.Doc()) + if err != nil { + return nil, err + } return converterResult{ - Result: buf, - ids: rcx.IDs.GetIdentities(), - toc: pctx.TableOfContents(), + ResultRender: renderResult, + tableOfContentsProvider: parseResult, + IdentitiesProvider: renderResult.(identity.IdentitiesProvider), }, nil + } var featureSet = map[identity.Identity]bool{ |