From 4d7a389942c2e2dbe5b04f0bed9d2de6f6c86528 Mon Sep 17 00:00:00 2001 From: Trilok Jain Date: Mon, 11 Jul 2022 13:30:54 +0530 Subject: [PATCH 1/4] Support for column wrapping --- README.md | 45 +++++++++++++++++++ pom.xml | 4 +- .../com/jakewharton/fliptables/FlipTable.java | 22 ++++++--- 3 files changed, 63 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 524db0d..45035e3 100644 --- a/README.md +++ b/README.md @@ -136,7 +136,52 @@ System.out.println(FlipTableConverters.fromObjects(headers, data)); ╚════════════╧═══════════╧═════╧═════════╝ ``` +Column wrapping (optional) +-------------------------- +**Fixed Table width** +```java +String[] headers = { "First Name", "Last Name", "Details" }; +String[][] data = { + { "One One One One", "Two Two Two:Two", "Three Three.Three,Three" }, + { "Joe", "Smith", "Hello" } +}; +System.out.println(FlipTable.of(headers, data, FixedWidth.withWidth(30))); + +``` +``` +╔════════════╤═══════════╤═════════════╗ +║ First Name │ Last Name │ Details ║ +╠════════════╪═══════════╪═════════════╣ +║ One One │ Two Two │ Three Three ║ +║ One One │ Two:Two │ .Three, ║ +║ │ │ Three ║ +╟────────────┼───────────┼─────────────╢ +║ Joe │ Smith │ Hello ║ +╚════════════╧═══════════╧═════════════╝ +``` + +**Custom Column widths** +```java +String[] headers = { "First", "Last", "Det" }; +String[][] data = { + { "One One One One", "Two Two Two:Two", "Fifteen four on on on on on five" }, + { "Joe", "Boe", "Hello" } +}; +System.out.println(FlipTable.of(headers, data, CustomColumnWidth.withColumnWidths(new int[] {5, 5, 8}))); +``` +``` +╔═══════╤═══════╤══════════╗ +║ First │ Last │ Det ║ +╠═══════╪═══════╪══════════╣ +║ One │ Two │ Fifteen ║ +║ One │ Two │ four on ║ +║ One │ Two: │ on on on ║ +║ One │ Two │ on five ║ +╟───────┼───────┼──────────╢ +║ Joe │ Boe │ Hello ║ +╚═══════╧═══════╧══════════╝ +``` Download -------- diff --git a/pom.xml b/pom.xml index bf1c695..999fe1f 100644 --- a/pom.xml +++ b/pom.xml @@ -68,8 +68,8 @@ maven-compiler-plugin 3.1 - 1.7 - 1.7 + 1.8 + 1.8 diff --git a/src/main/java/com/jakewharton/fliptables/FlipTable.java b/src/main/java/com/jakewharton/fliptables/FlipTable.java index 4407ce3..37ecdd7 100644 --- a/src/main/java/com/jakewharton/fliptables/FlipTable.java +++ b/src/main/java/com/jakewharton/fliptables/FlipTable.java @@ -15,6 +15,10 @@ */ package com.jakewharton.fliptables; +import com.jakewharton.fliptables.format.wrap.ColumnWrapFormat; +import com.jakewharton.fliptables.format.wrap.DefaultWrapFormat; +import com.jakewharton.fliptables.format.wrap.WrappedTableData; + /** *
  * ╔═════════════╤════════════════════════════╤══════════════╗
@@ -30,10 +34,13 @@ public final class FlipTable {
 
   /** Create a new table with the specified headers and row data. */
   public static String of(String[] headers, String[][] data) {
+	  return of(headers, data, new DefaultWrapFormat());
+  }
+  public static String of(String[] headers, String[][] data, ColumnWrapFormat columnWrapFormat) {
     if (headers == null) throw new NullPointerException("headers == null");
     if (headers.length == 0) throw new IllegalArgumentException("Headers must not be empty.");
     if (data == null) throw new NullPointerException("data == null");
-    return new FlipTable(headers, data).toString();
+    return new FlipTable(headers, data, columnWrapFormat).toString();
   }
 
   private final String[] headers;
@@ -42,12 +49,10 @@ public static String of(String[] headers, String[][] data) {
   private final int[] columnWidths;
   private final int emptyWidth;
 
-  private FlipTable(String[] headers, String[][] data) {
-    this.headers = headers;
-    this.data = data;
-
+  private FlipTable(String[] headers, String[][] data, ColumnWrapFormat columnWrapFormat) {
+    
     columns = headers.length;
-    columnWidths = new int[columns];
+    int[] columnWidths = new int[columns];
     for (int row = -1; row < data.length; row++) {
       String[] rowData = (row == -1) ? headers : data[row]; // Hack to parse headers too.
       if (rowData.length != columns) {
@@ -61,6 +66,11 @@ private FlipTable(String[] headers, String[][] data) {
         }
       }
     }
+    
+    WrappedTableData wrappedTableData = columnWrapFormat.adjustData(headers, data, columnWidths);
+    this.headers = wrappedTableData.getHeaders();
+    this.data = wrappedTableData.getData();
+    this.columnWidths = wrappedTableData.getColumnWidths();
 
     int emptyWidth = 3 * (columns - 1); // Account for column dividers and their spacing.
     for (int columnWidth : columnWidths) {

From 7ef6e789207d445e3baa3d189e8569bf9da39714 Mon Sep 17 00:00:00 2001
From: Trilok Jain 
Date: Mon, 11 Jul 2022 13:36:27 +0530
Subject: [PATCH 2/4] Support for column wrapping

---
 .classpath                                    | 27 +++++++++
 .project                                      | 23 ++++++++
 .settings/org.eclipse.core.resources.prefs    |  4 ++
 .settings/org.eclipse.jdt.core.prefs          |  8 +++
 .settings/org.eclipse.m2e.core.prefs          |  4 ++
 .../format/wrap/ColumnWrapFormat.java         | 53 +++++++++++++++++
 .../format/wrap/CustomColumnWidth.java        | 31 ++++++++++
 .../format/wrap/DefaultWrapFormat.java        |  9 +++
 .../fliptables/format/wrap/FixedWidth.java    | 43 ++++++++++++++
 .../format/wrap/WrappedTableData.java         | 30 ++++++++++
 .../format/wrap/ColumnWrapTest.java           | 58 +++++++++++++++++++
 .../fliptables/util/ResourceReader.java       | 26 +++++++++
 src/test/resources/custom-width-wrapping.txt  | 27 +++++++++
 src/test/resources/fixed-width-wrapping.txt   | 21 +++++++
 14 files changed, 364 insertions(+)
 create mode 100644 .classpath
 create mode 100644 .project
 create mode 100644 .settings/org.eclipse.core.resources.prefs
 create mode 100644 .settings/org.eclipse.jdt.core.prefs
 create mode 100644 .settings/org.eclipse.m2e.core.prefs
 create mode 100644 src/main/java/com/jakewharton/fliptables/format/wrap/ColumnWrapFormat.java
 create mode 100644 src/main/java/com/jakewharton/fliptables/format/wrap/CustomColumnWidth.java
 create mode 100644 src/main/java/com/jakewharton/fliptables/format/wrap/DefaultWrapFormat.java
 create mode 100644 src/main/java/com/jakewharton/fliptables/format/wrap/FixedWidth.java
 create mode 100644 src/main/java/com/jakewharton/fliptables/format/wrap/WrappedTableData.java
 create mode 100644 src/test/java/com/jakewharton/fliptables/format/wrap/ColumnWrapTest.java
 create mode 100644 src/test/java/com/jakewharton/fliptables/util/ResourceReader.java
 create mode 100644 src/test/resources/custom-width-wrapping.txt
 create mode 100644 src/test/resources/fixed-width-wrapping.txt

diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..5e8a55f
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,27 @@
+
+
+	
+		
+			
+			
+		
+	
+	
+		
+			
+			
+			
+		
+	
+	
+		
+			
+		
+	
+	
+		
+			
+		
+	
+	
+
diff --git a/.project b/.project
new file mode 100644
index 0000000..f677f32
--- /dev/null
+++ b/.project
@@ -0,0 +1,23 @@
+
+
+	fliptables
+	
+	
+	
+	
+		
+			org.eclipse.jdt.core.javabuilder
+			
+			
+		
+		
+			org.eclipse.m2e.core.maven2Builder
+			
+			
+		
+	
+	
+		org.eclipse.jdt.core.javanature
+		org.eclipse.m2e.core.maven2Nature
+	
+
diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..f9fe345
--- /dev/null
+++ b/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,4 @@
+eclipse.preferences.version=1
+encoding//src/main/java=UTF-8
+encoding//src/test/java=UTF-8
+encoding/=UTF-8
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..2f5cc74
--- /dev/null
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
+org.eclipse.jdt.core.compiler.release=disabled
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..f897a7f
--- /dev/null
+++ b/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/src/main/java/com/jakewharton/fliptables/format/wrap/ColumnWrapFormat.java b/src/main/java/com/jakewharton/fliptables/format/wrap/ColumnWrapFormat.java
new file mode 100644
index 0000000..555a68b
--- /dev/null
+++ b/src/main/java/com/jakewharton/fliptables/format/wrap/ColumnWrapFormat.java
@@ -0,0 +1,53 @@
+package com.jakewharton.fliptables.format.wrap;
+
+/**
+ * Provides a mechanism to wrap the text of the columns.
+ * Line breaks are added to break long texts without breaking the words
+ */
+public abstract class ColumnWrapFormat {
+	
+	private static final String SPLITTER_REGEX = "((?=:|,|\\.|\\s)|(?<=:|,|\\.|\\s))";
+	private static final String LINE_BREAK = "\n";
+	
+	public abstract WrappedTableData adjustData(String[] headers, String[][] data, int[] columnWidths);
+	
+	protected String[][] adjustedData(String[][] data, int[] adjustedWidths) {
+		String[][] adjustedData = new String[data.length][adjustedWidths.length];
+		for(int row = 0; row < data.length; row++) {
+			for(int col = 0; col < adjustedWidths.length; col++) {
+				adjustedData[row][col] = adjustFieldData(data[row][col], adjustedWidths[col]);
+			}
+		}
+		return adjustedData;
+	}
+	
+	protected String adjustFieldData(String field, int desiredWidth) {
+		if(null == field || field.isEmpty() || field.length() <= desiredWidth) {
+			return field;
+		}
+		return withLineBreaks(field, desiredWidth);
+	}
+	
+	/**
+	 * Adds line breaks on maxLineLength boundaries without breaking the words
+	 */
+	private String withLineBreaks(String input, int maxLineLength) {
+		String[] components = input.split(SPLITTER_REGEX);
+		StringBuilder builder = new StringBuilder();
+		int lineLength = 0, iterator = 0;
+		do {
+			String component = components[iterator]; 
+			if(lineLength == 0 || (lineLength + component.length() <= maxLineLength)) {
+				builder.append(component);
+				lineLength += component.length();
+				iterator++;
+			}
+			else {
+				builder.append(LINE_BREAK);
+				lineLength = 0;
+			}
+		} while(iterator < components.length);
+		
+		return builder.toString();
+	}
+}
diff --git a/src/main/java/com/jakewharton/fliptables/format/wrap/CustomColumnWidth.java b/src/main/java/com/jakewharton/fliptables/format/wrap/CustomColumnWidth.java
new file mode 100644
index 0000000..bed8b72
--- /dev/null
+++ b/src/main/java/com/jakewharton/fliptables/format/wrap/CustomColumnWidth.java
@@ -0,0 +1,31 @@
+package com.jakewharton.fliptables.format.wrap;
+
+/**
+ * Adjusting the columns of the table to the user provided column widths
+ * A column is never made narrower than the length of the header
+ */
+public class CustomColumnWidth extends ColumnWrapFormat {
+	
+	private int[] desiredColumnWidths;
+	
+	public static CustomColumnWidth withColumnWidths(int[] desiredColumnWidths) {
+		return new CustomColumnWidth(desiredColumnWidths);
+	}
+	
+	private CustomColumnWidth(int[] desiredColumnWidths) {
+		this.desiredColumnWidths = desiredColumnWidths;
+	}
+	
+	@Override
+	public WrappedTableData adjustData(String[] headers, String[][] data, int[] columnWidths) {
+		if (desiredColumnWidths.length != headers.length) {
+			throw new IllegalArgumentException("Length of the array of the desired columns does not match the number of columns");
+		}
+		
+		int[] adjustedWidths = new int[columnWidths.length];
+		for(int col = 0; col < columnWidths.length; col++) {
+			adjustedWidths[col] = Math.max(headers[col].length(), desiredColumnWidths[col]);
+		}
+		return new WrappedTableData(headers, adjustedData(data, adjustedWidths), adjustedWidths);
+	}
+}
diff --git a/src/main/java/com/jakewharton/fliptables/format/wrap/DefaultWrapFormat.java b/src/main/java/com/jakewharton/fliptables/format/wrap/DefaultWrapFormat.java
new file mode 100644
index 0000000..cdd5d59
--- /dev/null
+++ b/src/main/java/com/jakewharton/fliptables/format/wrap/DefaultWrapFormat.java
@@ -0,0 +1,9 @@
+package com.jakewharton.fliptables.format.wrap;
+
+public class DefaultWrapFormat extends ColumnWrapFormat {
+
+	@Override
+	public WrappedTableData adjustData(String[] headers, String[][] data, int[] columnWidths) {
+		return new WrappedTableData(headers, data, columnWidths);
+	}
+}
diff --git a/src/main/java/com/jakewharton/fliptables/format/wrap/FixedWidth.java b/src/main/java/com/jakewharton/fliptables/format/wrap/FixedWidth.java
new file mode 100644
index 0000000..afd042e
--- /dev/null
+++ b/src/main/java/com/jakewharton/fliptables/format/wrap/FixedWidth.java
@@ -0,0 +1,43 @@
+package com.jakewharton.fliptables.format.wrap;
+
+import java.util.Arrays;
+
+/**
+ * Reduces the individual column widths proportional to the table width.
+ * A column is never made narrower than the length of the header
+ */
+public class FixedWidth extends ColumnWrapFormat {
+	
+	private int maxWidth;
+	
+	public static FixedWidth withWidth(int tableWidth) {
+		return new FixedWidth(tableWidth);
+	}
+	
+	private FixedWidth(int width) {
+		this.maxWidth = width;
+	}
+	
+	@Override
+	public WrappedTableData adjustData(String[] headers, String[][] data, int[] columnWidths) {
+		int currentLength = Arrays.stream(columnWidths).sum();
+		double ratio = maxWidth / (1.0 * currentLength);
+		if(ratio > 1.0d) {
+			return new WrappedTableData(headers, data, columnWidths);
+		}
+		int[] adjustedWidths = adjustedColumnWidths(headers, columnWidths, ratio);
+		return new WrappedTableData(headers, adjustedData(data, adjustedWidths), adjustedWidths);
+	}
+	
+	private int[] adjustedColumnWidths(String headers[], int[] columnWidths, double ratio) {
+		int[] adjustedWidths = headers.length == 1 ?  new int[] { maxWidth }: new int[headers.length];
+		int index = 0, sum = 0;
+		for(; index < headers.length - 1; index++) {
+			adjustedWidths[index] = Math.max((int) (ratio * columnWidths[index]), headers[index].length());
+			sum += adjustedWidths[index];
+		}
+		adjustedWidths[index] = Math.max(maxWidth - sum, headers[index].length());
+		return adjustedWidths;
+	}
+
+}
diff --git a/src/main/java/com/jakewharton/fliptables/format/wrap/WrappedTableData.java b/src/main/java/com/jakewharton/fliptables/format/wrap/WrappedTableData.java
new file mode 100644
index 0000000..ee91c12
--- /dev/null
+++ b/src/main/java/com/jakewharton/fliptables/format/wrap/WrappedTableData.java
@@ -0,0 +1,30 @@
+package com.jakewharton.fliptables.format.wrap;
+
+/**
+ * Class to hold the adjusted (wrapped) data out
+ */
+public class WrappedTableData {
+	String[] headers;
+	String[][] data;
+	int[] columnWidths;
+	
+	public WrappedTableData() {}
+	
+	public WrappedTableData(String[] headers, String[][] data, int[] columnWidths) {
+		this.headers = headers;
+		this.data = data;
+		this.columnWidths = columnWidths;
+	}
+	
+	public String[] getHeaders() {
+		return this.headers;
+	}
+	
+	public String[][] getData() {
+		return this.data;
+	}
+	
+	public int[] getColumnWidths() {
+		return this.columnWidths;
+	}
+}
diff --git a/src/test/java/com/jakewharton/fliptables/format/wrap/ColumnWrapTest.java b/src/test/java/com/jakewharton/fliptables/format/wrap/ColumnWrapTest.java
new file mode 100644
index 0000000..57d3d66
--- /dev/null
+++ b/src/test/java/com/jakewharton/fliptables/format/wrap/ColumnWrapTest.java
@@ -0,0 +1,58 @@
+package com.jakewharton.fliptables.format.wrap;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.IOException;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import org.junit.Test;
+
+import com.jakewharton.fliptables.FlipTable;
+import com.jakewharton.fliptables.util.ResourceReader;
+
+public class ColumnWrapTest {
+	
+	private String[] headers = new String[] {"Feather", "Weather", "Fizz", "Buzz"};
+	private String[][] data = new String[3][headers.length];
+	
+	public ColumnWrapTest() {
+		for(int idx = 0; idx < 3; idx++) {
+			data[idx][0] = columnData("a", 6,  10);
+			data[idx][1] = columnData("b", 6,  5);
+			data[idx][2] = columnData("c", 6,  15);
+			data[idx][3] = columnData("d", 6,  25);
+		}
+		data[1][2] = "some long words somelongwords somelongerwords someevenlongerwords someevenmorelongerwords";
+	}
+	
+	private static String columnData(String base, int wordSize, int words) {
+		return IntStream.range(0, words)
+			.mapToObj(wordIndex -> IntStream.range(0, wordSize).mapToObj(charIndex -> base).collect(Collectors.joining()))
+			.collect(Collectors.joining(" "));
+	}
+	
+	@Test
+	public void testFixedWidthWrapping() throws IOException {
+		String read = ResourceReader.readFromResourceFile("fixed-width-wrapping.txt");
+		String flipTable = FlipTable.of(headers, data, FixedWidth.withWidth(120));
+		assertThat(flipTable).isEqualTo(read);
+	}
+	
+	@Test
+	public void testCustomWidthWrapping() throws IOException {
+		String read = ResourceReader.readFromResourceFile("custom-width-wrapping.txt");
+		String flipTable = FlipTable.of(headers, data, CustomColumnWidth.withColumnWidths(new int[] {30, 30, 30, 30}));
+		assertThat(flipTable).isEqualTo(read);
+	}
+	
+	public static void main(String args[]) {
+		String[] headers = { "First", "Last", "Det" };
+		String[][] data = {
+		    { "One One One One", "Two Two Two:Two", "Fifteen four on on on on on five" },
+		    { "Joe", "Boe", "Hello" }
+		};
+		System.out.println(FlipTable.of(headers, data, CustomColumnWidth.withColumnWidths(new int[] {5, 5, 8})));
+	}
+
+}
diff --git a/src/test/java/com/jakewharton/fliptables/util/ResourceReader.java b/src/test/java/com/jakewharton/fliptables/util/ResourceReader.java
new file mode 100644
index 0000000..64193ab
--- /dev/null
+++ b/src/test/java/com/jakewharton/fliptables/util/ResourceReader.java
@@ -0,0 +1,26 @@
+package com.jakewharton.fliptables.util;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+
+public class ResourceReader {
+	
+	public static String readFromResourceFile(String filePath) throws IOException {
+		
+		try(InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(filePath)) {
+		    StringBuilder textBuilder = new StringBuilder();
+		    try (Reader reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName(StandardCharsets.UTF_8.name())))) {
+		        int c = 0;
+		        while ((c = reader.read()) != -1) {
+		            textBuilder.append((char) c);
+		        }
+		    }
+		    return textBuilder.toString();
+		}
+	}
+}
diff --git a/src/test/resources/custom-width-wrapping.txt b/src/test/resources/custom-width-wrapping.txt
new file mode 100644
index 0000000..7f7055d
--- /dev/null
+++ b/src/test/resources/custom-width-wrapping.txt
@@ -0,0 +1,27 @@
+╔════════════════════════════════╤════════════════════════════════╤════════════════════════════════╤════════════════════════════════╗
+║ Feather                        │ Weather                        │ Fizz                           │ Buzz                           ║
+╠════════════════════════════════╪════════════════════════════════╪════════════════════════════════╪════════════════════════════════╣
+║ aaaaaa aaaaaa aaaaaa aaaaaa    │ bbbbbb bbbbbb bbbbbb bbbbbb    │ cccccc cccccc cccccc cccccc    │ dddddd dddddd dddddd dddddd    ║
+║ aaaaaa aaaaaa aaaaaa aaaaaa    │ bbbbbb                         │ cccccc cccccc cccccc cccccc    │ dddddd dddddd dddddd dddddd    ║
+║ aaaaaa aaaaaa                  │                                │ cccccc cccccc cccccc cccccc    │ dddddd dddddd dddddd dddddd    ║
+║                                │                                │ cccccc cccccc cccccc           │ dddddd dddddd dddddd dddddd    ║
+║                                │                                │                                │ dddddd dddddd dddddd dddddd    ║
+║                                │                                │                                │ dddddd dddddd dddddd dddddd    ║
+║                                │                                │                                │ dddddd                         ║
+╟────────────────────────────────┼────────────────────────────────┼────────────────────────────────┼────────────────────────────────╢
+║ aaaaaa aaaaaa aaaaaa aaaaaa    │ bbbbbb bbbbbb bbbbbb bbbbbb    │ some long words somelongwords  │ dddddd dddddd dddddd dddddd    ║
+║ aaaaaa aaaaaa aaaaaa aaaaaa    │ bbbbbb                         │ somelongerwords                │ dddddd dddddd dddddd dddddd    ║
+║ aaaaaa aaaaaa                  │                                │ someevenlongerwords            │ dddddd dddddd dddddd dddddd    ║
+║                                │                                │ someevenmorelongerwords        │ dddddd dddddd dddddd dddddd    ║
+║                                │                                │                                │ dddddd dddddd dddddd dddddd    ║
+║                                │                                │                                │ dddddd dddddd dddddd dddddd    ║
+║                                │                                │                                │ dddddd                         ║
+╟────────────────────────────────┼────────────────────────────────┼────────────────────────────────┼────────────────────────────────╢
+║ aaaaaa aaaaaa aaaaaa aaaaaa    │ bbbbbb bbbbbb bbbbbb bbbbbb    │ cccccc cccccc cccccc cccccc    │ dddddd dddddd dddddd dddddd    ║
+║ aaaaaa aaaaaa aaaaaa aaaaaa    │ bbbbbb                         │ cccccc cccccc cccccc cccccc    │ dddddd dddddd dddddd dddddd    ║
+║ aaaaaa aaaaaa                  │                                │ cccccc cccccc cccccc cccccc    │ dddddd dddddd dddddd dddddd    ║
+║                                │                                │ cccccc cccccc cccccc           │ dddddd dddddd dddddd dddddd    ║
+║                                │                                │                                │ dddddd dddddd dddddd dddddd    ║
+║                                │                                │                                │ dddddd dddddd dddddd dddddd    ║
+║                                │                                │                                │ dddddd                         ║
+╚════════════════════════════════╧════════════════════════════════╧════════════════════════════════╧════════════════════════════════╝
diff --git a/src/test/resources/fixed-width-wrapping.txt b/src/test/resources/fixed-width-wrapping.txt
new file mode 100644
index 0000000..611c55e
--- /dev/null
+++ b/src/test/resources/fixed-width-wrapping.txt
@@ -0,0 +1,21 @@
+╔═══════════════════════╤════════════╤══════════════════════════════════╤═══════════════════════════════════════════════════════════╗
+║ Feather               │ Weather    │ Fizz                             │ Buzz                                                      ║
+╠═══════════════════════╪════════════╪══════════════════════════════════╪═══════════════════════════════════════════════════════════╣
+║ aaaaaa aaaaaa aaaaaa  │ bbbbbb     │ cccccc cccccc cccccc cccccc      │ dddddd dddddd dddddd dddddd dddddd dddddd dddddd dddddd   ║
+║ aaaaaa aaaaaa aaaaaa  │ bbbbbb     │ cccccc cccccc cccccc cccccc      │ dddddd dddddd dddddd dddddd dddddd dddddd dddddd dddddd   ║
+║ aaaaaa aaaaaa aaaaaa  │ bbbbbb     │ cccccc cccccc cccccc cccccc      │ dddddd dddddd dddddd dddddd dddddd dddddd dddddd dddddd   ║
+║ aaaaaa                │ bbbbbb     │ cccccc cccccc cccccc             │ dddddd                                                    ║
+║                       │ bbbbbb     │                                  │                                                           ║
+╟───────────────────────┼────────────┼──────────────────────────────────┼───────────────────────────────────────────────────────────╢
+║ aaaaaa aaaaaa aaaaaa  │ bbbbbb     │ some long words somelongwords    │ dddddd dddddd dddddd dddddd dddddd dddddd dddddd dddddd   ║
+║ aaaaaa aaaaaa aaaaaa  │ bbbbbb     │ somelongerwords                  │ dddddd dddddd dddddd dddddd dddddd dddddd dddddd dddddd   ║
+║ aaaaaa aaaaaa aaaaaa  │ bbbbbb     │ someevenlongerwords              │ dddddd dddddd dddddd dddddd dddddd dddddd dddddd dddddd   ║
+║ aaaaaa                │ bbbbbb     │ someevenmorelongerwords          │ dddddd                                                    ║
+║                       │ bbbbbb     │                                  │                                                           ║
+╟───────────────────────┼────────────┼──────────────────────────────────┼───────────────────────────────────────────────────────────╢
+║ aaaaaa aaaaaa aaaaaa  │ bbbbbb     │ cccccc cccccc cccccc cccccc      │ dddddd dddddd dddddd dddddd dddddd dddddd dddddd dddddd   ║
+║ aaaaaa aaaaaa aaaaaa  │ bbbbbb     │ cccccc cccccc cccccc cccccc      │ dddddd dddddd dddddd dddddd dddddd dddddd dddddd dddddd   ║
+║ aaaaaa aaaaaa aaaaaa  │ bbbbbb     │ cccccc cccccc cccccc cccccc      │ dddddd dddddd dddddd dddddd dddddd dddddd dddddd dddddd   ║
+║ aaaaaa                │ bbbbbb     │ cccccc cccccc cccccc             │ dddddd                                                    ║
+║                       │ bbbbbb     │                                  │                                                           ║
+╚═══════════════════════╧════════════╧══════════════════════════════════╧═══════════════════════════════════════════════════════════╝

From 79e719c2f61b85317ddc01c12f518532179fba5b Mon Sep 17 00:00:00 2001
From: Trilok Jain 
Date: Mon, 11 Jul 2022 13:37:54 +0530
Subject: [PATCH 3/4] Support for column wrapping

---
 .gitignore | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/.gitignore b/.gitignore
index 469f38c..25e521e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,7 @@ target
 
 pom.xml.*
 release.properties
+
+.settings/
+.project/
+.classpath/

From 44bd607eeb94cf1a4efb02ec5b8dabb60579b2a3 Mon Sep 17 00:00:00 2001
From: Trilok Jain 
Date: Mon, 11 Jul 2022 13:40:31 +0530
Subject: [PATCH 4/4] Support for column wrapping

---
 .classpath                                 | 27 ----------------------
 .project                                   | 23 ------------------
 .settings/org.eclipse.core.resources.prefs |  4 ----
 .settings/org.eclipse.jdt.core.prefs       |  8 -------
 .settings/org.eclipse.m2e.core.prefs       |  4 ----
 5 files changed, 66 deletions(-)
 delete mode 100644 .classpath
 delete mode 100644 .project
 delete mode 100644 .settings/org.eclipse.core.resources.prefs
 delete mode 100644 .settings/org.eclipse.jdt.core.prefs
 delete mode 100644 .settings/org.eclipse.m2e.core.prefs

diff --git a/.classpath b/.classpath
deleted file mode 100644
index 5e8a55f..0000000
--- a/.classpath
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-	
-		
-			
-			
-		
-	
-	
-		
-			
-			
-			
-		
-	
-	
-		
-			
-		
-	
-	
-		
-			
-		
-	
-	
-
diff --git a/.project b/.project
deleted file mode 100644
index f677f32..0000000
--- a/.project
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-	fliptables
-	
-	
-	
-	
-		
-			org.eclipse.jdt.core.javabuilder
-			
-			
-		
-		
-			org.eclipse.m2e.core.maven2Builder
-			
-			
-		
-	
-	
-		org.eclipse.jdt.core.javanature
-		org.eclipse.m2e.core.maven2Nature
-	
-
diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index f9fe345..0000000
--- a/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,4 +0,0 @@
-eclipse.preferences.version=1
-encoding//src/main/java=UTF-8
-encoding//src/test/java=UTF-8
-encoding/=UTF-8
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index 2f5cc74..0000000
--- a/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,8 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
-org.eclipse.jdt.core.compiler.compliance=1.8
-org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
-org.eclipse.jdt.core.compiler.release=disabled
-org.eclipse.jdt.core.compiler.source=1.8
diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs
deleted file mode 100644
index f897a7f..0000000
--- a/.settings/org.eclipse.m2e.core.prefs
+++ /dev/null
@@ -1,4 +0,0 @@
-activeProfiles=
-eclipse.preferences.version=1
-resolveWorkspaceProjects=true
-version=1