[net.sources] Part 1 of 4 - PostScript programs

stephenf@elecvax.eecs.unsw.oz (Stephen Frede) (05/21/86)

# This is a set of programs which produce PostScript. Included are
# a back end for ditroff, a program which accepts plain text, and a
# program which accepts images.
# Also included are ditroff font width files and some miscellaneous
# PostScript scripts.
# For more details see the file READ_ME in the first part.
# There are 4 parts.
#
# Stephen Frede	University of New South Wales, Sydney, Australia
# 
# ACSnet:	stephenf@elecvax.oz	ARPA:	stephenf%elecvax.oz@seismo
# CSnet:	stephenf@elecvax.oz@csnet-relay.csnet
# UUCP:	{seimso,ubc-vision,ukc,mcvax,prlb2}!munnari!elecvax.oz!stephenf
# ------------------------------------------------------------------------

# This is a shell archive.  Remove anything before this line, then
# unpack it by saving it in a file and typing "sh file".  (Files
# unpacked will be owned by you and have default permissions.)
#
# This archive contains:
# READ_ME Makefile man/ipscript.1 man/lpscript.1 src/Makefile src/troff.sh src/tpscript/Makefile src/tpscript/dev.h src/tpscript/gendefs.sed src/tpscript/hash.h src/tpscript/pscript.h src/tpscript/sfont2defs.H src/tpscript/sfont2defs.h src/tpscript/stringdefs.H src/tpscript/stringdefs.h src/tpscript/tpscript.h

echo Creating directories man src src/opscript src/tpscript src/pscript devalw
mkdir man
mkdir src
mkdir src/opscript
mkdir src/tpscript
mkdir src/pscript
mkdir devalw

echo x - READ_ME
cat > "READ_ME" << '//E*O*F READ_ME//'
Copyright:	1985, Stephen Frede, UNSW Australia
	Use it and copy it as much as you want, but don't pretend you
	wrote it, or sell it for profit.

Authorship:	Originally by Stephen Frede.
		Various extensive changes by
			Cameron Davidson and Michael Rourke.

Contents:
	0) File 'READ_ME', directories 'src', 'src/tpscript',
		'src/opscript', 'src/pscript', 'man', 'devalw'

	1) Source for a back end to ditroff which converts ditroff
	   output to PostScript (src/tpscript).

	2) Font code and width tables suitable for use with ditroff (devalw).

	3) A program (lpscript) which converts plain text into postscript.
	   various options allow selection of font, size and rotation, etc.

	4) A program (ipscript) which converts bitmap images of various sorts
	   into postscript.

	5) Manual entries for lpscript and ipscript.

	6) The directory src/pscript contains some random postscript
	   programs that may or may not be useful.


NOTES:
	The sources should be pretty much bug free. They have been run on
	a few different systems, but I have no doubt that upon releasing it
	to the world, some will come to light. Please mail suggestions
	and fixes directly to me at the address given above.

	The troff names for many of the characters were taken from a paper
	about such things from:
		"Adventures with Typesetter Independent Troff", by
	Mark Kahrs and Lee Moore, Dept. Computer Science, University
	of Rochester, Rochester, NY 14627. TR159; June, 1985.

	Work is in progress to allow down-line loading of fonts other than
	those available by default in the LaserWriter (or whatever), such
	as the Berkeley fonts.

	They have never been run on anything other than a LaserWriter, but
	I don't know of any inherent machine dependencies (other than those
	indicated by "#if ALW").

	There are some further changes made by Cameron Davidson to fine tune
	some problems with rounding to pixel boundaries on the LaserWriter
	that are not included in this release.

	There are two basica possible approaches to generating postscript
	from some other format. The first is to generate a postscript
	program which then reads input and does the conversion itself.
	The alternative is to do as much of the translation as possible
	first, generating relatively simple postscript commands. This
	is the way these programs work. I have not seen Transcript, by
	Adobe Systems, but I suspect they do it the first way.

	Add an entry to the "magic" file that the file(1) command uses
	to look for the characters "%!" at the start of a file.
	This indicates that a file is "PostScript".

Installation:
	First you must have ditroff, a device independant troff from ATT,
	requiring a licence. This most usually comes with Documenter's
	WorkBench (DWB). This should include the program "makedev", used
	to "compile" the ascii font tables into binary, so that troff and
	tpscript can read them.

	Put all of this stuff into a directory somewhere.
	Edit the Makefile in the top directory and set SYS= one of the
	systems indicated there (AUSAM, V7, SYS5, BSD).
	Then set VERBOSE=1 if you want some needless extra frills. This
	is mainly just identifying jobs by username, etc.
	Set MAKEDEV to be the pathname of the makedev program (in the
	troff source directory ?).
	Then compile it all by saying "make" in the top directory.
	This should generate tpscript, ipscript and lpscript.
	Install them manually in whatever way is appropriate for your system.
	Possibly change the Makefiles to do this. Also note that the
	Makefiles will not do anything smart about .o files or anything
	like that.
	We have installed the real troff in /bin/ditroff and made troff a
	shell script that invokes the appropriate back end. The shell script
	is included here as src/troff.sh, use it if you want.
	Install the manual entries for ipscript and lpscript (from the man
	directory).

