Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/markdown_it/rules_inline/linkify.py: 13%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

38 statements  

1"""Process links like https://example.org/""" 

2 

3import re 

4 

5from .state_inline import StateInline 

6 

7# RFC3986: scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) 

8SCHEME_RE = re.compile(r"(?:^|[^a-z0-9.+-])([a-z][a-z0-9.+-]*)$", re.IGNORECASE) 

9 

10 

11def linkify(state: StateInline, silent: bool) -> bool: 

12 """Rule for identifying plain-text links.""" 

13 if not state.md.options.linkify: 

14 return False 

15 if state.linkLevel > 0: 

16 return False 

17 if not state.md.linkify: 

18 raise ModuleNotFoundError("Linkify enabled but not installed.") 

19 

20 pos = state.pos 

21 maximum = state.posMax 

22 

23 if ( 

24 (pos + 3) > maximum 

25 or state.src[pos] != ":" 

26 or state.src[pos + 1] != "/" 

27 or state.src[pos + 2] != "/" 

28 ): 

29 return False 

30 

31 if not (match := SCHEME_RE.search(state.pending)): 

32 return False 

33 

34 proto = match.group(1) 

35 if not (link := state.md.linkify.match_at_start(state.src[pos - len(proto) :])): 

36 return False 

37 url: str = link.url 

38 

39 # disallow '*' at the end of the link (conflicts with emphasis) 

40 url = url.rstrip("*") 

41 

42 full_url = state.md.normalizeLink(url) 

43 if not state.md.validateLink(full_url): 

44 return False 

45 

46 if not silent: 

47 state.pending = state.pending[: -len(proto)] 

48 

49 token = state.push("link_open", "a", 1) 

50 token.attrs = {"href": full_url} 

51 token.markup = "linkify" 

52 token.info = "auto" 

53 

54 token = state.push("text", "", 0) 

55 token.content = state.md.normalizeLinkText(url) 

56 

57 token = state.push("link_close", "a", -1) 

58 token.markup = "linkify" 

59 token.info = "auto" 

60 

61 state.pos += len(url) - len(proto) 

62 return True