1# Process autolinks '<protocol:...>'
2import re
3
4from .state_inline import StateInline
5
6EMAIL_RE = re.compile(
7 r"^([a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)$" # noqa: E501
8)
9AUTOLINK_RE = re.compile(r"^([a-zA-Z][a-zA-Z0-9+.\-]{1,31}):([^<>\x00-\x20]*)$")
10
11
12def autolink(state: StateInline, silent: bool) -> bool:
13 pos = state.pos
14
15 if state.src[pos] != "<":
16 return False
17
18 start = state.pos
19 maximum = state.posMax
20
21 while True:
22 pos += 1
23 if pos >= maximum:
24 return False
25
26 ch = state.src[pos]
27
28 if ch == "<":
29 return False
30 if ch == ">":
31 break
32
33 url = state.src[start + 1 : pos]
34
35 if AUTOLINK_RE.search(url) is not None:
36 fullUrl = state.md.normalizeLink(url)
37 if not state.md.validateLink(fullUrl):
38 return False
39
40 if not silent:
41 token = state.push("link_open", "a", 1)
42 token.attrs = {"href": fullUrl}
43 token.markup = "autolink"
44 token.info = "auto"
45
46 token = state.push("text", "", 0)
47 token.content = state.md.normalizeLinkText(url)
48
49 token = state.push("link_close", "a", -1)
50 token.markup = "autolink"
51 token.info = "auto"
52
53 state.pos += len(url) + 2
54 return True
55
56 if EMAIL_RE.search(url) is not None:
57 fullUrl = state.md.normalizeLink("mailto:" + url)
58 if not state.md.validateLink(fullUrl):
59 return False
60
61 if not silent:
62 token = state.push("link_open", "a", 1)
63 token.attrs = {"href": fullUrl}
64 token.markup = "autolink"
65 token.info = "auto"
66
67 token = state.push("text", "", 0)
68 token.content = state.md.normalizeLinkText(url)
69
70 token = state.push("link_close", "a", -1)
71 token.markup = "autolink"
72 token.info = "auto"
73
74 state.pos += len(url) + 2
75 return True
76
77 return False