docs: def build_anchor_link(header_text_trimmed: str,
                        header_duplicate_counter: str,
                        parser: str = 'github') -> str:
      r"""Apply the specified slug rule to build the anchor link.
  
      :parameter header_text_trimmed: the text that needs to be transformed
           in a link.
      :parameter header_duplicate_counter: a data structure that keeps track of
           possible duplicate header links in order to avoid them. This is
           meaningful only for certain values of parser.
      :parameter parser: decides rules on how to generate anchor links.
           Defaults to ``github``.
      :type header_text_trimmed: str
      :type header_duplicate_counter: dict
      :type parser: str
      :returns: None if the specified parser is not recognized, or the anchor
           link, otherwise.
      :rtype: str
      :raises: a built-in exception.
  
      .. note::
          The licenses of each markdown parser algorithm are reported on
          the 'Markdown spec' documentation page.
      """
      if (parser == 'github' or parser == 'cmark' or parser == 'gitlab'
              or parser == 'commonmarker'):
          header_text_trimmed = header_text_trimmed.lower()
          # Remove punctuation: Keep spaces, hypens and "word characters"
          # only.
          header_text_trimmed = re.sub(r'[^\w\s\- ]', '', header_text_trimmed)
          header_text_trimmed = header_text_trimmed.replace(' ', '-')
  
          # Check for duplicates.
          ht = header_text_trimmed
          # Set the initial value if we are examining the first occurrency.
          # The state of header_duplicate_counter is available to the caller
          # functions.
          if header_text_trimmed not in header_duplicate_counter:
              header_duplicate_counter[header_text_trimmed] = 0
          if header_duplicate_counter[header_text_trimmed] > 0:
              header_text_trimmed = header_text_trimmed + '-' + str(
                  header_duplicate_counter[header_text_trimmed])
          header_duplicate_counter[ht] += 1
          return header_text_trimmed
      elif parser == 'redcarpet':
          # To ensure full compatibility what follows is a direct translation
          # of the rndr_header_anchor C function used in redcarpet.
          STRIPPED = " -&+$,/:;=?@\"#{}|^~[]`\\*()%.!'"
          header_text_trimmed_len = len(header_text_trimmed)
          inserted = 0
          stripped = 0
          header_text_trimmed_middle_stage = ''
          for i in range(0, header_text_trimmed_len):
              if header_text_trimmed[i] == '<':
                  while i < header_text_trimmed_len and header_text_trimmed[
                          i] != '>':
                      i += 1
              elif header_text_trimmed[i] == '&':
                  while i < header_text_trimmed_len and header_text_trimmed[
                          i] != ';':
                      i += 1
              # str.find() == -1 if character is not found in str.
              # https://docs.python.org/3.6/library/stdtypes.html?highlight=find#str.find
              elif not curses.ascii.isascii(
                      header_text_trimmed[i]) or STRIPPED.find(
                          header_text_trimmed[i]) != -1:
                  if inserted and not stripped:
                      header_text_trimmed_middle_stage += '-'
                  stripped = 1
              else:
                  header_text_trimmed_middle_stage += header_text_trimmed[
                      i].lower()
                  stripped = 0
                  inserted += 1
  
          if stripped > 0 and inserted > 0:
              header_text_trimmed_middle_stage = header_text_trimmed_middle_stage[
                  0:-1]
  
          if inserted == 0 and header_text_trimmed_len > 0:
              hash = 5381
              for i in range(0, header_text_trimmed_len):
                  # Get the unicode representation with ord.
                  # Unicode should be equal to ASCII in ASCII's range of
                  # characters.
                  hash = ((hash << 5) + hash) + ord(header_text_trimmed[i])
  
              # This is equivalent to %x in C. In Python we don't have
              # the length problem so %x is equal to %lx in this case.
              # Apparently there is no %l in Python...
              header_text_trimmed_middle_stage = 'part-' + '{0:x}'.format(hash)
  
          return header_text_trimmed_middle_stage