|
|
|
@ -5,8 +5,9 @@ import ( |
|
|
|
|
"errors" |
|
|
|
|
"fmt" |
|
|
|
|
"io" |
|
|
|
|
"log" |
|
|
|
|
"net/url" |
|
|
|
|
"path" |
|
|
|
|
"path/filepath" |
|
|
|
|
"regexp" |
|
|
|
|
"strings" |
|
|
|
|
) |
|
|
|
@ -25,7 +26,10 @@ var linkRegexp = regexp.MustCompile(`^=>\s+(\S+)\s*(.*?)\s*$`) |
|
|
|
|
|
|
|
|
|
// GemtextToMarkdown reads a gemtext formatted body from the Reader and writes
|
|
|
|
|
// the markdown version of that body to the Writer.
|
|
|
|
|
func GemtextToMarkdown(dst io.Writer, src io.Reader) error { |
|
|
|
|
//
|
|
|
|
|
// gmiGateway, if given, is used for all `gemini://` links. The `gemini://`
|
|
|
|
|
// prefix will be stripped, and replaced with the given URL.
|
|
|
|
|
func GemtextToMarkdown(dst io.Writer, src io.Reader, gmiGateway *url.URL) error { |
|
|
|
|
|
|
|
|
|
bufSrc := bufio.NewReader(src) |
|
|
|
|
|
|
|
|
@ -40,7 +44,20 @@ func GemtextToMarkdown(dst io.Writer, src io.Reader) error { |
|
|
|
|
|
|
|
|
|
if match := linkRegexp.FindStringSubmatch(line); len(match) > 0 { |
|
|
|
|
|
|
|
|
|
isImg := hasImgExt(match[1]) |
|
|
|
|
u, err := url.Parse(match[1]) |
|
|
|
|
if err != nil { |
|
|
|
|
return fmt.Errorf("link to invalid url %q: %w", match[1], err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if u.Scheme == "gemini" && gmiGateway != nil { |
|
|
|
|
|
|
|
|
|
newU := *gmiGateway |
|
|
|
|
newU.Path = filepath.Join(newU.Path, u.Host, u.Path) |
|
|
|
|
newU.RawQuery = u.RawQuery |
|
|
|
|
u = &newU |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
isImg := hasImgExt(u.Path) |
|
|
|
|
|
|
|
|
|
descr := match[2] |
|
|
|
|
|
|
|
|
@ -52,9 +69,7 @@ func GemtextToMarkdown(dst io.Writer, src io.Reader) error { |
|
|
|
|
descr = "Link" |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
log.Printf("descr:%q", descr) |
|
|
|
|
|
|
|
|
|
line = fmt.Sprintf("[%s](%s)\n", descr, match[1]) |
|
|
|
|
line = fmt.Sprintf("[%s](%s)\n", descr, u.String()) |
|
|
|
|
|
|
|
|
|
if isImg { |
|
|
|
|
line = "!" + line |
|
|
|
|