home *** CD-ROM | disk | FTP | other *** search
- /*
- * roff - C version.
- * the Colonel (George Sicherman). 19 May 1983.
- * fix by Tim Maroney, 31 Dec 1984.
- * .hc implemented, 8 Feb 1985.
- * ported to PC, + font control - Dave Tutelman
- */
-
- #include <stdio.h>
- #include <b:printcap.h> /* use printcap for YOUR printer */
-
- #define TXTLEN (o_pl-o_m1-o_m2-o_m3-o_m4-2)
- #define IDTLEN (o_ti>=0?o_ti:o_in)
- #define MAXMAC 64
- #define MAXDEPTH 10
- #define MAXLENGTH 255
- #define UNDERL 1
- #define BOLD 2
- #define ITALIC 4
-
- char spacechars[] = " \t\n";
- int sflag, hflag, startpage, stoppage;
- char holdword[MAXLENGTH], *holdp;
- char assyline[MAXLENGTH]; /* place to assemble output line */
- int assylen; /* index into assyline */
- int infont = 0, outfont = 0, oldfont = 0;
- char assyfont[MAXLENGTH]; /* font indicator for output characters
- * bit 0 = ul (underline)
- * bit 1 = bo (bold)
- * bit 2 = it (italic)
- */
- char ehead[100], efoot[100], ohead[100], ofoot[100];
- struct macrotype {
- char mname[3];
- long int moff;
- } macro[MAXMAC];
- int n_macros;
- int depth;
- int adjtoggle;
- int isrequest = 0;
- char o_tr[40][2]; /* OUTPUT TRANSLATION TABLE */
- int o_cc = '.'; /* CONTROL CHARACTER */
- int o_hc = -1; /* HYPHENATION CHARACTER */
- int o_tc = ' '; /* TABULATION CHARACTER */
- int o_in = 0; /* INDENT SIZE */
- int o_ix = -1; /* NEXT INDENT SIZE */
- int o_ta[20] = {
- 9, 17, 25, 33, 41, 49, 57, 65, 73, 81, 89, 97, 105,
- 113, 121, 129, 137, 145, 153, 161};
- int n_ta = 20; /* #TAB STOPS */
- int o_ll = 65, o_ad = 1, o_po = 0, o_ls = 1, o_ig = 0, o_fi = 1;
- int o_pl = 66, o_ro = 0, o_hx = 0, o_bl = 0, o_sp = 0, o_sk = 0;
- int o_ce = 0, o_m1 = 2, o_m2 = 2, o_m3 = 1, o_m4 = 3;
- int o_li = 0, o_n1 = 0, o_n2 = 0, o_bp = -1, o_hy = 1;
- int o_ni = 1; /* LINE-NUMBER INDENT */
- int o_nn = 0; /* #LINES TO SUPPRESS NUMBERING */
- int o_ti = -1; /* TEMPORARY INDENT */
- int o_ul = 0, o_bo = 0, o_it = 0;
- int o_dev = 1; /* 0=SCREEN, 1=PRINTER, 2=TTY */
- char printer[4] = ""; /* NAME OF PRINTER, INITIALLY BLANK */
- int center = 0;
- int page_no = -1;
- int line_no = 9999;
- int n_outwords;
- FILE *File, *Macread, *Macwrite;
- FILE *Save;
- long int teller[MAXDEPTH], ftell();
- char *strcat(), *strcpy(), *strend(), *strhas();
- char *sprintf();
- char *request[] = {
- "ad","ar","bl","bp","br","cc","ce","de",
- "ds","ef","eh","fi","fo","hc","he","hx","hy","ig",
- "in","ix","li","ll","ls","m1","m2","m3","m4",
- "n1","n2","na","ne","nf","ni","nn","nx","of","oh",
- "pa","pl","po","ro","sk","sp","ss","ta","tc","ti",
- "tr","ul","bo","it",0};
- int c; /* LAST CHAR READ */
-
-
- main(argc,argv)
- int argc;
- char **argv;
- {
- while (--argc) switch (**++argv) {
- case '+':
- startpage=atoi(++*argv);
- break;
- case '-':
- ++*argv;
- if (isdigit(**argv)) stoppage=atoi(*argv);
- else switch(**argv) {
- case 's':
- sflag++;
- break;
- case 'h':
- hflag++;
- break;
- case 'd':
- o_dev=0;
- break;
- case 'p':
- ++*argv; /* GET RID OF "P" */
- strncpy(printer,*argv,3);
- break;
- case 't':
- o_dev=2;
- break;
- default:
- bomb();
- }
- break;
- default:
- argc++;
- goto endargs;
- }
- endargs:
- if (o_dev == 1) printcap(); /* GET PRINTER PARAMETERS */
- assylen=0;
- assyline[0]='\0';
- if (!argc) {
- File=stdin;
- readfile();
- }
- else while (--argc) {
- File=fopen(*argv,"r");
- if (NULL==File) {
- fprintf(stderr,"PCroff: cannot read %s\n",*argv);
- exit(1);
- }
- readfile();
- fclose(File);
- argv++;
- }
- writebreak();
- endpage();
- for (; o_sk; o_sk--) blankpage();
- /* NOW DO CLEANUP OF FILES */
- if (Macwrite) fclose (Macwrite);
- if (Macread) fclose (Macread);
- unlink ("MACWRITE.TMP");
- }
-
- readfile()
- {
- while (readline()) {
- if (isrequest) continue;
- if (center || !o_fi) {
- if (assylen) writeline(0,1);
- else blankline();
- }
- }
- }
-
- readline()
- {
- int startline, doingword;
- isrequest = 0;
- startline = 1;
- doingword = 0;
- c=suck();
- if (c == '\n') {
- o_sp = 1;
- writebreak();
- goto out;
- }
- else if (isspace(c)) writebreak();
- for (;;) {
- if (c==EOF) {
- if (doingword) bumpword();
- break;
- }
- if (c!=o_cc && o_ig) {
- while (c!='\n' && c!=EOF) c=suck();
- break;
- }
- if (isspace(c) && !doingword) {
- startline=0;
- switch (c) {
- case ' ':
- assyfont[assylen]=infont;
- assyline[assylen++]=' ';
- break;
- case '\t':
- tabulate();
- break;
- case '\n':
- goto out;
- }
- c = suck();
- continue;
- }
- if (isspace(c) && doingword) {
- bumpword();
- if (c=='\t') tabulate();
- else if (assylen) {
- assyfont[assylen]=infont;
- assyline[assylen++]=' ';
- }
- doingword=0;
- if (c=='\n') break;
- }
- if (!isspace(c)) {
- if (doingword) {
- *holdp++ = c;
- }
- else if (startline && c==o_cc && !o_li) {
- isrequest=1;
- return readreq();
- }
- else {
- doingword=1;
- holdp=holdword;
- *holdp++ = c;
- }
- }
- startline=0;
- c = suck();
- }
- out:
- if (o_ul) o_ul--;
- if (o_bo) o_bo--;
- if (o_it) o_it--;
- infont = (o_ul? UNDERL:0) | (o_bo? BOLD:0) | (o_it? ITALIC:0);
- center=o_ce;
- if (o_ce) o_ce--;
- if (o_li) o_li--;
- return c!=EOF;
- }
-
- /*
- * bumpword - add word to current line.
- */
-
- bumpword()
- {
- char *hc;
- int i;
- *holdp = '\0';
- infont = o_ul? UNDERL : 0;
- infont |= o_bo? BOLD : 0;
- infont |= o_it? ITALIC : 0;
- /*
- * If in no-fill mode, don't even try to hyphenate.
- */
- if (!o_fi) goto giveup;
- /*
- * We use a while-loop in case of ridiculously long words with
- * multiple hyphenation indicators.
- */
- if (assylen + reallen(holdword) > o_ll - IDTLEN) {
- if (!o_hy) writeline(o_ad,0);
- else while (assylen + reallen(holdword) > o_ll - IDTLEN) {
- /*
- * Try hyphenating it.
- */
- if (o_hc && strhas(holdword,o_hc)) {
- /*
- * There are hyphenation marks. Use them!
- */
- for (hc=strend(holdword); hc>=holdword; hc--) {
- if (*hc!=o_hc) continue;
- *hc = '\0';
- if (assylen + reallen(holdword) + 1 >
- o_ll - IDTLEN) {
- *hc = o_hc;
- continue;
- }
- /*
- * Yay - it fits!
- */
- dehyph(holdword);
- strcpy(&assyline[assylen],holdword);
- strcat(assyline,"-");
- for (i=assylen;
- i<=assylen+strlen(holdword)+1;
- i++)
- assyfont[i] = infont;
- assylen += strlen(holdword) + 1;
- strcpy(holdword,++hc);
- break; /* STOP LOOKING */
- } /* for */
- /*
- * It won't fit, or we've succeeded in breaking the word.
- */
- writeline(o_ad,0);
- if (hc<holdword) goto giveup;
- }
- else {
- /*
- * If no hyphenation marks, give up.
- * Let somebody else implement it.
- */
- writeline(o_ad,0);
- goto giveup;
- }
- } /* while */
- }
- giveup:
- /*
- * remove hyphenation marks, even if hyphenation is disabled.
- */
- if (o_hc) dehyph(holdword);
- strcpy(&assyline[assylen],holdword);
- for (i=assylen; i<=assylen+strlen(holdword); i++)
- assyfont[i] = infont;
- assylen+=strlen(holdword);
- holdp = holdword;
- }
-
- /*
- * dehyph - remove hyphenation marks.
- */
-
- dehyph(s)
- char *s;
- {
- char *t;
- for (t=s; *s; s++) if (*s != o_hc) *t++ = *s;
- *t='\0';
- }
-
- /*
- * reallen - length of a word, excluding hyphenation marks.
- */
-
- int
- reallen(s)
- char *s;
- {
- register n;
- n=0;
- while (*s) n += (o_hc != *s++);
- return n;
- }
-
- tabulate()
- {
- int j;
- for (j=0; j<n_ta; j++) if (o_ta[j]-1>assylen+IDTLEN) {
- for (; assylen+IDTLEN<o_ta[j]-1; assylen++) {
- assyline[assylen]=o_tc;
- assyfont[assylen]=infont;
- }
- return;
- }
- /* NO TAB STOPS REMAIN */
- assyfont[assylen]=infont;
- assyline[assylen++]=o_tc;
- }
-
- int
- readreq()
- {
- char req[3];
- int r, s;
- if (skipsp()) return c!=EOF;
- c=suck();
- if (c==EOF || c=='\n') return c!=EOF;
- if (c=='.') { /* END OF MACRO */
- o_ig = 0;
- do (c=suck());
- while (c!=EOF && c!='\n');
- if (depth) endmac();
- return c!=EOF;
- }
- if (o_ig) { /* IGNORING THIS LINE */
- while (c!=EOF && c!='\n') c=suck();
- return c!=EOF;
- }
- /* MAKE 2-CHAR STRING IN req */
- req[0]=c;
- c=suck();
- if (c==EOF || c=='\n') req[1]='\0';
- else req[1]=c;
- req[2]='\0';
- for (r=0; r<n_macros; r++) if (!strcmp(macro[r].mname,req)) {
- submac(r); /* CALL THE MACRO req */
- goto reqflsh;
- }
- for (r=0; request[r]; r++) if (!strcmp(request[r],req)) break;
- if (!request[r]) {
- do (c=suck());
- while (c!=EOF && c!='\n');
- return c!=EOF;
- }
- switch (r) {
- case 0: /* ad */
- o_ad=1;
- writebreak();
- break;
- case 1: /* ar */
- o_ro=0;
- break;
- case 2: /* bl */
- nread(&o_bl);
- writebreak();
- break;
- case 3: /* bp */
- case 37: /* pa */
- c=snread(&r,&s,1);
- if (s>0) o_bp=page_no+r;
- else if (s<0) o_bp=page_no-r;
- else o_bp=r;
- writebreak();
- if (line_no) {
- endpage();
- beginpage();
- }
- break;
- case 4: /* br */
- writebreak();
- break;
- case 5: /* cc */
- c=cread(&o_cc);
- break;
- case 6: /* ce */
- nread(&o_ce);
- writebreak();
- break;
- case 7: /* de */
- defmac();
- break;
- case 8: /* ds */
- o_ls=2;
- writebreak();
- break;
- case 9: /* ef */
- c=tread(efoot);
- break;
- case 10: /* eh */
- c=tread(ehead);
- break;
- case 11: /* fi */
- o_fi=1;
- writebreak();
- break;
- case 12: /* fo */
- c=tread(efoot);
- strcpy(ofoot,efoot);
- break;
- case 13: /* hc */
- c=cread(&o_hc);
- break;
- case 14: /* he */
- c=tread(ehead);
- strcpy(ohead,ehead);
- break;
- case 15: /* hx */
- o_hx=1;
- break;
- case 16: /* hy */
- nread(&o_hy);
- break;
- case 17: /* ig */
- o_ig=1;
- break;
- case 18: /* in */
- writebreak();
- snset(&o_in);
- o_ix = -1;
- break;
- case 19: /* ix */
- snset(&o_ix);
- if (!n_outwords) o_in=o_ix;
- break;
- case 20: /* li */
- nread(&o_li);
- break;
- case 21: /* ll */
- snset(&o_ll);
- break;
- case 22: /* ls */
- snset(&o_ls);
- break;
- case 23: /* m1 */
- nread(&o_m1);
- break;
- case 24: /* m2 */
- nread(&o_m2);
- break;
- case 25: /* m3 */
- nread(&o_m3);
- break;
- case 26: /* m4 */
- nread(&o_m4);
- break;
- case 27: /* n1 */
- o_n1=1;
- break;
- case 28: /* n2 */
- nread(&o_n2);
- break;
- case 29: /* na */
- o_ad=0;
- writebreak();
- break;
- case 30: /* ne */
- nread(&r);
- if (line_no+(r-1)*o_ls+1 > TXTLEN) {
- writebreak();
- endpage();
- beginpage();
- }
- break;
- case 31: /* nf */
- o_fi=0;
- writebreak();
- break;
- case 32: /* ni */
- snset(&o_ni);
- break;
- case 33: /* nn */
- snset(&o_nn);
- break;
- case 34: /* nx */
- do_nx();
- c='\n'; /* SO WE DON'T FLUSH THE FIRST LINE */
- break;
- case 35: /* of */
- c=tread(ofoot);
- break;
- case 36: /* oh */
- c=tread(ohead);
- break;
- case 38: /* pl */
- snset(&o_pl);
- break;
- case 39: /* po */
- snset(&o_po);
- break;
- case 40: /* ro */
- o_ro=1;
- break;
- case 41: /* sk */
- nread(&o_sk);
- break;
- case 42: /* sp */
- nread(&o_sp);
- writebreak();
- break;
- case 43: /* ss */
- writebreak();
- o_ls=1;
- break;
- case 44: /* ta */
- do_ta();
- break;
- case 45: /* tc */
- c=cread(&o_tc);
- break;
- case 46: /* ti */
- writebreak();
- c=snread(&r,&s,0);
- if (s>0) o_ti=o_in+r;
- else if (s<0) o_ti=o_in-r;
- else o_ti=r;
- break;
- case 47: /* tr */
- do_tr();
- break;
- case 48: /* ul */
- nread(&o_ul);
- infont |= o_ul? UNDERL:0;
- break;
- case 49: /* bo */
- nread(&o_bo);
- infont |= o_bo? BOLD:0;
- break;
- case 50: /* it */
- nread(&o_it);
- infont |= o_it? ITALIC:0;
- break;
- }
- reqflsh:
- while (c!=EOF && c!='\n') c=suck();
- return c!=EOF;
- }
-
- snset(par)
- int *par;
- {
- int r, s;
- c=snread(&r,&s,0);
- if (s>0) *par+=r;
- else if (s<0) *par-=r;
- else *par=r;
- }
-
- tread(s)
- char *s;
- {
- int leadbl;
- leadbl=0;
- for (;;) {
- c=suck();
- if (c==' ' && !leadbl) continue;
- if (c==EOF || c=='\n') {
- *s = '\0';
- return c;
- }
- *s++ = c;
- leadbl++;
- }
- }
-
- nread(i)
- int *i;
- {
- int f;
- f=0;
- *i=0;
- if (!skipsp()) for (;;) {
- c=suck();
- if (c==EOF) break;
- if (isspace(c)) break;
- if (isdigit(c)) {
- f++;
- *i = *i*10 + c - '0';
- }
- else break;
- }
- if (!f) *i=1;
- }
-
- int
- snread(i,s,sdef)
- int *i, *s, sdef;
- {
- int f;
- f = *i = *s = 0;
- for (;;) {
- c=suck();
- if (c==EOF || c=='\n') break;
- if (isspace(c)) {
- if (f) break;
- else continue;
- }
- if (isdigit(c)) {
- f++;
- *i = *i*10 + c - '0';
- }
- else if ((c=='+' || c=='-') && !f) {
- f++;
- *s = c=='+' ? 1 : -1;
- }
- else break;
- }
- while (c!=EOF && c!='\n') c=suck();
- if (!f) {
- *i=1;
- *s=sdef;
- }
- return c;
- }
-
- int
- cread(k)
- int *k;
- {
- int u;
- *k = -1;
- for (;;) {
- u=suck();
- if (u==EOF || u=='\n') return u;
- if (isspace(u)) continue;
- if (*k < 0) *k=u;
- }
- }
-
- defmac()
- {
- int i;
- char newmac[3], *nm;
- if (skipsp()) return;
- nm=newmac;
- if (!Macwrite) openwrite();
- *nm++ = suck();
- c=suck();
- if (c!=EOF && c!='\n' && c!=' ' && c!='\t') *nm++ = c;
- *nm = '\0';
- /* KILL OLD DEFINITION IF ANY */
- for (i=0; i<n_macros; i++) if (!strcmp(newmac,macro[i].mname)) {
- macro[i].mname[0]='\0';
- break;
- }
- if ((macro[n_macros].moff=ftell(Macwrite)) == -1) {
- fprintf(stderr,"PCroff: positioning error in macwrite\n");
- exit(1);
- }
- strcpy(macro[n_macros++].mname,newmac);
- while (c!=EOF && c!='\n') c=suck(); /* FLUSH HEADER LINE */
- while (copyline());
- }
-
- openwrite() /* OPEN MACWRITE.TMP FOR WRITING */
- {
- if (Macread) {
- fclose (Macread);
- Macread=0;
- }
- if (NULL==(Macwrite=fopen("MACWRITE.TMP","a"))) {
- fprintf(stderr,"PCroff: cannot open temp file\n");
- exit(1);
- }
- }
-
- openread() /* OPEN MACWRITE.TMP FOR READING */
- {
- if (Macwrite) {
- fclose (Macwrite);
- Macwrite=0;
- }
- if (NULL==(Macread=fopen("MACWRITE.TMP","r"))) {
- fprintf(stderr,"PCroff: cannot read-open temp file\n");
- exit(1);
- }
- }
-
- openmac()
- {
- if (NULL==(Macwrite=fopen("MACWRITE.TMP","w"))) {
- fprintf(stderr,"PCroff: cannot open temp file\n");
- exit(1);
- }
- if (NULL==(Macread=fopen("MACWRITE.TMP","r"))) {
- fprintf(stderr,"PCroff: cannot read-open temp file\n");
- exit(1);
- }
- }
-
- /* COPY A LINE FROM INPUT TO MACRO FILE.
- * RETURN 0 IF END OF MACRO (..), 1 OTHERWISE
- */
-
- int
- copyline()
- {
- int n, first, second;
- if (c==EOF) {
- fprintf(Macwrite,"..\n");
- return 0;
- }
- n=0;
- first=1;
- second=0;
- for (;;) {
- c=suck();
- if (c==EOF) {
- if (!first) putc('\n',Macwrite);
- return 0;
- }
- if (c=='\n') {
- putc('\n',Macwrite);
- return n!=2;
- }
- if (first && c=='.') n++;
- else if (second && n==1 && c=='.') n++;
- putc(c,Macwrite);
- second=first;
- first=0;
- }
- }
-
- /* MACRO HAS BEEN CALLED. SHIFT INPUT TO MACRO FILE
- * AND POSITION AT CALLED MACRO.
- */
-
- submac(r)
- int r;
- {
- while (c!=EOF && c!='\n') c=suck();
- if (depth) teller[depth-1]=ftell(Macread); /* ALREADY IN
- MACRO FILE. PUSH CURRENT MACRO */
- else {
- if (!Macread) openread();
- Save = File;
- File = Macread;
- }
- depth++;
- if (-1 == (fseek(Macread,macro[r].moff,0))) {
- fprintf(stderr,"PCroff: error seeking macro %s\n",
- macro[r].mname);
- exit(1);
- }
- }
-
- endmac() /* FINISHED USE OF MACRO */
- {
- depth--;
- if (depth) fseek(Macread,teller[depth-1],0);
- else File = Save;
- c='\n';
- }
-
- do_ta()
- {
- int v;
- n_ta = 0;
- for (;;) {
- nread(&v);
- if (v==1) return;
- else o_ta[n_ta++]=v;
- if (c=='\n' || c==EOF) break;
- }
- }
-
- do_tr()
- {
- char *t;
- t = &o_tr[0][0];
- *t='\0';
- if (skipsp()) return;
- for (;;) {
- c=suck();
- if (c==EOF || c=='\n') break;;
- *t++ = c;
- }
- *t = '\0';
- }
-
- do_nx()
- {
- char fname[100], *f;
- f=fname;
- if (skipsp()) return;
- for (;;) switch(c=suck()) {
- case EOF:
- case '\n':
- case ' ':
- case '\t':
- if (f==fname) return;
- goto got_nx;
- default:
- *f++ = c;
- }
- got_nx:
- fclose(File);
- *f = '\0';
- if (!(File=fopen(fname,"r"))) {
- fprintf(stderr,"PCroff: cannot read %s\n",fname);
- exit(1);
- }
- }
-
- int
- skipsp()
- {
- for (;;) switch(c=suck()) {
- case EOF:
- case '\n':
- return 1;
- case ' ':
- case '\t':
- continue;
- default:
- ungetc(c,File);
- return 0;
- }
- }
-
- writebreak()
- {
- int q;
- if (assylen) writeline(0,1);
- q = TXTLEN;
- if (o_bl) {
- if (o_bl + line_no > q) {
- endpage();
- beginpage();
- }
- for (; o_bl; o_bl--) blankline();
- }
- else if (o_sp) {
- if (o_sp + line_no > q) newpage();
- else if (line_no) for (; o_sp; o_sp--) blankline();
- }
- }
-
- blankline()
- {
- if (line_no >= TXTLEN) newpage();
- if (o_n2) o_n2++;
- spit('\n');
- line_no++;
- }
-
- writeline(adflag,flushflag)
- int adflag, flushflag;
- {
- int j, q;
- char lnstring[7];
- for (j=assylen-1; j; j--) {
- if (assyline[j]==' ') assylen--;
- else break;
- }
- q = TXTLEN;
- if (line_no >= q) newpage();
- for (j=0; j<o_po; j++) spit(' ');
- if (o_n1) {
- if (o_nn) for (j=0; j<o_ni+4; j++) spit(' ');
- else {
- for (j=0; j<o_ni; j++) spit(' ');
- sprintf(lnstring,"%3d ",line_no+1);
- spits(lnstring);
- }
- }
- if (o_n2) {
- if (o_nn) for (j=0; j<o_ni+4; j++) spit(' ');
- else {
- for (j=0; j<o_ni; j++) spit(' ');
- sprintf(lnstring,"%3d ",o_n2++);
- spits(lnstring);
- }
- }
- if (o_nn) o_nn--;
- if (center) for (j=0; j<(o_ll-assylen+1)/2; j++) spit(' ');
- else for (j=0; j<IDTLEN; j++) spit(' ');
- if (adflag && !flushflag) fillline();
- for (j=0; j<assylen; j++) {
- outfont = assyfont[j];
- assyfont[j] = 0; /* CLEAR FONT FLAG */
- spit(assyline[j]);
- }
- spit('\n');
- assylen=0;
- assyline[0]='\0';
- line_no++;
- for (j=1; j<o_ls; j++) if (line_no <= q) blankline();
- if (!flushflag) {
- if (o_hc) dehyph(holdword);
- strcpy(assyline,holdword);
- assylen=strlen(holdword);
- for (j=0; j <= assylen; j++) assyfont[j]=infont;
- *holdword='\0';
- holdp=holdword;
- }
- if (o_ix>=0) o_in=o_ix;
- o_ix = o_ti = -1;
- }
-
- fillline()
- {
- int excess, j, s, inc, spaces;
- adjtoggle^=1;
- if (!(excess = o_ll - IDTLEN - assylen)) return;
- if (excess < 0) {
- fprintf(stderr,"PCroff: internal error #2 [%d]\n",excess);
- exit(1);
- }
- for (j=2;; j++) {
- if (adjtoggle) {
- s=0;
- inc = 1;
- }
- else {
- s=assylen-1;
- inc = -1;
- }
- spaces=0;
- while (s>=0 && s<assylen) {
- if (assyline[s]==' ') spaces++;
- else {
- if (0<spaces && spaces<j) {
- insrt(s-inc);
- if (inc>0) s++;
- if (!--excess) return;
- }
- spaces=0;
- }
- s+=inc;
- }
- }
- }
-
- insrt(p)
- int p;
- {
- int i;
- for (i=assylen; i>p; i--) {
- assyline[i]=assyline[i-1];
- assyfont[i]=assyfont[i-1];
- }
- assylen++;
- }
-
- newpage()
- {
- if (page_no >= 0) endpage();
- else page_no=1;
- for (; o_sk; o_sk--) blankpage();
- beginpage();
- }
-
- beginpage()
- {
- int i;
- if (sflag) waitawhile();
- for (i=0; i<o_m1; i++) spit('\n');
- writetitle(page_no&1? ohead: ehead);
- for (i=0; i<o_m2; i++) spit('\n');
- line_no=0;
- }
-
- endpage()
- {
- int i;
- for (i=line_no; i<TXTLEN; i++) blankline();
- for (i=0; i<o_m3; i++) spit('\n');
- writetitle(page_no&1? ofoot: efoot);
- for (i=0; i<o_m4; i++) spit('\n');
- if (o_bp < 0) page_no++;
- else {
- page_no = o_bp;
- o_bp = -1;
- }
- }
-
- blankpage()
- {
- int i;
- if (sflag) waitawhile();
- for (i=0; i<o_m1; i++) spit('\n');
- writetitle(page_no&1? ohead: ehead);
- for (i=0; i<o_m2; i++) spit('\n');
- for (i=0; i<TXTLEN; i++) spit('\n');
- for (i=0; i<o_m3; i++) spit('\n');
- writetitle(page_no&1? ofoot: efoot);
- page_no++;
- for (i=0; i<o_m4; i++) spit('\n');
- line_no=0;
- }
-
- writetitle(t)
- char *t;
- {
- char d, *pst, *dst, *pgform(), *dtform();
- int j, l, m, n;
- int pln,dln;
- d = *t;
- if (o_hx || !d) {
- spit('\n');
- return;
- }
- pst=pgform(); /* FORM PAGE NUMBER STRING */
- dst=dtform(); /* FORM DATE STRING */
- pln=strlen(pst);
- dln=strlen(dst);
- for (j=0; j<o_po; j++) spit(' ');
- l=titlen(++t,d,pln,dln);
- while (*t && *t!=d) {
- if (*t=='%') spits(pst);
- else if (*t=='$') spits(dst);
- else spit(*t);
- t++;
- }
- if (!*t) {
- spit('\n');
- return;
- }
- m=titlen(++t,d,pln,dln);
- for (j=l; j<(o_ll-m)/2; j++) spit(' ');
- while (*t && *t!=d) {
- if (*t=='%') spits(pst);
- else if (*t=='$') spits(dst);
- else spit(*t);
- t++;
- }
- if (!*t) {
- spit('\n');
- return;
- }
- if ((o_ll-m)/2 > l) m+=(o_ll-m)/2;
- else m+=l;
- n=titlen(++t,d,pln,dln);
- for (j=m; j<o_ll-n; j++) spit(' ');
- while (*t && *t!=d) {
- if (*t=='%') spits(pst);
- else if (*t=='$') spits(dst);
- else spit(*t);
- t++;
- }
- spit('\n');
- }
-
- char *
- pgform()
- {
- static char pst[11];
- int i;
- if (o_ro) {
- *pst='\0';
- i=page_no;
- if (i>=400) {
- strcat(pst,"cd");
- i-=400;
- }
- while (i>=100) {
- strcat(pst,"c");
- i-=100;
- }
- if (i>=90) {
- strcat(pst,"xc");
- i-=90;
- }
- if (i>=50) {
- strcat(pst,"l");
- i-=50;
- }
- if (i>=40) {
- strcat(pst,"xl");
- i-=40;
- }
- while (i>=10) {
- strcat(pst,"x");
- i-=10;
- }
- if (i>=9) {
- strcat(pst,"ix");
- i-=9;
- }
- if (i>=5) {
- strcat(pst,"v");
- i-=5;
- }
- if (i>=4) {
- strcat(pst,"iv");
- i-=4;
- }
- while (i--) strcat(pst,"i");
- }
- else sprintf(pst,"%d",page_no);
- return pst;
- }
-
- /*
- dtform()
- USES deSMET C DATE FUNCTION. SEE deSMET-SPECIFIC FILE.
- */
-
- int
- titlen(t,c,p_len,d_len)
- char *t, c;
- int p_len,d_len;
- {
- int q;
- q=0;
- while (*t && *t!=c) switch (*t++) {
- case '%':
- q += p_len;
- break;
- case '$':
- q += d_len;
- break;
- default:
- q++;
- break;
- }
- return q;
- }
-
- spits(s)
- char *s;
- {
- while (*s) spit(*s++);
- }
-
- spit(c)
- char c;
- {
- static int col_no, n_blanks;
- char *t;
- for (t = (char *)o_tr; *t; t++) if (*t++==c) {
- c = *t;
- break;
- }
- if (page_no < startpage || (stoppage && page_no > stoppage)) return;
- if (c != ' ' && c != '\n' && n_blanks) {
- if (hflag && n_blanks>1)
- while (col_no/8 < (col_no+n_blanks)/8) {
- putc('\t',stdout);
- n_blanks-= 8 - (col_no & 07);
- col_no = 8 + col_no & ~07;
- }
- for (; n_blanks; n_blanks--) {
- putc(' ',stdout);
- col_no++;
- }
- }
- if (!isalnum(c)) outfont &= ~UNDERL;
- /* DON'T UNDERLINE WHITE SPACE */
- if (outfont != oldfont) { /* CHANGE FONTS */
- if (o_dev == 1) { /* PRINTER */
- if ((oldfont & UNDERL) && !(outfont & UNDERL))
- putfont(e_ul);
- if (!(oldfont & UNDERL) && (outfont & UNDERL))
- putfont(s_ul);
- if ((oldfont & BOLD) && !(outfont & BOLD))
- putfont(e_bo);
- if (!(oldfont & BOLD) && (outfont & BOLD))
- putfont(s_bo);
- if ((oldfont & ITALIC) && !(outfont & ITALIC))
- putfont(e_it);
- if (!(oldfont & ITALIC) && (outfont & ITALIC))
- putfont(s_it);
- }
- oldfont = outfont;
- }
- if (c == ' ') n_blanks++;
- else {
- if ((c>='!' && c<='~') || (c>='\240')) switch (o_dev) {
- case 0: /* DISPLAY SCREEN */
- putscrn (c,outfont);
- col_no++;
- break;
- case 1: /* PRINTER, ALREADY DONE WITH FONT CONTROL */
- putc (c,stdout);
- col_no++;
- break;
-
- case 2: /* DUMB TTY-TYPE PRINTER USES OVERSTRIKE */
- if (outfont & UNDERL) fputs("_\b",stdout);
- if (outfont & BOLD) {
- putc(c,stdout); putc('\b',stdout);
- putc(c,stdout); putc('\b',stdout);
- }
- if (outfont & ITALIC) fputs("_\b",stdout);
- putc (c,stdout);
- col_no++;
- break;
- }
- }
- if (c == '\n') {
- putc ('\n',stdout);
- col_no = 0;
- n_blanks = 0;
- }
- }
-
- int
- suck()
- {
- for (;;) {
- c=getc(File);
- if (islegal(c)) return c;
- }
- }
-
- /*
- * strhas - does string have character?
- * USG and BSD both have this in their libraries. Now, if
- * they could just agree on the name of the function ...
- */
-
- char *
- strhas(p,c)
- char *p, c;
- {
- for (; *p; p++) if (*p==c) return p;
- return NULL;
- }
-
- /*
- * strend - find NULL at end of string.
- */
-
- char *
- strend(p)
- char *p;
- {
- while (*p++);
- return p;
- }
-
- /*
- * isspace, isalnum, isdigit, islegal - classify a character.
- * We could just as well use <ctype.h> if it didn't vary from
- * one version of Unix to another. As it is, these routines
- * must be modified for weird character sets, like EBCDIC and
- * CDC Scientific.
- */
-
- int
- isspace(c)
- int c;
- {
- char *s;
- for (s=spacechars; *s; s++) if (*s==c) return 1;
- return 0;
- }
-
- int
- isalnum(c)
- int c;
- {
- return (c>='A'&&c<='Z') || (c>='a'&&c<='z') || (c>='0'&&c<='9');
- }
-
- int
- isdigit(c)
- int c;
- {
- return c>='0' && c<='9';
- }
-
- int
- islegal(c)
- int c;
- {
- return c>=' ' && c<='~' || isspace(c) || c=='\n' || c==EOF;
- }
-
- bomb()
- {
- fprintf(stderr,"usage: PCroff [+00] [-00] ");
- fprintf(stderr,"[-s][-h][-d][-t][-pPRINTER] file ...\n");
- exit(1);
- }
-
- putfont (s) /* SO WE CAN HAVE NUL IN A FONT CONTROL STRING */
- struct fontstring *s;
- {
- int i;
- for (i=0; i<s.len; i++)
- putc (s.seq[i], stdout);
- }
-