1# ~~strike through~~ 
    2from __future__ import annotations 
    3 
    4from .state_inline import Delimiter, StateInline 
    5 
    6 
    7def tokenize(state: StateInline, silent: bool) -> bool: 
    8    """Insert each marker as a separate text token, and add it to delimiter list""" 
    9    start = state.pos 
    10    ch = state.src[start] 
    11 
    12    if silent: 
    13        return False 
    14 
    15    if ch != "~": 
    16        return False 
    17 
    18    scanned = state.scanDelims(state.pos, True) 
    19    length = scanned.length 
    20 
    21    if length < 2: 
    22        return False 
    23 
    24    if length % 2: 
    25        token = state.push("text", "", 0) 
    26        token.content = ch 
    27        length -= 1 
    28 
    29    i = 0 
    30    while i < length: 
    31        token = state.push("text", "", 0) 
    32        token.content = ch + ch 
    33        state.delimiters.append( 
    34            Delimiter( 
    35                marker=ord(ch), 
    36                length=0,  # disable "rule of 3" length checks meant for emphasis 
    37                token=len(state.tokens) - 1, 
    38                end=-1, 
    39                open=scanned.can_open, 
    40                close=scanned.can_close, 
    41            ) 
    42        ) 
    43 
    44        i += 2 
    45 
    46    state.pos += scanned.length 
    47 
    48    return True 
    49 
    50 
    51def _postProcess(state: StateInline, delimiters: list[Delimiter]) -> None: 
    52    loneMarkers = [] 
    53    maximum = len(delimiters) 
    54 
    55    i = 0 
    56    while i < maximum: 
    57        startDelim = delimiters[i] 
    58 
    59        if startDelim.marker != 0x7E:  # /* ~ */ 
    60            i += 1 
    61            continue 
    62 
    63        if startDelim.end == -1: 
    64            i += 1 
    65            continue 
    66 
    67        endDelim = delimiters[startDelim.end] 
    68 
    69        token = state.tokens[startDelim.token] 
    70        token.type = "s_open" 
    71        token.tag = "s" 
    72        token.nesting = 1 
    73        token.markup = "~~" 
    74        token.content = "" 
    75 
    76        token = state.tokens[endDelim.token] 
    77        token.type = "s_close" 
    78        token.tag = "s" 
    79        token.nesting = -1 
    80        token.markup = "~~" 
    81        token.content = "" 
    82 
    83        if ( 
    84            state.tokens[endDelim.token - 1].type == "text" 
    85            and state.tokens[endDelim.token - 1].content == "~" 
    86        ): 
    87            loneMarkers.append(endDelim.token - 1) 
    88 
    89        i += 1 
    90 
    91    # If a marker sequence has an odd number of characters, it's split 
    92    # like this: `~~~~~` -> `~` + `~~` + `~~`, leaving one marker at the 
    93    # start of the sequence. 
    94    # 
    95    # So, we have to move all those markers after subsequent s_close tags. 
    96    # 
    97    while loneMarkers: 
    98        i = loneMarkers.pop() 
    99        j = i + 1 
    100 
    101        while (j < len(state.tokens)) and (state.tokens[j].type == "s_close"): 
    102            j += 1 
    103 
    104        j -= 1 
    105 
    106        if i != j: 
    107            token = state.tokens[j] 
    108            state.tokens[j] = state.tokens[i] 
    109            state.tokens[i] = token 
    110 
    111 
    112def postProcess(state: StateInline) -> None: 
    113    """Walk through delimiter list and replace text tokens with tags.""" 
    114    tokens_meta = state.tokens_meta 
    115    maximum = len(state.tokens_meta) 
    116    _postProcess(state, state.delimiters) 
    117 
    118    curr = 0 
    119    while curr < maximum: 
    120        try: 
    121            curr_meta = tokens_meta[curr] 
    122        except IndexError: 
    123            pass 
    124        else: 
    125            if curr_meta and "delimiters" in curr_meta: 
    126                _postProcess(state, curr_meta["delimiters"]) 
    127        curr += 1