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 }