#!/usr/bin/perl

@argv = @ARGV;
use Getopt::Std;

$bufN = 0;			# index in to buffer (@buf)
$LINE = 0;			# Total lines printed
$NoFmt = 0;			# A nofmt flag is in effect
$html = 0;			# HTML file ( 0 = no)
getopt('lr');			# get options (w/out -i)

if ( $opt_l eq "0"){
	$opt_l = "00";}         # force over-ride if left margin = "0"
else {
	$opt_l += 0;}		# left margin over-ride
$opt_r += 0;			# right margin over-ride
$lm = $opt_l;
$rm = $opt_r;
$rm = 72 unless ($rm);
$rm -= 2 if ($opt_u);
if ($opt_i) {			# default value for -i is 4
	@ARGV = @argv;		# restore command line
	getopt('ilr');		# get options (including -1)
	$opt_i = 4 unless ($opt_i);
}
usage() if ($opt_h);

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

sub usage{
	print "usage:\t$0 [-r R] [-l L] [-o] [-u]
	where -l L = left margin
	      -r R = right margin
	      -t expand tabs to 8 chars (rather than 4)
	      -o produce ordered list from individual paras
	      -u unordered list from individual paras
	      -p (HTML) text is pre-formatted with <pre>
	      -h print this screen
	      -i [n] hanging indent paras by n spaces (default 4)
	      -n process existing ordered list (single digit number)
	      -b process existing bullet list (\*)
	      -p seperate para for each LF
";
	exit (1);
	      
}

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

sub flushbuf{
	# Line length -- used to determine if the text should be wrapped
	my $i;
	$Llen = 0;
	return unless (@buf);
	print "\n" unless ( $LINE == 0 || $html);
	if ( $opt_u){
		# my $lm = 0;
		# if ( /^ +/ ){
			# $lm = length($lm);
		# }
		$buf[0] =~ s/^\*//;
		$buf[0] =~ s/^\s*//;
		$buf[0] = ' ' x $lm . '* ' . $buf[0];
		for ( $i = 1; $i <= $#buf; $i++){
			$buf[$i] =~ s/^\s*//;
			$buf[$i] = ' ' x $lm . "  " . $buf[$i];
		}
	}
	elsif ( $opt_i){
		for ( $i = 1; $i <= $#buf; $i++){
			$buf[$i] =~ s/^\s*//;
			$buf[$i] = ' ' x ($opt_i + $lm) . $buf[$i];
		}
	}
	foreach my $x(@buf){
		$x =~ s/\s*$//;
		print "$x\n";
		$LINE++;
	}
	undef(@buf);
	$bufN = 0;
}

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

while(<>){
	# This flag is used to determine if a HTML tag should be
	# counted in the length calculations (used with -p option).
	$skip_word = 0;
	$_ =~ s/\s*$//;
	$NoFmt = 1 if ( $_ eq '<!-- nofm -->');
	if ( $NoFmt){
		print "$_\n";
		$NoFmt = 0 if ( $_ eq '<!-- fm -->');
		next;
	}
	# preformatted label?
	if ( $_ =~ /<pre>/i){
		$PreFmt = 1;
		flushbuf();
	}
	# leave preformatted text as is
	if ( $PreFmt && !$opt_p){
		print "$_\n";
		$PreFmt = 0 if ( $_ =~ /\/pre/ );
		next;
	}
	# if this line begins and ends with tags leave it alone
	if ( $_ =~ /^\s*<.*>$/){
		flushbuf();
		print ' ' x $opt_l . "$_\n";
		next;
	}
	# print empty lines only in HTML files or if it is the first line
	if ( $_ =~ /^$/){
		flushbuf();
		next if ($html == 0 && $LINE);
		print "\n";
		next;
	}
	# -n option -- process and existing numbered list (pre-format HTML or plain text)
	if ( $opt_n && /^\s*[0-9]/){
		flushbuf() if (@buf);
		$opt_i = 3;
	}
	if ( $opt_b && /^\s*\*/){
		flushbuf() if (@buf);
		$opt_i = 2;
	}
	# force newline for list items
	flushbuf() if ($_ =~ /^\s*<li>/i);
	# force newline for list items specified with -u
	flushbuf() if ($_ =~ /^\*/ && $opt_u);
	# work out the left margin (unless specified as an option)
	unless ($opt_l){
		$ws = $_;
		$ws =~ s/\S.*$//;
		$ws =~ s/\t/        /g if ($opt_t);
		$ws =~ s/\t/    /g;
		$lm = length($ws);
	}
	if ( $_ =~ /<.*>/ ){
		$skip_word++ if ($opt_p);
		if ( $html == 0 && !$opt_p){
			$html++;
			$rm = 78 if ( $rm == 72 && $opt_r == 0);
		}
	}
	@w = split( ' ',$_);
	foreach my $x(@w){
		# if -p option specified, look for start of HTML flag
		$skip_word++ if ( $x =~ /</ && $opt_p);
		$Llen += length( $x) unless ($skip_word == 2);
		if ( $Llen > $rm){
			$bufN++;
			$Llen = length( $x);
		}
		unless ($buf[$bufN] ){
			$buf[$bufN] = ' ' x $lm;
			$Lbuf = $buf[$bufN];
		}
		$buf[$bufN] .= "$x ";
		$Lbuf .= "$x ";
		# if -p option specified, look for end of HTML flag
		$skip_word-- if ( $x =~ />/ && $opt_p);
		$Lbuf =~ s/<.*>// if $skip_word;
		$Llen = length($Lbuf);
	}
	# force newline if this line ends with a break tag (or if -p option)
	flushbuf() if ( $_ =~ /<br>$/i || $opt_p);
}
flushbuf() if (@buf);

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