##// END OF EJS Templates
Merge pull request #696 from fperez/fix_columnize...
Fernando Perez -
r4601:aa7247e8 merge
parent child Browse files
Show More
@@ -0,0 +1,44 b''
1 # encoding: utf-8
2 """Tests for IPython.utils.text"""
3
4 #-----------------------------------------------------------------------------
5 # Copyright (C) 2011 The IPython Development Team
6 #
7 # Distributed under the terms of the BSD License. The full license is in
8 # the file COPYING, distributed as part of this software.
9 #-----------------------------------------------------------------------------
10
11 #-----------------------------------------------------------------------------
12 # Imports
13 #-----------------------------------------------------------------------------
14
15 import os
16
17 import nose.tools as nt
18
19 from nose import with_setup
20
21 from IPython.testing import decorators as dec
22 from IPython.utils import text
23
24 #-----------------------------------------------------------------------------
25 # Globals
26 #-----------------------------------------------------------------------------
27
28 def test_columnize():
29 """Basic columnize tests."""
30 size = 5
31 items = [l*size for l in 'abc']
32 out = text.columnize(items, displaywidth=80)
33 nt.assert_equals(out, 'aaaaa bbbbb ccccc\n')
34 out = text.columnize(items, displaywidth=10)
35 nt.assert_equals(out, 'aaaaa ccccc\nbbbbb\n')
36
37
38 def test_columnize_long():
39 """Test columnize with inputs longer than the display window"""
40 text.columnize(['a'*81, 'b'*81], displaywidth=80)
41 size = 11
42 items = [l*size for l in 'abc']
43 out = text.columnize(items, displaywidth=size-1)
44 nt.assert_equals(out, '\n'.join(items+['']))
@@ -19,6 +19,7 b' from IPython.external.qt import QtCore, QtGui'
19 from IPython.config.configurable import Configurable
19 from IPython.config.configurable import Configurable
20 from IPython.frontend.qt.rich_text import HtmlExporter
20 from IPython.frontend.qt.rich_text import HtmlExporter
21 from IPython.frontend.qt.util import MetaQObjectHasTraits, get_font
21 from IPython.frontend.qt.util import MetaQObjectHasTraits, get_font
22 from IPython.utils.text import columnize
22 from IPython.utils.traitlets import Bool, Enum, Int, Unicode
23 from IPython.utils.traitlets import Bool, Enum, Int, Unicode
23 from ansi_code_processor import QtAnsiCodeProcessor
24 from ansi_code_processor import QtAnsiCodeProcessor
24 from completion_widget import CompletionWidget
25 from completion_widget import CompletionWidget
@@ -1295,52 +1296,7 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
1295 width = self._control.viewport().width()
1296 width = self._control.viewport().width()
1296 char_width = QtGui.QFontMetrics(self.font).width(' ')
1297 char_width = QtGui.QFontMetrics(self.font).width(' ')
1297 displaywidth = max(10, (width / char_width) - 1)
1298 displaywidth = max(10, (width / char_width) - 1)
1298
1299 return columnize(items, separator, displaywidth)
1299 # Some degenerate cases.
1300 size = len(items)
1301 if size == 0:
1302 return '\n'
1303 elif size == 1:
1304 return '%s\n' % items[0]
1305
1306 # Try every row count from 1 upwards
1307 array_index = lambda nrows, row, col: nrows*col + row
1308 for nrows in range(1, size):
1309 ncols = (size + nrows - 1) // nrows
1310 colwidths = []
1311 totwidth = -len(separator)
1312 for col in range(ncols):
1313 # Get max column width for this column
1314 colwidth = 0
1315 for row in range(nrows):
1316 i = array_index(nrows, row, col)
1317 if i >= size: break
1318 x = items[i]
1319 colwidth = max(colwidth, len(x))
1320 colwidths.append(colwidth)
1321 totwidth += colwidth + len(separator)
1322 if totwidth > displaywidth:
1323 break
1324 if totwidth <= displaywidth:
1325 break
1326
1327 # The smallest number of rows computed and the max widths for each
1328 # column has been obtained. Now we just have to format each of the rows.
1329 string = ''
1330 for row in range(nrows):
1331 texts = []
1332 for col in range(ncols):
1333 i = row + nrows*col
1334 if i >= size:
1335 texts.append('')
1336 else:
1337 texts.append(items[i])
1338 while texts and not texts[-1]:
1339 del texts[-1]
1340 for col in range(len(texts)):
1341 texts[col] = texts[col].ljust(colwidths[col])
1342 string += '%s\n' % separator.join(texts)
1343 return string
1344
1300
1345 def _get_block_plain_text(self, block):
1301 def _get_block_plain_text(self, block):
1346 """ Given a QTextBlock, return its unformatted text.
1302 """ Given a QTextBlock, return its unformatted text.
@@ -611,3 +611,76 b' class EvalFormatter(Formatter):'
611 raise KeyError(key)
611 raise KeyError(key)
612
612
613
613
614 def columnize(items, separator=' ', displaywidth=80):
615 """ Transform a list of strings into a single string with columns.
616
617 Parameters
618 ----------
619 items : sequence of strings
620 The strings to process.
621
622 separator : str, optional [default is two spaces]
623 The string that separates columns.
624
625 displaywidth : int, optional [default is 80]
626 Width of the display in number of characters.
627
628 Returns
629 -------
630 The formatted string.
631 """
632 # Note: this code is adapted from columnize 0.3.2.
633 # See http://code.google.com/p/pycolumnize/
634
635 # Some degenerate cases.
636 size = len(items)
637 if size == 0:
638 return '\n'
639 elif size == 1:
640 return '%s\n' % items[0]
641
642 # Special case: if any item is longer than the maximum width, there's no
643 # point in triggering the logic below...
644 item_len = map(len, items) # save these, we can reuse them below
645 longest = max(item_len)
646 if longest >= displaywidth:
647 return '\n'.join(items+[''])
648
649 # Try every row count from 1 upwards
650 array_index = lambda nrows, row, col: nrows*col + row
651 for nrows in range(1, size):
652 ncols = (size + nrows - 1) // nrows
653 colwidths = []
654 totwidth = -len(separator)
655 for col in range(ncols):
656 # Get max column width for this column
657 colwidth = 0
658 for row in range(nrows):
659 i = array_index(nrows, row, col)
660 if i >= size: break
661 x, len_x = items[i], item_len[i]
662 colwidth = max(colwidth, len_x)
663 colwidths.append(colwidth)
664 totwidth += colwidth + len(separator)
665 if totwidth > displaywidth:
666 break
667 if totwidth <= displaywidth:
668 break
669
670 # The smallest number of rows computed and the max widths for each
671 # column has been obtained. Now we just have to format each of the rows.
672 string = ''
673 for row in range(nrows):
674 texts = []
675 for col in range(ncols):
676 i = row + nrows*col
677 if i >= size:
678 texts.append('')
679 else:
680 texts.append(items[i])
681 while texts and not texts[-1]:
682 del texts[-1]
683 for col in range(len(texts)):
684 texts[col] = texts[col].ljust(colwidths[col])
685 string += '%s\n' % separator.join(texts)
686 return string
General Comments 0
You need to be logged in to leave comments. Login now