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:
parent
92dd19316c
commit
dd98ae492b
107
link/link.go
Normal file
107
link/link.go
Normal 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
|
||||
}
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user