class_docstr: Find tags and other markup and call handler functions.
  
  Usage:
      p = HTMLParser()
      p.feed(data)
      ...
      p.close()
  
  Start tags are handled by calling self.handle_starttag() or
  self.handle_startendtag(); end tags by self.handle_endtag().  The
  data between tags is passed from the parser to the derived class
  by calling self.handle_data() with the data as argument (the data
  may be split up in arbitrary chunks).  If convert_charrefs is
  True the character references are converted automatically to the
  corresponding Unicode character (and self.handle_data() is no
  longer split in chunks), otherwise they are passed by calling
  self.handle_entityref() or self.handle_charref() with the string
  containing respectively the named or numeric reference as the
  argument.
code: def parse_endtag(self, i):
      rawdata = self.rawdata
      assert (
          rawdata[i : i + 2] == "</"
      ), "unexpected call to parse_endtag"
      match = endendtag.search(rawdata, i + 1)  # >
      if not match:
          return -1
      gtpos = match.end()
      match = endtagfind.match(rawdata, i)  # </ + tag + >
      if not match:
          if self.cdata_elem is not None:
              self.handle_data(rawdata[i:gtpos])
              return gtpos
          # find the name: w3.org/TR/html5/tokenization.html#tag-name-state
          namematch = tagfind_tolerant.match(rawdata, i + 2)
          if not namematch:
              # w3.org/TR/html5/tokenization.html#end-tag-open-state
              if rawdata[i : i + 3] == "</>":
                  return i + 3
              else:
                  return self.parse_bogus_comment(i)
          tagname = namematch.group(1).lower()
          # consume and ignore other stuff between the name and the >
          # Note: this is not 100% correct, since we might have things like
          # </tag attr=">">, but looking for > after the name should cover
          # most of the cases and is much simpler
          gtpos = rawdata.find(">", namematch.end())
          self.handle_endtag(tagname)
          return gtpos + 1
  
      elem = match.group(1).lower()  # script or style
      if self.cdata_elem is not None:
          if elem != self.cdata_elem:
              self.handle_data(rawdata[i:gtpos])
              return gtpos
  
      self.handle_endtag(elem)
      self.clear_cdata_mode()
      return gtpos
  
imports: import re
  import _markupbase
  from html import unescape
label_desc: Use image node_id 14 for calling the HTMLParser obj's underlying member method code with example usage: obj.parse_endtag(i) and returns: gtpos, unknown, unknown, gtpos, gtpos, unknown, self