root@alice.marlow.reuters.co.uk (Operator) (02/23/88)
Well, heres my version of an ASCII to PostScript translator. It understands underline (either x <backspace> _, _ <backspace> x, or x <CR> _), bold (ditto). It understands a little about EPSON printer output, so if it sees an ESCAPE followed by the # defines in the listing, it will even do italic !!. Also, by using the '-d' switch, you can get DRAFT sprawled across each page. You may have to watch the backslashed newlines in the shar, which will probably cause 'sh' to throw up. // o All opinions are my own. (O) ( ) The powers that be ... / \_____( ) o \ | /\____\__/ _/_/ _/_/ UUCP: fox@alice.marlow.reuters.co.uk #--------------------------------CUT HERE------------------------------------- #! /bin/sh # # This is a shell archive. Save this into a file, edit it # and delete all lines above this comment. Then give this # file to sh by executing the command "sh file". The files # will be extracted into the current directory owned by # you with default permissions. # # The files contained herein are: # # \c -r--r--r-- 1 root 10775 Feb 22 13:20 pscript.c # echo 'x - pscript.c' if test -f pscript.c; then echo 'shar: not overwriting pscript.c'; else sed 's/^X//' << '________This_Is_The_END________' > pscript.c X# include <stdio.h> X# include <string.h> X X# ifdef lint X# define SCCSID(x) X# else X# define SCCSID(x) static char sccsid[] = x; X# endif X X# ifndef TRUE X# define TRUE 1 X# define FALSE 0 X# endif X X# ifndef NULL X# define NULL 0 X# endif X X# ifndef NIL X# define NIL NULL X# endif X X# ifndef BOOL X# define BOOL int X# endif X X# define ever (;;) X# define COL_WIDTH 11200 /* Max. column width. */ X X# define BS 0x08 X# define ESC 0x1b X# define CTRL_Z 0x1a X# define BON 'G' X# define BON1 'E' X# define BON2 '8' X# define BOFF 'H' X# define BOFF1 'F' X# define BOFF2 '9' X# define ION '4' X# define IOFF '5' X Xchar *version = "1.16"; X# define BSIZE 4096 Xchar lbuf[BSIZE]; Xunsigned char attr[BSIZE]; XFILE *fp; X X/*------------------------------------- X * The following is used to print the X * draft string across each page. X *-------------------------------------*/ Xchar *draft_string = X"/Times-Bold findfont 180 scalefont setfont \ X215 215 moveto \ X56 rotate \ X.97 setgray \ X(Draft) show \ X0 0 moveto \ X-56 rotate \ X0 setgray \n"; X X# define A_UNDERLINE 0x01 X# define A_BOLD 0x02 X# define A_ITALIC 0x04 X Xlong x = 1680; Xlong y = 1200; X X Xint line_count; Xint page_size = 66; Xint font_size = 10; Xint font = 0; Xint tfont_size = 10; Xint tfont = 0; Xlong num_lines_in_file; Xint num_pages; Xint page_no = 1; Xint col_count; /* Current column. */ Xint num_cols = 1; /* Number of columns. */ Xint col_width = COL_WIDTH; XBOOL do_header = FALSE; Xchar *file_name; Xint draft_flag = FALSE; /* TRUE if we want DRAFT across each page.*/ Xint p_flag = FALSE; X Xstruct font_table { X char *name; X int value; X } font_table[] = { X "courier", 0, X "times-roman", 24, X "roman", 24, X "helvetica", 8, X "symbol", 56, X NULL X }; X X Xmain(argc, argv) Xchar **argv; X{ register char *cp; X int arg_index; X X if (argc < 1) X usage(); X X arg_index = do_switches(argc, argv); X X if (arg_index >= argc) { X file_name = "<stdin>"; X fp = stdin; X } X else if ((fp = fopen(file_name = argv[arg_index], "rb")) == NULL) { X perror(argv[arg_index]); X exit(1); X } X X if (p_flag) { X copy_postscript(); X exit(0); X } X if (do_header) { X num_pages = 0; X while (!feof(fp)) { X get_line(); X if (++num_lines_in_file >= page_size || lbuf[0] == '\f') { X num_pages++; X num_lines_in_file = 0; X } X } X if (num_lines_in_file) X num_pages++; X rewind(fp); X num_pages /= num_cols; X } X X printf("%%!Pscript file version 1.16 (C) P. Fox 2/19/88\nPSp 16839 SFL\n"); X if (draft_flag) X printf("%s", draft_string); X line_count = 0; X col_count = 0; X while (!feof(fp)) { X int ch = get_line(); X if (++line_count > page_size) { X line_count = 1; X if (++col_count >= num_cols) { X col_count = 0; X printf("PE\n"); X if (draft_flag) X printf("%s", draft_string); X } X x = 1680; X } X if (ch == '\f') X line_count = 9999; X if (line_count == 1 && col_count == 0) X do_top_line(); X printf("%ld %ld P 8308 SLL %d %d F ", X y + (col_count * col_width), x, font, font_size); X print_line(lbuf); X x += 240; X } X printf("PE PSe\n\004"); X exit(0); X} Xcopy_postscript() X{ register char *cp; X X if (draft_flag) X printf("%s", draft_string); X while (!feof(fp)) { X if (fgets(lbuf, sizeof lbuf - 1, fp) == NULL) X break; X for (cp = lbuf; *cp; cp++) { X if (*cp == '\\') { X printf("\\%c", cp[1]); X cp++; X continue; X } X if (*cp == '(') X putchar('\n'); X putchar(*cp); X } X if (lbuf[0] == 'P' && lbuf[1] == 'E' && X (lbuf[2] == '\n' || lbuf[2] == NULL || lbuf[2] == ' ')) X if (draft_flag) X printf("%s", draft_string); X } X} Xprint_line(str) Xchar *str; X{ char *detab(); X char *cp = detab(str); X unsigned char *ap = attr; X unsigned char last_attr = 0; X BOOL in_bracket = FALSE; X int col = 0; X int width = 20; X# define MAX_WIDTH 60 X if (*cp == NULL || *cp == '\n') { X putchar('\n'); X return; X } X X set_up_attributes(cp); X X while (*cp) { X unsigned char x = *ap ^ last_attr; X X if (x && in_bracket) { X printf(") S "); X in_bracket = FALSE; X width += 3; X } X X if (x & A_BOLD) { X printf("%s ", *ap & A_BOLD ? "B" : "E"); X width += 2; X } X if (x & A_UNDERLINE) { X printf("%s ", *ap & A_UNDERLINE ? "LU" : "LE"); X width += 3; X } X if (x & A_ITALIC) { X printf("%s ", *ap & A_ITALIC ? "I" : "E"); X width += 2; X } X last_attr = *ap++; X X if (!in_bracket) { X putchar('('); X in_bracket= TRUE; X width++; X } X switch (*cp) { X case '\r': case '\n': X break; X case '(': case ')': case '\\': X putchar('\\'); X width++; X default: X putchar(*cp); X } X cp++; X col++; X if (++width >= MAX_WIDTH) { X printf(") S "); X if (last_attr & A_BOLD) printf("E "); X if (last_attr & A_UNDERLINE) printf("LE "); X if (last_attr & A_ITALIC) printf("E "); X putchar('\n'); X if (last_attr & A_BOLD) printf("B "); X if (last_attr & A_UNDERLINE) printf("LU "); X if (last_attr & A_ITALIC) printf("I "); X putchar('('); X width = 1; X } X } X printf(") S "); X if (last_attr & A_BOLD) X printf("E "); X if (last_attr & A_UNDERLINE) X printf("LE "); X printf("\n"); X} Xdo_switches(argc, argv) Xchar **argv; X X{ char *cp; X int i; X BOOL title = FALSE; X X for (i = 1; i < argc; i++) { X if (argv[i][0] != '-') X return i; X for (cp = argv[i]+1; *cp; cp++) { X title = FALSE; X switch (*cp) { X case '2': num_cols = 2; X col_width = COL_WIDTH / 2; X break; X case 'd': X draft_flag = TRUE; X break; X case 'f': X decode_font_name(title, cp+1); X cp = " "; X break; X case 'h': do_header = TRUE; X break; X case 'i': sscanf(cp+1, "%ld", &y); X cp = " "; X break; X case 'n': do_header = FALSE; X break; X case 'l': sscanf(cp+1, "%d", &page_size); X cp = " "; X break; X case 'p': p_flag = TRUE; X break; X case 's': sscanf(cp+1, "%d", title ? X &tfont_size : &font_size); X cp = " "; X break; X case 't': title = TRUE; X break; X default: X usage(); X } X } X } X return i; X} Xusage() X{ X fprintf(stderr, "pscript version %s\n\n", version); X fprintf(stderr, "Convert text file to PostScript file for APPLE\n"); X fprintf(stderr, "Laser printer.\n\n"); X fprintf(stderr, "Usage: pscript [-ln] [-ffont] [-sn] [file]\n\n"); X fprintf(stderr, " -2 Two column output.\n"); X fprintf(stderr, " -d Print DRAFT across each page.\n"); X fprintf(stderr, " -ffont Print using font 'font':\n"); X fprintf(stderr, " courier (default)\n"); X fprintf(stderr, " roman or times-roman\n"); X fprintf(stderr, " symbol\n"); X fprintf(stderr, " helvetica\n"); X fprintf(stderr, " -h Print header.\n"); X fprintf(stderr, " -in Set indent to n (default 1200)\n"); X fprintf(stderr, " -n Dont print header.\n"); X fprintf(stderr, " -ln Set page size to n lines (default %d)\n", X page_size); X fprintf(stderr, " -p File is already in Postscript.\n"); X fprintf(stderr, " (Used with -d to put DRAFT across\n"); X fprintf(stderr, " a postscript document.)\n"); X fprintf(stderr, " -sn Set font size to n (default 12)\n"); X fprintf(stderr, " -tffont Set title font name.\n"); X fprintf(stderr, " -tsn Set title font size.\n"); X X exit(1); X} Xchar * Xdetab(str) Xchar *str; X{ X static char buf[BSIZE]; X register char * cp = buf; X int col = 0; X X while (*str) { X if (*str++ == '\t') { X *cp++ = ' '; X col++; X while (col & 7) { X *cp++ = ' '; X col++; X } X } X else { X *cp++ = str[-1]; X col++; X } X } X *cp = NULL; X return buf; X} Xset_up_attributes(str) Xregister char *str; X{ char *strchr(); X char *line1 = strchr(str, '\r'); X unsigned char *ap = attr; X int i = strlen(str); X register char *cp = str; X int nbytes; X static char static_attr = 0; X X /*-------------------------------------------* X * Clear out the attribute array. * X *-------------------------------------------*/ X while (i-- > 0) X *ap++ = 0; X X /*-------------------------------------------* X * Process bold and underline when they are * X * done by overstriking. * X *-------------------------------------------*/ X if (line1) { X *line1++ = NULL; X for (ap = attr; *line1; ap++, cp++, line1++) { X if (*line1 == '_') X *ap |= A_UNDERLINE; X else if (*cp == '_') { X *ap |= A_UNDERLINE; X *cp = *line1; X } X else if (*line1 == *cp) X *ap |= A_BOLD; X } X } X /*-------------------------------------------* X * Process bold and underline when they are * X * done by backspacing. * X *-------------------------------------------*/ X nbytes = strlen(cp = str); X for (ap = attr; *cp; ) { X if (*cp != BS) { X cp++, ap++, nbytes--; X continue; X } X ap--; X if (cp[1] == '_') { X *ap |= A_UNDERLINE; X } X else if (cp[-1] == '_') { X cp[-1] = cp[1]; X *ap |= A_UNDERLINE; X } X else if (cp[1] == cp[-1]) X *ap |= A_BOLD; X strcpy(cp, cp+2); X nbytes -= 2; X memcpy(ap+1, ap+3, nbytes); X ap++; X } X X nbytes = strlen(str); X for (ap = attr, cp = str; *cp; nbytes--) { X if (*cp != ESC) { X *ap++ |= static_attr; X cp++; X continue; X } X if (cp[1] == BON || cp[1] == BON1 || cp[1] == BON2) X static_attr |= A_BOLD; X else if (cp[1] == BOFF || cp[1] == BOFF1 || cp[1] == BOFF2) X static_attr &= ~A_BOLD; X else if (cp[1] == ION) X static_attr |= A_ITALIC; X else if (cp[1] == IOFF) X static_attr &= ~A_ITALIC; X else { X *ap++ |= static_attr; X cp++; X continue; X } X strcpy(cp, cp+2); X memcpy(ap, ap+2, nbytes); X nbytes--; X } X X} Xdecode_font_name(title, str) Xchar *str; X{ struct font_table *fp = font_table; X char *cp; X X for (cp = str; *cp; cp++) X if (*cp >= 'a') X cp -= 0x20; X while (fp->name) { X if (strncmp(str, fp->name, strlen(str)) == 0) { X if (title) X tfont = fp->value; X else X font = fp->value; X return ; X } X fp++; X } X usage(); X} Xget_line() X{ X register char *cp; X int ch; X X for (cp = lbuf; !feof(fp); ) { X if ((ch = getc(fp)) == EOF || ch == '\n' || ch == '\f') X break; X if (ch == CTRL_Z) X continue; X *cp++ = ch; X } X if (cp > lbuf && cp[-1] == '\r') X cp--; X *cp = NULL; X return ch; X} Xdo_top_line() X{ X char *cp = file_name; X char buf[80]; X int i; X char *date(); X X if (do_header == FALSE) X return; X printf("1000 800 P 8308 SLL %d %d F B ", tfont, tfont_size); X for (i = 0; i < sizeof buf; ) X buf[i++] = ' '; X buf[79] = NULL; X buf[0] = 'F'; buf[1] = 'i'; buf[2] = 'l'; buf[3] = 'e'; buf[4] = ':'; X strcpy(buf+6, cp); X buf[strlen(buf)] = ' '; X strcpy(buf+23, date()); X buf[strlen(buf)] = ' '; X sprintf(buf+54, "Page %d of %d", page_no++, num_pages); X printf("(%s) S E\n", buf); X} X# include <time.h> Xchar *days[] = { X "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", X "Saturday"}; Xchar *months[] = { X "January", "February", "March", "April", "May", "June", X "July", "August", "September", "October", "November", "December" X }; Xchar * Xdate() X{ X char buf[64]; X struct tm *tp; X long l = time((long *) 0); X X tp = localtime(&l); X sprintf(buf, "%s, %d %s %d", days[tp->tm_wday], tp->tm_mday, X months[tp->tm_mon], 1900+tp->tm_year); X return buf; X} X ________This_Is_The_END________ if test `wc -l < pscript.c` -ne 530; then echo 'shar: pscript.c was damaged during transit (should have been 530 bytes)' fi fi ; : end of overwriting check exit 0
fox@alice.marlow.reuters.co.uk (Paul Fox) (02/23/88)
The ASCII to postscript translator I sent out needs as a requisite a file we call 'APPLASER.INI' dowloaded to the printer first. This file we got from Microsoft Word. It defines the macros (such as PS etc) which pscript needs to run with. I have not posted it, since it may be copyright Apple. Does anyone know the status of this ? There is a copy of this file in the Postscript cookbook. I'm not sure which chapter its in. Anyone else know ?