gemini-browser

A text-based gemini browser
git clone git://git.laack.co/gemini-browser.git
Log | Files | Refs | README

parse.go (2054B)


      1 package main
      2 
      3 import (
      4 	"fmt"
      5 	"net/url"
      6 	"strings"
      7 )
      8 
      9 func stripLeadingWhiteSpace(text string) string {
     10 
     11 	for len(text) > 0 {
     12 		if text[0] == ' ' || text[0] == '\t' {
     13 			if len(text) > 1 {
     14 				text = text[1:]
     15 			} else {
     16 				text = ""
     17 				return text
     18 			}
     19 		} else {
     20 			return text
     21 		}
     22 	}
     23 
     24 	return text
     25 }
     26 
     27 func ParseLinks(body string, currentUrl string) []string {
     28 
     29 	base, err := url.Parse(currentUrl)
     30 
     31 	if err != nil {
     32 		panic(err)
     33 	}
     34 
     35 	lines := strings.Split(body, "\n")
     36 
     37 	links := []string{}
     38 
     39 	escaped := false
     40 	escape := "```"
     41 
     42 	for _, item := range lines {
     43 
     44 		// must start with escape characters, the rest doesn't matter to us
     45 		// > Any line whose first three characters are "```" (...) are preformatted toggle lines
     46 		if len(item) >= 3 && strings.Compare(escape, item[:3]) == 0 {
     47 			escaped = !escaped
     48 		}
     49 
     50 		if len(item) > 3 && !escaped {
     51 			if item[0] == '=' && item[1] == '>' {
     52 
     53 				// sometimes links end with a \r, but that isn't valid so we won't allow it
     54 				links = append(links, stripLeadingWhiteSpace(item[2:]))
     55 			}
     56 		}
     57 
     58 	}
     59 
     60 	geminiLinks := []string{}
     61 
     62 	for _, item := range links {
     63 
     64 		// this is for finding the text associated with the link
     65 
     66 		indexOfSpace := strings.Index(item, " ")
     67 		indexOfTab := strings.Index(item, "\t")
     68 
     69 		// default if there aren't any
     70 		indexOfSpaceOrTab := len(item)
     71 
     72 		if indexOfSpace != -1 {
     73 			indexOfSpaceOrTab = indexOfSpace
     74 		}
     75 
     76 		if indexOfTab != -1 {
     77 			if indexOfTab < indexOfSpace || indexOfSpace == -1 {
     78 				indexOfSpaceOrTab = indexOfTab
     79 			}
     80 		}
     81 
     82 		if len(item) >= 10 && strings.Compare(item[:9], "gemini://") == 0 {
     83 			geminiLinks = append(geminiLinks, item[0:indexOfSpaceOrTab])
     84 		}
     85 
     86 		// there are urls that aren't relative that don't have // like like mailto: and monero:
     87 		if strings.Contains(item, ":") == false {
     88 			// relative link
     89 
     90 			u, err := url.Parse(item[0:indexOfSpaceOrTab])
     91 
     92 			if err != nil {
     93 				fmt.Printf("Unable to parse link: %s, %s\n", item, err)
     94 				continue
     95 			}
     96 
     97 			geminiLinks = append(geminiLinks, base.ResolveReference(u).String())
     98 		}
     99 	}
    100 
    101 	return geminiLinks
    102 }