b.AssertFileContent("public/p1/index.html", `Link First Link|PARTIAL1_EDITED PARTIAL2_EDITEDEND`)
}
-
func TestRenderHooks(t *testing.T) {
config := `
baseURL="https://example.org"
---
[First Link](https://www.google.com "Google's Homepage")
+<https://foo.bar/>
+https://bar.baz/
+<fake@example.com>
+<mailto:fake2@example.com>
{{< myshortcode3 >}}
b.Assert(int(counters.contentRenderCounter), qt.Equals, 45)
b.AssertFileContent("public/blog/p1/index.html", `
-<p>Cool Page|https://www.google.com|Title: Google's Homepage|Text: First Link|END</p>
+Cool Page|https://www.google.com|Title: Google's Homepage|Text: First Link|END
+Cool Page|https://foo.bar/|Title: |Text: https://foo.bar/|END
+Cool Page|https://bar.baz/|Title: |Text: https://bar.baz/|END
+Cool Page|mailto:fake@example.com|Title: |Text: fake@example.com|END
+Cool Page|mailto:fake2@example.com|Title: |Text: mailto:fake2@example.com|END
Text: Second
SHORT3|
<p>IMAGE: Cool Page||/images/Dragster.jpg|Title: image title|Text: Drag Racing|END</p>
package goldmark
import (
+ "fmt"
"strings"
"testing"
[Live Demo here!](https://docuapi.netlify.com/)
[I'm an inline-style link with title](https://www.google.com "Google's Homepage")
+<https://foo.bar/>
+https://bar.baz/
+<fake@example.com>
+<mailto:fake2@example.com>
## Code Fences
b := convert(c, mconf, content)
got := string(b.Bytes())
+ fmt.Println(got)
+
// Links
- // c.Assert(got, qt.Contains, `<a href="https://docuapi.netlify.com/">Live Demo here!</a>`)
+ c.Assert(got, qt.Contains, `<a href="https://docuapi.netlify.com/">Live Demo here!</a>`)
+ c.Assert(got, qt.Contains, `<a href="https://foo.bar/">https://foo.bar/</a>`)
+ c.Assert(got, qt.Contains, `<a href="https://bar.baz/">https://bar.baz/</a>`)
+ c.Assert(got, qt.Contains, `<a href="mailto:fake@example.com">fake@example.com</a>`)
+ c.Assert(got, qt.Contains, `<a href="mailto:fake2@example.com">mailto:fake2@example.com</a></p>`)
// Header IDs
c.Assert(got, qt.Contains, `<h2 id="custom">Custom ID</h2>`, qt.Commentf(got))
import (
"bytes"
+ "strings"
"sync"
"github.com/spf13/cast"
// RegisterFuncs implements NodeRenderer.RegisterFuncs.
func (r *hookedRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) {
reg.Register(ast.KindLink, r.renderLink)
+ reg.Register(ast.KindAutoLink, r.renderAutoLink)
reg.Register(ast.KindImage, r.renderImage)
reg.Register(ast.KindHeading, r.renderHeading)
}
return ast.WalkContinue, err
}
+func (r *hookedRenderer) renderAutoLink(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
+ if !entering {
+ return ast.WalkContinue, nil
+ }
+
+ n := node.(*ast.AutoLink)
+ var h hooks.Renderers
+
+ ctx, ok := w.(*renderContext)
+ if ok {
+ h = ctx.RenderContext().RenderHooks
+ ok = h.LinkRenderer != nil
+ }
+
+ if !ok {
+ return r.renderDefaultAutoLink(w, source, node, entering)
+ }
+
+ url := string(n.URL(source))
+ label := string(n.Label(source))
+ if n.AutoLinkType == ast.AutoLinkEmail && !strings.HasPrefix(strings.ToLower(url), "mailto:") {
+ url = "mailto:" + url
+ }
+
+ err := h.LinkRenderer.RenderLink(
+ w,
+ linkContext{
+ page: ctx.DocumentContext().Document,
+ destination: url,
+ text: label,
+ plainText: label,
+ },
+ )
+
+ // TODO(bep) I have a working branch that fixes these rather confusing identity types,
+ // but for now it's important that it's not .GetIdentity() that's added here,
+ // to make sure we search the entire chain on changes.
+ ctx.AddIdentity(h.LinkRenderer)
+
+ return ast.WalkContinue, err
+}
+
+// Fall back to the default Goldmark render funcs. Method below borrowed from:
+// https://github.com/yuin/goldmark/blob/5588d92a56fe1642791cf4aa8e9eae8227cfeecd/renderer/html/html.go#L439
+func (r *hookedRenderer) renderDefaultAutoLink(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
+ n := node.(*ast.AutoLink)
+ if !entering {
+ return ast.WalkContinue, nil
+ }
+ _, _ = w.WriteString(`<a href="`)
+ url := n.URL(source)
+ label := n.Label(source)
+ if n.AutoLinkType == ast.AutoLinkEmail && !bytes.HasPrefix(bytes.ToLower(url), []byte("mailto:")) {
+ _, _ = w.WriteString("mailto:")
+ }
+ _, _ = w.Write(util.EscapeHTML(util.URLEscape(url, false)))
+ if n.Attributes() != nil {
+ _ = w.WriteByte('"')
+ html.RenderAttributes(w, n, html.LinkAttributeFilter)
+ _ = w.WriteByte('>')
+ } else {
+ _, _ = w.WriteString(`">`)
+ }
+ _, _ = w.Write(util.EscapeHTML(label))
+ _, _ = w.WriteString(`</a>`)
+ return ast.WalkContinue, nil
+}
+
func (r *hookedRenderer) renderDefaultHeading(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
n := node.(*ast.Heading)
if entering {