[comp.lang.postscript] Multicolumn ASCII file lister with BS, HT, FF interp.

crtb@nih-csl.UUCP (chuck bacon) (03/16/89)

The following, called multicol.ps, derives from Printall.ps, which I found
on this newsgroup several months ago.  John Birchfield did the main work,
and I have embellished on it as I'm sure many readers have.

It interprets backspaces, tabs, formfeeds and extraneous returns, and is
built so that it could easily adapt to a variable number of columns.

A future feature which might be interesting would be an OPTIONAL first line
on a text starting with `!%' or some such, with desired columns and other
bits indicated therein.  If the first line didn't begin that way, it would
be assumed to be ordinary text.  As it is, doing two columns, nobody has to
provide anything to make it work.

I prefer what it does to what enscript does for the following reason:
an 8.5 x 11 page sideways can be cut in half, drilled, and inserted into an
IBM PC manual.  These manuals are apparently engineered with that in mind.
However, enscript only gives a tiny left margin, and even and odd pages are
only 5.25 inches apart rather than the 5.5 needed.  So here goes:
-----------------cut-----------------
%!PS-Adobe-
%%DocumentFonts: Courier
%%Title:	 MCOL.PS
%%Creator:	 CRTB, with thanks to John Birchfield
%%CreationDate:  Mar. 15, 1989
%%EndComments
%  This file may be placed before an ASCII file to be printed.
%  It chooses Courier, in small enough size to print two pages in landscape.

%  Universal CONSTANTS and basic housekeeping definitions

/CR  13 def			% Carriage Return
/FF  12 def			% Form Feed
/HT   9 def			% Horiz. Tab
/BS   8 def			% BackSpace
/inches { 72.0 mul } def	% Standard def.

%  CONSTANTS

/LMar 0.5 inches	def	% Distance from left edge of paper
/DX   5.5 inches	def	% Distance between columns
/RMar 4.5 inches	def	% Width of text column of 80 chars.
/textpointsize RMar 80 div def 	% Main text size (6.75 pts.)
/DY textpointsize def		% Vertical spacing between lines
/pagenumbersize textpointsize 0.85 mul def	% Page numbers are writ small
/LastX 10 inches	def	% Too far right to start a new column
/Top  8.0 inches	def	% Altitude of top of column
/Bot  0.5 inches	def	% Altitude of bottom

%  VARIABLES

/Line 1024 string def		% Print file line buffer
/Page  4 string def		% Room for page number string
/Pno 0 def			% Variable page number

%  Some procedural definitions; Sorry, guys, but Courier is the only
% fixed-width font found in a LaserWriter, and we can't expand tabs or
% interpret backspaces with variable-pitch fonts!

/Pagenumberfont /Courier findfont pagenumbersize scalefont def
/Maintextfont /Courier findfont textpointsize scalefont def
/CS textpointsize .600 mul def	% Width of a (Courier) character
/m2CS CS dup add neg def	% (used in BS computation)
/PX {LM RMar add} def		% Page-no. X-coord.
/PY Top .2 inches add def	% Page-no. Y-coord.
/Current_X { currentpoint pop } def
/Current_Y { currentpoint exch pop } def


%  Just before we enter our main loop, set landscape, page no. and margins

0 11 inches moveto currentpoint translate -90 rotate
/LM LMar DX sub def		% Phantom column, one to left of column 1
0 0 moveto			% Phantom line, impossibly low down

%		   ---	 Print_All_That_Follows   --- 
%	Print_All_That_Follows does just what it says (hopefully). It
%	begins reading the following lines of the currentfile and writes
%	them out into consecutive columns of the paper until End_Of_File.

/Print_All_That_Follows {
  { currentfile Line readline not { pop exit } if
    Line 0 get FF eq dup { Line 0 CR put } if
    Current_Y Bot le or {	% If at bottom, or Line begins with FF,
      /LM LM DX add def		% Move on to next column.
      LM LastX gt		% If we just overshot, go to next sheet.
        { gsave showpage grestore /LM LMar def } if
      /Pno Pno 1 add def	% Increment and display page no.
      Pagenumberfont setfont PX PY moveto Pno Page cvs show
      Maintextfont setfont 0 Top moveto
     } if			% <<if bottom of column or pagemark>>
    LM Current_Y DY sub moveto	% Start a new line
    % This procedure is executed between characters of 'kshow':
     {pop			% 'kshow' pushes prevs, next chars. onto stack
      dup HT eq {		% Expand tabs:
	1 1 Current_X LM sub	% Is the current char. position
	CS div .5 sub cvi not 7 and {	% at a multiple of eight?
	  pop ( ) show		% If not, display a blank
	 } for			% (may loop 0 to 7 times)
       } if			% <<if next char. is a HT>>
      dup CR eq { LM Current_Y moveto } if
      dup BS eq { Current_X LM gt { m2CS 0 rmoveto } if } if
      pop
     } exch kshow		% 'exch' catches readline's substring
   } loop
  showpage			% The last page must be flushed out.
} def

%---								    ---%
%---			 Let The Program Begin			    ---%
%---								    ---%

Print_All_That_Follows
-----------------cut-----------------
Respectfully submitted: Chuck Bacon, crtb@alw.nih.gov
-- 
crtb @ dxi.nih.gov, crtb @ alw.nih.gov, crb @ nihcudec (Bitnet), (301)496-4823