Add support for Wiki links and neuron's Folgezettel links

pull/6/head
Mickaël Menu 3 years ago
parent ade5da20df
commit 9f0b5dc7d4
No known key found for this signature in database
GPG Key ID: 53D73664CD359895

@ -0,0 +1,111 @@
package extensions
import (
"strings"
"github.com/yuin/goldmark"
"github.com/yuin/goldmark/ast"
"github.com/yuin/goldmark/parser"
"github.com/yuin/goldmark/text"
"github.com/yuin/goldmark/util"
)
// WikiLink is an extension parsing wiki links and neuron's Folgezettel.
//
// For example, [[wiki link]], [[[legacy downlink]]], #[[uplink]], [[downlink]]#.
var WikiLink = &wikiLink{}
type wikiLink struct{}
func (w *wikiLink) Extend(m goldmark.Markdown) {
m.Parser().AddOptions(
parser.WithInlineParsers(
util.Prioritized(&wlParser{}, 199),
),
)
}
type wlParser struct{}
func (p *wlParser) Trigger() []byte {
return []byte{'[', '#'}
}
func (p *wlParser) Parse(parent ast.Node, block text.Reader, pc parser.Context) ast.Node {
line, _ := block.PeekLine()
openerCharCount := 0
opened := false
closed := false
content := []byte{}
closerCharCount := 0
endPos := 0
// Folgezettel direction: -1 down, 0 unknown, 1 up
direction := 0
for i, char := range line {
endPos = i
if closed {
// Supports trailing hash syntax for neuron's Folgezettel, e.g. [[id]]#
if char == '#' {
direction = -1
}
break
}
if !opened {
switch char {
// Supports leading hash syntax for neuron's Folgezettel, e.g. #[[id]]
case '#':
direction = 1
continue
case '[':
openerCharCount += 1
continue
}
if openerCharCount < 2 || openerCharCount > 3 {
return nil
}
}
opened = true
if char == ']' {
closerCharCount += 1
if closerCharCount == openerCharCount {
closed = true
// neuron's legacy [[[Folgezettel]]].
if closerCharCount == 3 {
direction = -1
}
}
} else {
if closerCharCount > 0 {
content = append(content, strings.Repeat("]", closerCharCount)...)
closerCharCount = 0
}
content = append(content, char)
}
}
if !closed || len(content) == 0 {
return nil
}
block.Advance(endPos)
link := ast.NewLink()
link.Destination = content
// Title will be parsed as the link's rels.
switch direction {
case -1:
link.Title = []byte("down")
case 1:
link.Title = []byte("up")
}
return link
}

@ -5,6 +5,7 @@ import (
"regexp"
"strings"
"github.com/mickael-menu/zk/adapter/markdown/extensions"
"github.com/mickael-menu/zk/core/note"
"github.com/mickael-menu/zk/util/opt"
strutil "github.com/mickael-menu/zk/util/strings"
@ -37,6 +38,7 @@ func NewParser() *Parser {
xurls.Strict,
),
),
extensions.WikiLink,
),
),
}

@ -170,6 +170,14 @@ A link can have [one relation](one "rel-1") or [several relations](several "rel-
An https://inline-link.com and http://another-inline-link.com.
A [[Wiki link]] is surrounded by two brackets.
A [[[Folgezettel link]]] is surrounded by three brackets.
Neuron also supports a [[trailing hash]]# for Folgezettel links.
A #[[leading hash]] is used for #uplinks.
[External links](http://example.com) are marked [as such](ftp://domain).
`, []note.Link{
{
@ -225,6 +233,34 @@ A link can have [one relation](one "rel-1") or [several relations](several "rel-
Rels: []string{},
Snippet: "An https://inline-link.com and http://another-inline-link.com.",
},
{
Title: "",
Href: "Wiki link",
External: false,
Rels: []string{},
Snippet: "A [[Wiki link]] is surrounded by two brackets.",
},
{
Title: "",
Href: "Folgezettel link",
External: false,
Rels: []string{"down"},
Snippet: "A [[[Folgezettel link]]] is surrounded by three brackets.",
},
{
Title: "",
Href: "trailing hash",
External: false,
Rels: []string{"down"},
Snippet: "Neuron also supports a [[trailing hash]]# for Folgezettel links.",
},
{
Title: "",
Href: "leading hash",
External: false,
Rels: []string{"up"},
Snippet: "A #[[leading hash]] is used for #uplinks.",
},
{
Title: "External links",
Href: "http://example.com",

Loading…
Cancel
Save