mirror of
https://github.com/mickael-menu/zk
synced 2024-11-07 15:20:21 +00:00
Support Markdown autolinking for external links
This commit is contained in:
parent
e0c8e2fd02
commit
ade5da20df
@ -8,9 +8,11 @@ import (
|
||||
"github.com/mickael-menu/zk/core/note"
|
||||
"github.com/mickael-menu/zk/util/opt"
|
||||
strutil "github.com/mickael-menu/zk/util/strings"
|
||||
"github.com/mvdan/xurls"
|
||||
"github.com/yuin/goldmark"
|
||||
meta "github.com/yuin/goldmark-meta"
|
||||
"github.com/yuin/goldmark/ast"
|
||||
"github.com/yuin/goldmark/extension"
|
||||
"github.com/yuin/goldmark/parser"
|
||||
"github.com/yuin/goldmark/text"
|
||||
)
|
||||
@ -26,6 +28,15 @@ func NewParser() *Parser {
|
||||
md: goldmark.New(
|
||||
goldmark.WithExtensions(
|
||||
meta.Meta,
|
||||
extension.NewLinkify(
|
||||
extension.WithLinkifyAllowedProtocols([][]byte{
|
||||
[]byte("http:"),
|
||||
[]byte("https:"),
|
||||
}),
|
||||
extension.WithLinkifyURLRegexp(
|
||||
xurls.Strict,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
}
|
||||
@ -127,16 +138,30 @@ func parseLinks(root ast.Node, source []byte) ([]note.Link, error) {
|
||||
links := make([]note.Link, 0)
|
||||
|
||||
err := ast.Walk(root, func(n ast.Node, entering bool) (ast.WalkStatus, error) {
|
||||
if link, ok := n.(*ast.Link); ok && entering {
|
||||
href := string(link.Destination)
|
||||
if href != "" {
|
||||
links = append(links, note.Link{
|
||||
Title: string(link.Text(source)),
|
||||
Href: href,
|
||||
Rels: strings.Fields(string(link.Title)),
|
||||
External: strutil.IsURL(href),
|
||||
Snippet: extractLines(n.Parent(), source),
|
||||
})
|
||||
if entering {
|
||||
switch link := n.(type) {
|
||||
case *ast.Link:
|
||||
href := string(link.Destination)
|
||||
if href != "" {
|
||||
links = append(links, note.Link{
|
||||
Title: string(link.Text(source)),
|
||||
Href: href,
|
||||
Rels: strings.Fields(string(link.Title)),
|
||||
External: strutil.IsURL(href),
|
||||
Snippet: extractLines(n.Parent(), source),
|
||||
})
|
||||
}
|
||||
|
||||
case *ast.AutoLink:
|
||||
if href := string(link.URL(source)); href != "" && link.AutoLinkType == ast.AutoLinkURL {
|
||||
links = append(links, note.Link{
|
||||
Title: string(link.Label(source)),
|
||||
Href: href,
|
||||
Rels: []string{},
|
||||
External: true,
|
||||
Snippet: extractLines(n.Parent(), source),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return ast.WalkContinue, nil
|
||||
|
@ -168,6 +168,8 @@ func TestParseLinks(t *testing.T) {
|
||||
Paragraph containing [multiple **links**](stripped-formatting), here's one [relative](../other).
|
||||
A link can have [one relation](one "rel-1") or [several relations](several "rel-1 rel-2").
|
||||
|
||||
An https://inline-link.com and http://another-inline-link.com.
|
||||
|
||||
[External links](http://example.com) are marked [as such](ftp://domain).
|
||||
`, []note.Link{
|
||||
{
|
||||
@ -209,6 +211,20 @@ A link can have [one relation](one "rel-1") or [several relations](several "rel-
|
||||
Snippet: `Paragraph containing [multiple **links**](stripped-formatting), here's one [relative](../other).
|
||||
A link can have [one relation](one "rel-1") or [several relations](several "rel-1 rel-2").`,
|
||||
},
|
||||
{
|
||||
Title: "https://inline-link.com",
|
||||
Href: "https://inline-link.com",
|
||||
External: true,
|
||||
Rels: []string{},
|
||||
Snippet: "An https://inline-link.com and http://another-inline-link.com.",
|
||||
},
|
||||
{
|
||||
Title: "http://another-inline-link.com",
|
||||
Href: "http://another-inline-link.com",
|
||||
External: true,
|
||||
Rels: []string{},
|
||||
Snippet: "An https://inline-link.com and http://another-inline-link.com.",
|
||||
},
|
||||
{
|
||||
Title: "External links",
|
||||
Href: "http://example.com",
|
||||
|
1
go.mod
1
go.mod
@ -18,6 +18,7 @@ require (
|
||||
github.com/mattn/go-runewidth v0.0.10 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.6
|
||||
github.com/mickael-menu/pretty v0.2.3
|
||||
github.com/mvdan/xurls v1.1.0
|
||||
github.com/pelletier/go-toml v1.8.1
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
|
2
go.sum
2
go.sum
@ -133,6 +133,8 @@ github.com/mickael-menu/pretty v0.2.3 h1:AXi5WcBuWxwQV6iY/GhmCFpaoboQO2SLtzfujrn
|
||||
github.com/mickael-menu/pretty v0.2.3/go.mod h1:gupeWUSWoo3KX7BItIuouLgTqQLlmRylpaPdIK6IqLk=
|
||||
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ=
|
||||
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
|
||||
github.com/mvdan/xurls v1.1.0 h1:OpuDelGQ1R1ueQ6sSryzi6P+1RtBpfQHM8fJwlE45ww=
|
||||
github.com/mvdan/xurls v1.1.0/go.mod h1:tQlNn3BED8bE/15hnSL2HLkDeLWpNPAwtw7wkEq44oU=
|
||||
github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM=
|
||||
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
|
Loading…
Reference in New Issue
Block a user