Package jazzparser :: Package utils :: Module tableprint
[hide private]
[frames] | no frames]

Source Code for Module jazzparser.utils.tableprint

  1  """Pretty-printing tables as strings. 
  2   
  3  A bit of simple code to output a table to stdout. 
  4   
  5  Many thanks to  
  6  U{http://ginstrom.com/scribbles/2007/09/04/pretty-printing-a-table-in-python/} 
  7  for the basic code that I used to do the core stuff here. I've developed  
  8  on it a bit myself and added the Latex table stuff down the bottom. 
  9   
 10  """ 
 11  """ 
 12  ============================== License ======================================== 
 13   Copyright (C) 2008, 2010-12 University of Edinburgh, Mark Granroth-Wilding 
 14    
 15   This file is part of The Jazz Parser. 
 16    
 17   The Jazz Parser is free software: you can redistribute it and/or modify 
 18   it under the terms of the GNU General Public License as published by 
 19   the Free Software Foundation, either version 3 of the License, or 
 20   (at your option) any later version. 
 21    
 22   The Jazz Parser is distributed in the hope that it will be useful, 
 23   but WITHOUT ANY WARRANTY; without even the implied warranty of 
 24   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 25   GNU General Public License for more details. 
 26    
 27   You should have received a copy of the GNU General Public License 
 28   along with The Jazz Parser.  If not, see <http://www.gnu.org/licenses/>. 
 29   
 30  ============================ End license ====================================== 
 31   
 32  """ 
 33  __author__ = "Mark Granroth-Wilding <mark.granroth-wilding@ed.ac.uk>"  
 34   
 35   
 36  import locale 
 37  from textwrap import TextWrapper 
 38   
 39  from jazzparser.utils.base import filter_latex 
 40   
 41  locale.setlocale(locale.LC_NUMERIC, "") 
 42   
43 -def format_num(num):
44 """Format a number according to given places. 45 Adds commas, etc. Will truncate floats into ints! 46 """ 47 48 try: 49 inum = int(num) 50 return locale.format("%.*f", (0, inum), True) 51 52 except (ValueError, TypeError): 53 return str(num)
54
55 -def get_max_width(table, index):
56 """ 57 Get the maximum width of the given column index 58 59 """ 60 return max([max(len(line) for line in row[index].split("\n")) for row in table])
61
62 -def format_table(*args, **kwargs):
63 """ 64 Like L{pprint_table}, but returns a string containing the formatted table, 65 whilst L{pprint_table} outputs directly to a stream. 66 67 Args and kwargs are the same as to L{pprint_table}. 68 69 """ 70 from cStringIO import StringIO 71 out = StringIO() 72 # Run pprint_table to do the pretty-printing 73 pprint_table(out, *args, **kwargs) 74 # Get the string that was printed 75 string = out.getvalue() 76 out.close() 77 return string
78
79 -def pprint_table(out, table, justs=None, separator=None, outer_seps=False, \ 80 widths=None, blank_row=False, default_just=None, hanging_indent=0):
81 """ 82 Prints out a table of data, padded for alignment. 83 Each row must have the same number of columns. 84 85 Cells may include line breaks. 86 87 @param out: output stream 88 @type out: file-like object 89 @param table: table to print. 90 @type table: list of lists 91 @param outer_seps: Prints separators at the start and end of each row 92 if true. 93 @type outer_seps: bool 94 @type widths: list of ints 95 @param widths: maximum width for each column. None means no maximum is 96 imposed. Words are wrapped if the width exceeds the maximum 97 @type default_just: bool 98 @param default_just: the default justification to use for all columns 99 if C{justs} is not given or where a column's justification is not 100 given. Default False 101 @type hanging_indent: int 102 @param hanging_indent: hanging indent to apply to the column if a cell 103 is wrapped (number of spaces) 104 105 """ 106 col_paddings = [] 107 wrapper = TextWrapper() 108 109 if hanging_indent: 110 wrapper.indent = '' 111 wrapper.subsequent_indent = ' '*hanging_indent 112 113 # Format any numbers in the table 114 table = [ 115 [format_num(cell) for cell in row] 116 for row in table] 117 118 # Work out the maximum width of each column so we know how much to pad 119 for i in range(len(table[0])): 120 if widths is not None and widths[i] is not None: 121 col_paddings.append(widths[i]) 122 else: 123 col_paddings.append(get_max_width(table, i)) 124 125 # Work out justification of each column 126 coljusts = [] 127 if default_just is None: 128 default_just = False 129 for col in range(len(table[0])): 130 if justs: 131 if justs[col] is not None: 132 coljust = justs[col] 133 else: 134 coljust = default_just 135 else: 136 coljust = default_just 137 coljusts.append(coljust) 138 139 # Wrap the long cells that have a max width 140 multiline = [] 141 for row in table: 142 mlrow = [] 143 for col,cell in enumerate(row): 144 # If this cell exceeds its max width, put it on multiple lines 145 if widths is not None and \ 146 widths[col] is not None and \ 147 len(cell) > widths[col]: 148 wrapper.width = widths[col] 149 lines = [] 150 # Split on manual line breaks in the input as well 151 for input_line in cell.split("\n"): 152 lines.extend(wrapper.wrap(input_line)) 153 else: 154 lines = cell.split("\n") 155 mlrow.append(lines) 156 multiline.append(mlrow) 157 158 for row in multiline: 159 if outer_seps: 160 print >> out, separator, 161 # Find out the cell with the most lines in this row 162 max_lines = max(len(cell) for cell in row) 163 # Each line of the row 164 for line in range(max_lines): 165 for col in range(len(row)): 166 # If this cell doesn't have this many lines, just pad 167 padsize = col_paddings[col] + 2 168 if line >= len(row[col]): 169 text = " " * padsize 170 else: 171 # There's text: justify it 172 if coljusts[col]: 173 text = row[col][line].ljust(padsize) 174 else: 175 text = row[col][line].rjust(padsize) 176 if col != 0 and separator: 177 print >> out, separator, 178 print >> out, text, 179 if outer_seps: 180 print >> out, separator, 181 print >>out 182 # Add an extra blank line between rows 183 if blank_row: 184 print >>out
185 209