1# Process html entity - {, ¯, ", ... 
    2import re 
    3 
    4from ..common.entities import entities 
    5from ..common.utils import fromCodePoint, isValidEntityCode 
    6from .state_inline import StateInline 
    7 
    8DIGITAL_RE = re.compile(r"^&#((?:x[a-f0-9]{1,6}|[0-9]{1,7}));", re.IGNORECASE) 
    9NAMED_RE = re.compile(r"^&([a-z][a-z0-9]{1,31});", re.IGNORECASE) 
    10 
    11 
    12def entity(state: StateInline, silent: bool) -> bool: 
    13    pos = state.pos 
    14    maximum = state.posMax 
    15 
    16    if state.src[pos] != "&": 
    17        return False 
    18 
    19    if pos + 1 >= maximum: 
    20        return False 
    21 
    22    if state.src[pos + 1] == "#": 
    23        if match := DIGITAL_RE.search(state.src[pos:]): 
    24            if not silent: 
    25                match1 = match.group(1) 
    26                code = ( 
    27                    int(match1[1:], 16) if match1[0].lower() == "x" else int(match1, 10) 
    28                ) 
    29 
    30                token = state.push("text_special", "", 0) 
    31                token.content = ( 
    32                    fromCodePoint(code) 
    33                    if isValidEntityCode(code) 
    34                    else fromCodePoint(0xFFFD) 
    35                ) 
    36                token.markup = match.group(0) 
    37                token.info = "entity" 
    38 
    39            state.pos += len(match.group(0)) 
    40            return True 
    41 
    42    else: 
    43        if (match := NAMED_RE.search(state.src[pos:])) and match.group(1) in entities: 
    44            if not silent: 
    45                token = state.push("text_special", "", 0) 
    46                token.content = entities[match.group(1)] 
    47                token.markup = match.group(0) 
    48                token.info = "entity" 
    49 
    50            state.pos += len(match.group(0)) 
    51            return True 
    52 
    53    return False