diff --git a/papergrid/Cargo.toml b/papergrid/Cargo.toml index 3050b3e6..c6100a03 100644 --- a/papergrid/Cargo.toml +++ b/papergrid/Cargo.toml @@ -13,7 +13,7 @@ std = [] ansi = ["ansi-str", "ansitok"] [dependencies] -unicode-width = "=0.1.11" +unicode-width = "0.2" bytecount = "0.6" fnv = "1.0" ansi-str = { version = "0.8", optional = true } diff --git a/papergrid/src/util/string.rs b/papergrid/src/util/string.rs index 2fa863be..8eada2f4 100644 --- a/papergrid/src/util/string.rs +++ b/papergrid/src/util/string.rs @@ -7,33 +7,16 @@ /// Returns string width and count lines of a string. It's a combination of [`string_width_multiline`] and [`count_lines`]. #[cfg(feature = "std")] pub fn get_text_dimension(text: &str) -> (usize, usize) { - #[cfg(not(feature = "ansi"))] - { - let (lines, acc, max) = text.chars().fold((1, 0, 0), |(lines, acc, max), c| { - if c == '\n' { - (lines + 1, 0, acc.max(max)) - } else { - let w = unicode_width::UnicodeWidthChar::width(c).unwrap_or(0); - (lines, acc + w, max) - } - }); - - (lines, acc.max(max)) - } - - #[cfg(feature = "ansi")] - { - get_lines(text) - .map(|line| get_line_width(&line)) - .fold((0, 0), |(i, acc), width| (i + 1, acc.max(width))) - } + get_lines(text) + .map(|line| get_line_width(&line)) + .fold((0, 0), |(i, acc), width| (i + 1, acc.max(width))) } /// Returns a string width. pub fn get_line_width(text: &str) -> usize { #[cfg(not(feature = "ansi"))] { - unicode_width::UnicodeWidthStr::width(text) + get_string_width(text) } #[cfg(feature = "ansi")] @@ -44,7 +27,7 @@ pub fn get_line_width(text: &str) -> usize { ansitok::parse_ansi(text) .filter(|e| e.kind() == ansitok::ElementKind::Text) .map(|e| &text[e.start()..e.end()]) - .map(unicode_width::UnicodeWidthStr::width) + .map(get_string_width) .sum() } } @@ -53,10 +36,7 @@ pub fn get_line_width(text: &str) -> usize { pub fn get_text_width(text: &str) -> usize { #[cfg(not(feature = "ansi"))] { - text.lines() - .map(unicode_width::UnicodeWidthStr::width) - .max() - .unwrap_or(0) + text.lines().map(get_string_width).max().unwrap_or(0) } #[cfg(feature = "ansi")] @@ -72,7 +52,7 @@ pub fn get_char_width(c: char) -> usize { /// Returns a string width (accouting all characters). pub fn get_string_width(text: &str) -> usize { - unicode_width::UnicodeWidthStr::width(text) + unicode_width::UnicodeWidthStr::width(text.replace(|c| c < ' ', "").as_str()) } /// Calculates a number of lines. diff --git a/papergrid/tests/grid/render.rs b/papergrid/tests/grid/render.rs index 6fcd8f36..21a43273 100644 --- a/papergrid/tests/grid/render.rs +++ b/papergrid/tests/grid/render.rs @@ -207,14 +207,32 @@ test_table!( "+----+--+" ); +#[test] +fn emoji_width_test() { + use papergrid::util::string::get_string_width; + assert_eq!(get_string_width("👩"), 2); + assert_eq!(get_string_width("🔬"), 2); + assert_eq!(get_string_width("👩\u{200D}🔬"), 2); +} + +test_table!( + emoji_handling, + grid(2, 1).data([["👩👩👩👩👩👩"], ["Hello"]]).build(), + "+------------+" + "|👩👩👩👩👩👩|" + "+------------+" + "|Hello |" + "+------------+" +); + test_table!( - hieroglyph_handling_2, - grid(2, 1).data([["জী._ডি._ব্লক_সল্টলেক_দূর্গা_পুজো_২০১৮.jpg"], ["Hello"]]).build(), - "+------------------------------------+" - "|জী._ডি._ব্লক_সল্টলেক_দূর্গা_পুজো_২০১৮.jpg|" - "+------------------------------------+" - "|Hello |" - "+------------------------------------+" + emoji_handling_2, + grid(2, 1).data([["👩\u{200D}🔬👩\u{200D}🔬👩\u{200D}🔬👩\u{200D}🔬👩\u{200D}🔬👩\u{200D}🔬"], ["Hello"]]).build(), + "+------------+" + "|👩\u{200D}🔬👩\u{200D}🔬👩\u{200D}🔬👩\u{200D}🔬👩\u{200D}🔬👩\u{200D}🔬|" + "+------------+" + "|Hello |" + "+------------+" ); test_table!( diff --git a/testing_table/Cargo.toml b/testing_table/Cargo.toml index f9310b66..1aedcb9f 100644 --- a/testing_table/Cargo.toml +++ b/testing_table/Cargo.toml @@ -17,4 +17,4 @@ ansi = ["ansitok"] [dependencies] ansitok = { version = "0.2", optional = true } -unicode-width = "=0.1.11" +unicode-width = "0.2"