AQIT
0.1.0
Toggle main menu visibility
Loading...
Searching...
No Matches
table_plain.py
Go to the documentation of this file.
1
# Copyright (c) 2025-present Aquin Labs Private Limited. All Rights Reserved.
2
"""Plain Unicode tables for quiet CLI surfaces (no Rich)."""
3
4
from
__future__
import
annotations
5
6
import
sys
7
from
collections.abc
import
Sequence
8
9
10
# Box-drawing (falls back to ASCII if stdout can't encode them).
11
_UNICODE = {
12
"tl"
:
"┌"
,
"tr"
:
"┐"
,
"bl"
:
"└"
,
"br"
:
"┘"
,
13
"h"
:
"─"
,
"v"
:
"│"
,
14
"l"
:
"├"
,
"r"
:
"┤"
,
"t"
:
"┬"
,
"b"
:
"┴"
,
"x"
:
"┼"
,
15
}
16
_ASCII = {
17
"tl"
:
"+"
,
"tr"
:
"+"
,
"bl"
:
"+"
,
"br"
:
"+"
,
18
"h"
:
"-"
,
"v"
:
"|"
,
19
"l"
:
"+"
,
"r"
:
"+"
,
"t"
:
"+"
,
"b"
:
"+"
,
"x"
:
"+"
,
20
}
21
22
23
def
_glyphs
() -> dict[str, str]:
24
try
:
25
encoding = getattr(sys.stdout,
"encoding"
,
None
)
or
"utf-8"
26
"┌─│"
.encode(encoding)
27
return
_UNICODE
28
except
Exception:
29
return
_ASCII
30
31
32
def
_cell
(text: str, width: int, *, align: str =
"left"
) -> str:
33
s = str(text)
34
if
len(s) > width:
35
if
width <= 1:
36
s = s[:width]
37
else
:
38
s = s[: width - 1] +
"…"
39
if
align ==
"right"
:
40
return
s.rjust(width)
41
return
s.ljust(width)
42
43
44
def
format_table
(
45
headers: Sequence[str],
46
rows: Sequence[Sequence[str]],
47
*,
48
aligns: Sequence[str] |
None
=
None
,
49
max_col: int = 48,
50
) -> str:
51
"""Return a bordered table as a multi-line string."""
52
g =
_glyphs
()
53
n = len(headers)
54
if
aligns
is
None
:
55
aligns = [
"left"
] * n
56
elif
len(aligns) < n:
57
aligns = list(aligns) + [
"left"
] * (n - len(aligns))
58
59
widths = [min(max_col, len(str(h)))
for
h
in
headers]
60
for
row
in
rows:
61
for
i, cell
in
enumerate(row[:n]):
62
widths[i] = min(max_col, max(widths[i], len(str(cell))))
63
64
def
line(left: str, join: str, right: str) -> str:
65
return
left + join.join(g[
"h"
] * (w + 2)
for
w
in
widths) + right
66
67
def
row_line(cells: Sequence[str]) -> str:
68
parts = [
69
f
" {_cell(cells[i] if i < len(cells) else '', widths[i], align=aligns[i])} "
70
for
i
in
range(n)
71
]
72
return
g[
"v"
] + g[
"v"
].join(parts) + g[
"v"
]
73
74
out: list[str] = [
75
line(g[
"tl"
], g[
"t"
], g[
"tr"
]),
76
row_line(headers),
77
line(g[
"l"
], g[
"x"
], g[
"r"
]),
78
]
79
for
row
in
rows:
80
out.append(row_line(row))
81
out.append(line(g[
"bl"
], g[
"b"
], g[
"br"
]))
82
return
"\n"
.join(out)
83
84
85
def
print_table
(
86
headers: Sequence[str],
87
rows: Sequence[Sequence[str]],
88
*,
89
aligns: Sequence[str] |
None
=
None
,
90
max_col: int = 48,
91
title: str |
None
=
None
,
92
) ->
None
:
93
try
:
94
sys.stdout.reconfigure(encoding=
"utf-8"
)
# type: ignore[attr-defined]
95
except
Exception:
96
pass
97
if
title:
98
print(title)
99
print(
format_table
(headers, rows, aligns=aligns, max_col=max_col))
aquin.table_plain.print_table
None print_table(Sequence[str] headers, Sequence[Sequence[str]] rows, *, Sequence[str]|None aligns=None, int max_col=48, str|None title=None)
Definition
table_plain.py:96
aquin.table_plain._glyphs
dict[str, str] _glyphs()
Definition
table_plain.py:27
aquin.table_plain._cell
str _cell(str text, int width, *, str align="left")
Definition
table_plain.py:36
aquin.table_plain.format_table
str format_table(Sequence[str] headers, Sequence[Sequence[str]] rows, *, Sequence[str]|None aligns=None, int max_col=48)
Definition
table_plain.py:54
aquin
table_plain.py
AQIT · Aquin Labs Private Limited · Apache 2.0 · Generated by
1.18.0