Possible problems:
	First read the problems section in "Inside LaserWriter".
	Note the various patches from Adobe that have come over USENET.

	On some versions of Unix, if the LaserWriter is connected to
	a tty port, and a daemon of some sort continually sends stuff to
	the LaserWriter, but never reads anything, and the LaserWriter
	sends messages back (which aren't read by anyone), then when
	the total number of unread characters reaches a certain amount
	(TTYHOG, 256 or 512 usually), both the input AND output queues
	are flushed, so some characters to the LaserWriter get dropped,
	probably causing a syntax error and the rest of the job to be
	flushed. A good thing to do (even if you don't have this problem)
	is to collect all the output from that line and save it in a file.
	This makes looking at error and other messages from the LaserWriter
	quite easy (tail /tmp/laserout).

	Note a bug in many versions of eqn(1) which causes a right large
	square bracket to be made of '|' characters instead of "\(bv" chars.
	If you have the source, this is easy to fix.

	I don't know what some of the Berkeley ditroff output means.
	If someone would like to fill me in, I'll add it to tpscript.
//E*O*F READ_ME//

echo x - Makefile
cat > "Makefile" << '//E*O*F Makefile//'

# SYS should be one of AUSAM, BSD, SYSV, V7
# This is only really important if VERBOSE (below) is 1.
SYS=SYSV
# VERBOSE should be 1 to generate postscript code to echo stuff
# back down the communication line. Otherwise 0.
VERBOSE=0
MAKEDEV=../devalw	# pathname relative to devalw
CD=builtin cd

all:
	$(CD) src; $(MAKE) $(MFLAGS) SYS=$(SYS) VERBOSE=$(VERBOSE)
	$(CD) devalw; $(MAKE) MAKEDEV=$(MAKEDEV)
//E*O*F Makefile//

echo x - man/ipscript.1
cat > "man/ipscript.1" << '//E*O*F man/ipscript.1//'
.TH IPSCRIPT 1
.SH NAME
ipscript \- convert bit image into postscript
.SH SYNOPSIS
.B ipscript
[option] ... [file] ...
.SH DESCRIPTION
.I Ipscript
reads bit images from standard input (or files if specified) and produces
postscript output, suitable for sending to any postscript device (such
as an Apple Laserwriter) or for using with any program that expects
postscript input (such as a postscript interpreter used to drive some
other raster device).
In the output, grey levels are represented by a halftoning technique,
whereby a grid of halftone cells is produced from the input data.
The default frequency of halftone cells is 60 per inch, and an angle of 45 degrees.
(Alterable using the
.B \-f
and
.B \-p
options.)
The following options are understood:
.TP
.B \-wWidth
The image produced will be the given width (in cm).
This may be a real number.
The default is 18 cm.
.TP
.B \-hHeight
The image will be produced with the given height (in cm).
This may be a real number.
The default is 12cm.
.TP
.B \-aAspect
The image will be produced with the given aspect ratio.
The default aspect ratio is 1.5 (width/height).
If both width and height are specified on the command line,
the aspect ratio will be determined from these, rather than
this argument.
.TP
.B \-bBits
This argument controls the output resolution (ie the number of grey
levels used).
It may be any of 1, 2, 4, or 8 for 2, 4, 16 or 256 output grey
levels respectively.
The default is 8 bits.
.TP
.B \-gGrey
This (signed integer) value can be used to offset the input grey level by
a fixed amount.
It can be used to brighten or darken images.
.TP
.B \-yScanlines
This value determines the number of pixels along the Y axis of
the input image.
This is the number of scanlines of the input.
The default is 256.
.TP
.B \-xScanlength
This value is the number of pixels along the X axis of the input image.
This is the length of an input scanline.
The default is 256.
.TP
.B \-fFrequency
This value determines the output frequency in halftone cells/inch.
The default is device dependant, but is 60 for the Apple LaserWriter.
.TP
.B \-pAngle
Specifies the angle (in degrees) at which the output halftone cell
grid is rotated.
The default is device dependant, but is 45 for the Apple LaserWriter.
.TP
.B \-iFormat
This argument specifies the input format and resolution.
It consists of a character ('b' or 'x') followed by a value.
The character specifies the form of the input: whether input data
is given in raw bytes or in hex notation.
The following value gives the input greyscale resolution - the number
of bits representing the image which may appear in the input.
If hex input format is being used and the greyscale resolution is
less than or equal to 4 bits, single hex bytes are read, otherwise pairs
of hex bytes are read to achieve a resolution of up to 8 bits.
The default is 'b8' - bytes with a possible value of from 0 to 255.
Input is scaled using this information and the number of output
grey levels (if necessary).
.TP
.B \-sSkip
Directs \fIipscript\fP to skip the given no. of bytes at the start
of the input file.
This is useful for files which have headers at the beginning.
For example, Macquarie Uni satellite photos have a 128 byte header.
.TP
.B \-r[angle]
This argument specifies an image rotation in degrees.
If '-r' is given with no value, 90 is assumed, which results in landscape
mode being used (long axis of paper horizontal).
The default is 0, which is portrait mode (long axis of paper vertical).
.TP
.B \-n
Print the negative of the image. That is, reverse black and white.
.TP
.B \-S
Use manual feed instead of feeding from the paper tray.
.TP
.B \-L
Print using legal page type - 17.8 by 31.8 cm (7 by 12.5 inches) imageable
region, centred
on a 21.6 by 35.6 cm (8.5 by 14 inch) page.
The default (letter) paper type uses a 20.3 by 26.7 cm (8 by 10.5 inch)
imageable region, centred on a 21.6 by 27.9 cm (8.5 by 11 inch) page.
.SH SEE ALSO
ditroff(1)
.SH AUTHOR
Stephen Frede, UNSW, Australia
//E*O*F man/ipscript.1//

echo x - man/lpscript.1
cat > "man/lpscript.1" << '//E*O*F man/lpscript.1//'
.TH LPSCRIPT 1
.SH NAME
lpscript \- convert text to postscript
.SH SYNOPSIS
.B lpscript
[-o[offset]] [-r[rotation]] [-s[fontsize]] [-f[font]]
[-p[pitch]] [-t[tabsize]] [-h[horizontal_spacing]] [-S] [-L] [file ...]
.SH DESCRIPTION
.I Lpscript
reads text from standard input (or files if specified) and produces
postscript output, suitable for sending to any postscript device (such
as an Apple Laserwriter) or for using with any program that expects
postscript input (such as a postscript interpreter used to drive some
other raster device).
Text is normally aligned at the top and left with the imageable region
of the page (probably slightly smaller than the physical page size),
and a new page is taken whenever text would fall below this imageable
region.
The following options are understood, with all values able to be given
as integer or real:
.TP
.B \-o[distance]
Offset the text from the left edge of the imageable region, by the given
distance (in centimeters).
If \fB-o\fP is specified without a distance, 1 cm is assumed.
.TP
.B \-r[angle]
Rotate the page by the given angle, specified in degrees.
If no angle is specified, 90 degrees is assumed.
Normally, the page will be printed in portrait mode, ie with the
long axis vertical.
This option allows printing in landscape mode
(with the long axis horizontal).
Note that specifying an angle other than 0 or 90 will almost
certainly cause part of the text to fall outside the imageable region,
which serves you right for trying to be silly.
.TP
.B \-s[size]
Set the font size to the value given (in points) (72 points = 1 inch).
If a size is omitted, 12 is assumed.
The default point size without using this option is 10.
Specifying point sizes greater than 200 is probably silly and
certainly wastes toner.
.TP
.B \-t[tabsize]
Set the tab size to the value given (in characters).
If a value is omitted, 4 is assumed (the default is 8).
This option allows printing of program listings etc., to fit across
the page.
.TP
.B \-p[pitch]
Set the line spacing of printed text to this value.
Giving a value here will cause the line spacing to be set to that
value, in points (72 points = 1 inch).
If this argument is given without a value, double spacing is selected.
The default spacing is 0.
.TP
.B \-f[fontname]
Set the font used to the name given.
The default font is `Courier'.
If this argument is given without a fontname, `Times-Roman' is used.
The list of available fonts (for the Apple Laser-Writer) is: `Times-Roman'
; `Times-Italic'
; `Times-Bold'; `Times-BoldItalic'; `Courier'; `Courier-Oblique'
; `Courier-Bold'; `Courier-BoldOblique'; `Helvetica'; `Helvetica-Bold'
; `Helvetica-Oblique'; `Helvetica-BoldOblique'.
Note that only the Courier family is a fixed-width font; all the others
are variable width, and so program listings or columns of data will
not line up.
.TP
.B \-h[space]
Increase the horizontal spacing of characters by the given fraction of
the current font size.
For example, using `-h0.25' with a font size of 12 points in effect,
would cause an increase of horizontal spacing by 3 points.
By default, the characters are placed next to each other, using the
natural width of the characters.
Negative values (eg. -h-0.1) cause horizontal spacing to be decreased.
.TP
.B \-a[aspect-ratio]
Set the aspect ratio (height:width) of each character to the given value
(default 1).
.TP
.B \-S
Use manual feed instead of feeding from the paper tray.
.TP
.B \-L
Print using legal page type - 17.8 by 31.8 cm (7 by 12.5 inches) imageable
region, centred
on a 21.6 by 35.6 cm (8.5 by 14 inch) page.
The default (letter) paper type uses a 20.3 by 26.7 cm (8 by 10.5 inch)
imageable region, centred on a 21.6 by 27.9 cm (8.5 by 11 inch) page.
.SH SEE ALSO
ditroff(1)
.SH AUTHOR
Stephen Frede, UNSW, Australia
//E*O*F man/lpscript.1//

echo x - src/Makefile
cat > "src/Makefile" << '//E*O*F src/Makefile//'
CD=builtin cd
all: tpscript.d others
MFLAGS=SYS=$(SYS) VERBOSE=$(VERBOSE)

tpscript.d:
	$(CD) tpscript; $(MAKE) $(MFLAGS)

others:
	$(CD) opscript; $(MAKE) $(MFLAGS)
//E*O*F src/Makefile//

echo x - src/troff.sh
cat > "src/troff.sh" << '//E*O*F src/troff.sh//'
# troff shell script - invoke ditroff with appropriate args
#	- Stephen Frede
# The default device
dev=-Talw
# default postprocessor
post=tpscript
# ditroff arguments
ditargs=
# postprocessor arguments
postargs=
for i
do
	case $i in
	-Talw)	dev=-Talw
		post=tpscript
		;;
	-Toldalw)
		dev=-Toldalw
		post=oldtpscript
		;;
	-Ttek)	dev=-Talw	# use alw font tables
		post=tc
		;;
	-Tuqalw)
		dev=-Talw
		post=tpscript
		echo "-Tuqalw has been re-named -Talw (new default) (warning)" 1>&2
		;;
	-Thpgl)	dev=-Talw	# use alw font tables for now
		post=hpgl
		echo "hpgl back end not finished yet" 1>&2
		exit 1
		;;
	-T*)	echo invalid device $i;  exit 1 ;;
	-c*)	# -cxxx doesn't work; translate to -mxxx
		ditargs="$ditargs "-m`expr "$i" : "-.\(.*\)"` ;;
	-a)	# ascii representation - no postprocessor
		ditargs="$ditargs -a"
		post=""
		;;
	-R*)	# rotate
		if [ "$dev" != "-Talw" ]
		then
			echo "-R option only applies to device 'alw'" 1>&2
			exit 1
		fi
		postargs="$postargs "-r`expr "$i" : "-.\(.*\)"`
		;;
	-[sS])	# single page at a time - manual feed on ALW
		if [ "$dev" = "-Talw" ]
		then
			postargs="$postargs -S"
		else
			ditargs="$ditargs $i"
		fi
		;;
	*)	ditargs="$ditargs "$i	;;
	esac
done

if [ "$post" = "" ]
then
	/bin/ditroff $dev $ditargs
else
	/bin/ditroff $dev $ditargs | /usr/lib/troff/$post $postargs
fi
//E*O*F src/troff.sh//

echo x - src/tpscript/Makefile
cat > "src/tpscript/Makefile" << '//E*O*F src/tpscript/Makefile//'
# INSTALL=cp
INSTALL=:
I=..
ROOT=
INSDIR=/usr/bin
#	-DUQMINMET for hashed character name lookup
SYS=SYSV
VERBOSE=1	# 1 to turn on stuff; 0 to turn off
LOCALSYS=	# for various local mods
CFLAGS= -O
LDFLAGS= -n
DFLAGS= -DUQMINMET -D$(SYS) -DALW -DVERBOSE=$(VERBOSE) -D$(LOCALSYS)
CFILES=tpscript.c pcom.c stringdefs.c spline.c sfont2.c hash.c
OFILES=tpscript.o pcom.o stringdefs.o spline.o sfont2.o hash.o

.c.o:
	$(CC) $(CFLAGS) $(DFLAGS) -c $<

all tpscript:	$(OFILES)
	$(CC) $(LDFLAGS) -o tpscript $(OFILES)

install:	tpscript
	$(INSTALL) tpscript $(ROOT)$(INSDIR)/dalw
	chown bin $(ROOT)$(INSDIR)/dalw
	chgrp bin $(ROOT)$(INSDIR)/dalw
	chmod 711 $(ROOT)$(INSDIR)/dalw

lint:	tpscript.lint

tpscript.lint:	 $(CFILES)
	lint -D$(SYS) $(CFILES) > tpscript.lint

clean:
	rm -f *.o tpscript.lint

clobber:	clean
	rm tpscript stringdefs.h sfont2defs.H

stringdefs.h:	stringdefs.H
	sed -f gendefs.sed stringdefs.H >stringdefs.h

sfont2defs.h:	sfont2defs.H
	sed -f gendefs.sed sfont2defs.H >sfont2defs.h

hash.o:		hash.h tpscript.h
pcom.o:		pscript.h
sfont2.o:	sfont2defs.h tpscript.h
spline.o:	tpscript.h
stringdefs.o:	hash.h stringdefs.h
tpscript.o:	tpscript.h dev.h pscript.h
//E*O*F src/tpscript/Makefile//

echo x - src/tpscript/dev.h
cat > "src/tpscript/dev.h" << '//E*O*F src/tpscript/dev.h//'
/*      @(#)dev.h	1.1     */
/*
	dev.h: characteristics of a typesetter
*/

struct dev {
	short	filesize;	/* number of bytes in file, */
				/* excluding dev part */
	short	res;		/* basic resolution in goobies/inch */
	short	hor;		/* goobies horizontally */
	short	vert;
	short	unitwidth;	/* size at which widths are given, in effect */
	short	nfonts;		/* number of fonts physically available */
	short	nsizes;		/* number of sizes it has */
	short	sizescale;	/* scaling for fractional point sizes */
	short	paperwidth;	/* max line length in units */
	short	paperlength;	/* max paper length in units */
	short	nchtab;		/* number of funny names in chtab */
	short	lchname;	/* length of chname table */
	short	spare1;		/* in case of expansion */
	short	spare2;
};

struct font {		/* characteristics of a font */
	char	nwfont;		/* number of width entries for this font */
	char	specfont;	/* 1 == special font */
	char	ligfont;	/* 1 == ligatures exist on this font */
	char	spare1;		/* unused for now */
	char	namefont[10];	/* name of this font (e.g., "R" */
	char	intname[10];	/* internal name (=number) on device, in ascii */
};

/* ligatures, ORed into ligfont */

#define	LFF	01
#define	LFI	02
#define	LFL	04
#define	LFFI	010
#define	LFFL	020
//E*O*F src/tpscript/dev.h//

echo x - src/tpscript/gendefs.sed
cat > "src/tpscript/gendefs.sed" << '//E*O*F src/tpscript/gendefs.sed//'
/^#/		d
/^$/		d
/^[ 	]/	d
/^[^ 	]/	{
		s/{//
		s/#.*//
		t loop
		:loop
			N
			s/\n}$/ /
			t done
			s/#.*//
			t loop
			b loop
		:done
		s/[ 	][ 	]*/ /g
		s/\n/ /g
		s/ /	"/
		s/^/#define	DEF_/
		s/ *$/"/
		}
//E*O*F src/tpscript/gendefs.sed//

echo x - src/tpscript/hash.h
cat > "src/tpscript/hash.h" << '//E*O*F src/tpscript/hash.h//'

struct	hash_element {
	struct	hash_element	*hash_next;	/* pointer in linked list */
	struct	special_name	*hash_special;	/* if needs special treatment */
	short			hash_index;	/* index into chartab */
};

	/*
	 * special names need a postscript subroutine to print them as
	 * troff expects - the first request to print \(xx will generate
	 * the definition of a subroutine named Cxx and the character
	 * will be printed by invoking Cxx.
	 */
struct	special_name {
	char	*troff_name,	/* the name by which troff knows the char */
		*definition,	/* the definition string in postscript */
		sn_flags;	/* flag for various values defined below */
};

#define	SN_DEFINED	01
#define	SN_FRACTION	02	/* use special set-up common to all fractions */
#define	SN_BRACKET	04	/* use special set-up common to brackets */
#define	SN_BRK_ROUNDING	010	/* correct for rounding errors in width tables */

		/*
		 * if one of these is defined then there is some common
		 * procedure to define
		 * only one can be defined for any one name
		 */
#define	SN_ANY_MULTIPLE	(SN_FRACTION | SN_BRACKET | SN_BRK_ROUNDING )


typedef	struct	hash_element	HASH_ELEMENT;
typedef	struct	special_name	SPECIAL_NAME;

extern	SPECIAL_NAME	specnames[],
			multdefs[];

#define	HASH_SIZE	37

#define	NOHASH		(HASH_ELEMENT *)0
#define	NOSPECIAL	(SPECIAL_NAME *)0
//E*O*F src/tpscript/hash.h//

echo x - src/tpscript/pscript.h
cat > "src/tpscript/pscript.h" << '//E*O*F src/tpscript/pscript.h//'
/*
 *	pscript.h
 *	Some common definitions for programs that produce postscript
 */

#ifndef	PSCRIPT_DEFINED
#define	PSCRIPT_DEFINED	1

#ifndef	VERBOSE
#if	lint
#define	VERBOSE	1	/* if linting, check all the code */
#else	lint
#define	VERBOSE	0
#endif	lint
#endif	VERBOSE

#if	UNSW
#undef	AUSAM
#define	AUSAM	1
#endif	UNSW

#ifdef	AUSAM
#undef	AUSAM
#define	AUSAM	1
#else
#define	AUSAM	0
#endif	AUSAM

#ifdef	BSD
#undef	BSD
#define	BSD	1
#define	index	strchr
#define	rindex	strrchr
#include	<strings.h>	/* declarations for string functions */
#else
#define	BSD	0
#include	<string.h>	/* declarations for string functions */
#endif	BSD

#ifdef	SYSV
#undef	SYSV
#define	SYSV	1
#else
#define	SYSV	0
#endif	SYSV

#ifdef	V7
#undef	V7
#define	V7	1
#else
#define	V7	0
#endif	V7

#if	AUSAM + BSD + SYSV + V7 != 1
#include	"Must define 1 only of AUSAM, BSD, SYSV, V7"
#endif

#include	<stdio.h>

/* LaserWriter page types */
#define	PT_DEFAULT	0
#define	PT_LETTER	1
#define	PT_LEGAL	2
#define	PT_NOTE		3
#ifdef	ALW
#define	PT_A4		4	/* currently only on Apple LaserWriter */
#endif	ALW

/* Postscript defaults */
#define	PD_PAGETYPE	PT_LETTER	/* page size is "letter" */
#define	PD_ROTATION	0		/* page is portrait mode */
#define	PD_PFREQUENCY	60		/* pixel frequency (pixels/inch) */
#define	PD_PROTATION	45		/* pixel grid rotation (degrees) */

#define	ALW_RES		300	/* LaserWriter resolution is 300 dots/inch */

#define	PU_INCH		72	/* postscript units / inch */
#define	PU_CM		28.3465	/* postscript units / cm */

#define	TRUE		(bool)1
#define	FALSE		(bool)0

typedef int	bool;

extern FILE *	postr;		/* output stream */

void	perror(),
	exit();

#endif	PSCRIPT_DEFINED
//E*O*F src/tpscript/pscript.h//

echo ln src/tpscript/pscript.h src/opscript/pscript.h
ln src/tpscript/pscript.h src/opscript/pscript.h

echo x - src/tpscript/sfont2defs.H
cat > "src/tpscript/sfont2defs.H" << '//E*O*F src/tpscript/sfont2defs.H//'
#	sfont2defs.H
#	source file for definitions of special characters in the second
#	locally-defined special font
#	this file is processed by sed to produce sfont2defs.h
#	syntax is:
#	troff-name <white-space> { definition including optional comments
#		terminated by "}" on a line of its own
#		white space is minimised on output
#	anything following `#' is ignored
#	a line commencing with `#' is deleted
#	as are blank lines
#	note `\` should be escaped as "\\"


#	The bracket end pieces just load the stack with values which are then
#	used by the common procedure C.brk.end which does a
#	moveto rlineto rcurveto (then back to the start and across by 60)
#		rlineto rcurveto fill
#	This is only done to save the output file size and to make it
#	more confusing to interpret what is going on.
#	Remember the stack is loaded last in first out

lt	{
	0 150	   50 210	140 250		# inside rcurve to just below tip
	0 730
	0 150	   50 250	200 250		# outside rcurve to tip
	0 750				# rline up
	220 -250			# starting point
	C.brk.end
}

lb	{
	0 -150	   50 -210	140 -250	# inside rcurve to just below tip
	0 -730
	0 -150	   50 -250	200 -250	# outside rcurve to tip
	0 -750				# rline up
	220 750			# starting point
	C.brk.end
}

lk	{
	1 setlinewidth
	220 -250 moveto
	0 400 rlineto
	0 50    -50 100     -100 100  rcurveto
	50 0     100 50       100 100  rcurveto
	0 400 rlineto
	60 0 rlineto
	0 -400 rlineto
	0 -50    -50 -100     -100 -100  rcurveto
	50 0     100 -50       100 -100  rcurveto
	0 -400 rlineto
	closepath fill
}

rt	{
	0 150	   -50 250	-200 250	# outside rcurve to tip
	0 750				# rline up
	0 150	   -50 210	-140 250	# inside rcurve to just below tip
	0 730
	220 -250			# starting point
	C.brk.end
}

rb	{
	0 -150	   -50 -250	-200 -250	# outside rcurve to tip
	0 -750				# rline up
	0 -150	   -50 -210	-140 -250	# inside rcurve to just below tip
	0 -730
	220 750			# starting point
	C.brk.end
}

rk	{
	1 setlinewidth
	220 -250 moveto
	0 400 rlineto
	0 50    50 100       100 100  rcurveto
	-50 0     -100 50     -100 100  rcurveto
	0 400 rlineto
	60 0 rlineto
	0 -400 rlineto
	0 -50    50 -100       100 -100  rcurveto
	-50 0     -100 -50     -100 -100  rcurveto
	0 -400 rlineto
	fill
}


#		the floor and ceiling bracket parts are made up with two
#		procedures defined within the context of the font:
#			C.bv	which draws the bold vertical
#			C.barc	which adds the horizontal piece to the ceiling;
#				the X coord on the stack should be set to the
#				left edge of where the bar is to be put
#			C.barf	likewise for floor

lc	{
	C.bv				# draw the bv part
	280 				# move to bottom right edge of vert bar
	C.barc				# and draw in horizontal bar
}

lf	{
	C.bv 280 C.barf
}

rc	{
	C.bv 40 C.barc
}

rf	{
	C.bv 40 C.barf
}

br	{
	40 C.setl
	0 -250 moveto
	0 1000 rlineto
	stroke
}

rn	{
	40 C.setl
	0 895 moveto
	500 0 rlineto
	stroke
}

ci	{
	40 C.setl
	500 250 				# centre
	400					# radius
	0 360 arc				# draw circle
	stroke
}

sp_6	{		# 1/6 em narrow space
			# do nothing, the width is all that is needed
}

sp_12	{		# 1/12 em narrow space
			# null op
}

r1	{		# reversible chemical reaction
	40 C.setl
	0 setlinejoin
	700 180 moveto -650 currentlinewidth add 0 rlineto 200 -200 rlineto
	50 360 moveto 650 currentlinewidth sub 0 rlineto -200 200 rlineto
	stroke
}

r2	{		# reversible reaction with full arrowheads
	40 C.setl
	2 setlinejoin
	217 18 moveto
					# left arrowhead
	-150 150 rlineto 150 150 rlineto -150 -150 rlineto
	633 0 rlineto
	50 360 moveto
	633 0 rlineto
	-150 150 rlineto 150 -150 rlineto -150 -150 rlineto
	stroke
}
//E*O*F src/tpscript/sfont2defs.H//

echo x - src/tpscript/sfont2defs.h
cat > "src/tpscript/sfont2defs.h" << '//E*O*F src/tpscript/sfont2defs.h//'
#define	DEF_lt	"  0 150 50 210 140 250   0 730  0 150 50 250 200 250   0 750   220 -250   C.brk.end"
#define	DEF_lb	"  0 -150 50 -210 140 -250   0 -730  0 -150 50 -250 200 -250   0 -750   220 750   C.brk.end"
#define	DEF_lk	"  1 setlinewidth  220 -250 moveto  0 400 rlineto  0 50 -50 100 -100 100 rcurveto  50 0 100 50 100 100 rcurveto  0 400 rlineto  60 0 rlineto  0 -400 rlineto  0 -50 -50 -100 -100 -100 rcurveto  50 0 100 -50 100 -100 rcurveto  0 -400 rlineto  closepath fill"
#define	DEF_rt	"  0 150 -50 250 -200 250   0 750   0 150 -50 210 -140 250   0 730  220 -250   C.brk.end"
#define	DEF_rb	"  0 -150 -50 -250 -200 -250   0 -750   0 -150 -50 -210 -140 -250   0 -730  220 750   C.brk.end"
#define	DEF_rk	"  1 setlinewidth  220 -250 moveto  0 400 rlineto  0 50 50 100 100 100 rcurveto  -50 0 -100 50 -100 100 rcurveto  0 400 rlineto  60 0 rlineto  0 -400 rlineto  0 -50 50 -100 100 -100 rcurveto  -50 0 -100 -50 -100 -100 rcurveto  0 -400 rlineto  fill"
#define	DEF_lc	"  C.bv   280   C.barc"
#define	DEF_lf	"  C.bv 280 C.barf"
#define	DEF_rc	"  C.bv 40 C.barc"
#define	DEF_rf	"  C.bv 40 C.barf"
#define	DEF_br	"  40 C.setl  0 -250 moveto  0 1000 rlineto  stroke"
#define	DEF_rn	"  40 C.setl  0 895 moveto  500 0 rlineto  stroke"
#define	DEF_ci	"  40 C.setl  500 250   400   0 360 arc   stroke"
#define	DEF_sp_6	""
#define	DEF_sp_12	""
#define	DEF_r1	"  40 C.setl  0 setlinejoin  700 180 moveto -650 currentlinewidth add 0 rlineto 200 -200 rlineto  50 360 moveto 650 currentlinewidth sub 0 rlineto -200 200 rlineto  stroke"
#define	DEF_r2	"  40 C.setl  2 setlinejoin  217 18 moveto    -150 150 rlineto 150 150 rlineto -150 -150 rlineto  633 0 rlineto  50 360 moveto  633 0 rlineto  -150 150 rlineto 150 -150 rlineto -150 -150 rlineto  stroke"
//E*O*F src/tpscript/sfont2defs.h//

echo x - src/tpscript/stringdefs.H
cat > "src/tpscript/stringdefs.H" << '//E*O*F src/tpscript/stringdefs.H//'
#	source file for definitions for special characters in postscript
#	this file is processed by sed to produce stringdefs.h
#	syntax is:
#	troff-name <white-space> { definition including optional comments
#		terminated by "}" on a line of its own
#		white space is minimised on output
#	anything following `#' is ignored
#	a line commencing with `#' is deleted
#	as are blank lines
#	note `\` should be escaped as "\\"


12	{
	(1) (2) Cfract
}

14	{
	(1) (4) Cfract
}

34	{
	(3) (4) Cfract
}

13	{
	(1) (3) Cfract
}

18	{
	(1) (8) Cfract
}

23	{
	(2) (3) Cfract
}

38	{
	(3) (8) Cfract
}

58	{
	(5) (8) Cfract
}

78	{
	(7) (8) Cfract
}

ru	{
	0 ysiz pt 5 div 2 copy rmoveto		# up dist from bottom to baseline
	(_) show
	neg rmoveto	# back down
}


sr	{		# square root needs to be shoved to the right a touch
	currentfont			# save for later restoring
	/dx xsiz pt 0.05 mul def
	dx 0 rmoveto			# jump right by a bit
	f.S [ xsiz pt 0 0 ysiz pt 0 0 ]makefont setfont
	(\\326)s
	dx neg 0 rmoveto		# back again
	setfont				# restore prev font
}
	

sq	{		# draw a square box
	currentlinewidth currentpoint currentpoint
	ysiz pt 20.8 div dup dtransform round idtransform setlinewidth pop
	newpath moveto
	/dy ysiz pt 0.8 mul def		# side is 0.8em
	/dx xsiz pt 0.8 mul def		# side is 0.8em
	dx 8 div dy .1875 mul neg rmoveto	# move to starting point
	0 dy rlineto dx 0 rlineto
	0 dy neg rlineto
	closepath
		# the following search will put a different number of elements
		# on the stack depending whether true or false; thus we mark
		# here to clean up later
	mark
	currentfont /FontName get	# get the font name
	40 string cvs			# turn into a string
	(Bold) search			# is it bold type?
		{fill}			# if so then block in
		{stroke}		# otherwise outline
	ifelse
	cleartomark			# clean up stack
	moveto				# back to start
	xsiz pt 0 rmoveto			# to the end of the char
	setlinewidth
}

ff	{
	(f) show xsiz pt 20 div neg 0 rmoveto (f) s
}

Fi	{
	(f) show xsiz pt 20 div neg 0 rmoveto (\\256) s
}

Fl	{
	(f) show xsiz pt 20 div neg 0 rmoveto (\\257) s
}


#		fraction construction common procedure
#		this won't work properly yet for fonts slanted with \S
fract	{
	/fbot exch def			# arg 1 is bottom character
	/ftop exch def			# arg 2 is top character
	currentfont currentpoint	# for later restoration
	/f0 ysiz pt 2 div def		# little chars half size
	(0) stringwidth pop 2 div 0 rmoveto	# charwidth at half size
	(\\244)show			# draw the slanting line
	currentpoint 4 2 roll moveto	# save current and back to beginning
	0 f0 0.75 mul rmoveto		# up a bit
	fonttype [ xsiz pt 2 div 0 0 f0 0 0 ]makefont setfont
					# set a smaller font size
	ftop show
	moveto 				# back to the end of the /
	fbot show
	setfont				# restore font
}

//E*O*F src/tpscript/stringdefs.H//

echo x - src/tpscript/stringdefs.h
cat > "src/tpscript/stringdefs.h" << '//E*O*F src/tpscript/stringdefs.h//'
#define	DEF_12	"  (1) (2) Cfract"
#define	DEF_14	"  (1) (4) Cfract"
#define	DEF_34	"  (3) (4) Cfract"
#define	DEF_13	"  (1) (3) Cfract"
#define	DEF_18	"  (1) (8) Cfract"
#define	DEF_23	"  (2) (3) Cfract"
#define	DEF_38	"  (3) (8) Cfract"
#define	DEF_58	"  (5) (8) Cfract"
#define	DEF_78	"  (7) (8) Cfract"
#define	DEF_ru	"  0 ysiz pt 5 div 2 copy rmoveto   (_) show  neg rmoveto"
#define	DEF_sr	"  currentfont   /dx xsiz pt 0.05 mul def  dx 0 rmoveto   f.S [ xsiz pt 0 0 ysiz pt 0 0 ]makefont setfont  (\\326)s  dx neg 0 rmoveto   setfont"
#define	DEF_sq	"  currentlinewidth currentpoint currentpoint  ysiz pt 20.8 div dup dtransform round idtransform setlinewidth pop  newpath moveto  /dy ysiz pt 0.8 mul def   /dx xsiz pt 0.8 mul def   dx 8 div dy .1875 mul neg rmoveto   0 dy rlineto dx 0 rlineto  0 dy neg rlineto  closepath        mark  currentfont /FontName get   40 string cvs   (Bold) search   {fill}   {stroke}   ifelse  cleartomark   moveto   xsiz pt 0 rmoveto   setlinewidth"
#define	DEF_ff	"  (f) show xsiz pt 20 div neg 0 rmoveto (f) s"
#define	DEF_Fi	"  (f) show xsiz pt 20 div neg 0 rmoveto (\\256) s"
#define	DEF_Fl	"  (f) show xsiz pt 20 div neg 0 rmoveto (\\257) s"
#define	DEF_fract	"  /fbot exch def   /ftop exch def   currentfont currentpoint   /f0 ysiz pt 2 div def   (0) stringwidth pop 2 div 0 rmoveto   (\\244)show   currentpoint 4 2 roll moveto   0 f0 0.75 mul rmoveto   fonttype [ xsiz pt 2 div 0 0 f0 0 0 ]makefont setfont    ftop show  moveto   fbot show  setfont"
//E*O*F src/tpscript/stringdefs.h//

echo x - src/tpscript/tpscript.h
cat > "src/tpscript/tpscript.h" << '//E*O*F src/tpscript/tpscript.h//'
/*
 *	tpscript.h
 *	header definitions for tpscript.c:
 *		Troff post-processor for postscript devices
 */

#include	<stdio.h>
#include	"dev.h"
#include	"pscript.h"

#define	ERR_WARN	1	/* an input error - continue processing */
#define	ERR_FATAL	2	/* an input error - abort processing */
#define	ERR_SNARK	3	/* a program error - abort processing */
#define	UNDEFINED	-1

#define	BMASK		0xFF	/* low order byte */

#define	NASCII		128	/* no. ascii characters */
#define	NUNPRINT	32	/* no. unprintable characters */
#define	NASCPRINT	(NASCII-NUNPRINT)	/* no. printable ascii chars */
#define	MAXCHARS	255	/* max no. character codes */

#define	DEF_FONT	1	/* default initial font */
#define DEF_SIZE	10	/* default initial point size */
#define	DEF_DEV		"alw"	/* default device - apple laser-writer */

extern int	errno;
extern char	*sys_errlist[];

extern	FILE	*Debug ;
extern	char	*ifile;		/* current input file name */
extern	int	lineno,			/* line no. in current input file */
	npages;			/* no. pages printed so far */
extern	char	device[100],
	errbuf[100];		/* tmp buffer for error messages */
extern	int
	hpos,		/* current horizontal position */
	vpos;		/* current vertical position (rel. TOP pg.) */
extern	int	
	res,		/* resolution in THINGS/inch */
	hor_res,		/* min horizontal movement (in THINGS) */
	vert_res,		/* min vertical movement (in THINGS) */
	respunits;
float 	rotation;		/* page orientation (degrees) */
extern	int	currtfont,	/* current font number selected by troff */
	papertype; 		/* paper type (different imageable regions) */

/* font parameters */
struct	fontparam {
	int	fp_size;	/* character point size */
	float	fp_height,	/* character height (points) */
		fp_slant;	/* character slant (degrees) */
	struct fontdesc *
		fp_font;	/* font style */
};
extern	struct	fontparam
	tfp,		/* current troff font parameters */
	pfp;		/* current postscript font parameters */

#define	NOFONTDESC	((struct fontdesc *)NULL )

/* table of font descriptions */
struct fontdesc {
	char	*f_intname;	/* postscript name */
	char	*f_extname;	/* troff name */
	int	f_nent;		/* no. entries for this font */
	char	*f_widthtab;	/* character width tables */
	char	*f_codetab;	/* code table for this font */
	char	*f_fitab;	/* font index for this font */
	bool	f_mounted;	/* whether font is mounted or not */
};

extern struct fontdesc	*fontd,
			*spcfnt1,	/* special font */
			*spcfnt2;	/* special font 2 */

/* font mount table - array of pointers to font descriptions */
extern	struct fontdesc	**fontmount;

/* mapping between troff font names and builtin font names
 * This should go in the internal name part of the font description
 * itself, but there is only 10 bytes allocated (see dev.h).
 */
struct fontmap {
	char	*fm_extname;	/* Troff font name */
	char	*fm_intname;	/* Postscript font name */
};
extern	struct	fontmap fontmap[];

#define	NFONT	(sizeof(fontmap)/sizeof(fontmap[0]))

extern	struct dev	dev;

extern	short	*chartab;	/* char's index in charname array */
extern	char	*charname;	/* special character names */
extern	int	ncharname;		/* no. special character names */
extern	int	nfonts;		/* no. of fonts mounted */
extern	int	nfontmount;		/* no. of font mount positions */


#define	GETWIDTH(fdp, index)	\
  ((tfp.fp_size * ((fdp)->f_widthtab[ (index) ] & BMASK) + (respunits>>1)) / respunits)

	/*
	 * this is the width that the printer will have moved following
	 * the last printed character, if troff then says to move a
	 * different amount we will shift the difference
	 */
extern	int	width_pending;

extern	bool	word_started;	/* we are in middle of word string */

#define	CLOSEWORD()	{if ( word_started == TRUE ) {	\
				fputs( ")s", postr );	\
				word_started = FALSE;	\
				}			\
			}


