Skip to content

Commit

Permalink
Upgrade dependencies and fix invalid cell width calculation with mode…
Browse files Browse the repository at this point in the history
…rn unicode-width versions

Fixes phsym#165
  • Loading branch information
KonishchevDmitry committed Nov 4, 2024
1 parent 225f6d4 commit 2325f95
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 54 deletions.
11 changes: 6 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,10 @@ path = "src/main.rs"
name = "prettytable"

[dependencies]
unicode-width = "0.1"
term = "0.7"
lazy_static = "1.4"
is-terminal = "0.4"
csv = { version = "1.3", optional = true }
encode_unicode = "1.0"
csv = { version = "1.1", optional = true }
is-terminal = "0.4"
lazy_static = "1.5"
strip-ansi-escapes = "0.2.0"
term = "1.0"
unicode-width = "0.2"
51 changes: 2 additions & 49 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::fmt;
use std::io::{Error, ErrorKind, Write};
use std::str;

use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};
use unicode_width::UnicodeWidthStr;

use super::format::Alignment;

Expand Down Expand Up @@ -84,54 +84,7 @@ pub fn print_align<T: Write + ?Sized>(
/// Return the display width of a unicode string.
/// This functions takes ANSI-escaped color codes into account.
pub fn display_width(text: &str) -> usize {
#[derive(PartialEq, Eq, Clone, Copy)]
enum State {
/// We are not inside any terminal escape.
Normal,
/// We have just seen a \u{1b}
EscapeChar,
/// We have just seen a [
OpenBracket,
/// We just ended the escape by seeing an m
AfterEscape,
}

let width = UnicodeWidthStr::width(text);
let mut state = State::Normal;
let mut hidden = 0;

for c in text.chars() {
state = match (state, c) {
(State::Normal, '\u{1b}') => State::EscapeChar,
(State::EscapeChar, '[') => State::OpenBracket,
(State::EscapeChar, _) => State::Normal,
(State::OpenBracket, 'm') => State::AfterEscape,
_ => state,
};

// We don't count escape characters as hidden as
// UnicodeWidthStr::width already considers them.
if matches!(state, State::OpenBracket | State::AfterEscape) {
// but if we see an escape char *inside* the ANSI escape, we should ignore it.
if UnicodeWidthChar::width(c).unwrap_or(0) > 0 {
hidden += 1;
}
}

if state == State::AfterEscape {
state = State::Normal;
}
}

assert!(
width >= hidden,
"internal error: width {} less than hidden {} on string {:?}",
width,
hidden,
text
);

width - hidden
UnicodeWidthStr::width(strip_ansi_escapes::strip_str(text).as_str())
}

/// Wrapper struct which will emit the HTML-escaped version of the contained
Expand Down

0 comments on commit 2325f95

Please sign in to comment.