btrbk: fix table output for utf8 characters (require Text::CharWidth)

Use Text::CharWidth::mbswidth() if installed, fallback to
length(Encode::decode_utf8()), fallback to length().

 - Text::CharWidth handles wide chars (e.g. asian, taking up two
   columns on the terminal) correctly.

 - length(Encode::decode_utf8()) handles single-width chars only, and
   should be installed on most systems (perl >= v5.7.3).

 - langth() counts bytes, as we do not convert anything to UTF-8 in
   btrbk (NOT using `perl -CIOEioA` or binmode(STDOUT, ":utf8"))
unsafe-filenames
Axel Burri 2021-08-15 16:10:54 +02:00
parent 94a415e420
commit 48bf4f05b9
1 changed files with 8 additions and 2 deletions

10
btrbk
View File

@ -5183,6 +5183,11 @@ sub print_formatted(@)
}
else
{
# Text::CharWidth does it correctly with wide chars (e.g. asian) taking up two columns
my $termwidth = eval_quiet { require Text::CharWidth; } ? \&Text::CharWidth::mbswidth :
eval_quiet { require Encode; } ? sub { length(Encode::decode_utf8(shift)) } :
sub { length(shift) };
# sanitize and calculate maxlen for each column
my %maxlen = map { $_ => $no_header ? 0 : length($_) } @keys;
my @formatted_data;
@ -5195,7 +5200,8 @@ sub print_formatted(@)
$hide_column{$key} = 0 if(defined($val));
$val = $empty_cell_char if(!defined($val) || ($val eq ""));
$formatted_row{$key} = $val;
$maxlen{$key} = length($val) if($maxlen{$key} < length($val));
my $vl = $termwidth->($val);
$maxlen{$key} = $vl if($maxlen{$key} < $vl);
}
push @formatted_data, \%formatted_row;
}
@ -5246,7 +5252,7 @@ sub print_formatted(@)
foreach (@visible_keys) {
my $val = $row->{$_};
print $fh ' ' x $fill;
$fill = $maxlen{$_} - length($val);
$fill = $maxlen{$_} - $termwidth->($val);
if($ralign{$_}) {
print $fh ' ' x $fill;
$fill = 0;