program miser;
{Miser prints files in a format modelled on Tenex listing files.
 I.e. page numbers at the top of each physical page.  Logical
 pages do not force you to a new physical page, but just draw
 a line across the paper.  This is intended to save paper, and
 to be a bit more readable}

include 's:<pascal>pascmd.pas';

const
	noswitch=0;
	filesw=1;

var line:packed array[1:132]of char;  {place where a line is assembled}
  {Here are the major global state variables:
	logpage - the page number in the input file (logical page)
	subpage - starts at 1 when you go to a new logical page.
		Increased by 1 for each physical page on this
		logical page
	linenumber - line number on this physcial page}
   i,logpage,subpage,linenumber:integer;
   hyphens,filename:packed array[1:200]of char;
   swdone,ccl,gotfile:Boolean;
   switchtable:table;
   xwd:packed record case Boolean of
	true:(full:integer);
	false:(lh:0..777777B;rh:0..777777B)
	end;

{Digits returns the number of digits it will take to print a number}
function digits(number:integer):integer;
  var i:integer;
  begin
  i := 1;
  while (number div 10) > 0 do
    begin
    number := number div 10;
    i := i+1
    end;
  digits := i
  end;

{Header prints the page number, etc., at the top of a page.
 TOPPAGE means it is at the top.  Otherwise is in the middle of
 a page where a new logical page starts and we decide to draw
 a line instead of forcing a new page}
procedure header(toppage:Boolean);
  var i:integer;
  begin
  if subpage > 0
    then i := 6 + digits(logpage)
    else i := 6 + digits(logpage) + 1 + digits(subpage);
  write('-- ');
  write(' Page ',logpage:0);
  if subpage > 0
    then write(':',subpage:0);
  if toppage
    then write(' -- ',filename:72-i-7)
    else write(' ',hyphens:72-i-4);
  writeln
  end;

{CHECKEOP is done on every line to see if we need to go to a new
 page.  As a sideeffect increments SUBPAGE since we are then on
 the next physical page within the current logical one}
procedure checkeop;
  begin
  if linenumber > 60
    then begin
    page;
    subpage := subpage + 1;
    header(true);
    writeln;
    writeln;
    linenumber := 4
    end
  end;

{FORCEPAGE just puts out a new physical page.  Doesn't increment
 subpage}
procedure forcepage;
  begin
  page;
  header(true);
  writeln;
  writeln;
  linenumber := 4
  end;
    
procedure quit; extern;

{Scanfile is used to handle the argument to the /OUTPUT-FILE
 command.  It closes the default output file and gets a new one
 based on the user's file spec}
procedure scanfile;
  begin
  cmofi(output);
  gotfile := true;
  end;

begin

{Switchtable is table of compiler switches}
switchtable := tbmak(1);
tbadd(switchtable,filesw,'OUTPUT-FILE:',0);

cminir('MISER>');  {Prompt - cminir allows rescan usage}

cmifi(input);		{This is the main part of the command: input file}

  {now scan switches}
gotfile := false;
swdone := false;
loop
    cmmult;	{multiple mode}
    cmcfm;	{CRLF}
    i := cmswi(switchtable);  {or switch - i is dummy return}
    i := cmdo;  {now actually do it}
    exit if i = 1  {done if CRLF}    
    case cmint of
	filesw:scanfile
	end;
    end;

  {open files}
if gotfile
  then rewrite(output)
  else rewrite(output,'LPT:');
reset(input,'','/E');  {we need to see EOLN char, for form feeds, etc.}
   {set up strings used for header}
for i := 1 to 200 do filename[i] := ' ';
for i := 1 to 200 do hyphens[i] := '-';
jsys(30B{jfns};-1:filename,0:input,111110044011B,0);  {input file name
							to FILENAME}
   {init variables used in page counting}
logpage := 1; subpage := 0;
forcepage;
   {now the main loop}
while not eof do
  begin
  checkeop;
    {we copy in bunches of 132 characters until we see an end of line}
  repeat
    read(line:i);
    write(line:i)
   until i <= 132;
     {now analyse end of line}
  if input^ = chr(15B)  {CR - not really a new line, so just copy it}
    then write(output,input^)
  else if input^ = chr(12B)   {LF - is a new line, so count it}
    then begin write(output,input^); linenumber := linenumber + 1 end
  else if input^ = chr(14B)  {FF - on a new logical page, so do header}
    then if linenumber > 57  {if not room, to new page}
	   then begin linenumber := 61;
		logpage := logpage + 1;
		subpage := 0;
		forcepage
		end
	   else begin    {else a header on this page}
		writeln;
		logpage := logpage + 1;
		subpage := 0;
		header(false);
		writeln;
		linenumber := linenumber + 3
		end
  else begin writeln; linenumber := linenumber + 1 end;
  get(input)
  end
end.
