Repository: zhiburt/tabled
Pull request #450 (2024-11-17 21:42:11)

Address Charset changes and Wrap improvement


Patch:
diff --git a/papergrid/src/util/string.rs b/papergrid/src/util/string.rs
index 23365b9..d1e6b46 100644
--- a/papergrid/src/util/string.rs
+++ b/papergrid/src/util/string.rs
@@ -34,15 +34,7 @@ pub fn get_line_width(text: &str) -> usize {
 
 /// Returns a max string width of a line.
 pub fn get_text_width(text: &str) -> usize {
-    #[cfg(not(feature = "ansi"))]
-    {
-        text.lines().map(get_string_width).max().unwrap_or(0)
-    }
-
-    #[cfg(feature = "ansi")]
-    {
-        text.lines().map(get_line_width).max().unwrap_or(0)
-    }
+    text.lines().map(get_line_width).max().unwrap_or(0)
 }
 
 /// Returns a char width.
@@ -52,17 +44,7 @@ pub fn get_char_width(c: char) -> usize {
 
 /// Returns a string width (accouting all characters).
 pub fn get_string_width(text: &str) -> usize {
-    #[cfg(feature = "std")]
-    {
-        let text = text.replace(|c| c < ' ', "");
-        unicode_width::UnicodeWidthStr::width(text.as_str())
-    }
-
-    #[cfg(not(feature = "std"))]
-    {
-        // todo: make sure it's allright
-        unicode_width::UnicodeWidthStr::width(text)
-    }
+    unicode_width::UnicodeWidthStr::width(text)
 }
 
 /// Calculates a number of lines.
@@ -239,7 +221,7 @@ mod tests {
                 }
                 #[cfg(not(feature = "ansi"))]
                 {
-                    (2, 36)
+                    (2, 37)
                 }
             }
         );
diff --git a/tabled/src/settings/formatting/charset.rs b/tabled/src/settings/formatting/charset.rs
index df9f4fb..f13c819 100644
--- a/tabled/src/settings/formatting/charset.rs
+++ b/tabled/src/settings/formatting/charset.rs
@@ -81,7 +81,7 @@ where
             for col in 0..records.count_columns() {
                 let pos = (row, col);
                 let text = records.get_text(pos);
-                let text = text.replace(['\t', '\r'], "");
+                let text = clean_charset(text);
                 records.set(pos, text);
             }
         }
@@ -97,8 +97,14 @@ where
         let count_cols = records.count_columns();
         for pos in entity.iter(count_rows, count_cols) {
             let text = records.get_text(pos);
-            let text = text.replace(['\t', '\r'], "");
+            let text = clean_charset(text);
             records.set(pos, text);
         }
     }
 }
+
+fn clean_charset(text: &str) -> String {
+    // It's enough for covering '\t' and '\r'
+    // as well as a list of other unwanted escapes.
+    text.replace(|c| c != '\n' && c < ' ', "")
+}
diff --git a/tabled/src/settings/style/border.rs b/tabled/src/settings/style/border.rs
index a8f0a77..bcb5695 100644
--- a/tabled/src/settings/style/border.rs
+++ b/tabled/src/settings/style/border.rs
@@ -2,17 +2,14 @@ use core::marker::PhantomData;
 
 use crate::{
     grid::config::Border as GridBorder,
-    settings::{
-        style::{On, Style},
-        TableOption,
-    },
+    settings::style::{On, Style},
 };
 
 #[cfg(feature = "std")]
 use crate::{
     grid::config::{ColoredConfig, Entity},
     grid::records::{ExactRecords, Records},
-    settings::CellOption,
+    settings::{CellOption, TableOption},
 };
 
 /// Border represents a border of a Cell.
diff --git a/tabled/src/settings/width/wrap.rs b/tabled/src/settings/width/wrap.rs
index 316cec6..f7154f0 100644
--- a/tabled/src/settings/width/wrap.rs
+++ b/tabled/src/settings/width/wrap.rs
@@ -9,7 +9,7 @@ use crate::{
         config::{ColoredConfig, Entity},
         dimension::CompleteDimensionVecRecords,
         records::{EmptyRecords, ExactRecords, IntoRecords, PeekableRecords, Records, RecordsMut},
-        util::string::{get_char_width, get_string_width, get_text_width},
+        util::string::{get_char_width, get_text_width},
     },
     settings::{
         measurement::Measurement,
@@ -19,6 +19,9 @@ use crate::{
     },
 };
 
+#[cfg(not(feature = "ansi"))]
+use crate::grid::util::string::get_string_width;
+
 use super::util::{get_table_widths, get_table_widths_with_total};
 use crate::util::string::split_at_width;
 
