markup/goldmark: Improve attributes vs options

Fixes #9571
This commit is contained in:
Bjørn Erik Pedersen 2022-02-26 17:24:10 +01:00
parent 928a896962
commit 579ff9b652
6 changed files with 41 additions and 19 deletions

View file

@ -1798,6 +1798,10 @@ func (hr hookRendererTemplate) ResolvePosition(ctx interface{}) text.Position {
return hr.resolvePosition(ctx)
}
func (hr hookRendererTemplate) IsDefaultCodeBlockRenderer() bool {
return false
}
func (s *Site) renderForTemplate(name, outputFormat string, d interface{}, w io.Writer, templ tpl.Template) (err error) {
if templ == nil {
s.logMissingLayout(name, "", "", outputFormat)

View file

@ -90,11 +90,11 @@ type HeadingRenderer interface {
identity.Provider
}
// ElementPositionRevolver provides a way to resolve the start Position
// ElementPositionResolver provides a way to resolve the start Position
// of a markdown element in the original source document.
// This may be both slow and aproximate, so should only be
// used for error logging.
type ElementPositionRevolver interface {
type ElementPositionResolver interface {
ResolvePosition(ctx interface{}) text.Position
}

View file

@ -14,6 +14,7 @@
package codeblocks_test
import (
"strings"
"testing"
"github.com/gohugoio/hugo/hugolib"
@ -176,7 +177,7 @@ Position: {{ .Position | safeHTML }}
}
// Issue 9571
func TestOptionsNonChroma(t *testing.T) {
func TestAttributesChroma(t *testing.T) {
t.Parallel()
files := `
@ -188,23 +189,27 @@ title: "p1"
## Code
§§§bash {style=monokai}
§§§LANGUAGE {style=monokai}
echo "p1";
§§§
-- layouts/_default/single.html --
{{ .Content }}
-- layouts/_default/_markup/render-codeblock.html --
Style: {{ .Attributes }}|
Attributes: {{ .Attributes }}|Options: {{ .Options }}|
`
testLanguage := func(language, expect string) {
b := hugolib.NewIntegrationTestBuilder(
hugolib.IntegrationTestConfig{
T: t,
TxtarString: strings.ReplaceAll(files, "LANGUAGE", language),
},
).Build()
b := hugolib.NewIntegrationTestBuilder(
hugolib.IntegrationTestConfig{
T: t,
TxtarString: files,
},
).Build()
b.AssertFileContent("public/p1/index.html", expect)
}
b.AssertFileContent("public/p1/index.html", "asdfadf")
testLanguage("bash", "Attributes: map[]|Options: map[style:monokai]|")
testLanguage("hugo", "Attributes: map[style:monokai]|Options: map[]|")
}

View file

@ -18,7 +18,7 @@ import (
"fmt"
"sync"
"github.com/gohugoio/hugo/common/herrors"
"github.com/alecthomas/chroma/lexers"
htext "github.com/gohugoio/hugo/common/text"
"github.com/gohugoio/hugo/markup/converter/hooks"
"github.com/gohugoio/hugo/markup/goldmark/internal/render"
@ -61,8 +61,6 @@ func (r *htmlRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) {
}
func (r *htmlRenderer) renderCodeBlock(w util.BufWriter, src []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
defer herrors.Recover()
ctx := w.(*render.Context)
if entering {
@ -92,17 +90,26 @@ func (r *htmlRenderer) renderCodeBlock(w util.BufWriter, src []byte, node ast.No
if n.b.Info != nil {
info = n.b.Info.Segment.Value(src)
}
attrtp := attributes.AttributesOwnerCodeBlockCustom
if isd, ok := renderer.(hooks.IsDefaultCodeBlockRendererProvider); (ok && isd.IsDefaultCodeBlockRenderer()) || lexers.Get(lang) != nil {
// We say that this is a Chroma code block if it's the default code block renderer
// or if the language is supported by Chroma.
attrtp = attributes.AttributesOwnerCodeBlockChroma
}
// IsDefaultCodeBlockRendererProvider
attrs := getAttributes(n.b, info)
cbctx := &codeBlockContext{
page: ctx.DocumentContext().Document,
lang: lang,
code: s,
ordinal: ordinal,
AttributesHolder: attributes.New(attrs, attributes.AttributesOwnerCodeBlock),
AttributesHolder: attributes.New(attrs, attrtp),
}
cbctx.createPos = func() htext.Position {
if resolver, ok := renderer.(hooks.ElementPositionRevolver); ok {
if resolver, ok := renderer.(hooks.ElementPositionResolver); ok {
return resolver.ResolvePosition(cbctx)
}
return htext.Position{

View file

@ -61,6 +61,7 @@ type Highlighter interface {
Highlight(code, lang string, opts interface{}) (string, error)
HighlightCodeBlock(ctx hooks.CodeblockContext, opts interface{}) (HightlightResult, error)
hooks.CodeBlockRenderer
hooks.IsDefaultCodeBlockRendererProvider
}
type chromaHighlighter struct {
@ -129,6 +130,10 @@ func (h chromaHighlighter) RenderCodeblock(w hugio.FlexiWriter, ctx hooks.Codebl
return highlight(w, code, ctx.Lang(), attributes, cfg)
}
func (h chromaHighlighter) IsDefaultCodeBlockRenderer() bool {
return true
}
var id = identity.NewPathIdentity("chroma", "highlight")
func (h chromaHighlighter) GetIdentity() identity.Identity {

View file

@ -50,7 +50,8 @@ type AttributesOwnerType int
const (
AttributesOwnerGeneral AttributesOwnerType = iota
AttributesOwnerCodeBlock
AttributesOwnerCodeBlockChroma
AttributesOwnerCodeBlockCustom
)
func New(astAttributes []ast.Attribute, ownerType AttributesOwnerType) *AttributesHolder {
@ -99,7 +100,7 @@ func New(astAttributes []ast.Attribute, ownerType AttributesOwnerType) *Attribut
panic(fmt.Sprintf("not implemented: %T", vvv))
}
if ownerType == AttributesOwnerCodeBlock && chromaHightlightProcessingAttributes[nameLower] {
if ownerType == AttributesOwnerCodeBlockChroma && chromaHightlightProcessingAttributes[nameLower] {
attr := Attribute{Name: string(v.Name), Value: vv}
opts = append(opts, attr)
} else {