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