#!/usr/local/bin/perl

#   lprint2 - print ascii documents as two columns in PostScript landscape mode
#
#   Usage: lprint2 < /etc/sendmail.cf | lp
#
#   This software is Public Domain. Please maintain version history.
#   Report all bugs to Greg Ercolano (erco@3dsite.com).
#
#     1.00 10/04/98 erco@3dsite.com  -
#     x.xx xx/xx/xx -                -
#
use strict;
use Text::Tabs;		# expand()

my ($XSTART2COL_LEFT)    = .45;
my ($YSTART2COL_LEFT)    = (0 - .20);
my ($XSTART2COL_RIGHT)   = .45 + 5.3;
my ($YSTART2COL_RIGHT)   = (0 - .20);
my ($LINESPERPAGE2COL)   = 70;
my ($LINEWIDTH2COL)      = 80;
my ($FONTSIZE2COL)       = .10;


# RETURN STRING CONVERTED INTO AN 'ESCAPED' POSTSCRIPT TEXT STRING
#
#    $1 - REFERENCE: string
#
sub String2PSString($)
{
    my ($s) = @_;

    # Convert all tabs to spaces
    $s = expand($s);

    # Ugly hack to make sure no char mistaken for special postscript codes
    {
	my $s_out;
	foreach ( split ( //, $s ) )
	{
	    if ( ! /[A-Z,a-z,0-9 ]/ )
		{ $s_out .= "\\"; }
	    $s_out .= $_;
	}
	$s = $s_out;
    }
    return($s);
}

# FEED OFF A PAGE
#
#    $1 - HASH REFERENCE: %pageinfo
#    Returns 1 if a new paper page was just fed off.
#
sub FormFeed($)
{
    my ($pageinfo) = @_;

    $$pageinfo{'line'} = 0;
    $$pageinfo{'page'}++;

    if ( ! ( $$pageinfo{page} & 1 ) )
    {
	# EVEN NUMBERED PAGES APPEAR IN UPPER RIGHT OF PAGE
	#    Simply adjust the cursor position.
	#
	$$pageinfo{'x'} = $XSTART2COL_RIGHT;
	$$pageinfo{'y'} = $YSTART2COL_RIGHT;
	return(0);
    }
    else
    {
	# ODD NUMBERED PAGES ROLL OVER TO THE NEXT PHYSICAL PAGE
	#    Tell postscript to feed off a page.
	#
	$$pageinfo{'paperpage'}++;

	print "showpage restore\n\012" .
	      "%%Page $$pageinfo{paperpage} $$pageinfo{paperpage}\n" .
	      "save\n" .
	      "/Courier findfont $FONTSIZE2COL scalefont setfont 0 setgray\n";
	$$pageinfo{'x'} = $XSTART2COL_LEFT;
	$$pageinfo{'y'} = $YSTART2COL_LEFT;
	return(1);
    }
    #NOTREACHED#
}

# PRINT A LINE
#
#   $1 - REFERENCE: string to print
#   $2 - HASH REFERENCE: %pageinfo
#
#   Print's line, adjusts pageinfo values.
#
sub PrintLine($$)
{
    my ($s,$pageinfo) = @_;

    printf("%f %f moveto (%s) show\n", 
	$$pageinfo{'x'}, 
	$$pageinfo{'y'},
	String2PSString($$s));

    $$pageinfo{'y'} -= ($FONTSIZE2COL * 1.15);
    $$pageinfo{'line'}++;

    # Time to move to next page?
    if ( $$pageinfo{'line'} >= $$pageinfo{'linesperpage'} )
	{ return(FormFeed($pageinfo)); }
    
    return(0);
}

sub Ascii2PS2Col($$)
{
    my($linesperpage,	# lines per logical page (NOT PAPER PAGE)
       $maxwidth,	# max width of each line
      ) = @_;

    my %pageinfo;
    my $s = "";
    my $ff;
    my $line;

    $pageinfo{'x'}            = $XSTART2COL_LEFT;
    $pageinfo{'y'}            = $YSTART2COL_LEFT;
    $pageinfo{'line'}         = 0;
    $pageinfo{'page'}         = 1;	     # logical page (2 per paper page)
    $pageinfo{'paperpage'}    = 1;	     # paper pages
    $pageinfo{'linesperpage'} = $linesperpage;

    print <<"EOF";
\%!PS-Adobe-1.0
\%\%DocumentFonts: Courier
\%\%Dimensions: 0 0 612 792
\%\%Title: bu_utl
\%\%Creator: none
\%\%Pages: (atend)
\%\%EndComments
72 72 scale
90 rotate
save
\%\%EndProlog
\%\%Page $pageinfo{page} $pageinfo{page}
save
/Courier findfont $FONTSIZE2COL scalefont setfont 0 setgray
EOF

    # Line loop
    while ( <STDIN> )
    {
	s/\n//;		# strip crlfs
	$line = $_;

	while ( length ( $line ) > 0 )
	{
	    # BREAK LINE UP INTO maxwidth CHUNKS
	    $s    = substr($line, 0, $maxwidth);
	    $line = substr($line, $maxwidth);

	    # Check for form feeds in line
	    $ff = index($s, "\012");		# form feed?

	    # FF? Break line into pre-FF string and post-FF string,
	    #     print pre, move to next page, print post.
	    #
	    if ( $ff != -1 )
	    {
		my $a = substr($s, 0, $ff);
		my $b = substr($s, $ff+1);

		if ( $a ne "" ) { PrintLine(\$a, \%pageinfo); }
		FormFeed(\%pageinfo);
		if ( $b ne "" ) { PrintLine(\$b, \%pageinfo); }
		next;
	    }
	    else
	    {
		PrintLine(\$s, \%pageinfo);
	    }
	}
    }

    # Trailer
    print "showpage restore\n" .
	  "%%Trailer\n" .
	  "%%Pages: $pageinfo{paperpage}\n";
    return(0);
}

## MAIN
{
    Ascii2PS2Col($LINESPERPAGE2COL, $LINEWIDTH2COL);
    exit(0);
}
