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
54
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
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
114 table = [
115 [format_num(cell) for cell in row]
116 for row in table]
117
118
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
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
140 multiline = []
141 for row in table:
142 mlrow = []
143 for col,cell in enumerate(row):
144
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
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
162 max_lines = max(len(cell) for cell in row)
163
164 for line in range(max_lines):
165 for col in range(len(row)):
166
167 padsize = col_paddings[col] + 2
168 if line >= len(row[col]):
169 text = " " * padsize
170 else:
171
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
183 if blank_row:
184 print >>out
185
187 """
188 Prints out the Latex code to display the given
189 2D list as a table.
190
191 """
192 if justs is None:
193 justs = ["l"] * len(table[0])
194
195 if separator:
196 coldiv = " | "
197 else:
198 coldiv = " "
199
200 print >> out, "\\begin{tabular}{%s}" % coldiv.join(justs)
201
202 if headings:
203 print >> out, " & ".join(["\\textbf{%s}" % filter_latex("%s" % cell) for cell in table[0]]) + "\\\\\n"
204 print >> out, "\\\\\n".join([" & ".join([filter_latex("%s" % cell) for cell in row]) for row in table[1:]])
205 else:
206 print >> out, "\\\\\n".join([" & ".join([filter_latex("%s" % cell) for cell in row]) for row in table])
207
208 print >> out, "\\end{tabular}"
209