Trailing-Edge
-
PDP-10 Archives
-
decuslib20-10
-
decus/20-189/lpscr.c
There are no other files named lpscr.c in the archive.
/*
* lpscript
*
* Convert plain text to postscript
* - Stephen Frede, UNSW, Australia
*
* Ported to UT Instructional VAXcluster 05-Feb-1986 by Mic Kaczmarczik
* This version also has conditional code for the Utah PCC-20 compiler
*
* Modifications:
*
* 05-Feb-1986 MPK
* + -c (copies) switch
* + -o (output) switch
* + -m (top margin) switch
* + change -o (offset) to -i (indent)
* + #ifdef VAXC for string.h because VAX C doesn't have it
*
* 14-Apr-86 MPK
* + fix bug in process() in case '\t' -- x was being
* incremented automatically inside while loop
* instead of when we really put a space out. This
* was screwing up tab stops.
* + add code to process() to handle backspace characters.
* this feature doesn't always produce wonderful output
* with proportional fonts, but it handles typical line-printer
* underlining and overstriking.
* + avoid putting lines more than 80 chars long in output file.
* The line on the Postscript page is unaffected by this, but
* it keeps print symbionts and other record-oriented things
* happy.
* + add -b switch (bottom margin).
*
* Bugs:
* + The margin settings need to be more uniform.
*/
#include <stdio.h>
#ifdef VAXC
char *strcat();
char *strncat();
int strcmp();
int strncmp();
char *strcpy();
char *strncpy();
int strlen();
char *index();
char *rindex();
#else
#include <string.h>
#endif
#define INCH 72.0 /* no. postscript units / inch */
#define CM 28.35 /* postscript units / cm */
#define PAGEOFFSET (1.0*CM)
#define TOPMARGIN (1.0*CM) /* top margin of page */
#define BOTTOMMARGIN (1.0*CM) /* bottom margin of page */
#define FONTSIZE 10.0 /* default font size (in points) */
#define TABSIZE 8
#define ROTATION 0.0 /* default orientation */
#define FONT "Courier"
#define NEW_PAGE 014 /* ^L forces a new page */
#define TRUE 1
#define FALSE 0
/* typedef char int; */
FILE *ostr;
char *usage[] = { "Valid lpscript options:",
"\t-b[bottommargin]",
"\t-c[copies]",
"\t-f[font]",
"\t-h[spacing]",
"\t-i[indent]",
"\t-m[topmargin]",
"\t-o[file]",
"\t-p[pitch]",
"\t-r[rotation]",
"\t-s[fontsize]",
"\t-t[tabsize]",
(char *) 0
};
int tabsize; /* in character positions */
main(argc, argv)
int argc;
char **argv;
{
int status = 0; /* exit status (no. errors occured) */
float pageoffset,
topmargin,
bottommargin,
fontsize,
linepitch,
spacing,
rotation,
copies,
atof();
char *fontname;
FILE *istr;
fontsize = FONTSIZE;
pageoffset = 0.0;
topmargin = 0.0;
bottommargin = 0.0;
spacing = 0.0;
tabsize = TABSIZE;
rotation = ROTATION;
fontname = FONT;
copies = 1.0;
ostr = stdout;
argv++; /* skip program name */
while(*argv && **argv == '-')
{
char c;
(*argv)++; /* skip the '-' */
c = **argv; /* option letter */
(*argv)++; /* skip option letter */
switch(c)
{
case 'b': /* bottom margin (MPK 12-Apr-86) */
if(**argv == '\0')
bottommargin = BOTTOMMARGIN;
else
bottommargin = atof(*argv) * CM;
break;
case 'c': /* copies (MPK 05-Feb-86) */
if(**argv == '\0')
copies = 2.0;
else
copies = atof(*argv);
break;
case 'f': /* font */
if(**argv == '\0')
fontname = "Times-Roman";
else
fontname = *argv;
break;
case 'h': /* horizontal spacing */
if(**argv == '\0')
spacing = 0.25;
else
spacing = atof(*argv);
break;
case 'i': /* indent */
if(**argv == '\0')
pageoffset = PAGEOFFSET;
else
pageoffset = atof(*argv) * CM;
break;
case 'm': /* top margin (MPK) */
if(**argv == '\0')
topmargin = TOPMARGIN;
else
topmargin = atof(*argv) *CM;
break;
case 'o': /* output file (MPK 05-Feb-86) */
if (**argv != '\0') /* -o -> stdout */
if ((ostr = fopen(*argv,"w")) == NULL) {
fprintf(stderr,"can't open output\n");
exit(1);
}
break;
case 'p': /* pitch (line spacing) */
linepitch = atof(*argv);
break;
case 'r': /* rotation */
if(**argv == '\0')
rotation = 90.0;
else
rotation = atof(*argv);
break;
case 's': /* font size */
if(**argv == '\0')
fontsize = 12.0;
else
fontsize = atof(*argv);
break;
case 't': /* tab size */
if(**argv == '\0')
tabsize = 4;
else
tabsize = (int) atof(*argv);
break;
default:
fprintf(stderr, "Unknown option: '%c'\n",
**argv);
status++;
break;
}
argv++;
}
if(status)
{
int i;
for (i = 0; usage[i]; i++)
fprintf(stderr, "%s\n", usage);
exit(status);
/* NOTREACHED */
}
if(linepitch == 0)
linepitch = fontsize + 2;
spacing *= fontsize;
init(fontsize, pageoffset, topmargin, bottommargin, linepitch,
rotation, copies, fontname, spacing);
if(! *argv)
process(stdin);
else while(*argv
#ifdef TOPS20
&& (**argv != '\0')
#endif
){
#ifdef TOPS20
if (**argv == '>') {
argv++;
continue;
}
#endif
if((istr = fopen(*argv, "r")) == NULL)
{
perror(*argv);
status++;
}
else
{
process(istr);
fclose(istr);
}
argv++;
}
putc('\004', ostr);
#ifndef VAXC
exit(status);
#endif
}
process(istr)
FILE *istr;
{
register char ch;
register int x; /* used for tab calculations */
register int ll; /* keep track of output line length */
x = ll = 0;
putc('(', ostr);
while((ch=getc(istr)) != EOF)
{
if(ch == '\b' && (x > 0)) /* MPK 14-Apr-86 */
{
x--;
ll += 4;
fprintf(ostr, ")b (");
}
else if(ch == '\t')
{
int n = x + tabsize - (x % tabsize);
while(x < n) {
pch(' ');
x++;
ll++;
}
}
else if(ch == '\n')
{
x = ll = 0;
fprintf(ostr, ") n\n");
putc('(', ostr);
}
else if(ch == '\r')
{
x = ll = 0;
fprintf(ostr, ") r\n");
putc('(', ostr);
}
else if(ch == NEW_PAGE)
{
x = ll = 0;
fprintf(ostr, ") n p\n");
putc('(', ostr);
}
/* default case. Avoid NULs and output line length problems */
else if (ch != '\0')
{
pch(ch);
x++;
if (++ll > 80) { /* output line getting long - split */
fprintf(ostr,") showstring\n");
putc('(', ostr);
ll = 0;
}
}
}
fprintf(ostr, ") n p\n\f");
}
char *inittab[] = {
/* show a string with appropriate spacing */
"/showstring { spacing 0 3 -1 roll ashow } def",
/* print a page and start a new one */
"/p",
/* print out as many copies as desired */
"{ 1 1 copies { copypage pop } for\n",
/* Erase the page and start over, saving graphics state */
" erasepage newpath 0 pgtop moveto } def",
"/n",
/* show the string given as an arg */
"{ showstring",
/* now move down a line; linepitch is -'ve */
" 0 linepitch rmoveto",
/* save the new y posn */
" /y currentpoint exch pop def",
/* test if the next line would be below the bottom margin */
" y bottommargin lt",
/* if so, print the page, and move to the top of a new page */
" { p }",
/* else go to where the next line is due to start */
" { 0 y moveto } ifelse",
"} def",
"/r",
/* show the string given as an arg */
"{ showstring",
/* save y */
" /y currentpoint exch pop def",
/* and then move to the beginning of the current line */
" 0 y moveto",
"} def",
/* implement a backspace operation -- show the string so far, */
/* then back up to beginning of last character */
"/b",
" { dup () eq",
/* fake a space if there's nothing there. */
" { pop ( ) stringwidth pop neg 0 rmoveto }",
/* otherwise, extract last character in string and save it */
" { dup dup length 1 sub 1 getinterval exch",
/* draw the string */
" showstring",
/* move back by width of last character */
" stringwidth pop neg 0 rmoveto",
" } ifelse",
" } def",
(char *)0 };
init(fontsize, pageoffset, topmargin, bottommargin, linepitch,
rotation, copies, fontname, spacing)
float fontsize,
pageoffset,
topmargin,
bottommargin,
linepitch,
spacing,
rotation,
copies;
char *fontname;
{
register char **p;
fprintf(ostr, "\004\n");
p = inittab;
while(*p)
fprintf(ostr, "%s\n", *p++);
fprintf(ostr, "/copies %d def\n",(int) copies); /* MPK 05-Feb-86 */
fprintf(ostr, "/%s findfont %.1f scalefont setfont\n",
fontname, fontsize);
fprintf(ostr, "/linepitch %.1f def\n", -linepitch);
fprintf(ostr, "/spacing %.1f def\n", spacing);
/* apply rotation transformation, if any */
if(rotation != 0.0)
fprintf(ostr, "%.1f rotate\n", rotation);
/* get current imageable area */
fprintf(ostr, "clippath pathbbox\n");
/* save the upper right y coordinate */
fprintf(ostr, "/pgtop exch def\n");
/* save lower left y; translate origin to lower left */
fprintf(ostr, "pop /y exch def y translate\n");
/* subtract old lower left from upper right to get top of page */
/* then subtract linespacing (add -'ve) to get top text row */
fprintf(ostr, "/pgtop pgtop y sub linepitch add def\n");
/* apply horizontal offset, if any */
/* unfortunately, a slight fudge factor is required here */
fprintf(ostr, "%.1f 0 translate\n", pageoffset + 4);
/* apply top margin, if any */
fprintf(ostr, "/pgtop pgtop %.1f sub def\n", topmargin);
/* set up bottom margin, if any */
fprintf(ostr, "/bottommargin %.1f def\n",bottommargin);
/* move to top of page, ready to start printing */
fprintf(ostr, "newpath 0 pgtop moveto\n");
}
pch(ch)
int ch;
{
if(ch < ' ' || ch > '~')
fprintf(ostr, "\\%03.3o", ch);
else
{
if(ch == '(' || ch == ')' || ch == '\\')
putc('\\', ostr);
putc(ch, ostr);
}
}