#!/usr/bin/perl -w
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
#NAME
#  htmltextcols - format text into html table with columns
#  textcols     - format text into html table with columns
#  htmlcols     - format text into html table with columns
#
#SYNOPSIS
#  htmltextcols [options][file] 
#REQUIRES
#
#DESCRIPTION
#
#OPTIONS
#
# +c<N>
#   Produce <N> columns. Default: 2.
#
# +H<N>
#   Limit the rows of a table ("page") to N rows,
#   then start a new table.
#
# +p
#   Produce "page breaks" between the text tables, for printing.
#
# +T<text>
#   Put a title <text> across the top of each table.
#
# +w<N>
#   Limit the width of columns to <N> chars.
#
# +W<N>
#   Limit the total width to <N> chars.
#
#EXAMPLES
#
#FILES
#
#BUGS
#
#SEE ALSO
#
#AUTHOR
#  John Chambers <jc@trillian.mit.edu>
#  (This is a merger of a tool that I've developed  under  all  3  names  for
#  different  projects.  It's easiest to just acknowledge them all by listing
#  all the names.  Pick the one you prefer.  ;-)
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #

$| = 1;
$exitstat = 0;
($P = $0) =~ s".*/"";
$V = $ENV{"V_$P"} || $ENV{"D_$P"} || 1;	# Verbose level

$B       = 0;	# Border width
$cols    = 3;	# Default number of columns
$files   = 0;	# Number of files read so far
$lines   = 0;	# Number of lines so far
$linelim = 900;	# Max number of lines, mostly for debugging
$maxline = 0;	# Longest line length so far (after trimming)
$pages   = 6;	# Max number of pages (tables) to produce.
$rows    = 44;	# Rows per "page"
@text    = ();	# Accumulate full text here

$pagebreak = '<p style="page-break-after:always;"></p>';

if ($P =~ /^html/i) {	# Should we produce HTML output?
	$outfmt = 'HTML';
} else {
	$outfmt = 'TEXT';
}

arg:
for $arg (@ARGV) {		# Chew up the args ...
	if (($flg,$opt) = ($arg =~ /^([-+])(.*)$/)) {	# Is it a +/- option? 
		print STDERR "$P: c opt '$flg' \"$opt\"\n" if $V>2;
		if ($opt =~ /^c(\d*)/) {	# Columns
			print STDERR "$P: c opt '$1'\n" if $V>2;
			if ($i = int($1)) {		# Number of columns
				$cols = $i;
				print STDERR "$P: Columns: $cols [set]\n" if $V>2;
			} else {		# No number; it's an adjustment by 1
				if ($flg eq '-') {
					$cols --;
				} else {
					$cols ++;
				}
				print STDERR "$P: Columns: $cols [adjusted]\n" if $V>0;
			}
		} elsif ($opt =~ /^H(\d*)/) {	# Page rows
			print STDERR "$P: H opt '$1'\n" if $V>2;
			if ($i = int($1)) {		# Number of rows
				$rows = $i;
				print STDERR "$P: Page rows: $rows.\n" if $V>1;
			} else {		# No number; it's an adjustment by 1
				print STDERR "$P: Column width '$1' not a number. \n" if $V>0;
			}
		} elsif ($opt =~ /^w(\d*)/) {	# Column width
			print STDERR "$P: w opt '$1'\n" if $V>2;
			if ($i = int($1)) {		# Number of columns
				$cwidth = $i;
				print STDERR "$P: Column width '$cwidth'.\n" if $V>1;
			} else {		# No number; it's an adjustment by 1
				print STDERR "$P: Column width '$1' not a number. \n" if $V>0;
			}
		} elsif ($opt =~ /^V(\d*)/) {	# Verbose level
			print STDERR "$P: V=$1 [was $V]\n" if $V>1;
			$V = int($1);
		} elsif ($opt =~ /^W(\d*)/) {	# Table width
			print STDERR "$P: W opt '$1'\n" if $V>2;
			if ($i = int($1)) {		# Number of columns
				$pwidth = $i;
				print STDERR "$P: Table width: $pwidth [set]\n" if $V>1;
			} else {		# No number; it's an adjustment by 1
				print STDERR "$P: Column width '$1' not a number. \n" if $V>0;
			}
		} else {
			print STDERR "$P: Option \"$flg$opt\" not recognized.\n" if $V>0;
			next arg;
		}
	} else {
		print STDERR "$P: \"$arg\" not an option.\n" if $V>1;
		if (open(DATA,$arg)) {	# Is it a file (that we can read)?
			++$files;
			onefile('DATA');		# Slurp up the file
			close DATA;
		} else {
			print STDERR "$P: Can't read \"$arg\" [$?]\n" if $V>2;
		}
	}
}
if ($files < 1) {		# Did we (attempt to) read any files?
	&onefile('STDIN');	# If not, slurp up standard input
}
print STDERR "$P: We have $lines lines of text.\n" if $V>2;

