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
This commit is contained in:
Bjørn Erik Pedersen
2023-02-24 07:23:10 +01:00
parent e442a63bb7
commit 271318ad78
14 changed files with 258 additions and 45 deletions

View File

@@ -74,7 +74,7 @@ var NopConverter = new(nopConverter)
type nopConverter int
func (nopConverter) Convert(ctx RenderContext) (Result, error) {
func (nopConverter) Convert(ctx RenderContext) (ResultRender, error) {
return &bytes.Buffer{}, nil
}
@@ -85,15 +85,29 @@ func (nopConverter) Supports(feature identity.Identity) bool {
// Converter wraps the Convert method that converts some markup into
// another format, e.g. Markdown to HTML.
type Converter interface {
Convert(ctx RenderContext) (Result, error)
Convert(ctx RenderContext) (ResultRender, error)
Supports(feature identity.Identity) bool
}
// Result represents the minimum returned from Convert.
type Result interface {
// ParseRenderer is an optional interface.
// The Goldmark converter implements this, and this allows us
// to extract the ToC without having to render the content.
type ParseRenderer interface {
Parse(RenderContext) (ResultParse, error)
Render(RenderContext, any) (ResultRender, error)
}
// ResultRender represents the minimum returned from Convert and Render.
type ResultRender interface {
Bytes() []byte
}
// ResultParse represents the minimum returned from Parse.
type ResultParse interface {
Doc() any
TableOfContents() *tableofcontents.Fragments
}
// DocumentInfo holds additional information provided by some converters.
type DocumentInfo interface {
AnchorSuffix() string