code: def max_dimensions(table_data, padding_left=0, padding_right=0, padding_top=0, padding_bottom=0):
      
      inner_widths = [0] * (max(len(r) for r in table_data) if table_data else 0)
      inner_heights = [0] * len(table_data)
  
      # Find max width and heights.
      for j, row in enumerate(table_data):
          for i, cell in enumerate(row):
              if not hasattr(cell, 'count') or not hasattr(cell, 'splitlines'):
                  cell = str(cell)
              if not cell:
                  continue
              inner_heights[j] = max(inner_heights[j], cell.count('\n') + 1)
              inner_widths[i] = max(inner_widths[i], *[visible_width(l) for l in cell.splitlines()])
  
      # Calculate with padding.
      outer_widths = [padding_left + i + padding_right for i in inner_widths]
      outer_heights = [padding_top + i + padding_bottom for i in inner_heights]
  
      return inner_widths, inner_heights, outer_widths, outer_heights
docs: Get maximum widths of each column and maximum height of each row.
  
      :param iter table_data: List of list of strings (unmodified table data).
      :param int padding_left: Number of space chars on left side of cell.
      :param int padding_right: Number of space chars on right side of cell.
      :param int padding_top: Number of empty lines on top side of cell.
      :param int padding_bottom: Number of empty lines on bottom side of cell.
  
      :return: 4-item tuple of n-item lists. Inner column widths and row heights, outer column widths and row heights.
      :rtype: tuple