Author: bugman Date: Fri Mar 8 12:05:12 2013 New Revision: 18693 URL: http://svn.gna.org/viewcvs/relax?rev=18693&view=rev Log: Implemented multi-column support in lib.text.table.format_table(). Modified: trunk/lib/text/table.py Modified: trunk/lib/text/table.py URL: http://svn.gna.org/viewcvs/relax/trunk/lib/text/table.py?rev=18693&r1=18692&r2=18693&view=diff ============================================================================== --- trunk/lib/text/table.py (original) +++ trunk/lib/text/table.py Fri Mar 8 12:05:12 2013 @@ -88,16 +88,34 @@ # Initialise. line = prefix + pad_left + num_col = len(widths) # Loop over the columns. - for i in range(len(widths)): + for i in range(num_col): + # Multicolumn (middle/end). + if text[i] == MULTI_COL: + continue + # The column separator. if i > 0: line += separator - # The text. - line += text[i] - line += " " * (widths[i] - len(text[i])) + # Multicolumn (start). + if i < num_col-1 and text[i+1] == MULTI_COL: + # Find the full multicell width. + width = widths[i] + for j in range(i+1, num_col): + if text[j] == MULTI_COL: + width += len(separator) + widths[j] + + # Add the padded text. + line += text[i] + line += " " * (width - len(text[i])) + + # Normal cell. + else: + line += text[i] + line += " " * (widths[i] - len(text[i])) # Close the line. line += pad_right + postfix + "\n" @@ -108,6 +126,9 @@ def format_table(headings=None, contents=None, max_width=None, separator=' ', pad_left=' ', pad_right=' ', prefix=' ', postfix=' ', spacing=False, debug=False): """Format and return the table as text. + + If the heading or contents contains the value of the MULTI_COL constant defined in this module, then that cell will be merged with the previous cell to allow elements to span multiple columns. + @keyword headings: The table header. @type headings: list of lists of str @@ -139,18 +160,30 @@ num_cols = len(contents[0]) num_head_rows = len(headings) - # The column widths. - widths = [0] * num_cols + # Initialise the pre-wrapping column widths. + prewrap_widths = [0] * num_cols + + # Determine the maximum column widths from the headers. for i in range(num_head_rows): for j in range(num_cols): + # Skip multicolumn entries. + if j < num_cols-1 and headings[i][j+1] == MULTI_COL: + continue + # The element is larger than the previous. - if len(headings[i][j]) > widths[j]: - widths[j] = len(headings[i][j]) + if len(headings[i][j]) > prewrap_widths[j]: + prewrap_widths[j] = len(headings[i][j]) + + # Determine the maximum column widths from the content. for i in range(num_rows): for j in range(num_cols): + # Skip multicolumn entries. + if j < num_cols-1 and contents[i][j+1] == MULTI_COL: + continue + # The element is larger than the previous. - if len(contents[i][j]) > widths[j]: - widths[j] = len(contents[i][j]) + if len(contents[i][j]) > prewrap_widths[j]: + prewrap_widths[j] = len(contents[i][j]) # The free space for the text (subtracting the space used for the formatting). used = len(pad_left) @@ -162,7 +195,7 @@ free_space = 1000 # The maximal width for all cells. - free_width = sum(widths) + free_width = sum(prewrap_widths) # Column wrapping. if free_width > free_space: @@ -174,7 +207,7 @@ print("%-20s %s" % ("free space:", free_space)) # New structures. - new_widths = deepcopy(widths) + new_widths = deepcopy(prewrap_widths) num_cols_wrap = num_cols free_space_wrap = free_space col_wrap = [True] * num_cols @@ -215,7 +248,7 @@ # Debugging printouts. if debug: - print(" %-20s %s" % ("widths:", widths)) + print(" %-20s %s" % ("prewrap_widths:", prewrap_widths)) print(" %-20s %s" % ("new_widths:", new_widths)) print(" %-20s %s" % ("num_cols:", num_cols)) print(" %-20s %s" % ("num_cols_wrap:", num_cols_wrap)) @@ -225,7 +258,7 @@ # No column wrapping. else: - new_widths = widths + new_widths = prewrap_widths col_wrap = [False] * num_cols # The total table width. @@ -235,7 +268,7 @@ text += _rule(width=total_width) # Top rule. text += _blank(width=total_width) # Blank line. for i in range(num_head_rows): - text += _table_line(text=headings[i], widths=new_widths, separator=separator, pad_left=pad_left, pad_right=pad_right, prefix=prefix, postfix=postfix) + text += _table_line(text=headings[i], widths=new_widths, separator=' ', pad_left=pad_left, pad_right=pad_right, prefix=prefix, postfix=postfix) text += _rule(width=total_width) # Middle rule. # The table contents.