URI: 
       Allow markdown attribute lists to be used in title render hooks - hugo - [fork] hugo port for 9front
  HTML git clone git@git.drkhsh.at/hugo.git
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
   DIR README
   DIR LICENSE
       ---
   DIR commit cd0c5d7ef32cbd570af00c50ce760452381df64e
   DIR parent e7e194435b4c566f47d644f2e60c096ea1866254
  HTML Author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
       Date:   Mon, 22 Feb 2021 11:27:14 +0100
       
       Allow markdown attribute lists to be used in title render hooks
       
       Fixes #8270
       
       Diffstat:
         M docs/content/en/getting-started/co… |       3 +++
         M hugolib/content_render_hooks_test.… |      18 ++++++++++++++++--
         M markup/converter/hooks/hooks.go     |       7 +++++++
         M markup/goldmark/render_hooks.go     |      33 ++++++++++++++++++++++++++-----
       
       4 files changed, 54 insertions(+), 7 deletions(-)
       ---
   DIR diff --git a/docs/content/en/getting-started/configuration-markup.md b/docs/content/en/getting-started/configuration-markup.md
       @@ -179,6 +179,9 @@ Text
        PlainText
        : The plain variant of the above.
        
       +Attributes (map) {{< new-in "0.82.0" >}}
       +: A map of attributes (e.g. `id`, `class`)
       +
        #### Link with title Markdown example:
        
        ```md
   DIR diff --git a/hugolib/content_render_hooks_test.go b/hugolib/content_render_hooks_test.go
       @@ -60,6 +60,16 @@ func TestRenderHooks(t *testing.T) {
                config := `
        baseURL="https://example.org"
        workingDir="/mywork"
       +
       +[markup]
       +[markup.goldmark]
       +[markup.goldmark.parser]
       +autoHeadingID = true
       +autoHeadingIDType = "github"
       +[markup.goldmark.parser.attribute]
       +block = true
       +title = true
       +
        `
                b := newTestSitesBuilder(t).WithWorkingDir("/mywork").WithConfigFile("toml", config).Running()
                b.WithTemplatesAdded("_default/single.html", `{{ .Content }}`)
       @@ -85,7 +95,7 @@ Inner Block: {{ .Inner | .Page.RenderString (dict "display" "block" ) }}
                b.WithTemplatesAdded("_default/_markup/render-link.html", `{{ with .Page }}{{ .Title }}{{ end }}|{{ .Destination | safeURL }}|Title: {{ .Title | safeHTML }}|Text: {{ .Text | safeHTML }}|END`)
                b.WithTemplatesAdded("docs/_markup/render-link.html", `Link docs section: {{ .Text | safeHTML }}|END`)
                b.WithTemplatesAdded("_default/_markup/render-image.html", `IMAGE: {{ .Page.Title }}||{{ .Destination | safeURL }}|Title: {{ .Title | safeHTML }}|Text: {{ .Text | safeHTML }}|END`)
       -        b.WithTemplatesAdded("_default/_markup/render-heading.html", `HEADING: {{ .Page.Title }}||Level: {{ .Level }}|Anchor: {{ .Anchor | safeURL }}|Text: {{ .Text | safeHTML }}|END`)
       +        b.WithTemplatesAdded("_default/_markup/render-heading.html", `HEADING: {{ .Page.Title }}||Level: {{ .Level }}|Anchor: {{ .Anchor | safeURL }}|Text: {{ .Text | safeHTML }}|Attributes: {{ .Attributes }}|END`)
                b.WithTemplatesAdded("docs/_markup/render-heading.html", `Docs Level: {{ .Level }}|END`)
        
                b.WithContent("customview/p1.md", `---
       @@ -108,6 +118,10 @@ Image:
        
        ![Drag Racing](/images/Dragster.jpg "image title")
        
       +Attributes:
       +
       +## Some Heading {.text-serif #a-heading title="Hovered"} 
       +
        
        `, "blog/p2.md", `---
        title: Cool Page2
       @@ -238,7 +252,7 @@ SHORT3|
                // We may add type template support later, keep this for then. b.AssertFileContent("public/docs/docs1/index.html", `DOCS EDITED: https://www.google.com|</p>`)
                b.AssertFileContent("public/blog/p4/index.html", `IMAGE EDITED: /images/Dragster.jpg|`)
                b.AssertFileContent("public/blog/p6/index.html", "<p>Inner Link: EDITED: https://www.gohugo.io|</p>")
       -        b.AssertFileContent("public/blog/p7/index.html", "HEADING: With Headings||Level: 1|Anchor: heading-level-1|Text: Heading Level 1|END<p>some text</p>\nHEADING: With Headings||Level: 2|Anchor: heading-level-2|Text: Heading Level 2|ENDHEADING: With Headings||Level: 3|Anchor: heading-level-3|Text: Heading Level 3|END")
       +        b.AssertFileContent("public/blog/p7/index.html", "HEADING: With Headings||Level: 1|Anchor: heading-level-1|Text: Heading Level 1|Attributes: map[id:heading-level-1]|END<p>some text</p>\nHEADING: With Headings||Level: 2|Anchor: heading-level-2|Text: Heading Level 2|Attributes: map[id:heading-level-2]|ENDHEADING: With Headings||Level: 3|Anchor: heading-level-3|Text: Heading Level 3|Attributes: map[id:heading-level-3]|END")
        
                // https://github.com/gohugoio/hugo/issues/7349
                b.AssertFileContent("public/docs/p8/index.html", "Docs Level: 1")
   DIR diff --git a/markup/converter/hooks/hooks.go b/markup/converter/hooks/hooks.go
       @@ -19,6 +19,10 @@ import (
                "github.com/gohugoio/hugo/identity"
        )
        
       +type AttributesProvider interface {
       +        Attributes() map[string]string
       +}
       +
        type LinkContext interface {
                Page() interface{}
                Destination() string
       @@ -45,6 +49,9 @@ type HeadingContext interface {
                Text() string
                // PlainText is the unrendered version of Text.
                PlainText() string
       +
       +        // Attributes (e.g. CSS classes)
       +        AttributesProvider
        }
        
        // HeadingRenderer describes a uniquely identifiable rendering hook.
   DIR diff --git a/markup/goldmark/render_hooks.go b/markup/goldmark/render_hooks.go
       @@ -14,6 +14,8 @@
        package goldmark
        
        import (
       +        "sync"
       +
                "github.com/gohugoio/hugo/markup/converter/hooks"
        
                "github.com/yuin/goldmark"
       @@ -38,6 +40,25 @@ func newLinks() goldmark.Extender {
                return &links{}
        }
        
       +type attributesHolder struct {
       +        // What we get from Goldmark.
       +        astAttributes []ast.Attribute
       +
       +        // What we send to the the render hooks.
       +        attributesInit sync.Once
       +        attributes     map[string]string
       +}
       +
       +func (a *attributesHolder) Attributes() map[string]string {
       +        a.attributesInit.Do(func() {
       +                a.attributes = make(map[string]string)
       +                for _, attr := range a.astAttributes {
       +                        a.attributes[string(attr.Name)] = string(util.EscapeHTML(attr.Value.([]byte)))
       +                }
       +        })
       +        return a.attributes
       +}
       +
        type linkContext struct {
                page        interface{}
                destination string
       @@ -76,6 +97,7 @@ type headingContext struct {
                anchor    string
                text      string
                plainText string
       +        *attributesHolder
        }
        
        func (ctx headingContext) Page() interface{} {
       @@ -301,11 +323,12 @@ func (r *hookedRenderer) renderHeading(w util.BufWriter, source []byte, node ast
                err := h.HeadingRenderer.RenderHeading(
                        w,
                        headingContext{
       -                        page:      ctx.DocumentContext().Document,
       -                        level:     n.Level,
       -                        anchor:    string(anchor),
       -                        text:      string(text),
       -                        plainText: string(n.Text(source)),
       +                        page:             ctx.DocumentContext().Document,
       +                        level:            n.Level,
       +                        anchor:           string(anchor),
       +                        text:             string(text),
       +                        plainText:        string(n.Text(source)),
       +                        attributesHolder: &attributesHolder{astAttributes: n.Attributes()},
                        },
                )