mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05:00
Preserve HTML Text for link render hooks
The context now have two text methods: * Text - rendered * PlainText Fixes #6629
This commit is contained in:
parent
1b785a7a6d
commit
00954c5d1f
5 changed files with 79 additions and 12 deletions
|
@ -117,7 +117,10 @@ Title
|
||||||
: The title attribute.
|
: The title attribute.
|
||||||
|
|
||||||
Text
|
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 Markdown example for a inline-style link with title:
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
func TestRenderString(t *testing.T) {
|
||||||
|
|
||||||
b := newTestSitesBuilder(t)
|
b := newTestSitesBuilder(t)
|
||||||
|
|
|
@ -24,6 +24,7 @@ type LinkContext interface {
|
||||||
Destination() string
|
Destination() string
|
||||||
Title() string
|
Title() string
|
||||||
Text() string
|
Text() string
|
||||||
|
PlainText() string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Render struct {
|
type Render struct {
|
||||||
|
|
|
@ -15,9 +15,9 @@
|
||||||
package goldmark
|
package goldmark
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/bits"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
|
|
||||||
|
@ -162,8 +162,27 @@ func (c converterResult) GetIdentities() identity.Identities {
|
||||||
return c.ids
|
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 {
|
type renderContext struct {
|
||||||
util.BufWriter
|
*bufWriter
|
||||||
|
pos int
|
||||||
renderContextData
|
renderContextData
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,7 +224,7 @@ func (c *goldmarkConverter) Convert(ctx converter.RenderContext) (result convert
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
buf := &bytes.Buffer{}
|
buf := &bufWriter{Buffer: &bytes.Buffer{}}
|
||||||
result = buf
|
result = buf
|
||||||
pctx := newParserContext(ctx)
|
pctx := newParserContext(ctx)
|
||||||
reader := text.NewReader(ctx.Src)
|
reader := text.NewReader(ctx.Src)
|
||||||
|
@ -221,8 +240,8 @@ func (c *goldmarkConverter) Convert(ctx converter.RenderContext) (result convert
|
||||||
ids: identity.NewManager(converterIdentity),
|
ids: identity.NewManager(converterIdentity),
|
||||||
}
|
}
|
||||||
|
|
||||||
w := renderContext{
|
w := &renderContext{
|
||||||
BufWriter: bufio.NewWriter(buf),
|
bufWriter: buf,
|
||||||
renderContextData: rcx,
|
renderContextData: rcx,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ type linkContext struct {
|
||||||
destination string
|
destination string
|
||||||
title string
|
title string
|
||||||
text string
|
text string
|
||||||
|
plainText string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx linkContext) Destination() string {
|
func (ctx linkContext) Destination() string {
|
||||||
|
@ -61,6 +62,10 @@ func (ctx linkContext) Text() string {
|
||||||
return ctx.text
|
return ctx.text
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ctx linkContext) PlainText() string {
|
||||||
|
return ctx.plainText
|
||||||
|
}
|
||||||
|
|
||||||
func (ctx linkContext) Title() string {
|
func (ctx linkContext) Title() string {
|
||||||
return ctx.title
|
return ctx.title
|
||||||
}
|
}
|
||||||
|
@ -146,13 +151,16 @@ func (r *linkRenderer) renderImage(w util.BufWriter, source []byte, node ast.Nod
|
||||||
return ast.WalkContinue, nil
|
return ast.WalkContinue, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
text := string(n.Text(source))
|
||||||
|
|
||||||
err := h.ImageRenderer.Render(
|
err := h.ImageRenderer.Render(
|
||||||
w,
|
w,
|
||||||
linkContext{
|
linkContext{
|
||||||
page: ctx.DocumentContext().Document,
|
page: ctx.DocumentContext().Document,
|
||||||
destination: string(n.Destination),
|
destination: string(n.Destination),
|
||||||
title: string(n.Title),
|
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)
|
n := node.(*ast.Link)
|
||||||
var h *hooks.Render
|
var h *hooks.Render
|
||||||
|
|
||||||
ctx, ok := w.(renderContextData)
|
ctx, ok := w.(*renderContext)
|
||||||
if ok {
|
if ok {
|
||||||
h = ctx.RenderContext().RenderHooks
|
h = ctx.RenderContext().RenderHooks
|
||||||
ok = h != nil && h.LinkRenderer != nil
|
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)
|
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
|
return ast.WalkContinue, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
text := ctx.Buffer.Bytes()[ctx.pos:]
|
||||||
|
ctx.Buffer.Truncate(ctx.pos)
|
||||||
|
|
||||||
err := h.LinkRenderer.Render(
|
err := h.LinkRenderer.Render(
|
||||||
w,
|
w,
|
||||||
linkContext{
|
linkContext{
|
||||||
page: ctx.DocumentContext().Document,
|
page: ctx.DocumentContext().Document,
|
||||||
destination: string(n.Destination),
|
destination: string(n.Destination),
|
||||||
title: string(n.Title),
|
title: string(n.Title),
|
||||||
text: string(n.Text(source)),
|
text: string(text),
|
||||||
|
plainText: string(n.Text(source)),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
ctx.AddIdentity(h.LinkRenderer.GetIdentity())
|
ctx.AddIdentity(h.LinkRenderer.GetIdentity())
|
||||||
|
|
||||||
// Do not render the inner text.
|
return ast.WalkContinue, err
|
||||||
return ast.WalkSkipChildren, err
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue