[net.text] pltroff

rick@rochester.UUCP (Rick Floyd) (08/31/85)

A few months ago, I asked if anyone knew of a program to convert plot to
press. I got one positive response (thanks, Lee) suggesting that I look
at pltroff, a plot to troff filter. Pltroff is included in the Bell
ditroff release (in the pic directory). Unfortunately, pltroff doesn't
work as distributed. Here are diffs to correct enough of the problems to
make it run.

I've also added code that supports additional options (-D, -Tpress),
allows different line styles for the 'n' plot command and attempts to
make dotted and dashed lines look a little better. Compile with "-DUR" to
enable this code.

As a special no cost benefit, I've included a brief manual page.

	rick floyd
	rick@rochester.ARPA
	seismo!rochester!rick


-------------------- cut here --------------------
#!/bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #!/bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	driver.diff
#	pltroff.diff
#	pltroff.1g
# This archive created: Sat Aug 31 04:48:37 1985
export PATH; PATH=/bin:$PATH
if test -f 'driver.diff'
then
	echo shar: over-writing existing file "'driver.diff'"
fi
cat << \SHAR_EOF > 'driver.diff'
RCS file: RCS/driver.c,v
retrieving revision 1.1
diff -c2 -r1.1 driver.c
*** /tmp/,RCSt1029773	Sat Aug 31 04:42:00 1985
--- driver.c	Sat Aug 31 04:41:01 1985
***************
*** 1,2
  #include <stdio.h>
  #include <ctype.h>

--- 1,15 -----
+ /* HISTORY
+  * 12-May-85 rick at University of Rochester
+  *	Add DEVPRESS. Add globals DX and DY (for pltroff). Convert most
+  *	variables to float, since pltroff.c demands these (couldn't ever have
+  *	worked like this!). Add option ("-D") to use line drawing commands. 
+  *	Allow different lines styles for continued lines ('n' plot command). 
+  *	Fix some bugs in dotline, and use "label" to lay down the dots (this
+  *	last gives us much better placement of dotted lines (after tweeking
+  *	hshift and vshift) but may break other things - better would
+  *	be to draw the dots directly instead of using a character like
+  *	pltroff.c does).
+  */
+ 
  #include <stdio.h>
  #include <ctype.h>
***************
*** 6,10
  #define	DEVCAT	3
  #define	DEV450	4
! int	devtype	= DEV202;
  
  float	deltx;	/* max x value in output, for scaling */

--- 19,24 -----
  #define	DEVCAT	3
  #define	DEV450	4
! #ifdef UR
! #define DEVPRESS 6
  
  extern int useDline;
***************
*** 8,11
  int	devtype	= DEV202;
  
  float	deltx;	/* max x value in output, for scaling */
  float	delty;	/* max y value in output, for scaling */

--- 22,28 -----
  #define DEVPRESS 6
  
+ extern int useDline;
+ #endif UR
+ 
  float	deltx;	/* max x value in output, for scaling */
  float	delty;	/* max y value in output, for scaling */
***************
*** 11,15
  float	delty;	/* max y value in output, for scaling */
  int	dbg	= 0;
- int	res	= 972;	/* 202 is default */
  FILE	*fin;	/* input file pointer */
  char	*cmdname;

--- 28,31 -----
  float	delty;	/* max y value in output, for scaling */
  int	dbg	= 0;
  FILE	*fin;	/* input file pointer */
  char	*cmdname;
***************
*** 15,18
  char	*cmdname;
  int	crop	= 1;	/* trim off exterior white space if non-zero */
  float	hshift	= 0.3;	/* move this far left for text (in em's) */
  float	vshift	= 0.3;	/* this far down */

--- 31,38 -----
  char	*cmdname;
  int	crop	= 1;	/* trim off exterior white space if non-zero */
+ #ifdef UR
+ float	hshift	= 0.12;	/* move this far left for text (in em's) */
+ float	vshift	= 0.03;	/* this far down */
+ #else
  float	hshift	= 0.3;	/* move this far left for text (in em's) */
  float	vshift	= 0.3;	/* this far down */
***************
*** 17,21
  float	hshift	= 0.3;	/* move this far left for text (in em's) */
  float	vshift	= 0.3;	/* this far down */
! 			/* these values are suitable for circuit diagrams */
  int	linetype	= 's';	/* solid is normal */
  

--- 37,43 -----
  float	hshift	= 0.3;	/* move this far left for text (in em's) */
  float	vshift	= 0.3;	/* this far down */
! 		/* these values are suitable for circuit diagrams */
! #endif UR
! 
  int	linetype	= 's';	/* solid is normal */
  
***************
*** 20,23
  int	linetype	= 's';	/* solid is normal */
  
  char	buf[20000];
  char	*bp	= buf;

--- 42,49 -----
  int	linetype	= 's';	/* solid is normal */
  
+ int	devtype	= DEV202;
+ int	res	= 972;	/* 202 is default */
+ int	DX	= 4;
+ int	DY	= 4;
  char	buf[20000];
  char	*bp	= buf;
***************
*** 23,34
  char	*bp	= buf;
  
! int	sxmin;		/* lower limit from s command */
! int	symin;
! int	sxmax	= 4096;	/* upper */
! int	symax	= 4096;
! int	xmin	= 30000;	/* min values found in actual data */
! int	ymin	= 30000;
! int	xmax	= -30000;	/* max */
! int	ymax	= -30000;
  
  main(argc,argv)

--- 49,60 -----
  char	*bp	= buf;
  
! float	sxmin;		/* lower limit from s command */
! float	symin;
! float	sxmax	= 4096;	/* upper */
! float	symax	= 4096;
! float	xmin	= 30000;	/* min values found in actual data */
! float	ymin	= 30000;
! float	xmax	= -30000;	/* max */
! float	ymax	= -30000;
  
  main(argc,argv)
