Render a list of single-line strings as a compact set of columns. This method correctly handles strings containing ANSI style sequences and full-width characters (like those used in CJK languages). Each column is only as wide as necessary and columns are separated by two spa
(self, str_list: Sequence[str] | None, display_width: int = 80)
| 4422 | self.poutput() |
| 4423 | |
| 4424 | def render_columns(self, str_list: Sequence[str] | None, display_width: int = 80) -> str: |
| 4425 | """Render a list of single-line strings as a compact set of columns. |
| 4426 | |
| 4427 | This method correctly handles strings containing ANSI style sequences and |
| 4428 | full-width characters (like those used in CJK languages). Each column is |
| 4429 | only as wide as necessary and columns are separated by two spaces. |
| 4430 | |
| 4431 | :param str_list: Sequence of single-line strings to display |
| 4432 | :param display_width: max number of display columns to fit into |
| 4433 | :return: a string containing the columnized output |
| 4434 | """ |
| 4435 | if not str_list: |
| 4436 | return "" |
| 4437 | |
| 4438 | size = len(str_list) |
| 4439 | if size == 1: |
| 4440 | return str_list[0] |
| 4441 | |
| 4442 | rows: list[str] = [] |
| 4443 | |
| 4444 | # Try every row count from 1 upwards |
| 4445 | for nrows in range(1, len(str_list)): |
| 4446 | ncols = (size + nrows - 1) // nrows |
| 4447 | colwidths = [] |
| 4448 | totwidth = -2 |
| 4449 | for col in range(ncols): |
| 4450 | colwidth = 0 |
| 4451 | for row in range(nrows): |
| 4452 | i = row + nrows * col |
| 4453 | if i >= size: |
| 4454 | break |
| 4455 | x = str_list[i] |
| 4456 | colwidth = max(colwidth, su.str_width(x)) |
| 4457 | colwidths.append(colwidth) |
| 4458 | totwidth += colwidth + 2 |
| 4459 | if totwidth > display_width: |
| 4460 | break |
| 4461 | if totwidth <= display_width: |
| 4462 | break |
| 4463 | else: |
| 4464 | # The output is wider than display_width. Print 1 column with each string on its own row. |
| 4465 | nrows = len(str_list) |
| 4466 | ncols = 1 |
| 4467 | max_width = max(su.str_width(s) for s in str_list) |
| 4468 | colwidths = [max_width] |
| 4469 | for row in range(nrows): |
| 4470 | texts = [] |
| 4471 | for col in range(ncols): |
| 4472 | i = row + nrows * col |
| 4473 | x = "" if i >= size else str_list[i] |
| 4474 | texts.append(x) |
| 4475 | while texts and not texts[-1]: |
| 4476 | del texts[-1] |
| 4477 | for col in range(len(texts)): |
| 4478 | texts[col] = su.align_left(texts[col], width=colwidths[col]) |
| 4479 | rows.append(" ".join(texts)) |
| 4480 | |
| 4481 | return "\n".join(rows) |