[comp.lang.perl] Using 'format' for a BSD fold clone

gorpong@ping.chi.il.us (Gordon C. Galligher) (02/22/91)

HARDWARE:  80386
O/S:	   SCO "UNIX" System V.3.2
PERL:	   3.0 PL41

I found that I needed a Berkeley-like fold command, and decided to attempt
it in Perl (so I could try some good stuff with 'format' and 'eval' (I never
used 'eval' before and thought it was about d*mn time.)) :-)

I am sure some of you already know the problem I have experienced:  format
appears to not honor whitespace such as tabs.  All the tabs get truncated
to a single space.  Is there something to tell format not to do this?  Also,
with the code below (I will have ^L there so you do not have to read it if
you do not wish to) is there a way to get format to preserve any blank
lines which show up?  (The manual page states something about @*, but I need
the ^ picture field to get the special magic.)  I could always kludge it
and write my own \n and then decrement $- (I think that is the one) but that
is a mess.

Any help any of you can give me would be greatly appreciated.  This issue 
may have been beaten to death in the past few weeks during which I have not
had the opportunity to read news, and if so, I am sorry.  (But I sure would
like an e-mail reply! :-)  Thank you.

		-- Gordon.
--
Gordon C. Galligher	9127 Potter Rd. #2E	Des Plaines, IL    60016-4881
gorpong@ping.chi.il.us    gorpong%ping@uu.psi.com   ...!uu.psi.com!ping!gorpong
	"I know how it works....That's why I don't like it"
		-- Chip Salzenberg on SCO "UNIX" C2 Security Package

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=snip-snip=snip-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
:
###############################################################################
##									     ##
## ident: @(#)fold 1.0		PERL 3.0			2/21/91	     ##
##									     ##
###############################################################################
##
##	Modification History:
##
##		Opus 1.0
##		02/21/91 - Gordon C. Galligher (gorpong@ping.chi.il.us)
##			This is a simple little hack which does what the 
##			Berkeley 'fold' command does (forces lines to fit
##			a certain length).  Right now it accepts two
##			arguments, -w_width_, and -f.  The -w_width_ is
##			rather obvious, and if the -f is on the command
##			line (before any file names) then a form-feed is
##			injected between files.  These are not the same
##			as the Berkeley program, but as I said, this is a
##			hack.
##
###############################################################################

##
## System V.3 does not have a kernel which recognizes '#!' format, so I need
## to have this so perl will be executed.
##

eval "exec /usr/local/bin/perl -S $0 $*"
	if $running_under_some_shell;

##
## Any variables which have default values.
##

($argv0 = $0) =~ s!.*/!!;			# Get the basename

$DEFWIDTH = 80;					# Default width to break line
$FORMFEED = "\f";				# The formfeed character
$usage    = "usage:  $argv0 [-w_width_] [-f] [file ...]";	# Obvious

##
## Variables which can be changed via the command line
##

$width = $DEFWIDTH;				# The width to break the line
$form  = "";					# Default to no form-feed.
$evexp = "format =\n";				# The start of the eval expr.

##
## Parse command line arguments
##

while ($_ = $ARGV[0], m/^-/)
{
	shift(@ARGV);
	if    ( /^-w\d+/ ) { ($width = $_) =~ s/-w(.*)/$1/; }
	elsif ( /^-w/ )	   { $width = shift(@ARGV); }
	elsif ( /^-f$/ )   { $form   = $FORMFEED; }
	else		   { die "$usage\n"; }
} # WHILE $_ = ...

##
## Now to the good stuff.  The '^' is followed by 'x' ($width-1) '<'
## characters (I LOVE the x operator!) to force the line to be so long,
## and this is followed by two tilde's so the system will automatically
## exhaust $_ before continuing.  Then end the format declaration with
## the period alone on the line.  The next thing executes 'eval' to evaluate
## that nice little format I just built on the fly.
##

$evexp .= '^' . "<" x ($width - 1) . "~~\n\$_\n.\n";
eval "$evexp";

while (<>)					# Read all of the files
{
	chop if length > 0;			# Remove \n if not blank line
	write;					# Do the format magic
	print "$form" if eof && !eof();		# Print \f between files, NOT
} # WHILE <>					# after the last file.
-- 
Gordon C. Galligher	9127 Potter Rd. #2E	Des Plaines, IL    60016-4881
gorpong@ping.chi.il.us    gorpong%ping@uu.psi.com   ...!uu.psi.com!ping!gorpong
	"I know how it works....That's why I don't like it"
		-- Chip Salzenberg on SCO "UNIX" C2 Security Package