move sparkline example below interrupted git group
[barcat.git] / barcat
diff --git a/barcat b/barcat
index 0316b64460300a7e5ffb3dc73b4c696fe20024c2..dfe6a1018ecc8f55ba006db654366788795e43a5 100755 (executable)
--- a/barcat
+++ b/barcat
@@ -8,8 +8,10 @@ use re '/msx';
 
 our $VERSION = '1.07';
 
-use Getopt::Long '2.33', qw( :config gnu_getopt );
 my %opt;
+if (@ARGV) {
+require Getopt::Long;
+Getopt::Long->import('2.33', qw( :config gnu_getopt ));
 GetOptions(\%opt,
        'ascii|a!',
        'color|c!',
@@ -82,33 +84,7 @@ GetOptions(\%opt,
                exit;
        },
        'usage|h' => sub {
-               local $/ = undef;  # slurp
-               my $pod = readline *DATA;
-               $pod =~ s/^=over\K/ 25/;  # indent options list
-               $pod =~ s{
-                       ^=item \h \N*\n\n \N*\n \K  # first line
-                       (?: (?: ^=over .*? ^=back\n )? (?!=) \N*\n )*
-               }{\n}g;  # abbreviate options
-               $pod =~ s/[.,](?=\n)//g;  # trailing punctuation
-               $pod =~ s/^=item\ \K(?=--)/____/g;  # align long options
-               # abbreviate <variable> indicators
-               $pod =~ s/\Q>.../s>/g;
-               $pod =~ s/<(?:number|count|seconds)>/N/g;
-               $pod =~ s/<character(s?)>/\Uchar$1/g;
-               $pod =~ s/\Q | /|/g;
-               $pod =~ s/(?<!\w)<([a-z]+)>/\U$1/g;  # uppercase
-
-               require Pod::Usage;
-               my $parser = Pod::Usage->new(USAGE_OPTIONS => {
-                       -indent => 2, -width => 78,
-               });
-               $parser->select('SYNOPSIS', 'OPTIONS');
-               $parser->output_string(\my $contents);
-               $parser->parse_string_document($pod);
-
-               $contents =~ s/\n(?=\n\h)//msg;  # strip space between items
-               $contents =~ s/^\ \ \K____/    /g;  # nbsp substitute
-               print $contents;
+               /^=/ ? last : print for readline *DATA;  # text between __END__ and pod
                exit;
        },
        'help|?'  => sub {
@@ -118,6 +94,7 @@ GetOptions(\%opt,
                );
        },
 ) or exit 64;  # EX_USAGE
+}
 
 $opt{width} ||= $ENV{COLUMNS} || qx(tput cols) || 80 unless $opt{spark};
 $opt{color} //= -t *STDOUT;  # enable on tty
@@ -138,12 +115,21 @@ $opt{input} = (@ARGV && $ARGV[0] =~ m/\A[-0-9]/) ? \@ARGV : undef
 $opt{'sum-format'} = sub { sprintf '%.8g', $_[0] };
 $opt{'calc-format'} = sub { sprintf '%*.*f', 0, 2, $_[0] };
 $opt{'value-format'} = $opt{units} && sub {
-       my $unit = int(log(abs $_[0] || 1) / log(10) - 3*($_[0] < 1) + 1e-15);
-       my $float = $_[0] !~ /^0*[-0-9]{1,3}$/;
-       sprintf('%3.*f%1s',
-               $float && ($unit % 3) == ($unit < 0),  # tenths
-               $_[0] / 1000 ** int($unit/3),   # number
-               $#{$opt{units}} * 1.5 < abs $unit ? "e$unit" : $opt{units}->[$unit/3]
+       my $unit = (
+               log(abs $_[0] || 1) / log(10)
+               - 3 * (abs($_[0]) < .9995)   # shift to smaller unit if below 1
+               + 1e-15  # float imprecision
+       );
+       my $decimal = ($unit % 3) == ($unit < 0);
+       $unit -= log($decimal ? .995 : .9995) / log(10);  # rounded
+       $decimal = ($unit % 3) == ($unit < 0);
+       $decimal &&= $_[0] !~ /^-?0*[0-9]{1,3}$/;  # integer 0..999
+       sprintf('%*.*f%1s',
+               3 + ($_[0] < 0), # digits plus optional negative sign
+               $decimal,  # tenths
+               $_[0] / 1000 ** int($unit/3),  # number
+               $#{$opt{units}} * 1.5 < abs $unit ? sprintf('e%d', $unit) :
+                       $opt{units}->[$unit/3]  # suffix
        );
 };
 
@@ -312,6 +298,10 @@ while ($nr <= $limit) {
                color($color) for $val;
        }
        my $line = $lines[$nr] =~ s/\n/$val/r;
+       if (not length $val) {
+               say $line;
+               next;
+       }
        printf '%-*s', $len + length($val), $line;
        print $barmark[$_] // $opt{'graph-format'}
                for 1 .. $size && (($values[$nr] || 0) - $minval) * $size + .5;
@@ -362,6 +352,37 @@ sub show_exit {
 show_exit();
 
 __END__
+Usage:
+  barcat [OPTIONS] [FILES|NUMBERS]
+
+Options:
+  -a, --[no-]ascii         Restrict user interface to ASCII characters
+  -c, --[no-]color         Force colored output of values and bar markers
+  -f, --field=(N|REGEXP)   Compare values after a given number of whitespace
+                           separators
+      --header             Prepend a chart axis with minimum and maximum
+                           values labeled
+  -H, --human-readable     Format values using SI unit prefixes
+  -t, --interval[=(N|-LINES)]
+                           Output partial progress every given number of
+                           seconds or input lines
+  -l, --length=[-]SIZE[%]  Trim line contents (between number and bars)
+  -L, --limit[=(N|-LAST|START-[END])]
+                           Stop output after a number of lines
+      --graph-format=CHAR  Glyph to repeat for the graph line
+  -m, --markers=FORMAT     Statistical positions to indicate on bars
+      --min=N, --max=N     Bars extend from 0 or the minimum value if lower
+      --palette=(PRESET|COLORS)
+                           Override colors of parsed numbers
+      --spark[=CHARS]      Replace lines by sparklines
+  -s, --stat               Total statistics after all data
+  -u, --unmodified         Do not reformat values, keeping leading whitespace
+      --value-length=SIZE  Reserved space for numbers
+  -w, --width=COLUMNS      Override the maximum number of columns to use
+  -h, --usage              Overview of available options
+      --help               Full documentation
+      --version            Version information
+
 =encoding utf8
 
 =head1 NAME
@@ -630,16 +651,16 @@ Or the top 3 most frequent authors with statistics over all:
 
     git shortlog -sn | barcat -L3 -s
 
-Sparkline graphics of simple input given as inline parameters:
-
-       barcat --spark= 3 1 4 1 5 0 9 2 4
-
 Activity graph of the last days (substitute date C<-v-{}d> on BSD):
 
     ( git log --pretty=%ci --since=30day | cut -b-10
       seq 0 30 | xargs -i date +%F -d-{}day ) |
     sort | uniq -c | awk '$1--' | barcat --spark
 
+Sparkline graphics of simple input given as inline parameters:
+
+       barcat --spark= 3 1 4 1 5 0 9 2 4
+
 =head1 AUTHOR
 
 Mischa POSLAWSKY <perl@shiar.org>