Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/mistune/util.py: 100%

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

39 statements  

1import re 

2from html import _replace_charref # type: ignore[attr-defined] 

3from typing import Match 

4from urllib.parse import quote 

5 

6_expand_tab_re = re.compile(r"^( {0,3})\t", flags=re.M) 

7 

8 

9def expand_leading_tab(text: str, width: int = 4) -> str: 

10 def repl(m: Match[str]) -> str: 

11 s = m.group(1) 

12 return s + " " * (width - len(s)) 

13 

14 return _expand_tab_re.sub(repl, text) 

15 

16 

17def expand_tab(text: str, space: str = " ") -> str: 

18 repl = r"\1" + space 

19 return _expand_tab_re.sub(repl, text) 

20 

21 

22def escape(s: str, quote: bool = True) -> str: 

23 """Escape characters of ``&<>``. If quote=True, ``"`` will be 

24 converted to ``&quote;``.""" 

25 s = s.replace("&", "&amp;") 

26 s = s.replace("<", "&lt;") 

27 s = s.replace(">", "&gt;") 

28 if quote: 

29 s = s.replace('"', "&quot;") 

30 return s 

31 

32 

33def escape_url(link: str) -> str: 

34 """Escape URL for safety.""" 

35 safe = ( 

36 ":/?#@" # gen-delims - '[]' (rfc3986) 

37 "!$&()*+,;=" # sub-delims - "'" (rfc3986) 

38 "%" # leave already-encoded octets alone 

39 ) 

40 return quote(unescape(link), safe=safe) 

41 

42 

43def safe_entity(s: str) -> str: 

44 """Escape characters for safety.""" 

45 return escape(unescape(s)) 

46 

47 

48def unikey(s: str) -> str: 

49 """Generate a unique key for links and footnotes.""" 

50 key = " ".join(s.split()).strip() 

51 return key.lower().upper() 

52 

53 

54_charref_re = re.compile( 

55 r"&(#[0-9]{1,7};" 

56 r"|#[xX][0-9a-fA-F]+;" 

57 r"|[^\t\n\f <&#;]{1,32};)" 

58) 

59 

60 

61def unescape(s: str) -> str: 

62 """ 

63 Copy from `html.unescape`, but `_charref` is different. CommonMark 

64 does not accept entity references without a trailing semicolon 

65 """ 

66 if "&" not in s: 

67 return s 

68 return _charref_re.sub(_replace_charref, s) 

69 

70 

71_striptags_re = re.compile(r"(<!--.*?-->|<[^>]*>)") 

72 

73 

74def striptags(s: str) -> str: 

75 return _striptags_re.sub("", s) 

76 

77 

78_strip_end_re = re.compile(r"\n\s+$") 

79 

80 

81def strip_end(src: str) -> str: 

82 return _strip_end_re.sub("\n", src)