func matchTagName(s string) string { if len(s) < 2 { return "" } i := 0 if s[0] == '/' { i++ } start := i max := min(15+i, len(s)) for i < max && byteutil.IsLetter(s[i]) { i++ } if i >= len(s) { return "" } switch s[i] { case ' ', '\n', '/', '>': return byteutil.ToLower(s[start:i]) default: return "" } }
func matchAutolink(s string) string { if len(s) < 6 || s[0] != '<' { return "" } st := 0 n := 0 for i := 1; i < len(s); i++ { b := s[i] switch st { case 0: // initial state switch { case schemecs[b]: st = 1 n++ default: return "" } case 1: // h switch { case schemecs[b]: n++ if n > 23 { return "" } case b == ':': schema := byteutil.ToLower(s[1:i]) if !matchSchema(schema) { return "" } st = 2 default: return "" } case 2: // http: switch { case linkcs[b]: st = 3 break default: return "" } case 3: // http:/ switch { case linkcs[b]: break case b == '>': return s[1:i] default: return "" } } } return "" }
// Parse parses rawurl into a URL structure. func Parse(rawurl string) (*URL, error) { n, err := findScheme(rawurl) if err != nil { return nil, err } var url URL rest := rawurl hostless := false if n > 0 { url.Scheme, rest = byteutil.ToLower(rest[:n]), rest[n+1:] if url.Scheme == "javascript" { hostless = true } } if !hostless && strings.HasPrefix(rest, "//") { url.Slashes, rest = true, rest[2:] } if !hostless && (url.Slashes || (url.Scheme != "" && !slashedProtocol[url.Scheme])) { hostEnd := byteutil.IndexAnyTable(rest, &cs2) atSign := -1 i := hostEnd if i == -1 { i = len(rest) - 1 } for i >= 0 { if rest[i] == '@' { atSign = i break } i-- } if atSign != -1 { url.Auth, rest = rest[:atSign], rest[atSign+1:] } hostEnd = byteutil.IndexAnyTable(rest, &cs3) if hostEnd == -1 { hostEnd = len(rest) } if hostEnd > 0 && hostEnd < len(rest) && rest[hostEnd-1] == ':' { hostEnd-- } host := rest[:hostEnd] if len(host) > 1 { b := host[hostEnd-1] if byteutil.IsDigit(b) { for i := len(host) - 2; i >= 0; i-- { b := host[i] if b == ':' { url.Host, url.Port = host[:i], host[i+1:] break } if !byteutil.IsDigit(b) { break } } } else if b == ':' { host = host[:hostEnd-1] hostEnd-- } } if url.Port == "" { url.Host = host } rest = rest[hostEnd:] if ipv6 := len(url.Host) > 2 && url.Host[0] == '[' && url.Host[len(url.Host)-1] == ']'; ipv6 { url.Host = url.Host[1 : len(url.Host)-1] url.IPv6 = true } else if i := strings.IndexByte(url.Host, ':'); i >= 0 { url.Host, rest = url.Host[:i], url.Host[i:]+rest } } rest, url.Fragment = split(rest, '#') url.Path, url.RawQuery = split(rest, '?') return &url, nil }