class_docstr: Extract raw HTML from text.
  
  The raw HTML is stored in the [`htmlStash`][markdown.util.HtmlStash] of the
  [`Markdown`][markdown.Markdown] instance passed to `md` and the remaining text
  is stored in `cleandoc` as a list of strings.
code: def parse_starttag(self, i: int) -> int:  # pragma: no cover
      self.__starttag_text = None
      endpos = self.check_for_whole_start_tag(i)
      if endpos < 0:
          return endpos
      rawdata = self.rawdata
      self.__starttag_text = rawdata[i:endpos]
  
      # Now parse the data between `i+1` and `j` into a tag and `attrs`
      attrs = []
      match = htmlparser.tagfind_tolerant.match(rawdata, i + 1)
      assert match, "unexpected call to parse_starttag()"
      k = match.end()
      self.lasttag = tag = match.group(1).lower()
      while k < endpos:
          m = htmlparser.attrfind_tolerant.match(rawdata, k)
          if not m:
              break
          attrname, rest, attrvalue = m.group(1, 2, 3)
          if not rest:
              attrvalue = None
          elif (
              attrvalue[:1] == "'" == attrvalue[-1:]
              or attrvalue[:1] == '"' == attrvalue[-1:]
          ):  # noqa: E127
              attrvalue = attrvalue[1:-1]
          if attrvalue:
              attrvalue = htmlparser.unescape(attrvalue)
          attrs.append((attrname.lower(), attrvalue))
          k = m.end()
  
      end = rawdata[k:endpos].strip()
      if end not in (">", "/>"):
          lineno, offset = self.getpos()
          if "\n" in self.__starttag_text:
              lineno = lineno + self.__starttag_text.count("\n")
              offset = len(
                  self.__starttag_text
              ) - self.__starttag_text.rfind(
                  "\n"
              )  # noqa: E127
          else:
              offset = offset + len(self.__starttag_text)
          self.handle_data(rawdata[i:endpos])
          return endpos
      if end.endswith("/>"):
          # XHTML-style empty tag: `<span attr="value" />`
          self.handle_startendtag(tag, attrs)
      else:
          # *** set `cdata_mode` first so we can override it in `handle_starttag` (see #1036) ***
          if tag in self.CDATA_CONTENT_ELEMENTS:
              self.set_cdata_mode(tag)
          self.handle_starttag(tag, attrs)
      return endpos
  
imports: from __future__ import annotations
  import re
  import importlib.util
  import sys
  from typing import TYPE_CHECKING, Sequence
label_desc: Use image node_id 22 for calling the HTMLExtractor obj's underlying member method code with example usage: obj.parse_starttag(i) and returns: endpos, endpos, endpos