Repository: zhiburt/tabled
Pull request #299 (2023-03-07 17:22:58)

Split setting
Split checklist:
- [x] code
- [x] tests (please add more as you see fit 😄)
- [x] comments
- [X] example `examples/split.rs`
- [x] readme
- [x] examples/readme

Please give this a spin and let me know what you think. I'm always happy to make any necessary changes to get this right 😄 

---

Also, #290 describes extending this feature to the builder as well. This PR is only related to the setting implementation. If you like how it works I can look at updating the builder next, or it can be a ticket for other contributors to pick up. Who knows!


Patch:
diff --git a/README.md b/README.md
index 7f2fc1e..c2b75f0 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
 [<img alt="github" src="https://img.shields.io/badge/github-zhiburt/tabled-8da0cb?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/zhiburt/tabled/)
 [<img alt="crates.io" src="https://img.shields.io/crates/v/tabled.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/tabled)
 [<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-tabled-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs" height="20">](https://docs.rs/tabled)
-[<img alt="build status" src="https://img.shields.io/github/workflow/status/zhiburt/tabled/Continuous%20integration/master?style=for-the-badge" height="20">](https://github.com/zhiburt/tabled/actions)
+[<img alt="build status" src="https://img.shields.io/github/actions/workflow/status/zhiburt/tabled/ci.yml?branch=master&style=for-the-badge" height="20">](https://github.com/zhiburt/tabled/actions)
 [<img alt="coverage" src="https://img.shields.io/coveralls/github/zhiburt/tabled/master?style=for-the-badge" height="20">](https://coveralls.io/github/zhiburt/tabled)
 [<img alt="dependency status" src="https://deps.rs/repo/github/zhiburt/tabled/status.svg?style=for-the-badge" height="20">](https://deps.rs/repo/github/zhiburt/tabled)
 
@@ -64,6 +64,10 @@ An easy to use library for pretty printing tables of Rust `struct`s and `enum`s.
   - [Span](#span)
     - [Horizontal span](#horizontal-span)
     - [Vertical span](#vertical-span)
+  - [Split](#split)
+    - [Directions](#directions)
+    - [Behaviors](#behaviors)
+    - [Displays](#displays)
 - [Derive](#derive)
   - [Override a column name](#override-a-column-name)
   - [Hide a column](#hide-a-column)
@@ -1059,6 +1063,130 @@ println!("{}", table);
 +---+---+---+
 ```
 
+### Split
+
+You can `Split` a table on a row or column to redistribute the cells beyond that point 
+into a new shape with the provided point acting as the new, upper boundry in the direction selected.
+
+#### Directions
+
+Direction functions are the entry point for the `Split` setting.
+
+There are two directions available: `column` and `row`.
+
+```rust
+use std::iter::FromIterator;
+use tabled::{Table, settings::split::Split};
+
+let mut table = Table::from_iter(['a'..='z']);
+table.with(Split::column(12));
+table.with(Split::row(2));
+```
+
+```text
+┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
+│ a │ b │ c │ d │ e │ f │ g │ h │ i │ j │ k │ l │ m │ n │ o │ p │ q │ r │ s │ t │ u │ v │ w │ x │ y │ z │
+└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
+┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
+│ a │ b │ c │ d │ e │ f │ g │ h │ i │ j │ k │ l │
+├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
+│ m │ n │ o │ p │ q │ r │ s │ t │ u │ v │ w │ x │
+├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
+│ y │ z │   │   │   │   │   │   │   │   │   │   │<- y and z act as anchors to new empty cells
+└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘   to conform to the new shape
+┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
+│ a │ y │ b │ z │ c │ d │ e │ f │ g │ h │ i │ j │ k │ l │
+├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤<- Display::Clean removes empty cells that would be anchors otherwise
+│ m │   │ n │   │ o │ p │ q │ r │ s │ t │ u │ v │ w │ x │
+└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
+      ^anchors^
+```
+
+
+#### Behaviors
+
+Behaviors determine how cells attempt to conform to the new tables shape.
+
+There are two behaviors available: `zip` and `concat`. 
+
+`zip` is the default behavior.
+
+```rust
+use tabled::{Table, settings::split::Split};
+
+let mut table = Table::new(&data);
+
+table.with(Split::column(2).concat());
+table.with(Split::column(2).zip());
+```
+
+```text
+                                                +---+---+
+                                                | a | b |
+                                                +---+---+
++---+---+---+---+---+                           | f | g |
+| a | b | c | d | e | Split::column(2).concat() +---+---+
++---+---+---+---+---+           =>              | c | d |
+| f | g | h | i | j |                           +---+---+
++---+---+---+---+---+                           | h | i |
+                                                +---+---+
+                                                | e |   |
+                                                +---+---+
+                                                | j |   |
+                                                +---+---+
+
+                  sect 3                        +---+---+
+ sect 1   sect 2 (anchors)                      | a | b |
+  /   \   /   \   /   \                         +---+---+
++---+---+---+---+---+                           | c | d |
+| a | b | c | d | e |  Split::column(2).zip()   +---+---+
++---+---+---+---+---+           =>              | e |   |
+| f | g | h | i | j |                           +---+---+
++---+---+---+---+---+                           | f | g |
+                                                +---+---+
+                                                | h | i |
+                                                +---+---+
+                                                | j |   |
+                                                +---+---+
+```
+
+#### Displays
+
+Display functions give the user the choice to `retain` or `clean` empty sections in a `Split` table result.
+
+- `retain` does not filter any existing or newly added cells when conforming to a new shape.
+
+- `clean` filters out empty columns/rows from the output and prevents empty cells from acting as anchors to newly inserted cells.
+
+`clean` is the default `Display`.
+
+```rust
+use std::iter::FromIterator;
+use tabled::{
+    settings::{split::Split, style::Style},
+    Table,
+};
+let mut table = Table::from_iter(['a'..='z']);
+
+table.with(Split::column(25)).with(Style::modern());
+table.clone().with(Split::column(1).concat().retain());
+table.clone().with(Split::column(1).concat()); // .clean() is not necessary as it is the default display property 
+```
+
+```text
+┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
+│ a │ b │ c │ d │ e │ f │ g │ h │ i │ j │ k │ l │ m │ n │ o │ p │ q │ r │ s │ t │ u │ v │ w │ x │ y │
+├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
+│ z │   │   │   │   │   │   │   │   │   │   │   │   │   │   │   │   │   │   │   │   │   │   │   │   │<- lots of extra cells generated
+└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
+┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
+│ a │ b │ c │ d │ e │ f │ g │ h │ i │ j │ k │ l │ m │ n │ o │ p │ q │ r │ s │ t │ u │ v │ w │ x │ y │ z │  │  │  │  │  │  │  │  │  │  │  │  │  │  │  │  │  │  │  │  │  │  │  │  │
+└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
+┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ ^ cells retained during concatenation
+│ a │ b │ c │ d │ e │ f │ g │ h │ i │ j │ k │ l │ m │ n │ o │ p │ q │ r │ s │ t │ u │ v │ w │ x │ y │ z │
+└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘<- cells removed during concatenation
+```
+
 ## Derive
 
 To be able to use a `Tabled` macros each field must implement `std::fmt::Display`
@@ -1358,8 +1486,24 @@ println!("{}", table);
 
 ### Color
 
-The library doesn't bind you in usage of any color library but to be able to work correctly with color input you should
-add the `color` feature of `tabled` to your `Cargo.toml`
+The library doesn't bind you in usage of any color library but to be able to work correctly with color input, and avoid [miscalculation of string width](https://github.com/zhiburt/tabled/issues/26) because of embedded ansi sequences, you should add the `color` feature of `tabled` to your `Cargo.toml`:
+
+```toml
+tabled = { version = "*", features = ["color"] } 
+```
+
+Then you can use colored strings as values:
+
+```rust
+use owo_colors::OwoColorize;
+// ...
+let mut builder = tabled::builder::Builder::default();
+builder.add_record(vec!["green".green(), "red".red()])
+let mut table = builder.build();
+table.with(tabled::Style::rounded());
+```
+
+Another example:
 
 ```rust
 use tabled::{format::Format, object::Columns, Modify, Style, Table};
diff --git a/papergrid/examples/color_map.rs b/papergrid/examples/color_map.rs
index 7057b4b..7e9b2da 100644
--- a/papergrid/examples/color_map.rs
+++ b/papergrid/examples/color_map.rs
@@ -33,7 +33,7 @@ fn main() {
 
     let colors = generate_colors();
 
-    let grid = Grid::new(records, &dimension, &cfg).with_colors(colors);
+    let grid = Grid::new(records, &dimension, &cfg, &colors);
 
     grid.build(UTF8Stdout(std::io::stdout())).unwrap();
     println!();
diff --git a/papergrid/examples/colored_border.rs b/papergrid/examples/colored_border.rs
index d0525b2..6e2c010 100644
--- a/papergrid/examples/colored_border.rs
+++ b/papergrid/examples/colored_border.rs
@@ -5,6 +5,7 @@
 
 use papergrid::{
     color::AnsiColor,
+    colors::NoColors,
     config::{AlignmentHorizontal, AlignmentVertical, Borders, Entity::Global, Indent, Sides},
     dimension::Estimate,
     grid::spanned::{config::GridConfig, dimension::ExactDimension, Grid},
@@ -23,7 +24,7 @@ fn main() {
     let mut dim = ExactDimension::default();
     dim.estimate(&records, &cfg);
 
-    let grid = Grid::new(records, &dim, &cfg).to_string();
+    let grid = Grid::new(records, &dim, &cfg, NoColors).to_string();
 
     println!("{grid}");
 }
diff --git a/papergrid/examples/hello_world.rs b/papergrid/examples/hello_world.rs
index ec4457f..77d968a 100644
--- a/papergrid/examples/hello_world.rs
+++ b/papergrid/examples/hello_world.rs
@@ -2,6 +2,7 @@
 //! `cargo run --example hello_world`
 
 use papergrid::{
+    colors::NoColors,
     config::{AlignmentHorizontal, AlignmentVertical, Borders, Entity::Global, Indent, Sides},
     dimension::Estimate,
     grid::spanned::{dimension::ExactDimension, Grid, GridConfig},
@@ -20,7 +21,7 @@ fn main() {
     let mut dim = ExactDimension::default();
     dim.estimate(records, &cfg);
 
-    let grid = Grid::new(records, &dim, &cfg).to_string();
+    let grid = Grid::new(records, &dim, &cfg, NoColors).to_string();
 
     println!("{grid}");
 }
diff --git a/papergrid/examples/papergrid_color.rs b/papergrid/examples/papergrid_color.rs
index 8f9b86a..f82e497 100644
--- a/papergrid/examples/papergrid_color.rs
+++ b/papergrid/examples/papergrid_color.rs
@@ -6,6 +6,7 @@
 use std::io::Write;
 
 use papergrid::{
+    colors::NoColors,
     config::Borders,
     dimension::Estimate,
     grid::spanned::{ExactDimension, Grid, GridConfig},
@@ -24,7 +25,7 @@ fn main() {
     let mut dimension = ExactDimension::default();
     dimension.estimate(&records, &cfg);
 
-    let grid = Grid::new(&records, &dimension, &cfg);
+    let grid = Grid::new(&records, &dimension, &cfg, NoColors);
 
     grid.build(UTF8Stdout(std::io::stdout())).unwrap();
     println!();
diff --git a/papergrid/src/grid/spanned/config/mod.rs b/papergrid/src/grid/spanned/config/mod.rs
index ac18c7f..a792374 100644
--- a/papergrid/src/grid/spanned/config/mod.rs
+++ b/papergrid/src/grid/spanned/config/mod.rs
@@ -57,36 +57,6 @@ impl Default for GridConfig {
 }
 
 impl GridConfig {
-    /// Set a column span to a given cells.
-    ///
-    /// BEWARE
-    ///
-    /// IT'S CALLER RESPONSIBILITY TO MAKE SURE
-    /// THAT THERE NO INTERSECTIONS IN PLACE AND THE SPAN VALUE IS CORRECT
-    pub fn set_column_span(&mut self, pos: Position, span: usize) {
-        set_cell_column_span(self, pos, span);
-    }
-
-    /// Verifies if there's any spans set.
-    pub fn has_column_spans(&self) -> bool {
-        !self.span_columns.is_empty()
-    }
-
-    /// Set a column span to a given cells.
-    ///
-    /// BEWARE
-    ///
-    /// IT'S CALLER RESPONSIBILITY TO MAKE SURE
-    /// THAT THERE NO INTERSECTIONS IN PLACE AND THE SPAN VALUE IS CORRECT
-    pub fn set_row_span(&mut self, pos: Position, span: usize) {
-        set_cell_row_span(self, pos, span);
-    }
-
-    /// Verifies if there's any spans set.
-    pub fn has_row_spans(&self) -> bool {
-        !self.span_rows.is_empty()
-    }
-
     /// Returns a [`Margin`] value currently set.
     pub fn get_margin(&self) -> &Sides<ColoredMarginIndent> {
         &self.margin
@@ -385,50 +355,80 @@ impl GridConfig {
         self.border_colors.insert_border(pos, border)
     }
 
+    /// Sets off all borders possible on the [`Entity`].
+    ///
+    /// It doesn't changes globally set borders through [`GridConfig::set_borders`].
+    //
+    // todo: would be great to remove a shape
+    pub fn remove_border(&mut self, pos: Position, shape: (usize, usize)) {
+        self.borders.remove_border(pos, shape);
+    }
+
+    /// Gets a color of border of a cell on the grid.
+    //
+    // todo: would be great to remove a shape
+    pub fn remove_border_color(&mut self, pos: Position, shape: (usize, usize)) {
+        self.border_colors.remove_border(pos, shape);
+    }
+
     /// Get a span value of the cell, if any is set.
-    pub fn iter_span_rows(&self) -> impl Iterator<Item = (Position, usize)> + '_ {
-        self.span_rows.iter().map(|(&pos, &span)| (pos, span))
+    pub fn get_column_spans(&self) -> HashMap<Position, usize> {
+        self.span_columns.clone()
     }
 
     /// Get a span value of the cell, if any is set.
-    pub fn iter_span_columns(&self) -> impl Iterator<Item = (Position, usize)> + '_ {
-        self.span_columns.iter().map(|(&pos, &span)| (pos, span))
+    pub fn get_row_spans(&self) -> HashMap<Position, usize> {
+        self.span_rows.clone()
     }
 
     /// Get a span value of the cell, if any is set.
-    pub fn get_span_column(&self, pos: Position) -> Option<usize> {
+    pub fn get_column_span(&self, pos: Position) -> Option<usize> {
         self.span_columns.get(&pos).copied()
     }
 
     /// Get a span value of the cell, if any is set.
-    pub fn get_span_row(&self, pos: Position) -> Option<usize> {
+    pub fn get_row_span(&self, pos: Position) -> Option<usize> {
         self.span_rows.get(&pos).copied()
     }
 
     /// Removes column spans.
-    pub fn clear_span_column(&mut self) {
+    pub fn remove_column_spans(&mut self) {
         self.span_columns.clear()
     }
 
     /// Removes row spans.
-    pub fn clear_span_row(&mut self) {
+    pub fn remove_row_spans(&mut self) {
         self.span_rows.clear()
     }
 
-    /// Sets off all borders possible on the [`Entity`].
+    /// Set a column span to a given cells.
     ///
-    /// It doesn't changes globally set borders through [`GridConfig::set_borders`].
-    //
-    // todo: would be great to remove a shape
-    pub fn remove_border(&mut self, pos: Position, shape: (usize, usize)) {
-        self.borders.remove_border(pos, shape);
+    /// BEWARE
+    ///
+    /// IT'S CALLER RESPONSIBILITY TO MAKE SURE
+    /// THAT THERE NO INTERSECTIONS IN PLACE AND THE SPAN VALUE IS CORRECT
+    pub fn set_column_span(&mut self, pos: Position, span: usize) {
+        set_cell_column_span(self, pos, span);
     }
 
-    /// Gets a color of border of a cell on the grid.
-    //
-    // todo: would be great to remove a shape
-    pub fn remove_border_color(&mut self, pos: Position, shape: (usize, usize)) {
-        self.border_colors.remove_border(pos, shape);
+    /// Verifies if there's any spans set.
+    pub fn has_column_spans(&self) -> bool {
+        !self.span_columns.is_empty()
+    }
+
+    /// Set a column span to a given cells.
+    ///
+    /// BEWARE
+    ///
+    /// IT'S CALLER RESPONSIBILITY TO MAKE SURE
+    /// THAT THERE NO INTERSECTIONS IN PLACE AND THE SPAN VALUE IS CORRECT
+    pub fn set_row_span(&mut self, pos: Position, span: usize) {
+        set_cell_row_span(self, pos, span);
+    }
+
+    /// Verifies if there's any spans set.
+    pub fn has_row_spans(&self) -> bool {
+        !self.span_rows.is_empty()
     }
 }
 
@@ -481,7 +481,11 @@ impl GridConfig {
     }
 
     /// Gets a color of a cell horizontal.
-    pub fn get_horizontal_color(&self, pos: Position, count_rows: usize) -> Option<&AnsiColor<'_>> {
+    pub fn get_horizontal_color(
+        &self,
+        pos: Position,
+        count_rows: usize,
+    ) -> Option<&AnsiColor<'static>> {
         self.border_colors.get_horizontal(pos, count_rows)
     }
 
@@ -490,7 +494,7 @@ impl GridConfig {
         &self,
         pos: Position,
         count_columns: usize,
-    ) -> Option<&AnsiColor<'_>> {
+    ) -> Option<&AnsiColor<'static>> {
         self.border_colors.get_vertical(pos, count_columns)
     }
 
@@ -499,7 +503,7 @@ impl GridConfig {
         &self,
         pos: Position,
         shape: (usize, usize),
-    ) -> Option<&AnsiColor<'_>> {
+    ) -> Option<&AnsiColor<'static>> {
         self.border_colors.get_intersection(pos, shape)
     }
 
@@ -672,21 +676,15 @@ fn set_cell_column_span(cfg: &mut GridConfig, pos: Position, span: usize) {
 }
 
 fn is_cell_covered_by_column_span(cfg: &GridConfig, pos: Position) -> bool {
-    if !cfg.has_column_spans() {
-        return false;
-    }
-
-    cfg.iter_span_columns()
-        .any(|((row, col), span)| pos.1 > col && pos.1 < col + span && row == pos.0)
+    cfg.span_columns
+        .iter()
+        .any(|(&(row, col), span)| pos.1 > col && pos.1 < col + span && row == pos.0)
 }
 
 fn is_cell_covered_by_row_span(cfg: &GridConfig, pos: Position) -> bool {
-    if !cfg.has_row_spans() {
-        return false;
-    }
-
-    cfg.iter_span_rows()
-        .any(|((row, col), span)| pos.0 > row && pos.0 < row + span && col == pos.1)
+    cfg.span_rows
+        .iter()
+        .any(|(&(row, col), span)| pos.0 > row && pos.0 < row + span && col == pos.1)
 }
 
 fn is_cell_covered_by_both_spans(cfg: &GridConfig, pos: Position) -> bool {
@@ -694,8 +692,9 @@ fn is_cell_covered_by_both_spans(cfg: &GridConfig, pos: Position) -> bool {
         return false;
     }
 
-    cfg.iter_span_rows().any(|(p1, row_span)| {
-        cfg.iter_span_columns()
+    cfg.span_rows.iter().any(|(p1, row_span)| {
+        cfg.span_columns
+            .iter()
             .filter(|(p2, _)| &p1 == p2)
             .any(|(_, col_span)| {
                 pos.0 > p1.0 && pos.0 < p1.0 + row_span && pos.1 > p1.1 && pos.1 < p1.1 + col_span
diff --git a/papergrid/src/grid/spanned/dimension.rs b/papergrid/src/grid/spanned/dimension.rs
index c5e4b77..1becb6d 100644
--- a/papergrid/src/grid/spanned/dimension.rs
+++ b/papergrid/src/grid/spanned/dimension.rs
@@ -83,14 +83,14 @@ fn build_dimensions<R: Records>(records: R, cfg: &GridConfig) -> (Vec<usize>, Ve
             let width = width + pad.left.indent.size + pad.right.indent.size;
             let height = height + pad.top.indent.size + pad.bottom.indent.size;
 
-            match cfg.get_span_column(pos) {
+            match cfg.get_column_span(pos) {
                 Some(n) if n > 1 => {
                     vspans.insert(pos, (n, width));
                 }
                 _ => widths[col] = max(widths[col], width),
             }
 
-            match cfg.get_span_row(pos) {
+            match cfg.get_row_span(pos) {
                 Some(n) if n > 1 => {
                     hspans.insert(pos, (n, height));
                 }
@@ -275,7 +275,7 @@ fn build_height<R: Records>(records: R, cfg: &GridConfig) -> Vec<usize> {
             }
 
             let height = get_cell_height(cell.as_ref(), cfg, pos);
-            match cfg.get_span_row(pos) {
+            match cfg.get_row_span(pos) {
                 Some(n) if n > 1 => {
                     hspans.insert(pos, (n, height));
                 }
@@ -305,7 +305,7 @@ fn build_width<R: Records>(records: R, cfg: &GridConfig) -> Vec<usize> {
             }
 
             let width = get_cell_width(cell.as_ref(), cfg, pos);
-            match cfg.get_span_column(pos) {
+            match cfg.get_column_span(pos) {
                 Some(n) if n > 1 => {
                     vspans.insert(pos, (n, width));
                 }
diff --git a/papergrid/src/grid/spanned/grid.rs b/papergrid/src/grid/spanned/grid.rs
index b5b7045..42575de 100644
--- a/papergrid/src/grid/spanned/grid.rs
+++ b/papergrid/src/grid/spanned/grid.rs
@@ -9,7 +9,7 @@ use std::{
 
 use crate::{
     color::{AnsiColor, Color},
-    colors::{self, Colors, NoColors},
+    colors::Colors,
     config::{AlignmentHorizontal, AlignmentVertical, Indent, Position, Sides},
     dimension::Dimension,
     records::Records,
@@ -27,29 +27,19 @@ pub struct Grid<R, D, G, C> {
     colors: C,
 }
 
-impl<R, D, G> Grid<R, D, G, NoColors> {
+impl<R, D, G, C> Grid<R, D, G, C> {
     /// The new method creates a grid instance with default styles.
-    pub fn new(records: R, dimension: D, config: G) -> Self {
+    pub fn new(records: R, dimension: D, config: G, colors: C) -> Self {
         Grid {
             records,
             config,
             dimension,
-            colors: NoColors::default(),
+            colors,
         }
     }
 }
 
 impl<R, D, G, C> Grid<R, D, G, C> {
-    /// Sets colors map.
-    pub fn with_colors<Colors: colors::Colors>(self, colors: Colors) -> Grid<R, D, G, Colors> {
-        Grid {
-            records: self.records,
-            config: self.config,
-            dimension: self.dimension,
-            colors,
-        }
-    }
-
     /// Builds a table.
     pub fn build<F>(self, mut f: F) -> fmt::Result
     where
@@ -59,7 +49,7 @@ impl<R, D, G, C> Grid<R, D, G, C> {
         G: Borrow<GridConfig>,
         F: Write,
     {
-        if self.records.count_columns() == 0 {
+        if self.records.count_columns() == 0 || self.records.hint_count_rows() == Some(0) {
             return Ok(());
         }
 
@@ -132,6 +122,7 @@ fn print_grid_general<F: Write, R: Records, D: Dimension, C: Colors>(
     let mut row = 0;
     let mut line = 0;
     let mut is_prev_row_skipped = false;
+    let mut buf = None;
     while let Some(columns) = next_columns {
         let columns = columns.into_iter();
         next_columns = records_iter.next();
@@ -159,9 +150,16 @@ fn print_grid_general<F: Write, R: Records, D: Dimension, C: Colors>(
         if height == 1 {
             print_single_line_columns(f, columns, cfg, colors, dims, row, line, totalh, shape)?
         } else if height > 0 {
+            if buf.is_none() {
+                buf = Some(Vec::with_capacity(count_columns));
+            }
+
+            let buf = buf.as_mut().unwrap();
             print_multiline_columns(
-                f, columns, cfg, colors, dims, height, row, line, totalh, shape,
+                f, columns, cfg, colors, dims, height, row, line, totalh, shape, buf,
             )?;
+
+            buf.clear();
         }
 
         if height == 0 && !has_horizontal {
@@ -226,6 +224,7 @@ fn print_multiline_columns<'a, F, I, D, C>(
     line: usize,
     totalh: Option<usize>,
     shape: (usize, usize),
+    buf: &mut Vec<Cell<I::Item, &'a C::Color>>,
 ) -> fmt::Result
 where
     F: Write,
@@ -234,10 +233,8 @@ where
     D: Dimension,
     C: Colors,
 {
-    let mut buf = Vec::with_capacity(shape.1);
-    collect_columns(&mut buf, columns, cfg, colors, dimension, height, row);
-    print_columns_lines(f, &mut buf, height, cfg, line, row, totalh, shape)?;
-
+    collect_columns(buf, columns, cfg, colors, dimension, height, row);
+    print_columns_lines(f, buf, height, cfg, line, row, totalh, shape)?;
     Ok(())
 }
 
@@ -263,11 +260,11 @@ where
     print_margin_left(f, cfg, line, totalh)?;
 
     for (col, cell) in columns.enumerate() {
-        print_vertical_char(f, cfg, (row, col), 0, 1, shape)?;
-
+        let pos = (row, col);
         let width = dims.get_width(col);
-        let color = colors.get_color((row, col));
-        print_single_line_column(f, cell.as_ref(), cfg, width, color, (row, col))?;
+        let color = colors.get_color(pos);
+        print_vertical_char(f, cfg, pos, 0, 1, shape)?;
+        print_single_line_column(f, cell.as_ref(), cfg, width, color, pos)?;
     }
 
     print_vertical_char(f, cfg, (row, shape.1), 0, 1, shape)?;
@@ -364,9 +361,10 @@ fn collect_columns<'a, I, D, C>(
     D: Dimension,
 {
     let iter = iter.enumerate().map(|(col, cell)| {
+        let pos = (row, col);
         let width = dimension.get_width(col);
-        let color = colors.get_color((row, col));
-        Cell::new(cell, width, height, cfg, color, (row, col))
+        let color = colors.get_color(pos);
+        Cell::new(cell, width, height, cfg, color, pos)
     });
 
     buf.extend(iter);
@@ -379,47 +377,27 @@ fn print_split_line<F: Write, D: Dimension>(
     row: usize,
     shape: (usize, usize),
 ) -> fmt::Result {
-    if shape.1 == 0 {
-        return Ok(());
-    }
-
     let mut used_color = None;
-
-    let left = cfg.get_intersection((row, 0), shape);
-    if let Some(c) = left {
-        let clr = cfg.get_intersection_color((row, 0), shape);
-        if let Some(clr) = clr {
-            clr.fmt_prefix(f)?;
-            used_color = Some(clr);
-        }
-
-        f.write_char(c)?;
-    }
+    print_vertical_intersection(f, cfg, (row, 0), shape, &mut used_color)?;
 
     for col in 0..shape.1 {
         let width = dimension.get_width(col);
 
         // general case
         if width > 0 {
-            let main = cfg.get_horizontal((row, col), shape.0);
+            let pos = (row, col);
+            let main = cfg.get_horizontal(pos, shape.0);
             match main {
                 Some(c) => {
-                    let clr = cfg.get_horizontal_color((row, col), shape.0);
+                    let clr = cfg.get_horizontal_color(pos, shape.0);
                     prepare_coloring(f, clr, &mut used_color)?;
-
-                    print_horizontal_border(f, cfg, (row, col), width, c)?;
+                    print_horizontal_border(f, cfg, pos, width, c)?;
                 }
                 None => repeat_char(f, ' ', width)?,
             }
         }
 
-        let right = cfg.get_intersection((row, col + 1), shape);
-        if let Some(c) = right {
-            let clr = cfg.get_intersection_color((row, col + 1), shape);
-            prepare_coloring(f, clr, &mut used_color)?;
-
-            f.write_char(c)?;
-        }
+        print_vertical_intersection(f, cfg, (row, col + 1), shape, &mut used_color)?;
     }
 
     if let Some(clr) = used_color.take() {
@@ -522,31 +500,18 @@ fn print_split_line_spanned<S, F: Write, D: Dimension, C: Color>(
     row: usize,
     shape: (usize, usize),
 ) -> fmt::Result {
-    if shape.1 == 0 {
-        return Ok(());
-    }
-
     let mut used_color = None;
-
-    let left = cfg.get_intersection((row, 0), shape);
-    if let Some(c) = left {
-        let clr = cfg.get_intersection_color((row, 0), shape);
-        if let Some(clr) = clr {
-            clr.fmt_prefix(f)?;
-            used_color = Some(clr);
-        }
-
-        f.write_char(c)?;
-    }
+    print_vertical_intersection(f, cfg, (row, 0), shape, &mut used_color)?;
 
     for col in 0..shape.1 {
-        if cfg.is_cell_covered_by_both_spans((row, col)) {
+        let pos = (row, col);
+        if cfg.is_cell_covered_by_both_spans(pos) {
             continue;
         }
 
         let width = dimension.get_width(col);
         let mut col = col;
-        if cfg.is_cell_covered_by_row_span((row, col)) {
+        if cfg.is_cell_covered_by_row_span(pos) {
             // means it's part of other a spanned cell
             // so. we just need to use line from other cell.
 
@@ -554,31 +519,24 @@ fn print_split_line_spanned<S, F: Write, D: Dimension, C: Color>(
             cell.display(f)?;
 
             // We need to use a correct right split char.
-            let original_row = closest_visible_row(cfg, (row, col)).unwrap();
-            if let Some(span) = cfg.get_span_column((original_row, col)) {
+            let original_row = closest_visible_row(cfg, pos).unwrap();
+            if let Some(span) = cfg.get_column_span((original_row, col)) {
                 col += span - 1;
             }
         } else if width > 0 {
             // general case
-            let main = cfg.get_horizontal((row, col), shape.0);
+            let main = cfg.get_horizontal(pos, shape.0);
             match main {
                 Some(c) => {
-                    let clr = cfg.get_horizontal_color((row, col), shape.0);
+                    let clr = cfg.get_horizontal_color(pos, shape.0);
                     prepare_coloring(f, clr, &mut used_color)?;
-
-                    print_horizontal_border(f, cfg, (row, col), width, c)?;
+                    print_horizontal_border(f, cfg, pos, width, c)?;
                 }
                 None => repeat_char(f, ' ', width)?,
             }
         }
 
-        let right = cfg.get_intersection((row, col + 1), shape);
-        if let Some(c) = right {
-            let clr = cfg.get_intersection_color((row, col + 1), shape);
-            prepare_coloring(f, clr, &mut used_color)?;
-
-            f.write_char(c)?;
-        }
+        print_vertical_intersection(f, cfg, (row, col + 1), shape, &mut used_color)?;
     }
 
     if let Some(clr) = used_color.take() {
@@ -588,6 +546,23 @@ fn print_split_line_spanned<S, F: Write, D: Dimension, C: Color>(
     Ok(())
 }
 
+fn print_vertical_intersection<'a, F: fmt::Write>(
+    f: &mut F,
+    cfg: &'a GridConfig,
+    pos: Position,
+    shape: (usize, usize),
+    used_color: &mut Option<&'a AnsiColor<'static>>,
+) -> fmt::Result {
+    match cfg.get_intersection(pos, shape) {
+        Some(c) => {
+            let clr = cfg.get_intersection_color(pos, shape);
+            prepare_coloring(f, clr, used_color)?;
+            f.write_char(c)
+        }
+        None => Ok(()),
+    }
+}
+
 #[allow(clippy::too_many_arguments, clippy::type_complexity)]
 fn print_spanned_columns<'a, F, I, D, C>(
     f: &mut F,
@@ -625,7 +600,8 @@ where
                 continue;
             }
 
-            let rowspan = cfg.get_span_row((row, col)).unwrap_or(1);
+            let pos = (row, col);
+            let rowspan = cfg.get_row_span(pos).unwrap_or(1);
             if rowspan < 2 {
                 continue;
             }
@@ -636,7 +612,7 @@ where
                 this_height
             };
 
-            let colspan = cfg.get_span_column((row, col)).unwrap_or(1);
+            let colspan = cfg.get_column_span(pos).unwrap_or(1);
             skip = colspan - 1;
             let width = if colspan > 1 {
                 range_width(cfg, dimension, col, col + colspan, shape.1)
@@ -644,8 +620,8 @@ where
                 dimension.get_width(col)
             };
 
-            let color = colors.get_color((row, col));
-            let cell = Cell::new(cell, width, height, cfg, color, (row, col));
+            let color = colors.get_color(pos);
+            let cell = Cell::new(cell, width, height, cfg, color, pos);
 
             buf.insert(col, (cell, rowspan, colspan));
         }
@@ -670,7 +646,8 @@ where
             continue;
         }
 
-        let colspan = cfg.get_span_column((row, col)).unwrap_or(1);
+        let pos = (row, col);
+        let colspan = cfg.get_column_span(pos).unwrap_or(1);
         skip = colspan - 1;
 
         let width = if colspan > 1 {
@@ -679,15 +656,15 @@ where
             dimension.get_width(col)
         };
 
-        let rowspan = cfg.get_span_row((row, col)).unwrap_or(1);
+        let rowspan = cfg.get_row_span(pos).unwrap_or(1);
         let height = if rowspan > 1 {
             range_height(cfg, dimension, row, row + rowspan, shape.0)
         } else {
             this_height
         };
 
-        let color = colors.get_color((row, col));
-        let cell = Cell::new(cell, width, height, cfg, color, (row, col));
+        let color = colors.get_color(pos);
+        let cell = Cell::new(cell, width, height, cfg, color, pos);
 
         buf.insert(col, (cell, rowspan, colspan));
     }
@@ -896,10 +873,10 @@ fn print_text<F: Write>(f: &mut F, text: &str, clr: Option<impl Color>) -> fmt::
     }
 }
 
-fn prepare_coloring<'a, F: Write>(
+fn prepare_coloring<'a, 'b, F: Write>(
     f: &mut F,
-    clr: Option<&'a AnsiColor<'a>>,
-    used_color: &mut Option<&'a AnsiColor<'a>>,
+    clr: Option<&'a AnsiColor<'b>>,
+    used_color: &mut Option<&'a AnsiColor<'b>>,
 ) -> fmt::Result {
     match clr {
         Some(clr) => match used_color.as_mut() {
diff --git a/papergrid/src/lib.rs b/papergrid/src/lib.rs
index 178e140..41c4d52 100644
--- a/papergrid/src/lib.rs
+++ b/papergrid/src/lib.rs
@@ -26,6 +26,7 @@
 //!     records::IterRecords,
 //!     dimension::{Estimate},
 //!     config::Borders,
+//!     colors::NoColors,
 //!     grid::spanned::{config::GridConfig, Grid, ExactDimension},
 //! };
 //!
@@ -61,7 +62,7 @@
 //! dimension.estimate(&records, &cfg);
 //!
 //! // Creating a grid.
-//! let grid = Grid::new(&records, &dimension, &cfg).to_string();
+//! let grid = Grid::new(&records, &dimension, &cfg, NoColors).to_string();
 //!
 //! assert_eq!(
 //!     grid,
diff --git a/static_table/Cargo.toml b/static_table/Cargo.toml
index 5ceff4d..ce4d17d 100644
--- a/static_table/Cargo.toml
+++ b/static_table/Cargo.toml
@@ -1,9 +1,9 @@
 [package]
 name = "static_table"
-version = "0.1.0"
+version = "0.0.0"
 authors = ["Maxim Zhiburt <zhiburt@gmail.com>"]
 edition = "2018"
-description = "Derive macros which is used by tabled crate"
+description = "Library creates pretty tables at compiler time"
 repository = "https://github.com/zhiburt/tabled"
 license = "Unlicense/MIT"
 
diff --git a/static_table/README.md b/static_table/README.md
index 96fa80f..33988c2 100644
--- a/static_table/README.md
+++ b/static_table/README.md
@@ -34,3 +34,20 @@ Output
 | Rust | Graydon Hoare  | 2010          |
 +------+----------------+---------------+
 ```
+
+You can even use the macros in the documentation
+
+```rust
+/// Add joins 2 integers together to get a sum.
+/// 
+/// ```
+#[doc = static_table::static_table!([
+    ["a", "b", "result"],
+    ["1", '2', '3'],
+    ["2", '2', '4']
+])]
+/// ```
+pub fn add(left: usize, right: usize) -> usize {
+    left + right
+}
+```
diff --git a/static_table/examples/use_in_docs/Cargo.toml b/static_table/examples/use_in_docs/Cargo.toml
new file mode 100644
index 0000000..4e1cfa3
--- /dev/null
+++ b/static_table/examples/use_in_docs/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "use_in_docs"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[workspace]
+
+[dependencies]
+static_table = { path = "../.." }
\ No newline at end of file
diff --git a/static_table/examples/use_in_docs/src/lib.rs b/static_table/examples/use_in_docs/src/lib.rs
new file mode 100644
index 0000000..aedd081
--- /dev/null
+++ b/static_table/examples/use_in_docs/src/lib.rs
@@ -0,0 +1,22 @@
+//! # The table
+//!
+//! ```
+#![doc = static_table::static_table!([
+    ["a", "b", "result"],
+    ["1", '2', '3'],
+    ["2", '2', '4']
+])]
+//! ```
+
+/// Add joins 2 integers together to get a sum.
+/// 
+/// ```
+#[doc = static_table::static_table!([
+    ["a", "b", "result"],
+    ["1", '2', '3'],
+    ["2", '2', '4']
+])]
+/// ```
+pub fn add(left: usize, right: usize) -> usize {
+    left + right
+}
diff --git a/static_table/src/lib.rs b/static_table/src/lib.rs
index 047fcd7..ad7dc0c 100644
--- a/static_table/src/lib.rs
+++ b/static_table/src/lib.rs
@@ -489,9 +489,14 @@ impl<T: Parse> Parse for Pad<T> {
 
 fn expr_lit_to_string(expr_lit: &ExprLit) -> String {
     match &expr_lit.lit {
-        Lit::Str(s) => s.value(),
-        Lit::ByteStr(s) => format!("{:?}", s.value()),
-        lit => lit.to_token_stream().to_string(),
+        Lit::Str(val) => val.value(),
+        Lit::ByteStr(val) => format!("{:?}", val.value()),
+        Lit::Int(val) => val.base10_digits().to_string(),
+        Lit::Float(val) => val.base10_digits().to_string(),
+        Lit::Char(val) => val.value().to_string(),
+        Lit::Byte(val) => val.value().to_string(),
+        Lit::Bool(val) => val.value().to_string(),
+        Lit::Verbatim(val) => val.to_token_stream().to_string(),
     }
 }
 
@@ -885,11 +890,11 @@ fn create_table(mat: &MatrixInput) -> Result<Table> {
     let mut table = builder.build();
 
     for (pos, span) in vspan {
-        table.with(Modify::new(pos).with(Span::horizontal(span)));
+        table.with(Modify::new(pos).with(Span::column(span)));
     }
 
     for (pos, span) in hspan {
-        table.with(Modify::new(pos).with(Span::vertical(span)));
+        table.with(Modify::new(pos).with(Span::row(span)));
     }
 
     Ok(table)
diff --git a/tabled/Cargo.toml b/tabled/Cargo.toml
index 1008565..44ed729 100644
--- a/tabled/Cargo.toml
+++ b/tabled/Cargo.toml
@@ -239,6 +239,11 @@ name = "alphabet"
 path = "examples/alphabet.rs"
 required-features = ["std"]
 
+[[example]]
+name = "split"
+path = "examples/split.rs"
+required-features = ["std", "macros"]
+
 [features]
 default = ["derive", "macros"]
 std = ["papergrid/std"]
diff --git a/tabled/examples/README.md b/tabled/examples/README.md
index e419081..19c7e23 100644
--- a/tabled/examples/README.md
+++ b/tabled/examples/README.md
@@ -773,3 +773,37 @@ vvvvvvvvvvvvvvvvvv
 +----------------------+-----------------+--------------------+
 ```
 
+## split
+
+```
+┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐                       
+│ a │ b │ c │ d │ e │ f │ g │ h │ i │ j │ k │ l │ m │ n │ o │ p │ q │ r │ s │ t │ u │ v │ w │ x │ y │ z │                       
+└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘                       
+┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ ┌───┬───┐ ┌───┬───┐ ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ 
+│ a │ b │ c │ d │ e │ f │ g │ h │ i │ j │ k │ l │ │ a │ b │ │ a │ b │ │ a │ y │ b │ z │ c │ d │ e │ f │ g │ h │ i │ j │ k │ l │ 
+├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ ├───┼───┤ ├───┼───┤ ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 
+│ m │ n │ o │ p │ q │ r │ s │ t │ u │ v │ w │ x │ │ c │ d │ │ m │ n │ │ m │   │ n │   │ o │ p │ q │ r │ s │ t │ u │ v │ w │ x │ 
+├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ ├───┼───┤ ├───┼───┤ └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘ 
+│ y │ z │   │   │   │   │   │   │   │   │   │   │ │ e │ f │ │ y │ z │ ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ 
+└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘ ├───┼───┤ ├───┼───┤ │ a │ b │ c │ d │ e │ f │ g │ h │ i │ j │ k │ l │ y │ z │ 
+                                                  │ g │ h │ │ c │ d │ ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 
+                                                  ├───┼───┤ ├───┼───┤ │ m │ n │ o │ p │ q │ r │ s │ t │ u │ v │ w │ x │   │   │ 
+                                                  │ i │ j │ │ o │ p │ └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘ 
+                                                  ├───┼───┤ ├───┼───┤                                                           
+                                                  │ k │ l │ │ e │ f │                                                           
+                                                  ├───┼───┤ ├───┼───┤                                                           
+                                                  │ m │ n │ │ q │ r │                                                           
+                                                  ├───┼───┤ ├───┼───┤                                                           
+                                                  │ o │ p │ │ g │ h │                                                           
+                                                  ├───┼───┤ ├───┼───┤                                                           
+                                                  │ q │ r │ │ s │ t │                                                           
+                                                  ├───┼───┤ ├───┼───┤                                                           
+                                                  │ s │ t │ │ i │ j │                                                           
+                                                  ├───┼───┤ ├───┼───┤                                                           
+                                                  │ u │ v │ │ u │ v │                                                           
+                                                  ├───┼───┤ ├───┼───┤                                                           
+                                                  │ w │ x │ │ k │ l │                                                           
+                                                  ├───┼───┤ ├───┼───┤                                                           
+                                                  │ y │ z │ │ w │ x │                                                           
+                                                  └───┴───┘ └───┴───┘                     
+```
\ No newline at end of file
diff --git a/tabled/examples/span.rs b/tabled/examples/span.rs
index 950cc17..5572d74 100644
--- a/tabled/examples/span.rs
+++ b/tabled/examples/span.rs
@@ -13,8 +13,8 @@ use tabled::{
 fn main() {
     let data = [["just 1 column"; 5]; 5];
 
-    let h_span = |r, c, span| Modify::new(Cell::new(r, c)).with(Span::vertical(span));
-    let v_span = |r, c, span| Modify::new(Cell::new(r, c)).with(Span::horizontal(span));
+    let h_span = |r, c, span| Modify::new(Cell::new(r, c)).with(Span::row(span));
+    let v_span = |r, c, span| Modify::new(Cell::new(r, c)).with(Span::column(span));
 
     let table = Table::new(data)
         .with(h_span(0, 0, 5).with("span all 5 columns"))
diff --git a/tabled/examples/split.rs b/tabled/examples/split.rs
new file mode 100644
index 0000000..913a482
--- /dev/null
+++ b/tabled/examples/split.rs
@@ -0,0 +1,37 @@
+//! The example can be run by this command
+//! `cargo run --example split`
+
+use std::iter::FromIterator;
+use tabled::{
+    col, row,
+    settings::{split::Split, style::Style, Padding},
+    Table,
+};
+
+fn main() {
+    let mut table = Table::from_iter(['a'..='z']);
+    table.with(Style::modern());
+
+    let table_1 = table.clone().with(Split::column(12)).clone();
+    let table_2 = table_1.clone().with(Split::column(2).zip()).to_string();
+    let table_3 = table_1.clone().with(Split::column(2).concat()).to_string();
+    let table_4 = table_1.clone().with(Split::row(2).zip()).to_string();
+    let table_5 = table_1.clone().with(Split::row(2).concat()).to_string();
+
+    let mut table = col![
+        table,
+        row![
+            table_1,
+            table_2,
+            table_3,
+            col![table_4, table_5]
+                .with(Style::blank())
+                .with(Padding::zero())
+        ]
+        .with(Style::blank())
+        .with(Padding::zero()),
+    ];
+    table.with(Style::blank());
+
+    println!("{table}");
+}
diff --git a/tabled/src/settings/merge/mod.rs b/tabled/src/settings/merge/mod.rs
index 7bf5663..7cc1d25 100644
--- a/tabled/src/settings/merge/mod.rs
+++ b/tabled/src/settings/merge/mod.rs
@@ -59,8 +59,7 @@ where
 
                 // we need to mitigate messing existing spans
                 let is_cell_visible = cfg.is_cell_visible((row, column));
-
-                let is_row_span_cell = cfg.get_span_column((row, column)).is_some();
+                let is_row_span_cell = cfg.get_column_span((row, column)).is_some();
 
                 if !repeat_is_set {
                     if !is_cell_visible {
@@ -145,8 +144,7 @@ where
 
                 // we need to mitigate messing existing spans
                 let is_cell_visible = cfg.is_cell_visible((row, column));
-
-                let is_col_span_cell = cfg.get_span_row((row, column)).is_some();
+                let is_col_span_cell = cfg.get_row_span((row, column)).is_some();
 
                 if !repeat_is_set {
                     if !is_cell_visible {
diff --git a/tabled/src/settings/mod.rs b/tabled/src/settings/mod.rs
index 40e6914..1944895 100644
--- a/tabled/src/settings/mod.rs
+++ b/tabled/src/settings/mod.rs
@@ -103,6 +103,9 @@ mod shadow;
 pub mod span;
 #[cfg(feature = "std")]
 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
+pub mod split;
+#[cfg(feature = "std")]
+#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
 pub mod width;
 
 pub use cell_option::CellOption;
diff --git a/tabled/src/settings/panel/horizontal_panel.rs b/tabled/src/settings/panel/horizontal_panel.rs
index c8652cc..19e25f8 100644
--- a/tabled/src/settings/panel/horizontal_panel.rs
+++ b/tabled/src/settings/panel/horizontal_panel.rs
@@ -55,19 +55,21 @@ fn move_rows_aside<R: ExactRecords + Resizable>(records: &mut R, row: usize) {
 }
 
 fn move_row_spans(cfg: &mut GridConfig, target_row: usize) {
-    let spans = cfg.iter_span_columns().collect::<Vec<_>>();
-    for ((row, col), span) in spans {
-        if row >= target_row {
-            cfg.set_column_span((row, col), 1);
-            cfg.set_column_span((row + 1, col), span);
+    for ((row, col), span) in cfg.get_column_spans() {
+        if row < target_row {
+            continue;
         }
+
+        cfg.set_column_span((row, col), 1);
+        cfg.set_column_span((row + 1, col), span);
     }
 
-    let spans = cfg.iter_span_rows().collect::<Vec<_>>();
-    for ((row, col), span) in spans {
-        if row >= target_row {
-            cfg.set_row_span((row, col), 1);
-            cfg.set_row_span((row + 1, col), span);
+    for ((row, col), span) in cfg.get_row_spans() {
+        if row < target_row {
+            continue;
         }
+
+        cfg.set_row_span((row, col), 1);
+        cfg.set_row_span((row + 1, col), span);
     }
 }
diff --git a/tabled/src/settings/panel/vertical_panel.rs b/tabled/src/settings/panel/vertical_panel.rs
index 21016b7..a0bd005 100644
--- a/tabled/src/settings/panel/vertical_panel.rs
+++ b/tabled/src/settings/panel/vertical_panel.rs
@@ -57,19 +57,21 @@ fn move_columns_aside<R: Records + Resizable>(records: &mut R, column: usize) {
 }
 
 fn move_column_spans(cfg: &mut GridConfig, target_column: usize) {
-    let spans = cfg.iter_span_columns().collect::<Vec<_>>();
-    for ((row, col), span) in spans {
-        if col >= target_column {
-            cfg.set_column_span((row, col), 1);
-            cfg.set_column_span((row, col + 1), span);
+    for ((row, col), span) in cfg.get_column_spans() {
+        if col < target_column {
+            continue;
         }
+
+        cfg.set_column_span((row, col), 1);
+        cfg.set_column_span((row, col + 1), span);
     }
 
-    let spans = cfg.iter_span_rows().collect::<Vec<_>>();
-    for ((row, col), span) in spans {
-        if col >= target_column {
-            cfg.set_row_span((row, col), 1);
-            cfg.set_row_span((row, col + 1), span);
+    for ((row, col), span) in cfg.get_row_spans() {
+        if col < target_column {
+            continue;
         }
+
+        cfg.set_row_span((row, col), 1);
+        cfg.set_row_span((row, col + 1), span);
     }
 }
diff --git a/tabled/src/settings/span/column.rs b/tabled/src/settings/span/column.rs
index 7054c65..35de829 100644
--- a/tabled/src/settings/span/column.rs
+++ b/tabled/src/settings/span/column.rs
@@ -35,6 +35,7 @@ where
         let count_cols = records.count_columns();
 
         set_col_spans(cfg, self.size, entity, (count_rows, count_cols));
+        remove_false_spans(cfg);
     }
 }
 
@@ -104,3 +105,23 @@ fn span_has_intersections(cfg: &GridConfig, (row, col): Position, span: usize) -
 
     false
 }
+
+fn remove_false_spans(cfg: &mut GridConfig) {
+    for (pos, _) in cfg.get_column_spans() {
+        if cfg.is_cell_visible(pos) {
+            continue;
+        }
+
+        cfg.set_row_span(pos, 1);
+        cfg.set_column_span(pos, 1);
+    }
+
+    for (pos, _) in cfg.get_row_spans() {
+        if cfg.is_cell_visible(pos) {
+            continue;
+        }
+
+        cfg.set_row_span(pos, 1);
+        cfg.set_column_span(pos, 1);
+    }
+}
diff --git a/tabled/src/settings/span/mod.rs b/tabled/src/settings/span/mod.rs
index c23ef24..1139a2b 100644
--- a/tabled/src/settings/span/mod.rs
+++ b/tabled/src/settings/span/mod.rs
@@ -9,8 +9,8 @@
 //! let data = [[1, 2, 3], [4, 5, 6]];
 //!
 //! let table = Table::new(data)
-//!     .with(Modify::new((2, 0)).with(Span::horizontal(2)))
-//!     .with(Modify::new((0, 1)).with(Span::horizontal(2)))
+//!     .with(Modify::new((2, 0)).with(Span::column(2)))
+//!     .with(Modify::new((0, 1)).with(Span::column(2)))
 //!     .to_string();
 //!
 //! assert_eq!(
@@ -44,7 +44,7 @@ pub use row::RowSpan;
 /// # use tabled::{Table, settings::{Style, Span, Modify, object::Columns}};
 /// # let data: Vec<&'static str> = Vec::new();
 /// let table = Table::new(&data)
-///     .with(Modify::new(Columns::single(0)).with(Span::horizontal(2)));
+///     .with(Modify::new(Columns::single(0)).with(Span::column(2)));
 /// ```
 ///
 /// [`Table`]: crate::Table
@@ -55,14 +55,14 @@ impl Span {
     /// New constructs a horizontal/column [`Span`].
     ///
     /// If size is bigger then the total number of columns it will be ignored.
-    pub fn horizontal(size: usize) -> ColumnSpan {
+    pub fn column(size: usize) -> ColumnSpan {
         ColumnSpan::new(size)
     }
 
     /// New constructs a vertical/row [`Span`].
     ///
     /// If size is bigger then the total number of rows it will be ignored.
-    pub fn vertical(size: usize) -> RowSpan {
+    pub fn row(size: usize) -> RowSpan {
         RowSpan::new(size)
     }
 }
diff --git a/tabled/src/settings/span/row.rs b/tabled/src/settings/span/row.rs
index 683a64e..3864e74 100644
--- a/tabled/src/settings/span/row.rs
+++ b/tabled/src/settings/span/row.rs
@@ -35,6 +35,7 @@ where
         let count_cols = records.count_columns();
 
         set_row_spans(cfg, self.size, entity, (count_rows, count_cols));
+        remove_false_spans(cfg);
     }
 }
 
@@ -105,3 +106,23 @@ fn span_has_intersections(cfg: &GridConfig, (row, col): Position, span: usize) -
 
     false
 }
+
+fn remove_false_spans(cfg: &mut GridConfig) {
+    for (pos, _) in cfg.get_column_spans() {
+        if cfg.is_cell_visible(pos) {
+            continue;
+        }
+
+        cfg.set_row_span(pos, 1);
+        cfg.set_column_span(pos, 1);
+    }
+
+    for (pos, _) in cfg.get_row_spans() {
+        if cfg.is_cell_visible(pos) {
+            continue;
+        }
+
+        cfg.set_row_span(pos, 1);
+        cfg.set_column_span(pos, 1);
+    }
+}
diff --git a/tabled/src/settings/split/mod.rs b/tabled/src/settings/split/mod.rs
new file mode 100644
index 0000000..52bbee0
--- /dev/null
+++ b/tabled/src/settings/split/mod.rs
@@ -0,0 +1,418 @@
+//! This module contains a [`Split`] setting which is used to
+//! format the cells of a [`Table`] by a provided index, direction, behavior, and display preference.
+//!
+//! [`Table`]: crate::Table
+
+use core::ops::Range;
+
+use papergrid::config::Position;
+
+use crate::records::{ExactRecords, Records, Resizable};
+
+use super::TableOption;
+
+#[derive(Debug, Clone, Copy)]
+enum Direction {
+    Column,
+    Row,
+}
+
+#[derive(Debug, Clone, Copy)]
+enum Behavior {
+    Concat,
+    Zip,
+}
+
+#[derive(Debug, Clone, Copy, PartialEq)]
+enum Display {
+    Clean,
+    Retain,
+}
+
+/// Returns a new [`Table`] formatted with several optional parameters.
+///
+/// The required index parameter determines how many columns/rows a table will be redistributed into.
+///
+/// - index [`usize`]
+/// - direction [`Direction`]
+/// - behavior [`Behavior`] DEFAULT [`Behavior::Zip`]
+/// - display [`Display`] DEFAULT [`Display::Clean`]
+///
+/// # Example
+///
+/// ```rust,no_run
+/// use std::iter::FromIterator;
+/// use tabled::{
+///     settings::split::Split,
+///     Table,
+/// };
+///
+/// let mut table = Table::from_iter(['a'..='z']);
+/// let table = table.with(Split::column(4)).to_string();
+///
+/// assert_eq!(table, "+---+---+---+---+\n\
+///                    | a | b | c | d |\n\
+///                    +---+---+---+---+\n\
+///                    | e | f | g | h |\n\
+///                    +---+---+---+---+\n\
+///                    | i | j | k | l |\n\
+///                    +---+---+---+---+\n\
+///                    | m | n | o | p |\n\
+///                    +---+---+---+---+\n\
+///                    | q | r | s | t |\n\
+///                    +---+---+---+---+\n\
+///                    | u | v | w | x |\n\
+///                    +---+---+---+---+\n\
+///                    | y | z |   |   |\n\
+///                    +---+---+---+---+")
+/// ```
+///
+/// [`Table`]: crate::Table
+#[derive(Debug, Clone, Copy)]
+pub struct Split {
+    direction: Direction,
+    behavior: Behavior,
+    display: Display,
+    index: usize,
+}
+
+impl Split {
+    /// Returns a new [`Table`] split on the column at the provided index.
+    ///
+    /// The column found at that index becomes the new right-most column in the returned table.
+    /// Columns found beyond the index are redistributed into the table based on other defined
+    /// parameters.
+    ///
+    /// ```rust,no_run
+    /// # use tabled::settings::split::Split;
+    /// Split::column(4);
+    /// ```
+    ///
+    /// [`Table`]: crate::Table
+    pub fn column(index: usize) -> Self {
+        Split {
+            direction: Direction::Column,
+            behavior: Behavior::Zip,
+            display: Display::Clean,
+            index,
+        }
+    }
+
+    /// Returns a new [`Table`] split on the row at the provided index.
+    ///
+    /// The row found at that index becomes the new bottom row in the returned table.
+    /// Rows found beyond the index are redistributed into the table based on other defined
+    /// parameters.
+    ///
+    /// ```rust,no_run
+    /// # use tabled::settings::split::Split;
+    /// Split::row(4);
+    /// ```
+    ///
+    /// [`Table`]: crate::Table
+    pub fn row(index: usize) -> Self {
+        Split {
+            direction: Direction::Row,
+            behavior: Behavior::Zip,
+            display: Display::Clean,
+            index,
+        }
+    }
+
+    /// Returns a split [`Table`] with the redistributed cells pushed to the back of the new shape.
+    ///
+    /// ```text
+    ///                                                 +---+---+
+    ///                                                 | a | b |
+    ///                                                 +---+---+
+    /// +---+---+---+---+---+                           | f | g |
+    /// | a | b | c | d | e | Split::column(2).concat() +---+---+
+    /// +---+---+---+---+---+           =>              | c | d |
+    /// | f | g | h | i | j |                           +---+---+
+    /// +---+---+---+---+---+                           | h | i |
+    ///                                                 +---+---+
+    ///                                                 | e |   |
+    ///                                                 +---+---+
+    ///                                                 | j |   |
+    ///                                                 +---+---+
+    /// ```
+    ///
+    /// [`Table`]: crate::Table
+    pub fn concat(self) -> Self {
+        Self {
+            behavior: Behavior::Concat,
+            ..self
+        }
+    }
+
+    /// Returns a split [`Table`] with the redistributed cells inserted behind
+    /// the first correlating column/row one after another.
+    ///
+    /// ```text
+    ///                                              +---+---+
+    ///                                              | a | b |
+    ///                                              +---+---+
+    /// +---+---+---+---+---+                        | c | d |
+    /// | a | b | c | d | e | Split::column(2).zip() +---+---+
+    /// +---+---+---+---+---+           =>           | e |   |
+    /// | f | g | h | i | j |                        +---+---+
+    /// +---+---+---+---+---+                        | f | g |
+    ///                                              +---+---+
+    ///                                              | h | i |
+    ///                                              +---+---+
+    ///                                              | j |   |
+    ///                                              +---+---+
+    /// ```
+    ///
+    /// [`Table`]: crate::Table
+    pub fn zip(self) -> Self {
+        Self {
+            behavior: Behavior::Zip,
+            ..self
+        }
+    }
+
+    /// Returns a split [`Table`] with the empty columns/rows filtered out.
+    ///
+    /// ```text
+    ///                                                
+    ///                                                
+    ///                                                +---+---+---+
+    /// +---+---+---+---+---+                          | a | b | c |
+    /// | a | b | c | d | e | Split::column(3).clean() +---+---+---+
+    /// +---+---+---+---+---+           =>             | d | e |   |
+    /// | f | g | h |   |   |                          +---+---+---+
+    /// +---+---+---+---+---+                          | f | g | h |
+    ///               ^   ^                            +---+---+---+
+    ///               these cells are filtered
+    ///               from the resulting table
+    /// ```
+    ///
+    /// ## Notes
+    ///
+    /// This is apart of the default configuration for Split.
+    ///
+    /// See [`retain`] for an alternative display option.
+    ///
+    /// [`Table`]: crate::Table
+    pub fn clean(self) -> Self {
+        Self {
+            display: Display::Clean,
+            ..self
+        }
+    }
+
+    /// Returns a split [`Table`] with all cells retained.
+    ///
+    /// ```text
+    ///                                                 +---+---+---+
+    ///                                                 | a | b | c |
+    ///                                                 +---+---+---+
+    /// +---+---+---+---+---+                           | d | e |   |
+    /// | a | b | c | d | e | Split::column(3).retain() +---+---+---+
+    /// +---+---+---+---+---+           =>              | f | g | h |
+    /// | f | g | h |   |   |                           +---+---+---+
+    /// +---+---+---+---+---+             |-----------> |   |   |   |
+    ///               ^   ^               |             +---+---+---+
+    ///               |___|_____cells are kept!
+    /// ```
+    ///
+    /// ## Notes
+    ///
+    /// See [`clean`] for an alternative display option.
+    ///
+    /// [`Table`]: crate::Table
+    pub fn retain(self) -> Self {
+        Self {
+            display: Display::Retain,
+            ..self
+        }
+    }
+}
+
+impl<R, D, Cfg> TableOption<R, D, Cfg> for Split
+where
+    R: Records + ExactRecords + Resizable,
+{
+    fn change(&mut self, records: &mut R, _: &mut Cfg, _: &mut D) {
+        // variables
+        let Split {
+            direction,
+            behavior,
+            display,
+            index: section_length,
+        } = *self;
+        let mut filtered_sections = 0;
+
+        // early return check
+        if records.count_columns() == 0 || records.count_rows() == 0 || section_length == 0 {
+            return;
+        }
+
+        // computed variables
+        let (primary_length, secondary_length) = compute_length_arrangement(records, direction);
+        let sections_per_direction = ceil_div(primary_length, section_length);
+        let (outer_range, inner_range) =
+            compute_range_order(secondary_length, sections_per_direction, behavior);
+
+        // work
+        for outer_index in outer_range {
+            let from_secondary_index = outer_index * sections_per_direction - filtered_sections;
+            for inner_index in inner_range.clone() {
+                let (section_index, from_secondary_index, to_secondary_index) =
+                    compute_range_variables(
+                        outer_index,
+                        inner_index,
+                        secondary_length,
+                        from_secondary_index,
+                        sections_per_direction,
+                        filtered_sections,
+                        behavior,
+                    );
+
+                match (direction, behavior) {
+                    (Direction::Column, Behavior::Concat) => records.push_row(),
+                    (Direction::Column, Behavior::Zip) => records.insert_row(to_secondary_index),
+                    (Direction::Row, Behavior::Concat) => records.push_column(),
+                    (Direction::Row, Behavior::Zip) => records.insert_column(to_secondary_index),
+                }
+
+                let section_is_empty = copy_section(
+                    records,
+                    section_length,
+                    section_index,
+                    primary_length,
+                    from_secondary_index,
+                    to_secondary_index,
+                    direction,
+                );
+
+                if section_is_empty && display == Display::Clean {
+                    delete(records, to_secondary_index, direction);
+                    filtered_sections += 1;
+                }
+            }
+        }
+
+        cleanup(records, section_length, primary_length, direction);
+    }
+}
+
+/// Determine which direction should be considered the primary, and which the secondary based on direction
+fn compute_length_arrangement<R>(records: &mut R, direction: Direction) -> (usize, usize)
+where
+    R: Records + ExactRecords,
+{
+    match direction {
+        Direction::Column => (records.count_columns(), records.count_rows()),
+        Direction::Row => (records.count_rows(), records.count_columns()),
+    }
+}
+
+/// reduce the table size to the length of the index in the specified direction
+fn cleanup<R>(records: &mut R, section_length: usize, primary_length: usize, direction: Direction)
+where
+    R: Resizable,
+{
+    for segment in (section_length..primary_length).rev() {
+        match direction {
+            Direction::Column => records.remove_column(segment),
+            Direction::Row => records.remove_row(segment),
+        }
+    }
+}
+
+/// Delete target index row or column
+fn delete<R>(records: &mut R, target_index: usize, direction: Direction)
+where
+    R: Resizable,
+{
+    match direction {
+        Direction::Column => records.remove_row(target_index),
+        Direction::Row => records.remove_column(target_index),
+    }
+}
+
+/// copy cells to new location
+///
+/// returns if the copied section was entirely blank
+fn copy_section<R>(
+    records: &mut R,
+    section_length: usize,
+    section_index: usize,
+    primary_length: usize,
+    from_secondary_index: usize,
+    to_secondary_index: usize,
+    direction: Direction,
+) -> bool
+where
+    R: ExactRecords + Resizable,
+{
+    let mut section_is_empty = true;
+    for to_primary_index in 0..section_length {
+        let from_primary_index = to_primary_index + section_index * section_length;
+
+        if from_primary_index < primary_length {
+            let from_position =
+                format_position(direction, from_primary_index, from_secondary_index);
+            if records.get_cell(from_position).as_ref() != "" {
+                section_is_empty = false;
+            }
+            records.swap(
+                from_position,
+                format_position(direction, to_primary_index, to_secondary_index),
+            );
+        }
+    }
+    section_is_empty
+}
+
+/// determine section over direction or vice versa based on behavior
+fn compute_range_order(
+    direction_length: usize,
+    sections_per_direction: usize,
+    behavior: Behavior,
+) -> (Range<usize>, Range<usize>) {
+    match behavior {
+        Behavior::Concat => (1..sections_per_direction, 0..direction_length),
+        Behavior::Zip => (0..direction_length, 1..sections_per_direction),
+    }
+}
+
+/// helper function for shimming both behaviors to work within a single nested loop
+fn compute_range_variables(
+    outer_index: usize,
+    inner_index: usize,
+    direction_length: usize,
+    from_secondary_index: usize,
+    sections_per_direction: usize,
+    filtered_sections: usize,
+    behavior: Behavior,
+) -> (usize, usize, usize) {
+    match behavior {
+        Behavior::Concat => (
+            outer_index,
+            inner_index,
+            inner_index + outer_index * direction_length - filtered_sections,
+        ),
+        Behavior::Zip => (
+            inner_index,
+            from_secondary_index,
+            outer_index * sections_per_direction + inner_index - filtered_sections,
+        ),
+    }
+}
+
+/// utility for arguments of a position easily
+fn format_position(direction: Direction, primary_index: usize, secondary_index: usize) -> Position {
+    match direction {
+        Direction::Column => (secondary_index, primary_index),
+        Direction::Row => (primary_index, secondary_index),
+    }
+}
+
+/// ceil division utility because the std lib ceil_div isn't stable yet
+fn ceil_div(x: usize, y: usize) -> usize {
+    debug_assert!(x != 0);
+    1 + ((x - 1) / y)
+}
diff --git a/tabled/src/settings/style/span_border_correction.rs b/tabled/src/settings/style/span_border_correction.rs
index 0465358..6e529eb 100644
--- a/tabled/src/settings/style/span_border_correction.rs
+++ b/tabled/src/settings/style/span_border_correction.rs
@@ -36,7 +36,7 @@ use crate::{
 /// ];
 ///
 /// let mut table = Table::new(data);
-/// table.with(Modify::new((0, 0)).with("date").with(Span::horizontal(3)));
+/// table.with(Modify::new((0, 0)).with("date").with(Span::column(3)));
 ///
 /// assert_eq!(
 ///     table.to_string(),
@@ -86,8 +86,7 @@ where
 }
 
 fn correct_span_styles(cfg: &mut GridConfig, shape: (usize, usize)) {
-    let spans = cfg.iter_span_columns().collect::<Vec<_>>();
-    for &((row, c), span) in &spans {
+    for ((row, c), span) in cfg.get_column_spans() {
         for col in c..c + span {
             if col == 0 {
                 continue;
@@ -131,8 +130,7 @@ fn correct_span_styles(cfg: &mut GridConfig, shape: (usize, usize)) {
         }
     }
 
-    let spans = cfg.iter_span_rows().collect::<Vec<_>>();
-    for &((r, col), span) in &spans {
+    for ((r, col), span) in cfg.get_row_spans() {
         for row in r + 1..r + span {
             let mut border = cfg.get_border((row, col), shape);
             let borders = cfg.get_borders();
diff --git a/tabled/src/settings/table_option.rs b/tabled/src/settings/table_option.rs
index c601950..d29af1e 100644
--- a/tabled/src/settings/table_option.rs
+++ b/tabled/src/settings/table_option.rs
@@ -14,3 +14,26 @@ where
         T::change(self, records, cfg, dimension);
     }
 }
+
+impl<T, R, D, C> TableOption<R, D, C> for [T]
+where
+    T: TableOption<R, D, C>,
+{
+    fn change(&mut self, records: &mut R, cfg: &mut C, dimension: &mut D) {
+        for opt in self {
+            opt.change(records, cfg, dimension)
+        }
+    }
+}
+
+#[cfg(feature = "std")]
+impl<T, R, D, C> TableOption<R, D, C> for Vec<T>
+where
+    T: TableOption<R, D, C>,
+{
+    fn change(&mut self, records: &mut R, cfg: &mut C, dimension: &mut D) {
+        for opt in self {
+            opt.change(records, cfg, dimension)
+        }
+    }
+}
diff --git a/tabled/src/settings/width/truncate.rs b/tabled/src/settings/width/truncate.rs
index 6959008..44a7ec6 100644
--- a/tabled/src/settings/width/truncate.rs
+++ b/tabled/src/settings/width/truncate.rs
@@ -369,7 +369,7 @@ fn get_decrease_cell_list(
         (0..shape.0)
             .filter(|&row| cfg.is_cell_visible((row, col)))
             .for_each(|row| {
-                let (width, width_min) = match cfg.get_span_column((row, col)) {
+                let (width, width_min) = match cfg.get_column_span((row, col)) {
                     Some(span) => {
                         let width = (col..col + span).map(|i| widths[i]).sum::<usize>();
                         let min_width = (col..col + span).map(|i| min_widths[i]).sum::<usize>();
diff --git a/tabled/src/settings/width/wrap.rs b/tabled/src/settings/width/wrap.rs
index 40bdc18..e668a76 100644
--- a/tabled/src/settings/width/wrap.rs
+++ b/tabled/src/settings/width/wrap.rs
@@ -612,7 +612,7 @@ fn get_decrease_cell_list(
         (0..shape.0)
             .filter(|&row| cfg.is_cell_visible((row, col)))
             .for_each(|row| {
-                let (width, width_min) = match cfg.get_span_column((row, col)) {
+                let (width, width_min) = match cfg.get_column_span((row, col)) {
                     Some(span) => {
                         let width = (col..col + span).map(|i| widths[i]).sum::<usize>();
                         let min_width = (col..col + span).map(|i| min_widths[i]).sum::<usize>();
diff --git a/tabled/src/tables/iter/mod.rs b/tabled/src/tables/iter/mod.rs
index 956e691..a3ef0ae 100644
--- a/tabled/src/tables/iter/mod.rs
+++ b/tabled/src/tables/iter/mod.rs
@@ -33,6 +33,7 @@ use std::{cmp, fmt, io};
 
 use crate::{
     grid::{
+        colors::NoColors,
         compact::{CompactConfig, ExactDimension},
         config::{AlignmentHorizontal, Indent, Sides},
         dimension::Dimension,
@@ -137,19 +138,6 @@ impl<I> IterTable<I> {
         self
     }
 
-    /// Format table into [fmt::Write]er.
-    pub fn fmt<W: fmt::Write>(self, writer: W) -> fmt::Result
-    where
-        I: IntoRecords,
-    {
-        let (width, height) = self.dim.into();
-        let width = exact_list_to_exact_value(width);
-        let height = exact_list_to_exact_value(height);
-        let dims = Dims::new(width, height);
-
-        build_grid(writer, self.records, self.cfg, &self.table, dims)
-    }
-
     /// Build a string.
     ///
     /// We can't implement [`std::string::ToString`] cause it does takes `&self` reference.
@@ -173,6 +161,19 @@ impl<I> IterTable<I> {
         self.fmt(writer)
             .map_err(|err| io::Error::new(io::ErrorKind::Other, err))
     }
+
+    /// Format table into [fmt::Write]er.
+    pub fn fmt<W: fmt::Write>(self, writer: W) -> fmt::Result
+    where
+        I: IntoRecords,
+    {
+        let (width, height) = self.dim.into();
+        let width = exact_list_to_exact_value(width);
+        let height = exact_list_to_exact_value(height);
+        let dims = Dims::new(width, height);
+
+        build_grid(writer, self.records, self.cfg, &self.table, dims)
+    }
 }
 
 fn build_grid<W: fmt::Write, I: IntoRecords>(
@@ -204,12 +205,12 @@ fn build_grid<W: fmt::Write, I: IntoRecords>(
                 let records = LimitRows::new(records, limit);
                 let records = build_records(records, content_width, count_columns, count_rows);
                 let cfg = GridConfig::from(config);
-                return Grid::new(records, dims, cfg).build(writer);
+                return Grid::new(records, dims, cfg, NoColors).build(writer);
             }
             None => {
                 let records = build_records(records, content_width, count_columns, count_rows);
                 let cfg = GridConfig::from(config);
-                return Grid::new(records, dims, cfg).build(writer);
+                return Grid::new(records, dims, cfg, NoColors).build(writer);
             }
         }
     }
@@ -259,12 +260,12 @@ fn build_grid<W: fmt::Write, I: IntoRecords>(
             let records = LimitRows::new(records, limit);
             let records = build_records(records, contentw, count_columns, count_rows);
             let cfg = GridConfig::from(config);
-            Grid::new(records, dimension, cfg).build(writer)
+            Grid::new(records, dimension, cfg, NoColors).build(writer)
         }
         None => {
             let records = build_records(records, contentw, count_columns, count_rows);
             let cfg = GridConfig::from(config);
-            Grid::new(records, dimension, cfg).build(writer)
+            Grid::new(records, dimension, cfg, NoColors).build(writer)
         }
     }
 }
diff --git a/tabled/src/tables/table/mod.rs b/tabled/src/tables/table/mod.rs
index dccd737..8fe07d9 100644
--- a/tabled/src/tables/table/mod.rs
+++ b/tabled/src/tables/table/mod.rs
@@ -23,6 +23,7 @@ use crate::{
 };
 
 pub use dimension::TableDimension;
+use papergrid::colors::NoColors;
 
 /// The structure provides an interface for building a table for types that implements [`Tabled`].
 ///
@@ -253,12 +254,11 @@ impl fmt::Display for Table {
         let mut dimension = self.dimension.clone();
         dimension.estimate(&self.records, &config);
 
-        if !self.config.colors.is_empty() {
-            Grid::new(&self.records, &dimension, config.as_ref())
-                .with_colors(&self.config.colors)
-                .build(f)
+        let colors = &self.config.colors;
+        if !colors.is_empty() {
+            Grid::new(&self.records, &dimension, config, colors).build(f)
         } else {
-            Grid::new(&self.records, &dimension, config.as_ref()).build(f)
+            Grid::new(&self.records, &dimension, config, NoColors).build(f)
         }
     }
 }


Test patch:
diff --git a/papergrid/tests/render.rs b/papergrid/tests/render.rs
index 281c6ab..edc8346 100644
--- a/papergrid/tests/render.rs
+++ b/papergrid/tests/render.rs
@@ -16,6 +16,7 @@ mod util;
 
 use std::vec;
 
+use papergrid::colors::NoColors;
 use papergrid::grid::spanned::{config::GridConfig, Grid};
 use papergrid::{
     config::{AlignmentHorizontal, AlignmentVertical, Borders, Entity},
@@ -53,7 +54,7 @@ test_table!(
         let mut cfg = GridConfig::default();
         cfg.set_borders(util::DEFAULT_BORDERS);
 
-        let grid = Grid::new(&data, &dims, &cfg);
+        let grid = Grid::new(&data, &dims, &cfg, NoColors);
         grid.to_string()
     },
     "++"
@@ -78,7 +79,7 @@ test_table!(
             ..Default::default()
         });
 
-        let grid = Grid::new(data, &dims, &cfg);
+        let grid = Grid::new(data, &dims, &cfg, NoColors);
         grid.to_string()
     },
     "┌──────────┐"
diff --git a/papergrid/tests/util.rs b/papergrid/tests/util.rs
index df47c1a..c513d43 100644
--- a/papergrid/tests/util.rs
+++ b/papergrid/tests/util.rs
@@ -79,7 +79,7 @@ fn build_grid(
     let mut dims = ExactDimension::default();
     dims.estimate(&records, &cfg);
 
-    Grid::new(records, dims, cfg)
+    Grid::new(records, dims, cfg, NoColors)
 }
 
 fn records(rows: usize, cols: usize) -> Vec<Vec<String>> {
diff --git a/static_table/tests/static_table.rs b/static_table/tests/static_table.rs
index 6ce10b5..43778d9 100644
--- a/static_table/tests/static_table.rs
+++ b/static_table/tests/static_table.rs
@@ -100,6 +100,193 @@ fn static_table_byte_string() {
     assert_eq!(table, expected);
 }
 
+#[test]
+fn static_table_byte_char() {
+    let table = static_table!([[b'a'], [b'b']]);
+    let expected = "+----+\n\
+                          | 97 |\n\
+                          +----+\n\
+                          | 98 |\n\
+                          +----+";
+    assert_eq!(table, expected);
+}
+
+#[test]
+fn static_table_char() {
+    let table = static_table!([['a'], ['b']]);
+    let expected = "+---+\n\
+                          | a |\n\
+                          +---+\n\
+                          | b |\n\
+                          +---+";
+    assert_eq!(table, expected);
+}
+
+#[test]
+fn static_table_bool() {
+    let table = static_table!([[true], [false]]);
+    let expected = "+-------+\n\
+                          | true  |\n\
+                          +-------+\n\
+                          | false |\n\
+                          +-------+";
+    assert_eq!(table, expected);
+}
+
+#[test]
+fn static_table_u64() {
+    let table = static_table!([[0u64], [1u64]]);
+    let expected = "+---+\n\
+                          | 0 |\n\
+                          +---+\n\
+                          | 1 |\n\
+                          +---+";
+    assert_eq!(table, expected);
+}
+
+#[test]
+fn static_table_u32() {
+    let table = static_table!([[0u32], [1u32]]);
+    let expected = "+---+\n\
+                          | 0 |\n\
+                          +---+\n\
+                          | 1 |\n\
+                          +---+";
+    assert_eq!(table, expected);
+}
+
+#[test]
+fn static_table_u16() {
+    let table = static_table!([[0u16], [1u16]]);
+    let expected = "+---+\n\
+                          | 0 |\n\
+                          +---+\n\
+                          | 1 |\n\
+                          +---+";
+    assert_eq!(table, expected);
+}
+
+#[test]
+fn static_table_u8() {
+    let table = static_table!([[0u8], [1u8]]);
+    let expected = "+---+\n\
+                          | 0 |\n\
+                          +---+\n\
+                          | 1 |\n\
+                          +---+";
+    assert_eq!(table, expected);
+}
+
+#[test]
+fn static_table_i64() {
+    let table = static_table!([[0u64], [1u64]]);
+    let expected = "+---+\n\
+                          | 0 |\n\
+                          +---+\n\
+                          | 1 |\n\
+                          +---+";
+    assert_eq!(table, expected);
+}
+
+#[test]
+fn static_table_i32() {
+    let table = static_table!([[0u32], [1u32]]);
+    let expected = "+---+\n\
+                          | 0 |\n\
+                          +---+\n\
+                          | 1 |\n\
+                          +---+";
+    assert_eq!(table, expected);
+}
+
+#[test]
+fn static_table_i16() {
+    let table = static_table!([[0u16], [1u16]]);
+    let expected = "+---+\n\
+                          | 0 |\n\
+                          +---+\n\
+                          | 1 |\n\
+                          +---+";
+    assert_eq!(table, expected);
+}
+
+#[test]
+fn static_table_i8() {
+    let table = static_table!([[0u8], [1u8]]);
+    let expected = "+---+\n\
+                          | 0 |\n\
+                          +---+\n\
+                          | 1 |\n\
+                          +---+";
+    assert_eq!(table, expected);
+}
+
+#[test]
+fn static_table_isize() {
+    let table = static_table!([[0isize], [1isize]]);
+    let expected = "+---+\n\
+                          | 0 |\n\
+                          +---+\n\
+                          | 1 |\n\
+                          +---+";
+    assert_eq!(table, expected);
+}
+
+#[test]
+fn static_table_isize_minus() {
+    let table = static_table!([[-0], [-1isize]]);
+    let expected = "+----+\n\
+                          | -0 |\n\
+                          +----+\n\
+                          | -1 |\n\
+                          +----+";
+    assert_eq!(table, expected);
+}
+
+#[test]
+fn static_table_usize() {
+    let table = static_table!([[0usize], [1usize]]);
+    let expected = "+---+\n\
+                          | 0 |\n\
+                          +---+\n\
+                          | 1 |\n\
+                          +---+";
+    assert_eq!(table, expected);
+}
+
+#[test]
+fn static_table_float32() {
+    let table = static_table!([[0.0f32], [0.1f32]]);
+    let expected = "+-----+\n\
+                          | 0.0 |\n\
+                          +-----+\n\
+                          | 0.1 |\n\
+                          +-----+";
+    assert_eq!(table, expected);
+}
+
+#[test]
+fn static_table_float64() {
+    let table = static_table!([[0.0f64], [0.1f64]]);
+    let expected = "+-----+\n\
+                          | 0.0 |\n\
+                          +-----+\n\
+                          | 0.1 |\n\
+                          +-----+";
+    assert_eq!(table, expected);
+}
+
+#[test]
+fn static_table_float64_minus() {
+    let table = static_table!([[-0.0f64], [0.1f64]]);
+    let expected = "+------+\n\
+                          | -0.0 |\n\
+                          +------+\n\
+                          | 0.1  |\n\
+                          +------+";
+    assert_eq!(table, expected);
+}
+
 #[test]
 fn static_table_dims_differences_0() {
     let table = static_table!([["Hello World"; 2], ["hello"]]);
diff --git a/static_table/tests/syntax.rs b/static_table/tests/syntax.rs
index 30086b0..072fa4a 100644
--- a/static_table/tests/syntax.rs
+++ b/static_table/tests/syntax.rs
@@ -94,6 +94,11 @@ fn static_table_style() {
     static_table!([[1, 2, 123], [1, 2, 123], [1, 2, 123]], THEME = "MODERN");
 }
 
+// #[test(compail_fail)]
+// fn static_table_verbatim() {
+//     static_table!([[asd], [zxc], [1, 2, 123]]);
+// }
+
 // #[test]
 // fn static_table_with_init_rows() {
 //     static_table::static_table!([[1, 1, 3]; 3]);
diff --git a/tabled/tests/margin_test.rs b/tabled/tests/margin_test.rs
index f1ee106..958ed09 100644
--- a/tabled/tests/margin_test.rs
+++ b/tabled/tests/margin_test.rs
@@ -31,7 +31,7 @@ test_table!(
     margin_without_table_based_on_grid_borders,
     init_table::<3, 3, _, _>([((2, 2), "https://\nwww\n.\nredhat\n.com\n/en")])
         .with(Style::psql())
-        .with(Modify::new(Cell::new(3, 2)).with(Span::horizontal(2)))
+        .with(Modify::new(Cell::new(3, 2)).with(Span::column(2)))
         .with(Margin::new(1, 1, 1, 1).fill('>', '<', 'V', '^')),
     "VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV"
     "> N | column 0 | column 1 | column 2 <"
@@ -51,7 +51,7 @@ test_table!(
     table_with_empty_margin,
     init_table::<3, 3, _, _>([((2, 2), "https://\nwww\n.\nredhat\n.com\n/en")])
         .with(Style::psql())
-        .with(Modify::new(Cell::new(3, 2)).with(Span::horizontal(2)))
+        .with(Modify::new(Cell::new(3, 2)).with(Span::column(2)))
         .with(Margin::new(0, 0, 0, 0).fill('>', '<', 'V', '^')),
     " N | column 0 | column 1 | column 2 "
     "---+----------+----------+----------"
@@ -69,7 +69,7 @@ test_table!(
 fn table_with_margin_and_min_width() {
     let table = create_table::<3, 3>()
         .with(Style::psql())
-        .with(Modify::new(Cell::new(1, 1)).with(Span::horizontal(2)))
+        .with(Modify::new(Cell::new(1, 1)).with(Span::column(2)))
         .with(Margin::new(1, 1, 1, 1).fill('>', '<', 'V', '^'))
         .with(Width::truncate(20))
         .to_string();
@@ -93,7 +93,7 @@ fn table_with_margin_and_min_width() {
 fn table_with_margin_and_max_width() {
     let table = create_table::<3, 3>()
         .with(Style::psql())
-        .with(Modify::new(Cell::new(1, 1)).with(Span::horizontal(2)))
+        .with(Modify::new(Cell::new(1, 1)).with(Span::column(2)))
         .with(Margin::new(1, 1, 1, 1).fill('>', '<', 'V', '^'))
         .with(Width::increase(50))
         .to_string();
@@ -117,14 +117,14 @@ fn table_with_margin_and_max_width() {
 #[ignore = "It's not yet clear what to do with such spans"]
 fn table_0_spanned_with_width() {
     let table = create_table::<0, 0>()
-        .with(Modify::new(Cell::new(0, 0)).with(Span::horizontal(0)))
+        .with(Modify::new(Cell::new(0, 0)).with(Span::column(0)))
         .with(Width::increase(50))
         .to_string();
 
     assert_eq!(table, "++\n|\n++\n");
 
     let table = create_table::<0, 0>()
-        .with(Modify::new(Cell::new(0, 0)).with(Span::horizontal(0)))
+        .with(Modify::new(Cell::new(0, 0)).with(Span::column(0)))
         .with(Width::truncate(50))
         .to_string();
 
diff --git a/tabled/tests/panel_test.rs b/tabled/tests/panel_test.rs
index 98d8785..d6b8534 100644
--- a/tabled/tests/panel_test.rs
+++ b/tabled/tests/panel_test.rs
@@ -296,7 +296,7 @@ test_table!(
         .with(Panel::horizontal(0,"Linux Distributions"))
         .with(Panel::vertical(0,"asd"))
         .with(Panel::vertical(5,"zxc"))
-        .with(Modify::new((1, 3)).with(Span::horizontal(3)).with("wwwww")),
+        .with(Modify::new((1, 3)).with(Span::column(3)).with("wwwww")),
     " asd |       Linux Distributions       | zxc "
     "     +---+----------+-------+----------+     "
     "     | N | column 0 | wwwww | column 2 |     "
@@ -312,7 +312,7 @@ test_table!(
         .with(Panel::horizontal(0,"Linux Distributions"))
         .with(Panel::vertical(0,"asd"))
         .with(Panel::vertical(5,"zxc"))
-        .with(Modify::new((1, 3)).with(Span::horizontal(2)).with("wwwww")),
+        .with(Modify::new((1, 3)).with(Span::column(2)).with("wwwww")),
         " asd |   Linux Distributions    | zxc "
         "     +---+----------+-----+-----+     "
         "     | N | column 0 |   wwwww   |     "
@@ -328,7 +328,7 @@ test_table!(
         .with(Panel::horizontal(2,"Linux Distributions"))
         .with(Panel::vertical(0,"asd"))
         .with(Panel::vertical(5,"zxc"))
-        .with(Modify::new((0, 3)).with(Span::vertical(4)).with("xxxxx")),
+        .with(Modify::new((0, 3)).with(Span::row(4)).with("xxxxx")),
     " asd | N | column 0 | xxxxx | column 2 | zxc "
     "     +---+----------+-------+----------+     "
     "     | 0 |   0-0    |  0-1  |   0-2    |     "
diff --git a/tabled/tests/qc/tests/span.rs b/tabled/tests/qc/tests/span.rs
index a9f5970..5a57b7d 100644
--- a/tabled/tests/qc/tests/span.rs
+++ b/tabled/tests/qc/tests/span.rs
@@ -127,8 +127,8 @@ fn test_data_span_test() {
     set_theme(&mut table, theme);
     table.with(
         Modify::new((1, 2))
-            .with(Span::horizontal(0))
-            .with(Span::vertical(10)),
+            .with(Span::column(0))
+            .with(Span::row(10)),
     );
 
     let output = table.to_string();
@@ -147,7 +147,7 @@ fn set_span_hspan(table: &mut Table, list: &[u8]) {
             }
 
             let span = list[i];
-            table.with(Modify::new((r, c)).with(Span::horizontal(span as usize)));
+            table.with(Modify::new((r, c)).with(Span::column(span as usize)));
 
             i += 1;
         }
@@ -163,7 +163,7 @@ fn set_span_vspan(table: &mut Table, list: &[u8]) {
             }
 
             let span = list[i];
-            table.with(Modify::new((r, c)).with(Span::vertical(span as usize)));
+            table.with(Modify::new((r, c)).with(Span::row(span as usize)));
 
             i += 1;
         }
diff --git a/tabled/tests/render_settings.rs b/tabled/tests/render_settings.rs
index c98e916..349b7e0 100644
--- a/tabled/tests/render_settings.rs
+++ b/tabled/tests/render_settings.rs
@@ -150,9 +150,9 @@ test_table!(
     new_table(tab_data2())
         .with(TabSize::new(4))
         .with(Style::psql())
-        .with(Modify::new((0, 0)).with(Span::horizontal(3)))
-        .with(Modify::new((1, 0)).with(Span::horizontal(2)))
-        .with(Modify::new((2, 1)).with(Span::horizontal(2))),
+        .with(Modify::new((0, 0)).with(Span::column(3)))
+        .with(Modify::new((1, 0)).with(Span::column(2)))
+        .with(Modify::new((2, 1)).with(Span::column(2))),
     "                     N                     | column 2 "
     "----------------------+-----+--------------+----------"
     "     H        ello    World |     0-1      |   0-2    "
diff --git a/tabled/tests/span_test.rs b/tabled/tests/span_test.rs
index cef8f59..16cbd09 100644
--- a/tabled/tests/span_test.rs
+++ b/tabled/tests/span_test.rs
@@ -1,7 +1,11 @@
 #![cfg(feature = "std")]
 #![allow(clippy::redundant_clone)]
 
+use std::iter::FromIterator;
+
+use papergrid::config::Position;
 use tabled::{
+    builder::Builder,
     settings::{
         object::{Columns, Segment},
         style::{Border, BorderSpanCorrection, Style},
@@ -19,7 +23,7 @@ test_table!(
     create_table::<3, 3>()
         .with(Style::psql())
         .with(Modify::new(Segment::all()).with(Alignment::left()))
-        .with(Modify::new(Columns::single(0)).with(Span::horizontal(2))),
+        .with(Modify::new(Columns::single(0)).with(Span::column(2))),
     " N | column 1 | column 2 "
     "-+-+----------+----------"
     " 0 | 0-1      | 0-2      "
@@ -32,7 +36,7 @@ test_table!(
     create_table::<3, 3>()
         .with(Style::psql())
         .with(Modify::new(Segment::all()).with(Alignment::left()))
-        .with(Modify::new(Columns::new(1..2)).with(Span::horizontal(2))),
+        .with(Modify::new(Columns::new(1..2)).with(Span::column(2))),
     " N | column 0 | column 2 "
     "---+-----+----+----------"
     " 0 | 0-0      | 0-2      "
@@ -45,7 +49,7 @@ test_table!(
     create_table::<3, 3>()
         .with(Style::psql())
         .with(Modify::new(Segment::all()).with(Alignment::left()))
-        .with(Modify::new(Columns::single(0)).with(Span::horizontal(4))),
+        .with(Modify::new(Columns::single(0)).with(Span::column(4))),
     " N "
     "+++"
     " 0 "
@@ -58,7 +62,7 @@ test_table!(
     create_table::<3, 3>()
         .with(Style::psql())
         .with(Modify::new(Segment::all()).with(Alignment::left()))
-        .with(Modify::new((0, 0)).with(Span::horizontal(2))),
+        .with(Modify::new((0, 0)).with(Span::column(2))),
     " N       | column 1 | column 2 "
     "---+-----+----------+----------"
     " 0 | 0-0 | 0-1      | 0-2      "
@@ -71,7 +75,7 @@ test_table!(
     create_table::<3, 3>()
         .with(Style::psql())
         .with(Modify::new(Segment::all()).with(Alignment::left()))
-        .with(Modify::new((1, 0)).with(Span::horizontal(2))),
+        .with(Modify::new((1, 0)).with(Span::column(2))),
     " N | column 0 | column 1 | column 2 "
     "---+----------+----------+----------"
     " 0            | 0-1      | 0-2      "
@@ -83,7 +87,7 @@ test_table!(
     cell_span_test_2,
     create_table::<3, 3>()
         .with(Style::psql())
-        .with(Modify::new((2, 0)).with(Span::horizontal(2))),
+        .with(Modify::new((2, 0)).with(Span::column(2))),
     " N | column 0 | column 1 | column 2 "
     "---+----------+----------+----------"
     " 0 |   0-0    |   0-1    |   0-2    "
@@ -96,7 +100,7 @@ test_table!(
     create_table::<3, 3>()
         .with(Style::psql())
         .with(Modify::new(Segment::all()).with(Alignment::left()))
-        .with(Modify::new((3, 0)).with(Span::horizontal(2))),
+        .with(Modify::new((3, 0)).with(Span::column(2))),
     " N | column 0 | column 1 | column 2 "
     "---+----------+----------+----------"
     " 0 | 0-0      | 0-1      | 0-2      "
@@ -109,7 +113,7 @@ test_table!(
     create_table::<3, 3>()
         .with(Style::psql())
         .with(Modify::new(Segment::all()).with(Alignment::left()))
-        .with(Modify::new((0, 1)).with(Span::horizontal(2))),
+        .with(Modify::new((0, 1)).with(Span::column(2))),
     " N | column 0  | column 2 "
     "---+-----+-----+----------"
     " 0 | 0-0 | 0-1 | 0-2      "
@@ -122,7 +126,7 @@ test_table!(
     create_table::<3, 3>()
         .with(Style::psql())
         .with(Modify::new(Segment::all()).with(Alignment::left()))
-        .with(Modify::new((1, 1)).with(Span::horizontal(2))),
+        .with(Modify::new((1, 1)).with(Span::column(2))),
     " N | column 0 | column 1 | column 2 "
     "---+----------+----------+----------"
     " 0 | 0-0                 | 0-2      "
@@ -135,7 +139,7 @@ test_table!(
     create_table::<3, 3>()
         .with(Style::psql())
         .with(Modify::new(Segment::all()).with(Alignment::left()))
-        .with(Modify::new((2, 1)).with(Span::horizontal(2))),
+        .with(Modify::new((2, 1)).with(Span::column(2))),
     " N | column 0 | column 1 | column 2 "
     "---+----------+----------+----------"
     " 0 | 0-0      | 0-1      | 0-2      "
@@ -148,7 +152,7 @@ test_table!(
     create_table::<3, 3>()
         .with(Style::psql())
         .with(Modify::new(Segment::all()).with(Alignment::left()))
-        .with(Modify::new((3, 1)).with(Span::horizontal(2))),
+        .with(Modify::new((3, 1)).with(Span::column(2))),
     " N | column 0 | column 1 | column 2 "
     "---+----------+----------+----------"
     " 0 | 0-0      | 0-1      | 0-2      "
@@ -160,7 +164,7 @@ test_table!(
     cell_span_test_8,
     create_table::<3, 3>()
         .with(Style::psql())
-        .with(Modify::new((0, 2)).with(Span::horizontal(2))),
+        .with(Modify::new((0, 2)).with(Span::column(2))),
     " N | column 0 | column 1  "
     "---+----------+-----+-----"
     " 0 |   0-0    | 0-1 | 0-2 "
@@ -172,7 +176,7 @@ test_table!(
     cell_span_test_9,
     create_table::<3, 3>()
         .with(Style::psql())
-        .with(Modify::new((1, 2)).with(Span::horizontal(2))),
+        .with(Modify::new((1, 2)).with(Span::column(2))),
     " N | column 0 | column 1 | column 2 "
     "---+----------+----------+----------"
     " 0 |   0-0    |         0-1         "
@@ -184,7 +188,7 @@ test_table!(
     cell_span_test_10,
     create_table::<3, 3>()
         .with(Style::psql())
-        .with(Modify::new((2, 2)).with(Span::horizontal(2))),
+        .with(Modify::new((2, 2)).with(Span::column(2))),
     " N | column 0 | column 1 | column 2 "
     "---+----------+----------+----------"
     " 0 |   0-0    |   0-1    |   0-2    "
@@ -196,7 +200,7 @@ test_table!(
     cell_span_test_11,
     create_table::<3, 3>()
         .with(Style::psql())
-        .with(Modify::new((3, 2)).with(Span::horizontal(2))),
+        .with(Modify::new((3, 2)).with(Span::column(2))),
     " N | column 0 | column 1 | column 2 "
     "---+----------+----------+----------"
     " 0 |   0-0    |   0-1    |   0-2    "
@@ -208,7 +212,7 @@ test_table!(
     span_multiline,
     init_table::<3, 3, _, _>([((2, 2), "https://\nwww\n.\nredhat\n.com\n/en")])
         .with(Style::psql())
-        .with(Modify::new((3, 2)).with(Span::horizontal(2))),
+        .with(Modify::new((3, 2)).with(Span::column(2))),
     " N | column 0 | column 1 | column 2 "
     "---+----------+----------+----------"
     " 0 |   0-0    |   0-1    |   0-2    "
@@ -227,8 +231,8 @@ test_table!(
         .with(Style::psql())
         .with(Modify::new(Segment::all()).with(Padding::new(3, 0, 0, 0)))
         .with(Modify::new(Segment::all()).with(Alignment::left()))
-        .with(Modify::new((1, 1)).with(Span::horizontal(3)))
-        .with(Modify::new((3, 1)).with(Span::horizontal(3))),
+        .with(Modify::new((1, 1)).with(Span::column(3)))
+        .with(Modify::new((3, 1)).with(Span::column(3))),
     "   N|   column 0|   column 1|   column 2"
     "----+-----------+-----------+-----------"
     "   0|   0-0                             "
@@ -242,37 +246,37 @@ test_table!(
         .with(Style::modern())
         .with(
             Modify::new((0, 0))
-                .with(Span::horizontal(5))
+                .with(Span::column(5))
                 .with("span all 5 columns"),
         )
         .with(
             Modify::new((1, 0))
-                .with(Span::horizontal(4))
+                .with(Span::column(4))
                 .with("span 4 columns"),
         )
         .with(
             Modify::new((2, 0))
-                .with(Span::horizontal(3))
+                .with(Span::column(3))
                 .with("span 3 columns"),
         )
         .with(
             Modify::new((2, 3))
-                .with(Span::horizontal(2))
+                .with(Span::column(2))
                 .with("span 2 columns"),
         )
         .with(
             Modify::new((3, 0))
-                .with(Span::horizontal(2))
+                .with(Span::column(2))
                 .with("span 3 columns"),
         )
         .with(
             Modify::new((3, 2))
-                .with(Span::horizontal(3))
+                .with(Span::column(3))
                 .with("span 3 columns"),
         )
         .with(
             Modify::new((4, 1))
-                .with(Span::horizontal(4))
+                .with(Span::column(4))
                 .with("span 4 columns"),
         ),
     "┌───────────────┬───────────────┬───────────────┬───────────────┬───────────────┐"
@@ -294,7 +298,7 @@ test_table!(
     span_with_panel_test_0,
     new_table([[1, 2, 3]])
         .with(Panel::horizontal(0,"Tabled Releases"))
-        .with(Modify::new((1, 0)).with(Span::horizontal(2)))
+        .with(Modify::new((1, 0)).with(Span::column(2)))
         .with(Style::ascii()),
     "+-----+-----+-----+"
     "| Tabled Releases |"
@@ -309,7 +313,7 @@ test_table!(
     span_with_panel_test_1,
     new_table([[1, 2, 3], [4, 5, 6]])
         .with(Panel::horizontal(0,"Tabled Releases"))
-        .with(Modify::new((2, 0)).with(Span::horizontal(2)))
+        .with(Modify::new((2, 0)).with(Span::column(2)))
         .with(Style::ascii()),
     "+-----+-----+-----+"
     "| Tabled Releases |"
@@ -326,8 +330,8 @@ test_table!(
     span_with_panel_test_2,
     new_table([[1, 2, 3], [4, 5, 6]])
         .with(Panel::horizontal(0,"Tabled Releases"))
-        .with(Modify::new((1, 0)).with(Span::horizontal(2)))
-        .with(Modify::new((2, 0)).with(Span::horizontal(2)))
+        .with(Modify::new((1, 0)).with(Span::column(2)))
+        .with(Modify::new((2, 0)).with(Span::column(2)))
         .with(Style::ascii()),
     "+-----+-----+-----+"
     "| Tabled Releases |"
@@ -344,7 +348,7 @@ test_table!(
     span_with_panel_with_correction_test_0,
     new_table([[1, 2, 3]])
         .with(Panel::horizontal(0,"Tabled Releases"))
-        .with(Modify::new((1, 0)).with(Span::horizontal(2)))
+        .with(Modify::new((1, 0)).with(Span::column(2)))
         .with(Style::ascii())
         .with(BorderSpanCorrection),
     "+-----------------+"
@@ -360,7 +364,7 @@ test_table!(
     span_with_panel_with_correction_test_1,
     new_table([[1, 2, 3], [4, 5, 6]])
         .with(Panel::horizontal(0,"Tabled Releases"))
-        .with(Modify::new((2, 0)).with(Span::horizontal(2)))
+        .with(Modify::new((2, 0)).with(Span::column(2)))
         .with(Style::ascii())
         .with(BorderSpanCorrection),
     "+-----------------+"
@@ -378,8 +382,8 @@ test_table!(
     span_with_panel_with_correction_test_2,
     new_table([[1, 2, 3], [4, 5, 6]])
         .with(Panel::horizontal(0,"Tabled Releases"))
-        .with(Modify::new((1, 0)).with(Span::horizontal(2)))
-        .with(Modify::new((2, 0)).with(Span::horizontal(2)))
+        .with(Modify::new((1, 0)).with(Span::column(2)))
+        .with(Modify::new((2, 0)).with(Span::column(2)))
         .with(Style::ascii())
         .with(BorderSpanCorrection),
     "+-----------------+"
@@ -400,7 +404,7 @@ fn span_column_exceeds_boundaries_test() {
     // todo: determine if it's the right behaiviour
 
     create_table::<3, 3>()
-        .with(Modify::new(Columns::single(0)).with(Span::horizontal(100)))
+        .with(Modify::new(Columns::single(0)).with(Span::column(100)))
         .to_string();
 }
 
@@ -414,7 +418,7 @@ fn span_cell_exceeds_boundaries_test() {
     let table = create_table::<3, 3>()
         .with(Style::psql())
         .with(Modify::new(Segment::all()).with(Alignment::left()))
-        .with(Modify::new((0, 0)).with(Span::horizontal(20)))
+        .with(Modify::new((0, 0)).with(Span::column(20)))
         .to_string();
 
     assert_eq!(
@@ -431,7 +435,7 @@ fn span_cell_exceeds_boundaries_test() {
     let table = create_table::<3, 3>()
         .with(Style::psql())
         .with(Modify::new(Segment::all()).with(Alignment::left()))
-        .with(Modify::new((1, 1)).with(Span::horizontal(20)))
+        .with(Modify::new((1, 1)).with(Span::column(20)))
         .to_string();
 
     assert_eq!(
@@ -448,7 +452,7 @@ fn span_cell_exceeds_boundaries_test() {
     let table = create_table::<3, 3>()
         .with(Style::psql())
         .with(Modify::new(Segment::all()).with(Alignment::left()))
-        .with(Modify::new((1, 0)).with(Span::horizontal(20)))
+        .with(Modify::new((1, 0)).with(Span::column(20)))
         .to_string();
 
     assert_eq!(
@@ -468,7 +472,7 @@ fn span_cell_exceeds_boundaries_test() {
 fn span_zero_test() {
     let table = create_table::<3, 3>()
         .with(Style::psql())
-        .with(Modify::new((0, 0)).with(Span::horizontal(0)))
+        .with(Modify::new((0, 0)).with(Span::column(0)))
         .to_string();
 
     assert_eq!(
@@ -484,7 +488,7 @@ fn span_zero_test() {
 
     let table = create_table::<3, 3>()
         .with(Style::psql())
-        .with(Modify::new((0, 1)).with(Span::horizontal(0)))
+        .with(Modify::new((0, 1)).with(Span::column(0)))
         .to_string();
 
     assert_eq!(
@@ -500,7 +504,7 @@ fn span_zero_test() {
 
     let table = create_table::<3, 3>()
         .with(Style::psql())
-        .with(Modify::new((0, 2)).with(Span::horizontal(0)))
+        .with(Modify::new((0, 2)).with(Span::column(0)))
         .to_string();
 
     assert_eq!(
@@ -516,7 +520,7 @@ fn span_zero_test() {
 
     let table = create_table::<3, 3>()
         .with(Style::psql())
-        .with(Modify::new((0, 3)).with(Span::horizontal(0)))
+        .with(Modify::new((0, 3)).with(Span::column(0)))
         .to_string();
 
     assert_eq!(
@@ -532,7 +536,7 @@ fn span_zero_test() {
 
     let table = create_table::<3, 3>()
         .with(Style::psql())
-        .with(Modify::new((0, 4)).with(Span::horizontal(0)))
+        .with(Modify::new((0, 4)).with(Span::column(0)))
         .to_string();
 
     assert_eq!(
@@ -548,11 +552,11 @@ fn span_zero_test() {
 
     let table = create_table::<3, 3>()
         .with(Style::psql())
-        .with(Modify::new((0, 0)).with(Span::horizontal(0)))
-        .with(Modify::new((1, 1)).with(Span::horizontal(0)))
-        .with(Modify::new((2, 2)).with(Span::horizontal(0)))
-        .with(Modify::new((3, 2)).with(Span::horizontal(0)))
-        .with(Modify::new((3, 1)).with(Span::horizontal(0)))
+        .with(Modify::new((0, 0)).with(Span::column(0)))
+        .with(Modify::new((1, 1)).with(Span::column(0)))
+        .with(Modify::new((2, 2)).with(Span::column(0)))
+        .with(Modify::new((3, 2)).with(Span::column(0)))
+        .with(Modify::new((3, 1)).with(Span::column(0)))
         .to_string();
 
     assert_eq!(
@@ -572,7 +576,7 @@ fn span_zero_test() {
 fn span_all_table_to_zero_test() {
     let table = create_table::<2, 2>()
         .with(Style::psql())
-        .with(Modify::new(Segment::all()).with(Span::horizontal(0)))
+        .with(Modify::new(Segment::all()).with(Span::column(0)))
         .to_string();
 
     // todo: determine whether it's correct
@@ -592,7 +596,7 @@ mod row {
                 .clone()
                 .with(Style::ascii())
                 .with(Modify::new(Segment::all()).with(Alignment::left()))
-                .with(Modify::new(Rows::single(0)).with(Span::vertical(2)))
+                .with(Modify::new(Rows::single(0)).with(Span::row(2)))
                 .to_string();
 
             assert_eq!(
@@ -612,7 +616,7 @@ mod row {
                 .clone()
                 .with(Style::psql())
                 .with(Modify::new(Segment::all()).with(Alignment::left()))
-                .with(Modify::new(Rows::single(0)).with(Span::vertical(2)))
+                .with(Modify::new(Rows::single(0)).with(Span::row(2)))
                 .to_string();
 
             assert_eq!(
@@ -629,7 +633,7 @@ mod row {
                 .clone()
                 .with(Style::psql())
                 .with(Modify::new(Segment::all()).with(Alignment::left()))
-                .with(Modify::new(Rows::new(1..2)).with(Span::vertical(2)))
+                .with(Modify::new(Rows::new(1..2)).with(Span::row(2)))
                 .to_string();
 
             assert_eq!(
@@ -647,7 +651,7 @@ mod row {
                 .clone()
                 .with(Style::psql())
                 .with(Modify::new(Segment::all()).with(Alignment::left()))
-                .with(Modify::new(Rows::single(0)).with(Span::vertical(4)))
+                .with(Modify::new(Rows::single(0)).with(Span::row(4)))
                 .to_string();
 
             assert_eq!(table, " N + column 0 + column 1 + column 2 ");
@@ -665,7 +669,7 @@ mod row {
                     .clone()
                     .with(Style::psql())
                     .with(Modify::new(Segment::all()).with(Alignment::left()))
-                    .with(Modify::new((0, 0)).with(Span::vertical(2)))
+                    .with(Modify::new((0, 0)).with(Span::row(2)))
                     .to_string();
 
                 assert_eq!(
@@ -684,7 +688,7 @@ mod row {
                     .clone()
                     .with(Style::psql())
                     .with(Modify::new(Segment::all()).with(Alignment::left()))
-                    .with(Modify::new((1, 0)).with(Span::vertical(2)))
+                    .with(Modify::new((1, 0)).with(Span::row(2)))
                     .to_string();
 
                 assert_eq!(
@@ -702,7 +706,7 @@ mod row {
                 let table = table
                     .clone()
                     .with(Style::psql())
-                    .with(Modify::new((2, 0)).with(Span::vertical(2)))
+                    .with(Modify::new((2, 0)).with(Span::row(2)))
                     .to_string();
 
                 assert_eq!(
@@ -726,7 +730,7 @@ mod row {
                     .clone()
                     .with(Style::psql())
                     .with(Modify::new(Segment::all()).with(Alignment::left()))
-                    .with(Modify::new((0, 1)).with(Span::vertical(2)))
+                    .with(Modify::new((0, 1)).with(Span::row(2)))
                     .to_string();
 
                 assert_eq!(
@@ -745,7 +749,7 @@ mod row {
                     .clone()
                     .with(Style::psql())
                     .with(Modify::new(Segment::all()).with(Alignment::left()))
-                    .with(Modify::new((0, 2)).with(Span::vertical(2)))
+                    .with(Modify::new((0, 2)).with(Span::row(2)))
                     .to_string();
 
                 assert_eq!(
@@ -763,7 +767,7 @@ mod row {
                 let table = table
                     .clone()
                     .with(Style::psql())
-                    .with(Modify::new((0, 3)).with(Span::vertical(2)))
+                    .with(Modify::new((0, 3)).with(Span::row(2)))
                     .to_string();
 
                 assert_eq!(
@@ -786,7 +790,7 @@ mod row {
                     .clone()
                     .with(Style::psql())
                     .with(Modify::new(Segment::all()).with(Alignment::left()))
-                    .with(Modify::new((1, 1)).with(Span::vertical(2)))
+                    .with(Modify::new((1, 1)).with(Span::row(2)))
                     .to_string();
 
                 assert_eq!(
@@ -805,7 +809,7 @@ mod row {
                     .clone()
                     .with(Style::psql())
                     .with(Modify::new(Segment::all()).with(Alignment::left()))
-                    .with(Modify::new((2, 1)).with(Span::vertical(2)))
+                    .with(Modify::new((2, 1)).with(Span::row(2)))
                     .to_string();
 
                 assert_eq!(
@@ -827,7 +831,7 @@ mod row {
                     .clone()
                     .with(Style::psql())
                     .with(Modify::new(Segment::all()).with(Alignment::left()))
-                    .with(Modify::new((1, 2)).with(Span::vertical(2)))
+                    .with(Modify::new((1, 2)).with(Span::row(2)))
                     .to_string();
 
                 assert_eq!(
@@ -846,7 +850,7 @@ mod row {
                     .clone()
                     .with(Style::psql())
                     .with(Modify::new(Segment::all()).with(Alignment::left()))
-                    .with(Modify::new((2, 2)).with(Span::vertical(2)))
+                    .with(Modify::new((2, 2)).with(Span::row(2)))
                     .to_string();
 
                 assert_eq!(
@@ -868,7 +872,7 @@ mod row {
                     .clone()
                     .with(Style::psql())
                     .with(Modify::new(Segment::all()).with(Alignment::left()))
-                    .with(Modify::new((1, 3)).with(Span::vertical(2)))
+                    .with(Modify::new((1, 3)).with(Span::row(2)))
                     .to_string();
 
                 assert_eq!(
@@ -887,7 +891,7 @@ mod row {
                     .clone()
                     .with(Style::psql())
                     .with(Modify::new(Segment::all()).with(Alignment::left()))
-                    .with(Modify::new((2, 3)).with(Span::vertical(2)))
+                    .with(Modify::new((2, 3)).with(Span::row(2)))
                     .to_string();
 
                 assert_eq!(
@@ -908,7 +912,7 @@ mod row {
     fn span_with_panel_with_correction_test() {
         let data = [[1, 2, 3]];
         let table = Table::new(data)
-            .with(Modify::new((0, 0)).with(Span::vertical(2)))
+            .with(Modify::new((0, 0)).with(Span::row(2)))
             .with(Style::ascii())
             .with(BorderSpanCorrection)
             .to_string();
@@ -926,8 +930,8 @@ mod row {
 
         let data = [[1, 2, 3], [4, 5, 6]];
         let table = Table::new(data)
-            .with(Modify::new((1, 0)).with(Span::vertical(2)))
-            .with(Modify::new((0, 2)).with(Span::vertical(3)))
+            .with(Modify::new((1, 0)).with(Span::row(2)))
+            .with(Modify::new((0, 2)).with(Span::row(3)))
             .with(Style::ascii())
             .with(BorderSpanCorrection)
             .to_string();
@@ -947,9 +951,9 @@ mod row {
 
         let data = [[1, 2, 3], [4, 5, 6]];
         let table = Table::new(data)
-            .with(Modify::new((1, 0)).with(Span::vertical(2)))
-            .with(Modify::new((0, 2)).with(Span::vertical(3)))
-            .with(Modify::new((0, 1)).with(Span::vertical(2)))
+            .with(Modify::new((1, 0)).with(Span::row(2)))
+            .with(Modify::new((0, 2)).with(Span::row(3)))
+            .with(Modify::new((0, 1)).with(Span::row(2)))
             .with(Style::ascii())
             .with(BorderSpanCorrection)
             .to_string();
@@ -968,12 +972,8 @@ mod row {
 
         let data = [[1, 2, 3], [4, 5, 6]];
         let table = Table::new(data)
-            .with(Modify::new((1, 0)).with(Span::vertical(2)))
-            .with(
-                Modify::new((0, 1))
-                    .with(Span::vertical(2))
-                    .with(Span::horizontal(2)),
-            )
+            .with(Modify::new((1, 0)).with(Span::row(2)))
+            .with(Modify::new((0, 1)).with(Span::row(2)).with(Span::column(2)))
             .with(Style::ascii())
             .with(BorderSpanCorrection)
             .to_string();
@@ -995,8 +995,8 @@ mod row {
     fn span_example_test() {
         let data = [["just 1 column"; 5]; 5];
 
-        let h_span = |r, c, span| Modify::new((r, c)).with(Span::horizontal(span));
-        let v_span = |r, c, span| Modify::new((r, c)).with(Span::vertical(span));
+        let h_span = |r, c, span| Modify::new((r, c)).with(Span::column(span));
+        let v_span = |r, c, span| Modify::new((r, c)).with(Span::row(span));
 
         let table = Table::new(data)
             .with(h_span(0, 0, 5).with(String::from("span all 5 columns")))
@@ -1040,7 +1040,7 @@ mod row {
             ["7", "8", "9"],
         ];
         let table = Table::new(data)
-            .with(Modify::new((1, 1)).with(Span::vertical(3)))
+            .with(Modify::new((1, 1)).with(Span::row(3)))
             .with(Style::modern())
             .with(Highlight::new(Columns::single(1), Border::filled('*')))
             .to_string();
@@ -1073,11 +1073,7 @@ fn highlight_row_col_span_test() {
         ["7", "8", "9", "0"],
     ];
     let table = Table::new(data)
-        .with(
-            Modify::new((1, 1))
-                .with(Span::vertical(3))
-                .with(Span::horizontal(2)),
-        )
+        .with(Modify::new((1, 1)).with(Span::row(3)).with(Span::column(2)))
         .with(Style::modern())
         .with(Highlight::new(Columns::new(1..3), Border::filled('*')))
         .to_string();
@@ -1103,7 +1099,7 @@ fn highlight_row_col_span_test() {
 
 test_table!(
     column_span_bigger_then_max,
-    create_table::<3, 3>().with(Modify::new((0, 0)).with(Span::horizontal(100))),
+    create_table::<3, 3>().with(Modify::new((0, 0)).with(Span::column(100))),
     "+---+-----+-----+-----+"
     "|          N          |"
     "+---+-----+-----+-----+"
@@ -1117,7 +1113,7 @@ test_table!(
 
 test_table!(
     row_span_bigger_then_max,
-    create_table::<3, 3>().with(Modify::new((0, 0)).with(Span::vertical(100))),
+    create_table::<3, 3>().with(Modify::new((0, 0)).with(Span::row(100))),
     "+---+----------+----------+----------+"
     "| N | column 0 | column 1 | column 2 |"
     "+   +----------+----------+----------+"
@@ -1131,7 +1127,7 @@ test_table!(
 
 test_table!(
     column_span_invalid_position_row,
-    create_table::<3, 3>().with(Modify::new((1000, 0)).with(Span::horizontal(2))),
+    create_table::<3, 3>().with(Modify::new((1000, 0)).with(Span::column(2))),
     "+---+----------+----------+----------+"
     "| N | column 0 | column 1 | column 2 |"
     "+---+----------+----------+----------+"
@@ -1145,7 +1141,7 @@ test_table!(
 
 test_table!(
     column_span_invalid_position_column,
-    create_table::<3, 3>().with(Modify::new((0, 1000)).with(Span::horizontal(2))),
+    create_table::<3, 3>().with(Modify::new((0, 1000)).with(Span::column(2))),
     "+---+----------+----------+----------+"
     "| N | column 0 | column 1 | column 2 |"
     "+---+----------+----------+----------+"
@@ -1159,7 +1155,7 @@ test_table!(
 
 test_table!(
     column_span_invalid_position_row_and_column,
-    create_table::<3, 3>().with(Modify::new((1000, 1000)).with(Span::horizontal(2))),
+    create_table::<3, 3>().with(Modify::new((1000, 1000)).with(Span::column(2))),
     "+---+----------+----------+----------+"
     "| N | column 0 | column 1 | column 2 |"
     "+---+----------+----------+----------+"
@@ -1173,7 +1169,7 @@ test_table!(
 
 test_table!(
     row_span_invalid_position_row,
-    create_table::<3, 3>().with(Modify::new((1000, 0)).with(Span::vertical(2))),
+    create_table::<3, 3>().with(Modify::new((1000, 0)).with(Span::row(2))),
     "+---+----------+----------+----------+"
     "| N | column 0 | column 1 | column 2 |"
     "+---+----------+----------+----------+"
@@ -1187,7 +1183,7 @@ test_table!(
 
 test_table!(
     row_span_invalid_position_column,
-    create_table::<3, 3>().with(Modify::new((0, 1000)).with(Span::vertical(2))),
+    create_table::<3, 3>().with(Modify::new((0, 1000)).with(Span::row(2))),
     "+---+----------+----------+----------+"
     "| N | column 0 | column 1 | column 2 |"
     "+---+----------+----------+----------+"
@@ -1201,7 +1197,7 @@ test_table!(
 
 test_table!(
     row_span_invalid_position_row_and_column,
-    create_table::<3, 3>().with(Modify::new((1000, 1000)).with(Span::vertical(2))),
+    create_table::<3, 3>().with(Modify::new((1000, 1000)).with(Span::row(2))),
     "+---+----------+----------+----------+"
     "| N | column 0 | column 1 | column 2 |"
     "+---+----------+----------+----------+"
@@ -1212,3 +1208,27 @@ test_table!(
     "| 2 |   2-0    |   2-1    |   2-2    |"
     "+---+----------+----------+----------+"
 );
+
+test_table!(
+    fix_qc_0,
+    {
+        let data: [[i64; 39]; 2] = [[2542785870, 2382388818, 2879895075, 2885436543, 2331131758, 219892320, 2503640226, 3754929678, 2206481860, 686909682, 3456499235, 931699300, 1556722454, 958179233, 3896072307, 2042612749, 3354379549, 3272539286, 3926297167, 4294967295, 1650407458, 3322068437, 4294967295, 446762625, 829020202, 4150192304, 3430619243, 3460609391, 2992017103, 513091574, 1514148367, 2166549688, 1401371431, 2854075038, 1286733939, 2959901405, 4152658371, 0, 4224074215], [360331598, 3736108702, 2948800064, 2121584548, 1609988995, 469935087, 3974876615, 2193609088, 3568111892, 732365859, 0, 4294967295, 2994498036, 198522721, 1784359340, 1, 2732726754, 592359359, 3016729802, 878533877, 2997437699, 3573361662, 1111570515, 4294967295, 2245782848, 1383106893, 0, 0, 2869976103, 1611436878, 1682224972, 3249055253, 1562255501, 1370527728, 240481955, 334260406, 2247343342, 3000635978, 395723768]];
+        let row_spans = [2, 1, 27, 111, 226, 221, 121, 22, 252, 30, 115, 85, 255, 126, 26, 245, 36, 50, 255, 211, 47, 114, 174, 173, 145, 138, 78, 198, 253, 229, 151, 243, 242, 30, 52, 116, 177, 25, 1, 32, 28, 48, 225, 103, 17, 243, 0, 128, 69, 206, 221, 105, 239, 74, 184, 48, 178, 237, 120, 228, 184, 1, 132, 118, 14, 187];
+        let col_spans = [7, 91, 56, 246, 73];
+
+        let data = data.iter().map(|row| row.iter().map(ToString::to_string));
+        let rspans = create_span_list(2, 39).zip(row_spans.iter()).map(|(pos, span)| Modify::new(pos).with(Span::column(*span))).collect::<Vec<_>>();
+        let cspans = create_span_list(2, 39).zip(col_spans.iter()).map(|(pos, span)| Modify::new(pos).with(Span::row(*span))).collect::<Vec<_>>();
+
+        Builder::from_iter(data).build().with(Style::ascii()).with(rspans).with(cspans).to_string()
+    },
+    "+------+-----++++++++++++++++++++++++++++------------+------------+------------+------------+------------+-----------+-----------+------------+------------+-----------+"
+    "| 2542785870 | 2879895075               | 513091574                                                                                                                    |"
+    "+            +                          +------------+------------+------------+------------+------------+-----------+-----------+------------+------------+-----------+"
+    "|            |                          | 1611436878 | 1682224972 | 3249055253 | 1562255501 | 1370527728 | 240481955 | 334260406 | 2247343342 | 3000635978 | 395723768 |"
+    "+------+-----++++++++++++++++++++++++++++------------+------------+------------+------------+------------+-----------+-----------+------------+------------+-----------+"
+);
+
+fn create_span_list(count_rows: usize, count_cols: usize) -> impl Iterator<Item = Position> {
+    (0..count_rows).flat_map(move |r| (0..count_cols).map(move |c| (r, c)))
+}
diff --git a/tabled/tests/split_test.rs b/tabled/tests/split_test.rs
new file mode 100644
index 0000000..88107f9
--- /dev/null
+++ b/tabled/tests/split_test.rs
@@ -0,0 +1,278 @@
+#![cfg(feature = "std")]
+
+use std::iter::FromIterator;
+use tabled::{builder::Builder, settings::split::Split, Table};
+
+use crate::util::test_table;
+
+mod util;
+
+test_table!(
+    split_column_test,
+    Table::from_iter(['a'..='z']).with(Split::column(12)),
+    "+---+---+---+---+---+---+---+---+---+---+---+---+"
+    "| a | b | c | d | e | f | g | h | i | j | k | l |"
+    "+---+---+---+---+---+---+---+---+---+---+---+---+"
+    "| m | n | o | p | q | r | s | t | u | v | w | x |"
+    "+---+---+---+---+---+---+---+---+---+---+---+---+"
+    "| y | z |   |   |   |   |   |   |   |   |   |   |"
+    "+---+---+---+---+---+---+---+---+---+---+---+---+"
+);
+
+test_table!(
+    split_column_2_test,
+    Table::from_iter(['a'..='z'])
+        .with(Split::column(12))
+        .with(Split::column(4)),
+    "+---+---+---+---+"
+    "| a | b | c | d |"
+    "+---+---+---+---+"
+    "| e | f | g | h |"
+    "+---+---+---+---+"
+    "| i | j | k | l |"
+    "+---+---+---+---+"
+    "| m | n | o | p |"
+    "+---+---+---+---+"
+    "| q | r | s | t |"
+    "+---+---+---+---+"
+    "| u | v | w | x |"
+    "+---+---+---+---+"
+    "| y | z |   |   |"
+    "+---+---+---+---+"
+);
+
+test_table!(
+    split_column_retain_test,
+    Table::from_iter(['a'..='z'])
+        .with(Split::column(12))
+        .with(Split::column(4).retain()),
+    "+---+---+---+---+"
+    "| a | b | c | d |"
+    "+---+---+---+---+"
+    "| e | f | g | h |"
+    "+---+---+---+---+"
+    "| i | j | k | l |"
+    "+---+---+---+---+"
+    "| m | n | o | p |"
+    "+---+---+---+---+"
+    "| q | r | s | t |"
+    "+---+---+---+---+"
+    "| u | v | w | x |"
+    "+---+---+---+---+"
+    "| y | z |   |   |"
+    "+---+---+---+---+"
+    "|   |   |   |   |"
+    "+---+---+---+---+"
+    "|   |   |   |   |"
+    "+---+---+---+---+"
+);
+
+test_table!(
+    split_row_test,
+    Table::from_iter(['a'..='z'])
+        .with(Split::column(12))
+        .with(Split::column(4))
+        .with(Split::row(1).concat()), // take it back to the original shape
+    "+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+"
+    "| a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | y | z |"
+    "+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+"
+);
+
+test_table!(
+    split_row_2_test,
+    Table::from_iter(['a'..='z'])
+        .with(Split::column(12))
+        .with(Split::column(4))
+        .with(Split::row(2).concat()),
+    "+---+---+---+---+---+---+---+---+---+---+---+---+---+---+"
+    "| a | b | c | d | i | j | k | l | q | r | s | t | y | z |"
+    "+---+---+---+---+---+---+---+---+---+---+---+---+---+---+"
+    "| e | f | g | h | m | n | o | p | u | v | w | x |   |   |"
+    "+---+---+---+---+---+---+---+---+---+---+---+---+---+---+"
+);
+
+test_table!(
+    split_colum_index_beyond_size_test,
+    Table::from_iter(['a'..='z'])
+        .with(Split::column(10000)),
+    "+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+"
+    "| a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | y | z |"
+    "+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+"
+);
+
+test_table!(
+    split_row_index_beyond_size_test,
+    Table::from_iter(['a'..='z'])
+        .with(Split::row(10000)),
+    "+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+"
+    "| a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | y | z |"
+    "+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+"
+);
+
+test_table!(
+    split_empty_table_test,
+    Builder::default().build().with(Split::column(10000)),
+    ""
+);
+
+test_table!(
+    split_column_zero_argument_test,
+    Table::from_iter(['a'..='z']).with(Split::column(0)),
+    "+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+"
+    "| a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | y | z |"
+    "+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+"
+);
+
+test_table!(
+    split_row_zero_argument_test,
+    Table::from_iter(['a'..='z']).with(Split::row(0)),
+    "+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+"
+    "| a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | y | z |"
+    "+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+"
+);
+
+test_table!(
+    split_blank_table_test,
+    Table::from_iter([vec![String::new(); 26]]).with(Split::column(12)),
+    "+--+--+--+--+--+--+--+--+--+--+--+--+"
+    "|  |  |  |  |  |  |  |  |  |  |  |  |" // first section is protected
+    "+--+--+--+--+--+--+--+--+--+--+--+--+"
+);
+
+test_table!(
+    split_blank_table_2_test,
+    Table::from_iter([vec![String::new(); 26]]).with(Split::column(12).retain()),
+    "+--+--+--+--+--+--+--+--+--+--+--+--+"
+    "|  |  |  |  |  |  |  |  |  |  |  |  |"
+    "+--+--+--+--+--+--+--+--+--+--+--+--+"
+    "|  |  |  |  |  |  |  |  |  |  |  |  |"
+    "+--+--+--+--+--+--+--+--+--+--+--+--+"
+    "|  |  |  |  |  |  |  |  |  |  |  |  |"
+    "+--+--+--+--+--+--+--+--+--+--+--+--+"
+);
+
+test_table!(
+    split_zip_test,
+    Table::from_iter(['a'..='z'])
+        .with(Split::column(6))
+        .with(Split::row(2)),
+    "+---+---+---+---+---+---+---+---+---+---+---+---+---+---+"
+    "| a | m | y | b | n | z | c | o | d | p | e | q | f | r |"
+    "+---+---+---+---+---+---+---+---+---+---+---+---+---+---+"
+    "| g | s |   | h | t |   | i | u | j | v | k | w | l | x |"
+    "+---+---+---+---+---+---+---+---+---+---+---+---+---+---+"
+);
+
+test_table!(
+    split_concat_test,
+    Table::from_iter(['a'..='z'])
+        .with(Split::column(6))
+        .with(Split::row(2).concat()),
+    "+---+---+---+---+---+---+---+---+---+---+---+---+---+---+"
+    "| a | b | c | d | e | f | m | n | o | p | q | r | y | z |"
+    "+---+---+---+---+---+---+---+---+---+---+---+---+---+---+"
+    "| g | h | i | j | k | l | s | t | u | v | w | x |   |   |"
+    "+---+---+---+---+---+---+---+---+---+---+---+---+---+---+"
+);
+
+test_table!(
+    split_clean_test,
+    Table::from_iter(['a'..='z'])
+        .with(Split::column(12))
+        .with(Split::row(2)),
+    "+---+---+---+---+---+---+---+---+---+---+---+---+---+---+"
+    "| a | y | b | z | c | d | e | f | g | h | i | j | k | l |"
+    "+---+---+---+---+---+---+---+---+---+---+---+---+---+---+"
+    "| m |   | n |   | o | p | q | r | s | t | u | v | w | x |"
+    "+---+---+---+---+---+---+---+---+---+---+---+---+---+---+"
+);
+
+test_table!(
+    split_retain_test,
+    Table::from_iter(['a'..='z'])
+        .with(Split::column(12))
+        .with(Split::row(2).retain()),
+    "+---+---+---+---+---+--+---+--+---+--+---+--+---+--+---+--+---+--+---+--+---+--+---+--+"
+    "| a | y | b | z | c |  | d |  | e |  | f |  | g |  | h |  | i |  | j |  | k |  | l |  |"
+    "+---+---+---+---+---+--+---+--+---+--+---+--+---+--+---+--+---+--+---+--+---+--+---+--+"
+    "| m |   | n |   | o |  | p |  | q |  | r |  | s |  | t |  | u |  | v |  | w |  | x |  |"
+    "+---+---+---+---+---+--+---+--+---+--+---+--+---+--+---+--+---+--+---+--+---+--+---+--+"
+);
+
+test_table!(
+    split_mostly_blank_test,
+    Table::from_iter([vec![
+        "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
+        "", "", "", "", "", "", "", "", "", "", "A",
+    ]]).with(Split::column(5))
+       .with(Split::row(2)),
+    "+--+--+--+---+--+"
+    "|  |  |  |   |  |"
+    "+--+--+--+---+--+"
+    "|  |  |  | A |  |"
+    "+--+--+--+---+--+"
+);
+
+test_table!(
+    split_mostly_blank_retain_test,
+    Table::from_iter([vec![
+        "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
+        "", "", "", "", "", "", "", "", "", "", "A",
+    ]]).with(Split::column(5).retain()),
+    "+--+--+--+---+--+"
+    "|  |  |  |   |  |"
+    "+--+--+--+---+--+"
+    "|  |  |  |   |  |"
+    "+--+--+--+---+--+"
+    "|  |  |  |   |  |"
+    "+--+--+--+---+--+"
+    "|  |  |  |   |  |"
+    "+--+--+--+---+--+"
+    "|  |  |  |   |  |"
+    "+--+--+--+---+--+"
+    "|  |  |  |   |  |"
+    "+--+--+--+---+--+"
+    "|  |  |  | A |  |"
+    "+--+--+--+---+--+"
+);
+
+test_table!(
+    split_scattered_values_test,
+    Table::from_iter([vec![
+        "", "", "", "", "", "g", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
+        "", "", "", "", "", "", "", "", "", "", "A",
+    ]]).with(Split::column(5)),
+    "+---+--+--+---+--+"
+    "|   |  |  |   |  |"
+    "+---+--+--+---+--+"
+    "| g |  |  |   |  |"
+    "+---+--+--+---+--+"
+    "|   |  |  | A |  |"
+    "+---+--+--+---+--+"
+);
+
+test_table!(
+    split_scattered_values_column_and_row_test,
+    Table::from_iter([vec![
+        "", "", "", "", "", "g", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
+        "", "", "", "", "", "", "", "", "", "", "A",
+    ]]).with(Split::column(5)).with(Split::row(2)),
+    "+---+--+--+--+---+--+"
+    "|   |  |  |  | A |  |"
+    "+---+--+--+--+---+--+"
+    "| g |  |  |  |   |  |"
+    "+---+--+--+--+---+--+"
+);
+
+test_table!(
+    split_scattered_values_column_and_row_retain_test,
+    Table::from_iter([vec![
+        "", "", "", "", "", "g", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
+        "", "", "", "", "", "", "", "", "", "", "A",
+    ]]).with(Split::column(5).retain()).with(Split::row(2).retain()),
+    "+---+--+--+--+--+--+--+--+--+--+--+--+--+--+--+---+--+--+--+--+"
+    "|   |  |  |  |  |  |  |  |  |  |  |  |  |  |  | A |  |  |  |  |"
+    "+---+--+--+--+--+--+--+--+--+--+--+--+--+--+--+---+--+--+--+--+"
+    "| g |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   |  |  |  |  |"
+    "+---+--+--+--+--+--+--+--+--+--+--+--+--+--+--+---+--+--+--+--+"
+);
diff --git a/tabled/tests/style_test.rs b/tabled/tests/style_test.rs
index 4f85cbc..cff99b7 100644
--- a/tabled/tests/style_test.rs
+++ b/tabled/tests/style_test.rs
@@ -564,14 +564,14 @@ test_table!(
 test_table!(
     span_correct_test_0,
     create_table::<6, 4>()
-        .with(Modify::new((0, 3)).with(Span::horizontal(2)))
-        .with(Modify::new((1, 0)).with(Span::horizontal(3)))
-        .with(Modify::new((2, 0)).with(Span::horizontal(2)))
-        .with(Modify::new((2, 3)).with(Span::horizontal(2)))
-        .with(Modify::new((3, 0)).with(Span::horizontal(5)))
-        .with(Modify::new((4, 1)).with(Span::horizontal(4)))
-        .with(Modify::new((5, 0)).with(Span::horizontal(5)))
-        .with(Modify::new((6, 0)).with(Span::horizontal(5)))
+        .with(Modify::new((0, 3)).with(Span::column(2)))
+        .with(Modify::new((1, 0)).with(Span::column(3)))
+        .with(Modify::new((2, 0)).with(Span::column(2)))
+        .with(Modify::new((2, 3)).with(Span::column(2)))
+        .with(Modify::new((3, 0)).with(Span::column(5)))
+        .with(Modify::new((4, 1)).with(Span::column(4)))
+        .with(Modify::new((5, 0)).with(Span::column(5)))
+        .with(Modify::new((6, 0)).with(Span::column(5)))
         .with(BorderSpanCorrection),
     "+---+----------+----------+-----------+"
     "| N | column 0 | column 1 | column 2  |"
@@ -593,14 +593,14 @@ test_table!(
 test_table!(
     span_correct_test_1,
     create_table::<6, 4>()
-        .with(Modify::new((0, 0)).with(Span::horizontal(5)))
-        .with(Modify::new((1, 0)).with(Span::horizontal(3)))
-        .with(Modify::new((2, 0)).with(Span::horizontal(2)))
-        .with(Modify::new((2, 3)).with(Span::horizontal(2)))
-        .with(Modify::new((3, 0)).with(Span::horizontal(5)))
-        .with(Modify::new((4, 1)).with(Span::horizontal(4)))
-        .with(Modify::new((5, 0)).with(Span::horizontal(5)))
-        .with(Modify::new((6, 0)).with(Span::horizontal(5)))
+        .with(Modify::new((0, 0)).with(Span::column(5)))
+        .with(Modify::new((1, 0)).with(Span::column(3)))
+        .with(Modify::new((2, 0)).with(Span::column(2)))
+        .with(Modify::new((2, 3)).with(Span::column(2)))
+        .with(Modify::new((3, 0)).with(Span::column(5)))
+        .with(Modify::new((4, 1)).with(Span::column(4)))
+        .with(Modify::new((5, 0)).with(Span::column(5)))
+        .with(Modify::new((6, 0)).with(Span::column(5)))
         .with(BorderSpanCorrection),
     "+----------------------+"
     "|          N           |"
diff --git a/tabled/tests/width_test.rs b/tabled/tests/width_test.rs
index 75bfb6b..b9dee33 100644
--- a/tabled/tests/width_test.rs
+++ b/tabled/tests/width_test.rs
@@ -1302,8 +1302,8 @@ fn max_width_with_span() {
     let mut table = init_table::<3, 3, _, _>([((0, 1), "a long string")]);
     table
         .with(Style::psql())
-        .with(Modify::new((1, 1)).with(Span::horizontal(2)))
-        .with(Modify::new((2, 2)).with(Span::horizontal(2)));
+        .with(Modify::new((1, 1)).with(Span::column(2)))
+        .with(Modify::new((2, 2)).with(Span::column(2)));
 
     table.with(Width::truncate(40));
 
@@ -1522,7 +1522,7 @@ fn min_width_with_span_1() {
 
     let table = new_table(data)
         .with(Style::markdown())
-        .with(Modify::new((1, 0)).with(Span::horizontal(2)))
+        .with(Modify::new((1, 0)).with(Span::column(2)))
         .with(MinWidth::new(100))
         .to_string();
 
@@ -1550,7 +1550,7 @@ fn min_width_with_span_2() {
 
     let table = new_table(data)
         .with(Style::markdown())
-        .with(Modify::new((2, 0)).with(Span::horizontal(2)))
+        .with(Modify::new((2, 0)).with(Span::column(2)))
         .with(MinWidth::new(100))
         .to_string();
 
@@ -1719,7 +1719,7 @@ fn max_width_table_when_cell_has_tabs() {
 fn max_width_truncate_with_big_span() {
     let table = init_table::<3, 3, _, _>([((1, 1), "Hello World With Big Line; Here we gooooooo")])
         .with(Style::markdown())
-        .with(Modify::new((2, 1)).with(Span::horizontal(3)))
+        .with(Modify::new((2, 1)).with(Span::column(3)))
         .with(Width::truncate(40))
         .to_string();
 
@@ -1740,8 +1740,8 @@ fn max_width_truncate_with_big_span() {
         ((2, 2), "Hello World With Big Line; Here"),
     ])
     .with(Style::markdown())
-    .with(Modify::new((2, 1)).with(Span::horizontal(3)))
-    .with(Modify::new((3, 2)).with(Span::horizontal(2)))
+    .with(Modify::new((2, 1)).with(Span::column(3)))
+    .with(Modify::new((3, 2)).with(Span::column(2)))
     .to_string();
 
     assert_eq!(
@@ -1760,8 +1760,8 @@ fn max_width_truncate_with_big_span() {
         ((2, 2), "Hello World With Big Line; Here"),
     ])
     .with(Style::markdown())
-    .with(Modify::new((2, 1)).with(Span::horizontal(3)))
-    .with(Modify::new((3, 2)).with(Span::horizontal(2)))
+    .with(Modify::new((2, 1)).with(Span::column(3)))
+    .with(Modify::new((3, 2)).with(Span::column(2)))
     .with(Width::truncate(40))
     .to_string();
 
@@ -1782,8 +1782,8 @@ fn max_width_truncate_with_big_span() {
         ((2, 2), "Hello World With Big Line; Here"),
     ])
     .with(Style::markdown())
-    .with(Modify::new((2, 1)).with(Span::horizontal(2)))
-    .with(Modify::new((3, 2)).with(Span::horizontal(2)))
+    .with(Modify::new((2, 1)).with(Span::column(2)))
+    .with(Modify::new((3, 2)).with(Span::column(2)))
     .with(Width::truncate(40))
     .to_string();
 
@@ -1804,8 +1804,8 @@ fn max_width_truncate_with_big_span() {
         ((2, 2), "Hello World With Big L"),
     ])
     .with(Style::markdown())
-    .with(Modify::new((2, 1)).with(Span::horizontal(3)))
-    .with(Modify::new((3, 2)).with(Span::horizontal(2)))
+    .with(Modify::new((2, 1)).with(Span::column(3)))
+    .with(Modify::new((3, 2)).with(Span::column(2)))
     .to_string();
 
     assert_eq!(
@@ -1878,7 +1878,7 @@ fn max_width_truncate_priority_max() {
 fn max_width_truncate_priority_max_with_span() {
     let table = init_table::<3, 3, _, _>([((1, 1), "Hello World With Big Line")])
         .with(Style::markdown())
-        .with(Modify::new((2, 1)).with(Span::horizontal(2)))
+        .with(Modify::new((2, 1)).with(Span::column(2)))
         .with(Width::truncate(15).priority::<PriorityMax>())
         .to_string();
 
@@ -1974,7 +1974,7 @@ fn max_width_wrap_priority_max() {
 fn max_width_wrap_priority_max_with_span() {
     let table = init_table::<3, 3, _, _>([((1, 1), "Hello World With Big Line")])
         .with(Style::markdown())
-        .with(Modify::new((2, 1)).with(Span::horizontal(2)))
+        .with(Modify::new((2, 1)).with(Span::column(2)))
         .with(Width::wrap(15).priority::<PriorityMax>())
         .to_string();
 
@@ -2066,7 +2066,7 @@ fn max_width_truncate_priority_min() {
 fn max_width_truncate_priority_min_with_span() {
     let table = init_table::<3, 3, _, _>([((1, 1), "Hello World With Big Line")])
         .with(Style::markdown())
-        .with(Modify::new((2, 1)).with(Span::horizontal(2)))
+        .with(Modify::new((2, 1)).with(Span::column(2)))
         .with(Width::truncate(15).priority::<PriorityMin>())
         .to_string();
 
@@ -2084,7 +2084,7 @@ fn max_width_truncate_priority_min_with_span() {
 
     let table = init_table::<3, 3, _, _>([((1, 1), "Hello World With Big Line")])
         .with(Style::markdown())
-        .with(Modify::new((2, 1)).with(Span::horizontal(2)))
+        .with(Modify::new((2, 1)).with(Span::column(2)))
         .with(Width::truncate(17).priority::<PriorityMin>())
         .to_string();
 
@@ -2164,7 +2164,7 @@ fn max_width_wrap_priority_min() {
 fn max_width_wrap_priority_min_with_span() {
     let table = init_table::<3, 3, _, _>([((1, 1), "Hello World With Big Line")])
         .with(Style::markdown())
-        .with(Modify::new((2, 1)).with(Span::horizontal(2)))
+        .with(Modify::new((2, 1)).with(Span::column(2)))
         .with(Width::wrap(15).priority::<PriorityMin>())
         .to_string();