Skip to content

Commit 578071d

Browse files
authored
Merge pull request astanin#23 from stmcginnis/prettytable
2 parents f1882da + ba3c203 commit 578071d

File tree

3 files changed

+154
-1
lines changed

3 files changed

+154
-1
lines changed

README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ Supported table formats are:
142142
- "orgtbl"
143143
- "jira"
144144
- "presto"
145+
- "pretty"
145146
- "psql"
146147
- "rst"
147148
- "mediawiki"
@@ -221,6 +222,18 @@ corresponds to the `pipe` format without alignment colons:
221222
eggs | 451
222223
bacon | 0
223224

225+
`pretty` attempts to be close to the format emitted by the PrettyTables
226+
library:
227+
228+
>>> print(tabulate(table, headers, tablefmt="pretty"))
229+
+-------+-----+
230+
| item | qty |
231+
+-------+-----+
232+
| spam | 42 |
233+
| eggs | 451 |
234+
| bacon | 0 |
235+
+-------+-----+
236+
224237
`psql` is like tables formatted by Postgres' psql cli:
225238

226239
>>> print(tabulate(table, headers, tablefmt="psql"))
@@ -580,6 +593,18 @@ a multiline cell, and headers with a multiline cell:
580593
more | 42
581594
spam |
582595

596+
`pretty` tables:
597+
598+
>>> print(tabulate(table, headers, tablefmt="pretty"))
599+
+------+-----+
600+
| item | qty |
601+
| name | |
602+
+------+-----+
603+
| eggs | 451 |
604+
| more | 42 |
605+
| spam | |
606+
+------+-----+
607+
583608
`psql` tables:
584609

585610
>>> print(tabulate(table, headers, tablefmt="psql"))

