def table_layout(lens, maxWidth, separatorLength=1):
    """
    Build a 2 dimensional table layout for 1 dimensional data.

    The table is layed out in column major order such that the given items
    fit into the given maximum width. If Items do not fit, the returned
    widths are the maximum of lens.

    :param lens: List of lengths of all items to be layed out.
    :param maxWidth: Maximum width for the table.
    :param separatorLength: Length of the separator between items.

    :returns:
        List of lists of widths. ``table_layout(...)[i][j]`` gives the width of
        element ``(i,j)`` in the table.
    """

    # i and j are row and column indices, respectively.
    # m and n are number of rows and columns, repsectively.
    # n does not include columns that are not completely filled.

    N = len(lens)
    m = 1
    n = N//m
    while n > 0:

        # calculate widths of each fully filled column
        widthAux = [max(lens[j*m:(j+1)*m]) for j in range(n)]

        # combine with remainders
        widths = []
        for i in range(m):
            if i+n*m < N:
                widths.append(widthAux + [lens[i+n*m]])
            else:
                widths.append(widthAux)

        # compute maximum required width
        required = max(sum(w) + separatorLength*(len(w)-1) for w in widths)

        if required <= maxWidth:
            # fits, we are done here
            return widths

        # does not fit, try with one more row
        m += 1
        n = N//m

    # fallback if items do not fit
    return [[max(lens)]]*N