From 12cf076118570eebbff08c6b3090e0d4798447a1 Mon Sep 17 00:00:00 2001 From: cyfraeviolae Date: Wed, 3 Apr 2024 03:17:55 -0400 Subject: no venv --- venv/lib/python3.11/site-packages/rich/table.py | 1000 ----------------------- 1 file changed, 1000 deletions(-) delete mode 100644 venv/lib/python3.11/site-packages/rich/table.py (limited to 'venv/lib/python3.11/site-packages/rich/table.py') diff --git a/venv/lib/python3.11/site-packages/rich/table.py b/venv/lib/python3.11/site-packages/rich/table.py deleted file mode 100644 index 5fc5ace..0000000 --- a/venv/lib/python3.11/site-packages/rich/table.py +++ /dev/null @@ -1,1000 +0,0 @@ -from dataclasses import dataclass, field, replace -from typing import ( - TYPE_CHECKING, - Dict, - Iterable, - List, - NamedTuple, - Optional, - Sequence, - Tuple, - Union, -) - -from . import box, errors -from ._loop import loop_first_last, loop_last -from ._pick import pick_bool -from ._ratio import ratio_distribute, ratio_reduce -from .align import VerticalAlignMethod -from .jupyter import JupyterMixin -from .measure import Measurement -from .padding import Padding, PaddingDimensions -from .protocol import is_renderable -from .segment import Segment -from .style import Style, StyleType -from .text import Text, TextType - -if TYPE_CHECKING: - from .console import ( - Console, - ConsoleOptions, - JustifyMethod, - OverflowMethod, - RenderableType, - RenderResult, - ) - - -@dataclass -class Column: - """Defines a column within a ~Table. - - Args: - title (Union[str, Text], optional): The title of the table rendered at the top. Defaults to None. - caption (Union[str, Text], optional): The table caption rendered below. Defaults to None. - width (int, optional): The width in characters of the table, or ``None`` to automatically fit. Defaults to None. - min_width (Optional[int], optional): The minimum width of the table, or ``None`` for no minimum. Defaults to None. - box (box.Box, optional): One of the constants in box.py used to draw the edges (see :ref:`appendix_box`), or ``None`` for no box lines. Defaults to box.HEAVY_HEAD. - safe_box (Optional[bool], optional): Disable box characters that don't display on windows legacy terminal with *raster* fonts. Defaults to True. - padding (PaddingDimensions, optional): Padding for cells (top, right, bottom, left). Defaults to (0, 1). - collapse_padding (bool, optional): Enable collapsing of padding around cells. Defaults to False. - pad_edge (bool, optional): Enable padding of edge cells. Defaults to True. - expand (bool, optional): Expand the table to fit the available space if ``True``, otherwise the table width will be auto-calculated. Defaults to False. - show_header (bool, optional): Show a header row. Defaults to True. - show_footer (bool, optional): Show a footer row. Defaults to False. - show_edge (bool, optional): Draw a box around the outside of the table. Defaults to True. - show_lines (bool, optional): Draw lines between every row. Defaults to False. - leading (bool, optional): Number of blank lines between rows (precludes ``show_lines``). Defaults to 0. - style (Union[str, Style], optional): Default style for the table. Defaults to "none". - row_styles (List[Union, str], optional): Optional list of row styles, if more than one style is given then the styles will alternate. Defaults to None. - header_style (Union[str, Style], optional): Style of the header. Defaults to "table.header". - footer_style (Union[str, Style], optional): Style of the footer. Defaults to "table.footer". - border_style (Union[str, Style], optional): Style of the border. Defaults to None. - title_style (Union[str, Style], optional): Style of the title. Defaults to None. - caption_style (Union[str, Style], optional): Style of the caption. Defaults to None. - title_justify (str, optional): Justify method for title. Defaults to "center". - caption_justify (str, optional): Justify method for caption. Defaults to "center". - highlight (bool, optional): Highlight cell contents (if str). Defaults to False. - """ - - header: "RenderableType" = "" - """RenderableType: Renderable for the header (typically a string)""" - - footer: "RenderableType" = "" - """RenderableType: Renderable for the footer (typically a string)""" - - header_style: StyleType = "" - """StyleType: The style of the header.""" - - footer_style: StyleType = "" - """StyleType: The style of the footer.""" - - style: StyleType = "" - """StyleType: The style of the column.""" - - justify: "JustifyMethod" = "left" - """str: How to justify text within the column ("left", "center", "right", or "full")""" - - vertical: "VerticalAlignMethod" = "top" - """str: How to vertically align content ("top", "middle", or "bottom")""" - - overflow: "OverflowMethod" = "ellipsis" - """str: Overflow method.""" - - width: Optional[int] = None - """Optional[int]: Width of the column, or ``None`` (default) to auto calculate width.""" - - min_width: Optional[int] = None - """Optional[int]: Minimum width of column, or ``None`` for no minimum. Defaults to None.""" - - max_width: Optional[int] = None - """Optional[int]: Maximum width of column, or ``None`` for no maximum. Defaults to None.""" - - ratio: Optional[int] = None - """Optional[int]: Ratio to use when calculating column width, or ``None`` (default) to adapt to column contents.""" - - no_wrap: bool = False - """bool: Prevent wrapping of text within the column. Defaults to ``False``.""" - - _index: int = 0 - """Index of column.""" - - _cells: List["RenderableType"] = field(default_factory=list) - - def copy(self) -> "Column": - """Return a copy of this Column.""" - return replace(self, _cells=[]) - - @property - def cells(self) -> Iterable["RenderableType"]: - """Get all cells in the column, not including header.""" - yield from self._cells - - @property - def flexible(self) -> bool: - """Check if this column is flexible.""" - return self.ratio is not None - - -@dataclass -class Row: - """Information regarding a row.""" - - style: Optional[StyleType] = None - """Style to apply to row.""" - - end_section: bool = False - """Indicated end of section, which will force a line beneath the row.""" - - -class _Cell(NamedTuple): - """A single cell in a table.""" - - style: StyleType - """Style to apply to cell.""" - renderable: "RenderableType" - """Cell renderable.""" - vertical: VerticalAlignMethod - """Cell vertical alignment.""" - - -class Table(JupyterMixin): - """A console renderable to draw a table. - - Args: - *headers (Union[Column, str]): Column headers, either as a string, or :class:`~rich.table.Column` instance. - title (Union[str, Text], optional): The title of the table rendered at the top. Defaults to None. - caption (Union[str, Text], optional): The table caption rendered below. Defaults to None. - width (int, optional): The width in characters of the table, or ``None`` to automatically fit. Defaults to None. - min_width (Optional[int], optional): The minimum width of the table, or ``None`` for no minimum. Defaults to None. - box (box.Box, optional): One of the constants in box.py used to draw the edges (see :ref:`appendix_box`), or ``None`` for no box lines. Defaults to box.HEAVY_HEAD. - safe_box (Optional[bool], optional): Disable box characters that don't display on windows legacy terminal with *raster* fonts. Defaults to True. - padding (PaddingDimensions, optional): Padding for cells (top, right, bottom, left). Defaults to (0, 1). - collapse_padding (bool, optional): Enable collapsing of padding around cells. Defaults to False. - pad_edge (bool, optional): Enable padding of edge cells. Defaults to True. - expand (bool, optional): Expand the table to fit the available space if ``True``, otherwise the table width will be auto-calculated. Defaults to False. - show_header (bool, optional): Show a header row. Defaults to True. - show_footer (bool, optional): Show a footer row. Defaults to False. - show_edge (bool, optional): Draw a box around the outside of the table. Defaults to True. - show_lines (bool, optional): Draw lines between every row. Defaults to False. - leading (bool, optional): Number of blank lines between rows (precludes ``show_lines``). Defaults to 0. - style (Union[str, Style], optional): Default style for the table. Defaults to "none". - row_styles (List[Union, str], optional): Optional list of row styles, if more than one style is given then the styles will alternate. Defaults to None. - header_style (Union[str, Style], optional): Style of the header. Defaults to "table.header". - footer_style (Union[str, Style], optional): Style of the footer. Defaults to "table.footer". - border_style (Union[str, Style], optional): Style of the border. Defaults to None. - title_style (Union[str, Style], optional): Style of the title. Defaults to None. - caption_style (Union[str, Style], optional): Style of the caption. Defaults to None. - title_justify (str, optional): Justify method for title. Defaults to "center". - caption_justify (str, optional): Justify method for caption. Defaults to "center". - highlight (bool, optional): Highlight cell contents (if str). Defaults to False. - """ - - columns: List[Column] - rows: List[Row] - - def __init__( - self, - *headers: Union[Column, str], - title: Optional[TextType] = None, - caption: Optional[TextType] = None, - width: Optional[int] = None, - min_width: Optional[int] = None, - box: Optional[box.Box] = box.HEAVY_HEAD, - safe_box: Optional[bool] = None, - padding: PaddingDimensions = (0, 1), - collapse_padding: bool = False, - pad_edge: bool = True, - expand: bool = False, - show_header: bool = True, - show_footer: bool = False, - show_edge: bool = True, - show_lines: bool = False, - leading: int = 0, - style: StyleType = "none", - row_styles: Optional[Iterable[StyleType]] = None, - header_style: Optional[StyleType] = "table.header", - footer_style: Optional[StyleType] = "table.footer", - border_style: Optional[StyleType] = None, - title_style: Optional[StyleType] = None, - caption_style: Optional[StyleType] = None, - title_justify: "JustifyMethod" = "center", - caption_justify: "JustifyMethod" = "center", - highlight: bool = False, - ) -> None: - self.columns: List[Column] = [] - self.rows: List[Row] = [] - self.title = title - self.caption = caption - self.width = width - self.min_width = min_width - self.box = box - self.safe_box = safe_box - self._padding = Padding.unpack(padding) - self.pad_edge = pad_edge - self._expand = expand - self.show_header = show_header - self.show_footer = show_footer - self.show_edge = show_edge - self.show_lines = show_lines - self.leading = leading - self.collapse_padding = collapse_padding - self.style = style - self.header_style = header_style or "" - self.footer_style = footer_style or "" - self.border_style = border_style - self.title_style = title_style - self.caption_style = caption_style - self.title_justify: "JustifyMethod" = title_justify - self.caption_justify: "JustifyMethod" = caption_justify - self.highlight = highlight - self.row_styles: Sequence[StyleType] = list(row_styles or []) - append_column = self.columns.append - for header in headers: - if isinstance(header, str): - self.add_column(header=header) - else: - header._index = len(self.columns) - append_column(header) - - @classmethod - def grid( - cls, - *headers: Union[Column, str], - padding: PaddingDimensions = 0, - collapse_padding: bool = True, - pad_edge: bool = False, - expand: bool = False, - ) -> "Table": - """Get a table with no lines, headers, or footer. - - Args: - *headers (Union[Column, str]): Column headers, either as a string, or :class:`~rich.table.Column` instance. - padding (PaddingDimensions, optional): Get padding around cells. Defaults to 0. - collapse_padding (bool, optional): Enable collapsing of padding around cells. Defaults to True. - pad_edge (bool, optional): Enable padding around edges of table. Defaults to False. - expand (bool, optional): Expand the table to fit the available space if ``True``, otherwise the table width will be auto-calculated. Defaults to False. - - Returns: - Table: A table instance. - """ - return cls( - *headers, - box=None, - padding=padding, - collapse_padding=collapse_padding, - show_header=False, - show_footer=False, - show_edge=False, - pad_edge=pad_edge, - expand=expand, - ) - - @property - def expand(self) -> bool: - """Setting a non-None self.width implies expand.""" - return self._expand or self.width is not None - - @expand.setter - def expand(self, expand: bool) -> None: - """Set expand.""" - self._expand = expand - - @property - def _extra_width(self) -> int: - """Get extra width to add to cell content.""" - width = 0 - if self.box and self.show_edge: - width += 2 - if self.box: - width += len(self.columns) - 1 - return width - - @property - def row_count(self) -> int: - """Get the current number of rows.""" - return len(self.rows) - - def get_row_style(self, console: "Console", index: int) -> StyleType: - """Get the current row style.""" - style = Style.null() - if self.row_styles: - style += console.get_style(self.row_styles[index % len(self.row_styles)]) - row_style = self.rows[index].style - if row_style is not None: - style += console.get_style(row_style) - return style - - def __rich_measure__( - self, console: "Console", options: "ConsoleOptions" - ) -> Measurement: - max_width = options.max_width - if self.width is not None: - max_width = self.width - if max_width < 0: - return Measurement(0, 0) - - extra_width = self._extra_width - max_width = sum( - self._calculate_column_widths( - console, options.update_width(max_width - extra_width) - ) - ) - _measure_column = self._measure_column - - measurements = [ - _measure_column(console, options.update_width(max_width), column) - for column in self.columns - ] - minimum_width = ( - sum(measurement.minimum for measurement in measurements) + extra_width - ) - maximum_width = ( - sum(measurement.maximum for measurement in measurements) + extra_width - if (self.width is None) - else self.width - ) - measurement = Measurement(minimum_width, maximum_width) - measurement = measurement.clamp(self.min_width) - return measurement - - @property - def padding(self) -> Tuple[int, int, int, int]: - """Get cell padding.""" - return self._padding - - @padding.setter - def padding(self, padding: PaddingDimensions) -> "Table": - """Set cell padding.""" - self._padding = Padding.unpack(padding) - return self - - def add_column( - self, - header: "RenderableType" = "", - footer: "RenderableType" = "", - *, - header_style: Optional[StyleType] = None, - footer_style: Optional[StyleType] = None, - style: Optional[StyleType] = None, - justify: "JustifyMethod" = "left", - vertical: "VerticalAlignMethod" = "top", - overflow: "OverflowMethod" = "ellipsis", - width: Optional[int] = None, - min_width: Optional[int] = None, - max_width: Optional[int] = None, - ratio: Optional[int] = None, - no_wrap: bool = False, - ) -> None: - """Add a column to the table. - - Args: - header (RenderableType, optional): Text or renderable for the header. - Defaults to "". - footer (RenderableType, optional): Text or renderable for the footer. - Defaults to "". - header_style (Union[str, Style], optional): Style for the header, or None for default. Defaults to None. - footer_style (Union[str, Style], optional): Style for the footer, or None for default. Defaults to None. - style (Union[str, Style], optional): Style for the column cells, or None for default. Defaults to None. - justify (JustifyMethod, optional): Alignment for cells. Defaults to "left". - vertical (VerticalAlignMethod, optional): Vertical alignment, one of "top", "middle", or "bottom". Defaults to "top". - overflow (OverflowMethod): Overflow method: "crop", "fold", "ellipsis". Defaults to "ellipsis". - width (int, optional): Desired width of column in characters, or None to fit to contents. Defaults to None. - min_width (Optional[int], optional): Minimum width of column, or ``None`` for no minimum. Defaults to None. - max_width (Optional[int], optional): Maximum width of column, or ``None`` for no maximum. Defaults to None. - ratio (int, optional): Flexible ratio for the column (requires ``Table.expand`` or ``Table.width``). Defaults to None. - no_wrap (bool, optional): Set to ``True`` to disable wrapping of this column. - """ - - column = Column( - _index=len(self.columns), - header=header, - footer=footer, - header_style=header_style or "", - footer_style=footer_style or "", - style=style or "", - justify=justify, - vertical=vertical, - overflow=overflow, - width=width, - min_width=min_width, - max_width=max_width, - ratio=ratio, - no_wrap=no_wrap, - ) - self.columns.append(column) - - def add_row( - self, - *renderables: Optional["RenderableType"], - style: Optional[StyleType] = None, - end_section: bool = False, - ) -> None: - """Add a row of renderables. - - Args: - *renderables (None or renderable): Each cell in a row must be a renderable object (including str), - or ``None`` for a blank cell. - style (StyleType, optional): An optional style to apply to the entire row. Defaults to None. - end_section (bool, optional): End a section and draw a line. Defaults to False. - - Raises: - errors.NotRenderableError: If you add something that can't be rendered. - """ - - def add_cell(column: Column, renderable: "RenderableType") -> None: - column._cells.append(renderable) - - cell_renderables: List[Optional["RenderableType"]] = list(renderables) - - columns = self.columns - if len(cell_renderables) < len(columns): - cell_renderables = [ - *cell_renderables, - *[None] * (len(columns) - len(cell_renderables)), - ] - for index, renderable in enumerate(cell_renderables): - if index == len(columns): - column = Column(_index=index) - for _ in self.rows: - add_cell(column, Text("")) - self.columns.append(column) - else: - column = columns[index] - if renderable is None: - add_cell(column, "") - elif is_renderable(renderable): - add_cell(column, renderable) - else: - raise errors.NotRenderableError( - f"unable to render {type(renderable).__name__}; a string or other renderable object is required" - ) - self.rows.append(Row(style=style, end_section=end_section)) - - def add_section(self) -> None: - """Add a new section (draw a line after current row).""" - - if self.rows: - self.rows[-1].end_section = True - - def __rich_console__( - self, console: "Console", options: "ConsoleOptions" - ) -> "RenderResult": - if not self.columns: - yield Segment("\n") - return - - max_width = options.max_width - if self.width is not None: - max_width = self.width - - extra_width = self._extra_width - widths = self._calculate_column_widths( - console, options.update_width(max_width - extra_width) - ) - table_width = sum(widths) + extra_width - - render_options = options.update( - width=table_width, highlight=self.highlight, height=None - ) - - def render_annotation( - text: TextType, style: StyleType, justify: "JustifyMethod" = "center" - ) -> "RenderResult": - render_text = ( - console.render_str(text, style=style, highlight=False) - if isinstance(text, str) - else text - ) - return console.render( - render_text, options=render_options.update(justify=justify) - ) - - if self.title: - yield from render_annotation( - self.title, - style=Style.pick_first(self.title_style, "table.title"), - justify=self.title_justify, - ) - yield from self._render(console, render_options, widths) - if self.caption: - yield from render_annotation( - self.caption, - style=Style.pick_first(self.caption_style, "table.caption"), - justify=self.caption_justify, - ) - - def _calculate_column_widths( - self, console: "Console", options: "ConsoleOptions" - ) -> List[int]: - """Calculate the widths of each column, including padding, not including borders.""" - max_width = options.max_width - columns = self.columns - width_ranges = [ - self._measure_column(console, options, column) for column in columns - ] - widths = [_range.maximum or 1 for _range in width_ranges] - get_padding_width = self._get_padding_width - extra_width = self._extra_width - if self.expand: - ratios = [col.ratio or 0 for col in columns if col.flexible] - if any(ratios): - fixed_widths = [ - 0 if column.flexible else _range.maximum - for _range, column in zip(width_ranges, columns) - ] - flex_minimum = [ - (column.width or 1) + get_padding_width(column._index) - for column in columns - if column.flexible - ] - flexible_width = max_width - sum(fixed_widths) - flex_widths = ratio_distribute(flexible_width, ratios, flex_minimum) - iter_flex_widths = iter(flex_widths) - for index, column in enumerate(columns): - if column.flexible: - widths[index] = fixed_widths[index] + next(iter_flex_widths) - table_width = sum(widths) - - if table_width > max_width: - widths = self._collapse_widths( - widths, - [(column.width is None and not column.no_wrap) for column in columns], - max_width, - ) - table_width = sum(widths) - # last resort, reduce columns evenly - if table_width > max_width: - excess_width = table_width - max_width - widths = ratio_reduce(excess_width, [1] * len(widths), widths, widths) - table_width = sum(widths) - - width_ranges = [ - self._measure_column(console, options.update_width(width), column) - for width, column in zip(widths, columns) - ] - widths = [_range.maximum or 0 for _range in width_ranges] - - if (table_width < max_width and self.expand) or ( - self.min_width is not None and table_width < (self.min_width - extra_width) - ): - _max_width = ( - max_width - if self.min_width is None - else min(self.min_width - extra_width, max_width) - ) - pad_widths = ratio_distribute(_max_width - table_width, widths) - widths = [_width + pad for _width, pad in zip(widths, pad_widths)] - - return widths - - @classmethod - def _collapse_widths( - cls, widths: List[int], wrapable: List[bool], max_width: int - ) -> List[int]: - """Reduce widths so that the total is under max_width. - - Args: - widths (List[int]): List of widths. - wrapable (List[bool]): List of booleans that indicate if a column may shrink. - max_width (int): Maximum width to reduce to. - - Returns: - List[int]: A new list of widths. - """ - total_width = sum(widths) - excess_width = total_width - max_width - if any(wrapable): - while total_width and excess_width > 0: - max_column = max( - width for width, allow_wrap in zip(widths, wrapable) if allow_wrap - ) - second_max_column = max( - width if allow_wrap and width != max_column else 0 - for width, allow_wrap in zip(widths, wrapable) - ) - column_difference = max_column - second_max_column - ratios = [ - (1 if (width == max_column and allow_wrap) else 0) - for width, allow_wrap in zip(widths, wrapable) - ] - if not any(ratios) or not column_difference: - break - max_reduce = [min(excess_width, column_difference)] * len(widths) - widths = ratio_reduce(excess_width, ratios, max_reduce, widths) - - total_width = sum(widths) - excess_width = total_width - max_width - return widths - - def _get_cells( - self, console: "Console", column_index: int, column: Column - ) -> Iterable[_Cell]: - """Get all the cells with padding and optional header.""" - - collapse_padding = self.collapse_padding - pad_edge = self.pad_edge - padding = self.padding - any_padding = any(padding) - - first_column = column_index == 0 - last_column = column_index == len(self.columns) - 1 - - _padding_cache: Dict[Tuple[bool, bool], Tuple[int, int, int, int]] = {} - - def get_padding(first_row: bool, last_row: bool) -> Tuple[int, int, int, int]: - cached = _padding_cache.get((first_row, last_row)) - if cached: - return cached - top, right, bottom, left = padding - - if collapse_padding: - if not first_column: - left = max(0, left - right) - if not last_row: - bottom = max(0, top - bottom) - - if not pad_edge: - if first_column: - left = 0 - if last_column: - right = 0 - if first_row: - top = 0 - if last_row: - bottom = 0 - _padding = (top, right, bottom, left) - _padding_cache[(first_row, last_row)] = _padding - return _padding - - raw_cells: List[Tuple[StyleType, "RenderableType"]] = [] - _append = raw_cells.append - get_style = console.get_style - if self.show_header: - header_style = get_style(self.header_style or "") + get_style( - column.header_style - ) - _append((header_style, column.header)) - cell_style = get_style(column.style or "") - for cell in column.cells: - _append((cell_style, cell)) - if self.show_footer: - footer_style = get_style(self.footer_style or "") + get_style( - column.footer_style - ) - _append((footer_style, column.footer)) - - if any_padding: - _Padding = Padding - for first, last, (style, renderable) in loop_first_last(raw_cells): - yield _Cell( - style, - _Padding(renderable, get_padding(first, last)), - getattr(renderable, "vertical", None) or column.vertical, - ) - else: - for style, renderable in raw_cells: - yield _Cell( - style, - renderable, - getattr(renderable, "vertical", None) or column.vertical, - ) - - def _get_padding_width(self, column_index: int) -> int: - """Get extra width from padding.""" - _, pad_right, _, pad_left = self.padding - if self.collapse_padding: - if column_index > 0: - pad_left = max(0, pad_left - pad_right) - return pad_left + pad_right - - def _measure_column( - self, - console: "Console", - options: "ConsoleOptions", - column: Column, - ) -> Measurement: - """Get the minimum and maximum width of the column.""" - - max_width = options.max_width - if max_width < 1: - return Measurement(0, 0) - - padding_width = self._get_padding_width(column._index) - - if column.width is not None: - # Fixed width column - return Measurement( - column.width + padding_width, column.width + padding_width - ).with_maximum(max_width) - # Flexible column, we need to measure contents - min_widths: List[int] = [] - max_widths: List[int] = [] - append_min = min_widths.append - append_max = max_widths.append - get_render_width = Measurement.get - for cell in self._get_cells(console, column._index, column): - _min, _max = get_render_width(console, options, cell.renderable) - append_min(_min) - append_max(_max) - - measurement = Measurement( - max(min_widths) if min_widths else 1, - max(max_widths) if max_widths else max_width, - ).with_maximum(max_width) - measurement = measurement.clamp( - None if column.min_width is None else column.min_width + padding_width, - None if column.max_width is None else column.max_width + padding_width, - ) - return measurement - - def _render( - self, console: "Console", options: "ConsoleOptions", widths: List[int] - ) -> "RenderResult": - table_style = console.get_style(self.style or "") - - border_style = table_style + console.get_style(self.border_style or "") - _column_cells = ( - self._get_cells(console, column_index, column) - for column_index, column in enumerate(self.columns) - ) - row_cells: List[Tuple[_Cell, ...]] = list(zip(*_column_cells)) - _box = ( - self.box.substitute( - options, safe=pick_bool(self.safe_box, console.safe_box) - ) - if self.box - else None - ) - _box = _box.get_plain_headed_box() if _box and not self.show_header else _box - - new_line = Segment.line() - - columns = self.columns - show_header = self.show_header - show_footer = self.show_footer - show_edge = self.show_edge - show_lines = self.show_lines - leading = self.leading - - _Segment = Segment - if _box: - box_segments = [ - ( - _Segment(_box.head_left, border_style), - _Segment(_box.head_right, border_style), - _Segment(_box.head_vertical, border_style), - ), - ( - _Segment(_box.foot_left, border_style), - _Segment(_box.foot_right, border_style), - _Segment(_box.foot_vertical, border_style), - ), - ( - _Segment(_box.mid_left, border_style), - _Segment(_box.mid_right, border_style), - _Segment(_box.mid_vertical, border_style), - ), - ] - if show_edge: - yield _Segment(_box.get_top(widths), border_style) - yield new_line - else: - box_segments = [] - - get_row_style = self.get_row_style - get_style = console.get_style - - for index, (first, last, row_cell) in enumerate(loop_first_last(row_cells)): - header_row = first and show_header - footer_row = last and show_footer - row = ( - self.rows[index - show_header] - if (not header_row and not footer_row) - else None - ) - max_height = 1 - cells: List[List[List[Segment]]] = [] - if header_row or footer_row: - row_style = Style.null() - else: - row_style = get_style( - get_row_style(console, index - 1 if show_header else index) - ) - for width, cell, column in zip(widths, row_cell, columns): - render_options = options.update( - width=width, - justify=column.justify, - no_wrap=column.no_wrap, - overflow=column.overflow, - height=None, - ) - lines = console.render_lines( - cell.renderable, - render_options, - style=get_style(cell.style) + row_style, - ) - max_height = max(max_height, len(lines)) - cells.append(lines) - - row_height = max(len(cell) for cell in cells) - - def align_cell( - cell: List[List[Segment]], - vertical: "VerticalAlignMethod", - width: int, - style: Style, - ) -> List[List[Segment]]: - if header_row: - vertical = "bottom" - elif footer_row: - vertical = "top" - - if vertical == "top": - return _Segment.align_top(cell, width, row_height, style) - elif vertical == "middle": - return _Segment.align_middle(cell, width, row_height, style) - return _Segment.align_bottom(cell, width, row_height, style) - - cells[:] = [ - _Segment.set_shape( - align_cell( - cell, - _cell.vertical, - width, - get_style(_cell.style) + row_style, - ), - width, - max_height, - ) - for width, _cell, cell, column in zip(widths, row_cell, cells, columns) - ] - - if _box: - if last and show_footer: - yield _Segment( - _box.get_row(widths, "foot", edge=show_edge), border_style - ) - yield new_line - left, right, _divider = box_segments[0 if first else (2 if last else 1)] - - # If the column divider is whitespace also style it with the row background - divider = ( - _divider - if _divider.text.strip() - else _Segment( - _divider.text, row_style.background_style + _divider.style - ) - ) - for line_no in range(max_height): - if show_edge: - yield left - for last_cell, rendered_cell in loop_last(cells): - yield from rendered_cell[line_no] - if not last_cell: - yield divider - if show_edge: - yield right - yield new_line - else: - for line_no in range(max_height): - for rendered_cell in cells: - yield from rendered_cell[line_no] - yield new_line - if _box and first and show_header: - yield _Segment( - _box.get_row(widths, "head", edge=show_edge), border_style - ) - yield new_line - end_section = row and row.end_section - if _box and (show_lines or leading or end_section): - if ( - not last - and not (show_footer and index >= len(row_cells) - 2) - and not (show_header and header_row) - ): - if leading: - yield _Segment( - _box.get_row(widths, "mid", edge=show_edge) * leading, - border_style, - ) - else: - yield _Segment( - _box.get_row(widths, "row", edge=show_edge), border_style - ) - yield new_line - - if _box and show_edge: - yield _Segment(_box.get_bottom(widths), border_style) - yield new_line - - -if __name__ == "__main__": # pragma: no cover - from rich.console import Console - from rich.highlighter import ReprHighlighter - from rich.table import Table as Table - - from ._timer import timer - - with timer("Table render"): - table = Table( - title="Star Wars Movies", - caption="Rich example table", - caption_justify="right", - ) - - table.add_column( - "Released", header_style="bright_cyan", style="cyan", no_wrap=True - ) - table.add_column("Title", style="magenta") - table.add_column("Box Office", justify="right", style="green") - - table.add_row( - "Dec 20, 2019", - "Star Wars: The Rise of Skywalker", - "$952,110,690", - ) - table.add_row("May 25, 2018", "Solo: A Star Wars Story", "$393,151,347") - table.add_row( - "Dec 15, 2017", - "Star Wars Ep. V111: The Last Jedi", - "$1,332,539,889", - style="on black", - end_section=True, - ) - table.add_row( - "Dec 16, 2016", - "Rogue One: A Star Wars Story", - "$1,332,439,889", - ) - - def header(text: str) -> None: - console.print() - console.rule(highlight(text)) - console.print() - - console = Console() - highlight = ReprHighlighter() - header("Example Table") - console.print(table, justify="center") - - table.expand = True - header("expand=True") - console.print(table) - - table.width = 50 - header("width=50") - - console.print(table, justify="center") - - table.width = None - table.expand = False - table.row_styles = ["dim", "none"] - header("row_styles=['dim', 'none']") - - console.print(table, justify="center") - - table.width = None - table.expand = False - table.row_styles = ["dim", "none"] - table.leading = 1 - header("leading=1, row_styles=['dim', 'none']") - console.print(table, justify="center") - - table.width = None - table.expand = False - table.row_styles = ["dim", "none"] - table.show_lines = True - table.leading = 0 - header("show_lines=True, row_styles=['dim', 'none']") - console.print(table, justify="center") -- cgit v1.2.3