tabulate.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,16 @@ def escape_empty(val):
359359
padding=1,
360360
with_header_hide=None,
361361
),
362+
"pretty": TableFormat(
363+
lineabove=Line("+", "-", "+", "+"),
364+
linebelowheader=Line("+", "-", "+", "+"),
365+
linebetweenrows=None,
366+
linebelow=Line("+", "-", "+", "+"),
367+
headerrow=DataRow("|", "|", "|"),
368+
datarow=DataRow("|", "|", "|"),
369+
padding=1,
370+
with_header_hide=None,
371+
),
362372
"psql": TableFormat(
363373
lineabove=Line("+", "-", "+", "+"),
364374
linebelowheader=Line("|", "-", "+", "|"),
@@ -491,6 +501,7 @@ def escape_empty(val):
491501
"orgtbl": "orgtbl",
492502
"jira": "jira",
493503
"presto": "presto",
504+
"pretty": "pretty",
494505
"psql": "psql",
495506
"rst": "rst",
496507
}
@@ -1421,6 +1432,17 @@ def tabulate(
14211432
if tablefmt == "rst":
14221433
list_of_lists, headers = _rst_escape_first_column(list_of_lists, headers)
14231434

1435+
# PrettyTable formatting does not use any extra padding.
1436+
# Numbers are not parsed and are treated the same as strings for alignment.
1437+
# Check if pretty is the format being used and override the defaults so it
1438+
# does not impact other formats.
1439+
min_padding = MIN_PADDING
1440+
if tablefmt == "pretty":
1441+
min_padding = 0
1442+
disable_numparse = True
1443+
numalign = "center"
1444+
stralign = "center"
1445+
14241446
# optimization: look for ANSI control codes once,
14251447
# enable smart width functions only if a control code is found
14261448
plain_text = "\t".join(
@@ -1471,7 +1493,7 @@ def tabulate(
14711493
for idx, align in enumerate(colalign):
14721494
aligns[idx] = align
14731495
minwidths = (
1474-
[width_fn(h) + MIN_PADDING for h in headers] if headers else [0] * len(cols)
1496+
[width_fn(h) + min_padding for h in headers] if headers else [0] * len(cols)
14751497
)
14761498
cols = [
14771499
_align_column(c, a, minw, has_invisible, enable_widechars, is_multiline)

test/test_output.py

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,112 @@ def test_psql_multiline_with_empty_cells_headerless():
700700
assert_equal(expected, result)
701701

702702

703+
def test_pretty():
704+
"Output: pretty with headers"
705+
expected = "\n".join(
706+
[
707+
"+---------+---------+",
708+
"| strings | numbers |",
709+
"+---------+---------+",
710+
"| spam | 41.9999 |",
711+
"| eggs | 451.0 |",
712+
"+---------+---------+",
713+
]
714+
)
715+
result = tabulate(_test_table, _test_table_headers, tablefmt="pretty")
716+
assert_equal(expected, result)
717+
718+
719+
def test_pretty_headerless():
720+
"Output: pretty without headers"
721+
expected = "\n".join(
722+
[
723+
"+------+---------+",
724+
"| spam | 41.9999 |",
725+
"| eggs | 451.0 |",
726+
"+------+---------+",
727+
]
728+
)
729+
result = tabulate(_test_table, tablefmt="pretty")
730+
assert_equal(expected, result)
731+
732+
733+
def test_pretty_multiline_headerless():
734+
"Output: pretty with multiline cells without headers"
735+
table = [["foo bar\nbaz\nbau", "hello"], ["", "multiline\nworld"]]
736+
expected = "\n".join(
737+
[
738+
"+---------+-----------+",
739+
"| foo bar | hello |",
740+
"| baz | |",
741+
"| bau | |",
742+
"| | multiline |",
743+
"| | world |",
744+
"+---------+-----------+",
745+
]
746+
)
747+
result = tabulate(table, tablefmt="pretty")
748+
assert_equal(expected, result)
749+
750+
751+
def test_pretty_multiline():
752+
"Output: pretty with multiline cells with headers"
753+
table = [[2, "foo\nbar"]]
754+
headers = ("more\nspam \x1b[31meggs\x1b[0m", "more spam\n& eggs")
755+
expected = "\n".join(
756+
[
757+
"+-----------+-----------+",
758+
"| more | more spam |",
759+
"| spam \x1b[31meggs\x1b[0m | & eggs |",
760+
"+-----------+-----------+",
761+
"| 2 | foo |",
762+
"| | bar |",
763+
"+-----------+-----------+",
764+
]
765+
)
766+
result = tabulate(table, headers, tablefmt="pretty")
767+
assert_equal(expected, result)
768+
769+
770+
def test_pretty_multiline_with_empty_cells():
771+
"Output: pretty with multiline cells and empty cells with headers"
772+
table = [
773+
["hdr", "data", "fold"],
774+
["1", "", ""],
775+
["2", "very long data", "fold\nthis"],
776+
]
777+
expected = "\n".join(
778+
[
779+
"+-----+----------------+------+",
780+
"| hdr | data | fold |",
781+
"+-----+----------------+------+",
782+
"| 1 | | |",
783+
"| 2 | very long data | fold |",
784+
"| | | this |",
785+
"+-----+----------------+------+",
786+
]
787+
)
788+
result = tabulate(table, headers="firstrow", tablefmt="pretty")
789+
assert_equal(expected, result)
790+
791+
792+
def test_pretty_multiline_with_empty_cells_headerless():
793+
"Output: pretty with multiline cells and empty cells without headers"
794+
table = [["0", "", ""], ["1", "", ""], ["2", "very long data", "fold\nthis"]]
795+
expected = "\n".join(
796+
[
797+
"+---+----------------+------+",
798+
"| 0 | | |",
799+
"| 1 | | |",
800+
"| 2 | very long data | fold |",
801+
"| | | this |",
802+
"+---+----------------+------+",
803+
]
804+
)
805+
result = tabulate(table, tablefmt="pretty")
806+
assert_equal(expected, result)
807+
808+
703809
def test_jira():
704810
"Output: jira with headers"
705811
expected = "\n".join(

0 commit comments

Comments
 (0)