home *** CD-ROM | disk | FTP | other *** search
- /*
- pstext 1.3
- by Dan Judd
- St. Olaf College
- 11/29/89
-
- updated with several minor bug fixes 12/14/90 Dan Judd
- added -v flag and -x[rlp] and -y[tbp] flags 2/26/91 Dan Judd
- added -T flag 6/24/91 Dan Judd
-
- This program takes plain ascii text and converts it to Postscript.
- It takes a few options.
- [-p ] prints portrait mode 1 page (default)
- [-l ] prints landscape mode 1 page
- [-ld ] dual landscape mode 2 pages per page
- [-d ] dual portrait mode, prints 2 pages per page
- [-n number] number of lines per page
- [-t tabstring ] use a different tabstring size (00000000 default)
- [-f fontname ] use a different font (Courier default)
- [-s pointsize ] use a different point size (12 default)
- [-i pointoffset ] offset pointoffset points from normal (0 default)
- [-cy] turn font checking on (default)
- [-c] turn font checking on
- [-cn] turn font checking off
- [-x value] set x left margin to value
- [-xl value] set x left margin to value (18 default)
- [-xr value] set x right margin to value (14 default)
- [-xp value] set x page size to value (612 default)
- [-y value] set y top margin to value
- [-yt value] set y top margin to value (8 default)
- [-yb value] set y bottom margin to value (13 default)
- [-yp value] set y page size to value (792 default)
- [-v] print version and quit
- [-T printertype ] set defaults for printertype later flags modify this
-
- Margin values are based on 8 1/2 X 11 inch paper from an Apple
- LaserWriter other printers may vary. To change defaults see
- defines below.
-
- It handles tabs and backspaces in an intelligent way in any font.
-
- Copyright Dan Judd 1989
- This program is freely redistributable, but may not be sold.
- send bug fixes to danjudd@cps.msu.edu
- */
-
- #include <stdio.h>
- #include <strings.h>
- #include <ctype.h>
- #define TRUE 1
- #define FALSE 0
- #define DFLT_PTSIZE 12
- #define DFLT_FONT "Courier"
- #define DFLT_TABSTRING "00000000"
- #define INDENT 0
- #define DFLT_STYLE 1
- #define DFLT_LINES 0
- #define CHECKFONT TRUE
- #define XRMARGIN 14
- #define XLMARGIN 18
- #define XPAGE 612
- #define YPAGE 792
- #define YTMARGIN 8
- #define YBMARGIN 13
-
- static char version[] = "pstext version 1.3";
-
- /*
- getfile(fpin,fpout)
- FILE *fpin,fpout;
- Read in text from a file and output appropriate postscript
- */
- int getfile(fpin,fpout)
- FILE *fpin,*fpout;
- {
- int ch;
-
- fprintf(fpout,"(");
- while ((ch = getc(fpin))!=EOF) {
- if(isprint(ch)) {
- switch (ch ) {
- case '(':
- case ')':
- case '\\':
- fprintf(fpout,"\\%c",ch);
- break;
- default: fprintf(fpout,"%c",ch);
- break;
- }
- }
- else {
- switch (ch ) {
- case '\n': fprintf(fpout,")s\n(");
- break;
- case '\t': fprintf(fpout,")S\nht (");
- break;
- case '\b': fprintf(fpout,")S\nbs(");
- break;
- case '\r': fprintf(fpout,")S\ncr(");
- break;
- case '\f': fprintf(fpout,")S\nnp(");
- break;
- default:
- break;
- }
- }
- }
- /* send trailer */
- fprintf(fpout,")s\nnp\n");
- return(0);
- }
- /*
- Prints the header of Postscript commands that define
- the various procedures used. Yes it takes a lot of arguements,
- yes that makes it ugly, but is it uglier than using globals?
- I think not.
- */
- int printhead(fp,font,size,style,numlines,tabstring,indent,checkfont,
- xrmargin, xlmargin,xpage,ypage,ytmargin,ybmargin,version)
- FILE *fp;
- char *font;
- double size;
- int style;
- int numlines;
- char *tabstring;
- int indent;
- int checkfont;
- int xrmargin;
- int xlmargin;
- int xpage;
- int ypage;
- int ytmargin;
- int ybmargin;
- char *version;
- {
- fprintf(fp,"%%! PS - Adobe\n");
- fprintf(fp,"%% Created by %s by Dan Judd\n",version);
- fprintf(fp,"/PAGE_STYLE %d def\n",style);
- fprintf(fp,"/NUM_LINES %d def\n",numlines);
- fprintf(fp,"/FONT (%s) cvn def\n",font);
- fprintf(fp,"/FONT_SIZE %lf def\n",size);
- fprintf(fp,"%%check if font exists\n");
-
- /* this is vaguely device depenent, FontDirectory is standard, but */
- /* the Next uses SharedFontDirectory instead. The program won't crash,*/
- /* but the only font you can use is Courier. Blech. */
- /* if this is a problem just define CHECKFONT as FALSE early in the program*/
- if (checkfont) {
- fprintf(fp,"FontDirectory FONT known not { /FONT (Courier) cvn def} if\n");
- }
- fprintf(fp,"%%misc hardware defs\n");
- if (style > 2) {
- fprintf(fp,"/XLMARGIN %d def\n",xlmargin);
- }
- else
- {
- fprintf(fp,"/XLMARGIN %d def\n",(indent + xlmargin));
- }
- fprintf(fp,"/XRMARGIN %d def\n",xrmargin);
- fprintf(fp,"/XPAGE %d def\n",xpage);
- fprintf(fp,"/YPAGE %d def\n",ypage);
- fprintf(fp,"/YTMARGIN %d def\n",ytmargin);
- if (style < 3) {
- fprintf(fp,"/YBMARGIN %d def\n",ybmargin);
- }
- else
- {
- fprintf(fp,"/YBMARGIN %d def\n",(indent + ybmargin));
- }
- fprintf(fp,"/PAGENUM 1 def\n");
- fprintf(fp,"%%\n");
- fprintf(fp,"%%short defs to save space\n");
- fprintf(fp,"%%\n");
- fprintf(fp,"/bd {bind def} bind def\n");
- fprintf(fp,"/m {moveto} bd\n");
- fprintf(fp,"/l {lineto}bd\n");
- fprintf(fp,"/gs {gsave}bd\n");
- fprintf(fp,"/gr {grestore}bd\n");
- fprintf(fp,"/tr {translate} bd\n");
- fprintf(fp,"/rt {rotate} bd\n");
- fprintf(fp,"%%\n");
- fprintf(fp,"%%Set up vars and np depending on PAGE_STYLE\n");
- fprintf(fp,"%%\n");
- fprintf(fp,"%% Style 1\n");
- fprintf(fp,"1 PAGE_STYLE eq {\n");
- fprintf(fp," /PAGES_PER_SHEET 1 def\n");
- fprintf(fp," /sp {/SAVEOBJ save def} def\n");
- fprintf(fp," /np { showpage SAVEOBJ restore sp bp } bd\n");
- fprintf(fp," } if\n");
- fprintf(fp,"%% Style 2\n");
- fprintf(fp,"2 PAGE_STYLE eq {\n");
- fprintf(fp," /PAGES_PER_SHEET 2 def\n");
- fprintf(fp," /sp {/SAVEOBJ save def gs XPAGE 2 div dup 0 m YPAGE l stroke\n");
- fprintf(fp," newpath 0 0 m 0 YPAGE l XPAGE 2 div XRMARGIN sub dup\n");
- fprintf(fp," YPAGE l 0 l 0 0 l clip\n");
- fprintf(fp," } bd\n");
- fprintf(fp," /np { /PAGENUM 1 PAGENUM add def\n");
- fprintf(fp," PAGENUM PAGES_PER_SHEET\n");
- fprintf(fp," gt {gr showpage SAVEOBJ restore sp /PAGENUM 1 def }\n");
- fprintf(fp," {gr gs XPAGE 2 div 0 tr} ifelse\n");
- fprintf(fp," bp\n");
- fprintf(fp," } bd\n");
- fprintf(fp," } if\n");
- fprintf(fp,"%% Style 3\n");
- fprintf(fp,"3 PAGE_STYLE eq {\n");
- /* define if you want double page landscape mode to have fonts */
- /* proportional to single page portrait */
- #ifdef LANDPROP
- fprintf(fp," /FONT_SIZE FONT_SIZE .642 mul def\n");
- #endif
- fprintf(fp," /TMP XPAGE def\n");
- fprintf(fp," /XPAGE YPAGE def\n");
- fprintf(fp," /YPAGE TMP def\n");
- fprintf(fp," /TMP XRMARGIN def\n");
- fprintf(fp," /XRMARGIN YTMARGIN def\n");
- fprintf(fp," /YTMARGIN TMP def\n");
- fprintf(fp," /TMP XLMARGIN def\n");
- fprintf(fp," /XLMARGIN YBMARGIN def\n");
- fprintf(fp," /YBMARGIN TMP def\n");
- fprintf(fp," /PAGES_PER_SHEET 2 def\n");
- fprintf(fp," /sp {/SAVEOBJ save def gs 0 XPAGE tr -90 rt\n");
- fprintf(fp," XPAGE 2 div dup 0 moveto YPAGE l stroke\n");
- fprintf(fp," newpath 0 0 m 0 YPAGE l XPAGE 2 div XRMARGIN sub dup\n");
- fprintf(fp," YPAGE l 0 l 0 0 l clip\n");
- fprintf(fp," } bd\n");
- fprintf(fp," /np { /PAGENUM 1 PAGENUM add def\n");
- fprintf(fp," PAGENUM PAGES_PER_SHEET\n");
- fprintf(fp," gt {gr showpage SAVEOBJ restore sp /PAGENUM 1 def }\n");
- fprintf(fp," {gr gs 0 XPAGE 2 div tr -90 rt } ifelse\n");
- fprintf(fp," bp\n");
- fprintf(fp," } bd\n");
- fprintf(fp," } if\n");
- fprintf(fp,"%% Style 4\n");
- fprintf(fp,"4 PAGE_STYLE eq {\n");
- fprintf(fp," /TMP XPAGE def\n");
- fprintf(fp," /XPAGE YPAGE def\n");
- fprintf(fp," /YPAGE TMP def\n");
- fprintf(fp," /TMP XRMARGIN def\n");
- fprintf(fp," /XRMARGIN YTMARGIN def\n");
- fprintf(fp," /YTMARGIN TMP def\n");
- fprintf(fp," /TMP XLMARGIN def\n");
- fprintf(fp," /XLMARGIN YBMARGIN def\n");
- fprintf(fp," /YBMARGIN TMP def\n");
- fprintf(fp," /PAGES_PER_SHEET 1 def\n");
- fprintf(fp," /sp {/SAVEOBJ save def gs 0 XPAGE tr -90 rt\n");
- fprintf(fp," } bd\n");
- fprintf(fp," /np { gr showpage SAVEOBJ restore sp bp} bd\n");
- fprintf(fp," } if\n");
- fprintf(fp,"%%\n");
- fprintf(fp,"%%set up fonts\n");
- fprintf(fp,"%%\n");
- fprintf(fp,"NUM_LINES 1 ge {FONT findfont 1 scalefont setfont\n");
- fprintf(fp," /FONT_UPPER currentfont /FontBBox get 3 get 0 exch\n");
- fprintf(fp," currentfont /FontMatrix get transform exch pop def\n");
- fprintf(fp," /FONT_LOWER currentfont /FontBBox get 1 get 0 exch\n");
- fprintf(fp," currentfont /FontMatrix get transform exch pop def\n");
- fprintf(fp," /FONT_HT FONT_UPPER FONT_LOWER sub def\n");
- fprintf(fp," /FONT_SIZE YPAGE YBMARGIN sub YTMARGIN sub 1 sub\n");
- fprintf(fp," NUM_LINES div FONT_HT 1 gt {FONT_HT div } if def\n");
- fprintf(fp," } if\n");
- fprintf(fp,"\n");
- fprintf(fp,"FONT findfont FONT_SIZE scalefont setfont\n");
- fprintf(fp,"\n");
- fprintf(fp,"%%get height of font set tolerances\n");
- fprintf(fp," /FONT_UPPER currentfont /FontBBox get 3 get 0 exch\n");
- fprintf(fp," currentfont /FontMatrix get transform exch pop def\n");
- fprintf(fp," /FONT_LOWER currentfont /FontBBox get 1 get 0 exch\n");
- fprintf(fp," currentfont /FontMatrix get transform exch pop def\n");
- fprintf(fp," /FONT_HT FONT_UPPER FONT_LOWER sub def\n");
- fprintf(fp," FONT_HT 0 eq {/FONT_HT FONT_SIZE def } if\n");
- fprintf(fp," /FONT_MOVE FONT_SIZE FONT_HT gt {FONT_SIZE def} {FONT_HT def} ifelse\n");
- fprintf(fp,"/FONT_TOL FONT_HT YBMARGIN add def\n");
- fprintf(fp,"%%\n");
- fprintf(fp,"%%Routines common to all page styles\n");
- fprintf(fp,"%%\n");
- fprintf(fp,"/bp { XLMARGIN YPAGE YTMARGIN sub FONT_UPPER sub m\n");
- fprintf(fp," } bd\n");
- fprintf(fp,"/s { show currentpoint exch pop dup FONT_TOL\n");
- fprintf(fp," gt {FONT_MOVE sub XLMARGIN exch m} {np} ifelse} bd\n");
- fprintf(fp,"/S {show} bd\n");
- fprintf(fp,"/OFFSET (_) stringwidth pop neg def\n");
- fprintf(fp,"/bs { OFFSET 0 rmoveto } bd\n");
- fprintf(fp,"/bs {XLMARGIN currentpoint pop OFFSET add lt {OFFSET 0 rmoveto}\n");
- fprintf(fp,"{XLMARGIN currentpoint exch pop m}ifelse} bd\n");
- fprintf(fp,"/TABLEN (%s) stringwidth pop def\n",tabstring);
-
- /* Multiple tabs in succession don't always work due to floating point
- * math routing. On the QMS PS-410, more than two tabs in succession
- * caused the procedure to hang at the second tab spot because the
- * calculation of (curpoint - XLMARGIN)/TABLEN was always less than 2.
- * Add one percent of the tabwidth to the current point before calculating
- * the next tab position to force it over the edge. This won't affect
- * regular tabs since this (and any other remainder) is discarded by the
- * 'cvi' function.
- */
- fprintf(fp,"/ht {currentpoint exch TABLEN .01 mul add XLMARGIN sub TABLEN div \n");
- fprintf(fp," cvi 1 add TABLEN mul XLMARGIN add exch m}bd\n");
- fprintf(fp,"/cr {currentpoint XLMARGIN exch m pop} bd\n");
- fprintf(fp,"/lp {gr 1 PAGENUM ne {showpage}if} bd\n");
- fprintf(fp,"%%\n");
- fprintf(fp,"%%begin data et al\n");
- fprintf(fp,"%%\n");
- fprintf(fp,"sp\n");
- fprintf(fp,"bp\n");
- return(0);
- }
-
- /*
- * setupdevice - sets up defaults for a given printer type,
- * returns 0 if printer type set ok.
- * returns 1 if unknown printer type
- */
-
- int setupdevice(type,checkfont,xrmargin,xlmargin,xpage,ypage,ytmargin,ybmargin)
- char *type; /* printer type */
- int *checkfont;
- int *xrmargin;
- int *xlmargin;
- int *xpage;
- int *ypage;
- int *ytmargin;
- int *ybmargin;
- {
- char tmptype[256];
- int tmpi;
-
- for (tmpi = 0; type[tmpi] != '\0'; tmpi++) {
- if ( isupper(type[tmpi] )) {
- tmptype[tmpi] = tolower(type[tmpi]);
- }
- else {
- tmptype[tmpi] = type[tmpi];
- }
- }
-
- if (strcmp (tmptype, "alwnt") == 0 || strcmp (tmptype, "alwntx") == 0)
- {
- *checkfont = TRUE;
- *xrmargin = 14;
- *xlmargin = 18;
- *xpage = 612;
- *ypage = 792;
- *ytmargin = 8;
- *ybmargin = 13;
- return (0);
- }
-
- if (strcmp (tmptype, "next") == 0)
- {
- *checkfont = FALSE;
- *xrmargin = 9;
- *xlmargin = 11;
- *xpage = 612;
- *ypage = 792;
- *ytmargin = 10;
- *ybmargin = 10;
- return (0);
- }
-
- if (strcmp (tmptype, "hpiii") == 0 )
- {
- *checkfont = TRUE;
- *xrmargin = 18;
- *xlmargin = 18;
- *xpage = 612;
- *ypage = 792;
- *ytmargin = 18;
- *ybmargin = 18;
- return (0);
- }
- return (1);
- }
-
- /*
- * main program
- * args parsed, initial values set.
- */
- main(argc,argv)
- int argc;
- char *argv[];
- {
- double ptsize = DFLT_PTSIZE;
- char *font;
- char *tabstring;
- int style = DFLT_STYLE;
- int numlines = DFLT_LINES;
- int indent = INDENT;
- FILE *fpout = stdout;
- FILE *fpin = stdin;
- short badflag = FALSE;
- int checkfont = CHECKFONT;
- int xrmargin = XRMARGIN;
- int xlmargin = XLMARGIN;
- int xpage = XPAGE;
- int ypage = YPAGE;
- int ytmargin = YTMARGIN;
- int ybmargin = YBMARGIN;
- char *type; /* printer type */
- char ch; /* tmp character holder */
- int tmpint; /* tmp integer holder */
- char *progname;
- double atof();
-
- font = (char *) malloc(sizeof(DFLT_FONT));
- strcpy(font,DFLT_FONT);
- tabstring = (char *) malloc(sizeof(DFLT_TABSTRING));
- strcpy(tabstring,DFLT_TABSTRING);
- /* parse args */
- progname = *argv++;
-
- while ((--argc > 0)&&(*argv[0]=='-')) {
- switch(*++argv[0]) {
-
- case 'l': if(*++argv[0]=='d') {
- style = 3;
- }
- else {
- style = 4;
- };
- break;
- case 'p': style = 1;
- break;
- case 'd': style = 2;
- break;
- case '\0': argc = 1; /* read only standard input */
- break;
- case 'f': if (*++argv[0] != '\0'){
- font = *argv;
- }
- else
- if (--argc) {
- font = *++argv;
- }
- else {
- badflag = TRUE;
- }
- break;
- case 't': if (*++argv[0] !='\0'){
- tabstring = *argv;
- }
- else
- if (--argc) {
- tabstring = *++argv;
- }
- else {
- badflag = TRUE;
- }
- break;
-
- case 'T': if (*++argv[0] !='\0'){
- type = *argv;
- }
- else
- if (--argc) {
- type = *++argv;
- }
- else {
- badflag = TRUE;
- }
- if ( setupdevice(type, &checkfont, &xrmargin, &xlmargin,
- &xpage, &ypage, &ytmargin, &ybmargin) != 0 ) {
- fprintf(stderr,"Unknown printer type: %s \n",type);
- badflag = TRUE;
- }
-
- break;
- case 'n': if (*++argv[0] !='\0'){
- if((numlines = atof(*argv)) <= 0){
- fprintf(stderr,"specify a line number 1 or more\n");
- badflag = TRUE;
- }
- }
- else
- if (--argc) {
- if((numlines = atof(*++argv)) <= 0){
- fprintf(stderr,"specify a line number 1 or more\n");
- badflag = TRUE;
- }
- }
- else {
- badflag = TRUE;
- }
- break;
- case 'i': if (*++argv[0] !='\0'){
- if((indent = atof(*argv)) <= 0){
- fprintf(stderr,"specify a point offset of 1 or more\n");
- badflag = TRUE;
- }
- }
- else
- if (--argc) {
- if((indent = atof(*++argv)) <= 0){
- fprintf(stderr,"specify a point offset of 1 or more\n");
- badflag = TRUE;
- }
- }
- else {
- badflag = TRUE;
- }
- break;
- case 's': if (*++argv[0] !='\0'){
- if((ptsize = atof(*argv)) <= 0){
- fprintf(stderr,"specify a point size greater than 0\n");
- badflag = TRUE;
- }
- }
- else
- if (--argc) {
- if((ptsize = atof(*++argv)) <= 0){
- fprintf(stderr,"specify a point size greater than 0\n");
- badflag = TRUE;
- }
- }
- else {
- badflag = TRUE;
- }
- break;
- case 'c': if(*++argv[0]=='n') {
- checkfont = FALSE;
- }
- else {
- checkfont = TRUE;
- };
- break;
- case 'x': ch = *++argv[0];
- switch (ch) {
- case '\0':
- case 'r':
- case 'l':
- case 'p':
- if (*++argv[0] !='\0'){
- if((tmpint = atof(*argv)) < 0){
- fprintf(stderr,"specify value greater than 0\n");
- badflag = TRUE;
- }
- }
- else
- if (--argc) {
- if((tmpint = atof(*++argv)) < 0){
- fprintf(stderr,"specify value greater than 0\n");
- badflag = TRUE;
- }
- }
- else {
- badflag = TRUE;
- }
- break;
- default: badflag = TRUE;
- fprintf(stderr,"bad case %c with x flag\n",ch);
- break;
- }
- if (! badflag) {
- switch (ch) {
- case '\0':
- case 'l': xlmargin = tmpint;
- break;
- case 'r': xrmargin = tmpint;
- break;
- case 'p': xpage = tmpint;
- break;
- }
- }
-
- break;
-
- case 'y': ch = *++argv[0];
- switch (ch) {
- case '\0':
- case 't':
- case 'b':
- case 'p':
- if (*++argv[0] !='\0'){
- if((tmpint = atof(*argv)) < 0){
- fprintf(stderr,"specify value greater than 0\n");
- badflag = TRUE;
- }
- }
- else
- if (--argc) {
- if((tmpint = atof(*++argv)) < 0){
- fprintf(stderr,"specify value greater than 0\n");
- badflag = TRUE;
- }
- }
- else {
- badflag = TRUE;
- }
- break;
- default: badflag = TRUE;
- fprintf(stderr,"bad case %c with y flag\n",ch);
- break;
- }
- if (! badflag) {
- switch (ch) {
- case '\0':
- case 't': ytmargin = tmpint;
- break;
- case 'b': ybmargin = tmpint;
- break;
- case 'p': ypage = tmpint;
- break;
- }
- }
-
- break;
-
- case 'v': fprintf(stdout,"%s\n",version);
- return(0);
- break;
- default: badflag = TRUE;
- break;
-
- }
- if(badflag) {
- fprintf(stderr,"Usage: %s [-p] [-l] [-ld] [-d] [-n lines ] [-t ",progname);
- fprintf(stderr,"tabstring] [-f fontname] [-s pointsize] [-i point offset]");
- fprintf(stderr," [-T printertype ] ");
- fprintf(stderr,"[-c[yn] [-x[rlp] size] [-y[btp] size] [file1 ... ]\n");
- return(1);
- }
- *argv++;
- }
-
- /* set up postscript header */
-
- printhead(fpout,font,ptsize,style,numlines,tabstring,indent,checkfont,
- xrmargin, xlmargin,xpage,ypage,ytmargin,ybmargin,version);
- /* read files */
- if (argc <=0) {
- getfile(stdin,fpout);
- }
- else {
- while(argc--!=0) {
- if((fpin = fopen(*argv,"r"))!=NULL) {
- getfile(fpin,fpout);
- fclose(fpin);
- *argv++;
- }
- else{
- fprintf(stderr,"Unable to open file %s\n",*argv);
- fprintf(fpout,"\nlp\n");
- return(1);
- }
- }
- }
- /* makesure showpage is done so last page prints */
- fprintf(fpout,"\nlp\n");
- return(0);
- }
-