summaryrefslogtreecommitdiff
path: root/src/gmi/gemtext.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/gmi/gemtext.go')
-rw-r--r--src/gmi/gemtext.go73
1 files changed, 73 insertions, 0 deletions
diff --git a/src/gmi/gemtext.go b/src/gmi/gemtext.go
new file mode 100644
index 0000000..a1136bd
--- /dev/null
+++ b/src/gmi/gemtext.go
@@ -0,0 +1,73 @@
+package gmi
+
+import (
+ "bufio"
+ "errors"
+ "fmt"
+ "io"
+ "log"
+ "path"
+ "regexp"
+ "strings"
+)
+
+func hasImgExt(p string) bool {
+ switch path.Ext(strings.ToLower(p)) {
+ case ".jpg", ".jpeg", ".png", ".gif", ".svg":
+ return true
+ default:
+ return false
+ }
+}
+
+// matches `=> dstURL [optional description]`
+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 {
+
+ bufSrc := bufio.NewReader(src)
+
+ for {
+
+ line, err := bufSrc.ReadString('\n')
+ if err != nil && !errors.Is(err, io.EOF) {
+ return fmt.Errorf("reading: %w", err)
+ }
+
+ last := err == io.EOF
+
+ if match := linkRegexp.FindStringSubmatch(line); len(match) > 0 {
+
+ isImg := hasImgExt(match[1])
+
+ descr := match[2]
+
+ if descr != "" {
+ // ok
+ } else if isImg {
+ descr = "Image"
+ } else {
+ descr = "Link"
+ }
+
+ log.Printf("descr:%q", descr)
+
+ line = fmt.Sprintf("[%s](%s)\n", descr, match[1])
+
+ if isImg {
+ line = "!" + line
+ }
+ }
+
+ if _, err := dst.Write([]byte(line)); err != nil {
+ return fmt.Errorf("writing: %w", err)
+ }
+
+ if last {
+ return nil
+ }
+ }
+
+}