1
0
mirror of https://github.com/osmarks/mycorrhiza.git synced 2024-10-30 11:46:16 +00:00

Start moving universal link-related stuff to a separate module

This commit is contained in:
bouncepaw 2021-01-31 00:25:18 +05:00
parent 92dd19316c
commit dd98ae492b
2 changed files with 114 additions and 32 deletions

107
link/link.go Normal file
View File

@ -0,0 +1,107 @@
package link
import (
"fmt"
"path"
"strings"
"github.com/bouncepaw/mycorrhiza/util"
)
// LinkType tells what type the given link is.
type LinkType int
const (
LinkInavild LinkType = iota
// LinkLocalRoot is a link like "/list", "/user-list", etc.
LinkLocalRoot
// LinkLocalHypha is a link like "test", "../test", etc.
LinkLocalHypha
// LinkExternal is an external link with specified protocol.
LinkExternal
// LinkInterwiki is currently unused.
LinkInterwiki
)
// Link is an abstraction for universal representation of links, be they links in mycomarkup links or whatever.
type Link struct {
// Address is what the link points to.
Address string
// Display is what gets nested into the <a> tag.
Display string
Kind LinkType
DestinationUnknown bool
Protocol string
// How the link address looked originally in source text.
SrcAddress string
// How the link display text looked originally in source text. May be empty.
SrcDisplay string
// RelativeTo is hypha name to which the link is relative to.
RelativeTo string
}
// Classes returns CSS class string for given link.
func (l *Link) Classes() string {
if l.Kind == LinkExternal {
return fmt.Sprintf("wikilink wikilink_external wikilink_%s", l.Protocol)
}
classes := "wikilink wikilink_internal"
if l.DestinationUnknown {
classes += " wikilink_new"
}
return classes
}
// Href returns content for the href attrubite. You should always use it.
func (l *Link) Href() string {
switch l.Kind {
case LinkExternal, LinkLocalRoot:
return l.Address
default:
return "/hypha/" + l.Address
}
}
// From returns a Link object given these `address` and `display` on relative to given `hyphaName`.
func From(address, display, hyphaName string) *Link {
link := Link{
SrcAddress: address,
SrcDisplay: display,
RelativeTo: hyphaName,
}
if display == "" {
link.Display = address
} else {
link.Display = strings.TrimSpace(display)
}
switch {
case strings.ContainsRune(address, ':'):
pos := strings.IndexRune(address, ':')
link.Protocol = address[:pos]
link.Kind = LinkExternal
if display == "" {
link.Display = address[pos+1:]
if strings.HasPrefix(link.Display, "//") && len(link.Display) > 2 {
link.Display = link.Display[2:]
}
}
link.Address = address
case strings.HasPrefix(address, "/"):
link.Address = address
link.Kind = LinkLocalRoot
case strings.HasPrefix(address, "./"):
link.Kind = LinkLocalHypha
link.Address = util.CanonicalName(path.Join(hyphaName, address[2:]))
case strings.HasPrefix(address, "../"):
link.Kind = LinkLocalHypha
link.Address = util.CanonicalName(path.Join(path.Dir(hyphaName), address[3:]))
default:
link.Address = util.CanonicalName(address)
}
return &link
}

View File

@ -1,47 +1,22 @@
package markup
import (
"fmt"
"path"
"strings"
"github.com/bouncepaw/mycorrhiza/link"
)
// LinkParts determines what href, text and class should resulting <a> have based on mycomarkup's addr, display and hypha name.
//
// => addr display
// [[addr|display]]
// TODO: deprecate
func LinkParts(addr, display, hyphaName string) (href, text, class string) {
if display == "" {
text = addr
} else {
text = strings.TrimSpace(display)
l := link.From(addr, display, hyphaName)
if l.Kind == link.LinkLocalHypha && !HyphaExists(l.Address) {
l.DestinationUnknown = true
}
class = "wikilink wikilink_internal"
switch {
case strings.ContainsRune(addr, ':'):
pos := strings.IndexRune(addr, ':')
destination := addr[:pos]
if display == "" {
text = addr[pos+1:]
if strings.HasPrefix(text, "//") && len(text) > 2 {
text = text[2:]
}
}
return addr, text, fmt.Sprintf("wikilink wikilink_external wikilink_%s", destination)
case strings.HasPrefix(addr, "/"):
return addr, text, class
case strings.HasPrefix(addr, "./"):
hyphaName = canonicalName(path.Join(hyphaName, addr[2:]))
case strings.HasPrefix(addr, "../"):
hyphaName = canonicalName(path.Join(path.Dir(hyphaName), addr[3:]))
default:
hyphaName = canonicalName(addr)
}
if !HyphaExists(hyphaName) {
class += " wikilink_new"
}
return "/page/" + hyphaName, text, class
return l.Href(), l.Display, l.Classes()
}
// Parse markup line starting with "=>" according to wikilink rules.