home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 304_01 / roff57.c < prev    next >
Text File  |  1990-02-14  |  9KB  |  343 lines

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