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

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

34 statements  

1# Process html entity - {, ¯, ", ... 

2import re 

3 

4from ..common.entities import entities 

5from ..common.utils import fromCodePoint, isValidEntityCode 

6from .state_inline import StateInline 

7 

8# NB: no leading `^` -- these are applied via `.match(src, pos)`, which already 

9# anchors at `pos`. Anchoring this way avoids building `src[pos:]` on every 

10# `&`, which is an O(len) copy per call and makes long runs quadratic. 

11DIGITAL_RE = re.compile(r"&#((?:x[a-f0-9]{1,6}|[0-9]{1,7}));", re.IGNORECASE) 

12NAMED_RE = re.compile(r"&([a-z][a-z0-9]{1,31});", re.IGNORECASE) 

13 

14 

15def entity(state: StateInline, silent: bool) -> bool: 

16 pos = state.pos 

17 maximum = state.posMax 

18 

19 if state.src[pos] != "&": 

20 return False 

21 

22 if pos + 1 >= maximum: 

23 return False 

24 

25 if state.src[pos + 1] == "#": 

26 if match := DIGITAL_RE.match(state.src, pos): 

27 if not silent: 

28 match1 = match.group(1) 

29 code = ( 

30 int(match1[1:], 16) if match1[0].lower() == "x" else int(match1, 10) 

31 ) 

32 

33 token = state.push("text_special", "", 0) 

34 token.content = ( 

35 fromCodePoint(code) 

36 if isValidEntityCode(code) 

37 else fromCodePoint(0xFFFD) 

38 ) 

39 token.markup = match.group(0) 

40 token.info = "entity" 

41 

42 state.pos += len(match.group(0)) 

43 return True 

44 

45 else: 

46 if (match := NAMED_RE.match(state.src, pos)) and match.group(1) in entities: 

47 if not silent: 

48 token = state.push("text_special", "", 0) 

49 token.content = entities[match.group(1)] 

50 token.markup = match.group(0) 

51 token.info = "entity" 

52 

53 state.pos += len(match.group(0)) 

54 return True 

55 

56 return False