print STDERR "$P: $outfmt output wanted.\n" if $V>2;
if ($outfmt eq 'HTML') {
	&makehtml();
} else {
	print STDERR "$P: $outfmt output not implemented yet.\n" if $V>0;
	$exitstat = 1;
}


exit $exitstat;

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #

sub makehtml {my $F='makehtml';
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
	local($sent,$line,$c,$r,$p,$l) = (0,0,0,0,0,0);
	local($cpp,$cpr,$data,$bar);
	print STDERR "$F: $lines lines $cols cols $rows rows.\n" if $V>2;
	$cpp = $rows * ($cpr = $cols);
	print STDERR "$F: cells/row=$cpr cells/page=$cpp.\n" if $V>2;
	$bar = '-' x $cwidth;	# For forcing a cell's min width.
page:
	for ($p = 0; $p < $pages; ++$p) {
		last page if (($sent >= $lines) || ($l+1 >= $lines));
		$data = undef;
		print "<center><!-- $P -->\n";
		print "<table border=$B style='border-collapse:collapse'><!-- p=$p -->\n";
		print "<tr>\n";		# Force min cell width
		for ($c = 0; $c < $cols; ++$c) {
			print "\t<td>$bar</td>\n";
		}
		print "</tr>\n";
row:	for ($r = 0; $r < $rows; ++$r) {
			print "<tr><!-- p=$p r=$r -->\n"; 
cell:		for ($c = 0; $c < $cols; ++$c) {
				$l = ($p * $cpp) + ($c * $rows) + $r;	# Index in @text of the cell's data
				if ($l < $lines) {
					$data = $text[$l];
				#	print "\t<!-- $data -->\n";
					print "\t<td>$data </td><!-- $p.$r.$c l=$l -->\n";
					if ($data =~ m/^[-=*]/) {$data = "<B>$data</B>";}	# Bold special lines
					++$sent;
				} else {
					print STDERR "$F: Line $l is past the end of text.\n" if $V>2;
				#	print "\t<td></td><!-- $p.$r.$c l=$l -->\n";
				}
			}
			print "</tr><!-- p=$p r=$r l=$l -->\n"; 
		}
		print "</table><!-- p=$p l=$l -->\n";
		print "</center><!-- $P -->\n";
		print "$pagebreak\n" if ($pagebreak && ($sent < $lines));
	}
	print STDERR "$F: $sent cells sent.\n" if $V>2;
	return;
}

sub onefile {my $F='onefile'; local($file) = @_;
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
# This reads the data from $file, trims each line if necessare, and adds them #
# to the @text array.  Our return value is the number of lines accumulated in #
# @text so far.                                                               #
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
	local($line,$llen);
	print STDERR "$F: Reading $file ...\n" if $V>2;
	while ($line = <$file>) {		# Gobble up the file one line at a time
		if ($linelim && ($lines >= $linelim)) {	# Too much input?
			print STDERR "$F: Line limit $linelim exceeded.\n" if $V>0;
			close $file;
			return $lines;		# Tell the caller how many lines we have now
		}
		$line =~ s/[\s\r]+$//;	# Trim away any white stuff
		$llen = length($line);
		print STDERR "$F: LINE \"$line\"\n" if $V>2;
		if ($llen > $cwidth) {
			print STDERR "$F: llen=$llen >cwidth=$cwidth.\n" if $V>2;
			$line = substr($line,0,$cwidth);
			print STDERR "$F: Line \"$line\" truncated.\n" if $V>1;
			$maxline = $cwidth;
		} else {
			$maxline = $llen if ($llen > $maxline);
		}
		print STDERR "$F: llen=$llen maxline=$maxline.\n" if $V>2;
		if ($line =~ /[-=*]/) {
			push @text, "<B>$line</B>";	# Bold for special lines.
		} else {
			push @text, $line;
		}
	 	++$lines;
	}
	return $lines;		# Tell the caller how many lines we have now
}
