{$LINESIZE:130,$TITLE:'Print Formatter'}
{$SYMTAB-}
{$LINE-}
{
+*************************************************************+
|                                                             |
|                       P  R                                  |
|                                                             |
|    This program formats a file for printing.                |
|                                                             |
|    This syntax is:                                          |
|      PR FileSpec [switches]                                 |
|                                                             |
|       Blanks separate all arguments.                        |
|       The File Spec may contain DOS wildcard chars.         |
|       The FileSpec must follow PR.                          |
|       The FileSpec may be a DOS 2.0 path name.              |
|       The switches may be in any order, except that         |
|            /H must be last.                                 |
|                                                             |
|       Enterring just  PR  as a command will cause a         |
|       output of this explanation.                           |
|                                                             |
|       /Fname  re-direct printer output to file "name"       |
|       /H"..."  specify alternate heading                    |
|       /L#   specify line length (80 or 132)                 |
|                  default = 80                               |
|                  default = 55                               |
|       /M#   specify MODE of printer for listing             |
|                  default = 0 (see pg. 3-32 of Epson manual) |
|                  mode 2 = proportional spacing              |
|       /N    no headers                                      |
|       /O#   specify column offset for lines                 |
|                  default = 3                                |
|       /P#   specify page length (0 = don't page break)      |
|       /Q    letter Quality typeface                         |
|       /T#   specify tab spacing                             |
|              default = 8 except = 3 for .PAS & .INC files   |
|       /W    Wait for sheet feed between pages               |
|       /Z    do not output formfeed at end (or rev. LF)      |
|                                                             |
|       Note that  M  and  L  are two ways of specifying      |
|          the same thing; L <=80 is mode 0, L >80 is mode 4  |
|                                                             |
+*************************************************************+
|                  Copyright (c) 1983                         |
|                    Ray Turner                               |
|              Fountain Valley, California                    |
|                                                             |
|       Permission to copy for non-commercial use is          |
|       freely granted and even encouraged.                   |
|                                                             |
+*************************************************************+



						L I M I T A T I O N S


This program outputs a reverse line-feed sequence for the FX-80
 printer before closing the output file.  This is necesary to
 correct for a wierdness in the Pascal runtime code which outputs
 a linefeed upon  closing the file. Why this is so is baffling.  

The program currently requires that the file end with a CR to 
 satisfy a READLN; else a Pascal runtime error will occur.

			******************************************

							N O T E S

The tab algorithm matches that of The Final Word; other editors
 may  be different. This may be alterred in DeTab.

The program assumes an FX-80 printer and makes use of its type
 styles. However, these control codes are well commented and are
 easily changed for other printers. 

The output of the program is, by default, to PRN.  A RAM print
 spooler may be used.  Alternately, the output may be re-directed
 to a file and then printed with the IBM PRINT program.  The
 PRINT program adds a formfeed at the end, hence the /Z switch.
 Unless overridden with /L or /M, .LST files will be printed in
 132 col. format. Unless overridden with the /T switch, .PAS,
 .INC, and .LST files are printed with a tab value of 3, others
 with a tab value of 8. 

.OBJ, .EXE, and .COM files will not be printed.
 
This program uses a DOS interface package written in assembler,
 which is also included. 


			******************************************

}
{$page+}
{
PROGRAM FLOW
	Read command line and set parameters accordingly
	Get first file matching specifier, if none, error
	REPEAT for each file matching specifier
		REPEAT for each line in file
			if bottom of page, print form feed
			if top of page, print header
			convert tabs to spaces
			print line
		LOOP until end of file
		print form feed
	see if there is another file
	LOOP if there is
DONE
	

+*************************************************************+
|                                                             |
|   U N I T   I N T E R F A C E   S P E C I F I C A T I O N   |
|                                                             |
+*************************************************************+
}
{        Include UNIT DOS functions         }

{$INCLUDE:'DOSIF.INC',$LIST-}
{$LIST+}

{$PAGE+}
{
+*************************************************************+
|                                                             |
|                          P  R                               |
|                                                             |
+*************************************************************+
}

PROGRAM PR ( Input, Output );


USES DOSIF (DosDirEnt,FindFirstFile,FindNextFile,SetDTA,Rename,Delete,
					GetDirectory,Chdir,GetDiskSpace,CurrentDisk,GetTime,
					DeltaSecs,Inkey,CheckKey,ClearKey);

