shithub: hugo

Download patch

ref: 00954c5d1fda0b18cd1b847ee580d5f4caa76c70
parent: 1b785a7a6d3c264e39e4976c59b618c0ac1ba5f9
author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
date: Wed Dec 18 12:23:09 EST 2019

Preserve HTML Text for link render hooks

The context now have two text methods:

* Text - rendered
* PlainText

Fixes #6629

--- a/docs/content/en/getting-started/configuration-markup.md
+++ b/docs/content/en/getting-started/configuration-markup.md
@@ -117,7 +117,10 @@
 : 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:
 
--- a/hugolib/content_render_hooks_test.go
+++ b/hugolib/content_render_hooks_test.go
@@ -213,6 +213,37 @@
 
 }
 
+// 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)
--- a/markup/converter/hooks/hooks.go
+++ b/markup/converter/hooks/hooks.go
@@ -24,6 +24,7 @@
 	Destination() string
 	Title() string
 	Text() string
+	PlainText() string
 }
 
 type Render struct {
--- 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 @@
 	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 @@
 		}
 	}()
 
-	buf := &bytes.Buffer{}
+	buf := &bufWriter{Buffer: &bytes.Buffer{}}
 	result = buf
 	pctx := newParserContext(ctx)
 	reader := text.NewReader(ctx.Src)
@@ -221,8 +240,8 @@
 		ids:  identity.NewManager(converterIdentity),
 	}
 
-	w := renderContext{
-		BufWriter:         bufio.NewWriter(buf),
+	w := &renderContext{
+		bufWriter:         buf,
 		renderContextData: rcx,
 	}
 
--- a/markup/goldmark/render_link.go
+++ b/markup/goldmark/render_link.go
@@ -43,6 +43,7 @@
 	destination string
 	title       string
 	text        string
+	plainText   string
 }
 
 func (ctx linkContext) Destination() string {
@@ -61,6 +62,10 @@
 	return ctx.text
 }
 
+func (ctx linkContext) PlainText() string {
+	return ctx.plainText
+}
+
 func (ctx linkContext) Title() string {
 	return ctx.title
 }
@@ -146,6 +151,8 @@
 		return ast.WalkContinue, nil
 	}
 
+	text := string(n.Text(source))
+
 	err := h.ImageRenderer.Render(
 		w,
 		linkContext{
@@ -152,7 +159,8 @@
 			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 @@
 	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,10 +184,15 @@
 		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{
@@ -186,14 +199,14 @@
 			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
 
 }