[comp.lang.postscript] PostScript Fonts and Images on 1 Page

dean@devvax.JPL.NASA.GOV (Dean Okamura) (12/11/87)

I'm trying to find a way to print a page on a LaserWriter which
includes text and images.  I thought that I could do the following:
    1. Write an NROFF source.
    2. Run NROFF.
    3. Run ENSCRIPT to produce a PostScript file.
    4. Edit the PostScript file and insert a small image.
    5. Print the editted file.

I have not been able to print text and images on the same page.

Please mail an example of how I should be doing things.

Thanks in advance!

--- Dean

dean@devvax.JPL.NASA.GOV (Dean Okamura) (04/13/88)

Four months have passed since I made the following plea for help in
mixing TROFF and PostScript figures:

> I'm trying to find a way to print a page on a LaserWriter which
> includes text and images.  I thought that I could do the following:
>     1. Write an NROFF source.
>     2. Run NROFF.
>     3. Run ENSCRIPT to produce a PostScript file.
>     4. Edit the PostScript file and insert a small image.
>     5. Print the edited file.
>
> I have not been able to print text and images on the same page.

I received some suggestions to use Trevor Darrell's PSFIG macro package
which is a DITROFF or TeX pre-processor.  I never did try PSFIG for
various reasons.  First of all, the system I work on did not have
DITROFF or TeX.  If I did have TeX, we do not have a PSFIG-compatible
TeX output to PostScript filter.  Finally, we do not have sources for
psdit, a DITROFF output to PostScript filter, which must be patched to
use PSFIG with DITROFF.

So I went back to the original plan which was similar to formatting a
document and using a publishing system program to insert the PostScript
figures.  Figure positioning is done after the document has PostScript
coordinates.  Using a programming analogy, PostScript files are library
modules linked with PostScript compiled document source files.  A major
benefit is that you don't have to find or write a pre-processor for
each document formatter that exists.  The major problem is finding a
way to post-process the PostScript.

It turns out that the PostScript related problems were answered by
Mike Byron, Adobe Systems Incorporated:

> The problem is probably that enscript has fooled with the
> coordinate space.  It makes things 1/20th size, for instance.
>
> Try looking at the enscript prolog, and undoing things like the
> ".05 dup scale" around your drawing.  You will also need to do
> a save/restore around your PostScript language stuff, so that
> whatever you do will be undone.
>
> An alternate method for doing the above is to use the PostScript
> matrix operators to stuff away the current transformation
> matrix at the beginning of the job, then setmatrix to it just
> before your PostScript...
>
> Good luck!

The remaining PostScript problems were cleared up when I made the
images conform to the Aldus/Altsys/Adobe Encapsulated PostScript file
(EPSF) format.

After many blank sheets of paper, and a lot of help from Mike Byron, I
was able to print text and images on the same page.  However, the
placement of the figure was very strange.  It turned out that there is
a bug in the page reversal software we use.  Changing the initial
comment to "%!" turns off the page reversal and things print fine.

I refined the technique with TROFF instead of NROFF and incorporated
a symbolic reference assembler.  I call the package, TxTools.  A
small document and assorted files are included at the end of this
news posting.

I will be leaving JPL at the end of the week so e-mail accordingly.

-- 
Dean Okamura
Telos Consulting Services, 1370 N. Brea, #150, Fullerton, CA 92635.

