Skip to content

Commit 46c9fe3

Browse files
committed
replace DataRow namedtuple with a dataclass with the same name and an optional escape_map
generalize LaTeX escaping function, move escaping to _build_simple_row
1 parent 8abc5c9 commit 46c9fe3

1 file changed

Lines changed: 28 additions & 15 deletions

File tree

tabulate/__init__.py

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
PackageNotFoundError as _PackageNotFoundError,
55
version as _version,
66
)
7+
from typing import Callable, Union
78

89
try:
910
__version__ = _version("tabulate")
@@ -17,6 +18,7 @@
1718
from collections.abc import Iterable, Sized
1819
import dataclasses
1920
from decimal import Decimal
21+
from dataclasses import dataclass
2022
from functools import partial, reduce
2123
from html import escape as htmlescape
2224
import io
@@ -69,7 +71,12 @@ def _is_file(f):
6971
Line = namedtuple("Line", ["begin", "hline", "sep", "end"])
7072

7173

72-
DataRow = namedtuple("DataRow", ["begin", "sep", "end"])
74+
@dataclass
75+
class DataRow:
76+
begin: str
77+
sep: str
78+
end: str
79+
escape_map: dict = None
7380

7481

7582
# A table structure is supposed to be:
@@ -323,13 +330,7 @@ def make_header_line(is_header, colwidths, colaligns):
323330
}
324331

325332

326-
def _latex_row(cell_values, colwidths, colaligns, escrules=LATEX_ESCAPE_RULES):
327-
def escape_char(c):
328-
return escrules.get(c, c)
329-
330-
escaped_values = ["".join(map(escape_char, cell)) for cell in cell_values]
331-
rowfmt = DataRow("", "&", "\\\\")
332-
return _build_simple_row(escaped_values, rowfmt)
333+
_latex_row = DataRow("", "&", "\\\\", LATEX_ESCAPE_RULES)
333334

334335

335336
def _rst_escape_first_column(rows, headers):
@@ -652,8 +653,8 @@ def escape_empty(val):
652653
linebelowheader=Line("\\hline", "", "", ""),
653654
linebetweenrows=None,
654655
linebelow=Line("\\hline\n\\end{tabular}", "", "", ""),
655-
headerrow=partial(_latex_row, escrules={}),
656-
datarow=partial(_latex_row, escrules={}),
656+
headerrow=DataRow("", "&", "\\\\", {}),
657+
datarow=DataRow("", "&", "\\\\", {}),
657658
padding=1,
658659
with_header_hide=None,
659660
),
@@ -2506,13 +2507,24 @@ def _pad_row(cells, padding):
25062507
return cells
25072508

25082509

2509-
def _build_simple_row(padded_cells, rowfmt):
2510+
def _build_simple_row(padded_cells: list[list], rowfmt: DataRow) -> str:
25102511
"Format row according to DataRow format without padding."
2511-
begin, sep, end = rowfmt
2512-
return (begin + sep.join(padded_cells) + end).rstrip()
2512+
begin = rowfmt.begin
2513+
sep = rowfmt.sep
2514+
end = rowfmt.end
2515+
escape_map: dict = rowfmt.escape_map
2516+
2517+
if escape_map:
2518+
def escape_char(c):
2519+
return escape_map.get(c, c)
2520+
escaped_cells = ["".join(map(escape_char, cell)) for cell in padded_cells]
2521+
else:
2522+
escaped_cells = padded_cells
2523+
2524+
return (begin + sep.join(escaped_cells) + end).rstrip()
25132525

25142526

2515-
def _build_row(padded_cells, colwidths, colaligns, rowfmt):
2527+
def _build_row(padded_cells: list[list], colwidths: list[int], colaligns: list[str], rowfmt: Union[DataRow, Callable]) -> str:
25162528
"Return a string which represents a row of data cells."
25172529
if not rowfmt:
25182530
return None
@@ -2571,7 +2583,8 @@ def _build_line(colwidths, colaligns, linefmt):
25712583
else:
25722584
begin, fill, sep, end = linefmt
25732585
cells = [fill * w for w in colwidths]
2574-
return _build_simple_row(cells, (begin, sep, end))
2586+
rowfmt = DataRow(begin, sep, end)
2587+
return _build_simple_row(cells, rowfmt)
25752588

25762589

25772590
def _append_line(lines, colwidths, colaligns, linefmt):

0 commit comments

Comments
 (0)