Handle relative URLs in markdown, when a BaseURL is provided

This commit is contained in:
Christian Muehlhaeuser
2019-11-26 00:35:11 +01:00
parent c2af06bed0
commit 18e173b10d
+28 -6
View File
@@ -6,6 +6,8 @@ import (
"html" "html"
"io" "io"
"io/ioutil" "io/ioutil"
"log"
"net/url"
"os" "os"
"strconv" "strconv"
"strings" "strings"
@@ -34,7 +36,8 @@ type Element struct {
} }
type TermRenderer struct { type TermRenderer struct {
style map[StyleType]*ElementStyle BaseURL string
style map[StyleType]*ElementStyle
} }
func Render(in string, stylePath string) ([]byte, error) { func Render(in string, stylePath string) ([]byte, error) {
@@ -86,7 +89,26 @@ func NewTermRendererFromBytes(b []byte) (*TermRenderer, error) {
return tr, nil return tr, nil
} }
func NewElement(node *bf.Node) Element { func resolveRelativeURL(baseURL string, rel string) string {
u, err := url.Parse(rel)
if err != nil {
log.Fatal(err)
}
if u.IsAbs() {
return rel
}
if u.Path[0] == '/' {
u.Path = u.Path[1:]
}
base, err := url.Parse(baseURL)
if err != nil {
return rel
}
return base.ResolveReference(u).String()
}
func (tr *TermRenderer) NewElement(node *bf.Node) Element {
switch node.Type { switch node.Type {
case bf.Document: case bf.Document:
return Element{ return Element{
@@ -194,7 +216,7 @@ func NewElement(node *bf.Node) Element {
if node.LastChild != nil { if node.LastChild != nil {
if node.LastChild.Type == bf.Image { if node.LastChild.Type == bf.Image {
el := NewElement(node.LastChild) el := tr.NewElement(node.LastChild)
f = el.Fragments f = el.Fragments
} }
if len(node.LastChild.Literal) > 0 { if len(node.LastChild.Literal) > 0 {
@@ -206,7 +228,7 @@ func NewElement(node *bf.Node) Element {
} }
if len(node.LinkData.Destination) > 0 { if len(node.LinkData.Destination) > 0 {
f = append(f, Fragment{ f = append(f, Fragment{
Token: string(node.LinkData.Destination), Token: resolveRelativeURL(tr.BaseURL, string(node.LinkData.Destination)),
Pre: " (", Pre: " (",
Post: ")", Post: ")",
Style: Link, Style: Link,
@@ -229,7 +251,7 @@ func NewElement(node *bf.Node) Element {
} }
if len(node.LinkData.Destination) > 0 { if len(node.LinkData.Destination) > 0 {
f = append(f, Fragment{ f = append(f, Fragment{
Token: string(node.LinkData.Destination), Token: resolveRelativeURL(tr.BaseURL, string(node.LinkData.Destination)),
Pre: " [Image: ", Pre: " [Image: ",
Post: "]", Post: "]",
Style: Link, Style: Link,
@@ -417,7 +439,7 @@ func (tr *TermRenderer) renderFragment(w io.Writer, f Fragment) {
func (tr *TermRenderer) RenderNode(w io.Writer, node *bf.Node, entering bool) bf.WalkStatus { func (tr *TermRenderer) RenderNode(w io.Writer, node *bf.Node, entering bool) bf.WalkStatus {
// fmt.Fprintf(w, "%s %t", node.Type, entering) // fmt.Fprintf(w, "%s %t", node.Type, entering)
e := NewElement(node) e := tr.NewElement(node)
if entering && e.Pre != "" { if entering && e.Pre != "" {
fmt.Fprintf(w, "%s", e.Pre) fmt.Fprintf(w, "%s", e.Pre)
} }