renderTable function

String renderTable(
  1. List<String> header,
  2. List<List<String>> rows, {
  3. Style style = Style.plain,
  4. String decorate(
    1. int column,
    2. String paddedCell
    )?,
})

Renders rows as an aligned table. Cells are padded on their plain text first, then decorate may color them, so ANSI codes never break the alignment.

Implementation

String renderTable(
  List<String> header,
  List<List<String>> rows, {
  Style style = Style.plain,
  String Function(int column, String paddedCell)? decorate,
}) {
  final widths = [
    for (var c = 0; c < header.length; c++)
      [header[c], ...rows.map((r) => r[c])]
          .map((s) => s.length)
          .reduce((a, b) => a > b ? a : b),
  ];
  String line(List<String> cells, {bool head = false}) {
    final parts = [
      for (var c = 0; c < cells.length; c++)
        () {
          final padded = cells[c].padRight(widths[c]);
          if (head) return style.bold(padded);
          return decorate == null ? padded : decorate(c, padded);
        }(),
    ];
    return parts.join('  ').trimRight();
  }

  return [
    line(header, head: true),
    style.dim([for (final w in widths) style.rule * w].join('  ')),
    ...rows.map(line),
  ].join('\n');
}