Unencode markdown links when parsing a note

pull/88/head
Mickaël Menu 3 years ago
parent d74cf52d1e
commit bb4ab55372
No known key found for this signature in database
GPG Key ID: 53D73664CD359895

@ -18,6 +18,11 @@ var WikiLinkExt = &wikiLink{}
type wikiLink struct{}
// WikiLink represents a wiki link found in a Markdown document.
type WikiLink struct {
ast.Link
}
func (w *wikiLink) Extend(m goldmark.Markdown) {
m.Parser().AddOptions(
parser.WithInlineParsers(
@ -135,7 +140,7 @@ func (p *wlParser) Parse(parent ast.Node, block text.Reader, pc parser.Context)
label = href
}
link := ast.NewLink()
link := &WikiLink{Link: *ast.NewLink()}
link.Destination = []byte(href)
// Title will be parsed as the link's rel by the Markdown parser.
link.Title = []byte(rel)

@ -3,11 +3,13 @@ package markdown
import (
"bufio"
"fmt"
"net/url"
"regexp"
"strings"
"github.com/mickael-menu/zk/internal/adapter/markdown/extensions"
"github.com/mickael-menu/zk/internal/core"
"github.com/mickael-menu/zk/internal/util"
"github.com/mickael-menu/zk/internal/util/opt"
strutil "github.com/mickael-menu/zk/internal/util/strings"
"github.com/mickael-menu/zk/internal/util/yaml"
@ -22,7 +24,8 @@ import (
// Parser parses the content of Markdown notes.
type Parser struct {
md goldmark.Markdown
md goldmark.Markdown
logger util.Logger
}
type ParserOpts struct {
@ -35,7 +38,7 @@ type ParserOpts struct {
}
// NewParser creates a new Markdown Parser.
func NewParser(options ParserOpts) *Parser {
func NewParser(options ParserOpts, logger util.Logger) *Parser {
return &Parser{
md: goldmark.New(
goldmark.WithExtensions(
@ -57,6 +60,7 @@ func NewParser(options ParserOpts) *Parser {
},
),
),
logger: logger,
}
}
@ -70,7 +74,7 @@ func (p *Parser) ParseNoteContent(content string) (*core.NoteContent, error) {
parser.WithContext(context),
)
links, err := parseLinks(root, bytes)
links, err := p.parseLinks(root, bytes)
if err != nil {
return nil, err
}
@ -208,14 +212,15 @@ func parseTags(frontmatter frontmatter, root ast.Node, source []byte) ([]string,
}
// parseLinks extracts outbound links from the note.
func parseLinks(root ast.Node, source []byte) ([]core.Link, error) {
func (p *Parser) parseLinks(root ast.Node, source []byte) ([]core.Link, error) {
links := make([]core.Link, 0)
err := ast.Walk(root, func(n ast.Node, entering bool) (ast.WalkStatus, error) {
if entering {
switch link := n.(type) {
case *ast.Link:
href := string(link.Destination)
href, err := url.PathUnescape(string(link.Destination))
p.logger.Err(err)
if href != "" {
snippet, snStart, snEnd := extractLines(n, source)
links = append(links, core.Link{
@ -242,6 +247,21 @@ func parseLinks(root ast.Node, source []byte) ([]core.Link, error) {
SnippetEnd: snEnd,
})
}
case *extensions.WikiLink:
href := string(link.Destination)
if href != "" {
snippet, snStart, snEnd := extractLines(n, source)
links = append(links, core.Link{
Title: string(link.Text(source)),
Href: href,
Rels: core.LinkRels(strings.Fields(string(link.Title))...),
IsExternal: strutil.IsURL(href),
Snippet: snippet,
SnippetStart: snStart,
SnippetEnd: snEnd,
})
}
}
}
return ast.WalkContinue, nil

@ -4,6 +4,7 @@ import (
"testing"
"github.com/mickael-menu/zk/internal/core"
"github.com/mickael-menu/zk/internal/util"
"github.com/mickael-menu/zk/internal/util/opt"
"github.com/mickael-menu/zk/internal/util/test/assert"
)
@ -545,6 +546,31 @@ A link can have [one relation](one "rel-1") or [several relations](several "rel-
SnippetEnd: 744,
},
})
// Markdown links are decoded, but not WikiLinks.
// i.e. https://github.com/mickael-menu/zk/issues/86
test("[foo%20bar](202110031652%20foo%20bar)", []core.Link{
{
Title: "foo%20bar",
Href: "202110031652 foo bar",
IsExternal: false,
Rels: []core.LinkRelation{},
Snippet: "[foo%20bar](202110031652%20foo%20bar)",
SnippetStart: 0,
SnippetEnd: 37,
},
})
test("[[202110031652%20foo%20bar]]", []core.Link{
{
Title: "202110031652%20foo%20bar",
Href: "202110031652%20foo%20bar",
IsExternal: false,
Rels: []core.LinkRelation{},
Snippet: "[[202110031652%20foo%20bar]]",
SnippetStart: 0,
SnippetEnd: 28,
},
})
}
func TestParseMetadataFromFrontmatter(t *testing.T) {
@ -584,7 +610,7 @@ func parse(t *testing.T, source string) core.NoteContent {
}
func parseWithOptions(t *testing.T, source string, options ParserOpts) core.NoteContent {
content, err := NewParser(options).ParseNoteContent(source)
content, err := NewParser(options, &util.NullLogger).ParseNoteContent(source)
assert.Nil(t, err)
return *content
}

@ -89,11 +89,14 @@ func NewContainer(version string) (*Container, error) {
notebook := core.NewNotebook(path, config, core.NotebookPorts{
NoteIndex: sqlite.NewNoteIndex(db, logger),
NoteContentParser: markdown.NewParser(markdown.ParserOpts{
HashtagEnabled: config.Format.Markdown.Hashtags,
MultiWordTagEnabled: config.Format.Markdown.MultiwordTags,
ColontagEnabled: config.Format.Markdown.ColonTags,
}),
NoteContentParser: markdown.NewParser(
markdown.ParserOpts{
HashtagEnabled: config.Format.Markdown.Hashtags,
MultiWordTagEnabled: config.Format.Markdown.MultiwordTags,
ColontagEnabled: config.Format.Markdown.ColonTags,
},
logger,
),
TemplateLoaderFactory: func(language string) (core.TemplateLoader, error) {
loader := handlebars.NewLoader(handlebars.LoaderOpts{
LookupPaths: []string{

Loading…
Cancel
Save