Skip to content

Commit 2dd24af

Browse files
authored
Merge pull request #20 from freva/freva/hide-column
Support setting columns invisible
2 parents c466fae + 6a2dfea commit 2dd24af

File tree

6 files changed

+69
-37
lines changed

6 files changed

+69
-37
lines changed

src/main/java/com/github/freva/asciitable/AsciiTable.java

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,11 @@ static void writeTable(OutputStreamWriter osw, String lineSeparator, Character[]
3737
if (border.length != NO_BORDERS.length)
3838
throw new IllegalArgumentException("Border characters array must be exactly " + NO_BORDERS.length + " elements long");
3939

40-
String[][] stringData = objectArrayToString(data);
41-
int numColumns = getNumColumns(rawColumns, stringData);
40+
String[][] stringData = objectArrayToString(rawColumns, data);
41+
int numColumns = getNumColumns(rawColumns, data);
4242
Column[] columns = IntStream.range(0, numColumns)
4343
.mapToObj(index -> index < rawColumns.length ? rawColumns[index] : new Column())
44+
.filter(Column::isVisible)
4445
.toArray(Column[]::new);
4546

4647
writeTable(osw, lineSeparator, border, columns, stringData);
@@ -160,7 +161,7 @@ private static int[] getColWidths(Column[] columns, String[][] data) {
160161
}
161162

162163
/** Returns maximum number of columns between the header or any of the data rows */
163-
private static int getNumColumns(Column[] columns, String[][] data) {
164+
private static int getNumColumns(Column[] columns, Object[][] data) {
164165
return Arrays.stream(data)
165166
.mapToInt(cols -> cols.length)
166167
.reduce(columns.length, Math::max);
@@ -233,13 +234,20 @@ private static void writeRepeated(OutputStreamWriter osw, char c, int num) throw
233234
for (int i = 0; i < num; i++) osw.append(c);
234235
}
235236

236-
private static String[][] objectArrayToString(Object[][] array) {
237-
if (array instanceof String[][]) return (String[][]) array;
237+
private static String[][] objectArrayToString(Column[] columns, Object[][] array) {
238+
int[] numInvisible = new int[Math.max(1, columns.length)];
239+
for (int i = 0; i < columns.length; i++)
240+
numInvisible[i] = (i == 0 ? 0 : numInvisible[i - 1]) + (columns[i].isVisible() ? 0 : 1);
241+
242+
if (numInvisible[numInvisible.length - 1] == 0 && array instanceof String[][])
243+
return (String[][]) array;
244+
238245
String[][] stringArray = new String[array.length][];
239246
for (int i = 0; i < stringArray.length; i++) {
240-
stringArray[i] = new String[array[i].length];
241-
for (int j = 0; j < array[i].length; j++) {
242-
stringArray[i][j] = array[i][j] == null ? null : array[i][j].toString();
247+
stringArray[i] = new String[array[i].length - numInvisible[Math.min(numInvisible.length, array[i].length) - 1]];
248+
for (int j = 0, k = 0; k < stringArray[i].length; j++) {
249+
if (j < columns.length && !columns[j].isVisible()) continue;
250+
stringArray[i][k++] = array[i][j] == null ? null : array[i][j].toString();
243251
}
244252
}
245253
return stringArray;

src/main/java/com/github/freva/asciitable/Column.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,20 @@ public class Column {
1111
private int minWidth;
1212
private int maxWidth;
1313
private OverflowBehaviour overflowBehaviour;
14+
private boolean visible;
1415

1516
public Column() {
16-
this(null, null, HorizontalAlign.LEFT, HorizontalAlign.RIGHT, HorizontalAlign.LEFT, 0, 80, OverflowBehaviour.NEWLINE);
17+
this(null, null, HorizontalAlign.LEFT, HorizontalAlign.RIGHT, HorizontalAlign.LEFT, 0, 80, OverflowBehaviour.NEWLINE, true);
1718
}
1819

1920
@Deprecated
2021
public Column(String header, String footer, HorizontalAlign headerAlign, HorizontalAlign dataAlign,
2122
HorizontalAlign footerAlign, int maxWidth) {
22-
this(header, footer, headerAlign, dataAlign, footerAlign, 0, maxWidth, OverflowBehaviour.NEWLINE);
23+
this(header, footer, headerAlign, dataAlign, footerAlign, 0, maxWidth, OverflowBehaviour.NEWLINE, true);
2324
}
2425

25-
public Column(String header, String footer, HorizontalAlign headerAlign, HorizontalAlign dataAlign,
26-
HorizontalAlign footerAlign, int minWidth, int maxWidth, OverflowBehaviour overflowBehaviour) {
26+
Column(String header, String footer, HorizontalAlign headerAlign, HorizontalAlign dataAlign,
27+
HorizontalAlign footerAlign, int minWidth, int maxWidth, OverflowBehaviour overflowBehaviour, boolean visible) {
2728
this.header = header;
2829
this.footer = footer;
2930
this.headerAlign = headerAlign;
@@ -32,6 +33,7 @@ public Column(String header, String footer, HorizontalAlign headerAlign, Horizon
3233
this.minWidth = minWidth;
3334
this.maxWidth = maxWidth;
3435
this.overflowBehaviour = overflowBehaviour;
36+
this.visible = visible;
3537
}
3638

3739
public String getHeader() {
@@ -80,6 +82,10 @@ public int getFooterWidth() {
8082
return footer != null ? footer.length() : 0;
8183
}
8284

85+
public boolean isVisible() {
86+
return visible;
87+
}
88+
8389

8490
public Column header(String header) {
8591
this.header = header;
@@ -131,6 +137,12 @@ public Column maxWidth(int maxWidth, OverflowBehaviour overflowBehaviour) {
131137
@Deprecated
132138
public Column maxColumnWidth(int maxWidth) { return maxWidth(maxWidth); }
133139

140+
/** Sets whether this column should be rendered. Default is true */
141+
public Column visible(boolean visible) {
142+
this.visible = visible;
143+
return this;
144+
}
145+
134146
public <T> ColumnData<T> with(Function<T, String> getter) {
135147
return new ColumnData<T>(this, getter);
136148
}

src/main/java/com/github/freva/asciitable/ColumnData.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ public class ColumnData<T> extends Column {
77

88
ColumnData(Column column, Function<T, String> getter) {
99
super(column.getHeader(), column.getFooter(), column.getHeaderAlign(), column.getDataAlign(), column.getFooterAlign(),
10-
column.getMinWidth(), column.getMaxWidth(), column.getOverflowBehaviour());
10+
column.getMinWidth(), column.getMaxWidth(), column.getOverflowBehaviour(), column.isVisible());
1111
this.getter = getter;
1212
}
1313

src/main/java/com/github/freva/asciitable/LineUtils.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,15 @@ public static int maxLineLength(String str) {
2727
private static class LineIterator implements Iterator<String> {
2828
private final String str;
2929
private int position = 0;
30+
private boolean newlineLast = true;
3031

3132
private LineIterator(String str) {
3233
this.str = str;
3334
}
3435

3536
@Override
3637
public boolean hasNext() {
37-
return position < str.length();
38+
return newlineLast || position < str.length();
3839
}
3940

4041
@Override
@@ -44,10 +45,15 @@ public String next() {
4445
}
4546

4647
public int getLineEndPositionAndAdvanceToNextLine() {
48+
newlineLast = false;
4749
for (; position < str.length(); position++) {
4850
char ch = str.charAt(position);
49-
if (ch == '\n') return position++;
51+
if (ch == '\n') {
52+
newlineLast = true;
53+
return position++;
54+
}
5055
if (ch == '\r') {
56+
newlineLast = true;
5157
if (position + 1 == str.length() || str.charAt(position + 1) != '\n') return position++;
5258
position += 2;
5359
return position - 2;

src/test/java/com/github/freva/asciitable/AsciiTableTest.java

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,15 @@
33
import org.junit.Test;
44

55
import java.io.ByteArrayOutputStream;
6-
import java.io.FileOutputStream;
76
import java.io.IOException;
8-
import java.io.OutputStream;
97
import java.io.OutputStreamWriter;
10-
import java.nio.file.Files;
11-
import java.nio.file.Path;
12-
import java.nio.file.Paths;
138
import java.time.Instant;
149
import java.util.Arrays;
1510
import java.util.LinkedHashMap;
1611
import java.util.List;
1712
import java.util.Locale;
1813
import java.util.Map;
14+
import java.util.function.BiConsumer;
1915

2016
import static com.github.freva.asciitable.HorizontalAlign.*;
2117
import static org.junit.Assert.assertEquals;
@@ -385,23 +381,6 @@ public void tableWithParagraphsClipLeftOverflow() {
385381

386382
@Test
387383
public void tableWithParagraphsClipRightOverflow() throws IOException {
388-
try (OutputStream fos = Files.newOutputStream(Paths.get("table.txt"))) {
389-
AsciiTable.builder()
390-
.lineSeparator("\r\n")
391-
.border(AsciiTable.BASIC_ASCII_NO_OUTSIDE_BORDER)
392-
.data(planets, Arrays.asList(
393-
new Column().with(planet -> Integer.toString(planet.num)),
394-
new Column().header("Name").footer("Average").headerAlign(CENTER).dataAlign(RIGHT).with(planet -> planet.name),
395-
new Column().header("Diameter").headerAlign(RIGHT).dataAlign(CENTER).footerAlign(CENTER)
396-
.footer(String.format("%.03f", planets.stream().mapToDouble(planet -> planet.diameter).average().orElse(0)))
397-
.with(planet -> String.format("%.03f", planet.diameter)),
398-
new Column().header("Mass").headerAlign(RIGHT).dataAlign(LEFT)
399-
.footer(String.format("%.02f", planets.stream().mapToDouble(planet -> planet.mass).average().orElse(0)))
400-
.with(planet -> String.format("%.02f", planet.mass)),
401-
new Column().header("Atmosphere").headerAlign(LEFT).dataAlign(CENTER).with(planet -> planet.atmosphere)))
402-
.writeTo(fos);
403-
}
404-
405384
assertParagraphs(OverflowBehaviour.CLIP_RIGHT,
406385
"+------------------+------------------------------+",
407386
"| Long first heade | An even |",
@@ -457,6 +436,24 @@ public void tableWithParagraphsEllipsisRightOverflow() {
457436
"+------------------+------------------------------+");
458437
}
459438

439+
@Test
440+
public void invisibleColumns() {
441+
String[][] data = {{"11", "12", "13", "14"}, {"21", "22"}};
442+
BiConsumer<Boolean[], String[]> asserter = (visibleColumns, expectedRows) -> {
443+
Column[] columns = Arrays.stream(visibleColumns).map(visible -> new Column().visible(visible)).toArray(Column[]::new);
444+
assertEquals(String.join(System.lineSeparator(), expectedRows), AsciiTable.getTable(AsciiTable.NO_BORDERS, columns, data));
445+
};
446+
447+
asserter.accept(new Boolean[]{true, false}, new String[]{" 11 13 14 ", " 21 "});
448+
asserter.accept(new Boolean[]{true, false, true}, new String[]{" 11 13 14 ", " 21 "});
449+
asserter.accept(new Boolean[]{true, false, true, false}, new String[]{" 11 13 ", " 21 "});
450+
asserter.accept(new Boolean[]{false, false, true, false}, new String[]{" 13 ", " "});
451+
asserter.accept(new Boolean[]{}, new String[]{" 11 12 13 14 ", " 21 22 "});
452+
asserter.accept(new Boolean[]{true, true, true, true}, new String[]{" 11 12 13 14 ", " 21 22 "});
453+
asserter.accept(new Boolean[]{true, true, true, true, false}, new String[]{" 11 12 13 14 ", " 21 22 "});
454+
asserter.accept(new Boolean[]{true, true, true, true, true}, new String[]{" 11 12 13 14 ", " 21 22 "});
455+
}
456+
460457
@Test
461458
public void validateNullInHeader() {
462459
String[] headers = {"Lorem", null, "Dolor"};

src/test/java/com/github/freva/asciitable/LineUtilsTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,15 @@
99

1010
public class LineUtilsTest {
1111

12+
@Test
13+
public void ensureTrailingEmptyLineIsReturned() {
14+
assertEquals(Arrays.asList(""),
15+
LineUtils.lines("").collect(Collectors.toList()));
16+
17+
assertEquals(Arrays.asList("", ""),
18+
LineUtils.lines("\n").collect(Collectors.toList()));
19+
}
20+
1221
@Test
1322
public void linesIteratorTest() {
1423
assertEquals(Arrays.asList("", "", "Some text", "", "more text", "text", "end"),

0 commit comments

Comments
 (0)