docs: def generate(categorize=unicodedata.category, group_class=RangeGroup):
      '''
      Generate a dict of RangeGroups for each unicode character category,
      including general ones.
  
      :param categorize: category function, defaults to unicodedata.category.
      :type categorize: callable
      :param group_class: class for range groups, defaults to RangeGroup
      :type group_class: type
      :returns: dictionary of categories and range groups
      :rtype: dict of RangeGroup
      '''
      categories = collections.defaultdict(list)
      last_category = None
      last_range = None
      for c in range(sys.maxunicode + 1):
          category = categorize(chr(c))
          if category != last_category:
              last_category = category
              last_range = [c, c + 1]
              categories[last_category].append(last_range)
          else:
              last_range[1] += 1
      categories = {k: group_class(v) for k, v in categories.items()}
      categories.update({
          k: merge(*map(categories.__getitem__, g))
          for k, g in itertools.groupby(sorted(categories), key=lambda k: k[0])
          })
      return categories