#!/bin/sh
# This is a shell archive.
echo 'If the files were unpacked, "End of SHAR" will be echoed'
echo Extracting Telos.icon
sed >Telos.icon <<'!Hello!Kitty!' -e 's/X//'
X/* Format_version=1, Width=64, Height=64, Depth=1, Valid_bits_per_item=16
X */
X	0xFFFF,0x7F7E,0x07F8,0x07FF,0x8000,0x4142,0x180C,0x0801,
X	0x8000,0x8142,0x2002,0x1001,0x8001,0x0142,0x4001,0x2001,
X	0x8002,0x0142,0x8000,0xC001,0xFC34,0x0F43,0x03E0,0x43FF,
X	0x0424,0x1043,0x0410,0x4200,0x0428,0x2042,0x0808,0x4200,
X	0x0428,0x7F42,0x1004,0x41F8,0x0428,0x0142,0x1004,0x6004,
X	0x0428,0x0142,0x1004,0x7002,0x0428,0x0142,0x1004,0x2801,
X	0x0428,0x7F42,0x1004,0x67C1,0x0428,0x2042,0x0808,0x4061,
X	0x0424,0x1043,0x0410,0x4021,0x0424,0x0F43,0xFFE0,0x7FE1,
X	0x0422,0x0140,0x0100,0xC001,0x0421,0x0140,0x0100,0x8001,
X	0x0420,0x8140,0x0101,0x8002,0x0420,0x6140,0x0106,0x8004,
X	0x07E0,0x1F7F,0xFFFC,0xFFF8,0x8000,0x0000,0x0000,0x0001,
X	0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001,
X	0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001,
X	0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001,
X	0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001,
X	0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001,
X	0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001,
X	0x80E0,0x0000,0x0000,0x0001,0x8090,0x0000,0x0000,0x0001,
X	0x8088,0xE1C5,0x8000,0x0001,0x8089,0x1226,0x4000,0x0001,
X	0x8089,0x1024,0x4000,0x0001,0x8089,0xF1E4,0x4000,0x0001,
X	0x8089,0x0224,0x4000,0x0001,0x8091,0x1224,0x4000,0x0001,
X	0x80E0,0xE1E4,0x4000,0x0001,0x8000,0x0000,0x0000,0x0001,
X	0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001,
X	0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001,
X	0x8071,0x0000,0x0000,0x0001,0x8089,0x0000,0x0000,0x0001,
X	0x8089,0x21C6,0x8896,0x1C01,0x8089,0x4225,0x4899,0x2201,
X	0x8089,0x8025,0x4890,0x0201,0x8089,0x81E5,0x4890,0x1E01,
X	0x8089,0x4225,0x4890,0x2201,0x8089,0x2225,0x4990,0x2201,
X	0x8071,0x11E5,0x4690,0x1E01,0x8000,0x0000,0x0000,0x0001,
X	0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001,
X	0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001,
X	0x8000,0x0000,0x0000,0x0001,0xFFFF,0xFFFF,0xFFFF,0xFFFF
!Hello!Kitty!
echo Extracting app.ms
sed >app.ms <<'!Hello!Kitty!' -e 's/X//'
X.bp
X.SH
XAppendix A
X.LP
XThe following files are included as sources of implementation
Xspecific details.
XOne of the files,
X.I
Xlocate.ps,
X.R
Xoriginally appeared in the
X.I
XAdobe Illustrator User's Guide
X.R
X[_ADOB87_].
XThese files have been tested on Sun 3/X workstations running
X\*(TS software.
XPrinting the document with a Helvetica font is not necessary
Xbut was arbitrarily chosen as a suitable font.
X.sp 2
X.\"
X.SH
XLocate \*(PS Procedure
X.LP
X.B
XFile:
X.I
Xlocate.ps
X.R
X.\" save current font size
X.nr fS \n(.s
X.\" 9 point font
X.ps 9
X.nr PS 9
X.vs 10
X.nr VS 10
X.sp 1
X.ls 1
X.so locate.ms
X.sp 2
X.\" restore current font size
X.\" Assert: vertical space is font size + 2
X.ps \n(fS
X.nr PS \n(fS
X.vs \n(fS+2
X.nr VS \n(fS+2
X.\"
X.SH
XExample Make Source File
X.LP
X.B
XFile:
X.I
Xmakefile
X.R
X.\" save current font size
X.nr fS \n(.s
X.\" 9 point font
X.ps 9
X.nr PS 9
X.vs 10
X.nr VS 10
X.sp 1
X.ls 1
X.so makefile.ms
X.\" app.ms
!Hello!Kitty!
echo Extracting exsource
sed >exsource <<'!Hello!Kitty!' -e 's/X//'
X#!/bin/sh
X##	@(#)exsource.sh 1.00 DEO <04/12/88>
X# the type of extract determines header processing
Xcase $0 in
X*exsource) HEADER='
X/^(.\\"|#)ifdef Header/,/^(.\\"|#)endif Header/ { next }
X/^(.\\"|#)ifdef SFOC_CM_Header/,/^(.\\"|#)endif SFOC_CM_Header/ { next }
X' ;;
X*exprivate) HEADER='
X/^[.*/#][\\*/#][\\"*/#]* __PRIVATE__[\t ]*(\*\/)*$/ { next }
X/^[.*/#][\\*/#][\\"*/#]* __PUBLIC__[\t ]*(\*\/)*$/ { next }
X' ;;
X*exworld) HEADER='
X/^(.\\"|#)ifdef SFOC_CM_Header/,/^(.\\"|#)endif SFOC_CM_Header/ { next }
X' ;;
Xesac
X
Xawk '
X'"$HEADER"'
X# default :
X{ print $0 }
X' $*
X# exsource
!Hello!Kitty!
echo Extracting exsource.sh
sed >exsource.sh <<'!Hello!Kitty!' -e 's/X//'
X#!/bin/sh
X##	@(#)exsource.sh 1.00 DEO <04/12/88>
X#ifdef Header
X##
X## MANUAL
X##	EXSOURCE 1 "March 25, 1988"
X## NAME
X##	exsource, exworld -- extract source
X## SYNOPSIS
X##	exsource [ files ] ...
X##	exprivate [ files ] ...
X##	exworld [ files ] ...
X## DESCRIPTION
X##	_ exsource is used to extract source sections from _ files
X##	and write to the standard output.
X##
X##	_ exprivate is used to remove `__PRIVATE__' and `__PUBLIC__'
X##	lines from the documentation headers.  This allows private
X##	information to be used by tools such as EXMAN(1).
X##
X##	_ exworld is used to extract documentation headers and source
X##	sections from _ files and write to the standard output.
X##	The sections which are not exported to the world are generally
X##	configuration management and internal distribution only notes.
X## INPUTS
X##	_ files are ExTool-format text files.
X## OUTPUTS
X##	standard output.
X## RETURN VALUES
X##	[exit] see AWK manuals.
X## SEE ALSO
X##	exman(1).
X##
X#endif Header
X# the type of extract determines header processing
Xcase $0 in
X*exsource) HEADER='
X/^(.\\"|#)ifdef Header/,/^(.\\"|#)endif Header/ { next }
X/^(.\\"|#)ifdef SFOC_CM_Header/,/^(.\\"|#)endif SFOC_CM_Header/ { next }
X' ;;
X*exprivate) HEADER='
X/^[.*/#][\\*/#][\\"*/#]* __PRIVATE__[\t ]*(\*\/)*$/ { next }
X/^[.*/#][\\*/#][\\"*/#]* __PUBLIC__[\t ]*(\*\/)*$/ { next }
X' ;;
X*exworld) HEADER='
X/^(.\\"|#)ifdef SFOC_CM_Header/,/^(.\\"|#)endif SFOC_CM_Header/ { next }
X' ;;
Xesac
X
Xawk '
X'"$HEADER"'
X# default :
X{ print $0 }
X' $*
X# exsource
!Hello!Kitty!
echo Extracting locate.ps
sed >locate.ps <<'!Hello!Kitty!' -e 's/X//'
X%!PS-Adobe-2.0
X% "locate" expects to find eight numbers on the stack:
X% the first four numbers represent the bounding box of
X% the Illustration, as found in the %%BoundingBox
X% comment in the Illustrator file, followed by four
X% numbers representing the bounds of the rectangle on
X% the page which must contain the illustration:
X% [This procedure will use about 224 bytes of VM.  It
X% should be used within a save/restore construct].
X%
X% -- from Adobe Illustrator User's Manual, page 106.
X%
X% Adobe Illustrator is a trademark of Adobe Systems Incorporated.
X%
X/locate {% LLx LLy URx URy newLLx newLLy newURx newURy
X 8 dict begin
X  [/newURy /newURx /newLLy /newLLx /URy /URx /LLy /LLx]
X  { exch def } forall
X  newLLx newLLy translate % move origin to new location
X  newURx newLLx sub URx LLx sub div % X scale
X  newURy newLLy sub URy LLy sub div scale % Y scale
X  LLx neg LLy neg translate % compensate for LL offset
X end
X} bind def
!Hello!Kitty!
echo Extracting makefile
sed >makefile <<'!Hello!Kitty!' -e 's/X//'
X.SUFFIXES: .icon .ms .ps
X
XSHELL	= /bin/sh
XPAPER	= txtools.ms ref.ms app.ms
XTMPFILE	= tmp123
X
X# customized PostScript document
XFAMILY	= Helvetica
XFONTS	= ${PSFONTLIB}/${FAMILY}.head
XPSCAT	= pscat -F${PSFONTLIB}/${FAMILY}.ct -y -18
XPSFONTLIB = /usr/local/lib/lw/troff.font
X
X# Note: NROFF requires terminal type because of half-line movements
XNROFF	= nroff -Ttn300
X
X# Note: TROFF requires FONTS to run correctly
X# Example: @${TROFF} -ms ${FONTS} [ file ] ...
XTROFF	= troff -F${PSFONTLIB}/ftXX -t
X
X# source and support files
XSRCFILES = Telos.icon app.ms exsource exsource.sh locate.ps \
X	makefile psicon.sh ref.ms txcopy.sh txlink.c txtags.sh \
X	txtools.ms
XTARGETS	= psicon txcopy txlink txtags Telos.ps locate.ms makefile.ms
X
Xsystem:	setup paper
X
Xpaper:	${PAPER} ${TMPFILE}.ps
X	@txlink ${TMPFILE}.ps
X	@rm -f ${TMPFILE}.ps txlink.aux
X
X${TMPFILE}.ps: ${PAPER}
X	@# bug in psrev
X	@echo '%!' > ${TMPFILE}.ps
X	@txtags ${PAPER} | ${TROFF} -ms -i ${FONTS} | ${PSCAT} \
X		>> ${TMPFILE}.ps
X
Xproof:	${PAPER}
X	@txtags ${PAPER} | ${TROFF} -ms -i ${FONTS}
X	@rm -f txlink.aux
X
X# support file maintainence
X.c:
X	@${CC} ${CFLAGS} $< -o $@
X
X.icon.ps:
X	@psicon $< > $@
X
X.ps.ms:
X	@txcopy $< > $@
X
X.sh:
X	@exsource $< > $@
X	@chmod +x $@
X
Xmakefile.ms: makefile
X	@txcopy makefile > makefile.ms
X
Xsetup:	${TARGETS}
X
Xclean:
X	rm -f *.o ${TARGETS} ${TMPFILE}.ps txlink.aux
X
X# makefile
!Hello!Kitty!
echo Extracting psicon.sh
sed >psicon.sh <<'!Hello!Kitty!' -e 's/X//'
X#!/bin/sh
X##	@(#)psicon.sh 1.00 DEO <04/06/88>
X#ifdef Header
X##
X## MANUAL
X##	PSICON 1 "March 11, 1988"
X## NAME
X##	psicon -- iconedit to PostScript filter
X## SYNOPSIS
X##	psicon file
X## DESCRIPTION
X##	_ psicon translates iconedit _ file to Encapsulated PostScript
X##	File (EPSF) and writes to the standard output.
X## INPUTS
X##	_ file is a iconedit _ file.
X## OUTPUTS
X##	standard output.
X## RETURN VALUES
X##	[0] Successful.
X## NOTES
X##	The output from _ psicon can be printed on the LaserWriter
X##	by adding a line at the end of the file with the PostScript
X##	showpage operator.  A typical Unix command would be:
X##
X##	    (psicon file; echo "showpage") | lpr -Plw
X##
X##	PostScript is a trademark of Adobe Systems Incorporated.
X## SEE ALSO
X##	iconedit(1).
X##
X#endif Header
X# Assert: iconedit format
X# Format_version=1, Width=64, Height=64, Depth=1, Valid_bits_per_item=16
Xfor i in `grep 'Format_version' $1 | sed 's/,//g'`
Xdo
X	case $i in
X	Width=*) Width=`echo "$i" | sed 's/Width=//'` ;;
X	Height=*) Height=`echo "$i" | sed 's/Height=//'` ;;
X	esac
Xdone
X
X# PostScript prologue
Xecho "%!PS-Adobe-1.0"
Xecho "%%Title:$1 icon"
Xecho "%%Creator:`basename $0`"
Xecho "%%For:`whoami`"
Xecho "%%CreationDate:`date`"
Xecho "%%BoundingBox:72 72 144 144"
Xecho "%%EndComments"
X
X# PostScript image printing procedure
Xecho "/picstr 16 string def"
Xecho "/Icon"
Xecho "{ 0 setgray"
Xecho "  $Width $Height true [$Width 0 0 -$Height 0 $Height]"
Xecho "  { currentfile picstr readhexstring pop } imagemask"
Xecho "} def"
Xecho "%%EndProlog"
Xecho "gsave"
X
X# lower left hand corner and scale
Xecho "72 72 translate"
Xecho "72 72 scale"
Xecho "Icon"
X
X# change to picstr by removing 0x prefix, spaces, tabs, and commas
Xgrep '0x.*0x.*0x.*0x' $1 | sed -e '
Xs/0x//g
Xs/[	, ]//g'
X#  ^---<tab><comma><space> pattern
X
X# PostScript end
Xecho "grestore"
Xecho "%%Trailer"
X# icon
!Hello!Kitty!
echo Extracting ref.ms
sed >ref.ms <<'!Hello!Kitty!' -e 's/X//'
X.SH
XReferences
X.LP
X.nf
X.ls 1
X.@tag CITE _ADOB87_
X.IP [_ADOB87_]
XAdobe Systems Incorporated,
X.I
XAdobe Illustrator User's Guide,
X.R
XAdobe Systems Incorporated, Mountain View, Cal., 1987.
X.@tag CITE _ADOB86_
X.IP [_ADOB86_]
XAdobe Systems Incorporated,
X.I
X\*(PS Language Reference Manual,
X.R
XAddison-Wesley, Reading, Mass., 1986.
X.@tag CITE _ADOB87a_
X.IP [_ADOB87a_]
XAdobe Systems Incorporated,
X.I
X\*(PS Language Tutorial and Cookbook,
X.R
XAddison-Wesley, Reading, Mass., 1987.
X.@tag CITE _ADOB87b_
X.IP [_ADOB87b_]
XAdobe Systems Incorporated,
X.I
X\*(PS Developer's Toolkit,
X.R
XAdobe Systems Incorporated, Mountain View, Cal., 1987.
X.@tag CITE _AHO88_
X.IP [_AHO88_]
XA. V. Aho, and R. Sethi,
X\*QMaintaining Cross References in Manuscripts\*U,
XSoftware\*-Practice and Experience, vol. 18, no. 1, pp. 1-13, 1988.
X.@tag CITE _AWK79_
X.IP [_AWK79_]
XA. V. Aho, B. W. Kernighan, and P. J. Weinberger,
X\*QAwk \*- A Pattern Scanning and Processing Language\*U,
XSoftware\*-Practice and Experience, 18, no. 1, 1-13 (1988).
X.@tag CITE _AWK88_
X.IP [_AWK88_]
XA. V. Aho, B. W. Kernighan, and P. J. Weinberger,
X.I
XThe Awk Programming Language,
X.R
XAddison-Wesley, Reading, Mass., 1988.
X.@tag CITE _McMAH79_
X.IP [_McMAH79_]
X\*QSed \*- A Noninteractive Text Editor\*U,
XComputing Science Technical Report 77,
XAT&T Bell Laboratories,
XMurray Hill, N. J., 1979.
X.@tag CITE _THOM68_
X.IP [_THOM68_]
XK. Thompson,
X\*QRegular Expression Search Algorithm\*Q,
XComm. ACM, vol. 11, no. 6, pp. 419-422, 1968.
X.\" ref.ms
!Hello!Kitty!
echo Extracting txcopy.sh
sed >txcopy.sh <<'!Hello!Kitty!' -e 's/X//'
X#!/bin/sh
X##	@(#)txcopy.sh 1.00 DEO <04/12/88>
X#ifdef Header
X##
X## MANUAL
X##	TXCOPY 1 "April 6, 1988"
X## NAME
X##	txcopy -- NROFF copy filter
X## SYNOPSIS
X##	txcopy [ files ] ...
X## DESCRIPTION
X##	_ txcopy is used to filter _ files in order to use the
X##	NROFF .so command to copy files.  NROFF special characters
X##	are escaped.
X## INPUTS
X##	_ files are fixed formatted source files.
X## OUTPUTS
X##	standard output.
X## RETURN VALUES
X##	[exit] see AWK manuals.
X##
X#endif Header
Xecho '.\"Creator:txcopy 1.00 DEO <04/12/88>'
Xecho '.\"For:'`whoami`
Xecho '.\"CreationDate:'`date`
Xawk '
XBEGIN { print ".nf" }
X# default :
X{	s = $0;				# copy line as is
X	for (txcopyj = 1; txcopyj <= length(s); txcopyj++)
X	{
X		# NROFF comments
X		if (substr(s, txcopyj, 2) == "\\\"")
X		{
X			printf "\\\\\\&\""
X			txcopyj++
X			continue
X		}
X
X		txcopyc = substr(s, txcopyj, 1)
X
X		# NROFF command prefixes
X		if (txcopyc == ".")
X			printf "\\&."
X
X		# Note: single quotes are interpreted by the shell
X		else if (txcopyc == "'\''")
X			printf "\'\''"
X
X		# backslash
X		# Note: add \& to prevent interpretations
X		else if (txcopyc == "\\")
X			printf "\\\\\\&"
X
X		else
X			printf "%s", txcopyc
X	}
X	printf "\n"
X}
XEND { print ".fi" }
X' $*
X# txcopy
!Hello!Kitty!
echo Extracting txlink.c
sed >txlink.c <<'!Hello!Kitty!' -e 's/X//'
X#ifndef lint
Xstatic	char txlink_sccsid[] = "@(#)txlink.c <04/12/88>";
X#endif lint
X#ifdef Header
X/*
X** MANUAL
X**	TXLINK 1 "February 15, 1988"
X** NAME
X**	txlink -- TROFF and PostScript figures
X** SYNOPSIS
X**	txlink [ file ]
X** DESCRIPTION
X**	_ txlink is used to insert PostScript figures into _ file,
X**	which has been processed by TROFF and a PostScript filter,
X**	and write the results to the standard output.  _ txlink is not
X**	a complete PostScript figure placement and scaling tool.
X**	It is mainly an example of one way to include figures in
X**	files which have been processed by a document formatter and
X**	a PostScript filter.
X** INPUTS
X**	_ file is PostScript file resulting from running TROFF
X**	and a PostScript filter.  _ txlink will read from the standard
X**	input if _ file is not given.
X** OUTPUTS
X**	standard output.
X** RETURN VALUES
X**	[exit] exit value.
X** NOTES
X**	The TROFF source files contain "marks" for the lower left
X**	and upper right corners of the document box where a figure is
X**	inserted:
X**
X** NROFF .ta 1.5i 3.5i
X**	    +-	-FigureUR
X**	    |	 |
X**	    FigureLL	-+
X** NROFF .ta
X**
X**	Note: Only "FigureUR" and "FigureLL" are actually printed and
X**	"Figure" is the name of the figure.
X**
X**	One example way to generate these reference points is:
X**
X**	    .in +2.5i
X**	    FigureUR
X**	    .sp .5i
X**	    .in
X**	    FigureLL
X**
X**	Note: The temporary indentation of 2.5 inches and the .5 inch
X**	extra line spacing would be replaced by the desired dimensions.
X**	It may be necessary to use a TROFF "keep" so that the
X**	marks will be on the same page.
X**
X**	The PostScript figure is inserted into the document box based
X**	on the coordinates found in the PostScript filter output file.
X**	Adobe Transcript filters will generate this type of text
X**	placement:
X**
X**	    FigURx FigURy(FigureUR)S
X**
X**	Note: "FigURx" and "FigURy" appear as integers in the output
X**	file.
X**
X**	_ txlink is designed to work with _ txtags(1) which is
X**	a symbolic reference maintainence tool.  _ txtags produces
X**	a "tag reversal" file which is used by _ txlink to convert
X**	the figure numbers back into symbolic references.  This is
X**	necesary because the "Figure" part of the "FigureUR" string
X**	in the previous example would be changed into a number.
X**	The PostScript figure files are expected to be named with
X**	the symbolic reference name and a default extension of ".ps".
X**
X**	_ txlink uses a PostScript procedure called _ locate which
X**	appears in the Adobe Illustrator's User's Manual, chapter
X**	6, "Illustrator and PostScript."  This routine can handle
X**	placement and scaling of Encapsulated PostScript (EPSF) files
X**	using the default PostScript coordinate system.  A detailed
X**	explanation of EPSF files is available from Adobe Systems.
X**
X**	_ txlink attempts to isolate the effects of the figure by
X**	using a save/restore construct.  The showpage operator is
X**	also temporarily disabled during the execution of the
X**	PostScript figure code.
X**
X**	PostScript, Illustrator and Transcript are trademarks of
X**	Adobe Systems Incorporated.
X** FILES
X**	locate.ps, PostScript procedure to place and scale figure.
X**	txlink.aux, txtags(1) produced tag reversal file.
X** SEE ALSO
X**	nroff(1), troff(1), txtags(1), enscript(1), transcript(8).
X** REFERENCES
X**	Adobe Systems Incorporated, Adobe Illustrator User's Manual,
X**	Adobe Systems Incorporated, Mountain View, Cal., 1987.
X**
X**	Adobe Systems Incorporated, "Encapsulated PostScript File
X**	Format", Adobe Systems Incorporated, Mountain View, Cal., 1987.
X** BUGS
X**	There appears to be a bug in the page reversal software.
X**	The temporary work-around is to edit the first line of
X**	the PostScript output file and change it to "%!".
X**
X**	The PostScript filters will sometimes split the name of
X**	the figure.  _ txlink does not reconstruct the split figure
X**	names.
X**
X**	_ txlink will not work with PostScript filters which specify
X**	the coordinates apart from the text.
X** AUTHOR
X**	Dean Okamura
X**	Telos Consulting Services, 1370 N. Brea, #150, Fullerton, CA 92635.
X*/
X#endif Header
X
X#include <stdio.h>
X#include <string.h>
X#include <ctype.h>
X
X#define BufSize 256			/* maximum length line */
X#define MaxFigures 100			/* maximum number of figures */
X#define BoundingBox "%%BoundingBox:"
X#define BoundingBoxLen sizeof(BoundingBox)-1
X#define Prolog "%%EndProlog"
X#define PrologLen sizeof(Prolog)-1
X
X#ifndef TRUE
X#define TRUE 1
X#endif
X#ifndef FALSE
X#define FALSE 0
X#endif
X
X/* figure mark variables */
Xchar FigUR[BufSize] = "1";		/* figure name */
Xchar FigLL[BufSize] = "0";		/* figure name */
X
Xchar Figure[BufSize] = "";		/* figure file */
Xchar FigureExt[BufSize] = ".ps";	/* figure file extension */
Xchar FigureFile[BufSize] = "txlink.aux";	/* figure list file */
Xchar FigureList[MaxFigures+1][BufSize];	/* figure list */
X
Xchar Locate[BufSize] = "locate.ps";	/* locate procedure file */
X
X/* figure bounding box */
Xchar FigLLx[BufSize], FigLLy[BufSize];	/* lower left corner */
Xchar FigURx[BufSize], FigURy[BufSize];	/* upper right corner */
X
X/* figure document box */
Xchar DocLLx[BufSize], DocLLy[BufSize];	/* lower left corner */
Xchar DocURx[BufSize], DocURy[BufSize];	/* upper right corner */
X
X/* private routines */
Xstatic void CopyFile(), Prologue(), FigureBox(), Document();
Xstatic int FigureMark();
X
X/* page */
X/* copy file */
X
Xstatic void CopyFile(file)
Xchar file[];
X{
X	FILE *f;
X	char buf[BufSize];
X
X	/* file not open */
X	if (!(f = fopen(file, "r")))
X	{
X		perror(file);
X		exit(1);
X	}
X
X	/* copy file */
X	while (fgets(buf, BufSize, f))
X		(void)fputs(buf, stdout);
X
X	/* close file */
X	(void)fclose(f);
X}					/* CopyFile */
X
X/* page */
X/* get figure list */
X
Xstatic void GetFigureList(file)
Xchar *file;
X{
X	FILE *f;
X	char buf[BufSize];
X
X	/* open figure list */
X	if (!(f = fopen(file, "r")))
X	{
X		perror(file);
X		exit(1);
X	}
X
X	/* read in figure list */
X	while (fgets(buf, BufSize, f))
X	{
X		int n;
X		char buf1[BufSize];
X
X		sscanf(buf, "%d %s", &n, buf1);
X		if ((n < 0) || (n > MaxFigures))
X		{
X			fprintf(stderr, "illegal figure number %d\n", n);
X			exit(1);
X		}
X		(void)strcpy(FigureList[n], buf1);
X	}
X	(void)fclose(f);
X}					/* GetFigureList */
X
X/* page */
X/* process the prolog */
X
Xstatic void Prologue()
X{
X	char buf[BufSize];
X
X	/* read file and look for end of prolog */
X	while (fgets(buf, BufSize, stdin))
X	{
X		/* found end of prolog */
X		if (!strncmp(buf, Prolog, PrologLen))
X		{
X			/* insert locate procedure */
X			CopyFile(Locate);
X			break;
X		}
X
X		/* print prologue line */
X		(void)fputs(buf, stdout);
X	}
X	/* print end of prologue line */
X	(void)fputs(buf, stdout);
X}					/* Prologue */
X
X/* page */
X/* get figure mark */
X
Xstatic int FigureMark(s, type, DocXXx, DocXXy, FigXX)
Xchar s[];
Xchar *type;
Xchar DocXXx[];
Xchar DocXXy[];
Xchar FigXX[];
X{
X	static char figure[BufSize];
X	static char *s0, *s1, *s2, *t;
X	int k;
X
X	/* figure mark format: row column(FigureXX) */
X	/*     where XX is type LL or UR */
X	/*     and Figure is alphanumeric */
X
X	/* row and column check */
X	if (!(s0 = strchr(s, ' ')))
X		return(FALSE);
X
X	/* parenthesis checks */
X	else if (!(s1 = strchr(s0, '(')))
X		return(FALSE);
X
X	else if (!(s2 = strchr(s1, ')')))
X		return(FALSE);
X
X	/* skip (XX) marks */
X	else if ((s2 - s1) < 4)
X		return(FALSE);
X
X	/* mark type check */
X	else if (strncmp(s2-2, type, 2))
X		return(FALSE);
X
X	/* alphanumeric check */
X	else
X	{
X		for (t = s1+1; t < s2-2; t++)
X		{
X			if (!isalnum(*t))
X				return(FALSE);
X		}
X	}
X
X	/* copy to local buffer */
X	k = s2-2 - s;
X	(void)strncpy(figure, s, k);
X	figure[k] = '\0';
X
X	/* copy coordinates and figure mark */
X	(void)strcpy(DocXXx, strtok(figure, " ()"));
X	(void)strcpy(DocXXy, strtok((char *)NULL, " ()"));
X	(void)strcpy(FigXX, strtok((char *)NULL, " ()"));
X	return(TRUE);
X}					/* FigureMark */
X
X/* page */
X/* get figure bounding box information */
X
Xstatic void FigureBox(file, FigLLx, FigLLy, FigURx, FigURy)
Xchar *file;
Xchar FigLLx[];
Xchar FigLLy[];
Xchar FigURx[];
Xchar FigURy[];
X{
X	FILE *f;
X	char buf[BufSize];
X
X	/* figure file not open */
X	if (!(f = fopen(file, "r")))
X	{
X		perror(file);
X		exit(1);
X	}
X
X	/* read file and look for bounding box */
X	while (fgets(buf, BufSize, f))
X	{
X		/* get bounding box coordinates */
X		if (!strncmp(buf, BoundingBox, BoundingBoxLen))
X		{
X			sscanf(buf+BoundingBoxLen, "%s %s %s %s",
X			    FigLLx, FigLLy, FigURx, FigURy);
X			break;
X		}
X	}
X
X	/* close figure file */
X	(void)fclose(f);
X}					/* FigureBox */
X
X/* page */
X/* copy and process document section */
X
Xstatic void Document()
X{
X	char buf[BufSize];
X	int mark;
X
X	/* copy and process document section */
X	mark = FALSE;
X	while (fgets(buf, BufSize, stdin))
X	{
X		/* upper right mark */
X		if (FigureMark(buf, "UR", DocURx, DocURy, FigUR))
X		{
X			mark = TRUE;
X
X			/* comment out mark */
X			(void)fputs("% ", stdout);
X		}
X
X		/* lower left mark */
X		else if (FigureMark(buf, "LL", DocLLx, DocLLy, FigLL))
X		{
X			mark = TRUE;
X
X			/* comment out mark */
X			(void)fputs("% ", stdout);
X		}
X
X		/* display line */
X		(void)fputs(buf, stdout);
X
X		/* check for matching marks */
X		if (mark && !strcmp(FigUR, FigLL))
X		{
X			int n;
X
X			mark = FALSE;
X
X			/* convert Figure number to name */
X			sscanf(FigLL, "%d", &n);
X			(void)strcpy(Figure, FigureList[n]);
X
X			/* add default extension */
X			(void)strcat(Figure, FigureExt);
X
X			/* get figure bounding box information */
X			FigureBox(Figure, FigLLx, FigLLy, FigURx, FigURy);
X
X			/* isolate figure effects with save/restore */
X			(void)fputs("/--save0-- save def\n", stdout);
X
X			/* temporarily disable showpage */
X			(void)fputs("/showpage { } def\n", stdout);
X
X			/* print call to locate */
X			(void)fprintf(stdout,
X			    "%s %s %s %s %s %s %s %s locate\n",
X			    FigLLx, FigLLy, FigURx, FigURy,
X			    DocLLx, DocLLy, DocURx, DocURy);
X
X			/* copy figure file */
X			CopyFile(Figure);
X
X			/* restore state */
X			(void)fputs("--save0-- restore\n", stdout);
X
X			/* re-initialize for next figure */
X			(void)strcpy(FigUR, "0");
X			(void)strcpy(FigLL, "1");
X		}
X	}
X}					/* Document */
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X	/* user included PostScript output file */
X	if (argc == 2)
X	{
X		if (!freopen(argv[1], "r", stdin))
X		{
X			perror(argv[1]);
X			exit(1);
X		}
X	}
X
X	GetFigureList(FigureFile);
X	Prologue();
X	Document();
X	exit(0);
X}					/* txlink */
!Hello!Kitty!
echo Extracting txtags.sh
sed >txtags.sh <<'!Hello!Kitty!' -e 's/X//'
X#!/bin/sh
X##	@(#)txtags.sh 1.00 DEO <04/06/88>
X#ifdef Header
X##
X## MANUAL
X##	TXTAGS 1 "April 6, 1988"
X## NAME
X##	txtags -- reference tag assembler
X## SYNOPSIS
X##	txtags [ files ] ...
X## DESCRIPTION
X##	_ txtags is used to process reference tags according
X##	to the conventions described in Aho, 1988.
X## INPUTS
X##	_ files are NROFF source files.
X## OUTPUTS
X##	standard output.
X## RETURN VALUES
X##	[exit] see AWK manuals.
X## REFERENCES
X##	A. V. Aho, and R. Sethi, "Maintaining Cross References
X##	in Manuscripts", Software-Practice and Experience,
X##	vol. 18, no. 1, pp. 1-13, 1988.
X##
X#endif Header
Xsource=$*
Xscript=tmp$$
Xfigure=txlink.aux
X
Xgrep -h "^\.@tag" $source | awk '
X# truncate figure list header
XBEGIN	{ print "" > "'$figure'" }
X
X# create symbolic tag conversion editing command
X	{ print "s/" $3 "/" (++value[$2]) "/g"
X
X# save figure list
X	if ($2 == "FIG")
X	{
X		# Assert: _filename_ pattern
X		filename = substr($3, 2, length($3)-2)
X		print value[$2],filename >> "'$figure'"
X	}
X}
X
X# delete tags editing command
XEND	{ print "/^\\.@tag/d" }
X' > $script
Xsed -f $script $source
Xrm -f $script
X# txtags
!Hello!Kitty!
echo Extracting txtools.ms
sed >txtools.ms <<'!Hello!Kitty!' -e 's/X//'
X.\"
X.\" NO MANUAL
X.\" NAME
X.\"	txtools -- text processing tools
X.\" SYNOPSIS
X.\"	troff -ms -t txtools.ms ref.ms app.ms | lpr -Plw -t
X.\" DESCRIPTION
X.\"	This is an example source for a paper.
X.\" NOTES
X.\"	See file makefile for customized document production.
X.\" BUGS
X.\"	LaserWriter image -.25i vertical on the page.
X.\"
X.\"	troff font widths are not correct.
X.\"
X.\"	.sp cannot be the first macro on a page.
X.\"
X.\" strings constants
X.ds aw Awk
X.ds gr Grep
X.ds lw LaserWriter
X.ds PS P\s-2OST\s0S\s-2CRIPT\s0
X.ds se Sed
X.\" Note: TL, TS, and TT are used by ms macros
X.ds TS T\s-2RAN\s0S\s-2CRIPT\s0
X.ds Tt T\s-2X\s0T\s-2AGS\s0
X.ds Tl T\s-2X\s0L\s-2INK\s0
X.ds tr Troff
X.ds Tx T\s-2X\s0T\s-2OOLS\s0
X.ds UX U\s-2NIX\s0
X.\"
X.\" no hyphenation
X.nh
X.\" title page
X.TL
X\*(Tx
X.sp
XText Processing Tools
X.AU
XDean Okamura
X.\" abstract
X.AB
X\*(Tx is a small set of text processing tools that help the
Xuser maintain symbolic references in documents and
X\*Qlink\*U \*(PS figures into documents which have been prepared
Xfor printing on a \*(PS printer.
XThe tools are mainly presented as examples of how to
Xsolve common problems encountered in producing documents.
X.AE
X.sp 3
X.\" paper
X.SH
XIntroduction
X.LP
XMaintaining the consistency of names or numbers for
Xfigures, tables, bibliographic citations and other document
Xitems is a common problem.
XEach of these items can change many times during the
Xsuccessive drafts required to produce the final version.
XThe ability to use symbolic references in documents instead of
Xexplicit names and numbers can greatly simplify the bookkeeping
Xneeded to keep these items consistent.
X\*(Tt is essentially a \*Qreference tag assembler\*U that has
Xappeared in earlier papers [_AHO88_,_AWK88_].
XIn these reference assemblers, the author defines tags with the
Xform:
X.sp
X.IP
X.nf
X\&.@tag \fIitemclass tagname\fP
X.fi
X.sp
X.LP
Xwhich can appear anywhere in the text.
XThese symbolic tags are changed into the actual numbers
Xused in the document in three phases [_AHO88_]:
X.sp
X.IP
X1. Extracting the tag definitions from the source text.
X.sp
X2. Computing the numbers for the tag definitions and creating
Xa script of editing instructions.
X.sp
X3. Copying the source text, using the editing script to replace
Xtags by numbers and to delete tag definitions.
X.sp
X.LP
XThe three phases are implemented with \*(UX \*(gr [_THOM68_],
X\*(aw [_AWK79_], and \*(se [_McMAH79_].
XA simple change to the \*(aw program was made to allow the user
Xto convert numbered figures back to their symbolic reference.
X\*(Tl takes these symbolic references and \*Qlinks\*U
X\*(PS figures into the document.
XThe concept of linking is borrowed from C programming.
X\*(tr source files are analogous to C source files.
X\*(tr is used with a \*(PS filter to \*Qcompile\*U the sources to \*(PS
X\*Qobject\*U files.
XThese \*(PS files can be \*Qexecuted\*U on a \*(lw and
Xproduce hardcopy output.
XProofreading takes place with these copies but the documents
Xare missing \*(PS figures.
XThe figures are \*Qstubbed\*U out and the \*(PS program
Xjust prints a few marks and a white space where the figures
Xwill eventually be placed in the final version of the
Xdocument.
XA version with the figures included can be produced by
X\*Qre-linking\*U with the \*(PS figure object files.
XPerhaps the computer programming analogy has been stretched
Xtoo far, but it illustrates how \*(Tl is used in text processing.
X.PP
X\*(Tl expects the \*(PS document to be \*Qmarked\*U in a
Xknown format.
XOne string marks the bottom left corner of the figure and
Xa second string marks the upper right corner.
XThese strings are \*Qplain\*U text and appear in the
Xoutput of the text formatter.
XSince most text formatter and \*(PS filter combinations
Xwill not pass \*(PS commands, this solution was
Xchosen because it does not require coordination
Xbetween these software products.
X.PP
XThe major items of information that need to be known are the
X\*(PS coordinates of the missing figures.
XThese coordinates depend on the \*(PS filter used to
Xprocess the text formatter output.
XFor example, the \*(TS package from Adobe Systems contains
Xmany filter programs.
XEnscript which processes text files uses a coordinate system
Xwhere the origin is at the bottom left corner of the printed
Xpage, while pscat which processes \*(tr output places the origin
Xat the top left corner.
X\*(Tl assumes that the user has placed special text strings
Xin the document.
XEach \*(PS figure must be in a format known as
XEncapsulated \*(PS File (EPSF). [_ADOB87b_]
XThe figure file is scanned for the corresponding corner
Xcoordinates of the \*QBoundingBox\*U \*(PS comment which are part
Xof the EPSF conventions.
XWhen these parameters are known, the file is merged with
Xthe document file.
XThe actual figure positioning and scaling is performed by a
X\*(PS procedure that appeared in the user's manual that
Xaccompanies Adobe Illustrator. [_ADOB87_]
X.\" Example
X.SH
X\*(Tx Example
X.LP
X.I
XIconedit figure.
X.R
XThis image was created with a graphics editor, Iconedit [_EXAMPLE_SUN86_].
XThe editor creates a text file which was translated to EPSF.
X.sp
X.KS
X.in +1i
X_Telos_UR
X.sp 1i
X.in
X_Telos_LL
X
X.@tag FIG _Telos_
XFigure _Telos_. Example icon created with Iconedit.
X.sp 2
X.KE
X.\"
X.sp
X.I
XReferences
X.R
X.sp
X.@tag EXAMPLE_CITE _EXAMPLE_SUN86_
X.IP [_EXAMPLE_SUN86_]
XSun Microsystems,
XIconedit chapter in Suntools Documentation,
XSun Microsystems, Mountain View, Cal., 1986.
X.\"
X.sp 2
X.SH
XUsing \*(Tx to Create the Example
X.LP
XLet's look at what it took to insert figure _Telos_ into a
X\*(tr document.
XAlthough the actual details may differ for other text formatters
Xand \*(PS filters, the basic principles should be adaptable
Xfor these different cases.
XThe source contains figure and citation tags that are
Xprocessed by \*(Tt and two marks that \*(Tl expects.
X\*(Tl expects to find a marks such as \*Q_Telos_UR\*U and
X\*Q_Telos_LL\*U for the lower left and upper right corners
Xof the figure respectively.
X.sp
X.KS
X.nf
X\&.I
XIconedit figure\&.
X\&.R
XThis image was created with a graphics editor, Iconedit [_SUN86_]\&.
XThe editor creates a text file which was translated to EPSF\&.
X\&.sp
X\&.KS
X\&.in +1i
X_\&Telos\&_UR
X\&.sp 1i
X\&.in
X_\&Telos\&_LL
X
X\&.@tag FIG _\&Telos\&_
XFigure _\&Telos\&_\&. Example icon created with Iconedit\&.
X\&.sp
X\&.KE
X.fi
X.sp
X.nf
X\&.I
XReferences
X\&.R
X\&.sp
X\&.@tag CITE _\&SUN86\&_
X\&.IP [_\&SUN86\&_]
XSun Microsystems,
XIconedit chapter in Suntools Documentation,
XSun Microsystems, Mountain View, Cal\&., 1986\&.
X.fi
X
X.@tag FIG _TelosListing_
XFigure _TelosListing_. Source for paragraph with a figure.
X.KE
X.sp 2
XA major consideration in creating the \*(tr source is to isolate
Xthe marks in the \*(PS file and keep the figure on one page.
XIn the example shown in figure _TelosListing_, the method is
Xto place the marks on separate lines from the rest of the
Xdocument and \*(tr macros .KS and .KE are used to prevent the
Xfigure from being split between two pages.
X.PP
XRunning \*(Tt to convert the symbolic references and printing
Xthe document for proofreading could be done at this point.
XUsing
X.I
Xexample.ms
X.R
Xas the name of the \*(tr source file, the \*(UX command
Xwould be similar to:
X.IP
X.sp
X.nf
Xtxtags example.ms | troff -ms -i -t | pscat | lpr
X.fi
X.LP
X.sp
XThe actual commands used will probably require more font information.
XThe copy will not contain the figure but the figure number
Xwill appear at the lower left and upper right corners of where
Xthe figure will be placed in the final version.
X.PP
XEventually the time comes for pages with figures.
X\*(Tt has converted the tags and also created a file which contains
Xeach figure number and its original symbolic tags in order to
Xreproduce the original symbolic tag.
X\*(Tl uses this \*Qtag reversal\*U file after it has found the
Xfigure marks to determine the name of
Xthe \*(PS file to insert into the document.
XThe text file is processed in the normal way except that the
X\*(PS output is saved and not sent to the \*(lw.
XContinuing with the example, the \*(UX commands would be similar to:
X.sp
X.IP
X.nf
Xtxtags example.ms | troff -ms -i -t | pscat > example.ps
Xtxlink example.ps | lpr
X.fi
X.sp
X.LP
XNotice that \*(Tl requires a two step process and a temporary file,
X.I
Xexample.ps.
X.R
XThe two separate commands are used because the tag reversal
Xfile produced by \*(Tt is not always completely written by
Xthe time that \*(Tl starts its processing.
X.PP
XSince the \*(PS locate procedure used to place the figure
Xon the document page may be used more than once, \*(Tl
Xcopies locate.ps into the \*(PS prolog header.
XThis turns out to be very straightforward because there
Xis a special comment, %%EndProlog, which marks the end of
Xthe \*(PS filter procedures.
XThe file is scanned for figure marks which will appear
Xas:
X.IP
X.sp
X.nf
X864 2202(1UR)U
X432 2706(1LL)U
X.fi
X.LP
X.sp
XThe first two numbers are the page coordinates of the figure
Xmarks, the parentheses delimit \*(PS strings, and the final
Xletter is the name of a \*(PS procedure used to place that
Xstring on the page.
X\*(Tl changes these lines to comments so that they will not
Xbe printed and extracts the coordinates and figure number.
XIn figure _Telos_, the number is changed back into the symbolic
Xreference which becomes _\&Telos\&_, the underscores are removed,
Xand a default extension of \*Q.ps\*U is appended to generate
Xthe \*(PS figure file name.
XThe figure file is scanned for a special comment, %%BoundingBox,
Xwhich contains the lower left and upper right coordinates of
Xthe figure in default \*(PS coordinates for a page.
XFinally, \*(Tl creates the locate procedure call, includes
Xsome \*(PS commands to isolate the effects of the figure
Xfrom the rest of the document, and copies in the figure file.
XThe resulting \*(PS without the image producing statements
Xis shown in figure _PostScript_.
X.sp
X.nf
X% 864 2202(1UR)U
X% 432 2706(1LL)U
X/--save0-- save def
X/showpage { } def
X72 72 144 144 432 2706 864 2202 locate
X
X\&.\&.\&.
X% PostScript to produce image deleted.
X\&.\&.\&.
X
X--save0-- restore
X.fi
X
X.@tag FIG _PostScript_
XFigure _PostScript_. \*(Tl processed \*(PS fragment.
X.sp
X.SH
XConclusion
X.LP
XThe principle test case of \*(Tx has been the a Master's paper
Xwith many screen dump figures.
XUsing these tools has made the development of the paper a
Xmuch easier task.
XFor example, removing the manual paste-up of
Xthe screen dump figures has significantly reduced page
Xproduction time.
XIn addition to the time savings, the final product looks
Xmuch better than making screen dumps to a printer and
Xreducing the printout with a photocopier to a size which
Xfits on the page.
XThe major items which made this approach successful are
Xthe symbolic tag assembler and the \*(PS locate procedure.
XBoth of items are recommended as methods for future projects.
XIt should be emphasized again that the locate procedure has been
Xused with \*(PS filters that use different coordinate systems
Xbut still places the figure on the page without any additional
Xeffort to account for these differences.
XOf course this only applies to EPSF files.
XThe weakest assertion in the \*(Tl method of finding figures
Xin files is that the filter produces a certain
Xstyle of \*(PS code.
XThere is no guarantee that the filter will use the expected
Xstyle of coding or that the figure number and lower left
Xor upper right strings will be kept intact.
XHopefully with the proliferation of \*(PS filters in the
Xworld will arise a convention for displaying strings.
X\*(Tx do not address these issues but have performed well with
Xthe \*(tr text processor and the pscat \*(PS filter.
X.fi
X.\" Caveat
X.SH
XCaveats
X.LP
XUnfortunately some older versions of the \*(TS do
Xnot handle \*(Tl processed files.
XAs far as I know, the problem has been isolated to the page reversal
Xsoftware.
XThe fix-up is to change the initial line
Xof the \*(PS file sent to the \*(lw.
XThis can be done by inserting a line, \*Q%!\*U, at the
Xbeginning of the file which indicates
Xthat the file is legal \*(PS but does not follow
Xthe structuring conventions required to do page reversal.
X.LP
X.sp 2
X.SH
XAcknowledgements
X.LP
XThanks to Mike Byron, Adobe Systems Incorporated, who helped me figure
Xout the details of mixing \*(tr and \*(PS.
X.sp
X\*(PS and \*(TS are trademarks of Adobe Systems Incorporated.
X.\"
X.\" Note: reference.ms should follow.
X.\"
X.\" txtools
!Hello!Kitty!
echo ""
echo "End of SHAR"
exit