#!/usr/bin/perl -w
#
# txgifgraf     --crb3 20Jan07/15feb07
#  from
# txgraf        --crb3 02Jul06
#   quick text bargraph showing relative sizes of text
#   chapters. call it an indicator of where to focus the
#   storyteller's eye.
#
# this version paints up a GIF bar graph with more precise
# numbers.
#
#
use Chart::Bars;
#

$barcolor="1111FF";     # #RRGGBB
$xval=400;                              # comfy values for a 22-chapter setup; they
$yval=200;                              #  will be either specified or recalculated.
$subtitle=$title="";
$showit=$report=$chatty=$debug=$isx=$isy=0;
$min=100E3;
$arb=14;                                # arbitrary: we want 14px wide bars, square grid.
$hfudge=92;                             # text/border horizontal padding
$vfudge=140;                            # text/border vertical padding
while(defined($ARGV[0]) and index($ARGV[0],'-')==0){
  $arg=shift(@ARGV);                    # get any the switches
  $key=substr($arg,1,1);                # get no-arg switches first
  substr($arg,0,2)="";
  if($key eq 'v'){                      # verbose?
    $chatty ^= 1;
    next;
  }elsif($key eq 'D'){                  # silent running?
    $debug^=1;
    next;
  }elsif($key eq 'r'){                  # report X and Y at stdout?
    $report^=1;
    next;
  }elsif($key eq 'S'){                  # show graph after generating?
    $showit^=1;
    next;
  }elsif($key eq '?' or $key eq 'h'){                  # show helps and leave.
    print <<EOT;
 txgifgraf generates GIF graph of chapter sizes --crb3 20Jan07/15feb07
     txgifgraf [options] /subdir-with-enumerated-text-chapters-in-it
   Options:
       -a nn            arbitrary per-bar allotment in pixels
       -c <color>       bar color, name or #triplet
       -m nn            minimum graph Y-room in counted bytes
       -o <outfname>    gif will be named <outfname>.gif
       -r               toggle: report x,y sizes at stdout (off)
       -s <subtitle>    subtitle to put across top of graph, if not deprecated
       -t <title>       title to put across top of graph
       -x nn            override width in pixels
       -y nn            override height in pixels
       -S               toggle: show graph after generating (off)
       -v               toggle: script gets chatty
       -D               toggle: turn on ad-hoc debug tracers
       -h,-?            show helps, then leave
EOT
    exit(0);
  }
  $arg =~ s/^\=//;                      # handles switch=arg
  $arg=shift(@ARGVif($arg eq "" and ($ARGV[0] !~ /^\-\w/) );
# if $arg eq "";      # handles space-separated switch/arg
  if($key eq 'x'){                      # width
    $xval=0+$arg;
    $isx=1;
  }elsif($key eq 'y'){                  # height
    $yval=0+$arg;
    $isy=1;
  }elsif($key eq 't'){                  # title to put across top of graph
    $title=$arg;
  }elsif($key eq 's'){                  # subtitle to put across top of graph
    $subtitle=$arg;
  }elsif($key eq 'c'){                  # graph bar color
    $barcolor=$arg;
  }elsif($key eq 'o'){                  # gif will be named $outfname.gif
    $gifname=$arg;
  }elsif($key eq 'm'){                  # minimum graph Y-room in counted bytes
    $min=0+$arg;
  }elsif($key eq 'a'){                  # arbitrary per-bar allotment
    $arb=0+$arg;
  }else{
    warn "$0: unrecognized option -$key $arg\n";
  }
}
die "no subdir specified\n" unless defined $ARGV[0];
$sdir=$ARGV[0];

$rval=hex(substr($barcolor,0,2));
$gval=hex(substr($barcolor,2,2));
$bval=hex(substr($barcolor,4,2));

$szmax=$min;
(@ls)=`ls -l $sdir/*txt`;               #  ignore html files, dotfiles
foreach $ln (@ls){
  chomp $ln;
  (@lsln)=split(/\s+/,$ln);
  ($fname=$lsln[8]) =~ s/^.+\///;       #  shave path, leave filename.typ
  $sizes{$fname}=$sz=0+$lsln[4];        #  coerce to numeric
  $szmax=$sz if $sz > $szmax;
}
undef @ls;
undef @lsln;

$gifname="$sdir.chapgraph" unless defined $gifname;
$gifname .= ".gif";


#if($szmax > 100E3){    # get to that later
#}

if($szmax > $min){                     # pad up to one 10k-point higher
  my $rem = $szmax % 10E3;
  $szmax += (10E3 - $rem);
}

(@names)=(sort keys %sizes);
foreach $fl (@names){
  push(@fsiz,$sizes{$fl});
}

$chapcnt=$#fsiz +1;
unless($isx){
  $xval = ($chapcnt * $arb) + $hfudge;
}
unless($isy){
  $yval = ( ($szmax / 10E3* $arb) + $vfudge;
}

foreach $val (@fsiz){
  $val /= 1E3;
}
$szmax /= 1E3;

#
# the longhand way of determining the chapter-number placement.
# we are relying on the habit of naming chapters thus: ficname.00.txt
# ...we need to know if the firstly-numbered chapter is 00 or 01.
# 00 is (potentially) used for a prolog.
#
$na=$names[0];
$nb=$names[1];
$ni=0;
while(substr($na,$ni,1eq substr($nb,$ni,1)){
  $ni++;
}
$nbase = (substr($na,$ni,1eq '0' ? 0 : 1);

#
# print the actual graph.
#

for($cx = 0;$cx < $chapcnt;$cx++){      # generate numeric bar-labels
  $xlbl=sprintf("%2.02d",$nbase);
  $nbase++;
  push(@hlabels,$xlbl);
}

%gv=(
  'title' => $title,
#  'sub_title' => 'Chapter Lengths',
  'grid_lines' => 'true',
  'legend' => 'none',
  'max_val' => $szmax,
  'y_ticks' => ($szmax / 10)+1,         # include 0th tick
  'x_label' => 'chapter',
  'y_label' => 'length, Kbytes',
  'min_val' => 0,
);

$gv{'sub_title'} = $subtitle if length($subtitle);

$graf = Chart::Bars->new($xval,$yval);  # x,y?
$graf->set'colors' => { 'dataset0' => [ $rval,$gval,$bval ] } );
$graf->set%gv );
@gifdata = ( \@hlabels, \@fsiz );

$graf->gif($gifname,\@gifdata);

if($report){
  print "width=\"$xval\" height=\"$yval\"\n";
}

system("gifview $gifname"if $showit;

Grab a
gzipped
copy
here
 
Syntax highlighting using Syntax::Highlight::Engine::Kate