diff options
author | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2022-12-03 12:33:48 +0100 |
---|---|---|
committer | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2022-12-05 15:00:47 +0100 |
commit | 63126c6359a693345a3a81b22e0f95660b248044 (patch) | |
tree | 7f2fdf6af58735564cf3be57efbdad594150fa05 /markup/goldmark/render_hooks.go | |
parent | 535ea8cc9bf20b1ba6f656f9f3eee3818c6dc537 (diff) |
markup/goldmark: Add removeSurroundingParagraph for Markdown images
* Removes any surrounding paragraph nodes
* And transfers any attributes from the surrounding paragraph down to the image node
* Adds IsBlock and Ordinal (zero based) field to the image context passed to the image render hooks
IsBlock is set to true if `wrapStandAloneImageWithinParagraph = false` and the image's parent node has only one child.
Closes #8362
Fixes #10492
Fixes #10494
Fixes #10501
Diffstat (limited to 'markup/goldmark/render_hooks.go')
-rw-r--r-- | markup/goldmark/render_hooks.go | 89 |
1 files changed, 70 insertions, 19 deletions
diff --git a/markup/goldmark/render_hooks.go b/markup/goldmark/render_hooks.go index e28f816d6..f36f9f4e6 100644 --- a/markup/goldmark/render_hooks.go +++ b/markup/goldmark/render_hooks.go @@ -20,6 +20,7 @@ import ( "github.com/gohugoio/hugo/common/types/hstring" "github.com/gohugoio/hugo/markup/converter/hooks" "github.com/gohugoio/hugo/markup/goldmark/goldmark_config" + "github.com/gohugoio/hugo/markup/goldmark/images" "github.com/gohugoio/hugo/markup/goldmark/internal/render" "github.com/gohugoio/hugo/markup/internal/attributes" @@ -52,16 +53,13 @@ type linkContext struct { title string text hstring.RenderedString plainText string + *attributes.AttributesHolder } func (ctx linkContext) Destination() string { return ctx.destination } -func (ctx linkContext) Resolved() bool { - return false -} - func (ctx linkContext) Page() any { return ctx.page } @@ -78,6 +76,20 @@ func (ctx linkContext) Title() string { return ctx.title } +type imageLinkContext struct { + linkContext + ordinal int + isBlock bool +} + +func (ctx imageLinkContext) IsBlock() bool { + return ctx.isBlock +} + +func (ctx imageLinkContext) Ordinal() int { + return ctx.ordinal +} + type headingContext struct { page any level int @@ -151,14 +163,36 @@ func (r *hookedRenderer) renderImage(w util.BufWriter, source []byte, node ast.N text := ctx.Buffer.Bytes()[pos:] ctx.Buffer.Truncate(pos) + var ( + isBlock bool + ordinal int + ) + if b, ok := n.AttributeString(images.AttrIsBlock); ok && b.(bool) { + isBlock = true + } + if n, ok := n.AttributeString(images.AttrOrdinal); ok { + ordinal = n.(int) + } + + // We use the attributes to signal from the parser whether the image is in + // a block context or not. + // We may find a better way to do that, but for now, we'll need to remove any + // internal attributes before rendering. + attrs := r.filterInternalAttributes(n.Attributes()) + err := lr.RenderLink( w, - linkContext{ - page: ctx.DocumentContext().Document, - destination: string(n.Destination), - title: string(n.Title), - text: hstring.RenderedString(text), - plainText: string(n.Text(source)), + imageLinkContext{ + linkContext: linkContext{ + page: ctx.DocumentContext().Document, + destination: string(n.Destination), + title: string(n.Title), + text: hstring.RenderedString(text), + plainText: string(n.Text(source)), + AttributesHolder: attributes.New(attrs, attributes.AttributesOwnerGeneral), + }, + ordinal: ordinal, + isBlock: isBlock, }, ) @@ -167,6 +201,17 @@ func (r *hookedRenderer) renderImage(w util.BufWriter, source []byte, node ast.N return ast.WalkContinue, err } +func (r *hookedRenderer) filterInternalAttributes(attrs []ast.Attribute) []ast.Attribute { + n := 0 + for _, x := range attrs { + if !bytes.HasPrefix(x.Name, []byte(internalAttrPrefix)) { + attrs[n] = x + n++ + } + } + return attrs[:n] +} + // Fall back to the default Goldmark render funcs. Method below borrowed from: // https://github.com/yuin/goldmark/blob/b611cd333a492416b56aa8d94b04a67bf0096ab2/renderer/html/html.go#L404 func (r *hookedRenderer) renderImageDefault(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) { @@ -186,6 +231,10 @@ func (r *hookedRenderer) renderImageDefault(w util.BufWriter, source []byte, nod r.Writer.Write(w, n.Title) _ = w.WriteByte('"') } + if n.Attributes() != nil { + attrs := r.filterInternalAttributes(n.Attributes()) + attributes.RenderASTAttributes(w, attrs...) + } if r.XHTML { _, _ = w.WriteString(" />") } else { @@ -224,11 +273,12 @@ func (r *hookedRenderer) renderLink(w util.BufWriter, source []byte, node ast.No err := lr.RenderLink( w, linkContext{ - page: ctx.DocumentContext().Document, - destination: string(n.Destination), - title: string(n.Title), - text: hstring.RenderedString(text), - plainText: string(n.Text(source)), + page: ctx.DocumentContext().Document, + destination: string(n.Destination), + title: string(n.Title), + text: hstring.RenderedString(text), + plainText: string(n.Text(source)), + AttributesHolder: attributes.Empty, }, ) @@ -292,10 +342,11 @@ func (r *hookedRenderer) renderAutoLink(w util.BufWriter, source []byte, node as err := lr.RenderLink( w, linkContext{ - page: ctx.DocumentContext().Document, - destination: url, - text: hstring.RenderedString(label), - plainText: label, + page: ctx.DocumentContext().Document, + destination: url, + text: hstring.RenderedString(label), + plainText: label, + AttributesHolder: attributes.Empty, }, ) |