home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 128_01 / roff47.c < prev    next >
Text File  |  1985-03-10  |  8KB  |  312 lines

  1. /********************************************************/
  2. /*                            */
  3. /*            ROFF4, Version 1.60            */
  4. /*                            */
  5. /*(C) 1983,4 by Ernest E. Bergmann            */
  6. /*        Physics, Building #16            */
  7. /*        Lehigh Univerisity            */
  8. /*        Bethlehem, Pa. 18015            */
  9. /*                            */
  10. /* Permission is hereby granted for all commercial and    */
  11. /* non-commercial reproduction and distribution of this    */
  12. /* material provided this notice is included.        */
  13. /*                            */
  14. /********************************************************/
  15. /*Feb 15, 1984*/
  16. /*January 9, 1984*/
  17. #include "roff4.h"
  18. /*assuming REVSCROLL is FALSE*/
  19. /*output OUTBUF2 whith the vertical height of the mainline
  20. specified by VLINENO,FVLINENO[they must not be changed here].
  21. Excessive superscripting will be pushed down.*/
  22.  
  23. printout()
  24. {int level,top,bot;    /*"up" is negative;units fractional*/
  25. int lsave,fsave;
  26.  
  27. OUTBUF2[BPOS]='\0';
  28. fsave=FVLINENO;
  29. lsave=VLINENO;
  30. level=FRVAL*(PLINENO-VLINENO)+FPLINENO-FVLINENO;
  31. if(!OLDBOT) level++;
  32. excurs(&OUTBUF2[0],&top,&bot);
  33. if(top>level) level=top;
  34.  
  35. if(!REVSCROLL) FVLINENO += level;
  36. padv();
  37. for(;level<=bot;level++)
  38.     {OCNT=0;
  39.     do {OCNT++; flp(level,FALSE); }
  40.     while(retype());
  41.     if(level<bot)
  42.         {fraction();
  43.         putchar('\n');
  44.         FPLINENO++;
  45.         }
  46.     }
  47. flp(level,TRUE);    /*update UF, XF, MCNT*/
  48. OUTBUF2[0]=BPOS=0;
  49. OLDLN=VLINENO=lsave;
  50. OLDBOT=bot;
  51. FVLINENO=fsave;
  52. }
  53. /****************************************/
  54. /*moves printer vertically so that its position is specified
  55. by VLINENO,FVLINENO*/
  56. padv()
  57. {int w,f;    /*whole,fractional lines*/
  58. w=VLINENO-PLINENO;
  59. f=FVLINENO-FPLINENO;
  60. while(f<0) {w--; f += FRVAL; }
  61. while(f>=FRVAL)    {w++; f -= FRVAL; }
  62. if(w<0){fprintf(STDERR,"padv():VL=%d,PL=%d\n",
  63.             VLINENO,PLINENO);
  64.     if(REVSCROLL) backup(w*FRVAL+f);
  65.     else {VLINENO +=w;
  66.           FVLINENO +=f;
  67.           while(FVLINENO<0){VLINENO++;FVLINENO+=FRVAL;}
  68.           while(FVLINENO<FRVAL){VLINENO--;FVLINENO-=FRVAL;}
  69.           return;
  70.          }
  71.     }
  72. if(FRQ)    {while(f--){putchar('\n'); FPLINENO++; }
  73.     if(w){whole();while(w--){putchar('\n');PLINENO++;}}
  74.     }
  75. else    {while(w--){putchar('\n'); PLINENO++; }
  76.     if(f){fraction();while(f--){putchar('\n');FPLINENO++;}}
  77.     }
  78. while(FPLINENO>=FRVAL) {PLINENO++; FPLINENO -= FRVAL; }
  79. }
  80. /****************************************/
  81. backup(i)    /*not yet implemented*/
  82. int i;        /*# of fractional lines(probably negative)*/
  83. {fprintf(STDERR,"\nCan't back up yet\n");
  84. }
  85. /**************************************************/
  86. excurs(str,t,b) /*finds the topmost and bottommost line
  87.         positions of str*/
  88. char *str;
  89. int *t,*b;
  90. {int l;
  91. char c;
  92. *t=*b=l=0; /*current line position */
  93. c=*str;
  94. while(c){if(c==CFVAL){if(c=*(++str))
  95.             switch(c)
  96.             {case '+':l--; if(l<*t) *t=l;
  97.                 c=*(++str); break;
  98.             case '-':l++; if(l>*b) *b=l;
  99.                 c=*(++str); break;
  100.             default : c=*(++str); break;
  101.             }
  102.             }
  103.     else c=*(++str);
  104.     }
  105. }
  106.  
  107. /**************************************************/
  108. flp(level,updat)/*fancy line print at a given vertical level
  109.         the string in OUTBUF2[] with backspacing,
  110.         underlining, and strikout.  To permit boldface
  111.         it modifies DBUF[],DPOS so that retype can be
  112.         used to patch up OUTBUF2 for resubmittal to
  113.         flp()*/
  114. int level;    /* current vertical level to print*/
  115. int updat;    /* boolean for update of UF,XF,MCNT*/
  116. {int i;
  117.     BLKCNT=lbc(level,OUTBUF2);
  118.     FIRST=TRUE;
  119.     while((BLKCNT>0)||updat)
  120.         {prpass(level,updat); putchar('\r');
  121.         updat=FIRST=FALSE;
  122.         }
  123.     if(XCOL>-1){for(i=0;i<=XCOL;i++)
  124.             putchar(XBUF[i]);
  125.             putchar('\r');
  126.            }
  127.     if(UCOL>-1){for(i=0;i<=UCOL;i++)
  128.             putchar(UBUF[i]);
  129.             putchar('\r');
  130.            }
  131.     if((UCOL>-1)||(XCOL>-1)) initxu();
  132. }
  133.  
  134. /**************************************************/
  135. retype()    /*restores characters into OUTBUF2 from DBUF
  136.         that need to be overstruck again*/
  137. {int i;
  138. if(DPOS==-1) return(FALSE);
  139. else    {for(i=0;i<=DPOS;i++)
  140.         {if(DBUF[i])
  141.             {OUTBUF2[i]=DBUF[i];
  142.             DBUF[i]=FALSE;
  143.             }
  144.         }
  145.     DPOS=-1;
  146.     return(TRUE);
  147.     }
  148. }
  149.  
  150. /**************************************************/
  151. int lbc(lev,str) /*counts printable chars in line level and
  152.         above; parity must be reset*/
  153. int lev; /*=0 main line,=-1 superscripts,=+1 subscripts, etc.*/
  154. char *str;
  155. {char c,n;
  156. int l;
  157. l=n=0;
  158. c=*str;
  159. while(c){if(c==CFVAL){if(c=*(++str))
  160.             switch(c)
  161.             {case '+':l--;c=*(++str);break;
  162.             case '-':l++;c=*(++str);break;
  163.             default: c=*(++str);break;
  164.             }    }
  165.     else    {if((c>' ')&&(l<=lev)) if(c!=TCVAL) n++;
  166.         c=*(++str);
  167.         }
  168.     }
  169. return(n);
  170. }
  171.  
  172. /**************************************************/
  173. prpass(lev,updat) /*printer pass initial cr; no lf anywhere*/
  174. int lev; /*=0 main line,=-1 superscripts,=+1 subscripts, etc.*/
  175. int updat;/*boolean to update UF,XF,MCNT*/
  176. {char ch;
  177. int l;
  178. int xfs,ufs,mcnts;    /*save variables*/
  179. int p1,p2,p3;        /*position holders*/
  180. int cp2;    /*for tabulation calculation*/
  181. xfs=XF; ufs=UF; mcnts=MCNT;
  182. p1=p2=p3=l=BPOS=CP=PP=0;
  183. while(ch=OUTBUF2[BPOS])
  184.     {switch (class(ch))
  185.     {case    BLACK:/*print it if posssible*/
  186.         if((PP>CP)||(l>lev)){CP++;BPOS++;break;}
  187.         else    {while(CP>PP){putchar(' ');PP++;}
  188.             if(ch==SCVAL)putchar(' ');
  189.             else putchar(ch);PP++;
  190.             if(MCNT>OCNT)
  191.                 {DBUF[BPOS]=OUTBUF2[BPOS];
  192.                 if(BPOS>DPOS) DPOS=BPOS;
  193.                 }
  194.             OUTBUF2[BPOS++]=' ';
  195.             if(UF&&FIRST)UBUF[UCOL=CP]=UCHAR;
  196.             if(XF&&FIRST)XBUF[XCOL=CP]=XCHAR;
  197.             BLKCNT--; CP++;
  198.             } break;
  199.     case    WHITE:/*assume blank*/ CP++;BPOS++;break;
  200.     case    TRANSLATE:/*similar to BLACK and WHITE*/
  201.             ch=OUTBUF2[++BPOS];
  202.             if((PP>CP)||(l>lev)||(ch==' '))
  203.                 {CP++;BPOS++;break;}
  204.             else
  205.               {while(CP>PP){putchar(' ');PP++;}
  206.             trch(ch);PP++;
  207.             if(MCNT>OCNT)
  208.                 {DBUF[BPOS]=OUTBUF2[BPOS];
  209.                 DBUF[BPOS-1]=OUTBUF2[BPOS-1];
  210.                 if(BPOS>DPOS) DPOS=BPOS;
  211.                 }
  212.             OUTBUF2[BPOS++]=' ';
  213.             if(UF&&FIRST)UBUF[UCOL=CP]=UCHAR;
  214.             if(XF&&FIRST)XBUF[XCOL=CP]=XCHAR;
  215.             BLKCNT--; CP++;
  216.             } break;
  217.     case    CONTROL:/*decode on following letter*/
  218.             ch=OUTBUF2[++BPOS];
  219.             if(CPTR[ch-' ']) pcont(ch);
  220.             else switch(ch)
  221.             {case 'h':
  222.             case 'H':/*backspace*/
  223.                 if(CP)CP--;break;
  224.             case '+': l--; break;
  225.             case '-': l++; break;
  226.             case 'U': UF=TRUE;break;
  227.             case 'u': UF=FALSE;break;
  228.             case 'X': XF=TRUE;break;
  229.             case 'x': XF=FALSE;break;
  230.             case 'B': MCNT *=3;break;
  231.             case 'b': if(!(MCNT /=3))MCNT=1;
  232.                     break;
  233.             case 'D': MCNT *=2;break;
  234.             case 'd': if(!(MCNT /=2))MCNT=1;
  235.                     break;
  236.             case '(': p1=CP;break;
  237.             case ')': CP=p1;break;
  238.             case '[': p2=CP;break;
  239.             case ']': CP=p2;break;
  240.             case '{': p3=CP;break;
  241.             case '}': CP=p3;break;
  242.             default:/*?,ignore*/;break;
  243.             } BPOS++; break;
  244.     case    SENTINEL: OUTBUF2[BPOS]=0;break;
  245.     case    HTAB: for(cp2=0;CP>=0;cp2+=TABSIZ)CP-=TABSIZ;
  246.             CP=cp2; BPOS++; break;
  247.     case    OTHERS:
  248.        fprintf(STDERR,"\nweird character value: %o\n",ch);
  249.         BPOS++;
  250.         break;
  251.     }}
  252. if(!updat){/*restore original values*/
  253.     XF=xfs;
  254.     UF=ufs;
  255.     MCNT=mcnts;
  256.     }
  257. }
  258. /**************************************************/
  259. int class(c)
  260. char c;
  261. {if(c==TCVAL) return(TRANSLATE);
  262. if (c==CFVAL) return(CONTROL);
  263. if(c>' ') return(BLACK);
  264. if(c==' ') return(WHITE);
  265. if(c=='\n') return(SENTINEL);
  266. if(c=='\r') return(SENTINEL);
  267. if(c==TAB) return(HTAB);
  268. if(!c) return(SENTINEL);
  269. return(OTHERS);
  270. }
  271. /**************************************************/
  272. fraction()    /*put printer in fractional spcing mode;
  273.             set FRQ*/
  274. {if(!FRQ && FRSTRING && (FRVAL!=1))
  275.     {outstr(FRSTRING);
  276.     FRQ = TRUE;
  277.     }
  278. }
  279. /**************************************************/
  280. whole()        /*put printer in whole line spacing;
  281.             reset FRQ */
  282. {if(FRQ && WHSTRING)
  283.     {outstr(WHSTRING);
  284.     FRQ = FALSE;
  285.     }
  286. }
  287. /**************************************************/
  288. trch(c)    /*output string translation of c*/
  289. char c;
  290. {char *p;
  291.     if(c<' ') {putchar(TCVAL);putchar(c);return;}
  292.     p = TPTR[c-' '];
  293.     if(p) outstr(p);
  294.     else    {/*not initialized*/
  295.         putchar(TCVAL);
  296.         putchar('?');
  297.         }
  298. }
  299. /****************************************/
  300. pcont(c) /*output printer control string for c*/
  301. char c;
  302. {char *p;
  303.     if(c<' ') {putchar(CFVAL);putchar(c);return;}
  304.     p = CPTR[c-' '];
  305.     if(p) outstr(p);
  306.     else    {/*not initialized*/
  307.         putchar(CFVAL);
  308.         putchar('?');
  309.         }
  310. }
  311.  return(SENTINEL);
  312. if(c==TAB) return(