[comp.sources.unix] v11i073: Including PostScript figures in ditroff, Part02/05

rsalz@uunet.UU.NET (Rich Salz) (09/24/87)

Submitted-by: trevor@linc.cis.upenn.edu (Trevor Darrell)
Posting-number: Volume 11, Issue 73
Archive-name: psfig/Part02


# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Contents:  trf/lib/ trf/man/ trf/patches/ trf/tst/ trf/lib/README
#	trf/lib/psfig.tmac trf/man/README trf/man/cnote.txt trf/man/psfig.1
#	trf/patches/README trf/patches/ditroff.frag trf/patches/psdit.c.frag
#	trf/patches/psdit.c.patch trf/patches/psdit.pro.frag trf/tst/Makefile
#	trf/tst/test.trf
 
echo mkdir - trf/lib
mkdir trf/lib
chmod u=rwx,g=rx,o=rx trf/lib
 
echo x - trf/lib/README
sed 's/^@//' > "trf/lib/README" <<'@//E*O*F trf/lib/README//'
psfig/lib contains:

	psfig.tmac - troff macros that must be included
			using "-mpsfig" from ditroff.
			psfig.tmac should be placed with the other
			troff macros; we have it in /usr/lib/tmac.

@//E*O*F trf/lib/README//
chmod u=rw,g=r,o=r trf/lib/README
 
