GitHub Actions Workflow Status Publish Python Package to PyPI Code coverage Status
PyPi Package Version Supported Python versions PyPi status PyPi downloads
Code style: black mypy checked Linting: Ruff
While there are several libraries available for converting tables to strings in Python, none seemed to meet my specific requirements.
- Line Break Support: Easily include line breaks within cells for enhanced readability.
- Subtable Support: Easily include a table within a table for a more flexible presentation.
- Alignment: Easily align text in a cell in any direction.
- Emoji Integration: Effortlessly incorporate emoji characters into your tables to add visual appeal and context.
- [New!] ANSI Support: Use escape sequences for colors, decorations, and hyperlinks.
pip install -U table2string
pip install -U git+https://github.com/EgorKhabarov/table2string.git@master
>>> from table2string import Table, Themes, HorizontalAlignment, VerticalAlignment >>> Table([("1", "2", "3"), ("qwe", "rty\nuio", "")], name="Table Name", column_names=("c1", "c2", "c3")).print() +----------------+ | Table Name | +-----+-----+----+ | c1 | c2 | c3 | +-----+-----+----+ | 1 | 2 | 3 | +-----+-----+----+ | qwe | rty | | | | uio | | +-----+-----+----+ >>> from io import StringIO >>> Table.from_csv(StringIO('c1,c2,c3\n1,2,3\nqwe,"rty\nuio",'), name="Table Name").print() +----------------+ | Table Name | +-----+-----+----+ | c1 | c2 | c3 | +-----+-----+----+ | 1 | 2 | 3 | +-----+-----+----+ | qwe | rty | | | | uio | | +-----+-----+----+ >>> import sqlite3 >>> cursor = sqlite3.connect(":memory:").cursor().execute( ... "CREATE TABLE data (c1 TEXT, c2 TEXT, c3 TEXT);" ... ).executemany( ... "INSERT INTO data (c1, c2, c3) VALUES (?, ?, ?);", ... [("1", "2", "3"), ("qwe", "rty\nuio", "")], ... ).execute( ... "SELECT c1, c2, c3 FROM data;" ... ) >>> Table.from_db_cursor( ... cursor, ... name="Table Name", ... column_names=True, ... ).print() +----------------+ | Table Name | +-----+-----+----+ | c1 | c2 | c3 | +-----+-----+----+ | 1 | 2 | 3 | +-----+-----+----+ | qwe | rty | | | | uio | | +-----+-----+----+ >>> Table( ... [("c1", Table([("1", "2"), ("3", "4")], name="SubTable"))], ... name="Table Name", ... ).print(v_align=("-",), max_width=(2, 8)) +---------------+ | Table Name | +----+----------+ | | SubTable | | +-----+----+ | c1 | 1 | 2 | | +-----+----+ | | 3 | 4 | +----+-----+----+
| Argument | Type | Example | Description |
|---|---|---|---|
table |
Sequence[Sequence[Any]] |
[("1", "2"), ("3", "4")] |
A two-dimensional matrix |
h_align |
tuple[HorizontalAlignment | str, ...] | HorizontalAlignment | str |
HorizontalAlignment.CENTER |
Allows you to align text in a cell horizontally |
v_align |
tuple[VerticalAlignment | str, ...] | VerticalAlignment | str |
VerticalAlignment.MIDDLE |
Allows you to align text in a cell vertically |
text_splitter |
BaseTextSplitter | tuple[BaseTextSplitter, ...] |
AnsiTextSplitter() |
Allows you to customize text formatting, for example ANSI |
name |
str | None |
"Table Name" |
Table name |
name_h_align |
HorizontalAlignment | str |
HorizontalAlignment.CENTER |
Allows you to align table name horizontally |
name_v_align |
VerticalAlignment | str |
VerticalAlignment.MIDDLE |
Allows you to align table name vertically |
name_splitter |
BaseTextSplitter |
AnsiTextSplitter() |
Allows you to customize name formatting, for example ANSI |
column_names |
Sequence[str] | None |
("c1", "c2", ...column_count) |
Sets the names for the table columns |
column_names_h_align |
tuple[HorizontalAlignment | str, ...] | HorizontalAlignment | str |
HorizontalAlignment.CENTER |
Allows you to align column names horizontally |
column_names_v_align |
tuple[VerticalAlignment | str, ...] | VerticalAlignment | str |
VerticalAlignment.MIDDLE |
Allows you to align column names vertically |
column_names_splitter |
BaseTextSplitter | tuple[BaseTextSplitter, ...] |
AnsiTextSplitter() |
Allows you to customize column names formatting, for example ANSI |
max_width |
int | Tuple[int, ...] | None |
120 |
Allows you to set the width of the entire table or individually for each column |
max_height |
int | None |
10 |
Specifies the maximum height for rows |
maximize_height |
bool |
True |
Force height to be taken from max_height |
line_break_symbol |
str |
"\\" |
Line break symbol |
cell_break_symbol |
str |
"..." |
Symbol indicating the end of text when there is not enough height |
sep |
bool | range | tuple |
(1, 3, 6) |
Handles the separators between table rows and can be either a boolean type or possess a __contains__ method |
end |
str | None |
"\n" |
Behaves the same as print(end=) |
file |
TextIOWrapper | None |
sys.stdout or io.StringIO() |
Behaves the same as print(file=) |
theme |
Theme |
Themes.rounded_thick |
Allows you to set a specific theme for the table. For example, the border style |
ignore_width_errors |
bool |
False |
Fixes errors in max_width if they exist |
proportion_coefficient |
float |
0.5 |
Affects the width distribution of the columns. A value of 0.0 corresponds to proportional distribution, 1.0 averages the values, and 2.0 inverts them |
| Align | Example | Description |
|---|---|---|
"<align>" or ("<align>",) |
"^" or ("^",) |
Setting align ("^") for all columns |
("<align_1>", "<align_2>") |
("^", "<") |
Setting align_1 ("^") for the first column and align_2 ("<") for all other columns |
("<align_1>", "<align_2>", "<align_3>") |
("^", "<", ">") |
Setting align_1 ("^") for the first column and align_2 ("<") for the second and align_3 (">") for the third column |
You can also use the corresponding HorizontalAlignment or VerticalAlignment type
For name_h_align and name_v_align only the str type or the corresponding HorizontalAlignment or VerticalAlignment type is valid
| Align | Description |
|---|---|
AUTO or AUTO_AUTO or * or ** |
Alignment depends on the type. If this is a number and there are no line breaks in this cell, then align to the right; otherwise, align to the left. |
LEFT or LEFT_LEFT or < or << |
All lines are left aligned |
CENTER or CENTER_CENTER or ^ or ^^ |
All lines are center aligned |
RIGHT or RIGHT_RIGHT or > or >> |
All lines are right aligned |
LEFT_CENTER or <^ |
The first line is left aligned and the remaining lines are centered |
LEFT_RIGHT or <> |
The first line is left aligned and the remaining lines are right aligned |
CENTER_LEFT or ^< |
The first line is aligned to the center, and the remaining lines are aligned to the left of the first line. |
CENTER_RIGHT or ^> |
The first line is aligned to the center, and the remaining lines are aligned to the right of the first line. |
RIGHT_LEFT or >< |
The first line is right aligned and the remaining lines are left aligned |
RIGHT_CENTER or >^ |
The first line is right aligned and the remaining lines are centered |
| Align | Description |
|---|---|
TOP or ^ |
Text are top aligned |
MIDDLE or - |
Text are centered |
BOTTOM or _ |
Text are bottom aligned |
Example
>>> from functools import partial >>> sub_table_auto_func = partial(Table, [("123", "text",)], max_height=4, maximize_height=True) >>> sub_table_func = partial(Table, [("first line\ntext",)], max_height=4, maximize_height=True) >>> Table( ... [ ... *( ... [v_align, sub_table_auto_func(h_align="*", v_align=v_align)] + [ ... sub_table_func(h_align=h_align, v_align=v_align) ... for h_align in ("<", ">", "^", "^<", "^>") ... ] ... for v_align in ("^", "-", "_") ... ) ... ], ... column_names=(" ", "*", "<", ">", "^", "^<", "^>"), ... ).print(max_width=(1, len("first line")+4), v_align=("-",)) +---+----------------+----------------+----------------+----------------+----------------+----------------+ | | * | < | > | ^ | ^< | ^> | +---+-------+--------+----------------+----------------+----------------+----------------+----------------+ | | 123 | text | first line | first line | first line | first line | first line | | ^ | | | text | text | text | text | text | | | | | | | | | | | | | | | | | | | +---+-------+--------+----------------+----------------+----------------+----------------+----------------+ | | | | | | | | | | - | 123 | text | first line | first line | first line | first line | first line | | | | | text | text | text | text | text | | | | | | | | | | +---+-------+--------+----------------+----------------+----------------+----------------+----------------+ | | | | | | | | | | _ | | | | | | | | | | | | first line | first line | first line | first line | first line | | | 123 | text | text | text | text | text | text | +---+-------+--------+----------------+----------------+----------------+----------------+----------------+
| Width | Example | Description |
|---|---|---|
<width> |
10 |
Setting width (10) for the whole table |
(<width>,) |
(10,) |
Setting width_1 (10) for all column |
(<width_1>, <width_2>) |
(10, 20) |
Setting width_1 (10) for the first column and width_2 (20) for all other columns |
(<width_1>, <width_2>, <width_3>) |
(10, 20, 30) |
Setting width_1 (10) for the first column and width_2 (20) for the second and width_3 (30) for the third column |
Example
>>> # Width of the entire table with borders >>> Table([(1, 12345, "example")]).print(max_width=30) +-----+----------+-----------+ | 1 | 12345 | example | +-----+----------+-----------+ >>> # Width of each column individually >>> Table([(1, 12345, "example")]).print(max_width=(10,)) +------------+------------+------------+ | 1 | 12345 | example | +------------+------------+------------+ >>> Table([(1, 12345, "example")]).print(max_width=(1, 8, 6)) +---+----------+--------+ | 1 | 12345 | exampl/| | | | e | +---+----------+--------+ >>> Table([(1, 12345, "example")]).print(max_width=(1, 5, 7)) +---+-------+---------+ | 1 | 12345 | example | +---+-------+---------+ >>> Table([("123456\n\n789000", "example")]).print(max_width=(3, 4), max_height=4) +-----+------+ | 123/| exam/| | 456 | ple | | | | | 789...| | +-----+------+ >>> Table([("123456789",)]).print(max_width=(1,), max_height=1) +---+ | 1...| +---+ >>> Table([("123\n456\n789",)]).print( ... max_width=(3,), ... max_height=4, ... maximize_height=True, ... ) +-----+ | 123 | | 456 | | 789 | | | +-----+ >>> Table([("123456789",)]).print( ... max_width=(3,), ... max_height=4, ... maximize_height=True, ... ) +-----+ | 123/| | 456/| | 789 | | | +-----+
| Separator | Description |
|---|---|
sep=True |
All horizontal dividers included |
sep=False |
All horizontal dividers are disabled |
sep=(1,) |
Only first delimiter |
sep=(1, 3, 5) |
Only first third and fifth separator |
sep=range(1, 100, 5) |
Delimiter every five lines first 100 lines |
Example
>>> table_1 = Table([("qwe", "rty\nuio"), ("123456\n\n789000", "example")]) >>> kwargs = { ... "max_width": (3, 4), ... "max_height": 4, ... } >>> table_1.print(**kwargs, sep=True) +-----+------+ | qwe | rty | | | uio | +-----+------+ | 123/| exam/| | 456 | ple | | | | | 789...| | +-----+------+ >>> table_1.print(**kwargs, sep=False) +-----+------+ | qwe | rty | | | uio | | 123/| exam/| | 456 | ple | | | | | 789...| | +-----+------+ >>> table_2 = Table([("1", "2"), ("3", "4")], name="Name") >>> table_2.print(sep=True) +-------+ | Name | +---+---+ | 1 | 2 | +---+---+ | 3 | 4 | +---+---+ >>> table_2.print(sep=False) +-------+ | Name | +---+---+ | 1 | 2 | | 3 | 4 | +---+---+ >>> table_3 = Table([("1", "2"), ("3", "4"), ("5", "6"), ("7", "8")]) >>> table_3.print(sep=(1,)) +---+---+ | 1 | 2 | +---+---+ | 3 | 4 | | 5 | 6 | | 7 | 8 | +---+---+ >>> table_3.print(sep=(2,)) +---+---+ | 1 | 2 | | 3 | 4 | +---+---+ | 5 | 6 | | 7 | 8 | +---+---+ >>> table_3.print(sep=(1, 3)) +---+---+ | 1 | 2 | +---+---+ | 3 | 4 | | 5 | 6 | +---+---+ | 7 | 8 | +---+---+ >>> table_4 = Table([("1", "2"), ("3", "4"), ("5", "6"), ("7", "8")], name="Name") >>> table_4.print(sep=(1,)) +-------+ | Name | +---+---+ | 1 | 2 | +---+---+ | 3 | 4 | | 5 | 6 | | 7 | 8 | +---+---+ >>> table_4.print(sep=(2,)) +-------+ | Name | +---+---+ | 1 | 2 | | 3 | 4 | +---+---+ | 5 | 6 | | 7 | 8 | +---+---+ >>> table_4.print(sep=(1, 3)) +-------+ | Name | +---+---+ | 1 | 2 | +---+---+ | 3 | 4 | | 5 | 6 | +---+---+ | 7 | 8 | +---+---+
A variety of table border styles are available through the Themes interface:
Themes.ascii_thinThemes.ascii_thin_doubleThemes.ascii_doubleThemes.ascii_double_thinThemes.thinThemes.thin_thickThemes.thin_doubleThemes.rounded_doubleThemes.roundedThemes.rounded_thickThemes.thickThemes.thick_thinThemes.doubleThemes.double_thinThemes.booktabsThemes.ascii_booktabsThemes.markdown
Expandable previews below this section illustrate the visual appearance of each border theme.
Border types
>>> from table2string import Themes, HorizontalAlignment >>> table = [] >>> example_table = Table([(" ", " "), (" ", " "), (" ", " ")]) >>> theme_names = ( ... ("ascii_thin", "ascii_thin_double"), ... ("ascii_double", "ascii_double_thin"), ... ("thin", "thin_thick"), ... ("thin_double", "rounded_double"), ... ("rounded", "rounded_thick"), ... ("thick", "thick_thin"), ... ("double", "double_thin"), ... ("booktabs", "ascii_booktabs"), ... ("markdown", "None"), ... ) >>> for names in theme_names: ... table.append([]) ... for name in names: ... string_table = example_table.stringify( ... theme=getattr(Themes, name, Themes.ascii_thin) ... ) ... table[-1].append(f"{name}\n{string_table}") >>> Table(table).print(theme=Themes.thin, h_align=HorizontalAlignment.CENTER) โโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโ โ ascii_thin โ ascii_thin_double โ โ +---+---+ โ +---+---+ โ โ | | | โ | | | โ โ +---+---+ โ +===+===+ โ โ | | | โ | | | โ โ +---+---+ โ +---+---+ โ โ | | | โ | | | โ โ +---+---+ โ +---+---+ โ โโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโค โ ascii_double โ ascii_double_thin โ โ +===+===+ โ +===+===+ โ โ โ โ โ โ โ โ โ โ โ +===+===+ โ +---+---+ โ โ โ โ โ โ โ โ โ โ โ +===+===+ โ +===+===+ โ โ โ โ โ โ โ โ โ โ โ +===+===+ โ +===+===+ โ โโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโค โ thin โ thin_thick โ โ โโโโโฌโโโโ โ โโโโโฌโโโโ โ โ โ โ โ โ โ โ โ โ โ โโโโโผโโโโค โ โโโโโฟโโโโฅ โ โ โ โ โ โ โ โ โ โ โ โโโโโผโโโโค โ โโโโโผโโโโค โ โ โ โ โ โ โ โ โ โ โ โโโโโดโโโโ โ โโโโโดโโโโ โ โโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโค โ thin_double โ rounded_double โ โ โโโโโฌโโโโ โ โญโโโโฌโโโโฎ โ โ โ โ โ โ โ โ โ โ โ โโโโโชโโโโก โ โโโโโชโโโโก โ โ โ โ โ โ โ โ โ โ โ โโโโโผโโโโค โ โโโโโผโโโโค โ โ โ โ โ โ โ โ โ โ โ โโโโโดโโโโ โ โฐโโโโดโโโโฏ โ โโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโค โ rounded โ rounded_thick โ โ โญโโโโฌโโโโฎ โ โญโโโโฌโโโโฎ โ โ โ โ โ โ โ โ โ โ โ โโโโโผโโโโค โ โโโโโฟโโโโฅ โ โ โ โ โ โ โ โ โ โ โ โโโโโผโโโโค โ โโโโโผโโโโค โ โ โ โ โ โ โ โ โ โ โ โฐโโโโดโโโโฏ โ โฐโโโโดโโโโฏ โ โโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโค โ thick โ thick_thin โ โ โโโโโณโโโโ โ โโโโโณโโโโ โ โ โ โ โ โ โ โ โ โ โ โฃโโโโโโโโซ โ โ โโโโโโโโจ โ โ โ โ โ โ โ โ โ โ โ โฃโโโโโโโโซ โ โฃโโโโโโโโซ โ โ โ โ โ โ โ โ โ โ โ โโโโโปโโโโ โ โโโโโปโโโโ โ โโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโค โ double โ double_thin โ โ โโโโโฆโโโโ โ โโโโโฆโโโโ โ โ โ โ โ โ โ โ โ โ โ โ โโโโฌโโโโฃ โ โโโโโซโโโโข โ โ โ โ โ โ โ โ โ โ โ โ โโโโฌโโโโฃ โ โ โโโโฌโโโโฃ โ โ โ โ โ โ โ โ โ โ โ โโโโโฉโโโโ โ โโโโโฉโโโโ โ โโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโค โ booktabs โ ascii_booktabs โ โ โโโโโโโ โ ------- โ โ โ โ โ โโโโโโโ โ ======= โ โ โ โ โ โโโโโโโ โ ------- โ โ โ โ โ โโโโโโโ โ ------- โ โโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโค โ markdown โ None โ โ | | | โ +---+---+ โ โ |---|---| โ | | | โ โ | | | โ +---+---+ โ โ | | | โ | | | โ โ โ +---+---+ โ โ โ | | | โ โ โ +---+---+ โ โโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโ
Example
>>> from table2string import Table, Themes >>> name = "Table Name" >>> column_names = ("c1", "c2", "3") >>> table = [("1", "2", "3"), ("qwe", "rty\nuio", "")] >>> t = Table(table) >>> t_name = Table(table, name=name) >>> t_column_names = Table(table, column_names=column_names) >>> t_name_column_names = Table(table, name=name, column_names=column_names)
Themes.ascii_thin
>>> t.print(theme=Themes.ascii_thin) +-----+-----+---+ | 1 | 2 | 3 | +-----+-----+---+ | qwe | rty | | | | uio | | +-----+-----+---+ >>> t_column_names.print(theme=Themes.ascii_thin) +-----+-----+---+ | c1 | c2 | 3 | +-----+-----+---+ | 1 | 2 | 3 | +-----+-----+---+ | qwe | rty | | | | uio | | +-----+-----+---+ >>> t_name.print(theme=Themes.ascii_thin) +---------------+ | Table Name | +-----+-----+---+ | 1 | 2 | 3 | +-----+-----+---+ | qwe | rty | | | | uio | | +-----+-----+---+ >>> t_name_column_names.print(theme=Themes.ascii_thin) +---------------+ | Table Name | +-----+-----+---+ | c1 | c2 | 3 | +-----+-----+---+ | 1 | 2 | 3 | +-----+-----+---+ | qwe | rty | | | | uio | | +-----+-----+---+
Themes.ascii_thin_double
>>> t.print(theme=Themes.ascii_thin_double) +-----+-----+---+ | 1 | 2 | 3 | +=====+=====+===+ | qwe | rty | | | | uio | | +-----+-----+---+ >>> t_column_names.print(theme=Themes.ascii_thin_double) +-----+-----+---+ | c1 | c2 | 3 | +=====+=====+===+ | 1 | 2 | 3 | +-----+-----+---+ | qwe | rty | | | | uio | | +-----+-----+---+ >>> t_name.print(theme=Themes.ascii_thin_double) +---------------+ | Table Name | +-----+-----+---+ | 1 | 2 | 3 | +=====+=====+===+ | qwe | rty | | | | uio | | +-----+-----+---+ >>> t_name_column_names.print(theme=Themes.ascii_thin_double) +---------------+ | Table Name | +-----+-----+---+ | c1 | c2 | 3 | +=====+=====+===+ | 1 | 2 | 3 | +-----+-----+---+ | qwe | rty | | | | uio | | +-----+-----+---+
Themes.ascii_double
>>> t.print(theme=Themes.ascii_double) +=====+=====+===+ โ 1 โ 2 โ 3 โ +=====+=====+===+ โ qwe โ rty โ โ โ โ uio โ โ +=====+=====+===+ >>> t_column_names.print(theme=Themes.ascii_double) +=====+=====+===+ โ c1 โ c2 โ 3 โ +=====+=====+===+ โ 1 โ 2 โ 3 โ +=====+=====+===+ โ qwe โ rty โ โ โ โ uio โ โ +=====+=====+===+ >>> t_name.print(theme=Themes.ascii_double) +===============+ โ Table Name โ +=====+=====+===+ โ 1 โ 2 โ 3 โ +=====+=====+===+ โ qwe โ rty โ โ โ โ uio โ โ +=====+=====+===+ >>> t_name_column_names.print(theme=Themes.ascii_double) +===============+ โ Table Name โ +=====+=====+===+ โ c1 โ c2 โ 3 โ +=====+=====+===+ โ 1 โ 2 โ 3 โ +=====+=====+===+ โ qwe โ rty โ โ โ โ uio โ โ +=====+=====+===+
Themes.ascii_double_thin
>>> t.print(theme=Themes.ascii_double_thin) +=====+=====+===+ โ 1 โ 2 โ 3 โ +-----+-----+---+ โ qwe โ rty โ โ โ โ uio โ โ +=====+=====+===+ >>> t_column_names.print(theme=Themes.ascii_double_thin) +=====+=====+===+ โ c1 โ c2 โ 3 โ +-----+-----+---+ โ 1 โ 2 โ 3 โ +=====+=====+===+ โ qwe โ rty โ โ โ โ uio โ โ +=====+=====+===+ >>> t_name.print(theme=Themes.ascii_double_thin) +===============+ โ Table Name โ +=====+=====+===+ โ 1 โ 2 โ 3 โ +-----+-----+---+ โ qwe โ rty โ โ โ โ uio โ โ +=====+=====+===+ >>> t_name_column_names.print(theme=Themes.ascii_double_thin) +===============+ โ Table Name โ +=====+=====+===+ โ c1 โ c2 โ 3 โ +-----+-----+---+ โ 1 โ 2 โ 3 โ +=====+=====+===+ โ qwe โ rty โ โ โ โ uio โ โ +=====+=====+===+
Themes.ascii_booktabs
>>> t.print(theme=Themes.ascii_booktabs) --------------- 1 2 3 =============== qwe rty uio --------------- >>> t_column_names.print(theme=Themes.ascii_booktabs) --------------- c1 c2 3 =ใ=ใ=ใ=ใ=ใ=ใ=ใ=ใ=ใ=ใ=ใ=ใ=ใ=ใ=ใ 1 2 3 --------------- qwe rty uio --------------- >>> t_name.print(theme=Themes.ascii_booktabs) --------------- Table Name --------------- 1 2 3 =============== qwe rty uio --------------- >>> t_name_column_names.print(theme=Themes.ascii_booktabs) --------------- Table Name --------------- c1 c2 3 =ใ=ใ=ใ=ใ=ใ=ใ=ใ=ใ=ใ=ใ=ใ=ใ=ใ=ใ=ใ 1 2 3 --------------- qwe rty uio ---------------
Themes.thin
>>> t.print(theme=Themes.thin) โโโโโโโฌโโโโโโฌโโโโ โ 1 โ 2 โ 3 โ โโโโโโโผโโโโโโผโโโโค โ qwe โ rty โ โ โ โ uio โ โ โโโโโโโดโโโโโโดโโโโ >>> t_column_names.print(theme=Themes.thin) โโโโโโโฌโโโโโโฌโโโโ โ c1 โ c2 โ 3 โ โโโโโโโผโโโโโโผโโโโค โ 1 โ 2 โ 3 โ โโโโโโโผโโโโโโผโโโโค โ qwe โ rty โ โ โ โ uio โ โ โโโโโโโดโโโโโโดโโโโ >>> t_name.print(theme=Themes.thin) โโโโโโโโโโโโโโโโโ โ Table Name โ โโโโโโโฌโโโโโโฌโโโโค โ 1 โ 2 โ 3 โ โโโโโโโผโโโโโโผโโโโค โ qwe โ rty โ โ โ โ uio โ โ โโโโโโโดโโโโโโดโโโโ >>> t_name_column_names.print(theme=Themes.thin) โโโโโโโโโโโโโโโโโ โ Table Name โ โโโโโโโฌโโโโโโฌโโโโค โ c1 โ c2 โ 3 โ โโโโโโโผโโโโโโผโโโโค โ 1 โ 2 โ 3 โ โโโโโโโผโโโโโโผโโโโค โ qwe โ rty โ โ โ โ uio โ โ โโโโโโโดโโโโโโดโโโโ
Themes.thin_thick
>>> t.print(theme=Themes.thin_thick) โโโโโโโฌโโโโโโฌโโโโ โ 1 โ 2 โ 3 โ โโโโโโโฟโโโโโโฟโโโโฅ โ qwe โ rty โ โ โ โ uio โ โ โโโโโโโดโโโโโโดโโโโ >>> t_column_names.print(theme=Themes.thin_thick) โโโโโโโฌโโโโโโฌโโโโ โ c1 โ c2 โ 3 โ โโโโโโโฟโโโโโโฟโโโโฅ โ 1 โ 2 โ 3 โ โโโโโโโผโโโโโโผโโโโค โ qwe โ rty โ โ โ โ uio โ โ โโโโโโโดโโโโโโดโโโโ >>> t_name.print(theme=Themes.thin_thick) โโโโโโโโโโโโโโโโโ โ Table Name โ โโโโโโโฌโโโโโโฌโโโโค โ 1 โ 2 โ 3 โ โโโโโโโฟโโโโโโฟโโโโฅ โ qwe โ rty โ โ โ โ uio โ โ โโโโโโโดโโโโโโดโโโโ >>> t_name_column_names.print(theme=Themes.thin_thick) โโโโโโโโโโโโโโโโโ โ Table Name โ โโโโโโโฌโโโโโโฌโโโโค โ c1 โ c2 โ 3 โ โโโโโโโฟโโโโโโฟโโโโฅ โ 1 โ 2 โ 3 โ โโโโโโโผโโโโโโผโโโโค โ qwe โ rty โ โ โ โ uio โ โ โโโโโโโดโโโโโโดโโโโ
Themes.thin_double
>>> t.print(theme=Themes.thin_double) โโโโโโโฌโโโโโโฌโโโโ โ 1 โ 2 โ 3 โ โโโโโโโชโโโโโโชโโโโก โ qwe โ rty โ โ โ โ uio โ โ โโโโโโโดโโโโโโดโโโโ >>> t_column_names.print(theme=Themes.thin_double) โโโโโโโฌโโโโโโฌโโโโ โ c1 โ c2 โ 3 โ โโโโโโโชโโโโโโชโโโโก โ 1 โ 2 โ 3 โ โโโโโโโผโโโโโโผโโโโค โ qwe โ rty โ โ โ โ uio โ โ โโโโโโโดโโโโโโดโโโโ >>> t_name.print(theme=Themes.thin_double) โโโโโโโโโโโโโโโโโ โ Table Name โ โโโโโโโฌโโโโโโฌโโโโค โ 1 โ 2 โ 3 โ โโโโโโโชโโโโโโชโโโโก โ qwe โ rty โ โ โ โ uio โ โ โโโโโโโดโโโโโโดโโโโ >>> t_name_column_names.print(theme=Themes.thin_double) โโโโโโโโโโโโโโโโโ โ Table Name โ โโโโโโโฌโโโโโโฌโโโโค โ c1 โ c2 โ 3 โ โโโโโโโชโโโโโโชโโโโก โ 1 โ 2 โ 3 โ โโโโโโโผโโโโโโผโโโโค โ qwe โ rty โ โ โ โ uio โ โ โโโโโโโดโโโโโโดโโโโ
Themes.rounded
>>> t.print(theme=Themes.rounded) โญโโโโโโฌโโโโโโฌโโโโฎ โ 1 โ 2 โ 3 โ โโโโโโโผโโโโโโผโโโโค โ qwe โ rty โ โ โ โ uio โ โ โฐโโโโโโดโโโโโโดโโโโฏ >>> t_column_names.print(theme=Themes.rounded) โญโโโโโโฌโโโโโโฌโโโโฎ โ c1 โ c2 โ 3 โ โโโโโโโผโโโโโโผโโโโค โ 1 โ 2 โ 3 โ โโโโโโโผโโโโโโผโโโโค โ qwe โ rty โ โ โ โ uio โ โ โฐโโโโโโดโโโโโโดโโโโฏ >>> t_name.print(theme=Themes.rounded) โญโโโโโโโโโโโโโโโโฎ โ Table Name โ โโโโโโโฌโโโโโโฌโโโโค โ 1 โ 2 โ 3 โ โโโโโโโผโโโโโโผโโโโค โ qwe โ rty โ โ โ โ uio โ โ โฐโโโโโโดโโโโโโดโโโโฏ >>> t_name_column_names.print(theme=Themes.rounded) โญโโโโโโโโโโโโโโโโฎ โ Table Name โ โโโโโโโฌโโโโโโฌโโโโค โ c1 โ c2 โ 3 โ โโโโโโโผโโโโโโผโโโโค โ 1 โ 2 โ 3 โ โโโโโโโผโโโโโโผโโโโค โ qwe โ rty โ โ โ โ uio โ โ โฐโโโโโโดโโโโโโดโโโโฏ
Themes.rounded_thick
>>> t.print(theme=Themes.rounded_thick) โญโโโโโโฌโโโโโโฌโโโโฎ โ 1 โ 2 โ 3 โ โโโโโโโฟโโโโโโฟโโโโฅ โ qwe โ rty โ โ โ โ uio โ โ โฐโโโโโโดโโโโโโดโโโโฏ >>> t_column_names.print(theme=Themes.rounded_thick) โญโโโโโโฌโโโโโโฌโโโโฎ โ c1 โ c2 โ 3 โ โโโโโโโฟโโโโโโฟโโโโฅ โ 1 โ 2 โ 3 โ โโโโโโโผโโโโโโผโโโโค โ qwe โ rty โ โ โ โ uio โ โ โฐโโโโโโดโโโโโโดโโโโฏ >>> t_name.print(theme=Themes.rounded_thick) โญโโโโโโโโโโโโโโโโฎ โ Table Name โ โโโโโโโฌโโโโโโฌโโโโค โ 1 โ 2 โ 3 โ โโโโโโโฟโโโโโโฟโโโโฅ โ qwe โ rty โ โ โ โ uio โ โ โฐโโโโโโดโโโโโโดโโโโฏ >>> t_name_column_names.print(theme=Themes.rounded_thick) โญโโโโโโโโโโโโโโโโฎ โ Table Name โ โโโโโโโฌโโโโโโฌโโโโค โ c1 โ c2 โ 3 โ โโโโโโโฟโโโโโโฟโโโโฅ โ 1 โ 2 โ 3 โ โโโโโโโผโโโโโโผโโโโค โ qwe โ rty โ โ โ โ uio โ โ โฐโโโโโโดโโโโโโดโโโโฏ
Themes.rounded_double
>>> t.print(theme=Themes.rounded_double) โญโโโโโโฌโโโโโโฌโโโโฎ โ 1 โ 2 โ 3 โ โโโโโโโชโโโโโโชโโโโก โ qwe โ rty โ โ โ โ uio โ โ โฐโโโโโโดโโโโโโดโโโโฏ >>> t_column_names.print(theme=Themes.rounded_double) โญโโโโโโฌโโโโโโฌโโโโฎ โ c1 โ c2 โ 3 โ โโโโโโโชโโโโโโชโโโโก โ 1 โ 2 โ 3 โ โโโโโโโผโโโโโโผโโโโค โ qwe โ rty โ โ โ โ uio โ โ โฐโโโโโโดโโโโโโดโโโโฏ >>> t_name.print(theme=Themes.rounded_double) โญโโโโโโโโโโโโโโโโฎ โ Table Name โ โโโโโโโฌโโโโโโฌโโโโค โ 1 โ 2 โ 3 โ โโโโโโโชโโโโโโชโโโโก โ qwe โ rty โ โ โ โ uio โ โ โฐโโโโโโดโโโโโโดโโโโฏ >>> t_name_column_names.print(theme=Themes.rounded_double) โญโโโโโโโโโโโโโโโโฎ โ Table Name โ โโโโโโโฌโโโโโโฌโโโโค โ c1 โ c2 โ 3 โ โโโโโโโชโโโโโโชโโโโก โ 1 โ 2 โ 3 โ โโโโโโโผโโโโโโผโโโโค โ qwe โ rty โ โ โ โ uio โ โ โฐโโโโโโดโโโโโโดโโโโฏ
Themes.thick
>>> t.print(theme=Themes.thick) โโโโโโโณโโโโโโณโโโโ โ 1 โ 2 โ 3 โ โฃโโโโโโโโโโโโโโโโซ โ qwe โ rty โ โ โ โ uio โ โ โโโโโโโปโโโโโโปโโโโ >>> t_column_names.print(theme=Themes.thick) โโโโโโโณโโโโโโณโโโโ โ c1 โ c2 โ 3 โ โฃโโโโโโโโโโโโโโโโซ โ 1 โ 2 โ 3 โ โฃโโโโโโโโโโโโโโโโซ โ qwe โ rty โ โ โ โ uio โ โ โโโโโโโปโโโโโโปโโโโ >>> t_name.print(theme=Themes.thick) โโโโโโโโโโโโโโโโโ โ Table Name โ โฃโโโโโโณโโโโโโณโโโโซ โ 1 โ 2 โ 3 โ โฃโโโโโโโโโโโโโโโโซ โ qwe โ rty โ โ โ โ uio โ โ โโโโโโโปโโโโโโปโโโโ >>> t_name_column_names.print(theme=Themes.thick) โโโโโโโโโโโโโโโโโ โ Table Name โ โฃโโโโโโณโโโโโโณโโโโซ โ c1 โ c2 โ 3 โ โฃโโโโโโโโโโโโโโโโซ โ 1 โ 2 โ 3 โ โฃโโโโโโโโโโโโโโโโซ โ qwe โ rty โ โ โ โ uio โ โ โโโโโโโปโโโโโโปโโโโ
Themes.thick_thin
>>> t.print(theme=Themes.thick_thin) โโโโโโโณโโโโโโณโโโโ โ 1 โ 2 โ 3 โ โ โโโโโโโโโโโโโโโโจ โ qwe โ rty โ โ โ โ uio โ โ โโโโโโโปโโโโโโปโโโโ >>> t_column_names.print(theme=Themes.thick_thin) โโโโโโโณโโโโโโณโโโโ โ c1 โ c2 โ 3 โ โ โโโโโโโโโโโโโโโโจ โ 1 โ 2 โ 3 โ โฃโโโโโโโโโโโโโโโโซ โ qwe โ rty โ โ โ โ uio โ โ โโโโโโโปโโโโโโปโโโโ >>> t_name.print(theme=Themes.thick_thin) โโโโโโโโโโโโโโโโโ โ Table Name โ โฃโโโโโโณโโโโโโณโโโโซ โ 1 โ 2 โ 3 โ โ โโโโโโโโโโโโโโโโจ โ qwe โ rty โ โ โ โ uio โ โ โโโโโโโปโโโโโโปโโโโ >>> t_name_column_names.print(theme=Themes.thick_thin) โโโโโโโโโโโโโโโโโ โ Table Name โ โฃโโโโโโณโโโโโโณโโโโซ โ c1 โ c2 โ 3 โ โ โโโโโโโโโโโโโโโโจ โ 1 โ 2 โ 3 โ โฃโโโโโโโโโโโโโโโโซ โ qwe โ rty โ โ โ โ uio โ โ โโโโโโโปโโโโโโปโโโโ
Themes.double
>>> t.print(theme=Themes.double) โโโโโโโฆโโโโโโฆโโโโ โ 1 โ 2 โ 3 โ โ โโโโโโฌโโโโโโฌโโโโฃ โ qwe โ rty โ โ โ โ uio โ โ โโโโโโโฉโโโโโโฉโโโโ >>> t_column_names.print(theme=Themes.double) โโโโโโโฆโโโโโโฆโโโโ โ c1 โ c2 โ 3 โ โ โโโโโโฌโโโโโโฌโโโโฃ โ 1 โ 2 โ 3 โ โ โโโโโโฌโโโโโโฌโโโโฃ โ qwe โ rty โ โ โ โ uio โ โ โโโโโโโฉโโโโโโฉโโโโ >>> t_name.print(theme=Themes.double) โโโโโโโโโโโโโโโโโ โ Table Name โ โ โโโโโโฆโโโโโโฆโโโโฃ โ 1 โ 2 โ 3 โ โ โโโโโโฌโโโโโโฌโโโโฃ โ qwe โ rty โ โ โ โ uio โ โ โโโโโโโฉโโโโโโฉโโโโ >>> t_name_column_names.print(theme=Themes.double) โโโโโโโโโโโโโโโโโ โ Table Name โ โ โโโโโโฆโโโโโโฆโโโโฃ โ c1 โ c2 โ 3 โ โ โโโโโโฌโโโโโโฌโโโโฃ โ 1 โ 2 โ 3 โ โ โโโโโโฌโโโโโโฌโโโโฃ โ qwe โ rty โ โ โ โ uio โ โ โโโโโโโฉโโโโโโฉโโโโ
Themes.double_thin
>>> t.print(theme=Themes.double_thin) โโโโโโโฆโโโโโโฆโโโโ โ 1 โ 2 โ 3 โ โโโโโโโซโโโโโโซโโโโข โ qwe โ rty โ โ โ โ uio โ โ โโโโโโโฉโโโโโโฉโโโโ >>> t_column_names.print(theme=Themes.double_thin) โโโโโโโฆโโโโโโฆโโโโ โ c1 โ c2 โ 3 โ โโโโโโโซโโโโโโซโโโโข โ 1 โ 2 โ 3 โ โ โโโโโโฌโโโโโโฌโโโโฃ โ qwe โ rty โ โ โ โ uio โ โ โโโโโโโฉโโโโโโฉโโโโ >>> t_name.print(theme=Themes.double_thin) โโโโโโโโโโโโโโโโโ โ Table Name โ โ โโโโโโฆโโโโโโฆโโโโฃ โ 1 โ 2 โ 3 โ โโโโโโโซโโโโโโซโโโโข โ qwe โ rty โ โ โ โ uio โ โ โโโโโโโฉโโโโโโฉโโโโ >>> t_name_column_names.print(theme=Themes.double_thin) โโโโโโโโโโโโโโโโโ โ Table Name โ โ โโโโโโฆโโโโโโฆโโโโฃ โ c1 โ c2 โ 3 โ โโโโโโโซโโโโโโซโโโโข โ 1 โ 2 โ 3 โ โ โโโโโโฌโโโโโโฌโโโโฃ โ qwe โ rty โ โ โ โ uio โ โ โโโโโโโฉโโโโโโฉโโโโ
Themes.booktabs
>>> t.print(theme=Themes.booktabs) โโโโโโโโโโโโโโโ 1 2 3 โโโโโโโโโโโโโโโ qwe rty uio โโโโโโโโโโโโโโโ >>> t_column_names.print(theme=Themes.booktabs) โโโโโโโโโโโโโโโ c1 c2 3 โโโโโโโโโโโโโโโ 1 2 3 โโโโโโโโโโโโโโโ qwe rty uio โโโโโโโโโโโโโโโ >>> t_name.print(theme=Themes.booktabs) โโโโโโโโโโโโโโโ Table Name โโโโโโโโโโโโโโโ 1 2 3 โโโโโโโโโโโโโโโ qwe rty uio โโโโโโโโโโโโโโโ >>> t_name_column_names.print(theme=Themes.booktabs) โโโโโโโโโโโโโโโ Table Name โโโโโโโโโโโโโโโ c1 c2 3 โโโโโโโโโโโโโโโ 1 2 3 โโโโโโโโโโโโโโโ qwe rty uio โโโโโโโโโโโโโโโ
Themes.markdown
>>> t.print(theme=Themes.markdown) | 1 | 2 | 3 | |-----|-----|---| | qwe | rty | | | | uio | | >>> t_column_names.print(theme=Themes.markdown) | c1 | c2 | 3 | |-----|-----|---| | 1 | 2 | 3 | | qwe | rty | | | | uio | | >>> t_name.print(theme=Themes.markdown) | Table Name | | 1 | 2 | 3 | |-----|-----|---| | qwe | rty | | | | uio | | >>> t_name_column_names.print(theme=Themes.markdown) | Table Name | | c1 | c2 | 3 | |-----|-----|---| | 1 | 2 | 3 | | qwe | rty | | | | uio | |
You can define a completely custom theme:
>>> from table2string import Theme, Border >>> new_theme = Theme( # doctest: +SKIP ... name="your_new_theme_name", ... border=Border( ... horizontal="-", ... vertical="|", ... top_left="+", ... top_right="+", ... # other characters ... ), ... # Theme to be used for nested tables to ensure proper border merging ... # Defaults to the parent table's theme ... custom_sub_table_theme=None, ... )
Example
from prettytable import PrettyTable from table2string import Table names = ("plain text", "emoji") table = [ ( "text\ntext", "๐จโ๐ฉโ๐งโ๐ฆ๐จโ๐ฉโ๐ฆโ๐ฆ๐จโ๐ฉโ๐งโ๐ง\n" "๐จโ๐จโ๐งโ๐ฆ๐จโ๐จโ๐งโ๐ง๐จโ๐ฉโ๐ง๐ฉโโค๏ธโ๐จ\n" "๐จโโค๏ธโ๐จ๐ฏ๐ฉโ๐ฆผ๐ญ๐จโ๐ฉโ๐งโ๐ฆ\n" "๐จโ๐จโ๐งโ๐ฆ๐จโ๐จโ๐ฆ๐ฉโ๐ฉโ๐ง\n" "๐จโ๐จโ๐งโ๐ง๐จโ๐ฉโ๐ฆโ๐ฆ", ), ] t = PrettyTable(title="prettytable", field_names=names, h_align="c") t.add_rows(table) # type: ignore print(t) t = Table(table, name="table2string", column_names=names) t.print(h_align="^", sep=(1,))
Windows Terminal
Windows 10
Windows 11
VT100 terminal emulator
To elegantly display structured data inside table cells, you can embed subtables.
These subtables are rendered as full tables within a cell and will seamlessly merge borders with the parent table.
Since a subtable is itself a Table instance, you can nest them recursively without limit.
Subtables will automatically scale to fit the width of their parent cell.
Example
>>> Table( ... [ ... ("1",), ... (Table([("2", "3")]),), ... ] ... ).print() +-------+ | 1 | +---+---+ | 2 | 3 | +---+---+ >>> Table([( ... Table([( ... Table([( ... Table([( ... Table([( ... Table([( ... Table([( ... Table( ... [ ... ("1",), ... (Table([("2", "3")]),), ... ] ... ), ... )]), ... )]), ... )]), ... )]), ... )]), ... )]), ... )]).print() +-------+ | 1 | +---+---+ | 2 | 3 | +---+---+ >>> Table( ... [ ... ( ... "123", ... Table( ... [ ... ("456",), ... (Table([("789", "101")]),), ... ] ... ), ... ), ... ] ... ).print() +-----+-----------+ | 123 | 456 | | +-----+-----+ | | 789 | 101 | +-----+-----+-----+
Formatting is handled by classes from the text_splitters module.
All classes inherit from one another in a cascading fashion and ultimately extend BaseTextSplitter.
BaseTextSplitter(default in thestringifymethod) โ The base class. It provides thesplit_textmethod, which splits text by width and height to fit it into a cell.AnsiTextSplitterUnsafeโ Inherits fromBaseTextSplitterand wraps itssplit_textmethod. It wraps ANSI sequences and hyperlinks so they remain functional even when the text is wrapped.AnsiTextSplitter(default in theprintmethod) โ Inherits fromAnsiTextSplitterUnsafeand escapes unsafe sequences (everything except color and hyperlinks).
You can separately configure splitters for the table name and column headers. It is also possible to set a splitter for the entire table, or for each column individually.
name_splitterโ Splitter for the table name. Can be an instance of anyBaseTextSplittersubclass.column_names_splitterโ Splitter for column names. Can be an instance of aBaseTextSplittersubclass, or atupleof instances corresponding to the number of columns.text_splitterโ Splitter for table content. Can be an instance of aBaseTextSplittersubclass, or atupleof instances, one for each column.
If the tuple has fewer elements than there are columns, the last element of the tuple will be used for all remaining columns.
For convenient ANSI formatting, you can use the text_styles module.
It provides:
- Enum
Colorโ predefined foreground colors - Enum
BgColorโ predefined background colors - Function
style(text: str, *, fg: Color | tuple[int, int, int] | None = None, bg: BgColor | tuple[int, int, int] | None = None, **attrs) -> strโ wrap your text in the specified ANSI color/style codes - Function
link(url: str, text: str, **attrs) -> strโ create an OSC hyperlink around your text
You may also freely use the third-party Colorama library for colorizing table input.
Important
table2string does not automatically enable ANSI support on the Windows console.
To turn it on, call just_fix_windows_console() from the Colorama package before printing.
>>> from table2string import Table, Themes, style, link, Color, BaseTextSplitter, AnsiTextSplitter >>> # Same as Table([("q\x1b[31mwe\nr\x1b[0mty",)]).print() >>> red_text = style("we\nr", fg=Color.RED) >>> Table([(f"q{red_text}ty",)]).print() # AnsiTextSplitter by default +-----+ | q๏ฟฝ[31mwe๏ฟฝ[0m | | ๏ฟฝ[31mr๏ฟฝ[0mty | +-----+ >>> temp_text = style("Bold & Italic White", fg=(255, 255, 255), italic=True) >>> colored_text = style(f"Bold Gold {temp_text} Text", fg=(255, 170, 0), bold=True) >>> underlined_text = style("Underline", underline=True) >>> example_link = link("example.com", "Strikethrough Green Link", fg=(85, 255, 85), strike=True) >>> table = Table([(f"{colored_text}{underlined_text}{example_link}",)]) >>> table.print(max_width=25) +-----------------------+ | ๏ฟฝ[38;2;255;170;0m๏ฟฝ[1mBold Gold ๏ฟฝ[38;2;255;255;255m๏ฟฝ[3mBold & Ital๏ฟฝ[0m/| | ๏ฟฝ[38;2;255;170;0m๏ฟฝ[1m๏ฟฝ[38;2;255;255;255m๏ฟฝ[3mic White๏ฟฝ[0m๏ฟฝ[38;2;255;170;0m๏ฟฝ[1m Text๏ฟฝ[0m ๏ฟฝ[4mUnderli๏ฟฝ[0m/| | ๏ฟฝ[4mne๏ฟฝ[0m ๏ฟฝ]8;;https://example.com๏ฟฝ\๏ฟฝ[38;2;85;255;85m๏ฟฝ[9mStrikethrough Gree๏ฟฝ]8;;๏ฟฝ\๏ฟฝ[0m/| | ๏ฟฝ[38;2;85;255;85m๏ฟฝ[9m๏ฟฝ]8;;https://example.com๏ฟฝ\n Link๏ฟฝ]8;;๏ฟฝ\๏ฟฝ[0m | +-----------------------+ >>> table = Table( ... [("Text", "T\x1b[31me\nxt\x1b[0m1", "T\x1b[32mex\nt\x1b[0m2")], ... name=style("Table", fg=Color.BLUE), ... column_names=("Text", "Colored text 1", "Colored text 2"), ... ) >>> table.print( ... name_splitter=AnsiTextSplitter(), ... column_names_splitter=(BaseTextSplitter(),), # BaseTextSplitter for all remaining columns ... # Or column_names_splitter=BaseTextSplitter(), ... text_splitter=( ... BaseTextSplitter(), ... AnsiTextSplitter(), ... BaseTextSplitter(), # The color sequences will leak here if reset is missing ... ), ... ) +----------------------------------------+ | ๏ฟฝ[34mTable๏ฟฝ[0m | +------+----------------+----------------+ | Text | Colored text 1 | Colored text 2 | +------+----------------+----------------+ | Text | T๏ฟฝ[31me๏ฟฝ[0m | T๏ฟฝ[32mex | | | ๏ฟฝ[31mxt๏ฟฝ[0m1 | t๏ฟฝ[0m2 | +------+----------------+----------------+
You can create your own custom splitter formatter (e.g. for HTML or Markdown or other markup languages)
by subclassing AnsiTextSplitter or BaseTextSplitter and overriding the split_text and clear_formatting methods.
split_textโ Called for each cell. Should split the text so it fits within the cell.clear_formattingโ Called when calculating the width of a cell.
This method should remove all formatting, leaving only visible characters and ANSI sequences. For example, with HTML formatting, it should strip all tags and leave only the visible text.