docs: def strip_xss(html, whitelist=None, replacement="(removed)"):
      """
      This function returns a tuple containing:
  
          * *html* with all non-whitelisted HTML tags replaced with *replacement*.
          * A `set()` containing the tags that were removed.
  
      Any tags that contain JavaScript, VBScript, or other known XSS/executable
      functions will also be removed.
  
      If *whitelist* is not given the following will be used::
  
          whitelist = set([
              'a', 'abbr', 'aside', 'audio', 'bdi', 'bdo', 'blockquote', 'canvas',
              'caption', 'code', 'col', 'colgroup', 'data', 'dd', 'del',
              'details', 'div', 'dl', 'dt', 'em', 'figcaption', 'figure', 'h1',
              'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'ins', 'kbd', 'li',
              'mark', 'ol', 'p', 'pre', 'q', 'rp', 'rt', 'ruby', 's', 'samp',
              'small', 'source', 'span', 'strong', 'sub', 'summary', 'sup',
              'table', 'td', 'th', 'time', 'tr', 'track', 'u', 'ul', 'var',
              'video', 'wbr'
          ])
  
      .. note:: To disable the whitelisting simply set `whitelist="off"`.
  
      Example::
  
          >>> html = '<span>Hello, exploit: <img src="javascript:alert(\"pwned!\")"></span>'
          >>> html, rejects = strip_xss(html)
          >>> print("'%s', Rejected: '%s'" % (html, " ".join(rejects)))
          '<span>Hello, exploit: (removed)</span>', Rejected: '<img src="javascript:alert("pwned!")">'
  
      .. note:: The default *replacement* is "(removed)".
  
      If *replacement* is "entities" bad HTML tags will be encoded into HTML
      entities.  This allows things like <script>'whatever'</script> to be
      displayed without execution (which would be much less annoying to users that
      were merely trying to share a code example).  Here's an example::
  
          >>> html = '<span>Hello, exploit: <img src="javascript:alert(\"pwned!\")"></span>'
          >>> html, rejects = strip_xss(html, replacement="entities")
          >>> print(html)
          <span>Hello, exploit: &lt;img src="javascript:alert("pwned!")"&gt;</span>
          >>> print("Rejected: '%s'" % ", ".join(rejects))
          Rejected: '<img src="javascript:alert("pwned!")">'
  
      **NOTE:** This function should work to protect against *all* `the XSS
      examples at OWASP
      <https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet>`_.  Please
      `let us know <https://github.com/LiftoffSoftware/htmltag/issues>`_ if you
      find something we missed.
      """
      re_html_tag = re.compile( # This matches HTML tags (if used correctly)
        "(?i)<\/?\w+((\s+\w+(\s*=\s*(?:\".*?\"|'.*?'|[^'\">\s]+))?)+\s*|\s*)\/?>")
      # This will match things like 'onmouseover=' ('on<whatever>=')
      on_events_re = re.compile('.*\s+(on[a-z]+\s*=).*')
      if not whitelist:
          # These are all pretty safe and covers most of what users would want in
          # terms of formatting and sharing media (images, audio, video, etc).
          whitelist = set([
              'a', 'abbr', 'aside', 'audio', 'bdi', 'bdo', 'blockquote', 'canvas',
              'caption', 'code', 'col', 'colgroup', 'data', 'dd', 'del',
              'details', 'div', 'dl', 'dt', 'em', 'figcaption', 'figure', 'h1',
              'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'ins', 'kbd', 'li',
              'mark', 'ol', 'p', 'pre', 'q', 'rp', 'rt', 'ruby', 's', 'samp',
              'small', 'source', 'span', 'strong', 'sub', 'summary', 'sup',
              'table', 'td', 'th', 'time', 'tr', 'track', 'u', 'ul', 'var',
              'video', 'wbr'
          ])
      elif whitelist == "off":
          whitelist = None # Disable it altogether
      bad_tags = set()
      for tag in re_html_tag.finditer(html):
          tag = tag.group()
          tag_lower = tag.lower()
          short_tag = tag_lower.split()[0].lstrip('</').rstrip('>')
          if whitelist and short_tag not in whitelist:
              bad_tags.add(tag)
              continue
          # Make sure the tag can't execute any JavaScript
          if "javascript:" in tag_lower:
              bad_tags.add(tag)
              continue
          # on<whatever> events are not allowed (just another XSS vuln)
          if on_events_re.search(tag_lower):
              bad_tags.add(tag)
              continue
          # Flash sucks
          if "fscommand" in tag_lower:
              bad_tags.add(tag)
              continue
          # I'd be impressed if an attacker tried this one (super obscure)
          if "seeksegmenttime" in tag_lower:
              bad_tags.add(tag)
              continue
          # Yes we'll protect IE users from themselves...
          if "vbscript:" in tag_lower:
              bad_tags.add(tag)
              continue
      if replacement == "entities":
          for bad_tag in bad_tags:
              escaped = cgi.escape(bad_tag).encode('ascii', 'xmlcharrefreplace')
              html = html.replace(bad_tag, escaped.decode('ascii'))
      else:
          for bad_tag in bad_tags:
              html = html.replace(bad_tag, replacement)
      return (html, bad_tags)