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 goahead(self, end):
      rawdata = self.rawdata
      i = 0
      n = len(rawdata)
      while i < n:
          if self.convert_charrefs and not self.cdata_elem:
              j = rawdata.find("<", i)
              if j < 0:
                  # if we can't find the next <, either we are at the end
                  # or there's more text incoming.  If the latter is True,
                  # we can't pass the text to handle_data in case we have
                  # a charref cut in half at end.  Try to determine if
                  # this is the case before proceeding by looking for an
                  # & near the end and see if it's followed by a space or ;.
                  amppos = rawdata.rfind("&", max(i, n - 34))
                  if amppos >= 0 and not re.compile(r"[\s;]").search(
                      rawdata, amppos
                  ):
                      break  # wait till we get all the text
                  j = n
          else:
              match = self.interesting.search(rawdata, i)  # < or &
              if match:
                  j = match.start()
              else:
                  if self.cdata_elem:
                      break
                  j = n
          if i < j:
              if self.convert_charrefs and not self.cdata_elem:
                  self.handle_data(unescape(rawdata[i:j]))
              else:
                  self.handle_data(rawdata[i:j])
          i = self.updatepos(i, j)
          if i == n:
              break
          startswith = rawdata.startswith
          if startswith("<", i):
              if starttagopen.match(rawdata, i):  # < + letter
                  k = self.parse_starttag(i)
              elif startswith("</", i):
                  k = self.parse_endtag(i)
              elif startswith("<!--", i):
                  k = self.parse_comment(i)
              elif startswith("<?", i):
                  k = self.parse_pi(i)
              elif startswith("<!", i):
                  k = self.parse_html_declaration(i)
              elif (i + 1) < n:
                  self.handle_data("<")
                  k = i + 1
              else:
                  break
              if k < 0:
                  if not end:
                      break
                  k = rawdata.find(">", i + 1)
                  if k < 0:
                      k = rawdata.find("<", i + 1)
                      if k < 0:
                          k = i + 1
                  else:
                      k += 1
                  if self.convert_charrefs and not self.cdata_elem:
                      self.handle_data(unescape(rawdata[i:k]))
                  else:
                      self.handle_data(rawdata[i:k])
              i = self.updatepos(i, k)
          elif startswith("&#", i):
              match = charref.match(rawdata, i)
              if match:
                  name = match.group()[2:-1]
                  self.handle_charref(name)
                  k = match.end()
                  if not startswith(";", k - 1):
                      k = k - 1
                  i = self.updatepos(i, k)
                  continue
              else:
                  if ";" in rawdata[i:]:  # bail by consuming &#
                      self.handle_data(rawdata[i : i + 2])
                      i = self.updatepos(i, i + 2)
                  break
          elif startswith("&", i):
              match = entityref.match(rawdata, i)
              if match:
                  name = match.group(1)
                  self.handle_entityref(name)
                  k = match.end()
                  if not startswith(";", k - 1):
                      k = k - 1
                  i = self.updatepos(i, k)
                  continue
              match = incomplete.match(rawdata, i)
              if match:
                  # match.group() will contain at least 2 chars
                  if end and match.group() == rawdata[i:]:
                      k = match.end()
                      if k <= i:
                          k = n
                      i = self.updatepos(i, i + 1)
                  # incomplete
                  break
              elif (i + 1) < n:
                  # not the end of the buffer, and can't be confused
                  # with some other construct
                  self.handle_data("&")
                  i = self.updatepos(i, i + 1)
              else:
                  break
          else:
              assert 0, "interesting.search() lied"
      # end while
      if end and i < n and not self.cdata_elem:
          if self.convert_charrefs and not self.cdata_elem:
              self.handle_data(unescape(rawdata[i:n]))
          else:
              self.handle_data(rawdata[i:n])
          i = self.updatepos(i, n)
      self.rawdata = rawdata[i:]
  
imports: import re
  import _markupbase
  from html import unescape
label_desc: Use image node_id 8 for calling the HTMLParser obj's underlying member method code with example usage: obj.goahead(end) without return types