From: Nicolas Boisselier Date: Thu, 16 Jul 2026 15:15:11 +0000 (+0200) Subject: D bin/csv2human.TODEL X-Git-Url: https://git.nbdom.net/?a=commitdiff_plain;h=1b5f3cd96594393b6c7895c03e1b52245bd93216;p=nb.git D bin/csv2human.TODEL --- diff --git a/bin/csv2human.TODEL b/bin/csv2human.TODEL deleted file mode 100755 index ee43e96f..00000000 --- a/bin/csv2human.TODEL +++ /dev/null @@ -1,310 +0,0 @@ -#!/usr/bin/env perl -use strict; -use warnings; -use Unicode::GCString; -use Text::CharWidth qw(mbswidth); -use String::Print qw(printp); -#use utf8; -################################################################################# -# -# VERSION -# -################################################################################# -my $VERSION = '0.0.1'; -# NB 16.01.18 -# - create script - -################################################################################# -# -# GLOBALS -# -################################################################################# -my ($NAME) = $0 =~ m,([^/]+)$,; - -################################################################################# -# -# ARGS -# -################################################################################# -my $VERBOSE = $main::VERBOSE = 1; -my $DEBUG = $main::DEBUG = 0; - -my %Opt = ( - 'header' => 0, - 'total' => 1, - 'encode' => 1, - 'sep' => "\t", -); -get_options(\%Opt); -$main::_DATA_ = undef; - -################################################################################# -# -# BEGIN -# -################################################################################# -#use Data::Dumper; print Dumper(\%Opt); -use Encode; - -# -# Calculate lengths -# -my @len = (); -my @lines = (); - -use Encode; -binmode STDOUT, ":utf8" if $Opt{encode}; -#binmode STDOUT, "raw:"; -#binmode STDOUT; -sub realLength { - my $str = shift; - # NB 21.06.26 $str = Encode::encode_utf8($str) if $Opt{encode}; - # NB 21.06.26 $str = Encode::encode('UTF-8', $str) if $Opt{encode}; - $str = Encode::decode('UTF-8', $str); - # NB 21.06.26 return mbswidth($str); - # NB 21.06.26 my $gcs = Unicode::GCString->new($str); - # NB 21.06.26 return $gcs->columns(); - return length($str); -} - -sub pad_to_width { - my ($string, $width) = @_; - my $gcs = Unicode::GCString->new($string); - my $visual_width = $gcs->columns(); # Gets the actual screen width[reference:9][reference:10] - #$visual_width = length(Encode::encode_utf8($string)); - $visual_width = mbswidth($string); - #return $string if $visual_width>$width; - #$visual_width = 0 if $visual_width>$width; - my $padding = " " x ($width - $visual_width); - return $string . $padding; # For left-aligned text -} - -sub pad_format { - my $fmt = shift; - for my $str (@_) { - $fmt =~ /%-(\d+)s/; - my $width = $1; - my $new = pad_to_width($str,$width); - $fmt =~ s/%-(\d+)s/$new/; - } - return $fmt; -} - -while (<>) { - - my @F = $Opt{format} ? split(/\s*$Opt{sep}\s*/) : split(/$Opt{sep}/); - - for (my $i=0;$i<@F;$i++) { - chomp($F[$i]); - my $l; - $len[$i] = $l if ( $l = realLength($F[$i]) ) >= ($len[$i] || 0); - } - - push @lines, [@F]; -} - -exit unless @lines; - -# -# Build format string -# -my $tot = @lines - ($Opt{header} ? 1 : 0); - -my $t = -1; - -my $format = "│ ".join(" │ ",map {$t += $_ + 3; "\%-".$_."s"} @len)." │".chr(10); -my $sep_line_first = "┌".join("┬",map {("─"x($_+2))} @len)."┐".chr(10); -my $sep_line = "├".join("┼",map {("─"x($_+2))} @len)."┤".chr(10); -my $sep_line_last = "└".join("┴",map {("─"x($_+2))} @len)."┘".chr(10); -if (1 and $Opt{encode}) { - $format = Encode::decode("UTF-8",$format); - $sep_line_first = Encode::decode("UTF-8",$sep_line_first); - $sep_line = Encode::decode("UTF-8",$sep_line); - $sep_line_last = Encode::decode("UTF-8",$sep_line_last); -} -# NB 21.06.26 utf8::decode($format); -# NB 21.06.26 utf8::decode($sep_line_first); -# NB 21.06.26 utf8::decode($sep_line); -# NB 21.06.26 utf8::decode($sep_line_last); -#die $format; - -# -# Format / align -# -# a => 1 -# b => 222222 -if ($Opt{format}) { - my $sep = " ".$Opt{sep}." "; - my $i; - $format = join($sep, - map { - $i++; - $t += $_ + realLength($sep); - $i == @len ? '%s' : "\%-".$_."s"; - } @len - ).chr(10); - $sep_line_first = ""; - $sep_line = ""; - $sep_line_last = ""; - $VERBOSE = 0; - $Opt{total} = 0; - $Opt{header} = 0; -} - -# -# Print -# -print $sep_line_first; -my $i = 0; -my $count; -while (my $line = shift @lines) -{ - # Add missing empty columns - for (my $j=@$line; $j<@len; $j++ ) - { - $line->[$j] = ''; - } - - @$line = map { utf8::decode($_); $_ } @$line; - printf($format,@$line); - # NB 21.06.26 printf pad_format($format,@$line); - print $sep_line if $Opt{header} and !$i++; -} - -print $sep_line_last; -print "$tot Records\n" if $Opt{total}; - -################################################################################# -# -# END -# -################################################################################# -exit 0; - -################################################################################# -# -# Functions -# -################################################################################# -sub help { -#------------------------------------------------------------------------------ -# Print help and exit -#------------------------------------------------------------------------------ - - require 'Pod/Usage.pm' unless $INC{'Pod/Usage.pm'}; - - # Substitutions - sub pod_env { - my $v = ''; - eval '$v = ref(\\'.$_[0].') eq "ARRAY" ? join(" ",'.$_[0].') : '.$_[0].'; return defined $v ? $v : qq|UNDEF|;'; - return $v; - } - - $main::_DATA_ =~ s/([@\$][A-Z_a-z\{\}]+)/pod_env($1)/eg; - - my $in; - open($in,'<',\$main::_DATA_); - - open(STDOUT,"|perl -pe 's/\.$$//g'".(($ENV{PAGER}||'') eq 'less' ? "|less -FRi" : "")); - my $opts = { - -input => $in, - -ouput => \*STDOUT, - -exitval => 'noexit', - -sections => [qw(SYNOPSIS DESCRIPTION OPTIONS)], - -verbose => ($Opt{'help'} ? 99 : 3), - }; - - Pod::Usage::pod2usage($opts); - close $in; - close STDOUT; - - exit 0; -} - -#------------------------------------------------------------------------------ -# Print version and exit -#------------------------------------------------------------------------------ -sub version { print "$NAME: version [$VERSION]\n"; exit 0; } - -#------------------------------------------------------------------------------ -# Get options from pod -#------------------------------------------------------------------------------ -sub get_options { - - use Getopt::Long qw(:config no_ignore_case no_auto_abbrev); - - my @Opt; - - sub pod_opt { - local $_; - my $o = shift; - $o =~ s/(=.|[\+\-\!]$)//; - $o = join(", ",map{"-$_"} split(/[\|,:;]/,$o)); - return "$o"; - } - - while () { - s/option\[([^\]]+)\]/push(@Opt,$1) and pod_opt($1)/eg; - $main::_DATA_ .= $_; - } - - GetOptions($_[0],@Opt) || exit -1; - - help() if $_[0]{'help'} or $_[0]{'man'}; - version() if $_[0]{'version'}; - - $main::VERBOSE = $VERBOSE = $_[0]{'verbose'} if defined $_[0]{'verbose'}; - $main::DEBUG = $DEBUG = $_[0]{'debug'} if defined $_[0]{'debug'}; - -} - -__DATA__ - -=head1 NAME - -$NAME - Alternative to linux command column, format csv tab style rows - -=head1 SYNOPSIS - -Quick usage! - -=over - -=item $NAME --sep ',' --noheader FILE - -=item $NAME --help - -=back - -=head1 DESCRIPTION - -Description! - -=head1 OPTIONS - - -option[header|h!] Print or not header separotor after first row - -option[sep|s=s] Separtor - -option[encode|e!] Encode (default: $Opt{encode}) - -option[total|t!] Print number of total record (default: $Opt{total}) - -option[format|f!] Only format according to option --sep. Usefull for coding - -option[verbose|v+] Verbose mode: increase the verbosity level. - -option[debug+] Debug mode: increase the verbosity level. - -option[version|V] Print version (default: $VERSION) - -option[help|?] Print a brief help message and exits. - -option[man] Print the manual page and exits. - -=cut - -=head1 COPYRIGHT AND LICENSE - -Copyright (C) 2018 Nicolas Boisselier - -This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - -See . - -=head1 AUTHOR - -Nicolas Boisselier - -=cut