PROCEDURE Date(var s:string); EXTERN;

function GetNextArg(var SwitchType,Numeric:boolean;var SwitchChar:char;
			var StringArg:lstring;var NumericArg:integer):boolean;external;
			{ returns next argument from command line }
			{ returns true if there was an argument }
			{ arguments are fields separated by spaces or a slash (/) }
{			SwitchType      true if argument begins with a slash
			Numeric         true if argument is an integer
			SwitchChar      char following / for switch type args
								 (SwitchChar is folded to upper case)
			StringArg       contains the ASCII argument (not the /)
			NumericArg      contains the value of arg, if applicable

			double quotes ("...") must be used to enclose an arg 
				containing a space or slash (/). 
}


{$page+,$subtitle:'Constants & variables'}
										{ Constants for the FX-80 Printer }
CONST
	ESC = chr(27);									{ Escape character }
	BoldConst = ESC * '!' * chr(40);			{ Bold-enlarged style type }
	NormalConst = ESC * '!' * chr(0);		{ Normal Style type }
	CondensedFont = chr(4);						{ 132 col. font }
	NormalFont = chr(0);
	Quality = ESC * 'p' * chr(1);				{ letter quality mode }

									{####  change the default font here  ####}
	DefaultFont = chr(0);					{ use unless spec'd otherwise }


VAR
 Answer     : string(10); 
 Bold       : string(3);   { string to set printer bold for filename}
 ColOffset  : integer;     { Number of columns to indent output }
 CommandError : boolean;         { set if command error detected }
 DOSerror   : integer;        { DOS error code }
 DatePrinted : string(8);  { date printed }
 Directory  : DosDirEnt;      { DOS directory entry }
 DirectoryName : Lstring(13); { filename field from directory record }
 FileExt    : Lstring(3);     { filename extension }
 FileName   : Lstring(64);    { FileName to print }
 FileSpec   : Lstring(64);    { File specifier from command line }
 Heading    : string(27);  { Heading to use }
 HeadingGiven : boolean;   { Heading spec'd on command line}
 HeadingLength : integer;  { Maximum length of heading }
 InputFile  : Text ;          { Input file variable }
 LMspecd    : boolean;        { L or M switch spec'd }
 LetterQuality : boolean;  { letter quality mode-proportional spacing}
 Line       : Lstring(132);   { string to hold lines being read in }
 LineCount  : integer;        { number of lines printer this page }
 LinesPerPage  : integer;  { Number of lines to put on a page  }
 MHour,MMin,MMonth,MDay,Myear  :  word; { Time and date last modified }
 NoHeading  : Boolean;     { False if no headings desired }
 NoMore     : boolean;        { flag for another file to print }
 Normal     : string(3);   { string to set printer back to normal }
 NormalTabs : integer;     { tab spacing for non-.PAS & .INC files }
 NowFont    : string(3);   { actual string to set printer 80/132 mode }
 NumFiles   : integer;        { number of files printed }
 OffsetString : Lstring(132); { holds number of blanks to offset line }
 OutLine    : Lstring(255);   { De-tabbed string to print }
 PageNum    : integer;           { current page number }
 PascalTabs : integer;     { tab spacing for .PAS & .INC files }
 Path       : Lstring(64);    { Path name w/o filename }
 PrintFileName : Lstring(64);    { Name of file being printed }
 PrintOK    : boolean;        { probably ASCII file }
 Printer    : Text ;          { Printer file variable }
 SetFont    : string(3);   { default string to set printer 80/132 mode }
 Tabs       : integer;     { tab stop value }
 Wait       : boolean;     { sheet feed mode-wait between pages }
 Zswitch    : boolean;        { No formfeed-at-end switch }
 ch         : char;
 i          : integer;

{$page+,$subtitle:'Miscellaneous procedures'}

{*************************************************************}
{                                                             }
{                 Some of the less exciting procedures        }
{                                                             }
{*************************************************************}


FUNCTION largest(I1,I2:integer):integer;
begin							 { return larger of 2 integers }
	if I1 > I2 then largest := I1
	else largest := I2;
end;


PROCEDURE Move (var FromString:string;Fstart,Fend:integer;
					var ToString:string;Tstart:integer);
		{move a string (field) from one string to another}
		{the from string is VAR only for efficiency sake}

	var i,j : integer;
	begin
		i := Tstart;
		for j := Fstart to Fend do begin
			ToString[i] := FromString[j];
			i := i + 1
		end;
	end;


PROCEDURE Fill(var ToString:string;Tstart,Tend:integer;ch:char);
		{fill a string (field) with a character.}

	var i : integer;
	begin
		for i := Tstart to Tend do
			ToString[i] := ch;
	end;


PROCEDURE Asciiz (var str:lstring);		{add a null byte to end of string}
begin
	concat(str,chr(0));
end;


PROCEDURE MoveUntil (var ToString:lstring;var FromString:lstring;
							Fstart:integer;ch:char;limit:integer);
	 {move chars from one string to another until a 
								spec'd char is encountered.}
	 {chars are concatenated onto ToString from FromString[Fstart]. 
     Limit sets a max on scan. 
	  FromString is VAR just for efficiency sake.}

var i,count : integer;
begin
	count := scaneq(limit,ch,FromString,Fstart); { = # chars. skipped }
	for i := 0 to (count - 1) do
		concat(ToString,FromString[Fstart + i]);
end;


PROCEDURE MoveFN;		{ Create FileName from Path and FCB filename }
begin
	FileName := Path;
	ch := Directory.name[1];
	i := 1;
	while ch <> chr(0) do begin
		concat(FileName,ch);
		i := i + 1;
		ch := Directory.name[i]
	end;
end;


PROCEDURE AnotherFile (var NoMore:Boolean);		{ check for another file
																	matching filespec }
	BEGIN
	FindNextFile(Directory,NoMore);
	if not NoMore then MoveFN
	END;


PROCEDURE ExtentTab(var OK:boolean);	
								{ Set tabs for normal or Pascal (8,3) }
								{ Set expanded font by file extension }
								{ Set OK to not print binary files    }

	var j : integer;			{ depending on filename extension }
	BEGIN                   { set other EXT dependent stuff too }
		Tabs := NormalTabs;
		OK := true;  { default - ASCII file }
		NowFont := SetFont;
		FileExt := NULL;		{ init. to no extension in filename }
		j := scaneq(64,'.',FileName,1);		{scan for '.' in filename }
		if j < 9 then  			{ move filename extension }
			MoveUntil (FileExt,FileName,j+2,chr(0),3);
		if (FileExt = 'OBJ') or (FileExt = 'EXE') or (FileExt = 'COM') then
			OK := false;   { not an ASCII file }
		if (FileExt = 'LST') and not LMspecd then
			NowFont[3] := CondensedFont;
		if (FileExt = 'PAS') or (FileExt = 'INC') or
		   (FileExt = 'LST') then {Pascal type file}
			Tabs := PascalTabs;
		if Tabs <=0 then Tabs := 1
	END;     {ExtentTab}


 PROCEDURE FormFeed;			{ do top-of-form on printer }
	Begin
		write(Printer,chr(12));
	end;
	
{$page+,$subtitle:'DeTab'}

{*************************************************************}
{                                                             }
{             C O N V E R T  T A B S   to  S P A C E S        }
{                                                             }
{*************************************************************}

	PROCEDURE DeTab (Tabval:integer;var InString,OutString:Lstring;
							limit:integer);
{
	DeTab converts tab characters into the appropriate number of spaces
	while moving the string from InString to OutString.
   limit is the maximum length of OutString. 
	TabVal is the number of columns between tab stops.
}

		var nt,i,j,len  : integer;
			 ch,tab  : char;

		BEGIN
			len := ord(InString.len);
			tab := chr(9);			{horizontal tab char.}
			j := 1;
			OutString[0] := chr(0);		{init. string to null}

			for i := 1 to len do begin
				ch := InString[i];
				if ch = tab then begin 

					{ magic formula matching Final Word tabs }
					nt := Tabval - ( (j - 1) MOD Tabval);

					while nt > 0 do begin
						concat (OutString,' ');
						j := j + 1;
						if j >= limit then BREAK;
						nt := nt - 1
					end;   {while}
				end
				else { not a tab char } begin
					j := j + 1;
					if j >= limit then BREAK;
					concat(OutString,ch)
				end {if}
			end; {for}
		END;     {DeTab}

{$page+,$subtitle:'directions'}

 PROCEDURE PrintDirections;  { print directions if no args given }
   begin

writeln('+----------------------------------------------------------+');
writeln('|                                                          |');
writeln('|                       P  R                               |');
writeln('|                                                          |');
writeln('|    This program formats a file for printing.             |');
writeln('|                                                          |');
writeln('|    This syntax is:                                       |');
writeln('|      PR FileSpec [switches]                              |');
writeln('|                                                          |');
writeln('|       Blanks separate all arguments.                     |');
writeln('|       The File Spec may contain wildcard chars.          |');
writeln('|       The FileSpec must follow PR.                       |');
writeln('|       The FileSpec may be a DOS 2.0 path name.           |');
writeln('|       The switches may be in any order, except that      |');
writeln('|            /H must be last.                              |');
writeln('|                                                          |');
writeln('|       /Fname  re-direct printer output to file "name"    |');
writeln('|       /L#   specify line length (80 or 132)              |');
writeln('|                  default = 80                            |');
writeln('|       /P#   specify page length (0 = don''t page break)   |');
writeln('|                  default = 55                            |');
writeln('|       /N    no headers                                   |');
writeln('|                                                          |');
writeln('Press RETURN for more switches');
read(ch); { wait to continue }
writeln('|                                                          |');
writeln('|       /O#   specify column offset for lines              |');
writeln('|                  default = 3                             |');
writeln('|       /Q    letter Quality typeface                      |');
writeln('|       /H"..."  specify alternate heading                 |');
writeln('|       /M#   specify MODE of printer for listing          |');
writeln('|               default = 0 (see pg. 3-32 of Epson manual) |');
writeln('|               mode 2 = proportional spacing              |');
writeln('|       /T#   specify tab spacing                          |');
writeln('|             default = 8 except = 3 for .PAS & .INC fil   |');
writeln('|       /W    Wait for sheet feed between pages            |');
writeln('|       /Z    do not output formfeed at end (or rev. LF)   |');
writeln('|                                                          |');
writeln('|       Note that  M  and  L  are two ways of specifying   |');
writeln('|       the same thing; L <=80 is mode 0, L >80 is mode 4  |');
writeln('|                                                          |');
writeln('+----------------------------------------------------------+');
writeln('|                  Copyright (c) 1983                      |');
writeln('|                    Ray Turner                            |');
writeln('|              Fountain Valley, California                 |');
writeln('+----------------------------------------------------------+');
writeln;
CommandError := TRUE; { to stop any attemp at printing }
END;

{$PAGE+,$SUBTITLE:'Process Command Line'}
{
***************************************************************
|                                                             |
|                  C O M M A N D S                            |
|                                                             |
|   This procedure retrieves the parameters passed to PR      |
|   from the user command line and interprets them.           |
|                                                             |
***************************************************************
}

PROCEDURE Commands;

VAR
	tab            : integer;
	mode           : integer;
	length 			: integer;
	LineLength      : integer;
	LenFS, LenColon, LenBackSlash, LenPath : integer;
		{ command line argument variables }
	SwitchType,Numeric : boolean;
	SwitchChar : char;
	StringArg : Lstring(80);
	NumericArg : integer;


PROCEDURE BadCommand;
	begin
	writeln('ERROR IN COMMAND LINE IN SWITCH: ',SwitchChar);
	CommandError := TRUE;
	end;


BEGIN               					      {COMMANDS}
	HeadingGiven := FALSE;
	CommandError := FALSE;
	Zswitch := FALSE;
	Wait := false;
	LetterQuality := false;

	if not GetNextArg(SwitchType,Numeric,SwitchChar,FileSpec,NumericArg)
		then { null command line } PrintDirections
	else if SwitchType then begin
		CommandError := true;
		writeln('Missing or invalid File Specifier');
	end else begin
							{extract filespec from command line}
		ASCIIZ(FileSpec);        { add null to end of file spec for DOS }

						{  search and extract path specifier  }

		LenFS := ord(FileSpec.len);		{ find whether : or \ in FileSpec }
		LenColon := LenFS + scaneq(-LenFS,':',FileSpec,LenFS);
		LenBackSlash := LenFS + scaneq(-LenFS,'\',FileSpec,LenFS);
		LenPath := largest(LenColon,LenBackSlash);
		Path := NULL;
		for i := 1 to LenPath do concat(Path,Filespec[i]);
	
		LMspecd := false;
	end;
											{ now get the rest of the arguments }

	while GetNextArg(SwitchType,Numeric,SwitchChar,StringArg,NumericArg)
		do begin
		if SwitchType then begin

			CASE SwitchChar OF

			'M' : BEGIN					{ FX-80 mode switch }
						IF NOT Numeric then BadCommand;
						Mode := NumericArg;
						if Mode > 63 then Mode := 0;
						if Mode = 2 then { proportional space } begin
							SetFont[2] := 'p';
							SetFont[3] := chr(1);
							end
						else { normal mode setting } begin
							Mode := Mode AND #00FD;   { turn off bit 1 }
							SetFont[3] := chr(Mode)
							end;
						LMspecd := true
					END;		
	
			'O' : BEGIN					{ column offset switch }
					IF NOT Numeric then BadCommand;
					ColOffset := NumericArg;
					IF ColOffset > 132 then ColOffset := 132;
					IF ColOffset < 0 then ColOffset := 0
					END;
	
			'N' :							{ no heading switch }
					NoHeading := TRUE;
	
			'Q' :							{ letter quality }
					LetterQuality := TRUE;

			'L': BEGIN						{ line length switch }
					IF NOT Numeric then BadCommand;
					LineLength := NumericArg;
					IF LineLength <81 then SetFont[3] := NormalFont
					ELSE SetFont[3] := CondensedFont;
					LMspecd := true
					END;

			'T' : BEGIN					{ set tabs switch }
					IF NOT Numeric then BadCommand;
					Tab := NumericArg;
					if Tab < 1 then tab := 1;
					if Tab > 132 then Tab := 132;		
					NormalTabs := Tab;
					PascalTabs := Tab
					END;

			'P' : BEGIN					{ # lines per page switch }
					IF NOT Numeric then BadCommand;
					LinesPerPage := NumericArg;
					IF LinesPerPage <= 0 then 
						LinesPerPage := 32760; {make infinite (-1 to avoid ovflo)}
					END;

			'H' : BEGIN					{ heading switch }
					length := ord(StringArg.len);
					if length > HeadingLength then {heading too long}
						length := HeadingLength;
					fill(Heading,1,HeadingLength,' ');
					move(StringArg,1,length,Heading,1);
					HeadingGiven := TRUE;
					END;

			'F' : BEGIN					{ re-direct printer output }
					PrintFileName := NULL;
					copylst(StringArg,PrintFileName);
					writeln('print output re-directed to file: ',
								PrintFileName)
					END;
	
			'W' :							{ sheet feed switch }
					Wait := TRUE;

			'Z' : BEGIN					{ no formfeed-at-end switch }
					Zswitch := TRUE
					END;

			OTHERWISE BEGIN 
						BadCommand;
						writeln('UNKNOWN SWITCH SPECIFIED')
					END;

			END;   {end of CASE }

		end; {if SwitchType}
    end;  {while any more args}

END;  		{ Commands }

{$page+,$subtitle:'Print header'}

{*************************************************************}
{                                                             }
{                  P R I N T  the  H E A D E R                }
{                                                             }
{*************************************************************}

	PROCEDURE PrintHeading;   { printer header on top of each page }
	BEGIN

					{#### remove if you want a formfeed before 1st page ####}
		if PageNum > 0 then FormFeed;	{ no TOF for first page of file }
		PageNum := PageNum +1;	

		if Wait then begin     { sheet feed mode - wait for return }
			writeln('Insert next sheet of paper and press enter.');
			readln(Answer);
		end;
		IF NOT NoHeading then begin
			write(Printer,Bold);
			writeln(Printer,'  ',Heading,'  ',DatePrinted);
			write(Printer,Normal);		{ switch back top normal typeface }
			writeln(Printer,'   Page ',PageNum:2,' ':38,'Last Modified: ',
						MMonth:2,'/',MDay:2,'/',Myear:2,'  ',
						MHour:2,':',MMin:2);
			writeln(Printer);     			{ blank line after header }
			LineCount := 0;
		end
		else LineCount := 3;					{ to get same # lines/page }
		if LetterQuality then write(Printer,Quality)
		else write(Printer,NowFont);	{ set printer to 80 or 132 mode }
	END;         {PrintHeading}

{$PAGE+,$subtitle:'Main Program'}

{*************************************************************}
{                                                             }
{                  T H E   P R O G R A M                      }
{                                                             }
{*************************************************************}

BEGIN

{$pageif:10}

{*************************************************************}
{                                                             }
{           Interpret Command Line and set Parameters         }
{                                                             }
{*************************************************************}

										{ default values for parameters }

	Bold := BoldConst;
	Normal := NormalConst;
	ColOffset := 3;
	NoHeading := FALSE;
	LinesPerPage := 55;			{ default value }
	NormalTabs := 8;
	PascalTabs := 3;
	SetFont[1] := ESC; SetFont[2] := '!'; SetFont[3] := DefaultFont;
	HeadingLength := 27;					{ length of listing heading }
	NumFiles := 0;						{ number of files printed }
	PrintFileName := 'PRN';			{ set to printer as default }

	Commands;			{ read and interpret command line }
	if not CommandError then begin { print the stuff }

	ASSIGN (Printer,PrintFileName);			{ open the printer }
	REWRITE (Printer);

	writeln('printing file(s): ',FileSpec);
	write (LinesPerPage,' Lines per page     ');
	write ('Column offset = ',ColOffset:3,'     ');
	writeln;
	if NoHeading then write ('without heading     ');
	writeln;
	
	date (DatePrinted);		{ get today's date }		
									{ convert leading 0 to blank }
	If DatePrinted[1] = '0' then DatePrinted[1] := ' '; 
	
		{ set up a string with the number of blanks wanted for offset }
	for i := 1 to ColOffset do concat(OffsetString,' ');

{$pageif:10}

{*************************************************************}
{                                                             }
{             G E T  A  F I L E  T O  P R I N T               }
{                                                             }
{*************************************************************}


FindFirstFile(FileSpec,Directory,NoMore,DOSerror);

if NoMore then writeln('No files found matching specifier')
else



				{ here's where we really go to work printing a file! }
REPEAT 

	PageNum := 0;		               { Set page number }
	LineCount := LinesPerPage;			{just so we start with a heading}

	MoveFN;				{ create filename from Path and DOS buffer }

	MYear := (Directory.date DIV 512 ) + 80;
	MMonth := (Directory.date MOD 512) DIV 32;
	MDay := Directory.date MOD 32;
	MHour := Directory.time DIV 2048;
	MMin := (Directory.time MOD 2048) DIV 32;

	ExtentTab(PrintOK);						{ set tab stop by checking filename ext }
	if PrintOK then {its an ASCII file} begin 
		writeln('Printing: ',FileName,'  @ tabs =',Tabs:3);
		ASSIGN (InputFile,FileName);	{ open the file }
		RESET(InputFile);
	
		NumFiles := NumFiles + 1;

												{if no heading spec'd, use filename}
		if not HeadingGiven then begin
			fill(Heading,1,HeadingLength,' ');
			move(FileName,1,ord(FileName.len),Heading,1);
		end;

{$pageif:12}

{*************************************************************}
{                                                             }
{                  P R I N T  the  F I L E                    }
{                                                             }
{*************************************************************}


		While not eof(InputFile) DO
		begin
			readln(InputFile,Line);
			LineCount := LineCount +1;
			If LineCount >= LinesPerPage then PrintHeading;
			DeTab(Tabs,Line,OutLine,250);		{convert tabs to blanks}
			write(Printer,OffsetString);
			writeln(Printer,OutLine);
			if ( ord(OutLine.len) + ColOffset > 80 ) AND 
				(NowFont[3] = NormalFont) then { printer's going to fold line}
				LineCount := LineCount + 1
		end;


	writeln(PageNum:3,' Pages');
	Close(InputFile);

end
else writeln('Skipping: ',FileName);

											{ See if there's another file }
AnotherFile(NoMore);

			{ ##### remove if you change to formfeed at beginning of listing }
if (not NoMore) and PrintOK then FormFeed;     				{ Do top-of-page }

UNTIL NoMore  { files to print };


writeln;
writeln(NumFiles,' Files Printed');
writeln;	
if not Zswitch then begin
	FormFeed;
	write(Printer,ESC,'@');			{ reset printer to "normal" }
					{ This next wierdness is to correct for Pascal
					  doing a line-feed when closing the printer!! }
	write(Printer,ESC,'j',chr(36));		{ reverse feed one line }
end;

Close(Printer);

end; { Command Error - no printing }

END.
