hugo

Unnamed repository; edit this file 'description' to name the repository.

git clone git://git.shimmy1996.com/hugo.git
commit 00954c5d1fda0b18cd1b847ee580d5f4caa76c70
parent 1b785a7a6d3c264e39e4976c59b618c0ac1ba5f9
Author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Date:   Wed, 18 Dec 2019 17:23:09 +0100

Preserve HTML Text for link render hooks

The context now have two text methods:

* Text - rendered
* PlainText

Fixes #6629

Diffstat:
Mdocs/content/en/getting-started/configuration-markup.md | 5++++-
Mhugolib/content_render_hooks_test.go | 31+++++++++++++++++++++++++++++++
Mmarkup/converter/hooks/hooks.go | 1+
Mmarkup/goldmark/convert.go | 29++++++++++++++++++++++++-----
Mmarkup/goldmark/render_link.go | 25+++++++++++++++++++------
5 files changed, 79 insertions(+), 12 deletions(-)
diff --git a/docs/content/en/getting-started/configuration-markup.md b/docs/content/en/getting-started/configuration-markup.md
@@ -117,7 +117,10 @@ Title
 : The title attribute.
 
 Text
-: The link text.
+: The rendered (HTML) link text.
+
+PlainText
+: The plain variant of the above.
 
 A Markdown example for a inline-style link with title:
 
diff --git a/hugolib/content_render_hooks_test.go b/hugolib/content_render_hooks_test.go
@@ -213,6 +213,37 @@ P3: <p>P3. xml-link: https://www.example.org|</p>
 
 }
 
+// https://github.com/gohugoio/hugo/issues/6629
+func TestRenderLinkWithMarkupInText(t *testing.T) {
+
+	b := newTestSitesBuilder(t)
+
+	b.WithTemplates("index.html", `
+{{ $p := site.GetPage "p1.md" }}
+P1: {{ $p.Content }}
+
+	`,
+		"_default/_markup/render-link.html", `html-link: {{ .Destination | safeURL }}|Text: {{ .Text | safeHTML }}|Plain: {{ .PlainText | safeHTML }}`,
+	)
+
+	b.WithContent("p1.md", `---
+title: "p1"
+---
+
+START: [**should be bold**](https://gohugo.io)END
+
+Some regular **markup**.
+`)
+
+	b.Build(BuildCfg{})
+
+	b.AssertFileContent("public/index.html", `
+  P1: <p>START: html-link: https://gohugo.io|Text: <strong>should be bold</strong>|Plain: should be boldEND</p>
+<p>Some regular <strong>markup</strong>.</p>
+`)
+
+}
+
 func TestRenderString(t *testing.T) {
 
 	b := newTestSitesBuilder(t)
diff --git a/markup/converter/hooks/hooks.go b/markup/converter/hooks/hooks.go
@@ -24,6 +24,7 @@ type LinkContext interface {
 	Destination() string
 	Title() string
 	Text() string
+	PlainText() string
 }
 
 type Render struct {
diff --git a/markup/goldmark/convert.go b/markup/goldmark/convert.go
@@ -15,9 +15,9 @@
 package goldmark
 
 import (
-	"bufio"
 	"bytes"
 	"fmt"
+	"math/bits"
 	"path/filepath"
 	"runtime/debug"
 
@@ -162,8 +162,27 @@ func (c converterResult) GetIdentities() identity.Identities {
 	return c.ids
 }
 
+type bufWriter struct {
+	*bytes.Buffer
+}
+
+const maxInt = 1<<(bits.UintSize-1) - 1
+
+func (b *bufWriter) Available() int {
+	return maxInt
+}
+
+func (b *bufWriter) Buffered() int {
+	return b.Len()
+}
+
+func (b *bufWriter) Flush() error {
+	return nil
+}
+
 type renderContext struct {
-	util.BufWriter
+	*bufWriter
+	pos int
 	renderContextData
 }
 
@@ -205,7 +224,7 @@ func (c *goldmarkConverter) Convert(ctx converter.RenderContext) (result convert
 		}
 	}()
 
-	buf := &bytes.Buffer{}
+	buf := &bufWriter{Buffer: &bytes.Buffer{}}
 	result = buf
 	pctx := newParserContext(ctx)
 	reader := text.NewReader(ctx.Src)
@@ -221,8 +240,8 @@ func (c *goldmarkConverter) Convert(ctx converter.RenderContext) (result convert
 		ids:  identity.NewManager(converterIdentity),
 	}
 
-	w := renderContext{
-		BufWriter:         bufio.NewWriter(buf),
+	w := &renderContext{
+		bufWriter:         buf,
 		renderContextData: rcx,
 	}
 
diff --git a/markup/goldmark/render_link.go b/markup/goldmark/render_link.go
@@ -43,6 +43,7 @@ type linkContext struct {
 	destination string
 	title       string
 	text        string
+	plainText   string
 }
 
 func (ctx linkContext) Destination() string {
@@ -61,6 +62,10 @@ func (ctx linkContext) Text() string {
 	return ctx.text
 }
 
+func (ctx linkContext) PlainText() string {
+	return ctx.plainText
+}
+
 func (ctx linkContext) Title() string {
 	return ctx.title
 }
@@ -146,13 +151,16 @@ func (r *linkRenderer) renderImage(w util.BufWriter, source []byte, node ast.Nod
 		return ast.WalkContinue, nil
 	}
 
+	text := string(n.Text(source))
+
 	err := h.ImageRenderer.Render(
 		w,
 		linkContext{
 			page:        ctx.DocumentContext().Document,
 			destination: string(n.Destination),
 			title:       string(n.Title),
-			text:        string(n.Text(source)),
+			text:        text,
+			plainText:   text,
 		},
 	)
 
@@ -166,7 +174,7 @@ func (r *linkRenderer) renderLink(w util.BufWriter, source []byte, node ast.Node
 	n := node.(*ast.Link)
 	var h *hooks.Render
 
-	ctx, ok := w.(renderContextData)
+	ctx, ok := w.(*renderContext)
 	if ok {
 		h = ctx.RenderContext().RenderHooks
 		ok = h != nil && h.LinkRenderer != nil
@@ -176,24 +184,29 @@ func (r *linkRenderer) renderLink(w util.BufWriter, source []byte, node ast.Node
 		return r.renderDefaultLink(w, source, node, entering)
 	}
 
-	if !entering {
+	if entering {
+		// Store the current pos so we can capture the rendered text.
+		ctx.pos = ctx.Buffer.Len()
 		return ast.WalkContinue, nil
 	}
 
+	text := ctx.Buffer.Bytes()[ctx.pos:]
+	ctx.Buffer.Truncate(ctx.pos)
+
 	err := h.LinkRenderer.Render(
 		w,
 		linkContext{
 			page:        ctx.DocumentContext().Document,
 			destination: string(n.Destination),
 			title:       string(n.Title),
-			text:        string(n.Text(source)),
+			text:        string(text),
+			plainText:   string(n.Text(source)),
 		},
 	)
 
 	ctx.AddIdentity(h.LinkRenderer.GetIdentity())
 
-	// Do not render the inner text.
-	return ast.WalkSkipChildren, err
+	return ast.WalkContinue, err
 
 }