docs: def html2groff(data, name):
      """Convert HTML text from cplusplus.com to Groff-formatted text."""
      # Remove sidebar
      try:
          data = data[data.index('<div class="C_doc">'):]
      except ValueError:
          pass
  
      # Pre replace all
      for rp in pre_rps:
          data = re.compile(rp[0], rp[2]).sub(rp[1], data)
  
      for table in re.findall(r'<table.*?>.*?</table>', data, re.S):
          tbl = parse_table(escape_pre_section(table))
          # Escape column with '.' as prefix
          tbl = re.compile(r'T{\n(\..*?)\nT}', re.S).sub(r'T{\n\\E \1\nT}', tbl)
          data = data.replace(table, tbl)
  
      # Replace all
      for rp in rps:
          data = re.compile(rp[0], rp[2]).sub(rp[1], data)
  
      # Upper case all section headers
      for st in re.findall(r'.SH .*\n', data):
          data = data.replace(st, st.upper())
  
      # Add tags to member/inherited member functions
      # e.g. insert -> vector::insert
      #
      # .SE is a pseudo macro I created which means 'SECTION END'
      # The reason I use it is because I need a marker to know where section
      # ends.
      # re.findall find patterns which does not overlap, which means if I do
      # this: secs = re.findall(r'\n\.SH "(.+?)"(.+?)\.SH', data, re.S)
      # re.findall will skip the later .SH tag and thus skip the later section.
      # To fix this, '.SE' is used to mark the end of the section so the next
      # '.SH' can be find by re.findall
  
      page_type = re.search(r'\n\.SH "TYPE"\n(.+?)\n', data)
      if page_type and 'class' in page_type.group(1):
          class_name = re.search(r'\n\.SH "NAME"\n(?:.*::)?(.+?) ', data).group(1)
  
          secs = re.findall(r'\n\.SH "(.+?)"(.+?)\.SE', data, re.S)
  
          for sec, content in secs:
              # Member functions
              if ('MEMBER' in sec and
                  'NON-MEMBER' not in sec and
                  'INHERITED' not in sec and
                  sec != 'MEMBER TYPES'):
                  content2 = re.sub(r'\n\.IP "([^:]+?)"', r'\n.IP "%s::\1"'
                                    % class_name, content)
                  # Replace (constructor) (destructor)
                  content2 = re.sub(r'\(constructor\)', r'%s' % class_name,
                                    content2)
                  content2 = re.sub(r'\(destructor\)', r'~%s' % class_name,
                                    content2)
                  data = data.replace(content, content2)
              # Inherited member functions
              elif 'MEMBER' in sec and 'INHERITED' in sec:
                  inherit = re.search(r'.+?INHERITED FROM (.+)',
                                      sec).group(1).lower()
                  content2 = re.sub(r'\n\.IP "(.+)"', r'\n.IP "%s::\1"'
                                    % inherit, content)
                  data = data.replace(content, content2)
  
      # Remove pseudo macro '.SE'
      data = data.replace('\n.SE', '')
  
      return data