@@ -240,16 +243,32 @@ fn build_link_prefix_suffix(url: Option<String>) -> (String, String) {
 
 #[cfg(not(feature = "ansi"))]
 fn chunks(s: &str, width: usize) -> Vec<String> {
+    const REPLACEMENT: char = '\u{FFFD}';
+
     if width == 0 {
         return Vec::new();
     }
 
-    const REPLACEMENT: char = '\u{FFFD}';
+    println!("---> {:?}", s);
 
+    let mut prev_newline = false;
     let mut buf = String::with_capacity(width);
     let mut list = Vec::new();
     let mut i = 0;
     for c in s.chars() {
+        if c == '\n' {
+            if buf.is_empty() {
+                list.push(String::new());
+            } else {
+                list.push(buf);
+            }
+
+            buf = String::with_capacity(width);
+            i = 0;
+            prev_newline = true;
+            continue;
+        }
+
         let c_width = get_char_width(c);
         if i + c_width > width {
             let count_unknowns = width - i;
@@ -264,10 +283,11 @@ fn chunks(s: &str, width: usize) -> Vec<String> {
             list.push(buf);
             buf = String::with_capacity(width);
             i = 0;
+            prev_newline = false;
         }
     }
 
-    if !buf.is_empty() {
+    if !buf.is_empty() || prev_newline {
         list.push(buf);
     }
 
@@ -304,9 +324,12 @@ fn chunks(s: &str, width: usize, prefix: &str, suffix: &str) -> Vec<String> {
         let _ = write!(&mut line, "{}", text_style.start());
 
         while !text_slice.is_empty() {
+            println!("... {} {}", width, line_width);
+
             let available_space = width - line_width;
 
-            let part_width = get_string_width(text_slice);
+            let part_width = get_text_width(text_slice);
+
             if part_width <= available_space {
                 line.push_str(text_slice);
                 line_width += part_width;
@@ -326,10 +349,17 @@ fn chunks(s: &str, width: usize, prefix: &str, suffix: &str) -> Vec<String> {
 
             let (lhs, rhs, (unknowns, split_char)) = split_string_at(text_slice, available_space);
 
+            println!(
+                "---------> {:?} {} {}",
+                text_slice, available_space, split_char
+            );
+            println!("---------> {:?} {}", lhs, get_text_width(lhs));
+            println!("---------> {:?}", rhs);
+
             text_slice = &rhs[split_char..];
 
             line.push_str(lhs);
-            line_width += get_string_width(lhs);
+            line_width += get_text_width(lhs);
 
             const REPLACEMENT: char = '\u{FFFD}';
             line.extend(std::iter::repeat(REPLACEMENT).take(unknowns));
diff --git a/tabled/src/util/string.rs b/tabled/src/util/string.rs
index f616601..428ade5 100644
--- a/tabled/src/util/string.rs
+++ b/tabled/src/util/string.rs
@@ -99,6 +99,12 @@ pub(crate) fn split_at_width(s: &str, at_width: usize) -> (usize, usize, usize)
             break;
         };
 
+        if c == '\n' {
+            width = 0;
+            length += 1;
+            continue;
+        }
+
         let c_width = get_char_width(c);
         let c_length = c.len_utf8();
 


Test patch:
diff --git a/papergrid/tests/grid/format_configuration.rs b/papergrid/tests/grid/format_configuration.rs
index 6f37e3e..c4891de 100644
--- a/papergrid/tests/grid/format_configuration.rs
+++ b/papergrid/tests/grid/format_configuration.rs
@@ -935,19 +935,21 @@ fn tabs_arent_handled() {
 
     let grid = grid(1, 1).data([[json]]);
 
+    println!("{}", grid.clone().build());
+
     assert_eq!(
         grid.build(),
         static_table!(
-            "+-----------------------+"
-            "|{                      |"
+            "+-------------------------+"
+            "|{                        |"
             "|\t\t \"id\": \"1\",            |"
             "|\t\t \"name\": \"Hello World\",|"
             "|\t\t \"list\": [             |"
-            "|\t\t\t\t [1, 2, 3],            |"
-            "|\t\t\t\t [4, 5, 6],            |"
+            "|\t\t\t\t [1, 2, 3],          |"
+            "|\t\t\t\t [4, 5, 6],          |"
             "|\t\t ]                     |"
-            "|}                      |"
-            "+-----------------------+"
+            "|}                        |"
+            "+-------------------------+"
         ),
     );
 }
diff --git a/papergrid/tests/grid/render.rs b/papergrid/tests/grid/render.rs
index 21a4327..dd71200 100644
--- a/papergrid/tests/grid/render.rs
+++ b/papergrid/tests/grid/render.rs
@@ -238,21 +238,21 @@ test_table!(
 test_table!(
     doesnt_render_return_carige_0,
     grid(2, 2).change_cell((0, 1), "123\r\r\r567").build(),
-    "+---+------+"
+    "+---+---------+"
     "|0-0|123\r\r\r567|"
-    "+---+------+"
-    "|1-0|1-1   |"
-    "+---+------+"
+    "+---+---------+"
+    "|1-0|1-1      |"
+    "+---+---------+"
 );
 
 test_table!(
     doesnt_render_return_carige_1,
     grid(2, 2).change_cell((1, 1), "12345678").change_cell((0, 1), "123\r\r\r567").build(),
-    "+---+--------+"
-    "|0-0|123\r\r\r567  |"
-    "+---+--------+"
-    "|1-0|12345678|"
-    "+---+--------+"
+    "+---+---------+"
+    "|0-0|123\r\r\r567|"
+    "+---+---------+"
+    "|1-0|12345678 |"
+    "+---+---------+"
 );
 
 // #[test]
diff --git a/tabled/tests/core/table_test.rs b/tabled/tests/core/table_test.rs
index 69df96f..f47e2a2 100644
--- a/tabled/tests/core/table_test.rs
+++ b/tabled/tests/core/table_test.rs
@@ -311,10 +311,9 @@ test_table!(
     "│ This is the 0.19 release of Nushell. If you'd like to read more about it, please check out: http │"
     "│ s://www.nushell.sh/blog/2020/09/01/nushell_0_19.html                                             │"
     "│                                                                                                  │"
-    "│ For convenience, we are providing full build                                                     │"
-    "│ s for Windows, Linux, and macOS. These are the \"all extra features\" builds, so be sure you have  │"
-    "│ the requirements to enable all capabilities: https://github.com/nushell/book/blob/master/en/inst │"
-    "│ allation.md#dependencies                                                                         │"
+    "│ For convenience, we are providing full builds for Windows, Linux, and macOS. These are the \"all  │"
+    "│ extra features\" builds, so be sure you have the requirements to enable all capabilities: https:/ │"
+    "│ /github.com/nushell/book/blob/master/en/installation.md#dependencies                             │"
     "│                                                                                                  │"
     "└──────────────────────────────────────────────────────────────────────────────────────────────────┘"
 );
@@ -331,10 +330,9 @@ test_table!(
     "│ This is the 0.19 release of Nushell. If you'd like to read more about it, please check out: http │"
     "│ s://www.nushell.sh/blog/2020/09/01/nushell_0_19.html                                             │"
     "│                                                                                                  │"
-    "│ For convenience, we are providing full build                                                     │"
-    "│ s for Windows, Linux, and macOS. These are the \"all extra features\" builds, so be sure you have  │"
-    "│ the requirements to enable all capabilities: https://github.com/nushell/book/blob/master/en/inst │"
-    "│ allation.md#dependencies                                                                         │"
+    "│ For convenience, we are providing full builds for Windows, Linux, and macOS. These are the \"all  │"
+    "│ extra features\" builds, so be sure you have the requirements to enable all capabilities: https:/ │"
+    "│ /github.com/nushell/book/blob/master/en/installation.md#dependencies                             │"
     "│                                                                                                  │"
     "└──────────────────────────────────────────────────────────────────────────────────────────────────┘"
 );
@@ -785,10 +783,9 @@ fn multiline_table_test2() {
         "│ This is the 0.19 release of Nushell. If you'd like to read more about it, please check out: http │"
         "│ s://www.nushell.sh/blog/2020/09/01/nushell_0_19.html                                             │"
         "│                                                                                                  │"
-        "│ For convenience, we are providing full build                                                     │"
-        "│ s for Windows, Linux, and macOS. These are the \"all extra features\" builds, so be sure you have  │"
-        "│ the requirements to enable all capabilities: https://github.com/nushell/book/blob/master/en/inst │"
-        "│ allation.md#dependencies                                                                         │"
+        "│ For convenience, we are providing full builds for Windows, Linux, and macOS. These are the \"all  │"
+        "│ extra features\" builds, so be sure you have the requirements to enable all capabilities: https:/ │"
+        "│ /github.com/nushell/book/blob/master/en/installation.md#dependencies                             │"
         "│                                                                                                  │"
         "└──────────────────────────────────────────────────────────────────────────────────────────────────┘"
     );
diff --git a/tabled/tests/settings/render_settings.rs b/tabled/tests/settings/render_settings.rs
index 02e506c..232987c 100644
--- a/tabled/tests/settings/render_settings.rs
+++ b/tabled/tests/settings/render_settings.rs
@@ -89,16 +89,7 @@ test_table!(
 test_table!(
     tab_isnot_handled_by_default_test,
     Matrix::iter(tab_data1()).with(Style::psql()),
-    "      N       | column 0 | column 1 | column 2 "
-    "--------------+----------+----------+----------"
-    "      0       |   0-0    |   0-1    |   0-2    "
-    " 123\t123\tasdasd |   1-0    |   1-1    |   1-2    "
-    "      2       |   2-0    | htt\tps:// |   2-2    "
-    "              |          | www      |          "
-    "              |          | .        |          "
-    "              |          | red\that   |          "
-    "              |          | .c\tom     |          "
-    "              |          | /en      |          "
+    "       N        | column 0 | column 1  | column 2 \n----------------+----------+-----------+----------\n       0        |   0-0    |    0-1    |   0-2    \n 123\t123\tasdasd |   1-0    |    1-1    |   1-2    \n       2        |   2-0    | htt\tps:// |   2-2    \n                |          | www       |          \n                |          | .         |          \n                |          | red\that   |          \n                |          | .c\tom     |          \n                |          | /en       |          "
 );
 
 test_table!(