commit a0b8dcaed34293b39bce451d7a4b00051cdae7fe
Author: phoebos <ben@bvnf.space>
Date: Thu, 13 May 2021 15:26:35 +0100
initial
Diffstat:
A | gemini.go | | | 53 | +++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | gemtext.go | | | 59 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
2 files changed, 112 insertions(+), 0 deletions(-)
diff --git a/gemini.go b/gemini.go
@@ -0,0 +1,53 @@
+package main
+
+import (
+ "bufio"
+ "crypto/tls"
+ "flag"
+ "fmt"
+ "io/ioutil"
+ "net/url"
+ "os"
+ "strings"
+)
+
+func main() {
+ port := flag.Int("p", 1965, "port number")
+ plain := flag.Bool("plain", false, "print raw header and response (no formatting)")
+ flag.Parse()
+ // only accept one url
+ if flag.NArg() > 1 {
+ fmt.Fprintf(os.Stderr, "only give one url\n")
+ os.Exit(1)
+ }
+
+ u := flag.Args()[0]
+
+ if !strings.HasPrefix(u, "gemini://") {
+ u = "gemini://" + u
+ }
+
+ parsed, err := url.Parse(u)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "error parsing url (%s): %s\n", u, err.Error())
+ os.Exit(1)
+ }
+
+ conn, err := tls.Dial("tcp", parsed.Host+fmt.Sprintf(":%d", *port), &tls.Config{InsecureSkipVerify: true})
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "tls error: %s\n", err.Error())
+ os.Exit(1)
+ }
+ defer conn.Close()
+ conn.Write([]byte(u + "\r\n"))
+ resp, err := ioutil.ReadAll(bufio.NewReader(conn))
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "error: %s\n", err.Error())
+ os.Exit(2)
+ }
+ if *plain {
+ fmt.Println(string(resp))
+ os.Exit(0)
+ }
+ fmt.Println(Prettify(string(resp)))
+}
diff --git a/gemtext.go b/gemtext.go
@@ -0,0 +1,59 @@
+package main
+
+import (
+ "strings"
+)
+
+// Prettify formats gemtext nicely with escape sequences.
+func Prettify(plain string) string {
+ lines := strings.Split(plain, "\n")
+ outlines := make([]string, 0, len(lines))
+ preform := false
+ for _, line := range lines {
+ outline := line
+ line = strings.TrimSpace(line)
+ fwspace := strings.Index(line, " ")
+ var firstword string
+ if fwspace == -1 {
+ firstword = line
+ } else {
+ firstword = line[:fwspace]
+ }
+ if preform && firstword != "```" {
+ outlines = append(outlines, outline)
+ continue
+ }
+ if len(firstword) > 3 {
+ firstword = firstword[:3]
+ }
+
+ switch firstword {
+ case "```":
+ // preformatted
+ preform = !preform
+ continue
+ case "#":
+ // heading
+ outline = "\033[1;31m" + outline + "\033[m"
+ case "##":
+ // subheading
+ outline = "\033[1;32m" + outline + "\033[m"
+ case "###":
+ // sub-subheading
+ outline = "\033[1;33m" + outline + "\033[m"
+ case "*":
+ // list
+ outline = " •" + line[1:]
+ case ">":
+ // quote
+ outline = "\t\033[3;37m" + outline + "\033[m"
+ case "=>":
+ // link
+ outline = "\033[4;34m" + outline + "\033[m"
+ }
+
+ outlines = append(outlines, outline)
+ }
+
+ return strings.Join(outlines, "\n")
+}