/********************************************************/ /* */ /* ROFF4, Version 1.50 */ /* */ /* (C) 1983 by Ernest E. Bergmann */ /* Physics, Building #16 */ /* Lehigh Univerisity */ /* Bethlehem, Pa. 18015 */ /* */ /* Permission is hereby granted for all commercial and */ /* non-commercial reproduction and distribution of this */ /* material provided this notice is included. */ /* */ /********************************************************/ /*June 27, 1983*/ #include "roff4.h" /*assuming REVSCROLL is FALSE*/ /*output OUTBUF2 whith the vertical height of the mainline specified by VLINENO,FVLINENO[they must not be changed here]. Excessive superscripting will be pushed down.*/ printout() {int level,top,bot; /*"up" is negative;units fractional*/ int lsave,fsave; OUTBUF2[BPOS]='\0'; fsave=FVLINENO; lsave=VLINENO; level=FRVAL*(PLINENO-VLINENO)+FPLINENO-FVLINENO; if(!OLDBOT) level++; excurs(&OUTBUF2[0],&top,&bot); if(top>level) level=top; if(!REVSCROLL) FVLINENO += level; padv(); for(;level<=bot;level++) {OCNT=0; do {OCNT++; flp(level,FALSE); } while(retype()); if(level=FRVAL) {w++; f -= FRVAL; } if(w<0) if(REVSCROLL) backup(w*FRVAL+f); else {VLINENO +=w; FVLINENO +=f; while(FVLINENO<0){VLINENO++;FVLINENO+=FRVAL;} while(FVLINENO=FRVAL) {PLINENO++; FPLINENO -= FRVAL; } } /****************************************/ backup(i) /*not yet implemented*/ int i; /*# of fractional lines(probably negative)*/ {fprintf(STDERR,"\nCan't back up yet\n"); } /**************************************************/ excurs(str,t,b) /*finds the topmost and bottommost line positions of str*/ char *str; int *t,*b; {int l; char c; *t=*b=l=0; /*current line position */ c=*str; while(c){if(c==CFVAL){if(c=*(++str)) switch(c) {case '+':l--; if(l<*t) *t=l; c=*(++str); break; case '-':l++; if(l>*b) *b=l; c=*(++str); break; default : c=*(++str); break; } } else c=*(++str); } } /**************************************************/ flp(level,updat)/*fancy line print at a given vertical level the string in OUTBUF2[] with backspacing, underlining, and strikout. To permit boldface it modifies DBUF[],DPOS so that retype can be used to patch up OUTBUF2 for resubmittal to flp()*/ int level; /* current vertical level to print*/ int updat; /* boolean for update of UF,XF,MCNT*/ {int i; BLKCNT=lbc(level,OUTBUF2); FIRST=TRUE; while((BLKCNT>0)||updat) {prpass(level,updat); putchar('\r'); updat=FIRST=FALSE; } if(XCOL>-1){for(i=0;i<=XCOL;i++) putchar(XBUF[i]); putchar('\r'); } if(UCOL>-1){for(i=0;i<=UCOL;i++) putchar(UBUF[i]); putchar('\r'); } if((UCOL>-1)||(XCOL>-1)) initxu(); } /**************************************************/ retype() /*restores characters into OUTBUF2 from DBUF that need to be overstruck again*/ {int i; if(DPOS==-1) return(FALSE); else {for(i=0;i<=DPOS;i++) {if(DBUF[i]) {OUTBUF2[i]=DBUF[i]; DBUF[i]=FALSE; } } DPOS=-1; return(TRUE); } } /**************************************************/ int lbc(lev,str) /*counts printable chars in line level and above; parity must be reset*/ int lev; /*=0 main line,=-1 superscripts,=+1 subscripts, etc.*/ char *str; {char c,n; int l; l=n=0; c=*str; while(c){if(c==CFVAL){if(c=*(++str)) switch(c) {case '+':l--;c=*(++str);break; case '-':l++;c=*(++str);break; default: c=*(++str);break; } } else {if((c>' ')&&(l<=lev)) if(c!=TCVAL) n++; c=*(++str); } } return(n); } /**************************************************/ prpass(lev,updat) /*printer pass initial cr; no lf anywhere*/ int lev; /*=0 main line,=-1 superscripts,=+1 subscripts, etc.*/ int updat;/*boolean to update UF,XF,MCNT*/ {char ch; int l; int xfs,ufs,mcnts; /*save variables*/ int p1,p2,p3; /*position holders*/ int cp2; /*for tabulation calculation*/ xfs=XF; ufs=UF; mcnts=MCNT; p1=p2=p3=l=BPOS=CP=PP=0; while(ch=OUTBUF2[BPOS]) {switch (class(ch)) {case BLACK:/*print it if posssible*/ if((PP>CP)||(l>lev)){CP++;BPOS++;break;} else {while(CP>PP){putchar(' ');PP++;} if(ch==SCVAL)putchar(' '); else putchar(ch);PP++; if(MCNT>OCNT) {DBUF[BPOS]=OUTBUF2[BPOS]; if(BPOS>DPOS) DPOS=BPOS; } OUTBUF2[BPOS++]=' '; if(UF&&FIRST)UBUF[UCOL=CP]=UCHAR; if(XF&&FIRST)XBUF[XCOL=CP]=XCHAR; BLKCNT--; CP++; } break; case WHITE:/*assume blank*/ CP++;BPOS++;break; case TRANSLATE:/*similar to BLACK and WHITE*/ ch=OUTBUF2[++BPOS]; if((PP>CP)||(l>lev)||(ch==' ')) {CP++;BPOS++;break;} else {while(CP>PP){putchar(' ');PP++;} trch(ch);PP++; if(MCNT>OCNT) {DBUF[BPOS]=OUTBUF2[BPOS]; DBUF[BPOS-1]=OUTBUF2[BPOS-1]; if(BPOS>DPOS) DPOS=BPOS; } OUTBUF2[BPOS++]=' '; if(UF&&FIRST)UBUF[UCOL=CP]=UCHAR; if(XF&&FIRST)XBUF[XCOL=CP]=XCHAR; BLKCNT--; CP++; } break; case CONTROL:/*decode on following letter*/ ch=OUTBUF2[++BPOS]; if(CPTR[ch-' ']) pcont(ch); else switch(ch) {case 'h': case 'H':/*backspace*/ if(CP)CP--;break; case '+': l--; break; case '-': l++; break; case 'U': UF=TRUE;break; case 'u': UF=FALSE;break; case 'X': XF=TRUE;break; case 'x': XF=FALSE;break; case 'B': MCNT *=3;break; case 'b': if(!(MCNT /=3))MCNT=1; break; case 'D': MCNT *=2;break; case 'd': if(!(MCNT /=2))MCNT=1; break; case '(': p1=CP;break; case ')': CP=p1;break; case '[': p2=CP;break; case ']': CP=p2;break; case '{': p3=CP;break; case '}': CP=p3;break; default:/*?,ignore*/;break; } BPOS++; break; case SENTINEL: OUTBUF2[BPOS]=0;break; case HTAB: for(cp2=0;CP>=0;cp2+=TABSIZ)CP-=TABSIZ; CP=cp2; BPOS++; break; case OTHERS: printf("\nweird character value: %o\n",ch); BPOS++; break; }} if(!updat){/*restore original values*/ XF=xfs; UF=ufs; MCNT=mcnts; } } /**************************************************/ int class(c) char c; {if(c==TCVAL) return(TRANSLATE); if (c==CFVAL) return(CONTROL); if(c>' ') return(BLACK); if(c==' ') return(WHITE); if(c=='\n') return(SENTINEL); if(c=='\r') return(SENTINEL); if(c==TAB) return(HTAB); if(!c) return(SENTINEL); return(OTHERS); } /**************************************************/ fraction() /*put printer in fractional spcing mode; set FRQ*/ {if(!FRQ && FRSTRING && (FRVAL!=1)) {outstr(FRSTRING); FRQ = TRUE; } } /**************************************************/ whole() /*put printer in whole line spacing; reset FRQ */ {if(FRQ && WHSTRING) {outstr(WHSTRING); FRQ = FALSE; } } /**************************************************/ trch(c) /*output string translation of c*/ char c; {char *p; if(c<' ') {putchar(TCVAL);putchar(c);return;} p = TPTR[c-' ']; if(p) outstr(p); else {/*not initialized*/ putchar(TCVAL); putchar('?'); } } /****************************************/ pcont(c) /*output printer control string for c*/ char c; {char *p; if(c<' ') {putchar(CFVAL);putchar(c);return;} p = CPTR[c-' ']; if(p) outstr(p); else {/*not initialized*/ putchar(CFVAL); putchar('?'); } } .