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 0fox@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 ?