@@ -83,7 +83,7 @@ def __init__(self, header: str, *, width: Optional[int] = None,
8383 :param header: label for column header
8484 :param width: display width of column. This does not account for any borders or padding which
8585 may be added (e.g pre_line, inter_cell, and post_line). Header and data text wrap within
86- this width using word-based wrapping (defaults to width of header or 1 if header is blank)
86+ this width using word-based wrapping (defaults to actual width of header or 1 if header is blank)
8787 :param header_horiz_align: horizontal alignment of header cells (defaults to left)
8888 :param header_vert_align: vertical alignment of header cells (defaults to bottom)
8989 :param data_horiz_align: horizontal alignment of data cells (defaults to left)
@@ -95,12 +95,7 @@ def __init__(self, header: str, *, width: Optional[int] = None,
9595 """
9696 self .header = header
9797
98- if width is None :
99- # Use the width of the widest line in the header or 1 if the header has no width
100- line_widths = [ansi .style_aware_wcswidth (line ) for line in self .header .splitlines ()]
101- line_widths .append (1 )
102- self .width = max (line_widths )
103- elif width < 1 :
98+ if width is not None and width < 1 :
10499 raise ValueError ("Column width cannot be less than 1" )
105100 else :
106101 self .width = width
@@ -141,8 +136,20 @@ def __init__(self, cols: Sequence[Column], *, tab_width: int = 4) -> None:
141136 self .cols = copy .copy (cols )
142137 self .tab_width = tab_width
143138
139+ for col in self .cols :
140+ # Replace tabs before calculating width of header strings
141+ col .header = col .header .replace ('\t ' , SPACE * self .tab_width )
142+
143+ # For headers with the width not yet set, use the width of the
144+ # widest line in the header or 1 if the header has no width
145+ if col .width is None :
146+ line_widths = [ansi .style_aware_wcswidth (line ) for line in col .header .splitlines ()]
147+ line_widths .append (1 )
148+ col .width = max (line_widths )
149+
144150 @staticmethod
145- def _wrap_long_word (word : str , max_width : int , max_lines : Union [int , float ], is_last_word : bool ) -> Tuple [str , int , int ]:
151+ def _wrap_long_word (word : str , max_width : int , max_lines : Union [int , float ],
152+ is_last_word : bool ) -> Tuple [str , int , int ]:
146153 """
147154 Used by _wrap_text() to wrap a long word over multiple lines
148155
@@ -351,14 +358,16 @@ def add_word(word_to_add: str, is_last_word: bool):
351358
352359 # Stop line loop if we've written to max_lines
353360 if total_lines == max_lines :
354- # If this isn't the last data line and there is space left on the final wrapped line, then add an ellipsis
361+ # If this isn't the last data line and there is space
362+ # left on the final wrapped line, then add an ellipsis
355363 if data_line_index < len (data_str_lines ) - 1 and cur_line_width < max_width :
356364 wrapped_buf .write (constants .HORIZONTAL_ELLIPSIS )
357365 break
358366
359367 return wrapped_buf .getvalue ()
360368
361- def _generate_cell_lines (self , cell_data : Any , is_header : bool , col : Column , fill_char : str ) -> Tuple [Deque [str ], int ]:
369+ def _generate_cell_lines (self , cell_data : Any , is_header : bool ,
370+ col : Column , fill_char : str ) -> Tuple [Deque [str ], int ]:
362371 """
363372 Generate the lines of a table cell
364373
@@ -398,14 +407,14 @@ def generate_row(self, *, row_data: Optional[Sequence[Any]] = None, fill_char: s
398407
399408 :param row_data: If this is None then a header row is generated. Otherwise data should have an entry for each
400409 column in the row. (Defaults to None)
401- :param fill_char: character that fills remaining space in a cell. Defaults to space. If this is a tab, then it will
402- be converted to one space. (Cannot be a line breaking character)
410+ :param fill_char: character that fills remaining space in a cell. Defaults to space. If this is a tab,
411+ then it will be converted to one space. (Cannot be a line breaking character)
403412 :param pre_line: string to print before each line of a row. This can be used for a left row border and
404413 padding before the first cell's text. (Defaults to blank)
405414 :param inter_cell: string to print where two cells meet. This can be used for a border between cells and padding
406415 between it and the 2 cells' text. (Defaults to 2 spaces)
407- :param post_line: string to print after each line of a row. This can be used for padding after the last cell's text
408- and a right row border. (Defaults to blank)
416+ :param post_line: string to print after each line of a row. This can be used for padding after
417+ the last cell's text and a right row border. (Defaults to blank)
409418 :return: row string
410419 :raises: ValueError if data isn't the same length as self.cols
411420 :raises: TypeError if fill_char is more than one character (not including ANSI style sequences)
@@ -608,7 +617,8 @@ def generate_table(self, table_data: Sequence[Sequence[Any]], *,
608617 :param table_data: Data with an entry for each data row of the table. Each entry should have data for
609618 each column in the row.
610619 :param include_header: If True, then a header will be included at top of table. (Defaults to True)
611- :param row_spacing: A number 0 or greater specifying how many blank lines to place between each row (Defaults to 1)
620+ :param row_spacing: A number 0 or greater specifying how many blank lines to place between
621+ each row (Defaults to 1)
612622 :raises: ValueError if row_spacing is less than 0
613623 """
614624 if row_spacing < 0 :
@@ -820,8 +830,8 @@ def generate_table(self, table_data: Sequence[Sequence[Any]], *, include_header:
820830
821831class AlternatingTable (BorderedTable ):
822832 """
823- Implementation of BorderedTable which uses background colors to distinguish between rows instead of row border lines.
824- This class can be used to create the whole table at once or one row at a time.
833+ Implementation of BorderedTable which uses background colors to distinguish between rows instead of row border
834+ lines. This class can be used to create the whole table at once or one row at a time.
825835 """
826836 def __init__ (self , cols : Sequence [Column ], * , tab_width : int = 4 , column_borders : bool = True , padding : int = 1 ,
827837 bg_odd : Optional [ansi .bg ] = None , bg_even : Optional [ansi .bg ] = ansi .bg .bright_black ) -> None :
0 commit comments