echo x - trf/lib/psfig.tmac
echo x - CHANGE THE ^G\'s TO REAL BELL CHARACTERS ON LINE 6!
sed 's/^@//' > "trf/lib/psfig.tmac" <<'@//E*O*F trf/lib/psfig.tmac//'
@.\" psfig macros. An argument will turn off centering.
@.de F+
@.br
@.nr F, \\n(.u
@.nf
@.if ^G\\n(.z^G^G .sp -.5
@.if \\n(.$=0 .ce 9999
@..
@.de F-
@.ce 0
@.if \\n(F, .fi
@.br
@..
@//E*O*F trf/lib/psfig.tmac//
chmod u=rw,g=r,o=r trf/lib/psfig.tmac
 
echo mkdir - trf/man
mkdir trf/man
chmod u=rwx,g=rx,o=rx trf/man
 
echo x - trf/man/README
sed 's/^@//' > "trf/man/README" <<'@//E*O*F trf/man/README//'
psfig/man contains the following files:

	psfig.1 - a man page for psfig to be installed in /usr/man/man1.
			Type `cp psfig.1 /usr/man/man1', then
			`man psfig'.

	cnote.txt - a short document describing a few details of the
			PostScript File Structuring Convention that
			are relevant to psfig.
@//E*O*F trf/man/README//
chmod u=rw,g=r,o=r trf/man/README
 
echo x - trf/man/cnote.txt
echo BEWARE OF HAVING LOST UNDERSCORE-BACKSPACE SEQUENCES
sed 's/^@//' > "trf/man/cnote.txt" <<'@//E*O*F trf/man/cnote.txt//'









             POSTSCRIPT Structuring Conventions





     For POSTSCRIPT files to be proper, they must be  struc-
tured according to ``The POSTSCRIPT File Structuring Conven-
tion'',  as  defined  by  Adobe  Systems  (the  creator   of
POSTSCRIPT)   At  a  bare  minimum,  the  first  line  in  a
POSTSCRIPT file must start with the characters ``%!''.  _N_o_t_e
_t_h_a_t _M_a_c_D_r_a_w (at least the current version) _d_o_e_s _n_o_t _s_u_p_p_o_r_t
_t_h_i_s, so some programs (notably psfig and FigTeX) may reject
Macintosh  files as invalid. The solution to this is simple-
add a line of the form ``%!'' to the beginning of the  file.
Psfig and FigTeX users will also have to add a ``%%Bounding-
Box:'' comment just below the ``%!''.

     So, a sample file from MacDraw may have to  be  changed
from

        md begin
        T 32 760 100 72 72 psu
        ...

to:

        %!
        %%BoundingBox:  _a _b _c _d
        md begin
        T 32 760 100 72 72 psu
        ...

where (_a,_b) is the lower left coordinate and  (_c,_d)  is  the
upper right coordiate of the figure's bounding box expressed
in points (72 to the  inch),  relative  to  the  lower  left
corner  of  the page. Again, you probably only need to worry
about a bounding box if you are using psfig or FigTeX.









_________________________
  |- See the _P_O_S_T_S_C_R_I_P_T _L_a_n_g_u_a_g_e  _R_e_f_e_r_e_n_c_e  _M_a_n_u_a_l  for
futher details.




                      August 19, 1986


@//E*O*F trf/man/cnote.txt//
chmod u=rw,g=r,o=r trf/man/cnote.txt
 
echo x - trf/man/psfig.1
sed 's/^@//' > "trf/man/psfig.1" <<'@//E*O*F trf/man/psfig.1//'
@.TH PSFIG 1
@.SH NAME
psfig \- a troff preprocessor for PostScript figures
@.SH SYNTAX
@.B psfig
[
@.B \-D<search-dir>
] [
@.B \-d<draft-level>
]
[ file ... ]
@.SH DESCRIPTION
@.I Psfig
is a preprocessor for
@.IR ditroff (1)
that permits direct inclusion of PostScript figures and
special effects into a document.
The input files are copied to the standard output, except
for lines between .F+ and .F\- commands, which are assumed
to contain 
@.I psfig
commands. If no input files are given, 
@.I psfig
reads the standard input, so it may be used as part of
a pipe to ditroff.
The 
@.I -D<dir>
option specifies a directory in which to search for files. Any number of
these may be specified, and they will be searched in turn. The current 
directory is always searched first.
@.PP
The 
@.I \-mpsfig
argument must be given to 
@.IR ditroff , 
whose output is passed to
@.IR psdit ,
the ditroff to postscript conversion program supplied
with the Transcript package,
which produces the final output.
@.PP 
@.I Psfig
commands are enclosed between `.F+' and `.F-' macros in your document.
The simplest 
@.I psfig
command is the word `figure', followed by the name of
a PostScript file. 
For example,
@.PP
	\.F+
@.br
	figure image.ps
@.br
	\.F-
@.PP
would include the figure in `image.ps' into your document as a centered
display.
@.I Psfig
uses bounding box information from the PostScript file to decide where
the figure is normally printed on the page, then performs the
appropriate translation to move the figure to the current spot
on the 
@.I ditroff
page.
The proper amount of space is reserved so that the figure doesn't
conflict with anything else on the page. Adding an `L' argument to
`.F+' would force the figure to be flush left.
@.PP
Several options may be specified on the `figure' command,
including `height' or `width' followed by a troff value, which
would shrink or enlarge the figure to the specified measurement. If either
a height and a width is specified, but not both, then the figure is scaled
equally so that the shape of the figure is maintained. For example
@.PP
	\.F+
@.br
	figure image.ps height 1i
@.br
	\.F-
@.PP
would include `image.ps' scaled so that it has a vertical edge of one inch.
@.PP
For 
@.I psfig
to properly scale and move a figure, it must be able to tell what 
it's natural size and position on the page are. This is usually specified by
the bounding box comment in the PostScript file. Unfortunately, some 
applications (including MacDraw) do not provide this information. 
In this case you can add the clause `bounds \fIllx lly urx ury\fP' to 
the figure command, manually specifying the bounding box of the figure.
The four coordinates are, respectively, the lower left \fIx\fP coordinate,
the lower left \fIy\fP coordinate, the upper right \fIx\fP coordinate, and
the upper right \fIy\fP coordinate of the figure's bounding box, all 
specified in points relative to an origin in the lower left corner of the
page.
@.SH "DRAFT MODE"
@.PP
If a figure is very expensive to print (say a 100K image) it can be set in
draft mode, printing just an outline box and the name of the file, for all
but the final version of the document. Each 
@.I psfig
figure has a level associated with it; the default is 10, but this may be
superseeded with a `level \fIn\fP' clause on the figure command.
@.I -d<level>
flag specifies the draft level for
@.I psfig
to run at. If the level of a figure exceeds the 
draft level, the figure is printed in draft mode (just an outline box.)
The default draft level is 100, and the default level of a figure is 10.
If just a 
@.I \-d
is specified with no level, zero is assumed.
In full draft mode,
@.I psfig
is quite flexible. Plain-vanilla 
@.I troff
(or even
@.IR nroff )
and any generic output device will suffice, so that you can write a paper
on a non-PostScript system in draft mode, then print the final copy on a 
PostScript system.
@.SH "SEE ALSO"
@.PP
ditroff(1), transcript(8), psdit(1)
@.br
N. Batchelder and T. Darrell,
@.ul
Psfig \- A New Ditroff Preprocessor
@.br

@//E*O*F trf/man/psfig.1//
chmod u=rw,g=r,o=r trf/man/psfig.1
 
echo mkdir - trf/patches
mkdir trf/patches
chmod u=rwx,g=rx,o=rx trf/patches
 
echo x - trf/patches/README
sed 's/^@//' > "trf/patches/README" <<'@//E*O*F trf/patches/README//'
ditroff.frag

This code fragment should be added to t10.c to allow \X to center properly.

The two lines marked should be added to the ptout0() fcn.

==================================================================


psdit.c.patch

This patch to psdit (from version 2 transcript) allows it to
accept the special commands generated by ditroff (which are used by psfig)

The fontheight change fixes a small bug in the way psdit handles explicit 
height changes from ditroff.

run:

% ed psdit.c.old < psdit.c.patch

ed should print out:
30767
32131
and psdit.c.new will be created.

The file psdit.c.frag contains these patches in contextual context

===========================================

psdit.pro.frag:

this shows the first n lines of the file psdit.pro, add everything between
the comment "%% Psfig additions" and "%% end XMOD additions"

=====

good luck



@//E*O*F trf/patches/README//
chmod u=rw,g=r,o=r trf/patches/README
 
echo x - trf/patches/ditroff.frag
sed 's/^@//' > "trf/patches/ditroff.frag" <<'@//E*O*F trf/patches/ditroff.frag//'
ptout0(pi)
tchar	*pi;
{
	register short j, k, w;
	short	z, dx, dy, dx2, dy2, n;
	register tchar	i;
	int outsize;	/* size of object being printed */

	outsize = 1;	/* default */
	i = *pi;
	k = cbits(i);
	if (ismot(i)) {
		j = absmot(i);
		if (isnmot(i))
			j = -j;
		if (isvmot(i))
			lead += j;
		else 
			esc += j;
		return(outsize);
	}
	if (k == XON) {
		int c;
		if (xfont != mfont)
			ptfont();
		if (xpts != mpts)
			ptps();
		if (lead)
			ptlead();
/* ADD these two lines	vvv */
		if (esc)
			ptesc();
/* 		 	^^^ */
		fdprintf(ptid, "x X ");
		for (j = 1; (c=cbits(pi[j])) != XOFF; j++)
			outascii(pi[j]);
		oput('\n');
		return j+1;
	}
			;

@//E*O*F trf/patches/ditroff.frag//
chmod u=rw,g=r,o=r trf/patches/ditroff.frag
 
echo x - trf/patches/psdit.c.frag
sed 's/^@//' > "trf/patches/psdit.c.frag" <<'@//E*O*F trf/patches/psdit.c.frag//'
#ifndef lint
static char Notice[] = "Copyright (c) 1984, 1985 Adobe Systems Incorporated";
static char *RCSID="$Header: psdit.c,v 2.1 85/11/24 11:50:41 shore Rel $";
#endif
# define XMOD
/* psdit.c
 *
 * Copyright (c) 1984, 1985 Adobe Systems Incorporated

@.
@.
@.
@.

private devcntrl(fp)	/* interpret device control functions */
FILE *fp;
{
    char    str[20], str1[50], buf[50];
    int     c, n, res, minh, minv;

    fscanf (fp, "%s", str);
    switch (str[0]) {		/* crude for now */
	case 'i': 		/* initialize */
	    fileinit ();
	    t_init ();
@.
@.
@.
@.
@.
	    break;
	case 'S': 		/* slant */
	    fscanf (fp, "%d", &n);
	    t_slant (n);
	    lastcmd = FNT;
	    break;
#ifdef XMOD
	case 'X': {		/* \X command from ditroff */
            int last;
	    char largebuf[128];
	    fscanf (fp, "%1s", str);
	    switch (str[0]) {
		case 'p' :
		    FlushShow(0);MoveTo();DoMove();
		    fgets(largebuf, sizeof(largebuf), fp);
		    last = strlen(largebuf) - 1;
		    if (last >= 0 && largebuf[last] == '\n') {
			ungetc('\n', fp);
			largebuf[last] = ' ';
		    }
		    fputs(largebuf, tf);
		    putc('\n', tf);
		    break;
		case 'f' :
		    FlushShow(0);MoveTo();DoMove();
		    if (fscanf(fp, "%s", largebuf) == 1) {
			char *nl = (char *) index(largebuf, '\n');
			if (nl) *nl = '\0';
			includefile(largebuf);
		    } else
			fprintf(stderr, "warning - include cmd w/o path.\n");
		    break;
	    }
	}
	break;
#endif
    }
    /* skip rest of input line */
    while ((c = getc (fp)) != '\n') {if (c == EOF) break;};
}

#ifdef XMOD
includefile(filenm)
char *filenm; {

	FILE *inf;
	int ch, c1, c2, firstch = 0;

	if (!(inf = fopen(filenm, "r"))) {
		fprintf(stderr, "psdit: fopen(%s): ", filenm);
		perror();
		exit(1);
	}
	c1 = fgetc(inf); c2 = fgetc(inf);
	if (c1 != '%' || c2 != '!')
		fprintf(stderr, "psdit: %s not a postscript file.\n", filenm),
		exit(1);

	fputs("%!", tf);
	while ((ch = fgetc(inf)) != EOF) {
		fputc(ch, tf);
		if (firstch && ch == '%') {
			/* we have to double leading '%'s */
			fputc('%', tf);
		}
		firstch = (ch == '\n');
	}			
	fclose(inf);
}
#endif
private fileinit()	/* read in font and code files, etc. */
{

@.
@.
@.
@.
@//E*O*F trf/patches/psdit.c.frag//
chmod u=rw,g=r,o=r trf/patches/psdit.c.frag
 
echo x - trf/patches/psdit.c.patch
sed 's/^@//' > "trf/patches/psdit.c.patch" <<'@//E*O*F trf/patches/psdit.c.patch//'
891a
#ifdef XMOD
	fontheight = n;
#endif
@.
592a
#ifdef XMOD
includefile(filenm)
char *filenm; {

	FILE *inf;
	int ch, c1, c2, firstch = 0;

	if (!(inf = fopen(filenm, "r"))) {
		fprintf(stderr, "psdit: fopen(%s): ", filenm);
		perror();
		exit(1);
	}
	c1 = fgetc(inf); c2 = fgetc(inf);
	if (c1 != '%' || c2 != '!')
		fprintf(stderr, "psdit: %s not a postscript file.\n", filenm),
		exit(1);

	fputs("%!", tf);
	while ((ch = fgetc(inf)) != EOF) {
		fputc(ch, tf);
		if (firstch && ch == '%') {
			/* we have to double leading '%'s */
			fputc('%', tf);
		}
		firstch = (ch == '\n');
	}			
	fclose(inf);
}
#endif
@.
587a
#ifdef XMOD
	case 'X': {		/* \X command from ditroff */
            int last;
	    char largebuf[128];
	    fscanf (fp, "%1s", str);
	    switch (str[0]) {
		case 'p' :
		    FlushShow(0);MoveTo();DoMove();
		    fgets(largebuf, sizeof(largebuf), fp);
		    last = strlen(largebuf) - 1;
		    if (last >= 0 && largebuf[last] == '\n') {
			ungetc('\n', fp);
			largebuf[last] = ' ';
		    }
		    fputs(largebuf, tf);
		    putc('\n', tf);
		    break;
		case 'f' :
		    FlushShow(0);MoveTo();DoMove();
		    if (fscanf(fp, "%s", largebuf) == 1) {
			char *nl = (char *) index(largebuf, '\n');
			if (nl) *nl = '\0';
			includefile(largebuf);
		    } else
			fprintf(stderr, "warning - include cmd w/o path.\n");
		    break;
	    }
	}
	break;
#endif
@.
4a
# define XMOD
@.
w psdit.c.new
q
@//E*O*F trf/patches/psdit.c.patch//
chmod u=rw,g=r,o=r trf/patches/psdit.c.patch
 
echo x - trf/patches/psdit.pro.frag
sed 's/^@//' > "trf/patches/psdit.pro.frag" <<'@//E*O*F trf/patches/psdit.pro.frag//'
% lib/psdit.pro -- prolog for psdit (ditroff) files
% Copyright (c) 1984, 1985 Adobe Systems Incorporated. All Rights Reserved.
% last edit: shore Sat Nov 23 20:28:03 1985
% RCSID: %Header: psdit.pro,v 2.1 85/11/24 12:19:43 shore Rel %
% Psfig RCSID $Header: psdit.pro,v 1.4 87/07/05 23:28:58 trevor Exp $

/$DITroff 180 dict def $DITroff begin

%% Psfig additions
/DocumentInitState [ matrix currentmatrix currentlinewidth currentlinecap
currentlinejoin currentdash currentgray currentmiterlimit ] cvx def

/startFig {
	/SavedState save def
	userdict maxlength dict begin
	currentpoint transform

	DocumentInitState setmiterlimit setgray setdash setlinejoin setlinecap
		setlinewidth setmatrix

	itransform moveto

	/ury exch def
	/urx exch def
	/lly exch def
	/llx exch def
	/y exch 72 mul resolution div def
	/x exch 72 mul resolution div def
	
	currentpoint /cy exch def /cx exch def

	/sx x urx llx sub div def 	% scaling for x
	/sy y ury lly sub div def	% scaling for y

	sx sy scale			% scale by (sx,sy)

	cx sx div llx sub
	cy sy div ury sub translate
	
	/DefFigCTM matrix currentmatrix def

	/initmatrix {
		DefFigCTM setmatrix
	} def
	/defaultmatrix {
		DefFigCTM exch copy
	} def

	/initgraphics {
		DocumentInitState setmiterlimit setgray setdash 
			setlinejoin setlinecap setlinewidth setmatrix
		DefFigCTM setmatrix
	} def

	/showpage {
		initgraphics
	} def

} def
% Args are llx lly urx ury (in figure coordinates)
/clipFig {
	currentpoint 6 2 roll
	newpath 4 copy
	4 2 roll moveto
	6 -1 roll exch lineto
	exch lineto
	exch lineto
	closepath clip
	newpath
	moveto
} def
% doclip, if called, will always be just after a `startfig'
/doclip { llx lly urx ury clipFig } def
/endFig {
	end SavedState restore
} def
/globalstart {
	% Push details about the enviornment on the stack.
	fontnum fontsize fontslant fontheight firstpage 
	mh my resolution slotno currentpoint 
	pagesave restore gsave 
} def
/globalend {
	grestore moveto
	/slotno exch def /resolution exch def /my exch def
	/mh exch def /firstpage exch def /fontheight exch def
	/fontslant exch def /fontsize exch def /fontnum exch def
	F
	/pagesave save def
} def

%% end XMOD additions

/fontnum 1 def /fontsize 10 def /fontheight 10 def /fontslant 0 def
/xi {0 72 11 mul translate 72 resolution div dup neg scale 0 0 moveto
  /fontnum 1 def /fontsize 10 def /fontheight 10 def /fontslant 0 def F
  /pagesave save def}def
/PB{save /psv exch def currentpoint translate 
  resolution 72 div dup neg scale 0 0 moveto}def
/PE{psv restore}def
@//E*O*F trf/patches/psdit.pro.frag//
chmod u=rw,g=r,o=r trf/patches/psdit.pro.frag
 
echo mkdir - trf/tst
mkdir trf/tst
chmod u=rwx,g=rx,o=rx trf/tst
 
echo x - trf/tst/Makefile
sed 's/^@//' > "trf/tst/Makefile" <<'@//E*O*F trf/tst/Makefile//'
Ditroff= /usr/local/ditroff -Tpsc
Psfig= ../src/psfig -D../doc/figs
Macs= ../lib/psfig.tmac
#
# A Modified psdit, of course. 
Psdit= /usr/bin/psdit  

test.ps: test.trf
	$(Psfig) test.trf | $(Ditroff) -ms $(Macs) - | $(Psdit) > test.ps
@//E*O*F trf/tst/Makefile//
chmod u=rw,g=r,o=r trf/tst/Makefile
 
echo x - trf/tst/test.trf
sed 's/^@//' > "trf/tst/test.trf" <<'@//E*O*F trf/tst/test.trf//'
@.TL
A Simple Document with Two Figures
@.SH
The rosette
@.PP
This document was created with 
@.I psfig ,
a preprocessor for
@.I troff
that allows the inclusion of PostScript figures. For instance here
we have a rosette, roughly 2 inches across:
@.F+ 
figure rosette.ps width 2i
delim $$
@.F-
The rosette was taken from the Adobe Systems Cookbook. 
@.SH
The Pretzel
@.PP
Our standard in-line figure, is a pretzel ($ pretzel.ps width 1.2n $). Now all
we need is a mustard character (just kidding).
@.PP

@//E*O*F trf/tst/test.trf//
chmod u=rw,g=r,o=r trf/tst/test.trf
 
echo Inspecting for damage in transit...
temp=/tmp/shar$$; dtemp=/tmp/.shar$$
trap "rm -f $temp $dtemp; exit" 0 1 2 3 15
cat > $temp <<\!!!
       7      28     196 README
      13      34     166 psfig.tmac
       9      44     300 README
      66     215    1548 cnote.txt
     130     704    3999 psfig.1
      41     122     870 README
      41     113     650 ditroff.frag
     107     325    2163 psdit.c.frag
      73     203    1406 psdit.c.patch
     100     395    2513 psdit.pro.frag
       9      30     236 Makefile
      23      86     493 test.trf
     619    2299   14540 total
!!!
wc  trf/lib/README trf/lib/psfig.tmac trf/man/README trf/man/cnote.txt trf/man/psfig.1 trf/patches/README trf/patches/ditroff.frag trf/patches/psdit.c.frag trf/patches/psdit.c.patch trf/patches/psdit.pro.frag trf/tst/Makefile trf/tst/test.trf | sed 's=[^ 
]*/==' | diff -b $temp - >$dtemp
if [ -s $dtemp ]
then echo "Ouch [diff of wc output]:" ; cat $dtemp
else echo "No problems found."
fi
exit 0;