tabular function
- List<
List> rows, { - Map<
dynamic, Side> ? align, - Map<
dynamic, FormatCell> ? format, - List<
Sort> ? sort, - dynamic markdownAlign = false,
- Border border = Border.none,
- Style style = Style.markdown,
- List<
int> ? rowDividers = const [1], - @Deprecated('Use border=Border.vertical argument') dynamic outerBorder = false,
Converts a set of cells defined by a two-dimensional list to a Markdown formatted ASCII table. Returns a string with the table that is ready for printing.
rows
is the source data for the table. The first of the lists will be the header, the
others - ordinary rows. The values can be Strings, nums, null
, or any objects. Either
way, they end up being converted to strings.
align
specifies which way all cells in a particular column should be aligned. The keys
of this Map can be of type int then they denote the index of the column, or of type
String - then they denote the name of the column.
format
specifies how to convert each cell of a particular column to a row.
This conversion occurs after sorting, but before alignment. The keys of this Map can be
of type int then they denote the index of the column, or of type String - then they
denote the name of the column.
sort
determines the sorting order. Sorting can take place in several columns at once.
Priority will be given to the ones at the beginning of the list.
markdownAlign
determines whether to add the ':' characters to the delimiter under
the header. These symbols tell services like GitHub which way to align the columns after
converting the table to HTML.
border
determines whether an outer border should be added to the table and what parts
it should consist of.
rowDividers
contains the indices of the rows
, which must be preceded by a horizontal
divider. By default, there is only index 1, which corresponds to the divider between
the header and the body of the table. rowDividers: null
will cause dividers to be added
between all rows.
Implementation
String tabular(
List<List<dynamic>> rows,
{Map<dynamic, Side>? align,
Map<dynamic, FormatCell>? format,
List<Sort>? sort,
markdownAlign = false,
Border border = Border.none,
Style style = Style.markdown,
List<int>? rowDividers = const [1],
@Deprecated('Use border=Border.vertical argument') // since 2021-04-28
outerBorder = false}) {
if (rows.isEmpty) {
throw ArgumentError.value(rows, 'rows', 'Must not be empty');
}
if (outerBorder && border == Border.none) {
border = Border.vertical;
}
bool borderV = border == Border.vertical || border == Border.all;
bool borderH = border == Border.horizontal || border == Border.all;
final matrix = CellsMatrix(rows, format);
if (sort != null) {
matrix.sortBy(sort);
}
List<Side> colToAlign = createColToAlign(matrix, align);
String cross;
switch (style) {
case Style.markdown:
cross = '|';
break;
case Style.mysql:
cross = '+';
break;
}
String bar = '';
if (borderV) {
bar += cross;
}
for (int i = 0; i < matrix.columns.length; ++i) {
final align = markdownAlign ? colToAlign[i] : null;
int width = matrix.columns[i].textWidth;
// if (width<=0) {
// width = 1;
// }
final bool isSingleColumn = matrix.columns.length == 1;
final bool isFirstColumn = i == 0;
final bool isLastColumn = i == matrix.columns.length - 1;
int extra = 0;
if (!borderV) {
if (isSingleColumn) {
extra = -2;
} else if (isFirstColumn || isLastColumn) {
extra = -1;
}
}
//int extra = ((isFirstColumn || isLastColumn) && !borderV) ? -1 : 0;
switch (align) {
case null:
case Side.start:
//print("A $width $extra");
bar += ('-' * (width + 2 + extra));
break;
case Side.end:
//print("B");
bar += ('-' * (width + 1 + extra) + ':');
break;
case Side.center:
//print("C");
bar += (':' + '-' * width + ':');
}
if (borderV || !isLastColumn) {
bar += cross;
}
//print("width $width $bar");
}
String dashBar() => bar; // '+'+('-'*(bar.length-2))+'+';
final formattedRows = <String>[];
if (borderH) {
formattedRows.add(dashBar());
}
final aligner = Aligner();
var iRow = -1;
for (var row in matrix.rows) {
iRow++;
if (iRow > 0 && (rowDividers == null || rowDividers.contains(iRow))) {
formattedRows.add(bar);
}
var formatted = '';
var iCol = -1;
for (final me in enumerate(row)) {
final cell = me.value;
if (me.index == 0) {
if (borderV) {
formatted += '| ';
}
} else {
formatted += ' | ';
}
iCol++;
formatted += aligner.alignText(cell.toFinalString(),
matrix.columns[iCol].textWidth, colToAlign[iCol]);
}
if (borderV) {
formatted += ' |';
}
formattedRows.add(formatted);
}
if (borderH) {
formattedRows.add(dashBar());
}
return formattedRows.join('\n');
}