fbf331e0dd
Change-Id: I42b4a44fd6a2197e499e8623274b3cd1a4b5556f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/394003 Commit-Queue: Samuel Rawlins <srawlins@google.com> Reviewed-by: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Bob Nystrom <rnystrom@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
113 lines
3.4 KiB
Dart
113 lines
3.4 KiB
Dart
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
import 'dart:math' as math;
|
|
|
|
/// Print the given [table].
|
|
void printTable(List<List<String>> table) {
|
|
var buffer = StringBuffer();
|
|
buffer.writeTable(table);
|
|
print(buffer.toString());
|
|
}
|
|
|
|
/// Return an iterable that will produce all of the integer values between
|
|
/// [first] and [last] inclusive.
|
|
Iterable<int> range(int first, int last) sync* {
|
|
for (var i = first; i < last; i++) {
|
|
yield i;
|
|
}
|
|
}
|
|
|
|
/// Given a [table] represented as a list of rows, right justify all of the
|
|
/// cells in the given [column].
|
|
void rightJustifyColumn(List<List<String>> table, int column) {
|
|
var width = 0;
|
|
for (var i = 0; i < table.length; i++) {
|
|
var row = table[i];
|
|
width = math.max(width, row[column].length);
|
|
}
|
|
for (var i = 0; i < table.length; i++) {
|
|
var row = table[i];
|
|
var cellValue = row[column];
|
|
var length = cellValue.length;
|
|
if (length < width) {
|
|
var padding = ' ' * (width - length);
|
|
row[column] = '$padding$cellValue';
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Given a [table] represented as a list of rows, right justify all of the
|
|
/// cells in the given [columns].
|
|
void rightJustifyColumns(List<List<String>> table, Iterable<int> columns) {
|
|
for (var column in columns) {
|
|
rightJustifyColumn(table, column);
|
|
}
|
|
}
|
|
|
|
extension OutputUtilities on StringSink {
|
|
/// Write the given [table].
|
|
///
|
|
/// The table is represented as a list or rows, where each row is a list of
|
|
/// the contents of the cells in that row.
|
|
///
|
|
/// Throws an [ArgumentError] if the table is empty or if the rows do not
|
|
/// contain the same number of cells.
|
|
void writeTable(List<List<String>> table) {
|
|
var columnWidths = _computeColumnWidths(table);
|
|
for (var row in table) {
|
|
var lastNonEmpty = row.length - 1;
|
|
while (lastNonEmpty > 0) {
|
|
if (row[lastNonEmpty].isNotEmpty) {
|
|
break;
|
|
}
|
|
lastNonEmpty--;
|
|
}
|
|
for (var i = 0; i <= lastNonEmpty; i++) {
|
|
var cellContent = row[i];
|
|
var columnWidth = columnWidths[i];
|
|
var padding = columnWidth - cellContent.length;
|
|
write(cellContent);
|
|
if (i < lastNonEmpty) {
|
|
write(' ' * (padding + 2));
|
|
}
|
|
}
|
|
writeln();
|
|
}
|
|
}
|
|
|
|
/// Return the minimum widths for each of the columns in the given [table].
|
|
///
|
|
/// The table is represented as a list or rows, where each row is a list of
|
|
/// the contents of the cells in that row.
|
|
///
|
|
/// Throws an [ArgumentError] if the table is empty or if the rows do not
|
|
/// contain the same number of cells.
|
|
List<int> _computeColumnWidths(List<List<String>> table) {
|
|
if (table.isEmpty) {
|
|
throw ArgumentError('table cannot be empty');
|
|
}
|
|
var columnCount = table[0].length;
|
|
if (columnCount == 0) {
|
|
throw ArgumentError('rows cannot be empty');
|
|
}
|
|
var columnWidths = List<int>.filled(columnCount, 0);
|
|
for (var row in table) {
|
|
var rowLength = row.length;
|
|
if (rowLength > 0) {
|
|
if (rowLength != columnCount) {
|
|
throw ArgumentError(
|
|
'non-empty rows must contain the same number of columns',
|
|
);
|
|
}
|
|
for (var i = 0; i < rowLength; i++) {
|
|
var cellWidth = row[i].length;
|
|
columnWidths[i] = math.max(columnWidths[i], cellWidth);
|
|
}
|
|
}
|
|
}
|
|
return columnWidths;
|
|
}
|
|
}
|