Skip to content

Commit

Permalink
Adding column line-wrapping
Browse files Browse the repository at this point in the history
  • Loading branch information
themiurgo committed Jan 8, 2016
1 parent 028919b commit f7852e7
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 13 deletions.
33 changes: 20 additions & 13 deletions csvkit/utilities/csvlook.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,19 @@
import six

from csvkit import CSVKitReader
from csvkit.cli import CSVKitUtility
from csvkit.cli import CSVKitUtility
from csvkit.headers import make_default_headers

class CSVLook(CSVKitUtility):
description = 'Render a CSV file in the console as a fixed-width table.'

def add_arguments(self):
pass
self.argparser.add_argument('-w', '--wrap', dest='wrapwidth', type=int,
help='Columns wrapwidth (allows to view long fields in multilines).', default=60)

def main(self):
rows = CSVKitReader(self.input_file, **self.reader_kwargs)
max_chars = self.args.wrapwidth

# Make a default header row if none exists
if self.args.no_header_row:
Expand All @@ -42,15 +44,16 @@ def main(self):
# Insert the column names at the top
rows.insert(0, column_names)

# Work out column widths
widths = []

for row in rows:
for i, v in enumerate(row):
lv = min(len(v), max_chars)
try:
if len(v) > widths[i]:
widths[i] = len(v)
if lv > widths[i]:
widths[i] = lv
except IndexError:
widths.append(len(v))
widths.append(lv)

# Dashes span each width with '+' character at intersection of
# horizontal and vertical dividers.
Expand All @@ -59,22 +62,26 @@ def main(self):
self.output_file.write('%s\n' % divider)

for i, row in enumerate(rows):
output = []
# Each row is made of inner rows because of text wrapping
row = [d or '' for d in row]
n_inner_rows = int(max([len(d)-1 for d in row]) / max_chars) + 1
inner_rows = [[d[j*max_chars:(j+1)*max_chars] for d in row]
for j in range(n_inner_rows)]

for j, d in enumerate(row):
if d is None:
d = ''
output.append(' %s ' % six.text_type(d).ljust(widths[j]))
for inner_row in inner_rows:
output = []
for j, d in enumerate(inner_row):
output.append(' %s ' % six.text_type(d).ljust(widths[j]))

self.output_file.write('| %s |\n' % ('|'.join(output)))
self.output_file.write('| %s |\n' % ('|'.join(output)))

if (i == 0 or i == len(rows) - 1):
self.output_file.write('%s\n' % divider)

def launch_new_instance():
utility = CSVLook()
utility.main()

if __name__ == "__main__":
launch_new_instance()

4 changes: 4 additions & 0 deletions examples/wrapping.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
a,b,c
1,0123456789,3
1,01234567890,5
1,012345678,7
20 changes: 20 additions & 0 deletions tests/test_utilities/test_csvlook.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,23 @@ def test_unicode(self):
self.assertEqual(next(input_file), u'| 4 | 5 | ʤ |\n')
self.assertEqual(next(input_file), '|----+---+----|\n')

def test_wrapping(self):
args = ['-w', '5', 'examples/wrapping.csv', ]
output_file = six.StringIO()
utility = CSVLook(args, output_file)

utility.main()

input_file = six.StringIO(output_file.getvalue())

self.assertEqual(next(input_file), '|----+-------+----|\n')
self.assertEqual(next(input_file), '| a | b | c |\n')
self.assertEqual(next(input_file), '|----+-------+----|\n')
self.assertEqual(next(input_file), '| 1 | 01234 | 3 |\n')
self.assertEqual(next(input_file), '| | 56789 | |\n')
self.assertEqual(next(input_file), '| 1 | 01234 | 5 |\n')
self.assertEqual(next(input_file), '| | 56789 | |\n')
self.assertEqual(next(input_file), '| | 0 | |\n')
self.assertEqual(next(input_file), '| 1 | 01234 | 7 |\n')
self.assertEqual(next(input_file), '| | 5678 | |\n')
self.assertEqual(next(input_file), '|----+-------+----|\n')

0 comments on commit f7852e7

Please sign in to comment.