extern	int		strcmp();
extern	char		*emalloc();
extern	struct fontdesc *findfont();
extern	struct fontmap	*getfmap();

//E*O*F src/tpscript/tpscript.h//

echo Possible errors detected by \'wc\' [hopefully none]:
temp=/tmp/shar$$
trap "rm -f $temp; exit" 0 1 2 3 15
cat > $temp <<\!!!
    114    826   5046 READ_ME
     13     62    404 Makefile
    114    720   3990 ipscript.1
     96    632   3778 lpscript.1
      9     17    166 Makefile
     66    200   1326 troff.sh
     50    132   1172 Makefile
     39    219   1242 dev.h
     21     40    213 gendefs.sed
     42    202   1323 hash.h
     90    268   1661 pscript.h
    165    685   3557 sfont2defs.H
     17    327   1751 sfont2defs.h
    124    540   2717 stringdefs.H
     16    264   1494 stringdefs.h
    124    609   3837 tpscript.h
   1100   5743  33677 total
!!!
wc  READ_ME Makefile man/ipscript.1 man/lpscript.1 src/Makefile src/troff.sh src/tpscript/Makefile src/tpscript/dev.h src/tpscript/gendefs.sed src/tpscript/hash.h src/tpscript/pscript.h src/tpscript/sfont2defs.H src/tpscript/sfont2defs.h src/tpscript/stringdefs.H src/tpscript/stringdefs.h src/tpscript/tpscript.h | sed 's=[^ ]*/==' | diff -b $temp -
exit 0