***************
*** 41,44
  	while (argc > 1 && *argv[1] == '-') {
  		switch (c = argv[1][1]) {
  		case 'T':
  			if (strcmp(&argv[1][2], "aps") == 0) {

--- 67,75 -----
  	while (argc > 1 && *argv[1] == '-') {
  		switch (c = argv[1][1]) {
+ #ifdef UR
+ 		case 'D':
+ 		    useDline = 1;
+ 		    break;
+ #endif UR
  		case 'T':
  			if (strcmp(&argv[1][2], "aps") == 0) {
***************
*** 48,51
  				res = 432;
  				devtype = DEVCAT;
  			}
  			break;

--- 79,88 -----
  				res = 432;
  				devtype = DEVCAT;
+ #ifdef UR
+ 			} else if (strcmp(&argv[1][2], "press") == 0) {
+ 				res = 2540;
+ 				devtype = DEVPRESS;
+ 				DX = DY = 1;
+ #endif UR
  			}
  			break;
***************
*** 139,144
  			break;	/* BUG -- ignoring this because it overrides -c */
  			ctobuf('s');
! 			xytobuf(sxmin, symin);
! 			xytobuf(sxmax, symax);
  			break;
  		case 's':

--- 176,181 -----
  			break;	/* BUG -- ignoring this because it overrides -c */
  			ctobuf('s');
! 			xytobuf((int) sxmin, (int) symin);
! 			xytobuf((int) sxmax, (int) symax);
  			break;
  		case 's':
***************
*** 149,154
  			break;	/* BUG -- ignoring this because it overrides -c */
  			ctobuf(c);
! 			xytobuf(sxmin, symin);
! 			xytobuf(sxmax, symax);
  			break;
  		case 'T':

--- 186,191 -----
  			break;	/* BUG -- ignoring this because it overrides -c */
  			ctobuf(c);
! 			xytobuf((int) sxmin, (int) symin);
! 			xytobuf((int) sxmax, (int) symax);
  			break;
  		case 'T':
***************
*** 278,282
  {
  	char s[100], *p;
! 	int x, y, x1, y1, x2, y2, r, c;
  
  	openpl("\n");	/* outputs .PS\n */

--- 315,319 -----
  {
  	char s[100], *p;
! 	float x, y, x1, y1, x2, y2, r;
  
  	openpl("\n");	/* outputs .PS\n */
***************
*** 282,286
  	openpl("\n");	/* outputs .PS\n */
  	for (bp = buf; *bp; ) {
! 		switch (c = *bp++) {
  		case 'm':
  			x = getbuf();

--- 319,323 -----
  	openpl("\n");	/* outputs .PS\n */
  	for (bp = buf; *bp; ) {
! 		switch (*bp++) {
  		case 'm':
  			x = getbuf();
***************
*** 317,321
  			x = getbuf();
  			y = getbuf();
! 			cont(x, y);
  			break;
  		case 's':

--- 354,366 -----
  			x = getbuf();
  			y = getbuf();
! #ifdef UR
! 			if (linetype != 's')
! 			{
! 			    current_xy(&x1, &y1);
! 			    dotline(x1, y1, x, y, linetype);
! 			}
! 			else
! #endif UR
! 			    cont(x, y);
  			break;
  		case 's':
***************
*** 356,360
  
  dotline(x0, y0, x1, y1, type) /* dotted or dashed line */
! int x0, y0, x1, y1;
  int type;
  {

--- 401,405 -----
  
  dotline(x0, y0, x1, y1, type) /* dotted or dashed line */
! float x0, y0, x1, y1;
  int type;
  {
***************
*** 359,363
  int type;
  {
! 	int prevval = 10;
  	int i, numdots;
  	double a, b, sqrt(), dx, dy;

--- 404,412 -----
  int type;
  {
! #ifdef UR
! 	int prevval = 16, dotval = 25;  /* tuned for local printer */
! #else
!  	int prevval = 10;
! #endif UR
  	int i, numdots;
  	double a, b, sqrt(), dx, dy;
***************
*** 366,370
  	dy = y1 - y0;
  	if (type == '.') {
! 		numdots = sqrt(dx*dx + dy*dy) / prevval + 0.5;
  		for (i = 0; i <= numdots; i++) {
  			a = (float) i / (float) numdots;

--- 415,427 -----
  	dy = y1 - y0;
  	if (type == '.') {
! #ifdef UR
! 		numdots = sqrt(dx*dx + dy*dy) / dotval + 0.5;
! #else
!  		numdots = sqrt(dx*dx + dy*dy) / prevval + 0.5;
! #endif UR
! 		if (numdots == 0) {
! 		    line(x0, y0, x1, y1);
! 		    return;
! 		}
  		for (i = 0; i <= numdots; i++) {
  			a = (float) i / (float) numdots;
***************
*** 369,373
  		for (i = 0; i <= numdots; i++) {
  			a = (float) i / (float) numdots;
! 			move(x0 + (int)(a * dx), y0 + (int)(a * dy));
  			dot();
  		}

--- 426,433 -----
  		for (i = 0; i <= numdots; i++) {
  			a = (float) i / (float) numdots;
! 			move(x0 + a * dx, y0 + a * dy);
! #ifdef UR
! 			label(".", 'L', 0);
! #else
  			dot();
  #endif UR
***************
*** 371,374
  			move(x0 + (int)(a * dx), y0 + (int)(a * dy));
  			dot();
  		}
  	} else {	/* all others */

--- 431,435 -----
  #else
  			dot();
+ #endif UR
  		}
  	} else {	/* all others */
***************
*** 375,378
  		double d, dashsize, spacesize;
  		d = sqrt(dx*dx + dy*dy) + 0.5;
  		if (d <= 2 * prevval) {
  			line(x0, y0, x1, y1);

--- 436,443 -----
  		double d, dashsize, spacesize;
  		d = sqrt(dx*dx + dy*dy) + 0.5;
+ #ifdef UR
+ 		if (type == '_')
+ 		    prevval = prevval * 1.8; /* longdashed (crude, I know) */
+ #endif UR
  		if (d <= 2 * prevval) {
  			line(x0, y0, x1, y1);
***************
*** 385,389
  			a = i * (dashsize + spacesize) / d;
  			b = a + dashsize / d;
! 			line(x0 + (int)(a*dx), y0 + (int)(a*dy), x0 + (int)(b*dx), y0 + (int)(b*dy));
  			a = b;
  			b = a + spacesize / d;

--- 450,454 -----
  			a = i * (dashsize + spacesize) / d;
  			b = a + dashsize / d;
! 			line(x0 + a*dx, y0 + a*dy, x0 + b*dx, y0 + b*dy);
  			a = b;
  			b = a + spacesize / d;
***************
*** 388,392
  			a = b;
  			b = a + spacesize / d;
! 			move(x0 + (int)(a*dx), y0 + (int)(a*dy));
  		}
  		line(x0 + (int)(b * dx), y0 + (int)(b * dy), x1, y1);

--- 453,457 -----
  			a = b;
  			b = a + spacesize / d;
! 			move(x0 + a*dx, y0 + a*dy);
  		}
  		line(x0 + b * dx, y0 + b * dy, x1, y1);
***************
*** 390,394
  			move(x0 + (int)(a*dx), y0 + (int)(a*dy));
  		}
! 		line(x0 + (int)(b * dx), y0 + (int)(b * dy), x1, y1);
  	}
  }

--- 455,459 -----
  			move(x0 + a*dx, y0 + a*dy);
  		}
! 		line(x0 + b * dx, y0 + b * dy, x1, y1);
  	}
  }
SHAR_EOF
if test -f 'pltroff.diff'
then
	echo shar: over-writing existing file "'pltroff.diff'"
fi
cat << \SHAR_EOF > 'pltroff.diff'
RCS file: RCS/pltroff.c,v
retrieving revision 1.1
diff -c2 -r1.1 pltroff.c
*** /tmp/,RCSt1029789	Sat Aug 31 04:44:39 1985
--- pltroff.c	Sat Aug 31 04:40:41 1985
***************
*** 1,2
  /*
   *	This version has code generators to drive the old-style troff

--- 1,3 -----
+ /*LINTLIBRARY*/
  /*
   * HISTORY
***************
*** 1,3
  /*
   *	This version has code generators to drive the old-style troff
   *	that produces output for the Graphic Systems C/A/T.  

--- 1,15 -----
  /*LINTLIBRARY*/
  /*
+  * HISTORY
+  * 12-May-85  rick at University of Rochester
+  *	Add function to return current xy position (used by driver.c to
+  *	do different lines styles on continued lines).
+  *
+  * 26-Apr-84  lee at University of Rochester
+  *	Fixed a bug where the code assumed that the maximum internal movement
+  *	troff allows is 2^13.  That figure was true for old troff but was
+  *	increased to 2^15 in to-troff.
+  *
+  *
   *	This version has code generators to drive the old-style troff
   *	that produces output for the Graphic Systems C/A/T.  
***************
*** 106,109
  	printf(".PS %d %d %s", yconv(ymin), xconv(xmax), s);
  		/* assumes \n comes as part of s */
  	if (xconv(xmax) >= 8192 || yconv(ymax) >= 8192) {	/* internal troff limit: 13 bits for motion */
  		fprintf(stderr, "picture too high or wide");

--- 118,125 -----
  	printf(".PS %d %d %s", yconv(ymin), xconv(xmax), s);
  		/* assumes \n comes as part of s */
+ #ifdef UR
+ 	/* ti-troff uses 15 bits to describe motion! (not 13) */
+ 	if (xconv(xmax) >= 32768 || yconv(ymax) >= 32768) {	/* internal troff limit: 15 bits for motion */
+ #else
  	if (xconv(xmax) >= 8192 || yconv(ymax) >= 8192) {	/* internal troff limit: 13 bits for motion */
  #endif UR
***************
*** 107,110
  		/* assumes \n comes as part of s */
  	if (xconv(xmax) >= 8192 || yconv(ymax) >= 8192) {	/* internal troff limit: 13 bits for motion */
  		fprintf(stderr, "picture too high or wide");
  		exit(1);

--- 123,127 -----
  #else
  	if (xconv(xmax) >= 8192 || yconv(ymax) >= 8192) {	/* internal troff limit: 13 bits for motion */
+ #endif UR
  		fprintf(stderr, "picture too high or wide");
  		exit(1);
***************
*** 368,371
  }
  
  arc(x, y, x0, y0, x1, y1, r)	/* draw arc with center x,y */
  	float x, y, x0, y0, x1, y1, r;

--- 385,389 -----
  }
  
+ /*VARARGS6*/
  arc(x, y, x0, y0, x1, y1, r)	/* draw arc with center x,y */
  	float x, y, x0, y0, x1, y1, r;
***************
*** 467,470
  }
  
  linemod(s)
  	char *s;

--- 485,504 -----
  }
  
+ #ifdef UR
+ 
+ current_xy(x, y)  /* return current values of x and y (from hpos, vpos) */
+ 
+ float *x, *y;
+ {
+     *x = X0 + (hpos - 0.5)/xscale;
+     *y = ymax + (vpos - 0.5)/yscale;
+     if (OLDSTYLE)	/* not checked. */
+     {
+ 	*x += (1-DX)/xscale;
+         *y += (1-DY)/yscale;
+     }
+ }
+ #endif UR
+ 
  linemod(s)
  	char *s;
***************
*** 946,947
  	return x * dx;
  }

--- 980,982 -----
  	return x * dx;
  }
+ #endif
SHAR_EOF
if test -f 'pltroff.1g'
then
	echo shar: over-writing existing file "'pltroff.1g'"
fi
cat << \SHAR_EOF > 'pltroff.1g'
.TH PLTROFF 1G local "29 August 1985"
.UC 4
.SH NAME
pltroff \- convert plot to troff
.SH SYNOPSIS
.B pltroff
[ options ] 
.SH DESCRIPTION
.I Pltroff 
reads plotting instructions (see
plot(5))
from the standard input and generates the corresponding 
troff commands on standard output.
.PP
The following options are available:
.TP
.B \-D
Output explicit line drawing commands  
(instead of individual characters) when drawing lines. 
This generally gives much better
results on devices that support the commands.
.TP
.B \-T
Specify the intended plotting device. Currently recognized devices
include: 
.I press, aps 
and
.I cat.
The default is the Mergenthaler Linotron 202.
.TP
.B \-c
Normally 
.I pltroff
crops exterior white space in a picture.
If
.B \-c
is given, this is not done.
.TP
.B \-l "length"
Specifies the length of the plot. The default is 6 inches. If this option
is given, 
.B \-w 
must also be given.
.TP
.B \-w "width"
Specifies the width of the plot. The default is 6 inches. If this option
is given, 
.B \-l 
must also be given.
.TP
.B \-s "size"
Sets the size of the plot to 
.I size
by
.I size
inches. The default is 6 by 6.
.SH EXAMPLE
To generate 
troff commands, scaled for
a press printer, that graph an array of points:
.sp
	graph < array | pltroff -D -Tpress
.SH "SEE ALSO"
plot(1), plot(3), plot(5), ptroff(1), pic(1), graph(1)
.SH BUGS
.I Pltroff
will fail on very large input files.
.PP
The character '.' is used for dotted lines. The placement may be less
than optimal if the default font is changed.
.PP
.I Pltroff
only recognizes requests for "solid", "dotted", "dashed" and "longdashed"
lines. Other requests are converted to "dashed".
SHAR_EOF
#	End of shell archive
exit 0