1package sheet23import (4 "strings"56 "src.rest/cat/012/internal/formula"7 "src.rest/cat/012/internal/functions"8)910// Link returns the address a cell links to: its text when that is a URL11// (http, https or mailto), or the target of a HYPERLINK formula. It is12// empty for other cells.13func (s *Sheet) Link(a Addr) string {14 c := s.cells.get(a)15 if c == nil || c.Value.Kind != Text {16 return ""17 }18 if call, ok := c.expr.(formula.Call); ok && funcOf(call).Name == "HYPERLINK" && c.IsFormula() {19 v := functions.EvalAt(call.Args[0], s.wb.values(s).lib, a)20 if v.Kind == Error {21 return ""22 }23 return linkTarget(text(v), true)24 }25 return linkTarget(c.Value.Str, false)26}2728// linkTarget returns s as a link, or "" if it isn't one. Text in a cell29// must be a whole URL with a scheme; HYPERLINK also takes a bare domain,30// as Sheets does, and links it over https.31func linkTarget(s string, bare bool) string {32 s = strings.TrimSpace(s)33 if s == "" || strings.ContainsAny(s, " \t\n\x1b\x07") {34 return ""35 }36 lower := strings.ToLower(s)37 for _, scheme := range []string{"https://", "http://", "mailto:"} {38 if strings.HasPrefix(lower, scheme) {39 if len(s) == len(scheme) {40 return ""41 }42 return s43 }44 }45 if bare && strings.Contains(s, ".") && !strings.Contains(s, ":") {46 return "https://" + s47 }48 return ""49}