Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83; site pyuxqq.UUCP Path: utzoo!watmath!clyde!burl!ulysses!gamma!pyuxww!pyuxqq!ral From: ral@pyuxqq.UUCP (R A Levenberg) Newsgroups: net.micro.pc Subject: Re: printing files from UNIX while using comm. package Message-ID: <728@pyuxqq.UUCP> Date: Wed, 19-Jun-85 00:02:00 EDT Article-I.D.: pyuxqq.728 Posted: Wed Jun 19 00:02:00 1985 Date-Received: Thu, 20-Jun-85 20:13:14 EDT References: <617@hou2e.UUCP> Organization: Bell Communications Research, Piscataway, NJ Lines: 356 Simterm's companion UNIX program ibmpr is indeed distributed with the simterm diskette. Here's the source file received via floppy from Jim Holtman in April: ---------------------------------cut here--------------------------------------- /* * ibmpr [-p] * convert nroff TTY37 output to right form for IBM-PC terminals. * -p indicates hard copy desired * -i output ITALICS for 'underlines' (EPSON w/GRAFTRAX) */ #include #include #include #include #include "sys/ioctl.h" #include "termio.h" #define ESC 033 /* escape */ #define HFWD '9' #define HREV '8' #define FREV '7' #define LF '\n' #define CR 015 #define NFLAG 0200 /* hi-bit flag for non-showing chars */ #define NMASK 0177 #define AMP 046 /* & */ #define DEE 0144 /* d */ #define ATSIGN 0100 /* @ */ #define BFSIZ 1024 /* size of output buffer (bigger because of tbl weirds and nroff idiosyncracies */ #define ALLDELAY 0177400 /* all delay bits in termio.c_oflag */ /* puty adds control char to output, marked by hi-bit */ #define puty(c) putx(c|NFLAG) #define flg(x) ((char)(x|NFLAG)) /* set hi-bit of x */ int nlcnt, /* accumulated newline count */ frevcnt, /* accumulated reverse line-feeds */ halfpos, /* half-line position: -1 = above, +1 = below */ restrict = 0, /* 0==> full terminal, 1==> no display enhancements */ minimiz; /* 0==> normal, 1==> remove extra newlines */ char *ttydev; int svstmode; /* for mesg restore */ int restore(); char *ttyname(); int svsgflgs; struct termio sgb; int retcode = 2; /* return code */ char peekbuf[2]; char *peekstr = peekbuf; /* lookahead ptr */ char outbf[BFSIZ]; /* output assembly buffer */ char *bfnext = outbf, /* addr of next empty byte */ *bflast = &outbf[BFSIZ-1]; /* addr of last usable byte */ /* normal display enhancement strings */ char *enunder = "\033&dD", /* underline */ *ennorml = "\033&d@", /* normal output */ *ensuper = "\033&dH", /* superscript (half) */ *ensubsc = "\033&dL", /* subscript (half, underlined */ *enbold = "\033&dB"; /* BOLD (inverse only) */ int restore(); main(argc, argv) char **argv; { register c; scanarg(argc,argv); signal(SIGINT, restore); signal(SIGQUIT, restore); if (ioctl(1, TCGETA, &sgb) == 0) fixtty(); setbuf(stdin, calloc(BUFSIZ,1)); while((c = getchal()) != EOF) { if (nlcnt && c != LF) flushnl(); if (frevcnt && c != ESC) flushrv(); if (c == LF) { if (++nlcnt == 1) flushln(); continue; } if (c == ESC) escape(); else if (c == '\b') backsp(); else if (c == '_') { /* C nroff */ if ((c = getchal()) == '\b') { undersc(); } else { putx('_'); peekbuf[0] = c; peekstr = peekbuf; } } else putx(c); } flusher(); retcode = 0; restore(); } getchal() { if (*peekstr) return(*peekstr++); return(getchar()); } /* scanarg: scan arguments and set flags; ignore unknown args */ scanarg(argc,argv) int argc; char **argv; { register char *p; while ( --argc > 0) { p = *++argv; if (*p == '-') { ++p; if (*p == 'p') { if (p[1] == 0) printf("\033P1"); if (p[1] == 'c') printf("\033P2"); } else if (*p == 'i') printf("\033Pi"); /* italics */ } } } /* fixtty: get tty status and save; remove delay and CR-LF mapping */ fixtty() { struct stat sb; svsgflgs = sgb.c_oflag; sgb.c_oflag &= ~(ALLDELAY|ONLRET|OCRNL|ONLCR); ioctl(1, TCSETAW, &sgb); /* stty nl nl0 cr0 tab0 ff0 */ fstat(1, &sb); svstmode = sb.st_mode; ttydev = ttyname(1); chmod(ttydev, 0600); /* mesg n */ } /* flusher: flush accumulated newlines, reverse line feeds, buffer */ flusher() { flushln(); if (nlcnt) flushnl(); if (frevcnt) flushrv(); fflush(stdout); } /* flushrv: flush accumulated reverse line feeds */ flushrv() { while (frevcnt--) putstr("\033A"); putstr(ennorml); frevcnt = 0; } /* flushnl: flush accumulated newlines (count in nlcnt) */ flushnl() { if (minimiz != 0 && nlcnt > 2) nlcnt = 2; putchar(CR); while (nlcnt--) putchar(LF); nlcnt = 0; } putstr(p) char *p; { register char *pp; pp = p; while (*pp) puty(*pp++); } restore(){ if (isatty(1)) { sgb.c_oflag = svsgflgs; ioctl(1, TCSETAW, &sgb); chmod(ttydev, svstmode); } printf(" \r"); printf("\033P0"); printf("\033&d@"); exit(retcode); } /* escape: handle escape sequences */ escape() { register int c; c = getchal(); if (frevcnt && c != FREV) flushrv(); switch (c) { case FREV: frevcnt++; break; case HREV: if (halfpos == 0) { putstr(ensuper); halfpos--; } else if (halfpos > 0) { putstr(ennorml); halfpos--; } else { putstr("\033A"); /* roll back 1 */ putstr(ennorml); halfpos = 0; } break; case HFWD: if (halfpos == 0) { putstr(ensubsc); halfpos++; } else if (halfpos < 0) { putstr(ennorml); halfpos++; } else { putstr("\012"); /* roll up 1, i.e., LF w/o CR */ putstr(ennorml); halfpos = 0; } break; case '&': putstr("\033&"); puty(c = getchal()); if (c == 'd') puty(getchal()); break; case ')': putstr("\033)"); puty(getchal()); break; default: puty(ESC); puty(c); break; } } char peeku[3]; /* backsp: handle backspacing */ /* sequences are handled such that : ( \b is backspace ) */ /* a\b_ -> a in inverse video */ /* _\ba -> a in inverse video */ /* c\bd -> c in inverse video */ /* if a control char (ESC) precedes or follows '\b' */ /* then an actual backspace movement is performed */ backsp() { register char *bftmp; register int c; char *bfhi; int i, j, ncnt, bscnt; int boldflag; boldflag = 0; while(1){ c = getchal(); if (c==bfnext[-1]){ if (boldflag==0){ boldflag = 1; /* if last thing in the buffer are to turn off the BOLD, remove it */ if ((bfnext[-5]==flg(ESC))&& (bfnext[-4]==flg(AMP))&& (bfnext[-3]==flg(DEE))&& (bfnext[-2]==flg(ATSIGN))){ bfnext[-5] = bfnext[-1]; bfnext=bfnext-4; } else{ bftmp = bfnext+4; bfnext[3] = bfnext[-1]; bfnext--; putstr(enbold); bfnext=bftmp; } } c = getchal(); if (c=='\b') continue; } else putx('\b'); break; } if (boldflag==1) putstr(ennorml); /* put last char read back */ peeku[0] = c; peeku[1] = '\0'; peekstr = peeku; } /* undersc: handle C nroff's (_ BS char)+ sequences * assumes _ BS already found * if char is a control char, put char back and break. */ undersc() { register char c; putstr(enunder); while (1) { if ((c=getchal())==ESC) { peeku[0] = c; peeku[1] = '\0'; peekstr = peeku; break; } else putx(c); if ((c = getchal()) != '_') { peeku[0] = c; peeku[1] = '\0'; peekstr = peeku; break; } if ((c = getchal()) != '\b') { peeku[0] = '_'; peeku[1] = c; peekstr = peeku; break; } } putstr(ennorml); } /* flushln: flush out accumulated line */ flushln() { register char c, *p; putx('\0'); p = outbf; while (c = (*p++ & NMASK)) putchar(c); bfnext = outbf; } /* putx: add normal (printing) char to output */ putx(c) char c; { if (bfnext <= bflast) *bfnext++ = c; else die("line too long\n"); } die(mesg) char *mesg; { register char *p; char *c = "ibmpr: "; write(2, c, 4); p = mesg; while (*p) write(2, p++, 1); restore(); }